如何在Python中提取二进制矩阵的所有不相交子集(图像掩码)
提取二进制矩阵中不相交连通子集的解决方案
核心思路是识别二进制矩阵中的连通分量(即由1组成的不相交区域),再为每个分量生成独立的同尺寸二进制矩阵。以下是两种常用实现方式:
方法一:使用scipy.ndimage.label
适合快速处理,支持自定义连通性:
- 导入依赖库:
import numpy as np from scipy.ndimage import label - 具体步骤:
- 定义你的二进制矩阵(示例):
mask = np.array([ [1, 0, 1], [1, 0, 0], [0, 1, 1] ], dtype=np.uint8) - 标记所有连通分量:
# 默认4连通(上下左右),如需8连通可指定structure=np.ones((3,3)) labeled_mask, num_components = label(mask) - 生成每个独立子集矩阵:
individual_masks = [] for component_id in range(1, num_components + 1): # 将当前分量的位置设为1,其余为0 single_mask = (labeled_mask == component_id).astype(np.uint8) individual_masks.append(single_mask)
- 定义你的二进制矩阵(示例):
方法二:使用OpenCV.connectedComponents
适合与计算机视觉工作流结合:
- 导入依赖库:
import numpy as np import cv2 - 具体步骤:
- 定义二进制矩阵(需为uint8类型):
mask = np.array([ [1, 0, 1], [1, 0, 0], [0, 1, 1] ], dtype=np.uint8) - 标记连通分量:
# 默认8连通,如需4连通可指定connectivity=4 num_components, labeled_mask = cv2.connectedComponents(mask) - 生成每个独立子集矩阵:
individual_masks = [] # 注意:labeled_mask中0代表背景,分量ID从1开始 for component_id in range(1, num_components): single_mask = np.where(labeled_mask == component_id, 1, 0).astype(np.uint8) individual_masks.append(single_mask)
- 定义二进制矩阵(需为uint8类型):
关键说明
- 连通性:4连通指仅上下左右相邻的1视为同一区域;8连通包含对角线相邻的1,可根据需求调整。
- 输出结果:
individual_masks列表中包含N个与原矩阵尺寸一致的二进制矩阵,每个矩阵仅保留一个不相交的1子集。
内容的提问来源于stack exchange,提问作者Vahid S. Bokharaie
相关产品推荐
相关产品推荐

