霍夫圆检测
因为霍夫圆检测对噪声比较敏感,所以首先要对图像做中值滤波。
基于效率考虑,Opencv中实现的霍夫变换圆检测是基于图像梯度的实现,分为两步:
-
检测边缘,发现可能的圆心
-
基于第一步的基础上从候选圆心开始计算最佳半径大小
相关API
HoughCircles(
InputArray image, // 输入图像 ,必须是8位的单通道灰度图像
OutputArray circles, // 输出结果,发现的圆信息
Int method, // 方法 - HOUGH_GRADIENT
Double dp, // dp = 1是在原图上找 =2是在不原图小一半的图上找;
Double mindist, // 10 最短距离-可以分辨是两个圆的,否则认为是同心圆- src_gray.rows/8
Double param1, // canny edge detection high threshold(the lower one is twice smaller)
Double param2, // 中心点累加器阈值 – 候选圆心,值越小可能检测到更多的假圆
Int minradius, // 最小半径
Int maxradius//最大半径 半径范围越大计算速度越慢
)
代码展示
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main()
{
Mat src = imread("F:/Opencvlearn/picture/yu.jpg");
if (!src.data)
{
printf("could not load image...\n");
return -1;
}
namedWindow("input", WINDOW_AUTOSIZE);
imshow("input", src);
Mat blur;
medianBlur(src, blur, 3);
Mat gray;
cvtColor(blur, gray, COLOR_BGR2GRAY);
vector<Vec3f> pcircles;
Mat dst;
src.copyTo(dst);
HoughCircles(gray, pcircles, HOUGH_GRADIENT, 1, gray.cols / 2, 150, 43, 0, gray.cols / 2);
for (size_t i = 0; i < pcircles.size(); ++i)
{
Point center = Point(cvRound(pcircles[i][0]), cvRound(pcircles[i][1]));
int radius = cvRound(pcircles[i][2]);
circle(dst, center, radius, Scalar(0, 0, 255), 2, 4);
circle(dst, center, 2, Scalar(255, 0, 0), 2, 4);
}
namedWindow("output", WINDOW_AUTOSIZE);
imshow("output", dst);
waitKey(0);
return 0;
}
cvRound()将浮点数四舍五入到最接近的整数