Python实现电视里5毛特效的方法

  介绍

这篇文章主要讲解了Python实现电视里5毛特效的方法,内容清晰明了,对此有兴趣的小伙伴可以学习一下,相信大家阅读完之后会有帮助。

前段时间接触了一个批量抠图的模型库,而后在一些视频中找到灵感,觉得应该可以通过抠图的方式,给视频换一个不同的场景,于是就有了今天的文章。

我们先看看能实现什么效果,先来个正常版的,先看看原场景:

 Python实现电视里5毛特效的方法

下面是我们切换场景后的样子:

 Python实现电视里5毛特效的方法

看起来效果还是不错的,有了这个我们就可以随意切换场景,坟头蹦迪不是梦。另外,我们再来看看另外一种效果,相比之下要狂放许多:

 Python实现电视里5毛特效的方法

我们都知道,视频是由一帧一帧的画面组成的,每一帧都是一张图片,我们要实现对视频的修改就需要对视频中每一帧画面进行修改。所以在最开始,我们需要获取视频每一帧画面。

在我们获取帧之后,需要抠取画面中的人物。

抠取人物之后,就需要读取我们的场景图片了,在上面的例子中背景都是静态的,所以我们只需要读取一次场景。在读取场景之后我们切换每一帧画面的场景,并写入新的视频。

这时候我们只是生成了一个视频,我们还需要添加音频。而音频就是我们的原视频中的音频,我们读取音频,并给新视频设置音频就好了。

具体步骤如下:

    <李>读取视频,获取每一帧画面李 <>李批量抠图 <李>读取场景图片 <李>对每一帧画面进行场景切换李 <>李写入视频李 <李>读取原视频的音频李 <>李给新视频设置音频李

因为上面的步骤还是比较耗时的,所以在视频完成后通过邮箱发送通知,告诉我视频制作完成。

我们需要使用到的模块主要有如下几个:

枕头   opencv   moviepy   paddlehub

我们都可以直接用脉冲安装:

 pip安装枕头
  pip安装opencv-python
  pip安装moviepy 

其中OpenCV有一些适配问题,建议选取3.0以上版本。

在我们使用paddlehub之前,我们需要安装paddlepaddle:具体安装步骤可以参见官网。用paddlehub抠图参考:别再自己抠图了,Python用5行代码实现批量抠图。我们这里直接用脉冲安装cpu版本的:

 #安装paddlepaddle
  python - m pip安装paddlepaddle——https://mirror.baidu.com/pypi/simple
  #安装paddlehub
  pip安装- https://mirror.baidu.com/pypi/simple paddlehub 

有了这些准备工作就可以开始我们功能的实现了。

我们导入如下包:

进口cv2 # opencv
  导入邮件#自定义包,用于发邮件
  导入数学
  进口numpy np
  从公益诉讼导入图像#枕头
  进口paddlehub作为中心
  从moviepy。编辑器进口* 

其中枕头和opencv导入的名称不太一样,还有就是我自定义的邮件模块。另外我们还要先准备一些路径:

 #当前项目根目录,系统自动获取当前目录
  BASE_DIR=os.path.abspath (os.path.join (os.path.dirname (__file__),“!”))
  #每一帧画面保存的地址
  frame_path=BASE_DIR + & # 39; \ \ \ \帧& # 39;
  #抠好的图片位置
  humanseg_path=BASE_DIR + & # 39; \ \ humanseg_output \ \ & # 39;
  #最终视频的保存路径
  output_video=BASE_DIR + & # 39; \ \ result.mp4& # 39; 

接下来我们按照上面说的步骤一个一个实现。

<强>(1)读取视频,获取每一帧画面

<强>在 OpenCV中提供了读取帧的函数,我们只需要使用VideoCapture类读取视频,然后调用读函数读取帧,读方法返回两个参数,ret为是否有下一帧,帧为当前帧的ndarray对象。完整代码如下:

 def getFrame (video_name save_path):
  “““
  读取视频将视频逐帧保存为图片,并返回视频的分辨率大小和帧率
  :param video_name:视频的名称
  :param save_path:保存的路径
  返回:fps帧率、大小分辨率
  “““
  #读取视频
  视频=cv2.VideoCapture (video_name)
  
  #获取视频帧率
  fps=video.get (cv2.CAP_PROP_FPS)
  #获取画面大小
  宽度=int (video.get (cv2.CAP_PROP_FRAME_WIDTH))
  身高=int (video.get (cv2.CAP_PROP_FRAME_HEIGHT))
  大?(宽度、高度)
  
  #获取帧数,用于给图片命名
  frame_num=str (video.get (7))
  name=int(数学。战俘(10,len (frame_num)))
  #读取帧,ret为是否还有下一帧,帧为当前帧的ndarray对象
  ret,?video.read ()
  而随著:
  cv2。imwrite (save_path + str(名称)+ & # 39;jpg # 39;,框架)
  ret,?video.read ()
  名称+=1
  video.release ()
  返回fps,大小

Python实现电视里5毛特效的方法