opencv:视频去黑暗(增强)

         之前一篇博客写过一个关于图像去黑暗的算法(点击打开 图像去黑暗 ),它是一个去雾算法的延伸。最近学习了一些视频的基本知识,想把这个继续延伸到视频邻域。思路基本一样,先对视频解码为帧,然后在对每一帧图像进行去黑暗,最后在编码输出到文件夹。

    1、使用opencv对视频编解码

      正版视频编解码处理是使用ffmpeg处理完成,由于对ffmpeg掌握不熟悉,在对opencv进一步了解之后(见 参考文献 1、2、3),发现opencv提供了VideoCapture和VideoWriter来完成一个简单的视频编解码过程,虽然 相比于ffmpeg叫不上专业,但是对一些简单应用也能够满足要求。PSopencv提供的VideoWriter只能够输出avi格式,且编码器样式也很少,只有H264等几种常见的。所以用opencv处理视频确实算不上专业。

   

   2、针对视频的算法优化

        由于是处理视频,如果想要实时输出结果(为了实现连续性,帧率必须要在20fps或更高),必须要加快单帧处理速度。整个图像去黑暗算法中最为熬时间的步骤是求取透射率T的值。这里主要从两方面来优化算法:1、简化原有算法  2、增加新的加速运算的算法。

       1)原有算法简化

            为了平衡速度与效果,首先把图像去黑暗算法中关于导向滤波的算法砍掉,只使用暗原色先验来求透射率t(x),在求解暗原色图像的一个公式如下:


由公式可以看到 这里面除了求取R G B三通道最小值,还有一部区域最小值滤波,为了加速算法,这里经过实验省去最小值滤波步骤,直接用R G B三通道最小值作为暗原色图。


      2)算法加速

        因为在时间轴上相邻视频帧之间是具有极大的相关性的,没有必要去求取每一帧的透射率,所以这里借鉴的视频中基于块的帧间预测编码的相关知识。首先将视频划分为多个GOP(group of picture),每个GOP有一个关键帧(I帧),该帧是通过暗原色图来求取t值。而GOP的其他帧(称为P帧)的透射率则以关键帧的透射率来预测估计得到。投射率的预估准则是比较I帧和P帧对应像素点的差值,如果插值小于给定阈值 则直接沿用I帧的透射率,如果大于给定阈值,则重新计算对应位置的透射率。为了加快这一预估速度,将每一帧又化为为若干个大小为M*N(一般 M=N=16)的宏块.计算I帧和P帧对应宏块的SAD(Sum of Absolute Differences ).。 

        如果计算SAD时候每个宏块的每个像素点都用到,将也是一个很大的计算量,为了加快SAD的计算速度,对每一个宏块进行采样,由采样值来计算SAD值。采样方式如下图所示:


   只将宏块中标为蓝色区域的像素拿来计算SAD值。该过程被称为fast SAD算法。


  3、问题

       1、经过简化后的算法,确实处理速度加快,例如 处理一张 540*360的图像,从原来的1秒左右变为0.06秒左右。但是这个速度是任然达不到每秒20帧的水平。PS:个人感觉已经不可以在简化了,这里猜测可能用纯c的代码来写,速度才可能有进一步提升吧。

       2、增加的加速算法没有起到很好的加速效果,在测试过程中 一张540*360的图像有600多个宏块,在经过SAD过滤之后,需要重新计算投射率的宏块平均下来,降低到200~300个,减少一半多,但是由于计算SAD也需要消耗一部分时间,最后综合起来P帧的处理速度基本没太大变化。


      参考文献:

1、opencv3 读取视频

2、VideoCapture类

3、videoWroter类



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章