这套摄像头处理算法是可以直接使用的。只需要重写一下void servo()//舵机控制函数
输入的参数是**extern uint8 image_dec[60][80];**数组中保存的摄像头传过来二值化后的数据。
输出是距离赛道的偏差 保存在整形变量:duojijiaodu 中。把这个变量传入舵机打脚的pid算法中即可。
讲道理这样基本就可以用了。如果想跑的更顺畅,更快的话需要调整最下面代码中的

 my_piancha=(int)(mzd2*currentzhongjian_lk - mzd1*B);//0.95,0.32//偏差合成,控制转弯,1.1倍的点+0,9倍的斜率构成总的偏差

通过修改两个参数控制曲率和偏差的融合来实现。
注意:摄像头循迹不会走赛道中线,尤其在拐弯时。比如再拐一个左弯时,在入弯时车模会贴赛道右侧,出弯时会贴赛道左侧。这样可以保证高速过弯且不会冲出赛道。
这些代码是我之前上传文件的一部分。摄像头四轮

使用时,需要依次调用函数:
//摄像头转向控制
lkcongzhongjiansaomiao();
pianchachuli();
servo();

/*
摄像头循迹程序
我们这一届摄像头20CM高度,没法发挥出摄像头的优势,内切一直压线,
这个程序在30CM高度的摄像头中可以跑的3M/s数组   static int half_width_group【】中保存的是赛道宽的一半,可以在实际中测量然后修改这个数组中的数据。最终偏差是由中线的差值和曲率融合。pianchachuli()函数中my_piancha=(int)(mzd2*currentzhongjian_lk - mzd1*B);
这个表达式完成融合,可以通过调整两个参数的大小让小车转弯更顺滑,不压线servo函数中是控制舵机打脚,其中16.5/70是打角的系数,再乘以上面的my_piancha变量就是实际舵机需要打的角度*/
#include "saomiao.h"#include "headfile.h" //白1 黑0#include "math.h"
int qianzhan=29;
int my_piancha,my_lastzhongjian=40;
int jiao, x,y,linshi_x,linshi_right_heixian,linshi_y,ruyuanhuan_flag=0;
extern uint8 image_dec[60][80];int [60],right_heixian[60],left_heixian[60],zhidao_flag;
int lastpiancha_1,lastpiancha_2,lastpiancha_3,lastpiancha_4,duojijiaodu,flag_l=0,flag_r=0,linshi_left_heixian,B,shaobudaozuo_flag[60],shaobudaoyou_flag[60];
int shizidiyidian,shangshizidiyidian,S_Z;
int shizishu,chazhi,yy1,yy2,rushizi;
int duandian,duandianshu,duandianshu1,currentzhongjian_lk;
int xielv_flag;
int qulv_point=0,zhangai_right=0,zhangai_left=0;
int dian1,youshi_kuan_flag=0;
char s_wan_flag,shizi_flag,yuanhuan_flag=0,guai_flag=0;
int qvlv_quanju,qulv_jinduan,qulv_yuandaun;
int qulv_jinduan_right=0,qulv_jinduan_left=0,qulv_yuandaun_right=0,qulv_yuandaun_left=0,qvlv_quanju_right=0,qvlv_quanju_left=0;
int half_zhi[60];
int yy1_pinjun,yy2_pinjun;static int half_width_group[60]=
{0,0,0,0,0,0,0,0,8,
9,10,11,12,12,13,15,16,17,18,
19,20,21,22,23,24,25,25,26,28,
29,30,30,31,32,33,34,35,35,36,
37,38,38,39,39,40,40,40,40,40,
40,40,40,40,40,40,40,40,40,40
};
int regression(int startline,int endline)   //线性回归方程计算斜率
{if(endline>56)endline=56;int i;int sumX=0,sumY=0,avrX=0,avrY=0 ;int num=0,B_up1=0,B_up2=0,B_up,B_down;for(i=startline;i<=endline;i++){num++;sumX+=i;sumY+=currentzhongjian[i];}avrX=sumX/num;avrY=sumY/num;B_up=0;B_down=0;for(i=startline;i<=endline;i++){B_up1=(int)(currentzhongjian[i]-avrY);B_up2=i-avrX;B_up+=(int)(10*(B_up1*B_up2));B_up=B_up/100*100;B_down+=(int)(10*((i-avrX)*(i-avrX)));}if(B_down==0) B=0;else B=B_up*16/B_down;//16return B;
}int hy;
void huaxian(int x1,int y1,int x2,int y2)//将两个点之间连成一条线段
{int i,max,a1,a2;a1=x1;a2=x2;if(a1>a2){max=a1;a1=a2;a2=max;}
for(i=x1;i>0;i--)
{if((x2-x1)!=0){hy=(i-x1)*(y2-y1)/(x2-x1)+y1;currentzhongjian[i]=hy;if(hy<=1||hy>=79)break;}
}
}
void huaxian2(int xxx1,int yyy1,int xxx2,int yyy2)//两点之间的线段
{int i2,max2,a12,a22;a12=xxx1;a22=xxx2;if(a12>a22){max2=a12;a12=a22;a22=max2;}
for(i2=xxx1;i2<59;i2++)
{if((xxx2-xxx1)!=0){hy=(i2-xxx1)*(yyy2-yyy1)/(xxx2-xxx1)+yyy1;currentzhongjian[i2]=hy;}
}
}//*****************************************************舵机控制函数**********************************************************//
void servo()//舵机控制函数
{jiao= Servo_Center-(int)((duojijiaodu*16.5/70));//舵机的pid算法公式,没有小数,所以要除以70来实现小数
if(jiao>=Servo_Left)
jiao=Servo_Left;
if(jiao<=Servo_Right)
jiao=Servo_Right;
servo_PWM(jiao);
}
//***************************************************扫描函数***************************************************************//
void lkcongzhongjiansaomiao()
{int kuan_flag=0,lo=0,s_point=0,S_COUNT=0,fuduandian=0,qulv_yuanhuan=0,chushizi_flag=0;memset(shaobudaozuo_flag,0,sizeof(shaobudaozuo_flag));//清零函数memset(shaobudaoyou_flag,0,sizeof(shaobudaoyou_flag));int zhangai_flag=0,qulv_s_y=0,qulv_s_l=0;shangshizidiyidian=0;left_heixian[59]=0;right_heixian[59]=79; shizishu=0;rushizi=0;xielv_flag=0;shizi_flag=0;my_lastzhongjian=39;if(currentzhongjian[58])currentzhongjian[59]=my_lastzhongjian=currentzhongjian[58];elsecurrentzhongjian[59]=39;for(y=58;y>=0;y--)//扫描完58,整副图像处理完毕{for(x=my_lastzhongjian;x<=79;x++)//从中间向右扫描{if(image_dec[y][x]==0){right_heixian[y]=x;shaobudaoyou_flag[y]=1; break;}}for(x=my_lastzhongjian;x>=0;x--)//向左扫描{ if(image_dec[y][x]==0){left_heixian[y]=x;shaobudaozuo_flag[y]=1;break;}  }if(fuduandian==0){if(y>48)//丢边补线,加整个赛道补线{if(shaobudaoyou_flag[y]==0&&shaobudaozuo_flag[y]==1)//扫不到右{ right_heixian[y]=left_heixian[y]+2*half_width_group[y];//y为数组中的x值}else if(shaobudaoyou_flag[y]==1&&shaobudaozuo_flag[y]==0)//扫不到左{left_heixian[y]=right_heixian[y]-2*half_width_group[y];}else if(shaobudaoyou_flag[y]==0&&shaobudaozuo_flag[y]==0)//都扫不到{left_heixian[y]=0;//如果两边都扫不到,直接从中间提取中线right_heixian[y]=79;}}else if(y<=48)//更远的补线,{if(shaobudaoyou_flag[y]==0&&shaobudaozuo_flag[y]==1)//扫不到右{ right_heixian[y]=right_heixian[y+1]+(abs)(left_heixian[y]-left_heixian[y+1])-1;//根据左边这一点与上一点,//(y+1)为数组中上一次的x坐标,//left_heixian[y]-left_heixian[y+1]算左边偏移量,减一为后期补偿}else if(shaobudaoyou_flag[y]==1&&shaobudaozuo_flag[y]==0)//扫不到左{left_heixian[y]=left_heixian[y+1]-(abs)(right_heixian[y+1]-right_heixian[y])+1;}else if(shaobudaoyou_flag[y]==0&&shaobudaozuo_flag[y]==0)//都扫不到{left_heixian[y]=0;right_heixian[y]=79;}}//*************************************中线处理*********************************************************//currentzhongjian[y]=(int)((right_heixian[y]+left_heixian[y])/2);  //提取中间线(左边加右边比2)half_zhi[y]=(int)((right_heixian[y]-left_heixian[y])/2);  //一半赛道值(没用,不改)//*******************************************************中线滤波防止中线出现毛刺**************************************************/if(currentzhongjian[y]-currentzhongjian[y+1]>4&&y<42&&B<0)
currentzhongjian[y]=currentzhongjian[y+1]+1;
if(currentzhongjian[y]-currentzhongjian[y+1]<-4&&y<42&&B>0)
currentzhongjian[y]=currentzhongjian[y+1]-1;  /******************************************************************曲率计算**************************************************************/
if(y>30)//曲率近端判断
{if((currentzhongjian[y]-currentzhongjian[y+1])>0)
qulv_jinduan_right++;
else
if((currentzhongjian[y]-currentzhongjian[y+1])<0)
qulv_jinduan_left++;
}
if(y<25&&y>=7)//曲率远端判断,远处的一点就不要了
{if((currentzhongjian[y]-currentzhongjian[y+1])>0)
qulv_yuandaun_right++;
else if((currentzhongjian[y]-currentzhongjian[y+1])<0)
qulv_yuandaun_left++;
}
if(y<=55&&y>15)//曲率全局判断
{if((currentzhongjian[y]-currentzhongjian[y+1])>0)
qvlv_quanju_right++;
else
if((currentzhongjian[y]-currentzhongjian[y+1])<0)
qvlv_quanju_left++;}if(currentzhongjian[y]>79)//中线的限制幅度
currentzhongjian[y]=79;if(currentzhongjian[y]<0)
currentzhongjian[y]=0;my_lastzhongjian=currentzhongjian[y];//保存中间点坐标
if(y<56)//小s位置判断,小s弯道作直线冲刺
{if((currentzhongjian[y]-currentzhongjian[y+2])>0)
qulv_s_y++;
else
if((currentzhongjian[y]-currentzhongjian[y+2])<0)
qulv_s_l++;
if(y>36&&abs(currentzhongjian[y]-currentzhongjian[y+2])>0)
qulv_yuanhuan++;
//printf("y:%d\n",qulv_s_y);
//printf("l:%d\n",qulv_s_l);
}
if(y<58&&y>=10)
S_COUNT+=currentzhongjian[y];
// *******************************************小S断点搜索*********************************************//if(y>8&&(abs)(right_heixian[y]-currentzhongjian[y])<5||(abs)(left_heixian[y]-currentzhongjian[y])<5)//小S断点判定s_point=y;//
else
s_point=0;// *******************************************防止扫到跑道外*********************************************//if(y<36&&((abs)(right_heixian[y]-currentzhongjian[y])<1||(abs)(left_heixian[y]-currentzhongjian[y])<1))//防止扫到跑道外面
{duandian=y;fuduandian=y;if(y>15){duandianshu=y-15;if(duandianshu>35)duandianshu=35;}if(y>qianzhan){duandianshu1=y-qianzhan;if(duandianshu1>25)duandianshu1=25;}
}
else
{duandian=0;duandianshu=0;duandianshu1=0;
}}}if(right_heixian[y]-left_heixian[y]<half_width_group[y]&&right_heixian[y+1]-left_heixian[y+1]<half_width_group[y+1])//防止扫到跑道外面break;
//}
//********************************************************y行结束标志*******************************************************S_Z=S_COUNT/(48);//********************************************************************曲率计算*******************************************************************qvlv_quanju=abs(qvlv_quanju_right-qvlv_quanju_left);//曲率全局qulv_jinduan=abs(qulv_jinduan_right-qulv_jinduan_left);//曲率近端qulv_yuandaun=abs(qulv_yuandaun_right-qulv_yuandaun_left);//曲率远端qvlv_quanju_right=qvlv_quanju_left=qulv_jinduan_right=qulv_jinduan_left=qulv_yuandaun_right=qulv_yuandaun_left=0;// *******************************************************十字处理*********************************************************//if(duandian<16) // *****************************十字{for(int i=58;i>7;i--){ if(i>45&&(shaobudaozuo_flag[i]==1||shaobudaoyou_flag[i]==1))rushizi++;if((i>9&&i<=40)&&shaobudaozuo_flag[i]==0&&shaobudaoyou_flag[i]==0)shizishu++;if(i<45&&(shaobudaozuo_flag[i]==1||shaobudaoyou_flag[i]==1)&&shangshizidiyidian==0)shangshizidiyidian=i;}if(shizishu>2&&rushizi>10)//刚入十字{shizi_flag=1;//gpio_set(PTE1,1);xielv_flag=1;for(int i=49;i>0;i--){      if(shaobudaozuo_flag[i]==0&&shaobudaoyou_flag[i]==0){shizidiyidian=i;break;}     }if(shizidiyidian<34){yy1=shizidiyidian+19;yy2=shizidiyidian+24;}else if(shizidiyidian<40){yy1=shizidiyidian+13;yy2=shizidiyidian+18;}else if(shizidiyidian<45){yy1=shizidiyidian+9;yy2=shizidiyidian+13;}else if(shizidiyidian<49){yy1=shizidiyidian+6;yy2=shizidiyidian+10;}elseif(shizidiyidian<55){yy1=shizidiyidian+2;yy2=shizidiyidian+4;}yy1_pinjun=(currentzhongjian[yy1]+currentzhongjian[yy1+1]+currentzhongjian[yy1-1])/3;yy2_pinjun=(currentzhongjian[yy2]+currentzhongjian[yy2+1]+currentzhongjian[yy2-1])/3;//if(!ruyuanhuan_flag)huaxian(yy1,yy1_pinjun,yy2,yy2_pinjun); //huaxian(yy1,currentzhongjian[yy1],yy2,currentzhongjian[yy2]); }
else if(shizishu>4&&rushizi<=10&&shangshizidiyidian>=20)//出十字{chushizi_flag=1;// gpio_set(PTE1,1);xielv_flag=1;shizi_flag=1;//if(!ruyuanhuan_flag)huaxian2(shangshizidiyidian-6,currentzhongjian[shangshizidiyidian-6],58,currentzhongjian[58]);}//  gpio_set(PTE1,0);}//********************************************************圆环检测*******************************************************
if(shizi_flag&&qulv_yuanhuan<=10&&qulv_jinduan<7&&!chushizi_flag)
{signed char kkk=0,black_num=0;for( kkk=(int)(currentzhongjian[58]+currentzhongjian[57]+currentzhongjian[56])/3;kkk<=79;kkk++)//向右扫描黑块点数{if(!image_dec[8][kkk]||!image_dec[10][kkk]){black_num++;}elsebreak;}for( kkk=(int)(currentzhongjian[58]+currentzhongjian[57]+currentzhongjian[56])/3;kkk>=0;kkk--)//向左扫描黑块点数{if(!image_dec[8][kkk]||!image_dec[10][kkk]){black_num++;}elsebreak;}if(black_num>36)//检测到圆环{yuanhuan_flag++;//gpio_set(PTC18,0);//点亮led提示}else{yuanhuan_flag=0;//gpio_set(PTC18,1);关闭led提示}}
else
{yuanhuan_flag=0;//gpio_set(PTC18,1);//关闭led提示
}if(yuanhuan_flag>3)//连续检测到圆环三次以上
{guai_flag=1;
//gpio_set(PTA14,1);
}// ***********************************************************小S弯判定*小S弯判定*****************************************************//
if(s_point==0&&qulv_s_y>6&&qulv_s_l>6&&zhidao_flag<20&&!shizi_flag)
{s_wan_flag=1;//led(LED0, LED_ON);
}
else
{s_wan_flag=0;
//led(LED0, LED_OFF);
}}
//************************************************图像处理结束,下面是偏差处理************************************************/void pianchachuli()//偏差处理
{if(xielv_flag==0)regression(15+duandianshu,43+duandianshu);///斜率计算dian1=abs((currentzhongjian[52]+currentzhongjian[53]+currentzhongjian[54])/3-39);
//lins=currentzhongjian[30];
currentzhongjian_lk=(currentzhongjian[qianzhan+duandianshu1]-39);//点if(B>19)
B=19;
if(B<-19)
B=-19;float mzd1=0.11;  //曲率与中线合成的权值
float mzd2=0.75;
my_piancha=(int)(mzd2*currentzhongjian_lk - mzd1*B);//0.95,0.32//偏差合成,控制转弯,1.1倍的点+0,9倍的斜率构成总的偏差if(!ruyuanhuan_flag&&ruyuanhuan_flag<10)//拐50ms
{ruyuanhuan_flag++;
if(my_piancha<-4&&shizi_flag)//右边进的圆环
my_piancha+=13;
else
if(my_piancha>4&&shizi_flag)//左边进的圆环
my_piancha-=13;
}
else
ruyuanhuan_flag=0;lastpiancha_4=lastpiancha_3;
lastpiancha_3=lastpiancha_2;
lastpiancha_2=lastpiancha_1;
lastpiancha_1=duojijiaodu;
duojijiaodu=my_piancha; }

