FPGA图像处理之RGB转YCbCr算法实现

1. RGB模型介绍

所谓RGB模型,是认为人眼里有三种感光细胞,分别对应红色、绿色和蓝色最敏感。人眼之所以看到各种颜色的光,主要是这三种感光细胞感觉综合的结果,而红、绿、蓝被称为三原色。

2. YCbCr色域介绍

YCbCr在世界数字组织视频标准研制过程中,称为ITU - R BT.601 建议的一部分,其实是YUV经过缩放和偏移的翻版。YCbCr由Y(Luminance)、Cb(Chrominance-Blue)和Cr(Chrominance-Red)组成,其中Y表示颜色的明亮度和浓度,Cb和Cr则分别表示颜色的蓝色浓度偏移量和红色浓度偏移量。
YCbCr格式是一种数字信号,可以细分为两种格式: tv range格式与full range格式,主要区别如下。
1)tv range 格式
Y∈[16,235],Cb∈[16,240],Cr∈[16,240],主要是广播电视采用的数字标准。
2)full range 格式
Y、Cb、Cr∈[0,255],主要是PC端采用的标准,所以也称为pc range格式。

3. RGB与YCbCr转换公式

(1)对标准SDTV(标准清晰度电视),采用ITU - RBT.601数据格式,其中YCbCr为tv range格式,RGB与YCbCr的相互转换公式如下:

(2)(

\begin{vmatrix} Y\\ Cb\\ Cr \end{vmatrix}=\begin{bmatrix} 16\\ 128\\ 128 \end{bmatrix}+\begin{bmatrix} 0.257 &0.504 &0.098 \\ -0.148 &-0.291 &-0.439 \\ 0.439 &-0.368 & -0.071 \end{bmatrix} \begin{bmatrix} R\\ G\\ B \end{bmatrix}\begin{vmatrix} R\\ G\\ B \end{vmatrix}=\begin{bmatrix} 1.164 & 0.000 &1.596 \\ 1.164 & -0.392 & -0.813\\ 1.164 &2.017 & 0.000 \end{bmatrix}\begin{bmatrix} Y-16\\ Cb-128\\ Cr-128 \end{bmatrix}

(2)对full range 或者pc range 的YCbCr格式

\begin{vmatrix} Y\\ Cb\\ Cr \end{vmatrix}=\begin{bmatrix} 0\\ 128\\ 128 \end{bmatrix}+\begin{bmatrix} 0.299 &0.587&0.114 \\ -0.169 &-0.331&-0.500 \\ 0.500 &-0.419 & -0.081 \end{bmatrix} \begin{bmatrix} R\\ G\\ B \end{bmatrix}

\begin{vmatrix} R\\ G\\ B \end{vmatrix}=\begin{bmatrix} 1.000 & 0.000 &1.400 \\ 1.000 & -0.343 & -0.711\\ 1.000 &1.765 & 0.000 \end{bmatrix}\begin{bmatrix} Y\\ Cb-128\\ Cr-128 \end{bmatrix}

FPGA 硬件实现推导

原始公式如下:

Y0 = R*0.299 + G*0.578 + B*0.114

首先去掉浮点,把数值扩大256倍,公式如下(舍去小数点,不能四舍五入):

Y1 = R*76.544 + G*150.272+B*29.184 \approx R*76+G*150+B*29

再对上述结果右移8位,相当于除了256

Y2=(R*76+G*150+B*29)>>8

同上,推导Cb/Cr的计算公式如下:

Cb=(-R*43-G*84+B*128+32768)>>8

Cr=(R*128-G*107-B*20+32768)>>8

FPGA代码实现

module RGB888_YCbCr444(
	input clk,
	input rst_n,
	
	//Image data prepred to be processed
	input pre_img_vsync,    //Prepared Image data vsync valid signal
	input pre_img_href,     //Prepared Image data href valid signal
	input [7:0] per_img_red,   //Prepared Image red data to be processed
    input [7:0] per_img_green,   //Prepared Image green data to be processed
	input [7:0] per_img_blue,   //Prepared Image blue data to be processed
	
	//Image data has been processed
	output post_img_vsync,   //Processed Image data vsync valid signal
	output post_img_href,    //Processed Image data href valid signal
	output [7:0] post_img_Y,   //Processed Image brightness output
	output [7:0] post_img_Cb,   //Processed Image blue shading output
    output [7:0] post_img_Cr,   //Processed Image red shading output
	
	);
	reg [15:0] img_red_r0,img_red_r1,img_red_r2;
	reg [15:0] img_green_r0,img_green_r1,img_green_r2;
	reg [15:0] img_blue_r0,img_blue_r1,img_blue_r2;
	always@(posedge clk)begin
		img_red_r0 <= per_img_red * 8'd76;
		img_red_r1 <= per_img_red * 8'd43;
	    img_red_r2 <= per_img_red * 8'd128;
		img_green_r0 <= per_img_green * 8'd150;
		img_green_r1 <= per_img_green * 8'd84;
	    img_green_r2 <= per_img_green * 8'd107;
		img_blue_r0 <= per_img_blue * 8'd29;
		img_blue_r1 <= per_img_blue * 8'd128;
		img_blue_r2 <= per_img_blue * 8'd20;
	end
	
	reg [15:0] img_Y_r0;
	reg [15:0] img_Cb_r0;
	reg [15:0] img_Cr_r0;
	always@(posedge clk)begin
		img_Y_r0 <= img_red_r0 + img_green_r0 + img_blue_r0;
		img_Cb_r0 <= img_blue_r1 - img_red_r1 - img_green_r1 + 16'd32768;
		img_Cr_r0 <= img_red_r2 - img_green_r2 - img_blue_r2 + 16'd32768;
	end
	
	reg [7:0] img_Y_r1;
	reg [7:0] img_Cb_r1;
	reg [7:0] img_Cr_r1;
	always@(posedge clk)begin
		img_Y_r1 <= img_Y_r0[15:8];
		img_Cb_r1 <= img_Cb_r1[15:8];
		img_Cr_r1 <= img_Cr_r1[15:8];
	end
	
	reg [2:0] per_img_vsync_r;
	reg [2:0] per_img_href_r;
	always@(posedge clk)begin
		if(!rst_n)begin
			per_img_vsync_r <= 0;
			per_img_href_r <= 0;
		end
		else begin
			per_img_vsync_r <= {per_img_vsync_r[1:0],per_img_vsync};
			per_img_href_r <= {per_img_href_r[1:0],pre_img_href};
		end
	end
	
	assign post_img_vsync = per_img_vsync_r[2];
	assign post_img_href = per_img_href_r[2];
	assign post_img_Y = post_img_href ? img_Y_r1 : 8'd0;
	assign post_img_Cb = post_img_href ? img_Cb_r1 : 8'd0;
	assign post_img_Cr = post_img_href ? img_Cr_r1 : 8'd0;

endmodule

参考资料:基于MATLAB 与FPGA的图像处理教程 (韩彬)

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值