YCbCr转RGB

  YCbCr属于YUV中的一种颜色空间格式,其中“Y”表示明亮度(Luminance或Luma),也就是灰阶值;而“U”和“V” 表示的则是色度(Chrominance或Chroma)。在 RGB 颜色空间中,红,绿,蓝是基本元素。RGB 格式是显示器通常使用的格式。

  YUV色彩模型来源于RGB模型,该模型的特点是将亮度和色度分离开,从而适合于图像处理领域。

  YUV与RGB之间的转换公式如下:

    Y = 0.299*R + 0.587*G + 0.114*B
    U = -0.147*R - 0.289*G + 0.436*B = 0.492*(B - Y)
    V = 0.615*R - 0.515*G - 0.100*B = 0.877*(R - Y)
 
    R = Y  + 1.140*V
    G = Y - 0.394*U - 0.581*V
    B = Y + 2.032*U
  
  YCbCr模型来源于YUV模型,YCbCr是 YUV 颜色空间的偏移版本。
  YCbCr与RGB的转换公式如下:
    Y   = 0.257*R + 0.504*G + 0.098*B + 16
    Cb = -0.148*R - 0.291*G + 0.439*B + 128
    Cr  = 0.439*R - 0.368*G - 0.071*B + 128
 
    R   = 1.164*(Y - 16) + 1.596*(Cr - 128)
    G   = 1.164*(Y - 16) - 0.813*(Cr - 128) - 0.392*(Cb - 128)
    B   = 1.164*(Y - 16) + 2.017*(Cb - 128)
  
  由于笔者曾经在做OV5640实验时把输出的数据配成YCbCr格式,做完图像处理后,需要显示器显示,所以又把YCbCr格式的数据转换成RGB。根据公式用代码实现,FPGA没有浮点运算,这里先把公式左右两边同时左移10位即放大1024倍,然后再进行计算。代码采用流水线的方式,使用时可以一直把使能信号置1,输入到输出的过程,共消耗3个时钟周期。这里可以根据3个时钟延时对同步信号进行对应的延时。以下为代码:
  YCbCr2RGB.v
  1 //**************************************************************************
  2 // *** file name      : YCbCr2RGB.v
  3 // *** version        : 1.0
  4 // *** Description    : YCbCr2RGB
  5 // *** Blogs          : https://www.cnblogs.com/WenGalois123/
  6 // *** Author         : Galois_V
  7 // *** Date           : 2019.3.15
  8 // *** Changes        : Initial
  9 //**************************************************************************
 10 `timescale    1ns/1ps
 11 module YCbCr2RGB
 12 (
 13     input                             i_sys_clk           ,
 14     input                             i_convert_en        ,
 15     input            [7:0]            i_y_data            ,
 16     input            [7:0]            i_cr_data           ,
 17     input            [7:0]            i_cb_data           ,
 18     output    reg    [7:0]            o_red               ,
 19     output    reg    [7:0]            o_green             ,
 20     output    reg    [7:0]            o_blue                
 21 );
 22     reg            [7:0]             r_y_data         ;
 23     reg            [7:0]             r_cb_data        ;
 24     reg            [7:0]             r_cr_data        ;
 25     reg            [17:0]            r_r_ypart        ;
 26     reg            [17:0]            r_r_crpart       ;
 27     reg            [17:0]            r_g_ypart        ;
 28     reg            [17:0]            r_g_crpart       ;
 29     reg            [17:0]            r_g_cbpart       ;
 30     reg            [17:0]            r_b_ypart        ;
 31     reg            [17:0]            r_b_cbpart       ;
 32     reg            [20:0]            r_r_sum          ;
 33     reg            [20:0]            r_g_sum          ;
 34     reg            [20:0]            r_b_sum          ;
 35 
 36     always@(posedge i_sys_clk)
 37     begin
 38         if(i_convert_en)
 39         begin
 40             r_y_data  <= i_y_data;
 41             r_cr_data <= i_cr_data;
 42             r_cb_data <= i_cb_data;
 43         end
 44     end
 45 /******************************************************************************\
 46 calculate R = 1.164*(Y-16) + 1.596*(Cr-128) ;all data shift left ten places
 47 \******************************************************************************/    
 48     always@(posedge i_sys_clk)
 49     begin
 50         if(i_convert_en)
 51         begin
 52             r_r_ypart  <= 10'd168 * i_y_data;      //0.164*1024 = 168
 53             r_r_crpart <= 10'd610 * i_cr_data;     //0.594*1024 = 610
 54             r_r_sum    <= ((r_y_data + r_cr_data)<<10) + r_r_ypart + r_r_crpart - 228262;
 55         end
 56     end
 57 /******************************************************************************\
 58 calculate G = 1.164*(Y-16) - 0.813*(Cr-128) - 0.392*(Cb-128)
 59 \******************************************************************************/    
 60     always@(posedge i_sys_clk)
 61     begin
 62         if(i_convert_en)
 63         begin
 64             r_g_ypart  <= 10'd168 * i_y_data;      //0.164*1024 = 168
 65             r_g_crpart <= 10'd832 * i_cr_data;     //0.813*1024 = 832
 66             r_g_cbpart <= 10'd401 * i_cb_data;     //0.392*1024 = 401
 67             r_g_sum    <= r_y_data << 10 + r_g_ypart - r_g_crpart - r_g_cbpart + 138740;
 68         end
 69     end
 70 /******************************************************************************\
 71 calculate B = 1.164*(Y-16) + 2.017*(Cb-128)
 72 \******************************************************************************/    
 73     always@(posedge i_sys_clk)
 74     begin
 75         if(i_convert_en)
 76         begin
 77             r_b_ypart  <= 10'd168 * i_y_data;      //0.164*1024 = 168
 78             r_b_cbpart <= 10'd17  * i_cb_data;     //0.017*1024 = 17
 79             r_b_sum    <= (r_y_data <<10) + (r_cb_data << 11) + r_b_ypart + r_b_cbpart - 283574;
 80         end
 81     end
 82 /******************************************************************************\
 83 output R
 84 \******************************************************************************/    
 85     always@(posedge i_sys_clk)
 86     begin
 87         if(i_convert_en)
 88         begin
 89             if(r_r_sum[20])
 90             begin
 91                 o_red <= 'd0;
 92             end
 93             else if(r_r_sum[19:10]>255)
 94             begin
 95                 o_red <= 8'hff;
 96             end
 97             else
 98             begin
 99                 o_red <= r_r_sum[17:10];
100             end
101         end
102     end
103 /******************************************************************************\
104 output G
105 \******************************************************************************/    
106     always@(posedge i_sys_clk)
107     begin
108         if(i_convert_en)
109         begin
110             if(r_g_sum[20])
111             begin
112                 o_green <= 'd0;
113             end
114             else if(r_g_sum[19:10]>255)
115             begin
116                 o_green <= 8'hff;
117             end
118             else
119             begin
120                 o_green <= r_g_sum[17:10];
121             end
122         end
123     end
124 /******************************************************************************\
125 output B
126 \******************************************************************************/
127     always@(posedge i_sys_clk)
128     begin
129         if(i_convert_en)
130         begin
131             if(r_b_sum[20])
132             begin
133                 o_blue <= 'd0;
134             end
135             else if(r_b_sum[19:10]>255)
136             begin
137                 o_blue <= 8'hff;
138             end
139             else
140             begin
141                 o_blue <= r_b_sum[17:10];
142             end
143         end
144     end
145 
146 endmodule
 
posted on 2022-06-26 09:36  Galois_V  阅读(1891)  评论(0编辑  收藏  举报