☞ ░ 前往老猿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. Java_Stringbuilder和StringBuffer

    StringBuilder和StringBuffer非常类似, 均代表可变的字符串序列. 这两个类都是抽线类AbstractStringBuilder的子类, 方法几乎一样 /******String ...

  2. 常用简单电脑bai快捷键大全

    Ctrl+C 复制.duCtrl+X 剪切.Ctrl+V粘贴.Ctrl+Z撤销.Ctrl+A全选所有文件.zhiDelete删除.daoShift+Delete避开回收站直接永久删除(不可找回).F3 ...

  3. WSL-Ubuntu18.04 磁盘迁移 与 ns3-gym 安装

    WSL 安装 win10 版本应大于或等于 1903 win10 设置页面 输入 控制面板 并点击进入 找到 程序和功能 并打开 找到 启动或关闭 Windows 功能 并打开 向下拉 勾选 适用于L ...

  4. QQ群web前端分析三——pageSpeed

    使用pageSpeed插件,试试页面分析,看看有没有什么问题.等会上图 第一个问题,大部分人使用默认图片,但是这个图片的url确不一样,导致重复请求了若干次,这个...., 第二个问题,图片没有指定默 ...

  5. JS函数命名规范

    语法规范: 任何合法的javascript标识符都可以作为函数的名称. 约定俗成的内容:(非ECMAScript语法,但是为了便于开发者理解和识别,约定的函数命名规范.) 命名方法: 小驼峰式命名法 ...

  6. Java实现本地小数据量缓存尝试与实践&设计思考

    话不多说先贴代码 /** * 缓存工具 */ public class ConcurrentHashMapCacheUtils{ /** * 当前缓存个数 */ public static Integ ...

  7. [开源地址] 放弃Flink,.NET5.0开发CSharpFlink,简要设计、部署及二次开发说明。

    github地址:https://github.com/wxzz/CSharpFlinkgitee地址:https://gitee.com/wxzz/CSharpFlink 1 概述及背景 我们有一个 ...

  8. OpenCV之图像归一化(normalize)

    什么图像归一化 通俗地讲就是将矩阵的值通过某种方式变到某一个区间内 图像归一化的作用 目前能理解的就是归一化到某个区间便于处理,希望高人可以指点 opencv文档中的介绍 C++: void norm ...

  9. inotify+rsync实时同步备份nfs

    学习教程总结: 1.主机1:172.16.1.41,安装rsync并运行rsync --daemon 配置好/etc/rsyncd.conf 和密码文件rscync.password并设置chomd ...

  10. Docker 初始

    1. Docker 是什么? 官网的介绍是"Docker is the world's leading software container platform." 官方给Docke ...