基於FPGA的bayer轉RGB算法

一.基本知識

Raw RGB 每個像素只有一種顏色(R、G、B中的一種);
RGB 每個像素都有三種顏色,每一個的值在0~255之間;
在手機攝像頭的測試過程中,由sensor輸出的數據就是Raw data(Raw RGB),經過彩色插值就變成RGB。

也不一定就是測試過程,想要獲得真正的圖像,都必須有的一個過程;
sensor輸出的數據格式,主要分兩種:YUV(比較流行),RGB,這就是sonsor的數據輸出;這其中的GRB就是Raw RGB,是sensor的bayer陣列獲取的數據(每種傳感器獲得對應的顏色亮度);
RGB Bayer(CMOS sensor直接輸出的數據):


在這裏插入圖片描述

四種不同的格式如下:


ab

二.FPGA代碼

1.bayer2RGB模塊

module Bayer_RGB #(
                parameter ROW_WIDTH = 1920,
                parameter COL_WIDTH = 1080

)
(
                 input          I_clk_pixel,
                 input          I_rst_p,
                 input          I_v_sync,//high active
                 input          I_h_sync,//high active -data valid
                 input  [7:0]   I_bayer_data,
                 output         O_RGB_data_valid,
                 output [7:0]   O_RGB_data_R,
                 output [7:0]   O_RGB_data_G,
                 output [7:0]   O_RGB_data_B,
                 output         O_v_sync

    );
reg          v_sync_d1;
reg          v_sync_d2;
reg          v_sync_d3;
wire         v_sync_pos;
reg          h_sync_d1;
reg          h_sync_d2;
reg          h_sync_d3;
wire         h_sync_neg;
reg  [7:0]   bayer_data_d1;
reg  [7:0]   bayer_data_d2;
reg  [7:0]   bayer_data_d3;

reg  [10:0]  row_cnt;
reg  [10:0]  col_cnt;
wire [7:0]   shift_reg1_dout;
wire [7:0]   shift_reg2_dout;
reg  [7:0]   shift_reg2_dout_d1;

reg          RGB_data_valid;  
reg  [7:0]   RGB_R;
reg  [8:0]   RGB_G;
reg  [7:0]   RGB_B;

always@(posedge I_clk_pixel)
   begin
      v_sync_d1 <= I_v_sync;
      v_sync_d2 <= v_sync_d1;
      v_sync_d3 <= v_sync_d2;
      h_sync_d1 <= I_h_sync;
      h_sync_d2 <= h_sync_d1;
      h_sync_d3 <= h_sync_d2;                 
      bayer_data_d1 <= I_bayer_data;
      bayer_data_d2 <= bayer_data_d1;  
      bayer_data_d3 <= bayer_data_d2;  
      shift_reg2_dout_d1 <= shift_reg2_dout;
   end
assign v_sync_pos = v_sync_d1 & (~v_sync_d2);
assign h_sync_neg = (~h_sync_d1) & h_sync_d2;
//=======================================================================cnt
always@(posedge I_clk_pixel or posedge I_rst_p)
   begin
      if(I_rst_p)
         row_cnt <= 11'b0;
      else if(v_sync_pos)
         row_cnt <= 11'b0;   
      else if(h_sync_d2)
         if(row_cnt == ROW_WIDTH-1 )
            row_cnt <= 11'b0;
         else
            row_cnt <= row_cnt+ 1;
      else
          row_cnt <= row_cnt;              
   end
always@(posedge I_clk_pixel or posedge I_rst_p)
      begin
         if(I_rst_p)
            col_cnt <= 11'b0;
         else if(v_sync_pos)
            col_cnt <= 11'b0;            
         else if(row_cnt == ROW_WIDTH-1 && h_sync_d2)
             col_cnt <= col_cnt+ 1;
         else
             col_cnt <= col_cnt;              
      end  

