如何使用Python和OpenCV统计叶片显微图像中的气孔数量?
叶片气孔自动统计实现方案
原有代码失效原因
你使用的cvlib.detect_common_objects()是基于COCO通用数据集训练的检测接口,仅支持识别80类日常常见物体(如汽车、动物、家具等),数据集中没有叶片气孔类别,因此完全无法识别目标。
可行性说明
这类需求完全可以通过技术手段实现,气孔特征(椭圆形、厚黑色边缘)辨识度很高,不需要训练深度学习模型,仅用OpenCV传统图像处理方法就能完成统计,准确率足够支撑批量处理使用。
具体实现代码
import cv2 import numpy as np import matplotlib.pyplot as plt def count_stomata(image_path, min_area=100, max_area=1000, min_roundness=0.6): # 读取图像 img = cv2.imread(image_path) # 转灰度图 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 高斯模糊去噪 blurred = cv2.GaussianBlur(gray, (5, 5), 0) # 阈值分割:提取黑色边缘(可根据你的图像亮度调整阈值参数) _, thresh = cv2.threshold(blurred, 80, 255, cv2.THRESH_BINARY_INV) # 形态学操作,去除小噪点 kernel = np.ones((3,3), np.uint8) cleaned = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=1) # 检测轮廓 contours, _ = cv2.findContours(cleaned, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) count = 0 result_img = img.copy() for cnt in contours: # 计算轮廓面积 area = cv2.contourArea(cnt) if not (min_area < area < max_area): continue # 计算圆形度(越接近椭圆/圆形,值越接近1) perimeter = cv2.arcLength(cnt, True) roundness = 4 * np.pi * (area / (perimeter ** 2)) if roundness < min_roundness: continue # 符合条件的气孔计数,画框标记 count +=1 x,y,w,h = cv2.boundingRect(cnt) cv2.rectangle(result_img, (x,y), (x+w,y+h), (0,255,0), 2) cv2.putText(result_img, str(count), (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2) return count, result_img # 调用示例 if __name__ == "__main__": stomata_count, output = count_stomata("leaf1.jpg") print(f"检测到的气孔数量:{stomata_count}") # 显示结果,注意OpenCV是BGR格式,转成RGB适配matplotlib output_rgb = cv2.cvtColor(output, cv2.COLOR_BGR2RGB) plt.imshow(output_rgb) plt.axis('off') plt.show()
参数调整说明
如果出现误检、漏检的情况,可根据你的样本情况调整以下参数:
min_area/max_area:根据你图像中气孔的实际像素大小调整面积阈值,排除过大的杂质、过小的噪点- 阈值参数:如果图像整体偏亮/偏暗,调整
cv2.threshold的第二个参数(示例中为80),数值越高分割出来的深色区域越少 min_roundness:气孔椭圆度要求,数值越高筛选越严格,仅保留形状更接近正圆/椭圆的目标
内容的提问来源于stack exchange,提问作者hbstha123
相关产品推荐
相关产品推荐

