基于时空滤波和运动自适应的视频的去隔行算法

💡 本工程由贾天保、陈璐、魏群弢与2023年12月共同开发并于Dec 22, 2023首次发布

GitHub链接

EddieTyrael/Interlaced-to-Progressive (github.com)

CSDN链接

基于时空滤波和运动自适应的视频的去隔行算法

问题背景

在模拟电视时期,由于人眼视觉特性、带宽限制以及CRT显示器的特性,电视系统全部采用隔行扫描的方式进行传输和显示。而在LCD显示器推出和电视系统数字化之后,由于隔行扫描仍让能够大大节约带宽,因此隔行扫描的方式在当时仍然被很多标准采纳。但隔行扫描有其明显的缺点:

  1. 闪烁(flicker)。行间闪烁主要和细小的水平边缘有关,即图像中一条沿着水平方向的边,如门窗的上下边。因为隔行信号的特性,一个精细的水平边缘只能在相邻的两场中的一场显示,而在另一场中就消失了,这样这个精细的水平边缘就相当于以帧频(30Hz或者25Hz)在进行显示。观察者可以明显的觉察到这种异常的显示而如果这种边缘有垂直运动的话,这种闪烁也会随着垂直运动而移动,严重影响了观看体验。
  2. 锯齿(jaggies)。锯齿现象是隔行信号显示的一个普遍的现象,主要出现在静止或运动物体的对角线斜边处。对于静止或运动较少的图像,较低的垂直分辨率会引起台阶效应。当图像包含运动时,情况就变得更糟糕了。隔行图像的边缘每场只有一半的行数进行更新,这
    样就导致损失了边缘的细节。进一步,当边缘运动起来之后,下一场的边缘就会出现相对的位移,锯齿装的边缘就这样从一场运动到下一场,产生连续的锯齿现象。
  3. 爬行(crawling)。爬行是一种隔行信号产生的虚像,它主要出现在没有运动和较少细节的图像中。当观察者离显示设备比较近的时候,这种现象更为明显。因为每条隔行扫描线每帧只更新一次,人眼有时会盯住一组扫描线。在下一场,新的扫描线会出现在旧的扫描线之间,看起来好像原来的那组扫描线向上或向下移动到了一个新的位置上。再下一场,这一组扫描线又出现在原来的位置。最终的观看效果就是一组扫描线快速的向上或向下移动,从而引起爬行现象。
  4. 羽化(feather)。通常会出现在运动物体的轮廓处,主要是由于运动检测失误导致的。当运动的物体被误判断为静止,为了复原静止图像就会采用场间插值处理,那么在运动物体的轮廓边缘处,两个存在相对位移图像直接拼合,将导致图像出现虚影。

为了克服隔行扫描的诸多缺点,电视系统在带宽和处理能力允许之后就逐渐走向了逐行扫描的方式。但在这段过渡期,有诸多素材仍是隔行扫描的方式,因此在逐行扫描的系统中使用这些隔行扫描的素材便成为必须,也就催生出了本工程的基本应用场景。

功能概述

本工程使用滤波的方法实现了隔行视频的逐行化。输入以及输出均采用不带有辅助信息的纯YUV数据描述的视频(图像序列),可以使用附带的YUVViewerPlus打开并查看相应文件。

算法理论

去隔行插值技术的主要思想是利用时域和空域中的临近像素点对待处理像素点进行估算。本工程中采用了线性插值和运动自适应两种方法,具体如下。

  1. 线性方法
    1. 空间插值
    2. 时间插值
    3. 时空混合插值
  2. 运动自适应方法

空间插值(场内插值):

采用行平均法,根据上下行采样点数据的平均计算该未知采样点。

等效滤波器:

h ( m , n ) = { 7 16 , ( m , n ) = ( 1 , 0 ) , ( − 1 , 0 ) 1 16 , ( m , n ) = ( 3 , 0 ) , ( − 3 , 0 ) 0 , o t h e r w i s e h(m,n)=\left\{ \begin{array}{lr} \frac{7}{16}, & (m,n)=(1,0),(-1,0)\\\\ \frac{1}{16}, & (m,n)=(3,0),(-3,0)\\\\ 0, & otherwise\end{array} \right. h(m,n)= 167,161,0,(m,n)=(1,0),(1,0)(m,n)=(3,0),(3,0)otherwise

时间插值(场间插值):

采用场平均法,使用对称结构的滤波器,这种方法利用前后两场对应行的平均值来计算当前场
的数据。

等效滤波器:

h ( m , n ) = { 1 2 , ( m , n ) = ( 0 , 1 ) , ( 0 , − 1 ) 0 , o t h e r w i s e h(m,n)=\left\{ \begin{array}{lr} \frac{1}{2}, & (m,n)=(0,1),(0,-1)\\\\ 0, & otherwise\end{array} \right. h(m,n)= 21,0,(m,n)=(0,1),(0,1)otherwise

时空混合插值:

结合时间域和空间域(垂直)插值两者的优点,同时使用垂直滤波器和时间滤波器。本工程采用十字滤波法,使用上、下行和前、后场数据的平均值进行计算。

等效滤波器:

h ( m , n ) = { 1 4 , ( m , n ) = ( 0 , 1 ) , ( 0 , − 1 ) , ( 1 , 0 ) , ( − 1 , 0 ) 0 , o t h e r w i s e h(m,n)=\left\{ \begin{array}{lr} \frac{1}{4}, & (m,n)=(0,1),(0,-1),(1,0),(-1,0)\\\\ 0, & otherwise\end{array} \right. h(m,n)= 41,0,(m,n)=(0,1),(0,1),(1,0),(1,0)otherwise

运动自适应方法:

运动自适应方法的基本思想是将图像的去隔行处理分为针对运动图像针对静止图像的处理。 对于静止的图像采用时间域插值可以较好的还原逐行图像。对于运动的图像,前、后场的信息就不足以
用于估计当前场的数据,应该只采用当前场数据本身的数据在空间域内进行计算以避免出现严重的羽化现象。

启动示例

💡 工具链:Cmake → MSVC++

C++ Version 11

项目名称:final

项目文件编码:utf-8

  1. 安装MSVC++或GNU C++(MinGW)编译器。
  2. 使用CLion, Visual Stuio或Xcode加载CMake工程并运行即可。目录中将会生成四种算法对应的输出图像,无需额外配置。

💡 函数说明及参数说明详见代码

定制化运行:

在main.hpp中修改以下参数:

  • Height:待处理视频画幅高度(单位:像素)
  • Width:待处理视频画幅宽度(单位:像素)
  • filePath:待处理视频文件路径(格式:字符串)

重新运行CMake应用即可。

开发总结

本次开发涉及了多人合作的程序开发,是对三人协作能力的一次考验。在任务中需要灵活而精准地分配任务、核对任务进度,才能尽可能地提高效率。同时需要对代码有充分的重构和补充描述,以提高代码的可读性和规范性。

  • 26
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值