☞ ░ 前往老猿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. 视频直播源码开发中的流媒体协议:rtmp协议

    一.概念与摘要 视频直播源码的RTMP协议从属于应用层,被设计用来在适合的传输协议(如TCP)上复用和打包多媒体传输流(如音频.视频和互动内容).RTMP提供了一套全双工的可靠的多路复用消息服务,类似 ...

  2. Pycharm激活码,2020年9月29日最新激活码

    分享一个Pycharm激活码给大家: 5MJ8MJ2T1Q-eyJsaWNlbnNlSWQiOiI1TUo4TUoyVDFRIiwibGljZW5zZWVOYW1lIjoi6I635Y+W77yaIG ...

  3. ashx接收前台传来的数据

    前台js: $(function () { $.ajax({ url: "/TestAshx/GetJson.ashx", type: "post", data ...

  4. yum针对软件包操作的常用命令

    yum针对软件包操作的常用命令: 1.使用YUM查找软件包 命令:yum search php 2.列出所有可安装的软件包 命令:yum list php 3.列出所有可更新的软件包 命令:yum l ...

  5. Spider_知识目录_基础

    知识目录 静态网页抓取 Spider_基础总结1_Request(get/post__url传参_headers_timeout)+Reponse Spider_基础总结2_Requests异常 Sp ...

  6. 第05组 Alpha冲刺 (3/6)(组长)

    .th1 { font-family: 黑体; font-size: 25px; color: rgba(0, 0, 255, 1) } #ka { margin-top: 50px } .aaa11 ...

  7. 8.java设计模式之装饰者模式

    基本需求: 咖啡的种类有很多种,调料也有很多种,下单时,可以点单品咖啡也可以点单品咖啡+调料的组合,并计算下单时花费的金额 传统方式: 方式一 创建一个抽象类Drink,让所有的单品咖啡和组合咖啡都继 ...

  8. Linux下如何创建loop device

    在Linux中,有一种特殊的块设备叫loop device,这种loop device设备是通过映射操作系统上的正常的文件而形成的虚拟块设备 因为这种设备的存在,就为我们提供了一种创建一个存在于其他文 ...

  9. Flink处理函数实战之三:KeyedProcessFunction类

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  10. mysql之sql语句逻辑执行顺序

    1. (1)from先执行,from执行后就会将所有表(多个表时和单表所有的表)数据加载到内存中了 (2)ON执行,得到连接表用的连接条件. (3)JOIN执行,根据ON的连接条件,将from加载的所 ...