1. 霍夫圓變換
霍夫圓變換 (Hough Circle Transform)是一種數位影像處理中的特征提取技術,用於在影像中檢測圓形。它將二維影像空間中一個圓轉換為該圓半徑、圓心橫縱座標所確定的三維參數空間中一個點的過程。因此,圓周上任意三點所確定的圓,經霍夫變換後在三維參數空間應對應一點。
霍夫圓變換的優點:
通用性強,可以檢測任意大小、形狀的圓形。
效率高,可以快速檢測出影像中的圓形。
霍夫圓變換的缺點:
對雜訊敏感。
容易產生錯誤檢測。
計算量大。
2. 霍夫圓檢測的原理
2.1 標準霍夫圓變換
圓的一般方程式為:
,其中 (a、b) 為圓心座標,r 是圓的半徑。把影像空間轉換成參數空間,這裏將 x-y 平面轉化成 a-b-r 參數空間,則在影像空間中的一個過 x、y 點的圓,對應參數空間中高度變化的三維錐面。
過影像空間上同一個圓的點,對應的參數空間中的三維錐面,在 r 平面必然相交於一點 (a, b, r) ,這樣透過這一點就可以得到一個圓的參數。
標準霍夫圓變換的基本思想:對於影像中的每個邊緣點,我們考慮所有可能透過該點的圓形。對於每個這樣的圓形,我們將其參數 (a, b, r) 對應的累加器加 1。最終,累加器中值最大的點所對應的參數即為影像中存在的圓形參數。
2.2 霍夫梯度法
在 OpenCV 中使用了 霍夫梯度法 實作圓檢測。霍夫梯度法是一種改進的霍夫圓變換演算法,用於提高圓檢測的效率和魯棒性。
霍夫梯度法的基本原理:
與標準霍夫圓變換類似,霍夫梯度法也基於將影像空間中的圓形對映到參數空間中的點這一思想。
不同之處在於,霍夫梯度法利用邊緣點的 梯度方向 來對每個邊緣點進行投票,而不是簡單地累加所有可能的圓心。
梯度方向代表了邊緣點所在的圓的切線方向,因此,只有當圓心的位置與邊緣點的梯度方向一致時,才會對該圓進行投票。
霍夫梯度法包含以下步驟:
邊緣檢測: 使用 Canny 等邊緣檢測演算法獲取影像的邊緣點集合。
梯度計算: 使用 Sobel 算子等方法計算每個邊緣點的梯度方向。
參數空間投票: 遍歷所有可能的圓心座標 (x, y) 和半徑 r:
計算該圓上與邊緣點相交的點的梯度方向。
a. 將這些梯度方向與邊緣點的梯度方向進行比較。
b. 如果兩者一致,則為該候選圓在參數空間中對應的點投票。
局部最大值檢測: 在參數空間中尋找投票數最多的點,這些點對應的參數即為影像中存在的圓的參數。
圓形繪制: 根據檢測到的圓參數,繪制影像中的圓形。
霍夫梯度法與霍夫圓檢測的主要區別在於:
參數空間: 霍夫梯度法使用的是 梯度方向和圓半徑 參數空間,而霍夫圓檢測使用的是 圓心橫縱座標和圓半徑 參數空間。
投票策略: 霍夫梯度法根據 邊緣點的梯度方向 進行投票,而霍夫圓檢測根據 邊緣點的位置 進行投票。
因此,霍夫梯度法相比於標準霍夫圓變換具有以下優點:
計算效率更高: 利用梯度資訊減少了參數空間的搜尋範圍,提高了計算效率。
檢測精度更高: 利用梯度方向資訊可以更好地區分邊緣點,提高了檢測精度。
抗雜訊能力更強: 梯度資訊可以抑制部份雜訊的影響,提高抗雜訊能力。
霍夫梯度法也存在以下的一些缺點:
對參數設定敏感: 梯度閾值和累加器閾值等參數需要根據影像特點進行調整,否則可能影響檢測效果。
容易產生誤檢: 在邊緣點密集區域容易產生誤檢。
3. 範例
OpenCV 提供了
cv::HoughCircles
函式用於檢測影像中圓形的函式。
下面的例子,使用霍夫梯度法檢測圖中的硬幣。
#include"opencv2/imgproc.hpp"
#include"opencv2/highgui.hpp"
usingnamespacestd;
usingnamespace cv;
intmain(int argc, char **argv){
Mat src = imread(".../coins.jpg");
imshow("src", src);
Mat gray;
cvtColor(src, gray, cv::COLOR_BGR2GRAY); // 灰度化
Mat gauss;
GaussianBlur(gray, gauss, Size(15, 15),0); //降噪
Mat thresh;
threshold(gauss, thresh,0,255,THRESH_BINARY | THRESH_OTSU );
imshow("thresh", thresh);
vector<Vec3f> circles;
cv::HoughCircles(thresh, circles, HOUGH_GRADIENT, 1, 50, 100,15,5,100);
for (auto i = 0; i < circles.size(); i++)
{
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
circle(src, center, 3, Scalar(0, 0, 255), -1, 8);
circle(src, center, radius, Scalar(0, 0, 255), 3, 8);
}
imshow("result", src);
waitKey(0);
return0;
}
下面詳細介紹一下
HoughCircles
函式:
voidHoughCircles( InputArray image, OutputArray circles,
int method, double dp, double minDist,
double param1 = 100, double param2 = 100,
int minRadius = 0, int maxRadius = 0 );
第一個參數 image: 輸入影像,是 8 位單鍊結灰度影像。
第二個參數 circles: 輸出圓形資訊的容器,是一個
std::vector<Vec3f>
型別的陣列,其中每個元素包含三個浮點數,分別代表圓心的 x 座標、y 座標和半徑。
第三個參數 method: 圓形檢測方法,目前支持
HOUGH_GRADIENT
、
HOUGH_GRADIENT_ALT
。
第四個參數 dp: 累加器影像的分辨率與輸入影像分辨率的比值倒數,預設為 1。
第五個參數 minDist: 檢測到的圓心之間的最小距離,可以避免檢測到重疊的圓形。
第六個參數 param1:
HOUGH_GRADIENT
中的第一個參數,用於 Canny 邊緣檢測算子的高閾值,預設為 100。
第七個參數 param2:
HOUGH_GRADIENT
中的第二個參數,用於在檢測階段對圓心累加器的閾值,預設為 100。
第八個參數 minRadius: 圓形的最小半徑,預設為 0。
第九個參數 maxRadius: 圓形的最大半徑,預設為 0。
4. 總結
霍夫圓檢測是一種用於影像處理中圓形檢測的經典方法,具有廣泛的套用場景、良好的魯棒性和準確性、靈活性和可延伸性、高效的計算效能以及易於理解和實作等優點,在許多領域發揮著重要作用。
系統化學習直接掃碼檢視
推薦閱讀