參考文獻
彩色MT9V034攝像頭 Bayer轉rgb FPGA實現
https://www.cnblogs.com/hqz68/p/10413896.html
文章目錄
- 前言
- Bayer轉rgb
- 算法解析
- 總結
前言
Bayer格式是相機內部的原始數據, 一般后綴名為.raw。
對于彩色圖像,一般是三原色數據,rgb格式。但是攝像頭一個像素點只有rgb中一種數據。但是有很多攝像頭直接輸出rgb和yuv格式,如ov5640、ov7725等等,這是因為在Sensor模組的內部會有一個ISP模塊,會將 Sensor采集到的數據進行插值和特效處理,所以直接輸出彩色圖像。但不是所有的攝像頭都集成ISP,而直接輸出Bayer數據,這就需要寫Bayer轉rgb算法。
Bayer轉rgb
算法解析
mt9v034的Bayer陣列為例,注意輸出方向,從右到左,從上到下。
可以用shift register ip 或者fifo緩存兩行數據,形成2*2窗口。
shift_ram shift_ram_1 (.D (bayer_data ), // input wire [7 : 0] D.CLK (pclk ), // input wire CLK.CE (hsync_i ), // input wire CE.SCLR (~s_rst_n ), // input wire SCLR.Q (line_1 ) // output wire [7 : 0] Q
);shift_ram shift_ram_2 (.D (line_1 ), // input wire [7 : 0] D.CLK (pclk ), // input wire CLK.CE (hsync_i ), // input wire CE.SCLR (~s_rst_n ), // input wire SCLR.Q (line_2 ) // output wire [7 : 0] Q
);
行計數和列計數
always @ (posedge pclk or negedge s_rst_n) begin if(s_rst_n == 1'b0) beginhsync_i_1 <= 1'b0;hsync_i_2 <= 1'b0;hsync_i_3 <= 1'b0;endelse beginhsync_i_1 <= hsync_i;hsync_i_2 <= hsync_i_1;hsync_i_3 <= hsync_i_2;end
endalways @ (posedge pclk or negedge s_rst_n) begin if(s_rst_n == 1'b0) beginvsync_i_1 <= 1'b0;vsync_i_2 <= 1'b0;vsync_i_3 <= 1'b0;endelse beginvsync_i_1 <= vsync_i;vsync_i_2 <= vsync_i_1;vsync_i_3 <= vsync_i_2;end
end列計數
always @ (negedge pclk or negedge s_rst_n) beginif(s_rst_n == 1'b0)col_cnt <= 10'd0;else if (hsync_i_3 == 1'b1 && hsync_i_2 == 1'b1)col_cnt <= col_cnt + 1'b1; else col_cnt <= 10'd0;
end行計數
always @ (posedge pclk or negedge s_rst_n) beginif(s_rst_n == 1'b0)row_cnt <= 9'd0;else if(~hsync_i && hsync_i_1)row_cnt <= row_cnt + 1'b1;else if (~vsync_i && vsync_i_1)row_cnt <= 9'd0;
end
由于在列計數col_cnt中使用了hsync_i_3 == 1’b1 && hsync_i_2 == 1’b1的作為開始計數條件,相當于向后延遲了3個PCLK,所以col_cnt[0]為0時候,其實列計數為奇數列。
當然,如果列計數col_cnt中直接使用hsync_i == 1’b1作為開始計數條件,則col_cnt[0]為0時候,列計數為偶數列。
//data_control
always @ (posedge pclk or negedge s_rst_n) beginif(s_rst_n == 1'b0)data_control <= 3'b100;else if (hsync_i_2 == 1'b1 && hsync_i_1 == 1'b1)data_control <= {1'b0,row_cnt[0],~col_cnt[0]};elsedata_control <= 3'b100;
end
根據窗口移動,不難發現,總結出一條重要的規律:總共只有四種窗口,而且與行和列的奇偶有關。
假設計數器從零開始計數:
第一種{行偶,列偶}
第二種{行偶,列奇}
第三種{行奇,列偶}
第四種{行奇,列奇}
always @ (posedge pclk or negedge s_rst_n) beginif(s_rst_n == 1'b0) beginline1_1 <= 8'd0;line1_2 <= 8'd0;line2_1 <= 8'd0;line2_2 <= 8'd0;endelse beginline1_1 <= line_1;line1_2 <= line1_1;line2_1 <= line_2;line2_2 <= line2_1;end endalways @ (data_control) begincase(data_control)3'b000 : begin rgb_r = line1_1; rgb_g = line2_1 + line1_2; rgb_b = line2_2;end3'b001 : beginrgb_r = line1_2;rgb_g = line1_1 + line2_2; rgb_b = line2_1;end3'b010 : beginrgb_r = line2_1;rgb_g = line1_1 + line2_2;rgb_b = line1_2;end3'b011 : beginrgb_r = line2_2;rgb_g = line2_1 + line1_2;rgb_b = line1_1;enddefault: begin rgb_r = 8'd0;rgb_g = 9'd0;rgb_b = 8'd0; endendcase
endassign rgb_data = {rgb_r,rgb_g[8:1],rgb_b};
assign vsync_o = vsync_i_3;
assign hsync_o = hsync_i_3;
總結
本文根據mt9v034講解Bayer轉rgb的使用,不同攝像頭有不同的Bayer的起始排列位置,需要根據手冊撰寫代碼。