如何检测数组中存储的图像矩形ROI是否存在重叠?
检查ROI矩形是否存在重叠
问题描述
给定如下Python数组,每个元素对应图像中的一个ROI矩形,格式为([min_X, max_X], [min_Y, max_Y])(示例图像分辨率为1280x1080):
import numpy as np arr = [] arr.append( ([0.195, 0.229], [0.673, 0.754]) ) arr.append( ([1.0, 1.903], [0.161, 0.303]) ) arr.append( ([0.052, 0.321], [1.0, 1.929]) )
需要判断这些ROI中是否存在任意两个矩形重叠的情况。
核心判断逻辑
两个矩形不重叠的充要条件是其中一个完全在另一个的左侧、右侧、上方或下方:
- 矩形A的
max_X ≤矩形B的min_X→ A在B左侧 - 矩形A的
min_X ≥矩形B的max_X→ A在B右侧 - 矩形A的
max_Y ≤矩形B的min_Y→ A在B上方 - 矩形A的
min_Y ≥矩形B的max_Y→ A在B下方
若以上四个条件均不满足,则两个矩形存在重叠。
解决方案
方法1:遍历两两组合(适合小数量ROI)
先将原始数组转换为(min_X, max_X, min_Y, max_Y)的统一格式,再遍历所有两两ROI对进行判断:
import numpy as np # 转换为统一矩形格式 rects = np.array([[x_min, x_max, y_min, y_max] for (x_min, x_max), (y_min, y_max) in arr]) def check_overlap(rects): roi_count = len(rects) for i in range(roi_count): x1_min, x1_max, y1_min, y1_max = rects[i] for j in range(i + 1, roi_count): x2_min, x2_max, y2_min, y2_max = rects[j] # 判断是否不重叠 if (x1_max <= x2_min) or (x1_min >= x2_max) or (y1_max <= y2_min) or (y1_min >= y2_max): continue # 存在重叠,返回结果及重叠对索引 return True, (i, j) # 无重叠 return False, None # 执行检查 has_overlap, overlap_indices = check_overlap(rects) print(f"是否存在重叠:{has_overlap}") if has_overlap: print(f"重叠的ROI索引:{overlap_indices}")
方法2:Numpy向量化处理(适合大量ROI,效率更高)
利用Numpy广播机制批量计算所有两两组合的重叠情况,避免循环,提升处理速度:
import numpy as np # 转换为统一矩形格式 rects = np.array([[x_min, x_max, y_min, y_max] for (x_min, x_max), (y_min, y_max) in arr]) # 提取各维度的极值数组 min_x = rects[:, 0] max_x = rects[:, 1] min_y = rects[:, 2] max_y = rects[:, 3] # 计算所有两两组合的不重叠条件 left = max_x[:, None] <= min_x[None, :] right = min_x[:, None] >= max_x[None, :] top = max_y[:, None] <= min_y[None, :] bottom = min_y[:, None] >= max_y[None, :] # 不重叠的情况为任意一个条件成立 non_overlap = left | right | top | bottom # 对角线为自身对比,标记为不重叠(排除自身) np.fill_diagonal(non_overlap, True) # 判断是否存在重叠 has_overlap = not np.all(non_overlap) print(f"是否存在重叠:{has_overlap}") if has_overlap: # 提取所有不重复的重叠对(i < j) overlap_pairs = np.argwhere(~non_overlap) overlap_pairs = overlap_pairs[overlap_pairs[:, 0] < overlap_pairs[:, 1]] print(f"所有重叠ROI对:{overlap_pairs.tolist()}")
内容的提问来源于stack exchange,提问作者pookie
相关产品推荐
相关产品推荐

