现在我们知道了模拟视频变换为数字视频流后的格式,也知道了怎样创建和保存BMP文件,但是我们还不能把从数字视频流中截取的图像数据保存为BMP文件,因为数字视频流是用YUV描述的,而BMP文件是用RGB描述的。它们之间怎么转换呢?这就是色彩空间转换的问题。
RGB和YUV的对应关系用代数方程式表示如下:
Y = 0.299R +
U = - 0.147R-
V = 0.615R -
或者:
R=Y+1.14V
B=Y+2.03U
G=Y-0.58V-0.39U
CCIR601标准中定义的值与上面略有不同。在考虑了人的视觉系统和CRT显示器的非线性特性之后,推荐的转换方程如下:
R = Y + 1.371 V
G = Y - 0.698 *V - 0.336 U
B = Y + 1.732 U
不过读者要注意,上面的方程中的UV值因为符号扩展的原因平移了128,实际应该使用下面的这个修正的方程:
R = Y + 1.371 * (V - 128)
G = Y - 0.698 * (V - 128) - 0.336 * (U - 128)
B = Y + 1.732 * (U - 128)
对于上面的方程有几点说明:1、有一些采集卡会指定U、V为有符号数或无符号数,使用上面的方程时不要考虑这些,而认为Y、U、V是从采集卡得到的一个0到255之间的无符号的值。2、用上面的公式计算出的R、G、B值可能会超出0到255的范围,应该在计算完后进行检查,如果值小于0,则修正为0,如果值大于255,则修正为255。上面的转换方法经过我的实际使用,证明其效果是良好的。
空谈了这么多,来点更直观的吧!我们来看看一帧实际的图像。右边这帧图像是用武汉万德数码技术有限公司生产的VC302嵌入式图像采集卡采得的,信号源是电视机的视频输出(为了减小文件大小,右边的图片被压缩了10倍,原始图像要比现在显示的更清晰)。图像的像素分辨率是320*240(采集了一场中的288行,每行360个像素,但只从中截取了240行,每行截取了320个像素),第一幅是Y分量描述出的黑白图像,第二幅是U分量描述,第三幅是V分量描述,第四幅是YUV合成后的彩色图像。黑白图像与如此模糊的UV分量图合成后竟然可以得到色彩这么真实的彩色图像,你是不是有点难以相信?我也不敢相信,但这就是事实!从这些图的比较中我们可以得出这样的结论:1、Y分量基本上保留了彩色图像的轮廓细节,其分辨率是较高的。2、UV分量主观感觉十分模糊,分辨率低,只是大约地描述了整块的色彩,这正是所谓的“大面积着色”。3、我们在观察合成的彩色图像的时候并没有觉得图像的色彩模糊,这说明人眼对色彩细节的分辨能力是多么差!
接着,我们来讨论一下图像的显示问题。这个问题属于软件的范畴,大部分读者都比较熟悉,我不准备说太多。一种方法是把得到的YUV数据转换成RGB后来显示。另一种办法是直接用YUV数据来显示,现在的显卡都具备把YUV数据通过硬件直接转换为RGB的能力,通过使用Direct Draw技术,把YUV数据直接提交给显卡,这样就省掉了软件转换所花费的CPU时间。在嵌入式领域,可以使用数字接口的液晶显示器显示,要根据其具体情况来处理。
最后,说一下视频开发中常见的一些问题。1、首先要注意区分视频信号的制式。我国的电视台发送的信号是PAL制信号,所以电视机的视频输出是PAL制。但是电视机也可以接受其它制式的信号,比如VCD机的视频输出有很多是NTSC制的,在电视机上也可以播放。在我国市场上销售的摄像机(我说的是工业摄像机,而不是家用的摄录像机)大部分是PAL制的,但也有的是NTSC制,而且有的可以通过机身上的拨码开关来设定制式。2、有些DVD机采用了一些特别的办法来提高清晰度,比如所谓的“逐行扫描”,它们输出的信号与标准信号相比有一些差别,在电视机上播放是不会有问题的,但是一些采集卡却不能识别,导致采集的图像紊乱,所以在调试过程中要慎用DVD作信号源。3、分辨率的问题。分辨率一般是指垂直方向能分辨的等间隔排列的黑白条纹的最大线数。我们先来看看模拟视频,视频信号行正程的时间是52μs,而视频信号的带宽最大6 MHz,假定1Hz可以描述2个像素点,这样算来最多的线数=52μ*