如何优化掩码处理流程获取更清晰blob 实现图像红点准确计数
红色圆点计数掩码流程优化方案
核心问题分析
当前漏检问题主要来自三个环节:
- RGB颜色空间筛选鲁棒性差,亮度变化会导致部分偏暗/偏亮的红色圆点未被纳入掩码
- 形态学开运算迭代次数过多,会侵蚀边缘不完整的小目标,直接把部分圆点从掩码中抹除
- 计数逻辑仅用面积判断,没有结合圆点的形态特征,容易漏检、误检
具体优化步骤
1. 替换为HSV颜色空间做颜色筛选
红色在HSV空间的色调范围分为两段(0-10和170-180),能覆盖不同亮度、饱和度的红色目标,筛选精度远高于RGB空间。
2. 调整形态学操作逻辑
先做闭运算填补圆点内部的孔洞和断裂,再做开运算去除背景噪声,迭代次数控制在1-2次即可,避免过度侵蚀目标。
3. 优化计数逻辑
增加圆形度判断(圆形度=4π*面积/(周长²),完美圆形的圆形度接近1),排除不规则噪声的同时,避免完整的小圆点被误判为噪声。
优化后完整代码
import cv2 import os import numpy as np os.chdir('C:\Program Files\Python\projects\Blob') # 读取图像 image_input = cv2.imread('realbutwithacrylic.png') hsv = cv2.cvtColor(image_input, cv2.COLOR_BGR2HSV) # HSV空间红色阈值,分两段覆盖所有红色调 lower_red1 = np.array([0, 50, 50]) upper_red1 = np.array([10, 255, 255]) lower_red2 = np.array([170, 50, 50]) upper_red2 = np.array([180, 255, 255]) # 合并两个红色掩码 mask1 = cv2.inRange(hsv, lower_red1, upper_red1) mask2 = cv2.inRange(hsv, lower_red2, upper_red2) first_mask = cv2.bitwise_or(mask1, mask2) # 形态学操作:先闭运算补孔洞,再开运算去噪 kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5)) # 闭运算填补断裂 closed = cv2.morphologyEx(first_mask, cv2.MORPH_CLOSE, kernel, iterations=2) # 开运算去小噪声 opening = cv2.morphologyEx(closed, cv2.MORPH_OPEN, kernel, iterations=1) # 查找轮廓 cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] if len(cnts) == 2 else cnts[1] blobs = 0 for c in cnts: area = cv2.contourArea(c) # 过滤极小的噪声 if area < 100: continue # 计算圆形度 perimeter = cv2.arcLength(c, True) circularity = 4 * np.pi * (area / (perimeter * perimeter)) if perimeter !=0 else 0 # 圆形度大于0.7的判定为圆点 if circularity > 0.7: # 若存在重叠圆点计数需求,可保留原面积分段加2的逻辑,单圆点场景直接计数即可 blobs += 1 cv2.drawContours(image_input, [c], -1, (0,255,0), 2) print('blobs:', blobs) cv2.imshow('original mask', first_mask) cv2.imshow('processed mask', opening) cv2.imshow('result', image_input) cv2.waitKey(0) cv2.destroyAllWindows()
效果说明
调整后可以覆盖所有亮度的红色圆点,同时保留边缘不完整的目标,不会被形态学操作误删除,配合圆形度判断也能避免背景红色噪声被误算入计数,准确率会明显提升。
内容的提问来源于stack exchange,提问作者Lutfi Lais
相关产品推荐
相关产品推荐

