1. 程式人生 > 實用技巧 >從0開始的智慧車程式碼(1)

從0開始的智慧車程式碼(1)

逐飛科技開源連結:https://gitee.com/seekfree

程式碼從Seekfree_RT1064_Opensource_Library 開始。

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

根據 Seekfree 總鑽風例程說明,只使用一個攝像頭時選擇 CSI 介面(CSI 介面為影象採集專用介面內嵌 DMA,可以接受更高的畫素時鐘)。攝像頭 TX:C29,RX:C28。

void CSI_IRQHandler(void)
{
    CSI_DriverIRQHandler();     
//呼叫SDK自帶的中斷函式 這個函式最後會呼叫我們設定的回撥函式 __DSB(); //資料同步隔離 }

這個中斷函式在Seekfree_RT1064_Opensource_Library 中已經寫好了,不需要修改。

在主迴圈中首先判斷攝像頭資料是否採集完成(mt9v03x_csi_finish_flag),然後使用大津法求閾值。

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

uint8 getThreshold(uint8 *image,uint16 col,uint16 row)//
使用原影象計算閾值 { uint16 grayCount[256]={0};//灰度值分佈 uint32 graySum=0;//灰度值總和 uint16 pixelSum=0;//畫素點總數 float graypro[256]; uint8 threshold; uint16 i,j; uint16 step=2;//每行/列在step個畫素點的灰度值中取一個有效值 //統計灰度值分佈 for(i=0;i<row;i+=step){ for(j=0;j<col;i+=step){ grayCount[image[i*col+j]]++;//將前的點的畫素值作為計數陣列的下標
graySum+=image[i*col+j];//灰度值總和 pixelSum++; } } //計算每個畫素值的點在整幅影象中的比例 for(i=0;i<256;i++){ graypro[i]=(float)grayCount[i]/pixelSum; } float darkPixel=0;//深色畫素點所佔比例之和 float lightPixel;//淺色畫素點所佔比例之和 float darkPixelGray=0;//深色畫素點所佔比例與灰度值乘積之和 float lightPixelGray;//淺色畫素點所佔比例與灰度值乘積之和 float darkAverage;//深色畫素點平均灰度 float lightAverage;//淺色畫素點平均灰度 float delta; float maxDelta=0; for(i=0;i<256;i++){ darkPixel+=graypro[i]; lightPixel=1-darkPixel; darkPixelGray+=i*graypro[i]; lightPixelGray=graySum/pixelSum-darkPixelGray; darkAverage=darkPixelGray/darkPixel; lightAverage=lightPixelGray/lightPixel; delta=darkPixel*(darkAverage-graySum/pixelSum)*(darkAverage-graySum/pixelSum) +lightPixel*(lightAverage-graySum/pixelSum)*(lightAverage-graySum/pixelSum); if(delta>maxDelta){ maxDelta=delta; threshold=i; } else{ break; } } return threshold; }

求出閾值後對原影象陣列進行二值化。在二值化函式中,我將二值化後的陣列地址作為引數傳進函式。

void imageBinary(uint8 threshold,uint8 *image,uint8 *binaryImage,uint16 col,uint16 row){
  uint8 gray;
  uint16 i,j;
  for(i=0;i<row;i++){
    for(j=0;j<col;i++){
      gray=*(image+i*col+j);
      *(binaryImage+i*col+j)=gray>threshold?255:0;
    }
  }
}