FPGA 第4章 摄像头Bayer转rgb

参考文献
彩色MT9V034摄像头 Bayer转rgb FPGA实现
https://www.cnblogs.com/hqz68/p/10413896.html


前言

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) begin
        hsync_i_1 <= 1'b0;
        hsync_i_2 <= 1'b0;
        hsync_i_3 <= 1'b0;
    end
    else begin
        hsync_i_1 <= hsync_i;
        hsync_i_2 <= hsync_i_1;
        hsync_i_3 <= hsync_i_2;
    end
end


always @ (posedge pclk or negedge s_rst_n) begin 
     if(s_rst_n == 1'b0) begin
        vsync_i_1 <= 1'b0;
        vsync_i_2 <= 1'b0;
        vsync_i_3 <= 1'b0;
    end
    else begin
        vsync_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) begin
    if(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) begin
    if(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) begin
    if(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]};
    else
        data_control <= 3'b100;       
end

根据窗口移动,不难发现,总结出一条重要的规律:总共只有四种窗口,而且与行和列的奇偶有关。

假设计数器从零开始计数:

第一种{行偶,列偶}
在这里插入图片描述

第二种{行偶,列奇}
在这里插入图片描述

第三种{行奇,列偶}
在这里插入图片描述

第四种{行奇,列奇}
在这里插入图片描述


always @ (posedge pclk or negedge s_rst_n) begin
    if(s_rst_n == 1'b0) begin
        line1_1    <= 8'd0;
        line1_2    <= 8'd0;

        line2_1 <= 8'd0;
        line2_2 <= 8'd0;
    end
    else begin
        line1_1    <= line_1;
        line1_2    <= line1_1;

        line2_1    <= line_2;
        line2_2    <= line2_1;
    end    
        
end


always @ (data_control) begin
       case(data_control)
           3'b000 : begin 
               rgb_r = line1_1; 
               rgb_g = line2_1 + line1_2; 
               rgb_b = line2_2;
           end
           3'b001 : begin
               rgb_r = line1_2;
               rgb_g = line1_1 + line2_2; 
               rgb_b = line2_1;
           end
           3'b010 : begin
               rgb_r = line2_1;
               rgb_g = line1_1 + line2_2;
               rgb_b = line1_2;
           end
           3'b011 : begin
               rgb_r = line2_2;
               rgb_g = line2_1 + line1_2;
               rgb_b = line1_1;
           end
           default: begin 
               rgb_r = 8'd0;
               rgb_g = 9'd0;
               rgb_b = 8'd0; 
           end
           endcase
end

assign 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的起始排列位置,需要根据手册撰写代码。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值