网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
看一个视频就像是在快速地翻看图片,这也是使用python读取视频数据的方式。我们看到的每个"图片"都是视频的一个帧。在视频播放时,它是以每秒30帧的速度进行播放。
在视频数据中,每一帧都是一个巨大的数组。该数组通过指定数量的红、绿、蓝进行混合来告诉我们每个位置上每个像素的颜色。我们想看看视频中是否有多个帧出现了多次,有一个方法,就是计算我们看到的每一帧的次数。
我用两个字典类型的变量来进行计数。一个跟踪我已经看到的帧,另一个跟踪所有完全相同的帧。当我逐个浏览每一帧时,首先检查以前是否看过这一帧。如果没有,则把这一帧添加到我已看过的帧字典中(见下面的seenframes)。如果以前看过这一帧,则将它添加到另一个字典(dupframes)的列表中,这个字典包含了其他一模一样的帧。
代码如下:
这段代码在我的macbook pro上跑了大约一个小时。 我们来看看结果:
很好,结果看起来很直观,从下图中可以看出,帧5928与帧2048454相同,帧5936与帧2048462相同,以此类推。让我们目视确认。
完美。所以,这个视频肯定是伪造的。 然而,帧匹配的数量看起来实在太低了,值得怀疑啊。 真的只有25个相同的帧吗?在整整24小时的视频中这25帧的长度几乎不到1秒钟。我们来进一步看一下!
情况变复杂了
该程序的作用是确定相同的帧,这样我就能知道视频是在循环播放。让我们来看看上面两幅图像的后2秒的帧(帧5936 + 60和帧2048462 + 60)是什么样的。
等等…… 这两个图像看起来是一样的啊!但是他们为什么没有标记为匹配呢?我们可以把其中一个帧减去另外一个帧来找出不同之处。这个减法是对每个像素的红、绿、蓝的值分别做减法。
太好了,我们创造出了一个很酷的故障艺术!但是,实际上两个帧的差值仅仅是视频被压缩后的两个帧的差异。由于经过了压缩,原来相同的两个帧可能会受到噪音的影响而导致失真,从而在数值上不再一样(尽管它们在视觉上看起来是一样的)。
对上面的说明总结一下,当我将数据存储在字典中时,我取了每个图像的哈希。哈希函数将图像(数组)转换为整数。如果两个图像完全相同,则哈希函数将得到相同的整数。如果两个图像不同,我们将得到两个不同的整数。但是我们实际想要的是,如果两个图像只是稍微不同,我们然仍然能得到相同的整数。
简化我们的压缩问题
有几种不同的哈希算法,每种都有专门的使用场景。我们在这里将要看到的是感知哈希。与其他类型的哈希不同的是,对于靠近在一起的输入,它们的感知哈希值是相同的。反向图像搜索网站显然使用的是类似的技术,这些网站只是抓取他们遇到的网络和哈希图像。由于同一张图片在互联网上可能存在多种不同的分辨率和剪裁,所以检查其他具有相同哈希值的东西则更为方便。
然而,对于我们来说,又有新的麻烦了,因为我们处理的并不完全是图像,而是一系列的图像,每一张图片都是相差1/30秒。这意味着我们的哈希函数需要:
- 足够的宽松,两个仅因为压缩而产生噪声的帧的哈希值是相同的
- 足够的灵敏,两个相邻帧的哈希值是不同的 这可能很复杂。
均值哈希的参数选择
我要尝试使用的哈希算法称为均值哈希(aHash)。在网上能找到很多的信息,它的处理过程一般是这样的:降低图像分辨率,转换为灰度图,然后取哈希值。通过降低分辨率,我们可以消除噪声的影响。然而,我们冒着相邻帧可能会被标记为重复帧的风险,因为它们是相似的。通过调整分辨率可以稍稍解决这个问题。
下面,我分别以分辨率8x8和64x64显示均值哈希的结果。8x8看起来降采样的太多了,我们失去了太多的信息,似乎大多数图像看起来都是一样的了。对于64x64,它看起来和原来的图像没什么不同,两者之间可能没有足够大的区别来忽略压缩产生的噪声。
为了找到适合我们的分辨率,我试着在两段类似的视频中通过设置一系列不同的分辨率来寻找匹配项。返回的匹配项将出现在以下输出中:
- [8,108]
- [9,109]
- [10,11,110,111] 上述的解释是,第8帧和第108帧相同。第9帧和第109帧相同,但不同于8、108。第10、11、110、111帧与其他帧都不同,但彼此相同。这种情况很有可能发生,因为算法并不完美,偶尔也会混淆,认为两个相邻的帧是相同的。我们看看下面这几个数字:
- 有多少个匹配的桶?从上面可以看到,有3个。
- 每个桶中的平均帧数是多少?平均值为(2 + 2 + 4)/ 3 = 2.7。
- 所有桶中最多的帧是多少? 4。 这里的目标是获得大量的桶(第一个数字),并且每个桶内的帧数尽可能的少(平均或最差情况)。理论上来说,由于我正在看的这段视频有1个循环,所以每桶应该只有2帧。
好的,看起来64太极端了,我们几乎没有一个桶在这一点上。另一方面,在图形的左侧,桶的大小(Bucket Size)有一个爆炸点,其中所有的帧都被检测为重复的。这个爆炸点似乎是在20附近。从最大桶的大小(Max Bucket Size)那根曲线来看,20的那个数据点似乎有些奇怪。为了反驳这一段网上视频,我也只愿意做到这些了,那么,让我们一起去看看把分辨率设置为24后取哈希的情况吧。
最后
不知道你们用的什么环境,我一般都是用的Python3.6环境和pycharm解释器,没有软件,或者没有资料,没人解答问题,都可以免费领取(包括今天的代码),过几天我还会做个视频教程出来,有需要也可以领取~
给大家准备的学习资料包括但不限于:
Python 环境、pycharm编辑器/永久激活/翻译插件
python 零基础视频教程
Python 界面开发实战教程
Python 爬虫实战教程
Python 数据分析实战教程
python 游戏开发实战教程
Python 电子书100本
Python 学习路线规划
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
6d4c3ab8389e65ecb71ac0)**
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!