环境
vs2019,OpenCV
效果
函数解释
image:输入图像,可以是彩色图或者灰度图
circles:向量的向量,std::vector<cv::Vec3f>,cv::Vec3f里面存储每个圆的(x,y,radius)
method: 霍夫圆检测的方法,可用HOUGH_GRADIENT 和HOUGH_GRADIENT_ALT,在一般情况下两者差别不大。
dp:HOUGH_GRADIENT_ALT推荐值为1.5,如果要检测小圆,需要调整一下这个参数。
minDist: 圆之间的允许的最小距离。
param1: 传递给Canny边缘检测器的大阈值,该函数会执行边缘检测,所以不用我们在之前进行该操作。
param2:HOUGH_GRADIENT 的情况下,该值越小检测到的假的圆就越多,如果检测不到圆需要降低此值。
minRadius:检测到的圆的最小半径,可用于过滤
maxRadius:检测到的圆的最大半径。
代码
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/videoio.hpp>
#include<sstream>
int main(int argc, char* argv[])
{
cv::Mat img, img_gray, img_source;
img = cv::imread("E:\\Comm\\demo\\23.jpeg", 1);
img_source = img.clone();
cv::cvtColor(img, img_gray, cv::COLOR_BGR2GRAY); //灰度化
cv::GaussianBlur(img_gray, img_gray, cv::Size(3, 3),0 ); //高斯滤波
//cv::threshold(img_gray, img_gray, 70, 255, cv::THRESH_BINARY_INV);
cv::namedWindow("example", 1);
std::vector<cv::Vec3f> circles; //用于存储检测结果
cv::Mat img_b;
while (true)
{
//cv::dilate(img_b, img_b, cv::Mat());
//cv::erode(img_b, img_b, cv::Mat());
//cv::Canny(img_gray, img_b, 170, 200, 3, false); //边缘检测
//
//圆检测,模式1,dp=1, 最小距离20, Canny大阈值200, 圆的严格程度80, 最小半径100, 最大半径600
cv::HoughCircles(img_gray, circles, cv::HOUGH_GRADIENT, 1, 20, 200, 80, 100, 600);
//绘制检测到的圆
for (size_t i = 0; i < circles.size(); i++)
{
//圆心
cv::Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]); //半径
// 画圆心
cv::circle(img, center, 3, cv::Scalar(0, 255, 0), -1, 8, 0);
// 画圆
cv::circle(img, center, radius, cv::Scalar(0, 0, 255), 2, 8, 0);
}
//图像不为空则显示图像
if (img.empty() == false)
{
cv::imshow("example", img);
cv::imshow("binary", img_source);
}
int key = cv::waitKey(10); //等待30ms
if (key == int('q')) //按下q退出
{
break;
}
}
cv::destroyAllWindows(); //关闭所有窗口
return 0;
}
参数调整比较重要!