智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 12844|回复: 22
打印 上一主题 下一主题

我编的提取中线的程序

  [复制链接]

8

主题

53

帖子

0

精华

常驻嘉宾

Rank: 8Rank: 8

积分
3091

优秀会员奖章

威望
2551
贡献
482
兑换币
0
注册时间
2012-5-28
在线时间
29 小时
毕业学校
湖北
跳转到指定楼层
1#
发表于 2012-6-6 21:45:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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

12

主题

1121

帖子

0

精华

常驻嘉宾

Rank: 8Rank: 8

积分
3668

优秀会员奖章活跃会员奖章在线王奖章论坛元老奖章

QQ
威望
1871
贡献
1107
兑换币
93
注册时间
2011-3-14
在线时间
345 小时
2#
发表于 2012-6-7 11:51:54 | 只看该作者
谢谢分享!
回复

使用道具 举报

8

主题

126

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1417
QQ
威望
749
贡献
308
兑换币
100
注册时间
2011-3-7
在线时间
180 小时
3#
发表于 2012-6-8 17:24:46 | 只看该作者
你好,可以把后面的也加上吗?谢谢了
回复

使用道具 举报

8

主题

126

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1417
QQ
威望
749
贡献
308
兑换币
100
注册时间
2011-3-7
在线时间
180 小时
4#
发表于 2012-6-8 17:48:52 | 只看该作者
还有个问题,就是你每行都将flag清零,这样这个变量不久没意义了吗
回复

使用道具 举报

0

主题

35

帖子

0

精华

高级会员

Rank: 4

积分
722
威望
428
贡献
178
兑换币
120
注册时间
2012-8-6
在线时间
58 小时
毕业学校
东山大学
5#
发表于 2012-9-7 20:03:55 | 只看该作者
回复

使用道具 举报

0

主题

67

帖子

0

精华

高级会员

Rank: 4

积分
995
威望
460
贡献
249
兑换币
297
注册时间
2012-10-17
在线时间
143 小时
6#
发表于 2013-1-1 16:09:50 | 只看该作者
:D
回复

使用道具 举报

17

主题

466

帖子

0

精华

杰出人士

Rank: 12Rank: 12Rank: 12

积分
13941
QQ
威望
10902
贡献
2497
兑换币
716
注册时间
2011-9-24
在线时间
271 小时
7#
发表于 2013-1-1 17:31:51 | 只看该作者
vgjkl 发表于 2012-6-7 11:51
谢谢分享!

呵呵,人家是来求助的吧
回复

使用道具 举报

21

主题

892

帖子

0

精华

常驻嘉宾

爱板者

Rank: 8Rank: 8

积分
3857

活跃会员奖章优秀会员奖章在线王奖章论坛元老奖章

威望
1833
贡献
1048
兑换币
736
注册时间
2012-12-4
在线时间
488 小时
8#
发表于 2013-1-18 16:15:17 | 只看该作者
求中线提取程序 和思想 资料好难懂啊
回复

使用道具 举报

2

主题

108

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1175
威望
744
贡献
247
兑换币
92
注册时间
2011-3-31
在线时间
93 小时
9#
发表于 2013-3-4 23:40:03 | 只看该作者
此算法有漏洞,在弯道处
回复

使用道具 举报

0

主题

33

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
210
威望
131
贡献
47
兑换币
62
注册时间
2012-11-4
在线时间
16 小时
毕业学校
合肥大学
10#
发表于 2013-3-20 19:05:51 | 只看该作者
小s弯的话 不是很好啊
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-5 18:52 , Processed in 0.097034 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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