1. 程式人生 > >影象處理 C語言 hough變換 檢測直線

影象處理 C語言 hough變換 檢測直線

一天從網上下了20個vc的hough程式碼,沒有一個程式碼是成功的。令人鬱悶,我參考matlab程式碼寫出了hough檢測單個直線的程式

Hough變換:

本程式是我花費時間最長的程式;參考matlab演算法;首先求出原圖上的每一個畫素在變換域上的對應曲線,即原圖上每一點(i,j)對應變換域曲線(p,k);p=(int)(i*cos(pi*k/180)+j*sin(pi*k/180))(0<k<180);

然後遍歷(i,j),累加變換域重複出現的位置,即曲線的交點

然後遍歷累加器,尋找交點最大的資料,找出對應的原圖座標,即為所求直線

主要程式碼

for(i=0;i<img.height;i++) //轉化成灰度

{

for(j=0,n=0;n<img.width*3,j<img.width;n+=3,j++)

{ //gray 變數儲存rgb轉灰度的資料

gray= ((float)(img.image[lineBytes*i+n+2])+(float)(*(img.image+lineBytes*i+n+1))+(float)(*(img.image+lineBytes*i+n)))/3; //lineBytes 原圖每行實際位元組數

grayPic[i*img.width+j]=(byte)gray;//轉換成的灰度影象放在grayPic中

}

}

int logNum; //邊緣檢測

memset(lpDIBBits,(byte)0,sizeof(byte)*img.height*img.width);

for(i=3;i<img.height-2;i++)

for(j=3;j<img.width-2;j++)

{

//logNum 變數 記錄每次運算的值

logNum=16*grayPic[i*img.width+j]-grayPic[(i-2)*img.width+j]-grayPic[(i-1)*img.width+j-1]-2*grayPic[(i-1)*img.width+j]-grayPic[(i-1)*img.width+j+1]-grayPic[i*img.width+j-2]-2*grayPic[i*img.width+j-1]-2*grayPic[i*img.width+j+1]-grayPic[i*img.width+j+2]-grayPic[(i+1)*img.width+j-1]-2*grayPic[(i+1)*img.width+j]-grayPic[(i+1)*img.width+j+1]-grayPic[(i+2)*img.width+j];//log運算元

if(logNum > 0)

lpDIBBits[i*img.width+j]=255;//邊緣檢測後的資料存放在lpDIBBits中

else

lpDIBBits[i*img.width+j]=0;

}

for(i=1;i<img.height;i++) //img.height原圖高度

for(j=1;j<img.width;j++) //img.width 原圖寬度

{

if(lpDIBBits[i*img.width+j]==255) //對邊緣檢測後的資料(存在lpDIBBits中)進行hough變化

{

for(k=1;k<ma;k++) //ma=180

{

p=(int)(i*cos(pi*k/180)+j*sin(pi*k/180));//p hough變換中距離引數

p=(int)(p/2+mp/2); //p值優化防止為負

npp[k][p]=npp[k][p]++; //npp對變換域中對應重複出現的點累加

}

}

}

kmax=0; //最長直線的角度

pmax=0; //最長直線的距離

n=0; //這一部分為尋找最長直線

for(i=1;i<ma;i++) //ma=180

for(j=1;j<mp;j++) //mp為原圖對角線距離

{

if(npp[i][j]>yuzhi) //找出最長直線 yuzhi為中間變數用於比較

{

yuzhi=npp[i][j];

kmax=i; //記錄最長直線的角度

pmax=j; //記錄最長直線的距離

}

}

memset(temp,(byte)255,sizeof(byte)*img.width*img.height);//原圖中座標符合kmax和pmax的值

for(i=1;i<img.height;i++) //的集合即是最長的直線

for(j=1;j<img.width;j++)

{

if(lpDIBBits[i*img.width+j]==255)

{

p=(int)(i*cos(pi*kmax/180)+j*sin(pi*kmax/180));//pi=3.1415926

p=(int)(p/2+mp/2); //mp為原圖對角線距離

if(p==pmax)

*(temp+i*img.width+j)=0; //儲存影象資料 放在temp陣列中

}

}


右邊是原圖,裡面有圓和直線,左邊是經過hough變換檢測出的直線(版權所有 歡迎交流)