如何统计叠加二值图像中落在目标区域内外的白色圆点数量
二值图像点-连通域匹配统计解决方案
核心思路完全避开尺寸匹配的鲁棒性问题,本质是做点集与二值掩码的空间匹配,不需要对比两者的尺寸大小,实现逻辑如下:
- 第一步:预处理第二张blob掩码,用3x3矩形结构元做1次闭运算,填充区域内部的微小暗斑,操作不会改变blob原有轮廓范围,避免点刚好落在暗斑区域产生误判
- 第二步:提取第一张二值图中所有白色圆点的核心坐标:如果圆点是单像素点,直接提取所有白色像素坐标即可;如果圆点是有面积的标记块,提取每个白色连通域的质心作为该点的代表坐标
- 第三步:逐个遍历点坐标,查询预处理后的blob掩码在对应坐标的像素值,值为255(白色)则判定为落在连通域内,值为0则判定为落在范围外,直接累加计数即可
现成实现示例(Python + OpenCV)
import cv2 import numpy as np # 读取两张已对齐的二值图,必须用灰度模式读取 dot_mask = cv2.imread("圆点二值图路径.png", 0) blob_mask = cv2.imread("Blob二值图路径.png", 0) # 预处理Blob掩码,填充内部小孔 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) processed_blob = cv2.morphologyEx(blob_mask, cv2.MORPH_CLOSE, kernel) # 提取所有圆点的质心坐标(适配有面积的圆点,单像素点可直接用dot_coords = np.column_stack(np.where(dot_mask > 127))) num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(dot_mask, connectivity=8) dot_coords = centroids[1:] # 去掉背景对应的第0个标签 # 统计内外数量 inside_count = 0 outside_count = 0 for (y, x) in dot_coords: # np.where返回的坐标顺序为行、列,对应图像的y、x x = int(round(x)) y = int(round(y)) if processed_blob[y, x] > 127: inside_count += 1 else: outside_count += 1 print(f"连通域内点数量:{inside_count},连通域外点数量:{outside_count}")
特殊场景适配
如果统计规则要求「圆点只要有任意部分和Blob重叠就算命中」,不需要用质心判断,可以替换逻辑为:
- 对圆点二值图做连通域分析,给每个圆点分配独立的标签
- 将所有圆点的标签掩码和Blob掩码做按位与运算
- 统计和Blob掩码存在重叠的标签数量即可,同样不受两者尺寸比例影响
内容的提问来源于stack exchange,提问作者Ze0ruso
相关产品推荐
相关产品推荐

