RGB---YCbCr图像转换------图像处理

RGB—YCbCr图像转换------图像处理

介绍

通过MATLAB把RGB888的图像转换为RGB332的图像数据,然后通过MATLAB保存到TXT文本当中(因为332格数据为8bit正好一个字节,串口正好一次发送一个像素点,怎么转换之前写过 哈哈)。然后通过将RGB332转换为RGB565格式数据存入到SDRAM中,然后通过VGA驱动模块读出数据进行RGB—YCbCr图像转换最后通过VGA显示,需要注意的是在RGB—YCbCr图像转换过程中有数据计算需要打拍同步行场信号。

整体流程

首先通过串口接收端接收上位机发送的640 *480大小的图片数据,然后存入到SDRAM中,通过VGA驱动模块读取数据,然后进行RGB—YCbCr图像转换,最后通过VGA显示。具体RTL视图如下所示。
在这里插入图片描述

RGB—YCbCr图像转换原理

RGB—YCbCr图像转换公式如下所示。

 Y  = 0.299R +0.587G + 0.114B
 Cb = 0.568(B-Y) + 128 = -0.172R-0.339G + 0.511B + 128
 CR = 0.713(R-Y) + 128 = 0.511R-0.428G -0.083B + 128

因为FPGA不能进行浮点数运算所以将上式中带有小数部分扩大256倍然后再右移8bit,如下式所示

 Y  = (77 *R    +    150*G    +    29 *B)>>8
 Cb = (-43*R    -    85 *G    +    128*B)>>8 + 128
 Cr = (128*R    -    107*G    -    21 *B)>>8 + 128

为防止负数出现把128加入到括号内,如下式所示。

 Y  = (77 *R    +    150*G    +    29 *B        )>>8
 Cb = (-43*R    -    85 *G    +    128*B + 32768)>>8
 Cr = (128*R    -    107*G    -    21 *B + 32768)>>8

具体步骤

步骤(1)

因为RGB—YCbCr图像转换过程中数据都是以8bit位宽进行的,所以现将RGB565数据转换成RGB888格式数据,代码如下所示。

//RGB565 to RGB 888
assign rgb888_r         = {img_red  , img_red[4:2]  };
assign rgb888_g         = {img_green, img_green[5:4]};
assign rgb888_b         = {img_blue , img_blue[4:2] };

步骤(2)

进行公式中的全部相乘操作代码如下所示

always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        rgb_r_m0 <= 16'd0;
        rgb_r_m1 <= 16'd0;
        rgb_r_m2 <= 16'd0;
        rgb_g_m0 <= 16'd0;
        rgb_g_m1 <= 16'd0;
        rgb_g_m2 <= 16'd0;
        rgb_b_m0 <= 16'd0;
        rgb_b_m1 <= 16'd0;
        rgb_b_m2 <= 16'd0;
    end
    else begin
        rgb_r_m0 <= rgb888_r * 8'd77 ;
        rgb_r_m1 <= rgb888_r * 8'd43 ;
        rgb_r_m2 <= rgb888_r * 8'd128;
        rgb_g_m0 <= rgb888_g * 8'd150;
        rgb_g_m1 <= rgb888_g * 8'd85 ;
        rgb_g_m2 <= rgb888_g * 8'd107;
        rgb_b_m0 <= rgb888_b * 8'd29 ;
        rgb_b_m1 <= rgb888_b * 8'd128;
        rgb_b_m2 <= rgb888_b * 8'd21 ;
    end
end

步骤(3)

进行公示中的全部相加操作代码如下所示

always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        img_y0  <= 16'd0;
        img_cb0 <= 16'd0;
        img_cr0 <= 16'd0;
    end
    else begin
        img_y0  <= rgb_r_m0 + rgb_g_m0 + rgb_b_m0;
        img_cb0 <= rgb_b_m1 - rgb_r_m1 - rgb_g_m1 + 16'd32768;
        img_cr0 <= rgb_r_m2 - rgb_g_m2 - rgb_b_m2 + 16'd32768;
    end

end

步骤(4)

进行公示中的移位操作代码如下所示

always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        img_y1  <= 8'd0;
        img_cb1 <= 8'd0;
        img_cr1 <= 8'd0;
    end
    else begin
        img_y1  <= img_y0  >> 8;
        img_cb1 <= img_cb0 >> 8;
        img_cr1 <= img_cr0 >> 8;
    end
end

步骤(5)

打三拍进行行场同步代码如下所示

always@(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        pre_frame_vsync_d <= 3'd0;
        pre_frame_hsync_d <= 3'd0;
        pre_frame_de_d    <= 3'd0;
    end
    else begin
        pre_frame_vsync_d <= {pre_frame_vsync_d[1:0], pre_frame_vsync};
        pre_frame_hsync_d <= {pre_frame_hsync_d[1:0], pre_frame_hsync};
        pre_frame_de_d    <= {pre_frame_de_d[1:0]   , pre_frame_de   };
    end
end

assign post_frame_vsync = pre_frame_vsync_d[2]      ;
assign post_frame_hsync = pre_frame_hsync_d[2]      ;
assign post_frame_de    = pre_frame_de_d[2]         ;

将Y分量高5位、高6位、高5位数据作为VGA显示的红、绿、蓝三通道输入数据代码如下所示

assign  vga_rgb = {img_y_w[7:3],img_y_w[7:2],img_y_w[7:3]}   ;

最后通过VGA显示结果如下所示
原图
在这里插入图片描述
YCbCr格式图片
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值