影象處理 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變換檢測出的直線(版權所有 歡迎交流)