Hough圆变换

1、Hough圆检测原理;
2、相关API;
3、代码演示;

Hough圆检测原理

1、平面坐标中的圆变换到霍夫空间中后,圆上每个像素点产生的圆都会经过一次圆心,圆心会变得很亮;


相关API

cv::HoughCircles():
1、霍夫圆检测对图像噪声比较敏感,使用前需要先对图像做中值滤波(去除椒盐噪声);
2、基于效率考虑,OpenCV中实现霍夫变换圆检测是基于图像梯度的实现,分为两步:(提高计算效率)
①检测边缘,发现可能的圆心(此处使用Canny算法);
②基于第一步的基础上从候选圆心计算最佳半径的大小;

参数说明:
image:8位单通道灰度图像(双通道,三通道…都不行)
circles: 输出结果,是一个向量数组Vector;
method: --取HOUGH_GRADIENT,通过图像梯度寻找
dp : 取1,代表在原图上寻找(取2代表在原图的一半上寻找,寻找速度更快)
mindist: 最短距离(10),因为图像可能有同心圆,当圆半径很接近时就认为是同一个圆;
param1://设置Hough圆变换中Canny算法的高阈值(High threshold),低阈值取其一半;
param2: //中心点累加器阈值(30,50个像素则说明差不多有一小段圆弧了),与圆的半径有关;
minradius :待检测圆的最小半径设置
maxradius: 待检测圆的最大半径设置

Code

注意:
1、图像在调用HoughCircles()API之前必须进行图像预处理(模糊滤波),提高检测结果的准确性;
2、maxradius值设置不同,检测结果也不同

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main(int argc, char** argv)
{
   
	Mat dst;
	Mat src = imread("C:\\Users\\hello\\Desktop\\24.jpg");
	if (!src.data)
	{
   
		cout << "could not load the image..." << endl;
		return -1;
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);
	
	//中值滤波
	Mat medimage,grayimage;
	medianBlur(src, medimage,3);
	cvtColor(medimage, grayimage, CV_BGR2GRAY);
	//Hough圆检测
	//声明向量 存储数据,大小自动变化
	vector<Vec3f> circles;
	HoughCircles(grayimage, circles, HOUGH_GRADIENT, 1, 10, 100, 30, 5,50);//maxradius的值一定要设置合理
	src.copyTo(dst);
	for (int i = 0; i < circles.size(); i++)
	{
   
		Vec3f cc = circles[i];
		//画检测圆
		circle(dst, Point((int)cc[0], (int)cc[1]), (int)cc[2], Scalar(0, 0, 255), 1, LINE_AA);
		//圈出检测到的圆心
		circle(dst, Point((int)cc[0], (int)cc[1]), 3, Scalar(127, 127, 0), 1, LINE_AA);
	}
	imshow("Hough Detection Image", dst);

	waitKey(0);
	return 0;
}

效果

maxradius = 40时:

maxradius = 50时:(基本圆都检测出来了)


maxradius = 60时:(开始混乱)

maxradius = 70时: