從0開始的智能車代碼(1)


代碼從逐飛科技的開源庫開始。

想要站在巨人的肩膀上,首先要爬上巨人。在抄別人的代碼時,我將會經常發現一些不盡如人意的地方,但是為了使代碼順利運行,我將標記出這些問題而不改善。

在主循環中首先判斷攝像頭數據是否采集完成,然后使用大津法求閾值,根據閾值對原圖像數組進行二值化。

大津法(OTSU)是一種確定圖像二值化分割閾值的算法,由日本學者大津於 1979 年提出。從大津法的原理上來講,該方法又稱作最大類間方差法,因為按照大津法求得的閾值進行圖像二值化分割后,前景與背景圖像的類間方差最大。

void imageBinary(void)
{
  uint16 grayCount[256]={0};
  uint32 graySum=0;
  uint16 pixelSum=0;
  float graypro[256];
  
  uint8 threshold;
  uint16 i,j;
  uint16 step=2;//間隔
  
  for(i=0;i<MT9V032_H;i+=step){
    for(j=0;j<MT9V032_W;j+=step){
      grayCount[image[i][j]]++;
      graySum+=image[i][j];
      pixelSum++;
    }
  }
  
  for(i=0;i<256;i++){
    graypro[i]=(float)grayCount[i]/pixelSum;
  }
  
  float w0,w1,u0Temp,u1Temp,u0,u1,u,deltaTemp,deltaMax;
  deltaMax=0;
  for(i=0;i<256;i++){
    w0=w1=u0Temp=u1Temp=u0=u1=u=deltaTemp=0;
    for(j=0;j<256;j++){
      if(j<=i){
        w0+=graypro[j];
        u0Temp+=j*graypro[j];
      }
      else{
        w1+=graypro[j];
        u1Temp+=j*graypro[j];
      }
    }
    u0=u0Temp/w0;
    u1=u1Temp/w1;
    u=u0Temp+u1Temp;
    deltaTemp=w0*(u0-u)*(u0-u)+w1*(u1-u)*(u1-u);
    if(deltaTemp>deltaMax){
      deltaMax=deltaTemp;
      threshold=i;
    }
  }
  
  for(i=0;i<MT9V032_H;i++){
    for(j=0;j<MT9V032_W;j++){
      binaryImage[i][j]=(image[i][j]>threshold)?255:0;
    }
  }
  if(threshold<160){//出界停車
    DisableInterrupts;
    ctimer_pwm_duty(TIMER1_PWMCH0_A18,0);
    ctimer_pwm_duty(TIMER2_PWMCH1_B4,0);
  }
}

若求得閾值小於某個臨界值,則說明攝像頭已經幾乎看不到白色的賽道了,接下來要停止所有中斷並將電機輸出 PWM 波的占空比置零將車停下。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM