vc影像處理程式中經常要用到直線檢測,常用的直線檢測方法是Hough變換。
Hough變換是影像處理中從映像中識別幾何形狀的基本方法之一。Hough變換的基本原理在於利用點與線的對偶性,將原始映像空間的給定的曲線通過曲線表達形式變為參數空間的一個點。這樣就把原始映像中給定曲線的檢測問題轉化為尋找參數空間中的峰值問題。也即把檢測整體特性轉化為檢測局部特性。比如直線、橢圓、圓、弧線等。
簡而言之,Hough變換思想為:在原始映像座標系下的一個點對應了參數座標系中的一條直線,同樣參數座標系的一條直線對應了原始座標系下的一個點,然後,原始座標系下呈現直線的所有點,它們的斜率和截距是相同的,所以它們在參數座標系下對應於同一個點。這樣在將原始座標系下的各個點投影到參數座標系下之後,看參數座標系下有沒有聚集點,這樣的聚集點就對應了原始座標系下的直線。
以下代碼實現了最簡單的Hough變換直線檢測,輸入為width*height的二值圖(背景為0,前景為255),存放在矩陣src中,iThreshold為判斷為直線的域值。輸出pR為原點到直線的距離,pTh為直線的角度。
程式碼
void Hough(BYTE *src,int width,int height, int *pR, int *pTh, int iThreshold)
{
int *pArray;
int iRMax = (int)sqrt(width * width + height * height) + 1;
int iThMax = 361;
int iTh = 0;
int iR;
int iMax = -1;
int iThMaxIndex = -1;
int iRMaxIndex = -1;
pArray = new int[iRMax * iThMax];
memset(pArray, 0, sizeof(int) * iRMax * iThMax);
float fRate = (float)(PI/180);
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if(*src == 255)
{
for(iTh = 0; iTh < iThMax; iTh += 1)
{
iR = (int)(x * cos(iTh * fRate) + y * sin(iTh * fRate));
if(iR > 0)
{
pArray[iR/1 * iThMax + iTh]++;
}
}
}
src++;
} // x
} // y
for(iR = 0; iR < iRMax; iR++)
{
for(iTh = 0; iTh < iThMax; iTh++)
{
int iCount = pArray[iR * iThMax + iTh];
if(iCount > iMax)
{
iMax = iCount;
iRMaxIndex = iR;
iThMaxIndex = iTh;
}
}
}
if(iMax >= iThreshold)
{
*pR = iRMaxIndex;
*pTh = iThMaxIndex;
}
delete []pArray;
return;
} // end of Hough