智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 2454|回复: 5
打印 上一主题 下一主题

7620摄像头的处理

[复制链接]

15

主题

89

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1155
威望
669
贡献
314
兑换币
334
注册时间
2012-4-17
在线时间
86 小时
毕业学校
武汉理工大学
跳转到指定楼层
1#
发表于 2013-9-29 13:41:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*****************************************************************************************************
**                            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;
}
怎么运行不了,显示越界了,,求指导

9

主题

161

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2881

优秀会员奖章活跃会员奖章在线王奖章

威望
1361
贡献
804
兑换币
904
注册时间
2012-12-9
在线时间
358 小时
2#
发表于 2013-9-29 19:53:06 | 只看该作者
unsigned char Buffer[ROW][COLUMN];
unsigned char Buffer_Temp1[ROW][COLUMN];
unsigned char Buffer1[ROW][COLUMN];
数组不要定义的这么多 ,像你这样定义  对于XS128来说肯定越界啊
回复 支持 反对

使用道具 举报

15

主题

89

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1155
威望
669
贡献
314
兑换币
334
注册时间
2012-4-17
在线时间
86 小时
毕业学校
武汉理工大学
3#
 楼主| 发表于 2013-9-29 21:36:23 | 只看该作者
破风浪挂云帆 发表于 2013-9-29 19:53
unsigned char Buffer[ROW][COLUMN];
unsigned char Buffer_Temp1[ROW][COLUMN];
unsigned char Buffer1[ ...

那么,怎么处理这个问题呢?数组个数不变的前提之下。
回复 支持 反对

使用道具 举报

9

主题

161

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2881

优秀会员奖章活跃会员奖章在线王奖章

威望
1361
贡献
804
兑换币
904
注册时间
2012-12-9
在线时间
358 小时
4#
发表于 2013-9-30 18:55:05 | 只看该作者
李洋洋 发表于 2013-9-29 21:36
那么,怎么处理这个问题呢?数组个数不变的前提之下。

当初  我也是遇到了这样的问题,但图像采集的确是用不到这么多的数组吧!
回复 支持 反对

使用道具 举报

10

主题

95

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2653
威望
1291
贡献
808
兑换币
815
注册时间
2012-11-8
在线时间
277 小时
5#
发表于 2013-9-30 19:52:51 | 只看该作者
求指教
回复 支持 反对

使用道具 举报

15

主题

89

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1155
威望
669
贡献
314
兑换币
334
注册时间
2012-4-17
在线时间
86 小时
毕业学校
武汉理工大学
6#
 楼主| 发表于 2013-9-30 22:55:40 | 只看该作者
破风浪挂云帆 发表于 2013-9-30 18:55
当初  我也是遇到了这样的问题,但图像采集的确是用不到这么多的数组吧!

我试一下减少两个。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-7-1 13:40 , Processed in 0.050658 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表