//=================GBRG==================================
always@(posedge I_clk_pixel or posedge I_rst_p)
   begin
      if(I_rst_p)
         begin
            RGB_R <= 8'b0;
            RGB_G <= 8'b0;
            RGB_B <= 8'b0;
         end
      else
         case({col_cnt[0],row_cnt[0]})
            2'b00:
               begin
                  RGB_R <= shift_reg2_dout_d1;
                  RGB_G <= (bayer_data_d2 + shift_reg2_dout)>>1;
                  RGB_B <= bayer_data_d1;
               end    
            2'b01:
               begin
                  RGB_R <= shift_reg2_dout;
                  RGB_G <= (bayer_data_d1 + shift_reg2_dout_d1)>>1;
                  RGB_B <= bayer_data_d2;
               end  
            2'b10:
               begin
                  RGB_R <= bayer_data_d2;
                  RGB_G <= (bayer_data_d1 + shift_reg2_dout_d1)>>1;
                  RGB_B <= shift_reg2_dout;
               end
            2'b11:
               begin
                  RGB_R <= bayer_data_d1;
                  RGB_G <= (bayer_data_d2 + shift_reg2_dout)>>1;
                  RGB_B <= shift_reg2_dout_d1;
               end                                                                
            default:
               begin
                  RGB_R <= 8'b0;
                  RGB_G <= 8'b0;
                  RGB_B <= 8'b0;
               end
         endcase
   end
shift_ram_8x1080 shift_ram_8x1080_inst1 (
  .D(bayer_data_d1),        // input wire [7 : 0] D
  .CLK(I_clk_pixel),    // input wire CLK
  .CE(h_sync_d1),      // input wire CE
  .SCLR(I_rst_p),  // input wire SCLR
  .Q(shift_reg1_dout)        // output wire [7 : 0] Q
);

shift_ram_8x840 shift_ram_8x840_inst2 (
  .D(shift_reg1_dout),        // input wire [7 : 0] D
  .CLK(I_clk_pixel),    // input wire CLK
  .CE(h_sync_d1),      // input wire CE
  .SCLR(I_rst_p),  // input wire SCLR
  .Q(shift_reg2_dout)        // output wire [7 : 0] Q
);

assign O_RGB_data_valid = h_sync_d3;
assign O_v_sync = v_sync_d3;
//assign O_RGB_data = {RGB_R,RGB_G,RGB_B} ;
assign  O_RGB_data_R = RGB_R;
assign  O_RGB_data_G = RGB_G[7:0];
assign  O_RGB_data_B = RGB_B;
endmodule

2.testbench

module bayer_RGB_matlab_tb(

    );

reg          I_clk_pixel;
reg          I_rst_p;
reg          I_v_sync;
reg          I_h_sync;
wire  [7:0]   I_bayer_data;
wire         O_RGB_data_valid;
wire [7:0]  O_RGB_data_R;          
wire [7:0]  O_RGB_data_G;          
wire [7:0]  O_RGB_data_B;          

always #5 I_clk_pixel <= ~I_clk_pixel;

initial begin
   I_clk_pixel = 0;
   I_rst_p = 1;
   #10;
   I_rst_p = 0;   

end


Bayer_RGB 
#(
   .ROW_WIDTH(1280),
   .COL_WIDTH(1024)
)
  Bayer_RGB_inst
(
   .I_clk_pixel(I_clk_pixel),
   .I_rst_p(I_rst_p),
   .I_v_sync(I_v_sync),
   .I_h_sync(I_h_sync),
   .I_bayer_data(I_bayer_data),
   .O_RGB_data_valid(O_RGB_data_valid),
   .O_RGB_data_R(O_RGB_data_R),
   .O_RGB_data_G(O_RGB_data_G),
   .O_RGB_data_B(O_RGB_data_B),
   .O_v_sync()   
);

//=====================input==================================
reg [7:0] mem [1310719:0];
integer fin,number_file_R,number_file_G,number_file_B;
reg [29:0] addr;

