python实现抠出绿幕视频中的人物,合成到另一个背景视频中。

1 篇文章 0 订阅
1 篇文章 0 订阅

python实现抠出绿幕视频中的人物,合成到另一个背景视频中。要求是如果如果背景视频过短是,循环播放。
上python代码:

# -*- coding: utf-8 -*-
import numpy as np
import cv2
from moviepy.editor import VideoFileClip, concatenate_videoclips, CompositeVideoClip


def generate_mask(frame):
    frame_blurred = cv2.bilateralFilter(frame, d=9, sigmaColor=75, sigmaSpace=75)
    hsv = cv2.cvtColor(frame_blurred, cv2.COLOR_RGB2HSV)

    lower_green = np.array([40, 50, 50])
    upper_green = np.array([80, 255, 255])
    mask = cv2.inRange(hsv, lower_green, upper_green)
    mask_inv = cv2.bitwise_not(mask)

    #使用腐蚀和膨胀操作来清除噪点
    kernel = np.ones((3, 3), np.uint8)
    mask_inv = cv2.erode(mask_inv, kernel, iterations=1)
    mask_inv = cv2.dilate(mask_inv, kernel, iterations=1)

    #闭操作填充对象内细小空洞,开操作去除小对象
    mask_inv = cv2.morphologyEx(mask_inv, cv2.MORPH_CLOSE, kernel)
    mask_inv = cv2.morphologyEx(mask_inv, cv2.MORPH_OPEN, kernel)

    three_channel_mask = np.stack([mask_inv] * 3, axis=-1)
    return three_channel_mask


def simple_color_balance(frame, r_factor=0.95, g_factor=0.85, b_factor=0.95):
    frame_copy = frame.copy()
    #微调RGB各通道的系数可以更好地融合前景和背景
    frame_copy[:, :, 0] = np.clip(frame_copy[:, :, 0] * r_factor, 0, 255).astype(np.uint8)
    frame_copy[:, :, 1] = np.clip(frame_copy[:, :, 1] * g_factor, 0, 255).astype(np.uint8)
    frame_copy[:, :, 2] = np.clip(frame_copy[:, :, 2] * b_factor, 0, 255).astype(np.uint8)
    return frame_copy


def process_videos(foreground_video_path, background_video_path, output_video_path, output_size=(1080, 1920)):
    foreground_clip = VideoFileClip(foreground_video_path)
    background_clip = VideoFileClip(background_video_path).set_duration(foreground_clip.duration)
    num_loops = int(foreground_clip.duration / background_clip.duration + 1)
    background_clip = concatenate_videoclips([background_clip] * num_loops).subclip(0, foreground_clip.duration)
    background_clip = background_clip.resize(newsize=output_size)

    mask_clip = foreground_clip.fl_image(generate_mask).to_mask()
    masked_foreground = foreground_clip.set_mask(mask_clip).fl_image(simple_color_balance).resize(newsize=output_size)
    composite_clip = CompositeVideoClip([background_clip, masked_foreground], use_bgclip=True)
    composite_clip.set_duration(foreground_clip.duration).write_videofile(output_video_path, codec='libx264', fps=24)


# 调用函数开始处理视频 1.mov是绿幕视频,2.mp4背景视频,output.mp4输出合成视频
process_videos('F:\\shipin\\1.mov', 'F:\\shipin\\2.mp4', 'F:\\shipin\\output.mp4')

合成原理
在视频合成中,首先通过色键技术(绿幕技术)从前景视频中抠出主体。通过在HSV色彩空间中应用特定的色彩范围来生成一个掩模,这个掩模用于区分前景中的主体和背景。然后将主体与一个新的背景视频合成在一起。
最终的合成视频是通过将调整后的前景视频(已应用掩模和色彩平衡)放置在背景视频上形成的。使用MoviePy库中的CompositeVideoClip类来实现这一点,它允许你轻松地将多个视频层叠加在一起。

调整色键掩模参数
调整HSV阈值:
色键(Chroma Key)的HSV阈值对掩模的生成影响很大。调整这些阈值可以更精确地分离前景和背景,从而减少边缘的白点和亮点。
尝试缩小 lower_green 和 upper_green 之间的距离,使得绿色的选取更加严格。比如,可以尝试将 lower_green 改为 [45, 50, 50],upper_green 改为 [75, 255, 255]。
优化腐蚀和膨胀操作:
腐蚀(Erosion)可以帮助移除小白点,但如果过多可能会使前景边缘变得不平滑。
膨胀(Dilation)操作通常跟在腐蚀之后,用来恢复前景的形状,但过多的膨胀可能会引入额外的亮点。
可以尝试调整腐蚀和膨胀的迭代次数(iterations),或者更改核的大小(通过修改 kernel = np.ones((3, 3), np.uint8) 中的 (3, 3))。

调整色彩平衡参数
在 simple_color_balance 函数中,通过微调 r_factor, g_factor, b_factor 参数,可以帮助更好地融合前景和背景的色彩,减少因色彩不匹配产生的亮点。
小幅度调整这些因子,例如将 g_factor 从 0.90 调整到 0.85 或 0.95,观察效果。

这些是合成视频处理所需的Python库:
numpy 用于进行高效的数值计算。
cv2 (OpenCV) 提供强大的视频和图像处理功能。
moviepy 用于视频文件的读取、处理和合成。

以上代码改一下文件路径可以直接运行。有什么问题欢迎讨论学习。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值