You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 14:03:21