initial begin
     I_v_sync = 0;
     I_h_sync = 0;
     addr = 0;
    #20;
     $readmemh("E:/Matlab_project/bayer/bayer.txt",mem);
    #100;
     repeat(10)       @(posedge I_clk_pixel ) begin I_v_sync = 1;end
     repeat(1)        @(posedge I_clk_pixel ) begin I_h_sync = 1;end
     repeat(1310719)  @(posedge I_clk_pixel ) begin I_h_sync = 1; addr = addr+ 1;end
     repeat(20)       @(posedge I_clk_pixel ) begin I_v_sync = 0;I_h_sync = 0 ; end
end

assign I_bayer_data = mem[addr];

initial begin
   number_file_R = $fopen("E:/Matlab_project/bayer/Bayer2Gray_FPGA_R.txt","w");
   number_file_G = $fopen("E:/Matlab_project/bayer/Bayer2Gray_FPGA_G.txt","w");
   number_file_B = $fopen("E:/Matlab_project/bayer/Bayer2Gray_FPGA_B.txt","w");
 
   repeat(1311000) @(posedge I_clk_pixel)
     begin
     if(O_RGB_data_valid)
       begin
          $fwrite(number_file_R,"%d\n",O_RGB_data_R);//注意是$fwrite 而不是$write 
          $fwrite(number_file_G,"%d\n",O_RGB_data_G);//注意是$fwrite 而不是$write 
          $fwrite(number_file_B,"%d\n",O_RGB_data_B);//注意是$fwrite 而不是$write 
       end
     end
     
     #10
          $display("the image Bayer TO RGB is done!!!\n");
          $display("the cost time is %t",$time);
          $fclose(number_file_R);//只有$fclose 纔可以寫進去數據或更改原有數據 
          $fclose(number_file_G);
          $fclose(number_file_B);
end

endmodule

三.Matlab 代碼

1.生成仿真文件

clear;
close all;

src = imread('bayer.jpg');

r = src(:,:,1);
g = src(:,:,2);
b = src(:,:,3);
imshow(src);

[m,n,k] = size(src);
N = m*n;           %m行,n列
data_lenth = 8;    %數據位寬

data_r = reshape(r',1,N); %數字矩陣改爲1行N列
% data_g = reshape(g',1,N);
% data_b = reshape(b',1,N);

fin = fopen('bayer.txt','wt');
for i = 1:N
    fprintf(fin,'%x\n',data_r(i));
end
fclose(fin);

2.FPGA處理後圖像顯示

close all;
clear;

n = 1280;
m = 1024;

im = zeros(m,n,3);
im = uint8(im);

Bayer2Gray_FPGA_R = load('Bayer2Gray_FPGA_R.txt');%verilog 產生的灰度圖
Bayer2Gray_FPGA_R = reshape(Bayer2Gray_FPGA_R,n,m);
Bayer2Gray_FPGA_R = uint8(Bayer2Gray_FPGA_R');
im(:,:,1) = Bayer2Gray_FPGA_R;

Bayer2Gray_FPGA_G = load('Bayer2Gray_FPGA_G.txt');%verilog 產生的灰度圖
Bayer2Gray_FPGA_G = reshape(Bayer2Gray_FPGA_G,n,m);
Bayer2Gray_FPGA_G = uint8(Bayer2Gray_FPGA_G');
im(:,:,2) = Bayer2Gray_FPGA_G;

Bayer2Gray_FPGA_B = load('Bayer2Gray_FPGA_B.txt');%verilog 產生的灰度圖
Bayer2Gray_FPGA_B = reshape(Bayer2Gray_FPGA_B,n,m);
Bayer2Gray_FPGA_B = uint8(Bayer2Gray_FPGA_B');
im(:,:,3) = Bayer2Gray_FPGA_B;

imshow(im), title('Image-FPGA')
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章