OpenCV3霍夫圆检测
原理图
(来自于51CTO教学视频)
相关API
cv::HoughCircles
因为霍夫圆检测对噪声比较敏感,所以要对图像做中值滤波;
基于效率考虑,OpenCV中实现的霍夫变换圆检测时基于图像梯度的实现,分为两步
1.检测边缘,发现可能的圆心
2.基于第一步的基础上从侯选圆心开始计算最佳半径大小
HoughCircles(
InputArray imgage,//输入图像,必须为8位的单通道灰度图像
OutputArray circles,//输出结果,发现的圆信息
Int method,//方法-HOUGH_GRADIENT
Double dp,//dp=1
Double mindist,//10最短距离-可以分辨是两个圆的,否则认为是同心圆
Double param1,
Double param2,//中心点累加器阈值-候选圆心
Int minradius,//最小半径
Int maxradius//最大半径
)
//OpenCV3霍夫变换-圆的检测
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
const char* file = "my.png";
//读取图像
Mat img = imread(file);
//读取图像出错
if (img.empty()) {
cout << "null" << endl;
return -1;
}
//进行色彩空间的转换
cvtColor(img, img, CV_BGR2GRAY);
imshow("img", img);
//霍夫圆检测
vector<Vec3f>pcircles;//存放圆心,极坐标表示(x,y,r)
HoughCircles(img, pcircles, CV_HOUGH_GRADIENT, 1, 100, 100,30,0,200);
//1-累加器图像的分辨率,增大则分辨率变小
//100-很重要的一个参数,告诉两个圆之间的距离的最小距离,如果已知一副图像,可以先行计算出符合自己需要的两个圆之间的最小距离。
//100-canny算法的阈值上限,下限为一半(即100以上为边缘点,50以下抛弃,中间视是否相连而定)
//30-决定成圆的多寡 ,一个圆上的像素超过这个阈值,则成圆,否则丢弃
//0-最小圆半径,这个可以通过图片确定你需要的圆的区间范围
//200-最大圆半径
//从新加载图像
Mat newimg = imread(file);
if (newimg.empty()) {
return -1;
}
//画圆
for (size_t i = 0; i < pcircles.size(); ++i) {
circle(newimg, Point(pcircles[i][0], pcircles[i][1]), pcircles[i][2], Scalar(255, 0, 0), 2, 8);
cout << pcircles[i] << endl;
}
cout << "end" << endl;
imshow("newimg", newimg);
waitKey(0);
return 0;
}