美文网首页记录
如何用Python将电影做成笔记

如何用Python将电影做成笔记

作者: 慕长风啊 | 来源:发表于2020-02-09 14:13 被阅读0次

    前言

    这段时间疫情严重,在家就找些视频看,然后就发现了一部蛮有意思的纪录片——《生命·觉者》

    这是一部主持人和嘉宾问答过程中传递思想和观点的纪录片

    可能是因为做节目的关系,一些观点的表达方式容易引起争议,但是他们看待事物的角度和思想的高度令人叹服

    视频中的很多观点都发人深省,但我总觉得视频播放这种媒介形式对有深度的思想的传播不利,当我需要专注于讲话者的言语时,主持人的神情形态、视频的 BGM 和穿插的影视片段等等都是一种噪声

    要是能将讲话者的言谈记录下来整理成笔记,当作书本一样阅读就好了

    基于这一想法,又因该纪录片没有字幕文件,所以我就开始自己动手制作”笔记“

    视频下载

    视频我是 YouTube 上在线观看的,要做后期处理的话,首先要将视频下载下来

    一开始我选择了 pytube 这个第三方库,结果遇到了不少麻烦

    因为作者有几个月没有更新了,YouTube 的一些规则变化的很快,爬取过程会出现各种 BUG

    然后我就针对一个个 BUG 去改源码,修改的过程中虽然发现了有人在做同样的事并且推出了 pytube3,但是还需要进一步的修改

    为了避免重复造轮子,我最后尝试了下 youtube-dl,这是用 Python 写的一个命令行程序

    项目地址:

    https://github.com/ytdl-org/youtube-dl

    我本来不喜欢用这种写好的程序,印象中操作都太傻瓜化,总觉得灵活度会受到限制,但是接下来的使用感受却颠覆了我最初的想法

    image

    该程序的参数十分之多,可定制性非常高,基本上你能想到的问题都能在这些参数中找到

    比如说 -c 参数是开启断点续传功能,--yes-playlist 是下载整个播放列表的,-f best 默认下载最佳品质视频,-o 是对文件输出名做格式化,这些还是基本功能

    其他的一些参数,比如 --proxy 挂代理的作用我就不解释了,主要是 --socket-time 和 -R 参数,不知道是因为网络环境的问题还是 Youtube 的规则又发生了变化,每下载一条视频段,程序就会卡住,默认时间后会重试

    这里的 --socket-timeout 可以缩短延迟时间,加快下载速度, -R 参数控制重连次数,默认上限 10 次,改成"infinite"后去除上限

    差不多我想从源码处进行修改的点,参数上都提供了对应的接口,对开发人员十分友好

    通过上面的配置,这才解决了网络环境对 YouTube 视频下载的限制,然后用笔记本跑了一晚上将视频下载到磁盘

    image

    字幕提取

    下载完成后,就要开始对视频做字幕提取的工作了

    本次基于图像识别对视频所做的字幕提取工作都是通过 Python 的 OpenCV 库完成的

    比如初始化时对视频基本信息所做的读取工作:

    image

    该库的具体使用方法可参考:

    https://github.com/skvark/opencv-python

    首先要知道,视频由很多帧组成,比如下面演示中的视频的总帧数是 90986,帧率(fps)是 29.97,其数值等于该视频每秒连续出现多少帧

    现在的电影的帧率一般都大于 24fps,这时人眼观影时就会有流畅的感觉

    随便选取一帧如下:

    image

    然后用任意作图软件定位到字幕位置的 Y 轴坐标范围,这里我选取(325, 360),截取如下:

    image

    重复这一步骤就可以把每一帧图片中的字幕提取出来了

    但是接下来还有两个问题需要解决:

    1. 如何判断某一帧图像上是否有字幕?

    2. 如何判断这一帧同上一帧之间是否存在字幕切换?

    如果能解决以上问题,则可以:

    1. 遍历每一帧,去除无字幕图像

    2. 遍历过程中判断是否发生字幕切换,如果有则保留该图,否则去除

    综上所述,我们需要做一些简单的图像识别

    首先,要对图像做二值化处理,先得选取阈值(threshold)

    简单点可以自己赋值,黑色像素值是 0,白色像素值是 255,字幕通常是黑底白字,我们可以选个中间值 150

    image

    高级点的可以借助OTSU算法,来确定一个自适应的阈值

    image image

    但是部分处理结果会出现下面的情况:

    image

    所以最后我选择在OTSU算法的结果上加了个常量 15,用以消除未知的噪声

    image

    接下来,需要引进一个指标,来衡量图像相似度

    这里我选择用均方误差(MSE),计算两图像间对应位置像素点的平方误差之和的均值百分比:

    image

    比如取 b=0 时,上面第一张字幕图片与 0 值图像的误差 e 值计算为 3.128

    简单地归纳总结后发现:

    每张图像与 0 值图像的误差 e > 1时,有字幕;

    不同字幕图像的误差 e > 1时,发生字幕切换

    之后就可以遍历视频的每一帧并按以上步骤处理

    最后我将其中一部 50 分钟的视频浓缩成了一张 1M 大小的字幕长图

    image

    如果只想选取视频片段呢?

    那么首先要根据播放时间大致定位到是哪一帧

    image

    然后跳转到那一帧,再按上述步骤处理

    image

    文字识别

    最后一步就是将上面制作完成的字幕图片整理成文字了

    网上有各种OCR文字识别平台的接口可供调用,这里我以百度AI开放平台为例:

    image

    接口的具体调用方法可以参考官方文档,不过这里要注意下 image 参数的要求

    image

    而我最后生成的图像显然超过了要求数值

    image

    所以在合成字幕图像的时候要做个切割处理,不过每张图片集合的字幕数量不能简单的依据上面的 4096px 来计算,还要考虑到识别的准确度,单张图片集合字幕数量太多会造成识别出错

    然后我将 50 条字幕集成一张图片,一共生成 34 张图,每张图都可以准确识别出文字

    图像切割和生成的核心代码如下:

    image

    输出效果图:

    image

    单张图片OCR文字识别结果:

    image

    最后将识别结果整合一下

    image

    最后

    从上面的使用中,我感受到 Python 的 OpenCV 库确实十分强大

    其本身的定位是用于解决计算机视觉领域的问题,运用好不仅能完成视频字幕提取这种简单的任务,包括人脸识别运动检测等更广泛更实用的应用场景都能借助它来搞定

    尤其这几天大家都需要闭门不出,正好有时间来鼓捣鼓捣这些有意思的事情!

    本文首发于公众号: 慕长风的小酒馆

    相关文章

      网友评论

        本文标题:如何用Python将电影做成笔记

        本文链接:https://www.haomeiwen.com/subject/iyngxhtx.html