☞ ░ 前往老猿Python博文目录

一、引言

在moviepy官网的案例《Tracking and blurring someone’s face》和CSDN的moviepy大神ucsheep《MoviePy - 中文文档4-MoviePy实战案例-追踪人脸,打马赛克》都提供了追踪人脸并给影片中卓别林脸部打马赛克的样例,二者代码完全相同。

但老猿按照同样的方法实现却报ImportError错:

from moviepy.video.tools.tracking import manual_tracking, to_fxfy
ImportError: cannot import name 'to_fxfy' from 'moviepy.video.tools.tracking' (C:\Program Files\Python37\lib\site-packages\moviepy\video\tools\tracking.py)

查看tracking .py的源码,确实没有 to_fxfy方法。

为了解决该问题,老猿到处查找该问题相关资料,在ucsheep大神的QQ群内进行了咨询,并在moviepy的github项目中进行了咨询。ucsheep大神可能太忙,没有就该问题进行答复,而moviepy开源项目负责人之一tburrows13是这样答复的:

"Indeed the examples for some of these advanced tools are out of date or nonexistent (#850, #167). I'm expecting to update them soon.
In the meantime, have a look at #1061 or consider the documentation: https://zulko.github.io/moviepy/ref/videotools.html#module-moviepy.video.tools.tracking which looks like it is more up-to-date."

参考了 1061相关答复,试了下还是报错:ValueError: assignment destination is read-only

没办法,老猿只好阅读源代码,反复进行测试,循序渐进,曲折前进,最后实现了三种不同方式的人脸追踪打马赛克,下面就为大家介绍第一种解决思路。

二、背景知识

2.1、headblur简介

追踪人脸打马赛克需要使用headblur函数。

调用语法:

headblur(clip,fx,fy,r_zone,r_blur=None)

说明:

其中参数fx和fy是两个函数,该函数带参数t,用于确认t时刻需要模糊化范围的中心点位置,moviepy将对以中心点为圆心半径r_zone的圆范围内的图像进行模糊化处理,模糊化处理时的卷积核大小由r_blur指定。关于r_blur参数的作用请大家参考《moviepy音视频剪辑:headblur的参数r_blur卷积核的功能作用及用途》。

2.2、manual_tracking简介

manual_tracking是moviepy的工具模块moviepy.video.tools.tracking提供的函数,该模块还提供了autoTrack函数和findAround,其中findAround是供manual_tracking和autoTrack使用,autoTrack是根据匹配模式自动选择跟踪对象,后面再介绍。manual_tracking用于手工选择要跟踪的位置。

调用语法:

manual_tracking(clip, t1=None, t2=None, fps=None, nobjects = 1, savefile = None)

说明:
  • t1、t2:用于指定需要进行跟踪的剪辑位置范围,如果t2为None,则只跟踪t1位置的帧,如果t1、t2都为None则跟踪整个剪辑
  • fps:该参数不是剪辑本身的fps,而是跟踪时剪辑的以秒为单位的时间范围内需要显示的帧数,即在跟踪时,每秒的时间长度范围内需要抽取fps参数设定的帧数图像来显示,如t1和t2定义的剪辑跟踪长度为30秒,fps设置为2,则跟踪时moviepy会从剪辑中每秒抽取2帧显示,跟踪者需要对60帧图像标记跟踪位置
  • nobjects :每帧中需要跟踪位置的个数,缺省为1,当需要跟踪多个对象时设置为实际跟踪对象的个数
  • savefile :跟踪数据需要写入文件时由该参数指定保存文件的名称,可以带路径。

manual_tracking会根据参数 t1、t2以及fps和nobjects 设定,将剪辑 t1到t2位置的子剪辑逐帧显示出来,让操作者通过鼠标点击跟踪对象如人脸的中心,manual_tracking记下点击位置的xy坐标和对应剪辑的位置t,直到该时间段内所有帧都会,返回值为一个Trajectory对象组成的列表,列表元素的个数为nobjects参数的值指定。

三、实现自己的fx、fy方法

从headblur的参数介绍可以获知,fx、fy是返回二者参数t所在剪辑位置的跟踪点坐标,因此老猿按照这个目标来实现了这2个函数,由于跟踪点的手工跟踪一般不会设置fps很大,如设置为2,因此实际手工跟踪的帧的数量远少于实际数量,因此这个函数需要确保没跟踪的帧在fx、fy函数中也能返回对应坐标,老猿的处理很简单粗暴,对这种帧就返回距其最近的跟踪帧的坐标。

