HoughCircles函數(shù)
HoughCircles函數(shù)用于在灰度圖像中使用霍夫變換查找圓。該函數(shù)通過修改霍夫變換來實現(xiàn),通常可以很好地檢測出圓的中心,但可能無法找到正確的半徑。可以通過指定半徑范圍(minRadius和maxRadius)來協(xié)助該函數(shù),或者在#HOUGH_GRADIENT方法中將maxRadius設(shè)置為負(fù)數(shù)以僅返回圓心而不進(jìn)行半徑搜索,并使用其他過程找到正確的半徑。此外,還可以對圖像進(jìn)行一定程度的平滑處理,除非它已經(jīng)很軟。例如,可以使用7x7內(nèi)核和1.5x1.5 sigma或類似的模糊處理來平滑圖像。
函數(shù)原型:
CV_EXPORTS_W void HoughCircles(InputArray image, OutputArray circles, int method, double dp, double minDist, double param1 = 100, double param2 = 100, int minRadius = 0, int maxRadius = 0 );
參數(shù)說明:
image:輸入圖像,即源圖像,8位單通道圖像,如果使用彩色圖像,需要先轉(zhuǎn)換成灰度圖像;
circles:用來存儲HoughCircles的結(jié)果,類型為list,list中對象格式為x,y,r;
method:定義檢測圖像中圓的方法。目前唯一實現(xiàn)的方法是cv::HOUGH_GRADIENT;
dp:圖像像素分辨率與參數(shù)空間分辨率的比值(官方文檔上寫的是圖像分辨率與累加器分辨率的比值,它把參數(shù)空間認(rèn)為是一個累加器,畢竟里面存儲的都是經(jīng)過的像素點的數(shù)量),dp=1,則參數(shù)空間與圖像像素空間(分辨率)一樣大,dp=2,參數(shù)空間的分辨率只有像素空間的一半大;#通過設(shè)置dp可以減少計算量
minDist:檢測到的圓中心(x,y)坐標(biāo)之間的最小距離。如果minDist太小,則會保留大部分圓心相近的圓。如果minDist太大,則會將圓心相近的圓進(jìn)行合并(若兩圓心距離 < minDist,則認(rèn)為是同一個圓)。
param1:canny 邊緣檢測的高閾值,低閾值被自動置為高閾值的一半,默認(rèn)為 100。;
param2:累加平面某點是否是圓心的判定閾值。大于該閾值才判斷為圓。當(dāng)值設(shè)置的很小是,檢測到的圓越多。默認(rèn)值為 100;
minRadius:半徑的最小大?。ㄒ韵袼貫閱挝唬┠J(rèn)為 0;
maxRadius:半徑的最大大?。ㄒ韵袼貫閱挝唬┠J(rèn)為 0。
使用場景
HoughCircles 是一種圖像處理算法,用于檢測圖像中的圓?;舴驁A檢測能檢測出目標(biāo)圖像中存在的圓,但在實際使用中,參數(shù)調(diào)節(jié)存在很大的困難。
參數(shù)設(shè)置不合理會不僅導(dǎo)致計算量非常大,并且可能無法找不到你想保留的圓。
1)邊緣噪聲濾除
對圖像進(jìn)行 中值濾波 或者 均值濾波 或者 高斯濾波 優(yōu)化,減少圖像中存在的邊緣噪聲。
2)檢測參數(shù)如何設(shè)定
a. 檢索半徑設(shè)定
通過觀察原圖初步確定的圓的像素半徑范圍(對應(yīng)minRadius和maxRadius)。
b. 圓心累加值設(shè)定(對應(yīng)參數(shù)param2)
因為累加圓心(圓弧上的在圓心上的累加值,累加值超過該閾值則被認(rèn)為是一個圓)
c. 圓心距離設(shè)定(對應(yīng)參數(shù)miniDist)
通過觀察原圖所有希望找出的圓,然后確定2個圓心之間最小的距離。
使用案例
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
// 讀取原始圖像
Mat src = imread("3480e7ce_mk_tk_a_c2_6400_4480.png", IMREAD_COLOR);
if (src.empty())
{
cout << "無法讀取圖像" << endl;
return -1;
}
// 轉(zhuǎn)換為灰度圖像
Mat grayImage;
cvtColor(src, grayImage, COLOR_BGR2GRAY);
imshow("灰度圖", grayImage);
waitKey(0);
// 使用濾波器去噪
Mat blurImage;
// GaussianBlur(grayImage, blurImage, Size(9, 9), 2, 2); // 高斯濾波
// medianBlur(grayImage, blurImage, 7); // 中值濾波
blur(grayImage, blurImage, Size(7,7)); // 均值濾波
imshow("模糊濾波", blurImage);
waitKey(0);
// 使用 Canny 邊緣檢測
Mat edgesImage;
Canny(blurImage, edgesImage, 50, 100);
imshow("邊緣檢測", edgesImage);
waitKey(0);
clock_t t1 = clock();
// 使用 HoughCircles 檢測圓
vector<Vec3f> circles;
// 設(shè)置Hough變換參數(shù)
int minDist = 30; // 最小距離
int param1 = 100; // Canny邊緣檢測高閾值 # 保持和和前面Canny的閾值一致
int param2 = 15; // Hough變換高閾值
int minRadius = 10; // 最小半徑
int maxRadius = 100; // 最大半徑
HoughCircles(blurImage, circles, HOUGH_GRADIENT, 1, minDist, param1, param2, minRadius, maxRadius);
clock_t t2 = clock();
// 在原圖上繪制檢測到的圓
for (size_t 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, 255, 0), -1, 8, 0); // 繪制圓心
circle(src, center, radius, Scalar(0, 0, 255), 3, 8, 0); //繪制空心圓
}
clock_t t3 = clock();
double timeForHoughCircle = (double) (t2 - t1) / CLOCKS_PER_SEC * 1000;
double timeForDrawCircle = (double) (t3 - t2) / CLOCKS_PER_SEC * 1000;
cout << "HoughCircles:" << timeForHoughCircle << "ms, DrawCircle:" << timeForDrawCircle << "ms" <<endl;
// 顯示結(jié)果
imshow("霍夫圓檢測", src);
waitKey(0);
return 0;
}
灰度圖:
?模糊濾波:
?邊緣檢測:
?
霍夫圓檢測結(jié)果:
?
參考資料
opencv 十一 霍夫圓檢測原理及高級使用案例(含優(yōu)化步驟)文章來源:http://www.zghlxwxcb.cn/news/detail-774084.html
?文章來源地址http://www.zghlxwxcb.cn/news/detail-774084.html
到了這里,關(guān)于[C++] opencv - HoughCircles(霍夫圓查找)函數(shù)介紹和使用場景的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!