欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
K60項目設計智能車最終代碼
[打印本頁]
作者:
lxshuai
時間:
2018-2-18 11:32
標題:
K60項目設計智能車最終代碼
項目設計智能車最終代碼
0.png
(44.55 KB, 下載次數: 47)
下載附件
2018-2-19 03:13 上傳
單片機源程序如下:
#include "common.h"
#include "camera.h"
#include "gpio.h"
#include "exti.h"
#include "uart.h"
#include "roadJudge.h"
#include "arm_math.h"
#include "FTM.h"
#include "delay.h"
#include "isr.h"
//變量定義
unsigned char threshold;
unsigned char Is_SendPhoto=0;
unsigned char Pix_data[V][H]={0},Bina_data[V][H]={0};// int *p=new int[len];V=50;H=150;
int LeftBorder[V]={0},RightBorder[V]={0}, CenterLine[V]={0};//記錄左右邊界,和中間線
unsigned char CCD_V,CCD_H;//
unsigned char top_line=40,top_line1=50,top_line2=48;//為什么用char型
long count,WhiteNum;
unsigned char width_count=50;
unsigned char width_min=50;
unsigned char V_count=0; //采集行計數
unsigned char jump_point;
unsigned char last_top;//unsigned char到底是數還是字符啊?
unsigned char top_top_line=49;
unsigned char THRE[20];
long thre_sum=0;
unsigned char thread_count;
unsigned char center_min=30;
unsigned char left_line,right_line;
unsigned int left_count,right_count;
/* unsigned char left_tiaobian=0;
unsigned char right_tiaobian=0;
unsigned char left_guaidian=0;
unsigned char right_guaidian=0;
unsigned char left_tiaobian_row=0;
unsigned char right_tiaobian_row=0;
unsigned char left_guaidian_row=0;
unsigned char right_guaidian_row=0;
*/
//攝像頭初始化
void CameraInit()
{
exti_init(PORTC,1,rising_down); //行中斷,PORTC1 端口外部中斷初始化 ,上升沿觸發中斷,內部下拉,,,初始化外部中斷,內部函數,設定外部中斷(IO),
disable_irq(89); //行中斷關閉,,,89表示irq中斷向量號
disable_irq(90); //場中斷關閉,,,新的一幅圖像,下降沿有效
exti_init(PORTD,1,falling_down); //場中斷,PORTD1 端口外部中斷初始化 ,下降沿觸發中斷,內部下拉
}
//二值化函數
void BinaData()
{
int i=0,j=0;
//count=0;
unsigned char *p;
for(i=0;i<V;i++)
{
p=Pix_data[i];
for(j=0;j<H;j++)
{
if(*(p+j)>=threshold)
{
Bina_data[i][j]=1;
// count++;
}
else Bina_data[i][j]=0;
}
}
}
//整場去燥
void AllFilt()
{
count=0;
//unsigned char sum;
for(CCD_V=1;CCD_V<V-1;CCD_V++)
{
for(CCD_H=1;CCD_H<H-1;CCD_H++)
{
if(Bina_data[CCD_V][CCD_H]==1)
{ if((Bina_data[CCD_V-1][CCD_H]==1 || Bina_data[CCD_V+1][CCD_H]==1) && (Bina_data[CCD_V][CCD_H-1]==1 || Bina_data[CCD_V][CCD_H+1]==1))
{
Bina_data[CCD_V][CCD_H]=1;
count++;
}
else
Bina_data[CCD_V][CCD_H]=0;
/* sum=0;
sum=sum + Bina_data[CCD_V-1][CCD_H] + Bina_data[CCD_V-1][CCD_H-1] + Bina_data[CCD_V-1][CCD_H+1]
+ Bina_data[CCD_V][CCD_H-1] + Bina_data[CCD_V][CCD_H+1] + Bina_data[CCD_V+1][CCD_H+1]
+ Bina_data[CCD_V+1][CCD_H-1] + Bina_data[CCD_V+1][CCD_H];
if(sum>=4) Bina_data[CCD_V][CCD_H]=1;
else Bina_data[CCD_V][CCD_H]=0;
*/
}
else if(Bina_data[CCD_V][CCD_H]==0)
{
if((Bina_data[CCD_V-1][CCD_H]==0 || Bina_data[CCD_V+1][CCD_H]==0) && (Bina_data[CCD_V][CCD_H-1]==0 || Bina_data[CCD_V][CCD_H+1]==0))
{
Bina_data[CCD_V][CCD_H]=0;
}
else
{
Bina_data[CCD_V][CCD_H]=1;
count++;
}
/*sum=0;
sum=sum + Bina_data[CCD_V-1][CCD_H] + Bina_data[CCD_V-1][CCD_H-1] + Bina_data[CCD_V-1][CCD_H+1]
+ Bina_data[CCD_V][CCD_H-1] + Bina_data[CCD_V][CCD_H+1] + Bina_data[CCD_V+1][CCD_H+1]
+ Bina_data[CCD_V+1][CCD_H-1] + Bina_data[CCD_V+1][CCD_H];
if(sum<=6) Bina_data[CCD_V][CCD_H]=0;
else Bina_data[CCD_V][CCD_H]=1;*/
}
}
}
}
//統計圖像下半部分白點數
void WhiteCount()
{
WhiteNum=0;
for(CCD_V=0;CCD_V<25;CCD_V++)
for(CCD_H=0;CCD_H<H;CCD_H++)
if(Bina_data[CCD_V][CCD_H]==1)
WhiteNum++;
}
//中心線提取,,,480*640,LINE去除掉起始行
void get_center()
{
unsigned char *p;
static unsigned char last_center=75;
for(CCD_V=0;CCD_V<LINE;CCD_V++)//,,,為什么是前五行,視野最前方提取有何意義
{
p=Bina_data[CCD_V];
for(CCD_H=75;CCD_H>1;CCD_H--)//中間往右
{
if((*(p+CCD_H)==0) && (*(p+CCD_H-1)==0) && (*(p+CCD_H-2)==0)) //右邊黑線檢測,,,連續三列為黑
{
RightBorder[CCD_V]=CCD_H;//記錄列數
break;//找到該行的左邊界
}
else RightBorder[CCD_V]=0; //如果右邊沒有檢測到有黑線
}
for(CCD_H=75;CCD_H<H-2;CCD_H++) //中間往左
{
if((*(p+CCD_H)==0) && (*(p+CCD_H+1)==0) && (*(p+CCD_H+2)==0)) //左邊黑線檢測
{
LeftBorder[CCD_V]=CCD_H;
break;
}
else LeftBorder[CCD_V]=149; //如果左邊沒有檢測到有黑線
}
CenterLine[CCD_V]=(LeftBorder[CCD_V]+RightBorder[CCD_V])/2; //計算中心線
if(fabsf(CenterLine[4]-last_center)>=8) //基準,,,第五行有什么用?
CenterLine[4]=last_center;
last_center=CenterLine[4];
if((LeftBorder[CCD_V]-RightBorder[CCD_V])>width_count) //判斷賽道寬度,CCD_V=4
width_count=LeftBorder[CCD_V]-RightBorder[CCD_V];//width_count最大值, CenterLine記錄中間線, CenterLine[4]有什么特殊的?
}
for(CCD_V=LINE;CCD_V<V;CCD_V++)
{
p=Bina_data[CCD_V];
for(CCD_H=(unsigned char )CenterLine[CCD_V-1];CCD_H>1;CCD_H--)//中間往右,,,為什么是四行的中間點,而不是75?
{
if((*(p+CCD_H)==0) && (*(p+CCD_H-1)==0) && (*(p+CCD_H-2)==0)) //右邊黑線檢測
{
RightBorder[CCD_V]=CCD_H;
break;
}
else RightBorder[CCD_V]=0;
}
for(CCD_H=(unsigned char )CenterLine[CCD_V-1];CCD_H<H-2;CCD_H++) //中間往左,,,,能增加運算速度
{
if((*(p+CCD_H)==0) && (*(p+CCD_H+1)==0) && (*(p+CCD_H+2)==0)) //左邊黑線檢測
{
LeftBorder[CCD_V]=CCD_H;
break;
}
else LeftBorder[CCD_V]=149;
}
CenterLine[CCD_V]=(LeftBorder[CCD_V]+RightBorder[CCD_V])/2;
if((LeftBorder[CCD_V]-RightBorder[CCD_V])>width_count) ////判斷賽道寬度
width_count=LeftBorder[CCD_V]-RightBorder[CCD_V];//這真的是判斷賽道寬度嘛?這簡直在找最寬的賽道嘛?
}
}
//
void centeradjust()
{
for(CCD_V=top_line-1;CCD_V<V;CCD_V++)//四十行開始往上
{
if(LeftBorder[top_line-2]>=145 || LeftBorder[top_line-3]>=145)//如果上兩行的左邊界有一個大于145,(其實右邊界),調整思路是什么?
{
CenterLine[CCD_V]= (int)((147-left_offset_row)*1.0/(V-1-top_line)*(CCD_V+2-top_line)+0.5)+
left_offset_row; //這一堆可能在矯正些什么
if(CenterLine[CCD_V]>=147) CenterLine[CCD_V]=147;//左邊界最大到147,
}
if(RightBorder[top_line-2]<=5 || RightBorder[top_line-3]<=5)
{
CenterLine[CCD_V]=(int)((2-right_offset_row)*1.0/(V-1-top_line)*(CCD_V+2-top_line)+0.5)+right_offset_row;//右邊界的矯正
if(CenterLine[CCD_V]<=3) CenterLine[CCD_V]=2;
}
}
}
//起跑線,有點迷?
void stop_line()
{
Right_dot=0;
left_dot=0;
if(stop_flag==1)
{
for(CCD_V=10;CCD_V<15;CCD_V++)
{
for(CCD_H=RightBorder[20];CCD_H<=CenterLine[20];CCD_H++)
{
if(Bina_data[CCD_V][CCD_H]==0)//為何不統計寬度?統計勞什子的黑點數
Right_dot++;
}
for(CCD_H=CenterLine[20];CCD_H<=LeftBorder[20];CCD_H++)
{
if(Bina_data[CCD_V][CCD_H]==0)
left_dot++;
}
if((LeftBorder[CCD_V]-RightBorder[CCD_V])<width_min)
width_min=LeftBorder[CCD_V]-RightBorder[CCD_V]; //有點蒙了
}
if(Right_dot>=30 && Right_dot<=90 && left_dot<=90 && left_dot>=30 && top_line1>=45)
{
FTM_PWM_Duty(FTM0,CH4,1000);//要減速嘛?4,5通道是干嘛的?
FTM_PWM_Duty(FTM0,CH5,0);
if(gpio_get(PORTA,13)==0) delayms(50);//PORTA是干啥的?
if(gpio_get(PORTA,14)==0) delayms(50);
if(gpio_get(PORTA,15)==0) delayms(50);
if(gpio_get(PORTA,16)==0) delayms(50);
if(gpio_get(PORTA,12)==0) delayms(50);
gpio_set(PORTC,19,0);
}
}
}
//中心線判斷與矯正 頂端行求取,,,圖像的模糊
void TopGet()
{
for(CCD_V=8;CCD_V<V-2;CCD_V++)//又從第八行開始干啥?
{
if((CenterLine[CCD_V]-CenterLine[CCD_V+1])>center_error || (CenterLine[CCD_V+1]-CenterLine[CCD_V])>center_error) //中線誤差三?突變嘛?
{
if((CenterLine[CCD_V+1]-CenterLine[CCD_V+2])>center_error || (CenterLine[CCD_V+2]-CenterLine[CCD_V+1])>center_error)//連續兩行突變?
{
top_line1=CCD_V;//又干啥呀?
break;
}
else ;
}
else
top_line1=48;//這樣啊
if(LeftBorder[CCD_V]-RightBorder[CCD_V]<=30)
{
if(LeftBorder[CCD_V+1]-RightBorder[CCD_V+1]<=30)
{
top_line2=CCD_V;//30是允許通過行駛的寬度嘛?
break;
}
else ;
}
}
if(top_line1>=30 && top_line2>=30)
top_line=(top_line2 < top_line1) ? top_line2 : top_line1;//找個最小的
/*
if(count>=5100)
last_top=top_line;*/
}
void line_count()
{
left_line=0;
right_line=0;
for(CCD_V=0;CCD_V<49;CCD_V++)
{
if(LeftBorder[CCD_V]==149)
left_line++;
if(RightBorder[CCD_V]==0)
right_line++;
}
}
//十字交叉,,,沒看太明白
void CrossJudge()
{
if(count>=5000 && count<=5800 && right_line>=10 && left_line>=10)// && right_line<=18 && left_line<=18),,,count什么呀?
{
for(CCD_V=8;CCD_V<49;CCD_V++)
{
if(CenterLine[8]+CenterLine[7]-CenterLine[1]-CenterLine[0]<0)
{
if(LeftBorder[CCD_V] - LeftBorder[CCD_V-1]>= 3)
{
LeftBorder[CCD_V]=LeftBorder[CCD_V-1]-1;
RightBorder[CCD_V]=RightBorder[5];
}
else if(LeftBorder[CCD_V]>=145)
LeftBorder[CCD_V]=LeftBorder[CCD_V-1];
else;
}
else if(CenterLine[8]+CenterLine[7]-CenterLine[1]-CenterLine[0]>0)
{
if(RightBorder[CCD_V] - RightBorder[CCD_V-1]<= -3)
{
RightBorder[CCD_V]=RightBorder[CCD_V-1]+1;
LeftBorder[CCD_V]=LeftBorder[5];
}
else if(RightBorder[CCD_V]<= 5)
RightBorder[CCD_V]=RightBorder[CCD_V-1];
else;
}
CenterLine[CCD_V]=(LeftBorder[CCD_V]+RightBorder[CCD_V])/2;
}
for(CCD_V=49;CCD_V>top_line;CCD_V--)
{
for(CCD_H=CenterLine[top_line];CCD_H>RightBorder[top_line];CCD_H--)
{
if(Bina_data[CCD_V][CCD_H+1]==1 && Bina_data[CCD_V][CCD_H]==1)
{
if(Bina_data[CCD_V][CCD_H-1]==0 && Bina_data[CCD_V][CCD_H-2]==0)
{
RightBorder[CCD_V]=CCD_H;
break;
}
}
else RightBorder[CCD_V]=RightBorder[top_line];
}
for(CCD_H=CenterLine[top_line];CCD_H<LeftBorder[top_line];CCD_H++)
{
if(Bina_data[CCD_V][CCD_H+1]==1 && Bina_data[CCD_V][CCD_H]==1)
{
if(Bina_data[CCD_V][CCD_H+3]==0 && Bina_data[CCD_V][CCD_H+2]==0)
{
LeftBorder[CCD_V]=CCD_H;
break;
}
}
else LeftBorder[CCD_V]=LeftBorder[top_line];
}
CenterLine[CCD_V]=(LeftBorder[CCD_V]+RightBorder[CCD_V])/2;
}
for(CCD_V=48;CCD_V>=top_line;CCD_V--)
{
if((CenterLine[CCD_V]-CenterLine[CCD_V-1])>center_error || (CenterLine[CCD_V-1]-CenterLine[CCD_V])>center_error)
{
if((CenterLine[CCD_V]-CenterLine[CCD_V-2])>center_error || (CenterLine[CCD_V-2]-CenterLine[CCD_V])>center_error)
{
top_top_line=CCD_V;
break;
}
else ;
}
}
//中心線修正
}
}
//=====================================
//|| ||
//|| 十字道處理 ||
//|| ||
//=====================================
/* crossJudge()
{
char i,j;
char left_tiaobian=0;
char right_tiaobian=0;
char left_guaidian=0;
char right_guaidian=0;
char left_tiaobian_row=0;
char right_tiaobian_row=0;
char left_guaidian_row=0;
char right_guaidian_row=0;
if(count>=5000 && count<=5800 && right_line>=10 && left_line>=10) //十字道判斷條件1,整場黑點數2,白條寬度 3,斜十字能否準確判斷!
{
//==========十字道處理========== //搜索左下邊沿
for(i=1;i<V;i++) //注意不要讓數組溢出
{
//====左邊線處理==
//搜索拐點 //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&7?
//左右要寫的一樣
if(LeftBorder[i]>LeftBorder[i-1] || LeftBorder[i]>140) //抓住十字邊界的延生特點左突變
{
left_guaidian= LeftBorder[i-3];
left_guaidian_row=i-3;
break;
}
}
//搜索跳變點 //搜索左上邊沿
for(i=1;i<V;i++)
{
if(LeftBorder[i]-LeftBorder[i-1]<-10)
{
left_tiaobian= LeftBorder[i+2];
left_tiaobian_row=i+2;
break;
}
}
//搜索完后再補線。
//邊線補線
if((left_guaidian!=0)&&(left_tiaobian!=0)) //通過直線去補線效果更好
{
for(i=left_guaidian_row;i<=left_tiaobian_row;i++)
LeftBorder[i]=(char)((left_tiaobian- left_guaidian)*1.0/( left_tiaobian_row-left_guaidian_row)*(i-left_guaidian_row)+0.5)+ left_guaidian;
}
//====右邊線處理==
//搜索拐點
for(i=1;i<V;i++) //注意不要讓數組溢出
{
//====右邊線處理==
//搜索拐點 //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&7?
//左右要寫的一樣
if(RighttBorder[i]<RightBorder[i-1] || RightBorder[i]<10) //抓住十字邊界的延生特點左突變
{
right_guaidian= RightBorder[i-3];
right_guaidian_row=i-3;
break;
}
}
//搜索跳變點 //搜索右上邊沿
for(i=1;i<V;i++)
{
if( RightBorder[i]- RightBorderr[i-1]>10)
{
right_tiaobian= RightBorder[i+2];
right_tiaobian_row=i+2;
break;
}
}
//邊線補線
if((right_guaidian!=0)&&(right_tiaobian!=0))
{
for(i=right_guaidian_row;i<right_tiaobian_row-1;i++)
RightBorder[i]=(char)(( right_tiaobian-right_guaidian)*1.0/( right_tiaobian_row- right_guaidian_row)*(i-right_guaidian_row)+0.5)+right_guaidian;
}
}
//=================中心線重提取============
for(i=0;i<V;i++)
CenterLine[i]=(LeftBorder[i]+RightBorder[i])/2;
}*/
//小S
void S_road()
{
long center_sum=0;
//long left_sum=0,right_sum=0;
// unsigned char left_ave=0,right_ave=0;
if(count>5800)
{
for(CCD_V=5;CCD_V<=40;CCD_V++)
{
if(fabsf((LeftBorder[CCD_V]-LeftBorder[CCD_V+1])>=3)) LeftBorder[CCD_V]=LeftBorder[CCD_V-1];
if(fabsf(RightBorder[CCD_V]-RightBorder[CCD_V+1])>=3) RightBorder[CCD_V]=RightBorder[CCD_V-1];
CenterLine[CCD_V]=(LeftBorder[CCD_V]+RightBorder[CCD_V])/2;
center_sum+=CenterLine[CCD_V];
//right_sum+=RightBorder[CCD_V];
//left_sum+=LeftBorder[CCD_V];
}
//left_ave=left_sum/19;
//right_ave=right_sum/19;
for(CCD_V=5;CCD_V<=44;CCD_V++)
{
CenterLine[CCD_V]=center_sum/35;//好吧,中線變直線了,完美
/* if((right_line-left_line)>5)
CenterLine[CCD_V]=CenterLine[CCD_V]-10;
if((left_line-right_line)>5)
CenterLine[CCD_V]=CenterLine[CCD_V]+10;*/
}
}
}
//發送圖像到上位機
void send_photo()
{
int i=0,j=0;
//以下四句話是固定格式,是串口和上位機軟件之間的協議
uart_putchar(UART2,0);
uart_putchar(UART2,255);
uart_putchar(UART2,1);
uart_putchar(UART2,0);
for(i=V-1;i>=0;i--)
for(j=H-1;j>=0;j--)
{
if(j==CenterLine[i]) uart_putchar(UART2,0); //中心線
else if(j==RightBorder[i]) uart_putchar(UART2,0);
else if(j==LeftBorder[i]) uart_putchar(UART2,0);
else uart_putchar(UART2,Bina_data[i][j]);
}
}
void SendImg()
{
disable_irq(89);
disable_irq(90); //關閉場中斷,防止串口發送圖像數據進程被打亂
if(gpio_get(PORTA,11)==0) thread();
else threshold=135;
BinaData();
……………………
…………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
K60 smartcar最終代碼.rar
(1.83 MB, 下載次數: 33)
2018-2-18 11:32 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1