如何用Python为感兴趣区域(ROI)中的对象添加非矩形边框?
实现目标对象的非矩形分割边框效果
问题说明
现有一段Python代码,可从文件夹读取图片,通过ROI工具裁剪感兴趣区域,再使用rembg库去除背景。需求是为处理后的目标对象添加类似图像分割效果的非矩形边框,同时保留对象原有色彩与完整性。
实现思路
- 提取rembg处理后图像的alpha通道掩码:利用透明通道确定目标对象的轮廓范围
- 轮廓检测:通过OpenCV的轮廓提取函数获取目标的边缘轮廓
- 绘制非矩形边框:基于检测到的轮廓,使用自定义样式(如粗边框、虚线边框)绘制非矩形边框
- 边框与原图像叠加:将绘制好的边框合并到去除背景后的图像上,保留原色彩
修改后的完整代码
import cv2 import numpy as np import os from rembg import remove # 配置路径 input_folder = "待处理图片文件夹路径" output_folder = "处理后图片保存路径" count = 1 def image_resize(image, width=None, height=None, inter=cv2.INTER_AREA): dim = None (h, w) = image.shape[:2] if width is None and height is None: return image if width is None: r = height / float(h) dim = (int(w * r), height) else: r = width / float(w) dim = (width, int(h * r)) resized = cv2.resize(image, dim, interpolation=inter) return resized def add_segmentation_border(transparent_img, border_color=(0, 255, 0), border_thickness=3, is_dashed=False): # 分离alpha通道作为掩码 b, g, r, alpha = cv2.split(transparent_img) # 对掩码进行二值化,确保轮廓检测准确 _, mask = cv2.threshold(alpha, 1, 255, cv2.THRESH_BINARY) # 提取轮廓 contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 创建用于绘制边框的画布 border_img = transparent_img.copy() if is_dashed: # 绘制虚线边框 for cnt in contours: cv2.polylines(border_img, [cnt], isClosed=True, color=border_color, thickness=border_thickness, lineType=cv2.LINE_AA, shift=0, gapSize=5) else: # 绘制实线粗边框 cv2.drawContours(border_img, contours, -1, border_color, border_thickness, cv2.LINE_AA) return border_img # 遍历处理文件夹内图片 for filename in os.listdir(input_folder): img = cv2.imread(os.path.join(input_folder, filename)) if img is not None: # 统一调整图片高度 img = image_resize(img, height=600) # 选择ROI区域 roi = cv2.selectROI(img) print(f"选中ROI坐标:{roi}") # 裁剪ROI区域 im_cropped = img[int(roi[1]):int(roi[1]+roi[3]), int(roi[0]):int(roi[0]+roi[2])] # 去除背景 rembg_result = remove(im_cropped) # 注意:rembg返回的是带alpha通道的4通道图像,需确保是numpy数组格式 # 添加分割边框 bordered_img = add_segmentation_border(rembg_result, border_color=(0, 255, 0), border_thickness=4, is_dashed=False) # 显示结果 cv2.imshow("带分割边框的结果", bordered_img) # 保存结果(用PNG保留透明通道) save_path = os.path.join(output_folder, f"{count}.png") cv2.imwrite(save_path, bordered_img) count += 1 cv2.waitKey(0) cv2.destroyAllWindows()
关键代码说明
add_segmentation_border函数:核心功能实现,负责提取轮廓并绘制边框- 从4通道图像中分离alpha通道生成掩码,确保只检测目标对象的轮廓
- 支持实线边框和虚线边框两种样式,可通过
is_dashed参数切换 - 可自定义边框颜色(
border_color)和厚度(border_thickness)
- 保存格式改为PNG:JPG不支持透明通道,用PNG能完整保留去除背景后的透明效果
内容的提问来源于stack exchange,提问作者Atharav Jadhav
相关产品推荐
相关产品推荐

