这个系列的目的是通过对OpenCV示例,进一步了解OpenCV函数的使用,不涉及具体原理。
目录
简介
Example运行截图
Example分析
Example代码
简介
本文记录了对OpenCV示例
houghcircles
.cpp
的分析。
这个示例主要演示了如何使用
houghcircles
对图像进行圆形检测。
示例涉及到
HoughCircles。
HoughCircles
HoughCircles函数实现了圆形检测,它使用的算法
也是改进的霍夫变换——2-1霍夫变换(21HT)。
函数原型:
void HoughCircles( InputArray image, OutputArray circles,
int method, double dp, double minDist,
double param1 = 100, double param2 = 100,
int minRadius = 0, int maxRadius = 0 );
函数参数说明:
image:为输入图像,要求是灰度图像; circles:为输出圆向量,每个向量包括三个浮点型的元素——圆心横坐标,圆心纵坐标和圆 半径; method:为使用霍夫变换圆检测的算法,Opencv只实现了2-1霍夫变换,它的参数是 CV_HOUGH_GRADIENT;(一直都是如此) dp:为第一阶段所使用的霍夫空间的分辨率,dp=1时表示霍夫空间与输入图像空间的大小 一致,dp=2时霍夫空间是输入图像空间的一半,以此类推; minDist:为圆心之间的最小距离,如果检测到的两个圆心之间距离小于该值,则认为它们是 同一个圆心; param1:为边缘检测时使用Canny算子的高阈值; param2:为步骤1.5和步骤2.5中所共有的阈值; minRadius,maxRadius:为所检测到的圆半径的最小值和最大值。
PS:在实际应用中HoughCircles的参数很让人着急,因此往往与fitellipse配合使用,大致原理为: (1)使用HoughCircles做粗略定位; (2)使用fitellipse进一步精确定位。 |
Example截图
原图
|
效果图
|
|
|
Example分析
1.从命令行参数加载图像
const char* filename = argc >= 2 ? argv[1] : "../data/board.jpg";
Mat img = imread(filename, 0);
if(img.empty())
{
help();
cout << "can not open " << filename << endl;
return -1;
}
2.声明预览图像
Mat cimg;
3.对原图中值滤波
medianBlur(img, img, 5);
4.灰度化
cvtColor(img, cimg, COLOR_GRAY2BGR);
5.对图像进行圆形检测
vector<Vec3f> circles;
HoughCircles(img, circles, HOUGH_GRADIENT, 1, 10,
100, 30, 1, 30 // change the last two parameters
// (min_radius & max_radius) to detect larger circles
6.根据检测结果绘制检测圆形
for( size_t i = 0; i < circles.size(); i++ )
{
Vec3i c = circles[i];
circle( cimg, Point(c[0], c[1]), c[2], Scalar(0,0,255), 3, LINE_AA);
circle( cimg, Point(c[0], c[1]), 2, Scalar(0,255,0), 3, LINE_AA);
}
7.显示预览图
imshow("detected circles", cimg);
waitKey();
Example代码
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
static void help()
{
cout << "\nThis program demonstrates circle finding with the Hough transform.\n"
"Usage:\n"
"./houghcircles <image_name>, Default is ../data/board.jpg\n" << endl;
}
int main(int argc, char** argv)
{
const char* filename = argc >= 2 ? argv[1] : "../data/board.jpg";
Mat img = imread(filename, 0);
if(img.empty())
{
help();
cout << "can not open " << filename << endl;
return -1;
}
Mat cimg;
medianBlur(img, img, 5);
cvtColor(img, cimg, COLOR_GRAY2BGR);
vector<Vec3f> circles;
HoughCircles(img, circles, HOUGH_GRADIENT, 1, 10,
100, 30, 1, 30 // change the last two parameters
// (min_radius & max_radius) to detect larger circles
);
for( size_t i = 0; i < circles.size(); i++ )
{
Vec3i c = circles[i];
circle( cimg, Point(c[0], c[1]), c[2], Scalar(0,0,255), 3, LINE_AA);
circle( cimg, Point(c[0], c[1]), 2, Scalar(0,255,0), 3, LINE_AA);
}
imshow("detected circles", cimg);
waitKey();
return 0;
}
参考资料:
1.《
找圆算法((HoughCircles)总结与优化
》