Python中基于IoU高效合并12k重叠轮廓的优化需求
基于IoU直接合并重叠轮廓的优化实现
你有12000个带大量重叠的轮廓列表,想要跳过中间生成合并关系字典的步骤,直接基于IoU阈值完成重叠轮廓的合并,下面是高效实现方案:
核心思路
利用连通分量分析替代字典记录合并关系:重叠轮廓本质是连通的(A和B重叠、B和C重叠,则A/B/C属于同一组),通过IoU矩阵构建邻接图后,用连通分量直接分组,再对每组轮廓求并集完成合并。
完整代码实现
import numpy as np import pygeos from pygeos import intersection, union, area, Geometry from shapely.geometry import Polygon from scipy.sparse import csr_matrix from scipy.sparse.csgraph import connected_components # 1. 轮廓转pygeos几何对象 detection_contours = np.array([Geometry(str(Polygon(np.squeeze(val)))) for val in contours_list]) # 2. 计算IoU矩阵并构建邻接图 match_threshold = 0.5 # 根据业务需求调整IoU阈值 # 计算两两轮廓的交集/并集面积 intersection_areas = area(intersection(detection_contours[:, np.newaxis], detection_contours[np.newaxis, :])) union_areas = area(union(detection_contours[:, np.newaxis], detection_contours[np.newaxis, :])) iou_matrix = intersection_areas / union_areas # 生成邻接矩阵:IoU超过阈值则标记为连通,对角线置0(排除自身) adjacency_matrix = (iou_matrix > match_threshold).astype(int) np.fill_diagonal(adjacency_matrix, 0) # 3. 连通分量分析分组 graph = csr_matrix(adjacency_matrix) n_components, labels = connected_components(csgraph=graph, directed=False, return_labels=True) # 4. 直接合并每组轮廓 merged_contours = [] for label in range(n_components): # 提取当前组的所有轮廓 group_geoms = detection_contours[labels == label] # 合并组内所有轮廓(迭代求并集) merged_geom = group_geoms[0] for geom in group_geoms[1:]: merged_geom = union(merged_geom, geom) # 转回原轮廓格式(适配输入的contours_list结构) merged_poly = merged_geom.__geo_interface__ merged_contour = np.array(merged_poly['coordinates'][0]).reshape(-1, 1, 2) merged_contours.append(merged_contour)
方案优势
- 完全跳过了原方案中
keep_to_merge_list、dest等中间字典的生成与遍历步骤,逻辑更简洁 - 连通分量分析的时间复杂度远低于原字典遍历方案,处理12000个轮廓的效率提升明显
- 直接基于几何对象的并集操作,合并结果更精准
内容的提问来源于stack exchange,提问作者Ahmad Javed
相关产品推荐
相关产品推荐

