作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
void HoughCircles( InputArray image, OutputArray circles,
int method, double dp, double minDist,
double param1 = 100, double param2 = 100,
int minRadius = 0, int maxRadius = 0 );
OpenCV支持霍夫圆变换,霍夫圆变换的基本原理和线变换大体上类似,只是点对应的二维极径极角空间被三维的圆心点x、y、r空间取代。说“大体上类似”,是因为如果完全用相同的方法的话,累加平面会被三维的累加容器所代替,在这三维中,一维是x,一维是y,另外一维是圆的半径r。这就意味着需要大量的内存并且执行效率会很低,速度会很慢。
对直线来说,一条直线能用参数极径和极角表示,而对圆来说,需要三个参数表示,通常采用一种叫霍夫梯度法的方法来解决圆变换的问题。
原理如下:
这个实现可以使算法执行起来更高效,还能解决三维累加器中产生许多噪声并且使结果不稳定的稀疏分布问题。
#include
#include
using namespace std;
using namespace cv;
int main()
{
Mat src = imread("test.png");
Mat mid, dst;
dst = src.clone();
cvtColor(src, mid, COLOR_BGR2GRAY);
// 高斯滤波
GaussianBlur(mid, mid, Size(9, 9), 2, 2);
// 霍夫梯度法实现圆检测
vector circles;
HoughCircles(mid, circles, HOUGH_GRADIENT, 1.5, 100, 200, 200, 0, 0);
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(dst, center, 3, Scalar(0, 255, 0), -1, 8, 0);
circle(dst, center, radius, Scalar(0, 255, 255), 3, 8, 0);
}
imshow("src", src);
imshow("result", dst);
waitKey(0);
return 0;
}
该图是我之前做的一单私活中应用到的,当时的需求是进行圆检测,起初考虑用霍夫圆检测直接做,但是效果一般,并且准确性也不是很好;后面我基于边缘检测和特征圆识别方法,设计了一个识别圆的算法,虽然也不能解决所有的场景识别,但是效果比直接霍夫圆检测好一些,也更贴近圆的边缘,具体就不展示了。总的来说,霍夫圆检测还是不错的,针对一些简单些的图像还是能精准且稳定的识别,主要是应用很方便,调一个函数哈哈哈。
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!