如何计算布尔矩阵密度并圈选目标密集区域?
布尔矩阵高密度区域圈选方案
你的密度矩阵+凸包的思路完全可行,而且可以同时圈出两个目标区域,下面给你拆解落地方法,同时分享一个更高效的连通域分析方案:
一、你的思路落地步骤
1. 构建密度矩阵
密度矩阵的核心是计算每个像素邻域内1的数量,用滑动窗口实现即可:
- 选择合适的窗口大小(比如3×3,覆盖当前像素和周围8个像素)
- 遍历矩阵中每个像素,统计窗口内1的总数,将该值作为密度矩阵对应位置的元素
- 离群点的邻域1数量极少,高密度区域的密度值会显著更高
2. 阈值过滤离群点
根据目标区域的密度特点设置阈值(比如3×3窗口内1的数量≥4),将密度低于阈值的1置为0,这样就能过滤掉左上角和右下角的离群点,只保留两个高密度区域。
3. 提取双区域凸包
过滤后的矩阵会剩下两个独立的连通区域,分别提取每个区域的所有坐标点,再对每个区域单独计算凸包,就能同时圈出两个目标区域。
二、更高效的连通域分析方案
针对这类布尔矩阵的区域提取,连通域分析是更直接的方案,无需构建密度矩阵,步骤如下:
- 提取有效点集:将矩阵中所有值为1的像素坐标提取出来
- 连通域划分:用邻域搜索算法(4邻接或8邻接)将点集划分为不同的连通组件
- 过滤小组件:根据目标区域的大小(比如4×4=16个点),过滤掉点数极少的组件(即离群点)
- 圈选区域:对剩下的两个大组件,可直接用最小外接矩形圈选,或计算凸包得到更精确的边界
代码实现示例(Python)
import numpy as np from scipy.ndimage import label, find_objects from scipy.spatial import ConvexHull # 原始布尔矩阵 matrix = np.array([ [1,0,0,0,0,0,1,1,1,1], [0,0,0,0,0,0,1,1,1,1], [0,0,0,0,0,0,1,1,1,1], [0,0,0,0,0,0,1,1,1,1], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [1,1,1,1,0,0,0,0,0,0], [1,1,1,1,0,0,0,0,0,0], [1,1,1,1,0,0,0,0,1,1], [1,1,1,1,0,0,0,0,0,0] ]) # 8邻接连通域标记 labeled_mat, component_count = label(matrix, structure=np.ones((3,3))) # 获取每个连通域的边界框 components = find_objects(labeled_mat) # 筛选出目标区域(点数≥10,排除离群点) target_components = [] for idx in range(1, component_count + 1): mask = labeled_mat == idx if np.sum(mask) >= 10: target_components.append(mask) # 对每个目标区域计算凸包 for mask in target_components: coords = np.argwhere(mask) hull = ConvexHull(coords) print("区域凸包顶点坐标:", coords[hull.vertices])
补充说明
- 如果不需要凸包的精确边界,直接用
find_objects返回的slice对象就能快速得到每个区域的矩形范围,实现更简单 - 邻接方式可根据需求选择:4邻接(上下左右)或8邻接(含对角线),目标区域是矩形,两种方式都能准确划分
内容的提问来源于stack exchange,提问作者Carl
相关产品推荐
相关产品推荐

