1 图像bayer格式介绍

  bayer格式是伊士曼·柯达公司科学家Bryce Bayer发明的,Bryce Bayer所发明的拜耳阵列被广泛运用数字图像。Bayer格式是相机内部的原始数据, 一般后缀名为.raw。

  对于彩色图像,一般是三原色数据,rgb格式。但是摄像头一个像素点只有rgb中一种数据(下图为bayer色彩滤波阵列)。但是有很多摄像头直接输出rgb和yuv格式,如ov5640、ov7725等等,这是因为在Sensor模组的内部会有一个ISP模块,会将 Sensor采集到的数据进行插值和特效处理,所以直接输出彩色图像。但不是所有的摄像头都集成ISP,而直接输出Bayer数据,这就需要自己写Bayer转rgb算法。

2 MT9V034简单介绍

  做图像处理的朋友都知道,MT9V034是一款十分出色的做机器视觉的摄像头,一般都是灰度的。但是也有彩色款,当时我觉得灰度的效果那么好,一时头热就买一个彩色款的。mt9v034用起来很方便,可以不用寄存器配置,上电默认752*480分辨率。根据需求也可以iic配置。

  全局快门(相对滚动快门) 拍摄高速物体的效果:

  高动态效果:

3 MT9V034 datasheet 简单解析

  1)有效图像 752x480

    最大时钟为27Mhz

    最大帧率为60fps

    10位的adc(我的是八位的输出,店家只将高8位引出,有点影响最后图像的精度)

  2)这是mt9v034Bayer阵列,注意输出方向,从左到右,从上到下。

  3)摄像头ID号要根据 S_CTRL_ADR1, S_CTRL_ADR0这两个引脚咋连接的

  4)下图是摄像头原理图,很明显S_CTRL_ADR1, S_CTRL_ADR0是被拉低了,所以摄像头ID为0x90.上面说到摄像头只有高8位被引出,在这里可以证实了。

  5)下面是大部分寄存器,mt9v034可配置的寄存器很少。0x00是芯片版本。03、04是摄像头分辨率

  6)datasheet就介绍到这里,更多信息可以自己去阅读。

4 Bayer转rgb算法解析

我是用shift register ip 缓存两行数据,形成2*2窗口(这是FPGA做图像算法最常用的方法和ip),不是很会的朋友可以百度搜一搜,有很多博客可以学习,一定要自己仿真一下,搞明白,这有点难理解。

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

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

第一种{行偶,列偶}

第二种{行偶,列奇}

第三种{行奇,列偶}

第四种{行奇,列奇}

5 算法实现

