如何统计二维numpy数组或二值图像白色区域的角点数量
二维二值NumPy数组白色区域角点统计
需求说明
- 统计二维NumPy数组中白色区域(像素值为1)的角点总数量
- 支持可选输出角点坐标,方便结果校验
- 数组背景像素值统一为0,白色区域像素值统一为1
已有方案的问题
之前尝试的两类方案都无法满足需求:
- 手写if/else邻域判断逻辑:无法覆盖所有边界场景(比如数组边缘的角点、极小尺寸白色块的角点)
- OpenCV Harris角点检测:算法本身适配大尺寸稠密图像,对像素级极小角点漏检率极高,例如下方3×4的小数组包含的角点就无法被稳定检出:
[ [0, 0, 0, 0], [0, 1, 1, 1], [0, 1, 1, 1] ]
实现方案
针对像素级二值图像的角点检测,直接基于8邻域像素模式判断即可,不需要依赖复杂的CV算法:
- 对每个值为1的像素,提取其3×3邻域范围的所有像素,数组边界外的像素默认按0计算
- 凸直角角点的邻域特征为:当前像素为1,且邻域内刚好有3个连续相邻的1(对应角点延伸出的两个垂直边),其余邻域像素为0
- 若需要统计凹角点、斜向角点,只需要扩展邻域匹配规则即可
可运行代码
import numpy as np from scipy.ndimage import convolve def count_corners(bin_arr, return_positions=False): """ 统计二值数组中白色(1)区域的凸角点数量 :param bin_arr: 输入的二维0/1 numpy数组 :param return_positions: 是否返回角点坐标 """ # 3x3邻域卷积核,用不同权重唯一标记邻域位置 kernel = np.array([ [1, 2, 4], [8, 0, 16], [32, 64, 128] ], dtype=np.uint8) # 卷积计算每个像素的邻域特征值,边界外补0 neighbor_code = convolve(bin_arr.astype(np.uint8), kernel, mode='constant', cval=0) # 4种凸角点对应的特征值:左上、右上、左下、右下 corner_codes = {208, 104, 22, 11} # 筛选本身为1、且邻域匹配角点特征的像素 corner_mask = (bin_arr == 1) & (np.isin(neighbor_code, list(corner_codes))) corner_count = int(corner_mask.sum()) if return_positions: positions = np.argwhere(corner_mask) return corner_count, positions return corner_count # 测试示例 test_arr = np.array([ [0,0,0,0], [0,1,1,1], [0,1,1,1] ]) count, pos = count_corners(test_arr, return_positions=True) print(f"角点数量:{count}") print(f"角点坐标(行,列):\n{pos}")
测试输出
角点数量:4 角点坐标(行,列): [[1 1] [1 3] [2 1] [2 3]]
注:如果需要检测其他类型的角点,只需要把对应邻域模式的编码加入
corner_codes集合即可,所有邻域组合都可以通过卷积核的权重生成唯一编码,不会出现逻辑遗漏。
内容的提问来源于stack exchange,提问作者tejas bhakta
相关产品推荐
相关产品推荐

