CrazyBingo

YUV YCbCr解码设计

0
阅读(5766)

YUV YCbCr解码设计

视频信号为YUV信号,同时,目前CMOS摄像头支持YUV信号和RGB565两种模式。只玩过RGB565,未免不太爽,不仅仅因为YUV是视频信号,而且,YUV对RGB很好的压缩。

wps_clip_image-28561

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

wps_clip_image-5246

wps_clip_image-15931

YUV

Y:亮度(16-235) U:色彩 V:饱和度

YUV有很多格式,比如4:2:2; 4:2:2; 4:2:0等,一般摄像头YUV422格式的数据模式。

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

当年的黑白电视,只有亮度,即Y;YUV格式的出现很好的兼容了不同制式的电视,因为YUV2RGB可以转换为彩色图像,这个YCbCr中讲过了。

当然以上不是我主要要讲的,这里,以OV7670视频数据为例,捕获YUV信号的捕获,最大限度的保持数据的同步,并且使得数据不丢失,设计了时序,请听Bingo一一道来:

首先,对于视频而言,所谓YUV信号就是YCbCr信号,想知道更多的孩纸请看http://www.fdworkshop.me/read.php?tid=37

wps_clip_image-18602

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

wps_clip_image-24276

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

由于时序的严格,为了有效的解码,可以通过如下步骤

(1)捕获Cb0,Y0

(2)捕获Cr0,Y1

(3)捕获Cb1,Y2,输出Y0Cb0Cr0

(4)捕获Cr1,Y3,输出Y1Cb0Cr0

相关代码如下所示:

//convert yuv422 to yuv444 reg [2:0] yuv_state; reg [7:0] mY0, mY1, mY2, mY3; reg [7:0] mCb0, mCb1; reg [7:0] mCr0, mCr1; always@(posedge clk or negedge rst_n) begin if(!rst_n) begin yuv_state <= 3'd0; {mY0, mCb0, mCr0} <= {8'h0, 8'h0, 8'h0}; mY1 <= 8'h0; {mY2, mCb1, mCr1} <= {8'h0, 8'h0, 8'h0}; mY3 <= 8'h0; {Y, Cb,Cr} <= {8'h0, 8'h0, 8'h0}; end else if(yuv_capture_en) //ahead 2 clock begin case(yuv_state) //{Cb,Y},{Cr,Y}---YCbCr 3'd0: begin yuv_state <= 3'd1; {mCb0, mY0} <= image_data; end //reg p0 3'd1: begin yuv_state <= 3'd2; {mCr0, mY1} <= image_data; end //reg p1 3'd2: begin yuv_state <= 3'd3; {mCb1, mY2} <= image_data; {Y, Cb, Cr} <= {mY0, mCb0, mCr0}; end //p0; reg p2 3'd3: begin yuv_state <= 3'd4; {mCr1, mY3} <= image_data; {Y, Cb, Cr} <= {mY1, mCb0, mCr0}; end //p1; reg p3 3'd4: begin yuv_state <= 3'd5; {mCb0, mY0} <= image_data; {Y, Cb, Cr} <= {mY2, mCb1, mCr1}; end //p2; reg p0 3'd5: begin yuv_state <= 3'd2; {mCr0, mY1} <= image_data; {Y, Cb, Cr} <= {mY3, mCb1, mCr1}; end //p3; reg p1 endcase end else begin yuv_state <= 3'd0; {mY0, mCb0, mCr0} <= {8'h0, 8'h0, 8'h0}; {mY1, mCb1, mCr1} <= {8'h0, 8'h0, 8'h0}; {Y, Cb,Cr} <= {8'h0, 8'h0, 8'h0}; end end

状态机如下所示:

wps_clip_image-22179

经过实验,OV7670---YCbCr422解码---YCbCr444--RGB565---VGA显示效果不错,验证了解码代码的准确性。

Baidu
map