houghcircles函数
houghcircles函数用于在灰度图像中使用霍夫变换查找圆。该函数通过修改霍夫变换来实现,通常可以很好地检测出圆的中心,但可能无法找到正确的半径。可以通过指定半径范围(minradius和maxradius)来协助该函数,或者在#hough_gradient方法中将maxradius设置为负数以仅返回圆心而不进行半径搜索,并使用其他过程找到正确的半径。此外,还可以对图像进行一定程度的平滑处理,除非它已经很软。例如,可以使用7x7内核和1.5x1.5 sigma或类似的模糊处理来平滑图像。
函数原型:
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 );
参数说明:
使用场景
houghcircles 是一种图像处理算法,用于检测图像中的圆。霍夫圆检测能检测出目标图像中存在的圆,但在实际使用中,参数调节存在很大的困难。
参数设置不合理会不仅导致计算量非常大,并且可能无法找不到你想保留的圆。
1)边缘噪声滤除
对图像进行 中值滤波 或者 均值滤波 或者 高斯滤波 优化,减少图像中存在的边缘噪声。
2)检测参数如何设定
通过观察原图初步确定的圆的像素半径范围(对应minradius和maxradius)。
b. 圆心累加值设定(对应参数param2)
因为累加圆心(圆弧上的在圆心上的累加值,累加值超过该阈值则被认为是一个圆)
c. 圆心距离设定(对应参数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;
}
// 转换为灰度图像
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;
// 设置hough变换参数
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;
// 显示结果
imshow("霍夫圆检测", src);
waitkey(0);
return 0;
}
灰度图:
模糊滤波:
边缘检测:
霍夫圆检测结果:
参考资料
发表评论