3.1、实现代码:
if __name__ == '__main__':
def main():
movie_in = sys.argv[1] #参数指定的视频文件名
if len(sys.argv) == 3: #是否指定了只加载视频的前n秒,n为浮点数
subclip_s = float(sys.argv[2])
else:
subclip_s = None clip = VideoFileClip(movie_in)
if subclip_s is not None:
clip = clip.subclip(0, subclip_s) tracking = moviepy.video.tools.tracking.manual_tracking(clip, fps=2)[0] #取返回的第一个跟踪对象,实际上nobjects使用的是默认值1,因此也就一个跟踪对象
trackingInf = list(zip(tracking.tt, tracking.xx, tracking.yy)) #将跟踪点相关的时间、横坐标信息、纵坐标保存到列表trackingInf,即列表中每个元素为元组,该元组为(t,x,y)形式 #定义fx和fy函数:
def fx(t):
nonlocal trackingInf
t1 = t2 = None
for tc in trackingInf:
if t == tc[0]: #t即为跟踪的帧
return tc[1]
elif t > tc[0]: #记录t前面最近的跟踪帧
t1 = tc
else:#找到t之后最近的跟踪帧
if t1: #前面有跟踪帧
d1 = t - t1[0]
d2 = tc[0] - t
d = min(d1, d2)
return t1[1] if d == d1 else tc[1]
else: #t应该至少前面有个跟踪帧、后面也有个跟踪帧,否则为异常数据
return 0 return tc[1] #返回x坐标 def fy(t):
nonlocal trackingInf
t1 = t2 = None
for tc in trackingInf:
if t == tc[0]:
return tc[2]
elif t > tc[0]:
t1 = tc
else:
if t1:
d1 = t - t1[0]
d2 = tc[0] - t
d = min(d1, d2)
if d > 0.5: return 0
return t1[2] if d == d1 else tc[2]
else:
return 0 return tc[2]#返回y坐标 clip_blurred = clip.fx(vfx.headblur, fx, fy, 30) #进行模糊化处理,圆半径设置为30像素
clip_blurred.write_videofile(movie_in + '_blurred_me.mp4', bitrate="3000k") #输出文件 main()

3.2、执行效果

启动参数设置为F:\video\zbl1.mp4 54,对应视频为卓别林《淘金记》,加载视频的前4秒,跟踪设置为整个剪辑跟踪,fps为2,因此需要选择8个帧的跟踪数据。最终输出后的视频动画:



总体效果看起来还不错,就是当头部动作幅度比较大时有少许帧会遮不住。

四、小结

上面介绍了老猿结合manual_tracking使用headblur实现跟踪人脸打马赛克的过程,但这种方法其实是最笨的方法,上面的代码虽然达到了想要的效果,但一点也不Pythonic,老猿也非常不满意,但实现这个方法的同时,老猿想到了更好的办法,在付费专栏的文章《moviepy音视频剪辑:追踪人脸打马赛克的三种实现方式》介绍了另外两种更好的方法。同时在付费专栏《moviepy音视频剪辑:使用autoTrack、manual_tracking+headblur实现半自动追踪人脸打马赛克

》介绍了结合autoTrack的半自动跟踪实现方案和案例。

更多moviepy的介绍请参考《PyQt+moviepy音视频剪辑实战文章目录》或《moviepy音视频开发专栏》。

关于收费专栏

老猿的付费专栏《使用PyQt开发图形界面Python应用》专门介绍基于Python的PyQt图形界面开发基础教程,付费专栏《moviepy音视频开发专栏》详细介绍moviepy音视频剪辑合成处理的类相关方法及使用相关方法进行相关剪辑合成场景的处理,两个专栏加起来只需要19.9元,都适合有一定Python基础但无相关专利知识的小白读者学习。这2个收费专栏都有对应免费专栏,只是收费专栏的文章介绍更具体、内容更深入、案例更多。

收费专栏文章目录:《moviepy音视频开发专栏文章目录》、《使用PyQt开发图形界面Python应用专栏目录》,本文收费专栏对应文章为《moviepy音视频剪辑:追踪人脸打马赛克的三种实现方式》、《moviepy音视频剪辑:视频半自动追踪人脸打马赛克》、《Python+moviepy使用manual_tracking和headblur函数10行代码实现视频人脸追踪打马赛克》。

对于缺乏Python基础的同仁,可以通过老猿的免费专栏《专栏:Python基础教程目录》从零开始学习Python。

如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。

附:下面的二维码和连接提供了老猿使用的《淘金记》的视频片段及打马赛克后的视频

链接:https://pan.baidu.com/s/1Ka6Zl3dR15FNkireBPmDGw

提取码:5udf

跟老猿学Python、学5G!

☞ ░ 前往老猿Python博文目录

