文章目录
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时: