如何从2D NumPy数组分割图中提取各连通簇边界框(同类可多簇)
获取分割图中每个连通簇的边界框
没问题,你找对方向了!用scikit-image的measure模块完全能解决这个需求,我给你一步步拆解实现方法:
核心思路
首先用skimage.measure.label()给每个连通簇分配唯一标记(同一个类别下的不同连通簇会被标上不同数字),然后通过skimage.measure.regionprops()提取每个连通簇的属性,其中就包含我们需要的边界框坐标。
步骤详解&代码示例
1. 导入依赖库
import numpy as np from skimage import measure
2. 准备分割图(或用你自己的2D NumPy数组)
这里我模拟一个包含背景和多个类别、每个类别有多个连通簇的示例分割图:
# 构造示例分割图:0=背景,1=类别A,2=类别B,3=类别C seg_map = np.array([ [0, 0, 1, 1, 0, 2], [0, 1, 1, 0, 2, 2], [0, 0, 0, 0, 2, 0], [3, 3, 0, 1, 1, 1], ])
3. 标记连通区域
这里的connectivity参数要按需选择:
connectivity=1:4连通(仅上下左右相邻算连通)connectivity=2:8连通(包含对角线相邻)
如果要忽略背景类别(比如0),可以加上background=0参数:
# 生成连通区域标记图 labeled_seg = measure.label(seg_map, connectivity=1, background=0)
4. 提取每个连通簇的边界框及对应类别
遍历regionprops()返回的区域对象,就能拿到边界框和所属类别:
# 遍历所有连通区域 for region in measure.regionprops(labeled_seg, intensity_image=seg_map): # 获取连通簇的类别(同一区域内像素类别一致,均值就是类别值) class_id = int(region.intensity_mean) # 获取边界框:格式为(min_row, min_col, max_row, max_col) # 注意:max_row和max_col是开区间,若要包含最后一行/列,需+1 min_row, min_col, max_row, max_col = region.bbox # 输出结果 print(f"类别{class_id}的连通簇,边界框:行[{min_row}:{max_row}],列[{min_col}:{max_col}]")
输出结果示例
运行代码后会得到类似这样的输出:
类别1的连通簇,边界框:行[0:2],列[2:4] 类别2的连通簇,边界框:行[0:3],列[5:6] 类别2的连通簇,边界框:行[1:2],列[4:5] 类别3的连通簇,边界框:行[3:4],列[0:2] 类别1的连通簇,边界框:行[3:4],列[3:6]
额外实用技巧
- 如果需要把结果整理成结构化数据(比如按类别分组存储边界框),可以用字典收集:
class_bboxes = {} for region in measure.regionprops(labeled_seg, intensity_image=seg_map): class_id = int(region.intensity_mean) bbox = region.bbox if class_id not in class_bboxes: class_bboxes[class_id] = [] class_bboxes[class_id].append(bbox)
- 若不需要忽略背景,去掉
background参数即可,label()会给所有非零像素的连通簇标记。
内容的提问来源于stack exchange,提问作者gustavz
相关产品推荐
相关产品推荐

