整理摄像头图像采集模块讲解.docx
《整理摄像头图像采集模块讲解.docx》由会员分享,可在线阅读,更多相关《整理摄像头图像采集模块讲解.docx(156页珍藏版)》请在冰点文库上搜索。
整理摄像头图像采集模块讲解
一、智能车制作路线图
二、摄像头组小车构成框图
三、智能车摄像头类型
图像传感器根据感光原理可以分为CCD图像传感器和CMOS图像传感器。
根据信号输出形式又可以分为模拟信号输出与数字信号输出。
下面分别就图像传感器的这几种类型进行简单的讨论。
其摄像头的分类和大概的优缺点如上图所示,CCD摄像头的优点是图像质量高,动态性能好。
缺点是素元颗粒大,体积大,能耗高(往往需要12VDC升压电路),需要外围电路控制,且无法和外围信号处理电路集成。
但是因其成像质量较CMOS好的原因,高端照相机,摄像机等对图像质量要求较高的设备往往使用CCD图像传感器。
CMOS的缺点是图像质量较CCD差,动态性能不如CCD。
但CMOS的优点是像素元颗粒小,体积也小,像素阵列可以和信号处理器集成在一起,由于集成了内部信号处理器,所以可以设置参数,故CMOS芯片一般可以直接同步输出数字信号和时序信号。
CMOS图像传感器的图像质量虽然较CCD的差,但是并没有影响到智能车的控制或者说没有严重到不可克服的程度。
而通过上文介绍,我们知道CMOS传感器相较于CCD有着以下的优点:
CMOS图像传感器功耗小,一般只需5V电压即可工作,甚至有3.3V型号,相较与CCD的12V电压需求相比,CMOS传感器的电源与系统大多数芯片和控制电路相兼容,无需额外升压电路,采用CMOS简化了电路,提高了可靠性。
四、摄像头信号转化有很多种方案
方案一:
采用单片机的AD口,读取图像数据。
这个方案的优点是外接电路简单。
缺点是受到单片机AD转换速率的影响,读取的数据慢,而且数据错误率较高,同时严重的占用单片机的资源,导致程序运行慢等的缺点。
一般单片机超频到64M下,一行采集大概是80个点。
其精度对于图像的分析是不够的,特别是前瞻50cm以后的信号。
所以一般刚刚接触摄像头的选手会选择此方案。
但是稍微要提高车子的速度,该方案有很大的局限。
所以我们手创科技不推荐选手选择此方案。
方案二:
采用片外AD芯片,例如是高速AD转换芯片:
TLC5511。
其优点是转化速率快,能够实现比较准确的数据转换。
但其缺点是外围电路比较复杂,同时占用8个单片机IO口,成本比较高等。
从对图像的黑线提取的角度考虑,比较难实现动态阀值(动态阀值提取黑线的具体原理,下面会介绍)。
TLC5511电路图如下图说明:
方案三:
采用高速比较器,例如是高速比较器AD8032,(我们试验LM393也可以达到此效果)。
通过选择合适的电压作为比较器的参考电压,把图像信号转化为高低电平信号,其输出信号直接接到单片机的IO口,可以读取到图像信号,一般可得到黑线为1,白板为0的图像信号,(或者是黑线为0,白板为1的图像信息)。
此方案优点是数据转化速率快,若输出信号接单片机低位的IO口,同时单片机超频到64M和使用指针程序,一行可以采集到250个点。
同时能够实现准确的数据转换(几乎不会出错)。
其精度对于图像的分析是够的,一般在光线均匀和参考电压合理的前提下,最远处的黑线信号可以采集到4-5个点。
此方案缺点是参考电压固定不变,若不经过其他电路或者软件处理,很难实现动态阀值,所以导致图像信号受环境光线强度的影响。
造成车子的环境适应能力很差,特别是当车跑的快时,容易丢失信号,造成车子未能正确识别路径。
所以此方案虽然有很大的优点,但也有其比较致命的缺点。
手创科技团队根据以上三种方案的分析,决定充分利用方案三的优点,同时解决了方案三的缺点,提出了方案四,方案四是在方案三的基础上改进的,并且把方案四的技术集成到手创科技团队开发的摄像头,该摄像头输出行中断信号,场中断信号,图像黑线和白板的高低电平信号(这里是通过电路实现的,输出的电平信号可以直接接单片机任意的一个IO口,都可以读取图像信息)。
方案四:
?
?
采用高速比较器,例如是高速比较器AD8032,(我们试验LM393也可以达到此效果)。
通过镜像电路,得出与原图像信号相反的电压信号作为比较器的参考电压,(也就是按照我们人的思维,当摄像头输出电压比较高的白板时,我们希望找到一个比这个白板的电压低很多的电压值作为比较器的参考电压,同时若摄像头输出电压比较低的黑线时,我们希望找到一个比这个黑线的电压高很多的电压值作为比较器的参考电压,这样的话,我们就能够确保比较器输出的信号是准确的。
把原始的图像信号镜像后作为比较器的参考电压,刚刚好符合这个人的思维)把图像信号转化为高低电平信号,其输出信号直接接到单片机的IO口,就可以读取到图像信号,一般可得到黑线为1,白板为0的图像信号,(或者是黑线为0,白板为1的图像信息)。
此方案优点是数据转化速率快,若输出信号接单片机低位的IO口,同时单片机超频到64M和使用指针程序,一行可以采集到250左右个点。
同时能够实现准确的数据转换(出错率小于0.1%)。
同时当环境光线变化时,本摄像头因给比较器的参考电压相对空间比较大(也就是白板给的电压比较低,黑线给的电压比较高),所以环境变化造成的信号变化,对本摄像头的影响很小,单片机不用采用任何处理,一般光线在比较大的范围内变化,最远处的黑线信号都可以采集到4-5个点,其精度对于图像的分析是绝对够的,同时也能确保在不同光线的环境下,也能输出正确的黑线信号。
所以采用此方案,在调整好相对镜像电压后,选手不必担心光线不均匀对车子的影响,甚至不用但光线对车子的影响。
(当然这里要说明的是,任何技术都是在一定范围内实现的,也就是说本摄像头虽然环境适应能力强,但是也不是万能的摄像头,选手不要误会我们的摄像头能够识别晚上黑暗和太阳光下的环境。
明确的说明,我们的摄像头做不到这样。
我们摄像头是在一定光线强度下,能够比较强的适应环境的变化。
)
此方案缺点:
由于镜像电路需要响应时间(镜像电路的工作频率150MHZ),故一行图像中黑线的起始点与没有采用镜像电路的方案三相比将往后推迟一个点左右,但几乎不影响黑线的提取,采用此方案,提取的点个数不变。
所以此方案有很大的优点,缺点相对对车子的影响可以忽略。
{
下面,我简单分析下目前各视频采集方案的优劣:
1.模拟摄像头(CCD和模拟CMOS)+LM1881==》MCUA/D(我们采用的是硬件的二值化法)
这个方案应该说是最经典的方案,
优点:
成本低(LM1881只要10元);方案实现简单(只需根据几个同步信号,开启AD连续采集即可);
缺点:
需要A/D速度支持,以获得高分辨率。
A/D速度与MCU总线时钟有关,所以需要超频,但MCU稳定性必须牺牲。
改进:
为提高图像采集的分辨率,有的队伍引入高速片外AD,效果也很不错,如上海大学白骑士,AD采用5510这类已足够,价格15元左右
2.模拟摄像头(CCD和模拟CMOS)+SAA7113视频解码+AL422B==》MCUIO
这个方案个人所知只有第二届华南理工用过
优点:
经典的图像采集方案,为各视频采集卡和其他产品所应用,能完整采集整幅图像。
摄像头兼容性好,可以随时更换更好的摄像头,获得更清晰图像,而采集部分软硬件不需要做太大改变
缺点:
方案复杂,涉及大量逻辑操作,一般用CPLD或FPGA配合。
在智能车比赛中,规定不能使用可编程器件,使用74做逻辑功能,控制几个芯片较为复杂,体积、可靠性都很难保证,制作难度较大。
涉及IIC操作,增加调试时间难度。
3.数字摄像头(CMOS数字:
OV7620等)==》MCUIO
这个方案是网友们提出的,其监视数字摄像头的VSYN和HREF信号,每行开始时,连续读取MCU与CMOS连接的数据口Y口。
优点:
数字摄像头方案,采集简单,无需A/D
缺点:
与模拟摄像头+AD类似,采集分辨率与MCU频率相关。
数字摄像头信号输出频率可高达13.5MHz,没有DMA功能MCU从IO读信号再写入内存,速度跟不上,同样需要牺牲稳定性进行超频使用。
因为没有引入PCLK视频同步信号,直接采集CMOS数据口,有可能会采集到不稳定的数据(即CMOS数据口状态正在改变时)这一点可能造成严重的干扰
4.数字摄像头(CMOS数字:
OV7620等)+FIFO==》MCUIO
优点:
这个方案克服了方案3中MCU速度与CMOS不匹配的问题,采用FIFO作为缓冲,可以采集完整图像。
图像采集分辨率与FIFO容量有关。
缺点:
FIFO价格较高,特别是大容量。
若使用视频FIFO,性价比较高,但同样有方案2中大量逻辑器件的问题。
CMOS模块性价比极低,CMOS芯片只需20-30元,售价200元
}
五、以ov5116摄像头为例的信号转化
5.1ov5116信号讲解
本摄像头原始的视频信号如下图所示。
与理论的视频信号相吻合
经过串口和调试程序得到的图像信息。
5.2硬件电路讲解
5.3软件部分讲解
#include
#include"derivative.h"
#defineuintunsignedint
#defineucharunsignedchar
voidpll_init();
voidpwm_init();
voiddelayms(uintms);
voidIO_Init(void);
voidTIM_Init(void);
voidSCI_Init(void);
voidSCI_Write(unsignedcharSendChar);
voiddelay(uintnum);
voidmyfun();
#definelie31
#definehang_end130
ucharc_lie=0;
uintlie_count=0;
ucharta[lie][hang_end];
uintget_hang[]={17,40,60,78,94,109,123,135,146,156,
165,174,181,187,195,200,206,210,215,219,
223,227,231,234,237,240,243,245,248,250,251};
uinth,l,i,mlz,mly,zhongxian,lie_1,start_flag=0;
voidmain()
{
pll_init();
pwm_init();
IO_Init();
TIM_Init();
SCI_Init();
EnableInterrupts;
DDRE=0xff;
for(;;)
{
/*for(lie_1=0;lie_1{
for(i=0;i<130;i++)
{
if(ta[lie_1][i]),
{
SCI_Write(0x20);///出***
}else
{
SCI_Write(0x2a);////出
}
}
SCI_Write(0x0d);////回车
SCI_Write(0x0a);
}*/
myfun();
}
}
voidmyfun()
{
if(PTJ_PTJ7==0)//舵机开关
{
start_flag=!
start_flag;
DDRE=~DDRE;//指示灯
PWME_PWME3=!
PWME_PWME3;//舵机
PWME_PWME1=!
PWME_PWME1;//电机
delayms(100);
while(PTJ_PTJ7==0);
}
if(PTJ_PTJ6==0)//电机开关
{
PWMDTY01=500;
PORTB_PB6=!
PORTB_PB6;
delayms(100);
while(PTJ_PTJ6==0);
}
if(start_flag)
{
h=5;
for(l=0;l<130;l++)
{
if(ta[h][l])
{
mlz=l;
for(l=129;l>0;l--)
{
if(ta[h][l]==1)
{
mly=l;
zhongxian=(mlz+mly)/2;
if(zhongxian>90)
{
PWMDTY23=3000;
}
elseif(zhongxian<40)
{
PWMDTY23=5500;
}
else
{
PWMDTY23=4300;
}
break;
}
}
break;
}
}
}else
{
//PORTB=0x00;
PWME=0x00;
}
/*for(l=0;l<130;l++)
{
if(ta[h][l]==1)
{
mlz=l;
for(l=129;l>0;l--)
{
if(ta[h][l]==1)
{
mly=l;
zhongxian=(mlz+mly);
zhongxian=zhongxian/2;
if(zhongxian>65)
{
PWMDTY23=3500;
PORTE=0xff;
}
else
{
PWMDTY23=5000;
PORTE=0x00;
}
break;
}
}
break;
}
}*/
}
voiddelay(uintnum)
{
uinta,b;
for(a=0;afor(b=0;b<48;b++);
}
voidpll_init()
{
CLKSEL=0X00;
PLLCTL_PLLON=1;
SYNR=0Xc0|0X05;
REFDV=0X80|0X01;
POSTDIV=0X00;
_asm(nop);
_asm(nop);
_asm(nop);
while(!
CRGFLG_LOCK);
CLKSEL_PLLSEL=1;//48MHZ;
}
//PWM输出的初始化
voidpwm_init(void)
{
PWME=0x00;
PWMCTL=0x30;//在通道1,3输出
PWMPOL=0x0a;//3,5通道初始输出高电平
PWMCLK=0x00;/*全选AB*/
PWMPRCLK=0x33;//Busclock/8=6MHZdianjiduoji6MHZ
PWMCAE=0x0a;//中心对齐方式输出
PWMPER01=3000;//01通道1Khz
PWMDTY01=0;
PWMPER23=60000;//舵机50HZ
PWMDTY23=4300;//3000左转极限!
5500右转极限!
////////4500-中间
//PWME=0x0a;//通道3,1使能
}
voiddelayms(uintms)
{
uintm,n;
for(m=ms;m>0;m--)
for(n=4400;n>0;n--);
}
voidSCI_Init(void)
{
SCI0BD=312.5;//115200bps
SCI0CR1=0;//正常8位模式,无奇偶校验
SCI0CR2=0X2C;//发送接受允许中断允许
}
voidSCI_Write(unsignedcharSendChar)
{
while(!
(SCI0SR1&0x80));
SCI0DRH=0x00;
SCI0DRL=SendChar;
}
voidTIM_Init(void)
{
TIOS=0x00;//外部输入捕捉0,1通道
TCTL4=0x09;//通道0上升沿触发行中,通道1下降沿触发场中断
TSCR1=0x80;//使能
TSCR2=0X00;
TIE=0x03;//通道0,1中断使能
TFLG1=0xFF;//清中断标志位
}
voidIO_Init(void)
{
DDRS_DDRS2=0;//行中断的采集口
DDRJ_DDRJ7=0;
DDRJ_DDRJ6=0;
DDRB=0xff;
PORTB=0x00;
}
#pragmaCODE_SEG__NEAR_SEGNON_BANKED
voidinterrupt8PT0_Interrupt(void)
{
DisableInterrupts;
TFLG1_C0F=1;
delay
(1);//确保不采到消隐信号
if(lie_count==get_hang[c_lie]&&c_lie{
ta[c_lie][0]=PTS_PTS2;ta[c_lie][1]=PTS_PTS2;ta[c_lie][2]=PTS_PTS2;
ta[c_lie][3]=PTS_PTS2;ta[c_lie][4]=PTS_PTS2;ta[c_lie][5]=PTS_PTS2;
ta[c_lie][6]=PTS_PTS2;ta[c_lie][7]=PTS_PTS2;ta[c_lie][8]=PTS_PTS2;
ta[c_lie][9]=PTS_PTS2;ta[c_lie][10]=PTS_PTS2;ta[c_lie][11]=PTS_PTS2;
ta[c_lie][12]=PTS_PTS2;ta[c_lie][13]=PTS_PTS2;ta[c_lie][14]=PTS_PTS2;
ta[c_lie][15]=PTS_PTS2;ta[c_lie][16]=PTS_PTS2;ta[c_lie][17]=PTS_PTS2;
ta[c_lie][18]=PTS_PTS2;ta[c_lie][19]=PTS_PTS2;ta[c_lie][20]=PTS_PTS2;
ta[c_lie][21]=PTS_PTS2;ta[c_lie][22]=PTS_PTS2;ta[c_lie][23]=PTS_PTS2;
ta[c_lie][24]=PTS_PTS2;ta[c_lie][25]=PTS_PTS2;ta[c_lie][26]=PTS_PTS2;
ta[c_lie][27]=PTS_PTS2;ta[c_lie][28]=PTS_PTS2;ta[c_lie][29]=PTS_PTS2;
ta[c_lie][30]=PTS_PTS2;ta[c_lie][31]=PTS_PTS2;ta[c_lie][32]=PTS_PTS2;
ta[c_lie][33]=PTS_PTS2;ta[c_lie][34]=PTS_PTS2;ta[c_lie][35]=PTS_PTS2;
ta[c_lie][36]=PTS_PTS2;ta[c_lie][37]=PTS_PTS2;ta[c_lie][38]=PTS_PTS2;
ta[c_lie][39]=PTS_PTS2;ta[c_lie][40]=PTS_PTS2;ta[c_lie][41]=PTS_PTS2;
ta[c_lie][42]=PTS_PTS2;ta[c_lie][43]=PTS_PTS2;ta[c_lie][44]=PTS_PTS2;
ta[c_lie][45]=PTS_PTS2;ta[c_lie][46]=PTS_PTS2;ta[c_lie][47]=PTS_PTS2;
ta[c_lie][48]=PTS_PTS2;ta[c_lie][49]=PTS_PTS2;ta[c_lie][50]=PTS_PTS2;
ta[c_lie][51]=PTS_PTS2;ta[c_lie][52]=PTS_PTS2;ta[c_lie][53]=PTS_PTS2;
ta[c_lie][54]=PTS_PTS2;ta[c_lie][55]=PTS_PTS2;ta[c_lie][56]=PTS_PTS2;
ta[c_lie][57]=PTS_PTS2;ta[c_lie][58]=PTS_PTS2;ta[c_lie][59]=PTS_PTS2;
ta[c_lie][60]=PTS_PTS2;ta[c_lie][61]=PTS_PTS2;ta[c_lie][62]=PTS_PTS2;
ta[c_lie][63]=PTS_PTS2;ta[c_lie][64]=PTS_PTS2;ta[c_lie][65]=PTS_PTS2;
ta[c_lie][66]=PTS_PTS2;ta[c_lie][67]=PTS_PTS2;ta[c_lie][68]=PTS_PTS2;
ta[c_lie][69]=PTS_PTS2;ta[c_lie][70]=PTS_PTS2;ta[c_lie][71]=PTS_PTS2;
ta[c_lie][72]=PTS_PTS2;ta[c_lie][73]=PTS_PTS2;ta[c_lie][74]=PTS_PTS2;
ta[c_lie][75]=PTS_PTS2;ta[c_lie][76]=PTS_PTS2;ta[c_lie][77]=PTS_PTS2;
ta[c_lie][78]=PTS_PTS2;ta[c_lie][79]=PTS_PTS2;ta[c_lie][80]=PTS_PTS2;
ta[c_lie][81]=PTS_PTS2;ta[c_lie][82]=PTS_PTS2;ta[c_lie][83]=PTS_PTS2;
ta[c_lie][84]=PTS_PTS2;ta[c_lie][85]=PTS_PTS2;ta[c_lie][86]=PTS_PTS2;
ta[c_lie][87]=PTS_PTS2;ta[c_lie][88]=PTS_PTS2;ta[c_lie][89]=PTS_PTS2;
ta[c_lie][90]=PTS_PTS2;ta[c_lie][91]=PTS_PTS2;ta[c_lie][92]=PTS_PTS2;
ta[c_lie][93]=PTS_PTS2;ta[c_lie][94]=PTS_PTS2;ta[c_lie][95]=PTS_PTS2;
ta[c_lie][96]=PTS_PTS2;ta[c_lie][97]=PTS_PTS2;ta[c_lie][98]=PTS_PTS2;
ta[c_lie][99]=PTS_PTS2;ta[c_lie][100]=PTS_PTS2;ta[c_lie][101]=PTS_PTS2;
ta[c_lie][102]=PTS_PTS2;ta[c_lie][103]=PTS_PTS2;ta[c_lie][104]=PTS_PTS2;
ta[c_lie][105]=PTS_PTS2;ta[c_lie][106]=PTS_PTS2;ta[c_lie][107]=PTS_PTS2;
ta[c_lie][108]=PTS_PTS2;ta[c_lie][109]=PTS_PTS2;ta[c_lie][110]=PTS_PTS2;
ta[