CrazyBingo

Chapter 05: OV7670 YUV视频解码

0
阅读(11181)

Chapter 05: OV7670 YUV视频解码

wps_clip_image-13941

wps_clip_image-16672

1. 写在前面的话

时间是2012年7月13号,19:48,我的脑子一直处在兴奋状态,有太多的东西得记下来,我的大脑处于亢奋状态。每次脑袋剧烈运动,都感到阵阵酸痛……可是这件事情既然开始了,就一发而不可收拾。不管有没有价值,还是继续吧,省得脑袋内存泄露……

Chapter 04中讲到了RGB565视频信号的采样,这样开始讲YUV信号的采样,以及解码等设计思路。

2. ITU-R BT.656 格式简说

ITU-R BT.601和ITU-R BT.656是国际电信联盟(International Telecommunication Union)无线通信部门(ITU-R)制定的标准。严格来说,ITU-R BT.656应该是隶属ITU-R BT.601的一个子协议。ITU-R BT.601是演播室数字电视编码参数标准,而ITU-R BT.656 则是ITU-R BT.601附件A中的数字接口标准,用于主要数字视频设备(包括芯片)之间采用27Mhzs并口或243Mbs串行接口的数字传输接口标准。

详细的说明可以见Bingo博文:

http://www.cnblogs.com/crazybingo/archive/2011/03/27/1996974.html

由于ITU-R BT.656视频信号为YUV信号,同时,目前CMOS摄像头支持YUV信号和RGB565两种模式。只玩过RGB565,未免不太爽,不仅仅因为YUV解码之后效果会更好,而且,YUV对视频信号的了解,很有好处。

YUV信号的提出,是因为国际上出现彩色电视,为了兼容黑白电视的信号而设计的,其由于视频码率,压缩,兼容性的优势,一直被沿用至今。如下是YUV4:2:2的视频格式数据流:

wps_clip_image-15778

对于视频信号而言,还存在帧头帧尾,FF0000XY。因为传统的电视是隔行扫描的,通过此序列的采样,能够有效地捕获信号。OV7670摄像头YUV模式下输出的输出帧头帧尾如下图所示:

wps_clip_image-32012

wps_clip_image-25204

帧头,帧尾的设定,主要是为了有小区分奇场,偶场的视频流。因为传统PAL是隔行扫描的。

关于ITU-R BT.656想了解更多透彻的只是,介意去看看《视频技术手册-第五版》一书。

3. YUV格式简说

YUV由Y、U、V复合而成,其中Y:亮度(16-235) ,U:色彩 V:饱和度。YUV有很多格式,比如4:2:2; 4:2:2; 4:2:0等,一般摄像头YUV422格式的数据模式。如下图所示:

wps_clip_image-16375

YUV422模式即水平方向上UV的采样速度为Y的一半,相当于每两个点采样一个U,V,每一个点采样一个Y。这样被允许的原因是因为,我们的眼睛对亮度的敏感度远大于对色度的敏感度,因此可以通过牺牲色度的采样率来达到图像数据压缩的目的。

当年的黑白电视,只有亮度,即Y;YUV格式的出现很好的兼容了不同制式的电视,因为YUV既能兼容灰度信号,又能通过YUV2RGB可以转换为彩色图像,兼容彩色液晶。不明白的孩子,可以直接让{R,G,B}={Y,Y,Y},看看是不是黑白灰度的图像。

YUV主要应用在模拟系统中,而YCbCr是通过YUV信号的发展,通过了校正,主要应用在数字视频中的一种格式,一般意义上YCBCr即为YUV信号,没有严格的划分。CbCr分别为蓝色色差、红色色差,详细的说明请看Bingo博文,这里不是重点。

http://www.cnblogs.com/crazybingo/archive/2012/06/07/2540595.html

4. YCbCr视频流接受

其实,以上都不是本文的重点,这里,以OV7670视频数据为例,捕获YCbCr信号的捕获,最大限度的保持数据的同步,确保数据不丢失,设计思路,时序,电路,请听Bingo一一道来!

对于OV7670而言,YUV下的视频流,只是纯粹的YCbCr信号,而不是所谓奇场、偶场的ITU-R BT.656格式,因此在数据流上,RGB565与YCbCr是数据总量完全相同,所以完全可以按照前篇中的视频接收方法,直接缓存与SDRAM中。唯一的RGB565不同的地方就是,从SDRAM中读取之后,需要经过YCbCr4:2:2→YCbCr4:4:4→RGB888(RGB565)才能正常显示。因此,通过这两个步骤去阐述吧。

4.1. YCbCr422转YCbCr444

wps_clip_image-21543

还是上面那幅图示,标准的视频的YCbCr信号,以Cb0 Y0 Cr0 Y1 Cb1 Y2 Cr1 Y3………当然通过合并8bit到16bit(为了存储,16bit)后,数据变成了{Cb0Y0} {Cr0Y1} {Cb1Y2} {Cr1Y3}………

wps_clip_image-20379