moviepy1.03音视频剪辑:使用manual_tracking和headblur实现追踪人脸打马赛克的更多相关文章

  1. moviepy音视频剪辑:使用autoTrack、manual_tracking+headblur实现半自动追踪人脸打马赛克

    一.引言 在<moviepy1.03音视频剪辑:使用manual_tracking和headblur实现追踪人脸打马赛克>介绍了使用手动跟踪跟踪人脸移动轨迹和使用headblur对人脸进行 ...

  2. moviepy音视频剪辑:视频半自动追踪人脸打马赛克

    一.引言 在<moviepy1.03音视频剪辑:使用manual_tracking和headblur实现追踪人脸打马赛克>介绍了使用手动跟踪跟踪人脸移动轨迹和使用headblur对人脸进行 ...

  3. moviepy音视频剪辑:视频变换处理与内容相关的变换函数headblur、mask_and/or、mirror_x/y、rotate、painting、scroll介绍

    一.引言 在<moviepy音视频剪辑:moviepy中的剪辑基类Clip详解>介绍了剪辑基类的fl.fl_time.fx方法,在<moviepy音视频剪辑:视频剪辑基类VideoC ...

  4. PyQt+moviepy音视频剪辑实战文章目录

    ☞ ░ 前往老猿Python博文目录 ░ 本专栏为moviepy音视频剪辑合成相关内容介绍的免费专栏,对应的收费专栏为<moviepy音视频开发专栏>. 一.moviepy基础能力系统介绍 ...

  5. Python音视频剪辑库MoviePy1.0.3中文教程导览及可执行工具下载

    ☞ ░ 前往老猿Python博文目录 ░ 一.简介 MoviePy是一个用于视频编辑的Python模块,可用于进行视频的基本操作(如剪切.拼接.标题插入).视频合成(也称非线性编辑).视频处理或创建高 ...

  6. moviepy音视频剪辑:headblur函数遇到的ValueError assignment destination is read-only问题及解决办法

    ☞ ░ 前往老猿Python博文目录 ░ 一.运行环境 运行环境如下: python版本:3.7 opencv-python版本:4.2.0.34 numpy版本:1.19.0 二.错误案例代码及报错 ...

  7. moviepy音视频剪辑:headblur函数遇到的TypeError: integer argument expected, got float错误的解决方案

    运行环境如下: python版本:3.7 opencv-python版本:4.2.0.34 numpy版本:1.19.0 错误信息: 在调用moviepy1.03版本的headblur函数执行人脸跟踪 ...

  8. moviepy音视频剪辑:headblur的参数r_blur卷积核以及fx、fy、r_zone的功能作用及用途

    ☞ ░ 前往老猿Python博文目录 ░ 在moviepy1.03版本中,headblur的调用语法为:headblurbak(clip,fx,fy,r_zone,r_blur=None) 其中参数f ...

  9. 在Python中使用moviepy进行音视频剪辑混音合成时输出文件无声音问题

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 在使用moviepy进行音视频剪辑时发现输出成功但 ...

随机推荐

  1. springcloud-zinpin的安装与使用

    springcloud-zipkin的安装与使用 1.什么是zipkin 一个分布式系统的调用跟踪监控系统,把每次微服务调用都埋上点,打印固定格式的日志,然后收集到zipkin中,然后zipkin做数 ...

  2. css 兼容性总结

    1.就是ie6双倍边距的问题,在使用了float的情况下,不管是向左还是向右都会出现双倍,最简单的解决方法就是用display:inline;加到css里面去. 2.文字本身的大小不兼容.同样是fon ...

  3. Ubuntu 18.04 Tomcat 安装及配置

    转载自:https://blog.csdn.net/weixx3/article/details/80808484 1.下载Tomcat 8.5.31到Apache Tomcat官网,选择tar.gz ...

  4. Docker - 解决容器内获取的时间和主机的时间不一样的问题

    问题背景 分别在容器和主机下执行 date 命令 可以看到,时间是完全不一样的 解决方案 在运行容器时,挂载 /etc/localtime  目录 docker run -d -v /etc/loca ...

  5. 没有真实串口设备时使用"虚拟串口驱动"调试你的串口代码

    目录 前言 示例代码 总结 前言 很多时候需要编写串口代码,但是又没有真实串口设备来调试代码.以及本身就是要操作2个串口的情况,可以使用"虚拟串口驱动"工具方便的调试代码. 使用方 ...

  6. HTTP 抓包 ---复习一下

    1.connection 字段 2.accept 字段 3.user-agent 字段 4.host字段 等字段需要注意: HTTP事务的延时主要有以下:1).解析时延   DNS解析与DNS缓存 客 ...

  7. linux文件的3个时间和7种文件类型

    linux文件的三个时间:  atime: access time --最近访问时间. ctime: change time --最近改变时间. mtime:modify time --最近修改时间. ...

  8. C/C++编程日记:逻辑井字棋(圈叉)(用空格初始化)

    问题描述: 3*3的棋盘中,只要一条线上出现三个一样的棋子就获胜(玩家或电脑):如果棋盘已经放满还未出现三个棋子一条线则打成平手. 具体细节: 初始化棋盘(用空格初始化)     //初始化棋盘 vo ...

  9. 光棍节程序员闯关秀writeup

    答题链接https://1111.segmentfault.com/ 第一关 首先当然是右键查看源码啊 点击链接进入下一关 第二关 还是老样子,右键查看源码 这个key是要放在URL链接里敲回车的 第 ...

  10. 面试官:连Spring AOP都说不明白,自己走还是我送你?

    前言 因为假期原因,有一段时间没给大家更新了!和大家说个事吧,放假的时候一位粉丝和我说了下自己的被虐经历,在假期前他去某互联网公司面试,结果直接被人家面试官Spring AOP三连问给问的一脸懵逼!其 ...