|
作品摘要
本作品为基于ATLYS FPGA开发平台、VmodCAM双目摄像头模块开发设计的双目立体视觉系统。VmodCAM用于采集双路的视觉信息,FPGA开发平台负责完成视觉信息的处理及图像的高速分析。采集到得左右两路图像信息通过分析处理,便可得到二维图像上的深度信息。深度信息的体现本作品中设计了两种方式,其一为视觉信息的立体显示,经过处理生成叠加的红蓝3D图像,给人直观上的立体感受。该设计方面可以应用于立体视觉的采集与显示,定位为立体视觉的采集与显示系统。另一方面,通过在FPGA片上设计的高速图像处理系统,可以根据左右图像的差距,计算出图像的深度信息,也就是物体在环境中相对于双目摄像头的三维坐标。该设计方面可以应用到人机交互、机器视觉领域,作为机器对环境情况的认知设备。
FPGA开发板在本作品中的作用主要有:①配置摄像头模块,采集摄像头数据;②将图像数据缓存在片外的DDR2中;③完成图像的分析处理;④完成图像的显示及UART数据传输。
设计目标
一方面,完成立体视觉实时采集与显示系统的设计,让人戴上3D眼镜后可以实时看到立体画面;另一方面,实现物体三维空间定位。
已实现:基于红蓝3D眼镜的立体视觉实时采集与显示;红外光点的三维空间定位。
将实现:基于偏振3D眼镜的立体视觉实时采集与显示;简单环境下的物体空间定位及环境三维重建,并开发成用于人机交互的设备。
设计总概
本设计为在FPGA片上完成的视频、图像采集与处理系统,完成三维图像的重建与数学建模。片上系统使用VHDL+Verilog联合开发,具有很高的数据处理速度。该设计的两个方面目前已初步实现,图像的采集、处理过程均由片上系统完成,为该设计的进一步优化打下了很好的基础。
开发工具
硬件方面:
- Diglient ATLYS FPGA 开发板
- Diglient VmodCAM 双目摄像头模块
- LCD 显示器
- 计算机
软件方面:
- XILINX ISE
- Digilent Adept
- Processing
背景
根据有关科学统计,人们通过视觉获得的信息量约占获得信息总量的70%。视觉信息中具有着很多有价值的信息量,但是由于视觉信息数据量大,处理过程复杂等因素,过去很长一段时间中,视觉信息处理仅处于理论研究阶段。
过去20年间,随着IT产业的飞速前进,软硬件方面均发生的翻天覆地的变化,这让许多复杂的视觉信息的处理的过程变得越来越可实现化。
近几年以来,视频图像处理方向上的工程应用越来越多,并已走入大多数人的生活。比如:指纹识别、Kinect体感器等等。
然而,目前的图像处理过程的实现大多是基于软件平台的,如Intel开发的图像处理库OpenCV等。对于低速、简单的图像处理,软件尚能胜任,但高速、杂的图像处理过程用软件处理起来很难达到实时性。鉴于这方面的原因,我们决定采用FPGA的并行处理、流水线处理能力实现视觉信息的高速处理。
通过FPGA做视觉信息处理的过程,不断探索硬件图像处理算法。同时,图像具有的很多方面特征用并行处理方式去完成将具有显著优势,这也将是未来图像处理的一个重要发展方向。
设计介绍
第一部分:立体视频采集与显示
1.总体框图:
本系统由从硬件上看由三大部分构成,分别是用于图像采集的摄像头模块、实现图像处理的FPGA开发板、进行结果显示的LCD显示器。
2.硬件组成部分:
(1)摄像头模块:采用Digilent公司出品的VmodCAM摄像头模块。该模块上搭载有两个Micron公司的MT9D112 CMOS图像传感器(本系统中用到一个)。该传感器最高支持1600x900分辨率,采用IIC的配置协议,并且内置PLL锁相环,能够产生严格精准相位的控制时钟,达到高速高精度的目的。
- 数据处理系统:本硬件平台的数据图像处理,智能识别系统由FPGA开发板实现。本项目中使用的为Digilent公司的ATLYS FPGA 开发板。其上集成的FPGA 芯片为Xilinx 公司生产的Spartan-6 LX45。该开发板上集成有多个视频输入输出接口(HDMI),适合做视频处理。
- 显示模块:我们采用液晶显示器作为系统的显示界面,达到可视化强,便于实时的交互的效果。
(1)系统架构
(1)系统架构
(2)摄像头模块
Input:
D_I(7:0):8-bit数据输入(data input),来自片外的摄像头模块,传输像素的值,通常两个时钟的数据(16bit)组成一个像素值;
CLK:时钟信号,来自时钟模块Inst_SysCon的CAMCLK_O输出;
CLK_180:时钟信号,来自时钟模块Inst_SysCon的CAMCLK_180_O输出(应该为CLK信号的180度相差信号,用来与CLK协调完成D_I(7:0)到D_O(15:0)的转化,起到像素前后部分的标志位作用);
FV_I:帧有效信号(Frame Valid),也称场同步信号,来自摄像头模块,输出一帧图像期间,电平为高,帧与帧之间时,电平拉低;(参见MT9D112_DS Page28 Figure18)
LV_I:行有效信号(Line Valid),也称行同步信号,来自摄像头模块,输出图像的一行期间,电平为高,行与行之间时,电平拉低;(参见MT9D112_DS Page28 Figure18)
PCLK_I:信号来自CAM_PCLK_I经过I/O缓冲器(IOBUF)后的输出,逻辑上等价于CAM_PCLK_I;
RST_I:模块复位信号,来自SysCon模块的ASYNC_RST端口。
Output:
D_O(15:0):16-bit数据输出信号(RGB565),由两个8-bit的输入数据组装得到,代表一个像素的颜色值等,输出给FBCtl图像缓存控制模块的DIA(15:0);
DV_O:输出给FBCtl图像缓存控制模块的ENA,作为使能信号,每当一个像素的16位数值配齐时置1;
MCLK_O:输出给摄像头,作为其外部时钟信号XCLK的输入(6—54MHz);
PCLK_O:输出给FBCtl图像缓存控制模块的CLKA,来自于PCLK_I的缓冲,作为图像存储时的像素同步时钟;
PWDN_O:恒定为0,直接输出给摄像头的,起到power_up功能;
RST_O:输出给摄像头,用作摄像头复位(低有效);
VDDEN_O:与Inst_camctlB的相同端口求与后输出到摄像头的VDDEN管脚,应该是连到摄像头,作为工作接通通电源的使能信号;
SCL:输出到摄像头的SCLK端口(FPGA→Camera),作为串行接口的时钟输入;
SDA:输出到摄像头的SDATA端口(FPGA↔Camera),作为串行接口的信号传输。
(3)图像缓存控制模块
Input:
ENC:来自VideoTimingCtl模块的VDE_O端口,读写控制();
RSTC_I:来自SysCon模块的ASYNC_RST端口;
CLKC:来自SysCon模块的PCLK_O端口;
//////////////////////////////////////////////////////////////////////////////
ENB:来自CamCtlB模块的DV_O端口,读写控制(1写);
RSTB_I:来自Inst_InputSync_FVB模块的D_O端口取反与SysCon模块的ASYNC_RST端口求或;
CLKB:来自CamCtlB模块的PCLK_O端口;
/////////////////////////////////////////////////////////////////////////////
ENA:来自CamCtlA模块的DV_O端口,读写控制(1写);
RSTA_I:来自Inst_InputSync_FVA模块的D_O端口取反与SysCon模块的ASYNC_RST端口求或;
CLKA:来自CamCtlA模块的PCLK_O端口;
/////////////////////////////////////////////////////////////////////////////
ddr2clk_2x:来自SysCon模块的DDR2CLK_2X_O端口;
ddr2clk_2x_180:来自SysCon模块的DDR2CLK_2X_180_O端口;
pll_ce_0:来自SysCon模块的PLL_CE_0_O端口;
pll_ce_90:来自SysCon模块的PLL_CE_90_O端口;
pll_lock:来自SysCon模块的PLL_LOCK端口;
async_rst:来自SysCon模块的ASYNC_RST端口;
mcb_drp_clk:来自SysCon模块的MCB_DRP_CLK_O端口;
RD_MODE(1:0):来自SysCon模块的MSEL_O(1:0)端口;
DIB(15:0):来自Inst_camctlB模块的D_O(15:0)端口;
DIA(15:0):来自Inst_camctlA模块的D_O(15:0)端口;
Output:
RDY_O:该信号取反后与SysCon模块的ASYNC_RST信号求或后输给VideoTimingCtl模块的RST_I端口;
mcb3_dram_ras_n:输出给DDR2;
mcb3_dram_cas_n:输出给DDR2;
mcb3_dram_we_n:输出给DDR2;
mcb3_dram_odt:输出给DDR2;
mcb3_dram_cke:输出给DDR2;
mcb3_dram_dm:输出给DDR2;
mcb3_dram_udm:输出给DDR2;
mcb3_dram_ck:输出给DDR2;
mcb3_dram_ck_n:输出给DDR2;
DOC(15:0):输出给DVITransmitter模块的BLUE_I/GREEN_I/RED_I,以RGB565的方式自高位向低位排列;
mcb3_dram_a(12:0):输出给DDR2;
mcb3_dram_ba(2:0):输出给DDR2;
mcb3_dram_udqs:双向端口,连接到DDR2;
mcb3_dram_udqs_n:双向端口,连接到DDR2;
mcb3_rzq:双向端口,连接到DDR2;
mcb3_zio:双向端口,连接到DDR2;
mcb3_dram_dqs:双向端口,连接到DDR2;
mcb3_dram_dqs_n:双向端口,连接到DDR2;
mcb3_dram_dq(15:0):双向端口,连接到DDR2;
第二部分:三维空间定位
- 摄像头模块:在摄像头前加装了两个850nm的红外滤光片,用来滤出红外光点。
模块源代码:
module center(
input pclk, // pixel clock
input din, // 1-bit pixel value, come from BW image buffer
input [11:0] Hcnt, // 0-1599 来自VideoTimmingCtl的HCNT_O
input [10:0] Vcnt, // 0-899 来自VideoTimmingCtl的 VCNT_O
output reg[11:0] center_h, // 0-1599,中点横向坐标
output reg [10:0] center_v // 0-899,中点纵向坐标
);
reg [20:0] num; //亮点区像素总数
wire [19:0] h_num; //亮点区像素总数的一半
reg [20:0] num_cnt; //亮点区像素总数计数
reg [11:0] h_cnt; //中点横向坐标计数
reg [10:0] v_cnt; //中点纵向坐标计数
reg [20:0] center_line_sum; //中间一行的有效像素横坐标和
reg [20:0] center_line_sum_cnt; //中间一行的有效像素横坐标和计数
reg [10:0] center_line_num; //中间一行的有效像素总数
reg [10:0] center_line_num_cnt; //中间一行的有效像素总数计数
assign h_num= num[20:1];
//有效区间
reg en;
always@(*) begin
if(Hcnt>0 && Hcnt<1599 && Vcnt>0 && Vcnt<899)
en<= 1;
else
en<= 0;
end
//亮点区像素总数计数
always@(posedge pclk) begin
if(Hcnt==1 && Vcnt==0) //扫描到像素点(1,0)处时
begin
num_cnt<= 0;
end
else
if(din==1 && en==1) num_cnt<= num_cnt+1;
else num_cnt<= num_cnt;
end
//中点纵坐标计数
always@(posedge pclk) begin
if(num_cnt<h_num) v_cnt<= Vcnt;
else v_cnt<= v_cnt;
end
//中间一行有效像素横坐标和
always@(posedge pclk) begin
if(Hcnt==1 && Vcnt==0) //扫描到像素点(1,0)处时
begin
center_line_sum_cnt<= 0;
end
else
if(Vcnt==center_v && en==1 &&din==1)
center_line_sum_cnt<= center_line_sum_cnt + Hcnt;
else
center_line_sum_cnt<= center_line_sum_cnt;
end
//中间一行的有效像素总数
always@(posedge pclk) begin
if(Hcnt==1 && Vcnt==0) //扫描到像素点(1,0)处时
begin
center_line_num_cnt<= 0;
end
else
if(Vcnt==center_v && en==1 &&din==1)
center_line_num_cnt<= center_line_num_cnt + 1;
else
center_line_num_cnt<= center_line_num_cnt;
end
//除法器
wire rfd;
wire [10:0] fractional;
wire [20:0] quotient;
div Divider (
.rfd(rfd),
.clk(pclk),
.dividend(center_line_sum),
.quotient(quotient),
.divisor(center_line_num),
.fractional(fractional)
);
//一帧结尾赋值
always@(posedge pclk) begin
if(Hcnt==1598 && Vcnt==899)//扫描到像素点(1598,899)处时
begin
num<= num_cnt;
center_v<= v_cnt;
center_h<= quotient[11:0];
center_line_sum<= center_line_sum_cnt;
center_line_num<= center_line_num_cnt;
end
end
endmodule
PC上在Processing环境中开发了一个3D动画界面,通过立方体模拟红外光点的三维位置。该程序接收从开发板经由UART协议发来的光点坐标,并将结果显示在窗口中。
|
|