金牌会员
- 积分
- 1155
- 威望
- 669
- 贡献
- 314
- 兑换币
- 334
- 注册时间
- 2012-4-17
- 在线时间
- 86 小时
- 毕业学校
- 武汉理工大学
|
/*****************************************************************************************************
** OV6620 ImageProcess
** (c) Copyright 2009-2010, DEMOK
** All Rights Reserved
**
** V1.1.0
*****************************************************************************************************/
/////调试发现 串口发送函数放置在主函数循环函数中实时性好 采集70个点噪声较少 而且黑线剧中
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
#define ROW 40
#define COLUMN 65
#define SAMP_ROW_START 11
#define SAMP_ROW_MAX 280
#define THRESHOLD 0x45 //静态阈值
#define ROW_START 1
#define ROW_MID 10
#define ROW_END 36
#define BLACK 0
#define WHITE 1
#define BLACK_LINE_MAX0 15
#define BLACK_LINE_MIN0 4
#define BLACK_LINE_MAX1 12
#define BLACK_LINE_MIN1 2
#define LEFT_LIMIT 1
#define RIHGT_LIMIT 69
#define CENTER 35
unsigned char Buffer[ROW][COLUMN];
unsigned char Buffer_Temp1[ROW][COLUMN];
unsigned char Buffer1[ROW][COLUMN];
unsigned char SampleFlag=0 ;
unsigned char jiange;
unsigned int m=0;
unsigned int n=0;
unsigned int line=0;
unsigned char Flag=0;
unsigned int Line_Center[ROW]={20};
//--------------初始化函数----------------//
/*时钟初始化程序*/
void PLL_Init(void) //PLLCLK=2*OSCCLK*(SYNR+1)/(REFDV+1)
{ //锁相环时钟=2*16*(2+1)/(1+1)=48MHz
CLKSEL=0x00; //48mhz
PLLCTL_PLLON=1;
SYNR=0XC0 | 0X05;
REFDV=0X80 | 0X01;
POSTDIV=0X00;
_asm(nop);
_asm(nop);
while(0==CRGFLG_LOCK);//锁相环锁定
CLKSEL_PLLSEL=1;//选定外部时钟
}
//--------------行场中断初始化-------------//
void IC_Init(void)
{
TIOS=0x00;
TCTL4=0x09;
TSCR1=0x80;
TIE=0x03;
TFLG1=0xFF;
}
void IO_Init(void)
{
DDRA=0X00;
}
//----------初始化SCI0---------------------//
void SCI_Init()
{
SCI0BD=26;
SCI0CR1=0;
SCI0CR2=0X2C;
SCI0DRL = 0XFF;
}
//---------------写SCI数据-------------------//
void SCI_Write(unsigned char sendchar)
{
while (!(SCI0SR1&0x80));
SCI0DRH=0;
SCI0DRL=sendchar;
}
//黑线的中值滤波 取中值
int get_mid(unsigned int a,unsigned int b,unsigned int c)
{
unsigned int x=0; //让灰度值从左到右依次增大
if(a>b){x=b;b=a;a=x;}
if(b>c){x=c;c=b;b=x;}
if(a>b){x=b;b=a;a=x;}
return b ;
}
//求绝对值
int abs_1(int x)
{
if(x<0)x=-x;
return(x);
}
void black_extract(void)
{
unsigned char black_lost=0;//黑线丢失计数器
unsigned char stop=0; //停车圈数计数器
unsigned char i=0,j=0,left=0,right=0,start_flag1=0,start_flag2=0;
unsigned char left_line=0,right_line=0,left_edge=0,right_edge=0;
int temp=0;
unsigned char left_flag1=0,right_flag1=0,left_flag2=0,right_flag2=0;
Line_Center[0]=Line_Center[ROW-1];
////////////////////////////////////////////////////
/////图像前部分用边缘检测法
///////////////////////////////////////////////////
for(i=ROW_START;i<ROW_MID;i++) // 1到10行
{
left=0; //左右跳变清零,这是必须的!!
right=0;
for(j=5;j<=COLUMN-5;j++) //两边搜索 最边界干扰略去 5到65列
{
if(Buffer1[i][j]-Buffer1[i][j+1]>0)
{left=j;left_flag1++;}
if(Buffer1[i][COLUMN-j]-Buffer1[i][COLUMN-j-1]>0)
{right=COLUMN-j;right_flag1++;}
}
//////////求黑线的中心
if((left_flag1==1) && (right_flag1==1))
{
if((right-left>=BLACK_LINE_MIN0)&&(right-left<=BLACK_LINE_MAX0)) //过滤过宽过细的黑线
{
Line_Center[i]=(right+left+1)/2;
_asm(nop);
//black_lost=0;//黑线丢失清零
}
}
else /////////////////过宽过细黑线进行插值
{
if(i<3) Line_Center[i]=Line_Center[i-1];
else
{temp=2*Line_Center[i-1]-Line_Center[i-2];
if(temp>RIHGT_LIMIT) temp=RIHGT_LIMIT;
else if(temp<LEFT_LIMIT) temp=LEFT_LIMIT;
Line_Center[i]=temp;}
}
}
////////////////////////////////////////////////////
/////图像后部分用边缘检测法
///////////////////////////////////////////////////
for(i=ROW_MID;i<ROW;i++)
{
left=0; //左右跳变清零,这是必须的!!
right=0;
for(j=10;j<=COLUMN-10;j++) //两边搜索 最边界干扰略去
{
if(Buffer1[i][j]-Buffer1[i][j+1]>0)
{left=j;left_line=left;}
if(Buffer1[i][COLUMN-j]-Buffer1[i][COLUMN-j-1]>0)
{right=COLUMN-j;right_line=right;}
}
//////////求黑线的中心
if((right-left>=BLACK_LINE_MIN1)&&(right-left<=BLACK_LINE_MAX1)) //过滤过宽过细的黑线
{
Line_Center[i]=(right+left+1)/2;
_asm(nop);
//black_lost=0;//黑线丢失清零
}
else /////////////////过宽过细黑线进行插值
{
temp=2*Line_Center[i-1]-Line_Center[i-2];
if(temp>RIHGT_LIMIT) temp=RIHGT_LIMIT;
else if(temp<LEFT_LIMIT) temp=LEFT_LIMIT;
Line_Center[i]=temp;
}
}
for(i=2;i<ROW;i++)
{
if(abs_1(Line_Center[i-1]-Line_Center[i])>5 ) //黑线是连续的 值还需要确认 即相差多少就认为是错误
{
temp=2*Line_Center[i-1]-Line_Center[i-2];
if(temp>RIHGT_LIMIT)temp=RIHGT_LIMIT;
else if(temp<LEFT_LIMIT)temp=LEFT_LIMIT;
Line_Center[i]=temp;
}
}
//黑线的中值滤波程序!
for(i=1;i<ROW-1;i++)
{temp=get_mid(Line_Center[i-1],Line_Center[i],Line_Center[i+1]);
Line_Center[i]=temp;}
}
void Image_binaryzation(unsigned int row) //二值化程序
{ unsigned char *p_Image;
unsigned char *q_Image;
q_Image=&Buffer1[row][0];
for(p_Image=&Buffer[row][0];p_Image<=&Buffer[row][COLUMN-1];p_Image++)
{
if((*p_Image<THRESHOLD)&&(*(p_Image+1)<THRESHOLD))
*(q_Image++)=BLACK;
else
*(q_Image++)=WHITE;
}
}
void chuli(void)
{
unsigned char i,j;
int temp=0;
for(i=0;i<ROW;i++)
{
temp=Line_Center[i];
for(j=0;j<COLUMN;j++)
{ if(Buffer1[i][j]==0)
Buffer_Temp1[i][j]=0;
// SCI_Write('0') ;
else
Buffer_Temp1[i][j]=0xf0;
if((j>temp-2)&& (j<temp+2))
Buffer_Temp1[i][j]=0;
}
SCI_Write(0x0D);
SCI_Write(0X0A);
}
Flag=1;
}
void SCI0_Transmit(void) //发送信息到DEMO软件
{
byte temp;
unsigned char i,j;
temp = SCI0SR1; //清零
SCI0DRH = 0;
SCI0DRL = 0XFF; //图像头0XFF
while (!(SCI0SR1&0x80));
for(i = 0;i< ROW;i++)
{
for(j = 0;j < COLUMN ;j++)
{
//---------------发送像素数据到DEMOKTOOL---------------------//
if(Buffer_Temp1[i][j] == 0xFF) Buffer_Temp1[i][j] = 0xFE; //若为图像头 自减
SCI0DRL =Buffer_Temp1[i][j];
while (!(SCI0SR1&0x80));
//---------------发送像素数据到DEMOKTOOL---------------------//
}
//SCI0DRL = 0X0A; //回车
//while (!(SCI0SR1&0x80));
//SCI0DRL = 0X0D; //换行
//while (!(SCI0SR1&0x80));
}
}
void main(void)
{
/* put your own code here */
PLL_Init();
IC_Init();
IO_Init();
SCI_Init();
EnableInterrupts;
for(;;)
{
black_extract();
chuli();
SCI0_Transmit();
// _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 Port0_Interrupt()
{
TFLG1_C0F=1;
line++; //行计数器加 1
if ( SampleFlag == 0 || line<SAMP_ROW_START || line>SAMP_ROW_MAX )
{
return;//判断是否从新的一场开始
}
if(line<=132)jiange=12;
else if(line>132&&line<=200) jiange=8;
else if(line>200&&line<=248) jiange=6;
else jiange=4;
if(line%jiange==0)
{
Buffer[m][0] = PORTA;
Buffer[m][1] = PORTA;
Buffer[m][2] = PORTA;
Buffer[m][3] = PORTA;
Buffer[m][4] = PORTA;
Buffer[m][5] = PORTA;
Buffer[m][6] = PORTA;
Buffer[m][7] = PORTA;
Buffer[m][8] = PORTA;
Buffer[m][9] = PORTA;
Buffer[m][10] = PORTA;
Buffer[m][11] = PORTA;
Buffer[m][12] = PORTA;
Buffer[m][13] = PORTA;
Buffer[m][14] = PORTA;
Buffer[m][15] = PORTA;
Buffer[m][16] = PORTA;
Buffer[m][17] = PORTA;
Buffer[m][18] = PORTA;
Buffer[m][19] = PORTA;
Buffer[m][20] = PORTA;
Buffer[m][21] = PORTA;
Buffer[m][22] = PORTA;
Buffer[m][23] = PORTA;
Buffer[m][24] = PORTA;
Buffer[m][25] = PORTA;
Buffer[m][26] = PORTA;
Buffer[m][27] = PORTA;
Buffer[m][28] = PORTA;
Buffer[m][29] = PORTA;
Buffer[m][30] = PORTA;
Buffer[m][31] = PORTA;
Buffer[m][32] = PORTA;
Buffer[m][33] = PORTA;
Buffer[m][34] = PORTA;
Buffer[m][35] = PORTA;
Buffer[m][36] = PORTA;
Buffer[m][37] = PORTA;
Buffer[m][38] = PORTA;
Buffer[m][39] = PORTA;
Buffer[m][40] = PORTA;
Buffer[m][41] = PORTA;
Buffer[m][42] = PORTA;
Buffer[m][43] = PORTA;
Buffer[m][44] = PORTA;
Buffer[m][45] = PORTA;
Buffer[m][46] = PORTA;
Buffer[m][47] = PORTA;
Buffer[m][48] = PORTA;
Buffer[m][49] = PORTA;
Buffer[m][50] = PORTA;
Buffer[m][51] = PORTA;
Buffer[m][52] = PORTA;
Buffer[m][53] = PORTA;
Buffer[m][54] = PORTA;
Buffer[m][55] = PORTA;
Buffer[m][56] = PORTA;
Buffer[m][57] = PORTA;
Buffer[m][58] = PORTA;
Buffer[m][59] = PORTA;
Buffer[m][60] = PORTA;
Buffer[m][61] = PORTA;
Buffer[m][62] = PORTA;
Buffer[m][63] = PORTA;
Buffer[m][64] = PORTA;
Buffer[m][65] = PORTA;
Buffer[m][66] = PORTA;
Buffer[m][67] = PORTA;
Buffer[m][68] = PORTA;
Buffer[m][69] = PORTA;
Buffer[m][70] = PORTA;
Buffer[m][71] = PORTA;
Buffer[m][72] = PORTA;
Buffer[m][73] = PORTA;
Buffer[m][74] = PORTA;
Buffer[m][75] = PORTA;
Buffer[m][76] = PORTA;
Buffer[m][77] = PORTA;
Buffer[m][78] = PORTA;
Buffer[m][79] = PORTA;
Buffer[m][80] = PORTA;
Buffer[m][81] = PORTA;
Buffer[m][82] = PORTA;
Buffer[m][83] = PORTA;
Buffer[m][84] = PORTA;
Buffer[m][85] = PORTA;
Buffer[m][86] = PORTA;
Buffer[m][87] = PORTA;
Buffer[m][88] = PORTA;
Buffer[m][89] = PORTA;
Buffer[m][90] = PORTA;
Buffer[m][91] = PORTA;
Buffer[m][92] = PORTA;
Buffer[m][93] = PORTA;
Buffer[m][94] = PORTA;
Buffer[m][95] = PORTA;
Buffer[m][96] = PORTA;
Buffer[m][97] = PORTA;
Buffer[m][98] = PORTA;
Buffer[m][99] = PORTA;
Buffer[m][100] = PORTA;
Buffer[m][101] = PORTA;
Buffer[m][102] = PORTA;
Buffer[m][103] = PORTA;
Buffer[m][104] = PORTA;
Buffer[m][105] = PORTA;
Buffer[m][106] = PORTA;
Buffer[m][107] = PORTA;
Buffer[m][108] = PORTA;
Buffer[m][109] = PORTA;
Buffer[m][110] = PORTA;
Buffer[m][111] = PORTA;
Buffer[m][112] = PORTA;
Buffer[m][113] = PORTA;
Buffer[m][114] = PORTA;
Buffer[m][115] = PORTA;
Buffer[m][116] = PORTA;
Buffer[m][117] = PORTA;
Buffer[m][118] = PORTA;
Buffer[m][119] = PORTA;
m++;
}
Image_binaryzation(m);
}
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 9 Port1_interrupt()
{
TFLG1_C1F=1; //清场中断
TFLG1_C0F=1; //清行中断
m=0; //列清零
line=0; //行计数器
SampleFlag=1;//场标志位置 1
Flag=0;
}
怎么运行不了,显示越界了,,求指导
|
|