视频处理加速及应用实践:基于英特尔GPU
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.5 常见视频图像处理算法

视频图像处理的对象主要是静态的视频图像数据,是完全意义上针对图像做的各种处理,其算法也是随着实际需求不断发展演进的,这里主要介绍Media SDK支持的主要功能,包括:去噪(denoise),颜色空间转换(Color Space Convert,CSC),去隔行(deinterlace),裁剪(crop),合成(composition),缩放(scale),调整帧率(frame rate conversion),反电视电影(inverse telecine),场交织(fields weaving),场分离(fields splitting),图像细节和边缘增强(picture details/edges enhancement),调整亮度(brightness)、对比度(contrast)、饱和度(saturation)、色调(hue),图像防抖(image stabilization),图像结构检测(picture structure detection)等。

1.5.1 去隔行扫描

隔行扫描视频存储以场为单位,所有的场都是按时间顺序排列的;而逐行扫描的视频的存储以帧为单位,同一帧的数据保存在一起。去隔行扫描是指找到一种方法来将场数据合并到帧数据的过程。

在图1-4中,左边的圆圈是图像线的“端视图”,相当于沿着二维平面的水平方向看过去。偏移显示了记录时的时差。这是顶场优先(Top Field First,TFF)的布局。底场优先(Bottom Field First,BFF)的布局也是类似的。基本上,隔行扫描意味着两个一半分辨率的帧会一起出现在屏幕上。当图像的运动不剧烈时,这是很好的,但运动发生时的捕捉时间差异会导致一种特征性的木梳齿效果,如图1-4右侧所示。

图1-4 隔行扫描帧和逐行扫描帧

对于追求效率的实现,Media SDK推荐使用线性去隔行扫描算法。而对于追求图像质量的实现,Media SDK推荐使用高级去隔行(Advanced DeInterlace,ADI)算法实现,因为它需要很多复杂的操作来保证图像的质量,甚至在某些情况下需要花费比编码更长的时间。本节的其余部分将重点介绍ADI。

ADI算法可以通过时域或者空域来实现:

时域去隔行(Temporal DeInterlace,TDI):用于运动场景变化不剧烈的区域。假设场之间的时间相关性很高,无须考虑运动向量,也就是说不需要通过插值奇偶场来得到融合的帧。

空域去隔行(Spatial DeInterlace,SDI):用于运动场景变化剧烈的区域。需要通过插值相邻场来得到融合后的帧数据,通常情况下,同一场时间邻域内的场数据的权值更高。

那么,如何判断一个区域的运行是否剧烈呢?要实现这个目的,就需要对运行进行量化,在实际的执行中,主要通过时空运动度量(Spatial-Temporal Motion Measure,STMM)来实现。如果此度量显示当前像素周围的区域几乎没有运动,则通过对时域上的前一个和后一个字段的像素值求平均值来填充缺失的像素,同理可用于某行的重构;如果STMM显示存在运动,则通过从空域上相邻的像素插值来填充缺失的像素,同理可用于某行的重构。TDI和SDI的结果可以按照某个比例进行混合来得到最终的STMM的结果,这样可以防止TDI和SDI模式之间突然转换。MBAFF(MacroBlock-Adaptive Frame-Field,宏块自适应帧场),对编码对象为帧的图片使用宏块对结构,允许16×16个宏块处于场模式,与MPEG-2相比,在编码对象为帧的图片中,场模式的处理导致了要处理16×8个半宏块。PAFF或PicAFF(Picture-Adaptive Frame-Field,图像自适应帧场)允许图片自由选择编码为完整的帧,还是其中两个场组合在一起进行编码,或者作为单独的场进行编码。

1.5.2 帧率转换

帧率是视频播放过程中一个常用的参数,表示每秒播放的帧数,以“fps(frames per second)为单位。为了流畅地播放视频,解码视频的速度一定要大于播放的速度,这样才不会造成卡顿、模糊等不好的观看体验。同时,不同的播放设备对帧率有不同的要求,例如NTSC使用29.97fps,PAL是25fps,为了让不同的视频源数据能够在不同的设备上播放,帧率转换就非常必要了。