如上是某公司的解码代码如上所示,CbCr与对应的Y肯定错位了,只是肉眼看不到;但是,既然我们知道问题,我们也能改进,为什么不严谨一点呢??

为了保持数据上的同步,同时又不能丢失任何一个Byte,重新组合出一幅完整的YCbCr的图像,我们需要将所谓的YCbCr4:2:2转换为YCbCr4:4:4,即每一个像素都有完整的亮度色差!但这需要几级寄存,加上数据的拼接,同步设计。由于时序的严格,为了有效的解码,可以通过如下步骤的序列,来完成!如此,既保证了数据的同步,不至于色差的错位,同时又有效的拼接了数据,有利于保存。

① 捕获Cb0,Y0

② 捕获Cr0,Y1

③ 捕获Cb1,Y2,输出Y0Cb0Cr0

④ 捕获Cr1,Y3,输出Y1Cb0Cr0

相关Verilog的设计如下图所示:

wps_clip_image-15015

经过测试,木有问题。

4.2. YCbCr444转RGB565

YCbCr转RGB888,有这么一个公式,如下:

R = 1.164(Y-16) + 1.596(Cr-128)

G = 1.164(Y-16) - 0.813(Cr-128) - 0.391(Cb-128)

B = 1.164(Y-16) + 2.018(Cb-128)

纠结啊,你们软件设计的,且不管效率如何,可以直接用浮点运算,来实现YCbCr2RGB。可是,可是FPGA是0和1的世界,不可以的你懂得。怎么办办呢,只能和进行放大,然后用乘法器或者。。。。

我就不喜欢用乘法器,CPLD怎么办啊!!!有完美主义的我选择了移位去实现,倾听彬哥一一分解:

1) 首先,分离变量法,谁都学过吧

R = 1.164Y + 1.596Cr - 222.912
G = 1.164Y - 0.391Cb - 0.813Cr + 135.488
B = 1.164Y + 2.018Cb - 276.928

2) 然后进行放大,加上移位,去掉可恶的浮点

XOUT[19:0] = ((Y*10'd596) + (Cr*10'd817) - 18'd114131)>>9;

YOUT[19:0] = ((Y*10'd596) - (Cb*10'd200) - (Cr*10'd416) + 18'd69370)>>9;

ZOUT[19:0] = ((Y*10'd596) + (Cb*11'd1033) - 18'd141787)>>9;

3) 最后,到这一步,用FPGA的话,可以用乘法器去实现了。可是CPLD呢?所以我不能像某公司的开发板例程那样用MUX,我还是想继续,完美是没有极限的,如下:

XOUT = (((Y<<9)+(Y<<6)+(Y<<4)+(Y<<2)) + ((Cr<<9)+(Cr<<8)+(Cr<<5)+(Cr<<4)+Cr) - 18'd114131)>>9;

YOUT = (((Y<<9)+(Y<<6)+(Y<<4)+(Y<<2)) - ((Cb<<7)+(Cb<<6)+(Cb<<3)) - ((Cr<<8)+(Cr<<7)+(Cr<<5)) + 18'd69370)>>9;

ZOUT = (((Y<<9)+(Y<<6)+(Y<<4)+(Y<<2)) + ((Cb<<10)+(Cb<<3)+Cb) - 18'd141787)>>9;

4) 最后一步,这是C语言也得操作的部分,乘除法出现的溢出,我们要截断,如下截断正负溢出的部分,使得数据保持在0-255以内。如下:

R <= XOUT[10] ? 8'h0 : (XOUT[8:0] > 9'd255) ? 8'hff : XOUT[7:0];

G <= YOUT[10] ? 8'h0 : (YOUT[8:0] > 9'd255) ? 8'hff : YOUT[7:0];

B <= ZOUT[10] ? 8'h0 : (ZOUT[8:0] > 9'd255) ? 8'hff : ZOUT[7:0];

5) 由于硬件原因,RGB888转换为RGB565,这个不多说了。。。

在Quartus中综合编译,发现用流水线+移位操作实现YUV2RGB(能达到80M),远比用乘法器(只能50M)速度要快,当然在一定范围内,两者都可以。当然我还是没满足,继续分布运算,同步逻辑,硬是活生生的将速度提升了上去。最后,移位转换RTL如下所示:

wps_clip_image-4346

整个系统。整体设计,数据流如下图所示,聪明的你应该知道视频如何存储,解码了吧……

wps_clip_image-30858

其实这一节没有什么重要的东西,无非就是算法啦,就看你愿不愿意去发挥了。算法的重要性,以至于她在视频图像处理领域,有着德高望重的地位。有一位高人写过一篇我看了好多遍,越看越有价值的文章,强烈推介你看一下,请自行下载:http://www.chinaaet.com/lib/detail.aspx?id=89943

算法的东西太重要了,不管是视频编解码,还是图像去噪,滤波等等算法,都将是视频图像处理的精髓,这些接口,都是一件衣服罢了……

Baidu
map