如何在Python中提取二维布尔数组同值连续子区域的索引
你要实现的是二维数组的同值连通域索引提取,以下是两种可直接运行的实现方案,默认采用四邻域连通规则(上下左右相邻判定为连续,如需八邻域可按注释调整):
方案1:基于scipy的高效实现
适合处理大规模数组,代码简洁:
import numpy as np from scipy.ndimage import label # 输入示例数组 arr = np.array([[1, 1, 0, 0, 1], [1, 0, 0, 0, 0], [0, 0, 1, 1, 1], [0, 0, 0, 1, 1], [1, 0, 1, 1, 0]]) # 定义四邻域连通规则,如需八邻域可替换为 np.ones((3,3), dtype=bool) connect_structure = np.array([[0,1,0], [1,1,1], [0,1,0]], dtype=bool) all_regions = [] # 分别提取值为1和值为0的连通域 for target_val in [0, 1]: # 连通域标记,返回标记后的数组和连通域数量 labeled_arr, region_count = label(arr == target_val, structure=connect_structure) for region_id in range(1, region_count + 1): # 提取当前连通域的所有坐标索引 coords = np.argwhere(labeled_arr == region_id).tolist() all_regions.append({ "value": target_val, "indexes": coords }) # 打印输出所有区域 for idx, region in enumerate(all_regions): print(f"区域{idx+1},值为{region['value']},索引:{region['indexes']}")
方案2:手动BFS实现(无第三方依赖)
如果不想引入scipy依赖,可直接用原生Python+Numpy实现广度优先搜索遍历:
import numpy as np def get_connected_regions(arr, connectivity=4): rows, cols = arr.shape visited = np.zeros_like(arr, dtype=bool) all_regions = [] # 邻接偏移量定义 if connectivity == 4: offsets = [(-1,0), (1,0), (0,-1), (0,1)] else: # 八邻域 offsets = [(-1,-1), (-1,0), (-1,1), (0,-1), (0,1), (1,-1), (1,0), (1,1)] for i in range(rows): for j in range(cols): if not visited[i][j]: current_val = arr[i][j] queue = [(i,j)] visited[i][j] = True current_region = [(i,j)] # BFS遍历整个连通域 while queue: x, y = queue.pop(0) for dx, dy in offsets: nx, ny = x + dx, y + dy if 0 <= nx < rows and 0 <= ny < cols \ and not visited[nx][ny] \ and arr[nx][ny] == current_val: visited[nx][ny] = True current_region.append((nx, ny)) queue.append((nx, ny)) all_regions.append({ "value": current_val, "indexes": current_region }) return all_regions # 调用示例 arr = np.array([[1, 1, 0, 0, 1], [1, 0, 0, 0, 0], [0, 0, 1, 1, 1], [0, 0, 0, 1, 1], [1, 0, 1, 1, 0]]) regions = get_connected_regions(arr, connectivity=4) for idx, region in enumerate(regions): print(f"区域{idx+1},值为{region['value']},索引:{region['indexes']}")
示例输出会按照顺序返回所有同值连续区域的索引,对应你给出的示例数组,值为1的连通域共4个,值为0的连通域共2个,和高亮划分结果完全匹配。
内容的提问来源于stack exchange,提问作者bug_money
相关产品推荐
相关产品推荐

