87 lines
3.3 KiB
Python
87 lines
3.3 KiB
Python
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 |