初始提交
This commit is contained in:
87
shape_spectral_background.py
Normal file
87
shape_spectral_background.py
Normal file
@ -0,0 +1,87 @@
|
||||
import matplotlib
|
||||
import matplotlib.pyplot as plt
|
||||
matplotlib.use('TkAgg')
|
||||
from plantcv import plantcv as pcv
|
||||
import numpy as np
|
||||
import cv2
|
||||
|
||||
|
||||
|
||||
def process_images_background(full_bil_path, mask, outdir='None', debug="None"):
|
||||
# 初始化参数
|
||||
class options:
|
||||
def __init__(self):
|
||||
self.image = full_bil_path # 输入的光谱图像路径
|
||||
self.debug = debug # 设置调试模式:'plot' 或 'print'
|
||||
self.writeimg = False # 是否保存图片
|
||||
self.result = outdir # 输出结果文件路径
|
||||
self.outdir = outdir # 输出文件夹路径
|
||||
|
||||
args = options()
|
||||
|
||||
# 设置 PlantCV 的全局参数
|
||||
pcv.params.debug = args.debug
|
||||
pcv.params.dpi = 100 # 设置 DPI
|
||||
pcv.params.text_size = 1 # 文本大小
|
||||
pcv.params.text_thickness = 1 # 文本粗细
|
||||
|
||||
# 读取光谱图像(ENVI 格式)
|
||||
spectral_array = pcv.readimage(filename=args.image, mode='envi')
|
||||
bath_100 = spectral_array.array_data[:, :, 100]
|
||||
bath_over = pcv.threshold.binary(gray_img=bath_100, threshold=5500, object_type='light')
|
||||
|
||||
# 将PIL 16位掩膜转换为8位二值化格式
|
||||
# 如果mask是非零值则设置为255(塑料区域),否则为0(背景)
|
||||
mask_array = np.array(mask) if not isinstance(mask, np.ndarray) else mask
|
||||
b_thresh_unit8 = ((mask_array > 0).astype(np.uint8)) * 255
|
||||
|
||||
# 填充小的孔洞,并反转掩膜
|
||||
b_fill = pcv.fill(bin_img=b_thresh_unit8, size=250)
|
||||
b_fill_inverted = pcv.invert(b_fill)
|
||||
|
||||
# 创建形态统计和光谱统计掩膜
|
||||
dilate_img = pcv.dilate(gray_img=b_fill_inverted, ksize=3, i=4)
|
||||
bath_erode = pcv.erode(gray_img=bath_over, ksize=3, i=4)
|
||||
|
||||
# 塑料掩膜的反转和非黑色背景的掩膜相乘
|
||||
dilate_img = dilate_img * bath_erode / 255
|
||||
dilate_img = pcv.fill(bin_img=dilate_img, size=10000)
|
||||
|
||||
# 使用cv2.connectedComponents代替pcv.create_labels,避免污染plantcv outputs
|
||||
num1, labeled_spectral_mask = cv2.connectedComponents(dilate_img.astype(np.uint8))
|
||||
|
||||
# plt.figure(figsize=(10, 8))
|
||||
# plt.imshow(dilate_img, cmap='nipy_spectral')
|
||||
# plt.colorbar(label='Object Label')
|
||||
# plt.title(f'Labeled Spectral Mask - {num1} objects detected')
|
||||
# plt.xlabel('X coordinate')
|
||||
# plt.ylabel('Y coordinate')
|
||||
# plt.show()
|
||||
print(f"Number of objects (second mask): {num1 - 1}") # -1 because first label is background
|
||||
|
||||
# 直接计算每个对象的面积并找到最大面积的对象
|
||||
max_area = 0
|
||||
max_label = 0
|
||||
|
||||
# 遍历所有标签(从1开始,0是背景)
|
||||
for label in range(1, num1):
|
||||
# 创建当前标签的掩膜
|
||||
obj_mask = labeled_spectral_mask == label
|
||||
# 计算面积
|
||||
area = np.sum(obj_mask)
|
||||
if area > max_area:
|
||||
max_area = area
|
||||
max_label = label
|
||||
|
||||
# 提取最大面积对象的光谱
|
||||
if max_label > 0:
|
||||
max_obj_mask = labeled_spectral_mask == max_label
|
||||
# 获取最大对象在所有波段的光谱值
|
||||
spectral_values = spectral_array.array_data[max_obj_mask, :]
|
||||
# 计算平均光谱
|
||||
mean_spectrum = np.mean(spectral_values, axis=0)
|
||||
# 返回最大面积对象的平均光谱
|
||||
return mean_spectrum/10000
|
||||
else:
|
||||
# 如果没有找到有效背景对象,返回全零光谱
|
||||
return np.zeros(spectral_array.array_data.shape[-1]) / 10000
|
||||
Reference in New Issue
Block a user