1.霍夫圆检测API
cv::HoughCircles( src,//输入图像
OutputArray Circles,//输出圆的参数,输出向量的集合(圆心坐标x,圆心坐标y,半径r)
int method,//方法,选用HOUGH_GRADIENT(霍夫圆梯度法)
double dp,//表示输入图像分辨率与圆心累加器分辨率的比值,常取1
double mindist,//可分辨两个圆的最小距离,小于此距离则判断为同心圆
double param1,//Canny边缘检测的高阈值,低阈值为它的1/2
double param2,//圆心累加器阈值,大于此阈值才判断为圆心
int minradins,//圆最小半径
int maxradins,//圆最大半径,限制圆的输出)
从API中可以有如下猜想:
参数param1影响Canny检测的效果,参数param2影响算法认为可能为圆的个数,参数mindist阈值,用以判断两圆点的距离与该阈值的大小关系,并作相应输出。
2.使用Trackbar进行调参,观察影响
#include<opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
Mat src, canny_img, gray_img, binary_img, CLOSS_IMG,dst,up_img;
int p1 = 100;
int p2 = 100;
int mindist = 100;
void getHoughCircles(int, void*) {
dst = up_img.clone();
vector<Vec4f>circles;
HoughCircles(binary_img, circles, HOUGH_GRADIENT, 1, mindist*0.1, p1, p2, 0, 0);
//画线
for (size_t i = 0; i < circles.size(); i++) {
Vec4f c = circles[i];
circle(dst, Point(c[0], c[1]), c[2], Scalar(255, 0, 0), 2, LINE_AA);
circle(dst, Point(c[0], c[1]), 2, Scalar(0, 0, 255), 2, LINE_AA);
}
imshow("Final Result", dst);
}
int main(int argc, char** argv) {
src = imread("D:/cv_img_test/indicator.jpg");
if (src.empty()) {
cout << "can not read image" << endl;
return -1;
}
namedWindow("Input Window", WINDOW_AUTOSIZE);
imshow("Input Window", src);
//上采样
pyrUp(src, up_img, Size(src.cols * 2, src.rows * 2));
//中值滤波
medianBlur(up_img, up_img, 3);
//锐化
Mat kernel = (Mat_<int>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(up_img, up_img, -1, kernel);
imshow("UPimg", up_img);
//灰度转换
cvtColor(up_img, gray_img, COLOR_BGR2GRAY);
//二值化
threshold(gray_img, binary_img,200,255,THRESH_BINARY);
imshow("Binary Result", binary_img);
//霍夫变换
dst = up_img.clone();
namedWindow("Final Result");
createTrackbar("p1", "Final Result", &p1, 255, getHoughCircles);
createTrackbar("p2", "Final Result", &p2, 300, getHoughCircles);
createTrackbar("mindist", "Final Result", &mindist, 300, getHoughCircles);
imshow("Final Result", dst);
waitKey(0);
return 0;
}
3.结果
3.1 param2的影响
直接运行结果,此时p1=100(即param1,p2同理),p2=100,mindist=10(Trackbar上显示为100,实际传入乘以0.1,即为10),没有检测出圆,原因为p2阈值选取过大。
当p2减小到98时,开始检测到1个圆。
随着p2的增加,输出圆个数增加,并出现较多误判。
3.2 p1的影响
对于p1影响Canny边缘检测的效果,在此例中边缘检测效果较好,调整p1的值无法没有明显变化。(选择其他普遍性更强的图像进行检测)
3.3 mindist的影响
在上述较多误判时增大mindist的数值,能够减少误判圆的数量,算法自动选择最可能为圆的进行输出。本例中当mindist的值取大于27.9时,效果较好。
反之,减少mindist的值,会增加圆误判的可能性。