常驻嘉宾
- 积分
- 3091
- 威望
- 2551
- 贡献
- 482
- 兑换币
- 0
- 注册时间
- 2012-5-28
- 在线时间
- 29 小时
- 毕业学校
- 湖北
|
1贡献
这是我在红树伟业的程序基础上增加了自己的思想
本来的思想是 前五行从中间向两边扫描(一定至少又一边会有线的,我用模拟信号看过,而且左边的线离车最近处一定在车的左边,右边同理,摄像头旋转180度安装,这样一幅图像上面就是离车最近车,方便编程) 之后就边缘追踪扫描
如果哪边没有扫描到黑线就根据一条黑线提取中线 并且没有扫到黑线的一边下一行还是从中间扫描这一边,直到这边扫到为止又追踪扫描
本来程序编好了 可是不怎么理想,下面就是一个简单的中间向两边扫描的程序,效果不怎么好 结果就是几个黑点,没有得到三条线(两边的黑线和中线),请各位走过的路过的指点下 我的思想有什么问题没有,还有我下面这么简单的程序为什么会得到的几个黑点
/********************************************************************************/
/********************************************************************************
红树伟业智能车专业店MC9S12XS128汽车电子综合开发平台
淘宝店?:ttp://hongshuweiye.taobao.com/
原创时间:2012年3月10号
客服手机:13926966989
客服QQ :372618964
代码交流:191364597@qq.com
*********************************************************************************
*********************************************************************************/
#include <hidef.h>
#include "derivative.h"
#include <mc9s12xs128.h>
#define ROW 40 //数字摄像头所采集的二维数组行数
#define COLUMN 120 //数字摄像头所采集的二维数组列数
#define ROW_START 10 //数字摄像头二维数组行开始行值
#define ROW_MAX 200 //数字摄像头所采集的二维数组行最大值
#define THRESHOLD 0xB0 //图像阈值,根据所采集图像亮度值大小的实际情况调整(OV7620所采集的亮度值大小为0--255)
#define COLUMN_mid 60
unsigned char Buffer[ROW][COLUMN]={0}; //所采集的图像二维数组
unsigned char Image_Center[ROW]={0}; //所采集的图像中心线
unsigned char SampleFlag=0; //奇偶场标记
unsigned int m=0; //换行变量
unsigned int Line; //行中断计数变量
unsigned int hang;
unsigned char flag,right_flag,left_flag;
unsigned int Get_Image[]={
17,19,21,23,25,28,31,34,37,40,43,46,49,53,57,
61,65,69,73,77,81,85,89,94,99,105,111,117,123,
129,135,141,147,153,159,166,173,180,187
}; //定每场采哪几行。
/*************************************************************/
/* 初始化PLL函数 */
/*************************************************************/
void PLL_Init(void) {
CLKSEL=0X00; //disengage PLL to system
PLLCTL_PLLON=1; //turn on PLL
SYNR =0xc0 | 0x09;
REFDV=0x80 | 0x01;
POSTDIV=0x00; //pllclock=2*osc*(1+SYNR)/(1+REFDV)=160MHz;
_asm(nop); //BUS CLOCK=80M
_asm(nop);
while(!(CRGFLG_LOCK==1)); //when pll is steady ,then use it;
CLKSEL_PLLSEL =1; //engage PLL to system;
}
/*************************************************************/
/* 行场中断初始化函数 */
/*************************************************************/
void TIM_Init(void)
{
TIOS=0x00; //外部输入捕捉0,1通道
TCTL4=0x09; //通道0 上升沿触发,通道1下降沿触发
TSCR1=0x80; //使能
TIE=0x03; //通道 0,1 中断使能
TFLG1=0xFF; //清中断标志位
}
/*************************************************************/
/* IO口初始化函数 */
/*************************************************************/
void IO_Init(void)
{
DDRA=0X00; //端口A配置成输入
}
/*************************************************************/
/* 延时函数 */
/*************************************************************/
void delays(long m){
while(m--);
}
/*************************************************************/
/* 串口0初始化函数 */
/*************************************************************/
void SCI_Init()
{
SCI0BD=261; //19200bps Baud Rate=BusClock/(16*SCIBD)
//SCI0BD=521;
SCI0CR1=0; //正常8 位模式,无奇偶校验
SCI0CR2=0X2C; //发送允许 接受中断允许
}
/*************************************************************/
/* 串口0发送函数 */
/*************************************************************/
void SCI_Write(unsigned char SendChar)
{
while (!(SCI0SR1&0x80));
SCI0DRH=0;
SCI0DRL=SendChar;
}
/*************************************************************/
/* 向电脑串口发送所采集的图像 */
/*************************************************************/
void Process(void) {
unsigned char i,j;
for(i=0;i<ROW;i++) {
for(j=0;j<COLUMN;j++) {
if(Buffer[j]==0)////////////////////if(Buffer[j]>=THRESHOLD)
SCI_Write('0');////////////////////SCI_Write('1');
else SCI_Write('1');/////////////else SCI_Write('0');
}
SCI_Write(0x0D);
SCI_Write(0x0A);
}
}
/*************************************************************/
void tiquheixian(void) { //功能 提取中线 同时用电脑显示两边黑线和中线
unsigned char i,j,k,t;// i行参数 j一行向左扫描参数 k一行向右扫描参数
for(i=0;i<ROW;i++) {//摄像头倒装 180度 上面就是离车最近的地方
flag=0; //只扫描到一条线时 上一行跟下一行偏移量
for(j=COLUMN_mid;j>2;j--) {//行有中间向左扫描
left_flag=0; //左边是否有黑线标志 0表示无
right_flag=0; //右边是否有线标志 0表示无
if((Buffer[j]>=THRESHOLD)&&(Buffer[j-1]>=THRESHOLD)) {
Buffer[j]=0; //左边扫到黑线位置
left_flag++; //左边有线标志
break;
}
}
for(k=COLUMN_mid;k<119;k++) {//行由中间向右扫描
if((Buffer[k]<=THRESHOLD)&&(Buffer[k+1]<=THRESHOLD)) {
Buffer[j]=0;//右边黑线位置
right_flag++; //右边有线标志
break;
}
}
if(left_flag&&right_flag) {//如果两边都有线
t=(unsigned char)(j+k)/2;
Buffer[t]=0;//中心黑线位置
} else if(left_flag){//只有左边有线
flag+=2; //根据观察远一行比进一行到中线距离小2 一般远处就能扫到两条线那就可以直接按两条线提取中线
t=j+60-flag; //向右偏移60-flag
Buffer[t]=0;
} else{//只有右边有线
flag+=2;
t=k-60+flag;
Buffer[t]=0;
}
}
}
/*************************************************************/
/* 主函数 */
/*************************************************************/
void main(void)
{
/* put your own code here */
PLL_Init();
TIM_Init();
IO_Init();
SCI_Init();
EnableInterrupts;
for(;;)
{
tiquheixian();
Process(); //向电脑串口发送所采集的图像
}
// _FEED_COP(); /* feeds the dog */
/* loop forever */
/* please make sure that you never leave main */
}
/*************************************************************/
/* 行中断处理函数 */
/*************************************************************/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 8 PT0_Interrupt()
{
TFLG1_C0F=1; //行中断标志位清除,以便于下次行中断进行
Line++; //行中断计数变量
if ( SampleFlag == 0 || Line<ROW_START || Line>ROW_MAX )
{
return; //不是要采集图像的有效行,返回
}
if( Line==Get_Image[hang])
{
delays(8);
Buffer[m][0]=PORTA;_asm();Buffer[m][1]=PORTA;_asm();Buffer[m][2]=PORTA;_asm();Buffer[m][3]=PORTA;_asm();Buffer[m][4]=PORTA;_asm();
Buffer[m][5]=PORTA;_asm();Buffer[m][6]=PORTA;_asm();Buffer[m][7]=PORTA;_asm();Buffer[m][8]=PORTA;_asm();Buffer[m][9]=PORTA;_asm();
Buffer[m][10]=PORTA;_asm();Buffer[m][11]=PORTA;_asm();Buffer[m][12]=PORTA;_asm();Buffer[m][13]=PORTA;_asm();Buffer[m][14]=PORTA;_asm();
Buffer[m][15]=PORTA;_asm();Buffer[m][16]=PORTA;_asm();Buffer[m][17]=PORTA;_asm();Buffer[m][18]=PORTA;_asm();Buffer[m][19]=PORTA;_asm();
Buffer[m][20]=PORTA;_asm();Buffer[m][21]=PORTA;_asm();Buffer[m][22]=PORTA;_asm();Buffer[m][23]=PORTA;_asm();Buffer[m][24]=PORTA;_asm();
Buffer[m][25]=PORTA;_asm();Buffer[m][26]=PORTA;_asm();Buffer[m][27]=PORTA;_asm();Buffer[m][28]=PORTA;_asm();Buffer[m][29]=PORTA;_asm();
Buffer[m][30]=PORTA;_asm();Buffer[m][31]=PORTA;_asm();Buffer[m][32]=PORTA;_asm();Buffer[m][33]=PORTA;_asm();Buffer[m][34]=PORTA;_asm();
Buffer[m][35]=PORTA;_asm();Buffer[m][36]=PORTA;_asm();Buffer[m][37]=PORTA;_asm();Buffer[m][38]=PORTA;_asm();Buffer[m][39]=PORTA;_asm();
Buffer[m][40]=PORTA;_asm();Buffer[m][41]=PORTA;_asm();Buffer[m][42]=PORTA;_asm();Buffer[m][43]=PORTA;_asm();Buffer[m][44]=PORTA;_asm();
Buffer[m][45]=PORTA;_asm();Buffer[m][46]=PORTA;_asm();Buffer[m][47]=PORTA;_asm();Buffer[m][48]=PORTA;_asm();Buffer[m][49]=PORTA;_asm();
Buffer[m][50]=PORTA;_asm();Buffer[m][51]=PORTA;_asm();Buffer[m][52]=PORTA;_asm();Buffer[m][53]=PORTA;_asm();Buffer[m][54]=PORTA;_asm();
Buffer[m][55]=PORTA;_asm();Buffer[m][56]=PORTA;_asm();Buffer[m][57]=PORTA;_asm();Buffer[m][58]=PORTA;_asm();Buffer[m][59]=PORTA;_asm();
Buffer[m |
|