换背景有多方法,剪辑软件,深度学习模型等等。

这种方法可能是最简单快速的了,缺点是需要自己用取色器对视频的绿幕进行取色,然后多次尝试确定一个还可以的上下限,但是最终还是会有边缘效果一般的情况。

优点是速度快,比起基于深度学习的模型来说。

import cv2
import numpy as np

# 读取视频文件
cap = cv2.VideoCapture('a.mp4')

# 读取替换图像并调整尺寸
background = cv2.imread('bg.jpg')
if background.shape[:2] != (int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)), int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))):
    background = cv2.resize(background, (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))))

# 目标颜色的BGR范围(基于#25B77F,稍微扩展上下限)
lower_bound = (90, 140, 10)  # BGR 下限
upper_bound = (180, 210, 110)  # BGR 上限

# 定义缩放比例
scale_percent = 50  # 缩放到50%

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    # 提取绿幕部分
    green_mask = cv2.inRange(frame, lower_bound, upper_bound)

    # 生成反向掩码
    inverse_mask = cv2.bitwise_not(green_mask)

    # 使用掩码提取背景和原视频的不同部分
    foreground = cv2.bitwise_and(frame, frame, mask=inverse_mask)
    background_part = cv2.bitwise_and(background, background, mask=green_mask)

    # 合并两个部分
    combined = cv2.add(foreground, background_part)

    # 缩放合并后的图像
    width = int(combined.shape[1] * scale_percent / 100)
    height = int(combined.shape[0] * scale_percent / 100)
    resized_combined = cv2.resize(combined, (width, height))

    # 展示最终替换效果
    cv2.imshow('Replaced Video', resized_combined)

    # 按下空格暂停,按下'q'退出
    key = cv2.waitKey(1) & 0xFF
    if key == ord(' '):  # 空格暂停
        cv2.waitKey(0)
    elif key == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

image.png

需要用深度学习模型可以使用xy3xy3/video-background-removal: fork from https://huggingface.co/spaces/innova-ai/video-background-removal/tree/main

fork的hugging face项目,做了一些下载路径的修改

Last modification:November 10, 2024
如果觉得我的文章对你有用,请随意赞赏