如何为Numpy数组中的多组非零值生成多个边界框?
如何为Numpy数组中的多个非零区域生成对应的边界框?
我有一个表示图像的Numpy数组,已经把感兴趣区域设为非零值,其余区域为0。如果只有单个区域,我可以通过查找非零值的首尾出现位置来获取边界框坐标,但当非零值分布在多个独立区域时,怎么生成多个对应的边界框?
示例数组如下:
import numpy as np A = np.array([[0, 0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1, 1], [0, 0, 0, 0, 1, 1, 1], [0, 0, 0, 0, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0]])
我需要围绕数组中的1生成两个独立的边界框。
解决方案:用连通区域标记逐个计算边界框
要处理多个独立的非零区域,核心是先识别每个连通的非零块,再分别计算每个块的边界框。这里可以用scipy.ndimage.label来标记不同的连通区域,再遍历每个区域计算坐标。
步骤1:标记连通区域
先导入依赖,然后用label函数给每个独立的非零区域分配唯一编号:
import numpy as np from scipy.ndimage import label # 示例数组 A = np.array([[0, 0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1, 1], [0, 0, 0, 0, 1, 1, 1], [0, 0, 0, 0, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0]]) # 标记连通区域,labels里每个区域有唯一编号,num_regions是区域总数 labels, num_regions = label(A)
这里num_regions会返回2,对应示例中的两个独立区域。
步骤2:计算每个区域的边界框
遍历每个区域编号,找出该区域内所有元素的坐标,然后取行和列的最小、最大值,得到边界框(格式为(y_min, x_min, y_max, x_max),可根据需求调整):
bounding_boxes = [] for region_id in range(1, num_regions + 1): # 获取当前区域所有元素的行、列坐标 y_coords, x_coords = np.where(labels == region_id) # 计算边界框的四个坐标 y_min, y_max = y_coords.min(), y_coords.max() x_min, x_max = x_coords.min(), x_coords.max() bounding_boxes.append((y_min, x_min, y_max, x_max)) # 输出结果 print(bounding_boxes)
运行后输出:
[(1, 0, 2, 1), (3, 4, 5, 6)]
第一个边界框覆盖行1-2、列0-1,第二个覆盖行3-5、列4-6,正好对应两个非零区域。
额外说明
- 默认
label用的是4连通(上下左右相邻算同一区域),如果需要把对角线相邻的元素也算同一区域,可传入structure=np.ones((3,3))启用8连通。 - 不想用scipy的话,也可以用OpenCV的
cv2.connectedComponents实现类似的连通区域标记。
内容的提问来源于stack exchange,提问作者Dee Rawat
相关产品推荐
相关产品推荐

