如何移除被遮挡目标的分割结果,仅绘制可见目标的边界框?
移除分割结果中被遮挡目标的可行方案
针对被树木等物体遮挡的分割目标,可通过以下几种实用方法过滤:
1. 基于目标完整性的面积占比筛选
核心逻辑:被遮挡的目标,其分割区域在自身外接矩形内的占比会远低于完整目标。
- 步骤:
- 用
cv2.findContours()提取分割掩码的轮廓 - 对每个轮廓计算最小外接矩形
cv2.boundingRect() - 计算轮廓面积
cv2.contourArea()与矩形面积的比值 - 设置合理阈值(比如0.5-0.7,根据目标类型调整),过滤比值低于阈值的目标
- 用
- 代码片段:
import cv2 import numpy as np mask = cv2.imread('segmentation_mask.png', 0) contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) valid_contours = [] area_ratio_threshold = 0.6 # 可根据场景调整 for cnt in contours: x, y, w, h = cv2.boundingRect(cnt) rect_area = w * h cnt_area = cv2.contourArea(cnt) ratio = cnt_area / rect_area if ratio >= area_ratio_threshold: valid_contours.append(cnt) # 绘制有效目标边界框 img = cv2.imread('original_image.png') for cnt in valid_contours: x, y, w, h = cv2.boundingRect(cnt) cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2) cv2.imwrite('result.png', img)
2. 结合原始图像的颜色/纹理特征过滤
利用原始图像的视觉特征,判断分割区域是否混杂了遮挡物的特征(比如树木的绿色)。
- 步骤:
- 根据分割掩码提取原始图像中目标区域的ROI
- 将ROI转换到HSV空间,统计遮挡物对应颜色的像素占比
- 占比超过阈值则判定为被遮挡目标,予以移除
- 代码片段:
img = cv2.imread('original_image.png') mask = cv2.imread('segmentation_mask.png', 0) valid_contours = [] occlusion_color_threshold = 0.2 # 遮挡物颜色占比阈值 # 定义树木绿色的HSV范围 lower_green = np.array([35, 40, 40]) upper_green = np.array([77, 255, 255]) contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for cnt in contours: x, y, w, h = cv2.boundingRect(cnt) roi = img[y:y+h, x:x+w] roi_hsv = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV) mask_green = cv2.inRange(roi_hsv, lower_green, upper_green) green_pixel_ratio = np.sum(mask_green > 0) / (w * h) if green_pixel_ratio <= occlusion_color_threshold: valid_contours.append(cnt)
3. 轮廓形状匹配过滤
提前收集完整目标的轮廓模板,通过形状相似度判断分割目标是否完整。
- 步骤:
- 导入完整目标的轮廓模板(比如提前标注的完整车辆轮廓)
- 计算分割轮廓与模板的Hu矩相似度
cv2.matchShapes() - 设置相似度阈值,过滤匹配度低的目标
- 代码片段:
# 假设template_contour是提前加载的完整目标轮廓 template_mask = cv2.imread('template_mask.png', 0) template_contour, _ = cv2.findContours(template_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0] contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) valid_contours = [] shape_similarity_threshold = 0.3 # 值越小,形状越相似 for cnt in contours: similarity = cv2.matchShapes(cnt, template_contour, cv2.CONTOURS_MATCH_I1, 0.0) if similarity <= shape_similarity_threshold: valid_contours.append(cnt)
4. 利用分割模型的像素置信度过滤
如果你的分割模型输出包含像素级置信度图,可以通过目标区域的平均置信度判断:
- 步骤:
- 加载分割模型输出的置信度图(与掩码尺寸一致)
- 对每个目标轮廓区域,计算平均置信度
- 过滤平均置信度低于阈值的目标
内容的提问来源于stack exchange,提问作者Zee Jan
相关产品推荐
相关产品推荐