首先说明我是用xilinx的zynq fpga,altera的也有类似的ip。我直接说明一下ip 参数修改,其他的怎么添加ip什么的我就不讲了,不会的自己百度学习。

  1)这是ip首页,蓝框自定义ip名,修改一下红框的参数,我们是8位数据,一行数据为640个。clock enable端与sclr端可以根据自己的要求决定勾不勾选。其他默认就行,点击ok可以了。

  2)vivado也提供端口例化模板,如下图操作就行,

  3)源码

    用两个shift register ip形成2*2的窗口,代码就不具体解说了,自己仿真一下结合源码理解吧。

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2019/02/04 10:29:56
// Design Name: colour MT98V034 bayer2rgb
// Module Name: MT_bayer2rgb
// Project Name: Colour_MT_bayer2rgb
// Target Devices: ZYNQ7020
// Tool Versions: vivado2018.3
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
////////////////////////////////////////////////////////////////////////////////// module MT_bayer2rgb(
//system singal
input s_rst_n ,
//cmos simgals
input vsync_i ,
input hsync_i ,
input pclk ,
input [:] bayer_data ,
//输出
output vsync_o ,
output hsync_o ,
output [:] rgb_data
); //========================================================================\
// =========== Define Parameter and Internal signals ===========
//========================================================================/ reg [:] col_cnt ;
reg [:] row_cnt ; reg hsync_i_1 ;
reg hsync_i_2 ;
reg hsync_i_3 ; reg vsync_i_1 ;
reg vsync_i_2 ;
reg vsync_i_3 ; wire [:] line_1 ;
wire [:] line_2 ;
reg [:] data_control ; reg [:] line1_1 ;
reg [:] line1_2 ; reg [:] line2_1 ;
reg [:] line2_2 ; reg [:] rgb_r ;
reg [:] rgb_g ;
reg [:] rgb_b ;
//=============================================================================
//**************************** Main Code *******************************
//============================================================================= //列计数
always @ (negedge pclk or negedge s_rst_n) begin
if(s_rst_n == 'b0)
col_cnt <= 'd0;
else if (hsync_i_3 == 'b1 && hsync_i_2 == 1'b1)
col_cnt <= col_cnt + 'b1;
else
col_cnt <= 'd0;
end always @ (posedge pclk or negedge s_rst_n) begin
if(s_rst_n == 'b0) begin
hsync_i_1 <= 'b0;
hsync_i_2 <= 'b0;
hsync_i_3 <= '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 == 'b0) begin
vsync_i_1 <= 'b0;
vsync_i_2 <= 'b0;
vsync_i_3 <= 'b0;
end
else begin
vsync_i_1 <= vsync_i;
vsync_i_2 <= vsync_i_1;
vsync_i_3 <= vsync_i_2;
end
end //行计数
always @ (posedge pclk or negedge s_rst_n) begin
if(s_rst_n == 'b0)
row_cnt <= 'd0;
else if(~hsync_i && hsync_i_1)
row_cnt <= row_cnt + 'b1;
else if (~vsync_i && vsync_i_1)
row_cnt <= 'd0;
end //data_control
always @ (posedge pclk or negedge s_rst_n) begin
if(s_rst_n == 'b0)
data_control <= 'b100;
else if (hsync_i_2 == 'b1 && hsync_i_1 == 1'b1)
data_control <= {'b0,row_cnt[0],~col_cnt[0]};
else
data_control <= 'b100;
end 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 == 'b0) begin
line1_1 <= 'd0;
line1_2 <= 'd0; line2_1 <= 'd0;
line2_2 <= '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)
'b000 : begin
rgb_r = line1_1;
rgb_g = line2_1 + line1_2;
rgb_b = line2_2;
end
'b001 : begin
rgb_r = line1_2;
rgb_g = line1_1 + line2_2;
rgb_b = line2_1;
end
'b010 : begin
rgb_r = line2_1;
rgb_g = line1_1 + line2_2;
rgb_b = line1_2;
end
'b011 : begin
rgb_r = line2_2;
rgb_g = line2_1 + line1_2;
rgb_b = line1_1;
end
default: begin
rgb_r = 'd0;
rgb_g = 'd0;
rgb_b = 'd0;
end
endcase
end assign rgb_data = {rgb_r,rgb_g[:],rgb_b};
assign vsync_o = vsync_i_3;
assign hsync_o = hsync_i_3;
endmodule

  4)最后欣赏一下效果 ,效果还不错,继承了灰度款的优良性能。

最后说明一下,最后分辨率改为640*480,但是发现480指的是0~480,所以行计数器在481清零。我是用的zynq,所以没进行iic硬件配置,用的是ps端arm的 iic接口做的。如果用默认的分辨率就需要修改一下ip的深度和行计数器的清零的数值就行了。说到仿真,vivado自带的仿真器还是没有modelsim好,但是modelsim仿真含有vivado ip的工程时,很麻烦,独立仿真更不行,ip仿真的源文件不好添加,联合仿真操作有点繁琐,这里呢先不讲,我下次再另外写一篇博客总结一下。

彩色MT9V034摄像头 Bayer转rgb FPGA实现的更多相关文章

  1. 图像处理之基础---yuv420及其rgb,bayer, yuv, RGB的相互转换详解

    YUV格式解析1(播放器——project2) 根据板卡api设计实现yuv420格式的视频播放器 打开*.mp4;*.264类型的文件,实现其播放. 使用的视频格式是YUV420格式   YUV格式 ...

  2. QT 实现彩色图亮度均衡,RGB和HSI空间互相转换

    从昨天折腾到今天.再折腾下去我都要上主楼了  大致和灰度图均衡是一样的,主要是不能像平滑什么的直接对R,G,B三个分量进行.这样出来的图像时没法看的.因此我们要对亮度进行均衡.而HSI彩色空间中的分量 ...

  3. bayer, yuv, RGB转换方法

    因为我的STVxxx USB camera输出格式是bayer格式,手头上只有YUVTOOLS这个查看工具,没法验证STVxxx在开发板上是否正常工作. 网上找了很久也没找到格式转换工具,最后放弃了, ...

  4. 图像处理之基础---彩色转灰度算法优化rgb to yuv

    File:      StudyRGB2Gray.txtName:      彩色转灰度算法彻底学习Author:    zyl910Version:   V1.0Updata:    2006-5- ...

  5. 【VS开发】【图像处理】 bayer, yuv, RGB转换方法

    因为我的STVxxx USB camera输出格式是bayer格式,手头上只有YUVTOOLS这个查看工具,没法验证STVxxx在开发板上是否正常工作. 网上找了很久也没找到格式转换工具,最后放弃了, ...

  6. ov5640摄像头设备驱动

    http://www.cnblogs.com/firege/p/5806121.html  (驱动大神) http://blog.csdn.net/yanbixing123/article/detai ...

  7. 31全志r58平台Android4.4.2下打开USB摄像头

    31全志r58平台Android4.4.2下打开USB摄像头 2018/10/26 16:00 版本:V1.0 开发板:SC5806 1.系统编译:(略) 2.需要修改的文件: W:\r58_andr ...

  8. C语言实现将彩色BMP位图转化为二值图

    CTF做了图片的隐写题,还没有形成系统的认识,先来总结一下BMP图的组成,并通过将彩色图转为二值图的例子加深下理解. 只写了位图二进制文件的格式和代码实现,至于诸如RGB色彩和调色板是什么的一些概念就 ...

  9. bayer转dng实现过程记录

    前言 项目中需要将imx185出来的raw数据转成dng格式,一开始认为很简单的事情,后面才发现还是挺复杂的!!!首先考虑的是不写任何代码,直接用adobe提供的转换工具来转,结果发现,不仅是adob ...

随机推荐

  1. http://www.html5tricks.com/demo/jiaoben2255/index.html 排序算法jquery演示源代码

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.or ...

  2. apple air装双系统(win7)

     同事买了一个apple air.用不习惯,希望再装个win7,经过多次试验,得到例如以下操作方法: 1.在MAC系统里的"有用工具"中找到"Boot Camp 助理 ...

  3. android自己定义控件系列教程-----仿新版优酷评论剧集卡片滑动控件

    我们先来看看优酷的控件是怎么回事? 仅仅响应最后也就是最顶部的卡片的点击事件,假设点击的不是最顶部的卡片那么就先把它放到最顶部.然后在移动到最前面来.重复如次. 知道了这几条那么我们就非常好做了. 里 ...

  4. iOS----四方块 动画button实现

    突然想起来上一次面试考官提问的一个问题:怎样创建一个菱形,并让它对应单击事件.能够开合的效果. 当时第一反应使用button来填充菱形的图片来实现,只是考官说,这样点击的区域不够灵敏,毕竟button ...

  5. Netlink通信机制【转】

    本文转载自:http://www.cnblogs.com/wenqiang/p/6306727.html 一.什么是Netlink通信机制  Netlink套接字是用以实现用户进程与内核进程通信的一种 ...

  6. bzoj 5090 组题

    题目大意: 一个数列,求一段长度不少于k的数 使平均值最大 思路: 把所有数列里的数,转换为(i,sum i)的点 然后求一个下凸包,在这个过程中对于长度特殊处理一下,使栈内至少有一段长度大于等于k ...

  7. telnet端口问题

    今天测试发现telnet 一个端口不通,开始还以为是服务开放这个端口有问题,后来才发现这个端口是udp的.而telnet下层走的tcp协议,自然无法测试那些tcp的端口. 而之前下意识里还总以为都可以 ...

  8. RDA 升级

    烧录BOOT升级方式: 1.连接 2.烧录BOOT 1)升级“bootrom_raw.bin” 99K,这种升级方式需要Tera Term 工具,按“F5”  U盘升级. 编译的升级文件“RR8503 ...

  9. java线程系列---Runnable和Thread的区别 (转载)

    转自:http://blog.csdn.net/wwww1988600/article/details/7309070 在java中可有两种方式实现多线程,一种是继承 Thread类,一种是实现Run ...

  10. codevs4511信息传递(Tarjan求环)

    题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...