☞ ░ 前往老猿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. 快速傅里叶变换(FFT)学习笔记(其二)(NTT)

    再探快速傅里叶变换(FFT)学习笔记(其二)(NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其二)(NTT) 写在前面 一些约定 前置知识 同余类和剩余系 欧拉定理 阶 原根 求原根 NTT ...

  2. MarkdownPad 2中编辑

    一级标题 二级标题 三级标题 四级标题 五级标题 六级标题 #######七级标题 ########八级标题 #!/bin/bash declare -i evenSum=0 declare -i i ...

  3. Redis基础—了解Redis是如何做数据持久化的

    之前的文章介绍了Redis的简单数据结构的相关使用和底层原理,这篇文章我们就来聊一下Redis应该如何保证高可用. 数据持久化 我们知道虽然单机的Redis虽然性能十分的出色, 单机能够扛住10w的Q ...

  4. 使用flexbox的自适应照片布局

    作者:Tim Vam Damme 让我们来看看一种超轻量级的方法,它可以为一组任意大小的照片创建水平砖砌效果.将任何照片丢到上面,它们将边对边无缝对齐. 该解决方案不仅轻巧,而且非常简单.我们将使用无 ...

  5. 手写简易React-Fiber

    1.首先创建createElement函数 1 function createElement ( 2 type, 3 config, 4 ...children 5 ) { 6 7 const pro ...

  6. 1. 线性DP 53. 最大子序和.

    53. 最大子序和. https://leetcode-cn.com/problems/maximum-subarray/ func maxSubArray(nums []int) int { dp ...

  7. wireguard使用

    1.编译与安装 sudo apt-get install libmnl-dev libelf-dev linux-headers-$(uname -r) build-essential pkg-con ...

  8. iscsi客户端常用操作

    说明 本篇主要记录iscsi的客户端的一些常用的一些操作 iscsi服务端常用操作 删除一个lun tgtadm --lld iscsi --mode logicalunit --op delete ...

  9. 解决calamari无法获取节点信息的bug

    前言 一直在做calamari的相关的一些打包和安装的工作,都是业余弄的东西,所以并没有仔细的进行功能点的验证测试,正好ceph社区群里面有人问了个问题 calamari上是不是能看到ceph的ver ...

  10. Python_案例_斐波那契数

    方法一: 1 #!/usr/bin/python3 2 3 # Fibonacci series: 斐波纳契数列 4 # 两个元素的总和确定了下一个数 5 a, b = 0, 1 6 while b ...