yuv格式具有亮度信息和色彩信息分离的特点,但大多数图像处理操作都是基于rgb格式。
因此当要对图像进行后期处理显示时,需要把yuv格式转换成rgb格式。
rgb与yuv的变换公式如下:
yuv(256 级别) 可以从8位 rgb 直接计算:
y = 0.299 r + 0.587 g + 0.114 b
u = - 0.1687 r - 0.3313 g + 0.5 b + 128
v = 0.5 r - 0.4187 g - 0.0813 b + 128
反过来,rgb 也可以直接从yuv (256级别) 计算:
r = y + 1.402 (cr-128)
g = y - 0.34414 (cb-128) - 0.71414 (cr-128)
b = y + 1.772 (cb-128)
yuv格式比较多,下面以yv12格式为例,说明yv12格式转化成rgb24格式的方法。
其基本思路是按照rgb与yuv的变换公式进行逐像素的计算,但具体实现过程中,优化方法和技巧影响最终的转换效率。
说明:为了方便查看转换后的结果,在实现过程中,是bgr24格式代替rgb24格式,其转换过程是不变。
1. 基本实现
按照yuv与rgb的变换公式,逐像素访问y、u、v分量的值,并转换成rgb。
2. 基于查表法的实现
逐一访问像素,进行浮点运算,比较耗时,因而利用空间换时间思路,以查找表来替代转换过程中的一些计算。
优化过程可参考:
3. 基于opencv的实现
利用opencv提供的转换函数实现yuv到rgb的转换,实现简单方便。实现过程,只需要合理构造包含yuv数据的mat,具体实现方法如下。
4. 基于ffmpeg的实现
利用ffmpeg中swscale实现yuv到rgb的转换,实现过程中,需要构造avpicture结构,具体实现方法如下。
5. 基于pinknoise的实现
参考资料:
下载上述网站提供的yuv2rgb代码,利用yuv420_2_rgb888函数即可实现yuv到rgb的转换。
6. 转换效率分析
测试序列:1920*1080
测试环境:opencv2.4.8, ffmpeg2.0, yuv2rgb v0.03
method
time(ms)
yv12tobgr24_native
83.7263
yv12tobgr24_table
54.2376
yv12tobgr24_opencv
26.0529
yv12tobgr24_ffmpeg
3.41499
yv12tobgr24_pinknoise
14.1215
由上述表格可以看出,基于ffmpeg的格式转换效率最高,利用查找表法可以提高转换效率,但基于查找表法的转换效率有待进一步优化提升。
后续应关注于ffmpeg其格式转换的算法实现,抽取其实现代码,使格式转换不依赖于ffmpeg库。