[python opencv video抠图并更换背景]

完整实现

  • 可以对前景进行缩放

  • 可以对前景进行平移

python 复制代码
import cv2
import numpy as np


def adjust_img(img, position_params, size_rate):
    """调整图像
    必须先缩小-再平移

    :param img:
    :param position_params:
    :param size_rate:
    :return:
    """
    h, w = img.shape[:2]

    # 进行缩放
    new_size = [int(size_rate * h), int(size_rate * w)]
    img = cv2.resize(img, (new_size[1], new_size[0]))
    if w >= new_size[1]:
        pad_w = w - new_size[1]
        pad_h = h - new_size[0]
        top, bottom = pad_h // 2, pad_h - (pad_h // 2)
        left, right = pad_w // 2, pad_w - (pad_w // 2)
        img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT,
                                 None,
                                 (0, 0, 0))
    else:
        crop_w = (new_size[1] - w) // 2
        crop_h = (new_size[0] - h) // 2

        img = img[crop_h:crop_h + h, crop_w:crop_w + w]

    # 进行平移
    MAT = np.float32(
        [[1, 0, int(w * position_params[1])], [0, 1, int(h * position_params[0])]])  # 构造平移变换矩阵
    img = cv2.warpAffine(img, MAT, (w, h), borderValue=(0, 0, 0))  # 设置白色填充

    return img


def video_compositing(video_root, mask_root, output_path, background_root, position_params,
                      size_rate):
    """

    :param video_root:
    :param mask_root: mask path
    :param output_path: 输出位置
    :param background_root: 背景图像path
    :param position_params: [0.5, 0.5], [垂直,水平]控制人像在图像中的位置, 计算例如:水平移动像素数/水平像素总数
    :param size_rate: 控制缩放大小,1:原始大小
    :return:
    """

    video = cv2.VideoCapture(video_root)
    mask = cv2.VideoCapture(mask_root)

    if not video.isOpened():
        print(f"Failed to open video file: {video_root}")
        return

    if not mask.isOpened():
        print(f"Failed to open mask file: {mask_root}")
        return

    rval, frame = video.read()
    rval_mask, frame_mask = mask.read()

    fps = video.get(cv2.CAP_PROP_FPS)
    h, w = frame.shape[:2]

    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    video_writer = cv2.VideoWriter(output_path, fourcc, fps, (w, h))
    num_frame = video.get(cv2.CAP_PROP_FRAME_COUNT)

    # 是否加背景
    if background_root:
        background = cv2.imread(background_root)
        background = cv2.resize(background, (w, h))
    else:
        background = None

    for c in range(int(num_frame)):
        if (frame is None) or (frame_mask is None):
            continue

        # 计算前景
        foreground = frame * (frame_mask / 255)
        foreground = adjust_img(foreground, position_params, size_rate)

        # 是否加背景
        if background_root:
            frame_mask = adjust_img(frame_mask, position_params, size_rate)
            fg_com = foreground + background * (1 - frame_mask / 255)
        else:
            fg_com = foreground

        video_writer.write(fg_com.astype(np.uint8))
        rval, frame = video.read()
        rval_mask, frame_mask = mask.read()

    video_writer.release()

运行测试

python 复制代码
video_compositing(
    'data/video.mp4',
    'data/mask.mp4',
    'data/results.mp4',
    'data/img.jpg',
    position_params=[0., 0.3],  # 垂直,水平
    size_rate=1.8
)
相关推荐
飞翔的佩奇5 小时前
【完整源码+数据集+部署教程】【天线&水】舰船战舰检测与分类图像分割系统源码&数据集全套:改进yolo11-repvit
前端·python·yolo·计算机视觉·数据集·yolo11·舰船战舰检测与分类图像分割系统
木头左6 小时前
最大回撤约束下ETF多因子动态止盈参数校准方案
python
汤姆yu6 小时前
2026版基于python的协同过滤音乐推荐系统
开发语言·python
汤姆yu6 小时前
基于python的电子商务管理系统
开发语言·python
may_一一6 小时前
pycharm\python 安装下载
ide·python·pycharm
后台开发者Ethan6 小时前
FastAPI之 Python的类型提示
python·fastapi·ai编程
hello kitty w7 小时前
Python学习(11) ----- Python的泛型
windows·python·学习
没有梦想的咸鱼185-1037-16637 小时前
AI Agent结合机器学习与深度学习在全球气候变化驱动因素预测中的应用
人工智能·python·深度学习·机器学习·chatgpt·数据分析
周杰伦_Jay7 小时前
【MCP开发部署流程表格分析】MCP架构解析、开发流程、部署方案、安全性分析
人工智能·深度学习·opencv·机器学习·架构·transformer
测试19988 小时前
Selenium自动化测试+OCR-获取图片页面小说详解
自动化测试·软件测试·python·selenium·测试工具·ocr·测试用例