基于OpenCV实现人像前景轮廓检测、居中裁剪及背景替换方案咨询
基于OpenCV的竖版人像标准化处理方案
核心实现思路
- 采用预训练人像分割模型精准提取人像前景,替代传统背景检测方法,适配复杂背景场景
- 提取人像轮廓的 bounding box 计算中心位置,以此确定居中裁剪区域
- 通过掩码将人像与原图分离,合成到白色背景上完成标准化处理
完整代码实现
import cv2 import numpy as np def standardize_portrait(img_path, target_size=(512, 768)): # 读取输入图像 img = cv2.imread(img_path) if img is None: raise ValueError("无法读取目标图像文件") h, w = img.shape[:2] # 加载预训练人像分割模型(DeepLabv3+轻量版) # 需提前将模型配置和权重文件放在代码同目录下 model_cfg = "deeplabv3_mnv2_pascal_trainval.pbtxt" model_weights = "frozen_inference_graph.pb" net = cv2.dnn.readNetFromTensorflow(model_weights, model_cfg) # 预处理图像适配模型输入要求 blob = cv2.dnn.blobFromImage(img, 1.0, (512, 512), (127.5, 127.5, 127.5), swapRB=True, crop=False) net.setInput(blob) output = net.forward() # 生成人像掩码(Pascal VOC数据集类别15对应person) mask = output[0, :, :, 15] mask = cv2.resize(mask, (w, h)) mask = (mask > 0.5).astype(np.uint8) * 255 # 二值化掩码 # 提取人像轮廓并计算 bounding box contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not contours: raise ValueError("未检测到有效人像轮廓") largest_contour = max(contours, key=cv2.contourArea) x, y, bw, bh = cv2.boundingRect(largest_contour) # 计算居中裁剪区域 target_h, target_w = target_size # 人像中心坐标 person_center_x = x + bw // 2 person_center_y = y + bh // 2 # 确定裁剪区域左上角坐标,确保人像居中且不超出原图边界 crop_x = max(0, person_center_x - target_w // 2) crop_y = max(0, person_center_y - target_h // 2) # 修正裁剪区域右下角边界 crop_x_end = min(w, crop_x + target_w) crop_y_end = min(h, crop_y + target_h) # 若原图尺寸不足目标尺寸,调整边界保证人像居中 if crop_x_end - crop_x < target_w: crop_x = max(0, crop_x_end - target_w) if crop_y_end - crop_y < target_h: crop_y = max(0, crop_y_end - target_h) # 裁剪原图和掩码 cropped_img = img[crop_y:crop_y_end, crop_x:crop_x_end] cropped_mask = mask[crop_y:crop_y_end, crop_x:crop_x_end] # 合成白色背景的标准化人像 white_bg = np.full_like(cropped_img, (255, 255, 255), dtype=np.uint8) foreground = cv2.bitwise_and(cropped_img, cropped_img, mask=cropped_mask) background = cv2.bitwise_and(white_bg, white_bg, mask=~cropped_mask) result = cv2.bitwise_or(foreground, background) return result # 示例调用 standardized_img = standardize_portrait("user_photo.jpg", target_size=(512, 768)) cv2.imshow("标准化人像", standardized_img) cv2.imwrite("standardized_portrait.jpg", standardized_img) cv2.waitKey(0) cv2.destroyAllWindows()
关键细节说明
- 人像分割模型:选用DeepLabv3+轻量版模型,比传统背景减法(如MOG2)更精准,能有效处理复杂背景下的竖版人像提取
- 轮廓筛选:通过取面积最大的轮廓确保只保留主体人像,适配单人照片场景
- 居中逻辑:以人像中心为基准计算裁剪区域,即使人像位于画面左侧,也能自动调整至裁剪后画面的中心位置
- 背景替换:利用掩码的位运算实现人像与白色背景的无缝合成,避免边缘生硬问题
注意事项
- 需提前下载模型配置文件
deeplabv3_mnv2_pascal_trainval.pbtxt和权重文件frozen_inference_graph.pb,放置在代码同目录下 target_size可根据需求调整,常见竖版比例为3:4(如512x768)或1:1(如512x512)- 若输入图像存在多个人像,代码会自动选择面积最大的主体人像进行处理
内容的提问来源于stack exchange,提问作者Wizard.Ritvik
相关产品推荐
相关产品推荐