帧率转换的核心思想就是添加或删除帧,以便以新的帧率覆盖相同的时间轴。当输入帧率和输出帧率是整数倍关系的时候,这就很简单了,例如:

50fps到25fps:每隔一帧丢掉一帧,输出帧计数为原始帧数的1/2。

25fps到50fps:在每帧之后插入一个新帧,因此输出帧数为原始帧数的2倍。

然而,对于一个通用的解决方案,就必须基于输入视频帧率和输出视频帧率的关系进行算法设计。例如,当将60fps转换为50fps时,每6帧将被丢掉一帧,剩下5帧。有一些特殊情况,例如,如果VPP被初始化为以29.97(NTSC)的输入帧率和23.976(胶片/DVD/蓝光)的输出帧率执行逐行扫描,则使用逆电视电影算法。

1.5.3 电视电影刷新率转换

telecine这个概念是为在标准视频设备中看电影而引入的,这个单词由电视(television)和电影(cinema)结合而成。传统电影的帧率为24fps,也叫作FLM24格式,而电视的帧率为25fps(PAL)或者30fps(NTSC),如果简单地在电视设备上直接播放电影的话,画面就会出现抖动,为了避免这种现象,就需要在播放过程中适当加入一些帧或者场,这个过程就叫作telecine。从24fps转到30fps,正好是4帧到5帧的转换,也就是说,每4场会增加1场,例如,原始序列为T0B0 T1B1 T2B2 T3B3,做了转换后的序列为T0B0 T0B1 T1B2 T2B2 T3B3。还有一种FLM30格式,这种电影在拍摄时就是按30fps采样的,在NTSC电视上播放时不需要增加帧,而只是简单地将帧转换成场进行播放即可。

反电视电影刷新率转换过程是电视电影刷新率转换过程的逆过程,为什么要做反电视电影(inverse telecine)呢?很多NTSC流是从FLM24的源通过4帧到5帧转换得来的,用于电视播放。但现在的电视不像以前的电视,除了隔行扫描(interlace)模式外,还有逐行扫描(progressive)模式,也就是说,需要做去隔行处理。通常的去隔行算法都是考虑正常的T0B0、T0B1的输入的,如果出现了上面所说的T1B2这样的输入,则必然削弱去隔行算法的效果,于是反电视电影的处理就出现了。因此反电视电影处理一般包含两部分内容:电视电影的探测和重组帧。电视电影的探测指的是通过顶场和底场的校验,检测当前的帧率是不是从4帧到5帧转变过来的,因为如果是转变过来的,就会出现“底场 顶场 顶场 顶场底场(底 顶 顶 顶 底)”这样的场排列,也就是说2个底场中间夹着3个顶场的数据。如果不是转变过来的,而是原始的视频序列,也就是说顶场和底场交替出现,那么就没有必要做反电视电影的处理了。当检测到是什么样的序列之后,重组帧的操作就变得简单了,对于前一种情况,把插入的那一场去掉就好,对于后一种情况就直接略过,不需要做任何处理。

1.5.4 缩放

缩放(scaling)是最常用的视频图像处理算法之一,一般包括裁剪(cropping)、尺寸调整(resizing)、拉伸(stretching)等操作。要执行裁剪操作,请使用CropX、CropY、CropW和CropH参数定义感兴趣的区域(Region Of Interest,ROI)。同时可以在ROI的上、下、左、右通过填充一些黑色的像素来达到裁剪的目的。同时,裁剪的功能和保持纵横比(aspect ratio)的功能可以联合使用,既裁剪了图像,又保持了裁剪后图像的纵横比。经过上述裁剪后的图像如图1-5所示。

图1-5 裁剪示意图

英特尔集成显卡支持两种类型的图像缩放算法:双线性(bilinear)法和高级视频缩放器(Advanced Video Scaler,AVS)法。这两种算法最关键的不同点是怎样处理像素插值。线性插值是根据两个点的值来估计两点之间的线上某个位置的点的值,即根据这个点和两个点的位置的线性距离进行线性插值。双线性图像缩放是使用基于周围像素的插值技术来产生更平滑的缩放,它只用到周围的4(2×2)个点。而AVS比双线性图像缩放用到了更多的相邻点(8×8)。表1-1是两种缩放算法特点的对比。

表1-1 双线性法和AVS法对比