恩智浦智能车赛。摄像头处理函数。相关推荐

  1. 浅谈全国大学生智能车竞赛-摄像头组图像处理及控制算法

    由于是第一次写技术博客,先做一下自我介绍.本人本科专业是光电信息科学与工程(工),就读于长春理工大学光电工程学院,研究生为华中科技大学光学工程专业.本科期间参加参加过各类比赛,其中印象最深的还是智能车 ...

  2. 飞思卡尔智能车之摄像头使用篇

    飞思卡尔智能车之摄像头使用    今天来给大家说说摄像头的使用,很显然摄像头对摄像头组的重要性是不言而喻的,因为摄像头是小车提取赛道信息最关键的传感器了,所以只有把摄像头使用好才能让你的小车快速稳定的 ...

  3. 恩智浦智能车核心板LPC54606PCB原理图

    恩智浦智能车核心板LPC54606PCB原理图 做了份LPC54606的核心板,用来给学弟学妹们学习焊接和编程,引脚几乎全引出,数字地模拟地之前做了隔离处理,测试后可用,压缩包含 PCB的3D展示感兴 ...

  4. 恩智浦智能车MOS双驱动

    "恩智浦"智能车MOS双驱动 特性: 控制信号3.3V与5V兼容 模块供电电压:5V-12V 双路PWM调制,控制电机正反转,占空比0%~100% 工作频率可达200KHz(建议频 ...

  5. 恩智浦智能车大赛2020_我校AI电磁车队荣获2020年全国大学生“恩智浦”杯智能汽车竞赛全国一等奖...

    日前,第十五届"恩智浦"全国大学生智能汽车竞赛线下全国总决赛在南京信息工程大学落幕.我校工程实训中心智能车工作室天职师大AI电磁车队在毛福新老师的指导下,精心准备,沉着应战,一路过 ...

  6. 恩智浦智能车大赛2020_内蒙古科技大学第九届智能车大赛校内公开赛总决赛

    为了激发学生的创新意识,提高学生的动手能力,培养团队合作意识,秉承"实践源于真知,创新放飞梦想"的思想.2020年12月6日,内蒙古科技大学第九届智能车大赛总决赛如约而至.本次大赛 ...

  7. 恩智浦智能车大赛2020_我院第十三届“恩智浦”杯智能车校内选拔赛宣讲会顺利举行...

    2020年11月28日9:00,第十三届"恩智浦"杯智能车校内选拔赛宣讲会在长安大学北校区明远2201教室成功举行. 到场嘉宾 本次活动由我院大学生科技创新创业协会智能车部承办.本 ...

  8. 第十五届智能车赛比赛 比赛组织参考文档

    第十五届全国大学生智能车竞赛 比赛组织参考文档 作者:卓晴博士 全国大学生智能车竞赛秘书处 2020-07-27 Monday 2020年由于全球新冠肺炎大流行的影响,使得第十五届智能车竞赛在组织比赛 ...

  9. 恩智浦智能车大赛2020_2020年中国人工智能机器人大赛在宝鸡市会展中心举办

    11月20日,2020年中国人工智能机器人大赛在陕西宝鸡会展中心开幕.本次大赛为期三天,将有来自湖北.河南.山西等地的530余支队伍同台比拼. 据了解,大赛分为预赛.初赛.决赛,期间将进行垃圾分类机器 ...

  10. 2020恩智浦智能车大赛规则_2020年世界人工智能围棋大赛落幕,各路围棋AI共同论道...

    作为今年世界三大人工智能赛事之一,"福建海峡银行杯"2020年世界人工智能围棋大赛于12月3日完赛,上届冠军星阵围棋成功卫冕,采薇围棋.天狗围棋.里拉零分别夺得亚军.季军和第四名. ...

最新文章

  1. c语言通讯录打电话,C语言实现简易通讯录 | 术与道的分享
  2. Outlook addon CommandBarButton picture 的不透明效果解决方案
  3. 使用SQL脚本创建数据库,操作主键、外键与各种约束(MS SQL Server)
  4. .NET Windows服务应用程序
  5. qq截图工具提取_QQ截图隐藏的这些简单又实用的技能,怪我没早告诉你
  6. sql中 in 、not in 、exists、not exists 用法和差别
  7. 《ArcGIS Runtime SDK for .NET开发笔记》--三维功能
  8. CodeForces 828E DNA Evolution(树状数组)题解
  9. js获取元素,窗口的宽度、高度
  10. B - 好数 51Nod - 1717
  11. 按钮按一下画个直线_直线导轨数控车床概念和作用
  12. JavaSE 字符串
  13. rk3399pro添加ALC5640音频配置
  14. 叶俊—中国的安东尼·罗宾
  15. struct template 函数 特化
  16. 放弃了又何需执着 ?
  17. excel高效之指定列求和、列加单位、列间做基础运算
  18. 滕州小学计算机教室,东湖教育四十年|滕州小学--小学校 大世界
  19. 英语四六级保命班笔记
  20. css动画中文字慢慢显示,利用定时器和css3动画制作文字依次渐变显示的效果

热门文章

  1. 因子分析怎么计算权重?
  2. 《SAP从入门到精通》——1.2 SAP系统实施思想
  3. scrapy爬取cnnvd网址数据
  4. 基于暗通道先验的单幅图像去雾
  5. Anaconda下载源设置及还原默认
  6. ie11不兼容java_解决ie11不兼容的多个方法
  7. Apizza-绑定数据模型
  8. 柔性电子综述2014:Wearable Electronics and Smart Textiles 可穿戴电子设备
  9. Java开发手册归纳知识点
  10. 集成电路模拟版图入门-版图基础学习笔记(四)