换背景有多方法,剪辑软件,深度学习模型等等。
这种方法可能是最简单快速的了,缺点是需要自己用取色器对视频的绿幕进行取色,然后多次尝试确定一个还可以的上下限,但是最终还是会有边缘效果一般的情况。
优点是速度快,比起基于深度学习的模型来说。
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()
需要用深度学习模型可以使用xy3xy3/video-background-removal: fork from https://huggingface.co/spaces/innova-ai/video-background-removal/tree/main
fork的hugging face项目,做了一些下载路径的修改