OpenCV20---霍夫圆检测
程序员文章站
2022-07-14 11:18:20
...
二十、霍夫圆检测
1、霍夫圆检测原理
- 从平面坐标到极坐标转换3个参数C(,,),其中、是圆心。
- 假设平面坐标的任意一个圆上的点,转换到极坐标中:C(,,)处有最大值,霍夫变换正是利用这个原理实现圆的检测。
霍夫圆检测先检测边缘,将非边缘处都变为零值。遍历所有非零值,将其投影为(a,b,r)空间的一个圆,笛卡尔坐标中同一个圆上的所有点投影到(a,b,r)空间将交于一点,这一点为笛卡尔坐标中这个圆的圆心。(a,b,r)中空间中每一个点有一个累加器,有一条线经过该点,累加器加1,根据阈值(大于某一个阈值)找到所有可能的圆心。
xa+yb =
axo+byo =
2、相关APIcv::HoughCircles
- 因为霍夫圆检测对噪声比较敏感,所以首先要对图像做中值滤波。
- 基于效率考虑,opencv中实现的霍夫圆检测是基于图像梯度的实现,分为两步:
(1)检测边缘,发现可能的圆心
(2)基于第一步的基础上从候选圆心开始计算最佳半径大小
HoughCircles(
InputArray image,//输入图像,必须是8位的单通道灰度图像
OutputArray circles,//输出结果,发现的圆信息,为三元向量组,存储每个可能的圆心坐标和半径信息(a,b,r)
int method,//方法-HOUGH_GRADIENT,求梯度,得到可能的边缘值,其余为零值
double dp,//取dp = 1,代表在原图的尺度下寻找,0.5为在原图的一半尺度上寻找
double mindist,//最短距离可以分辨是两个圆的,否则认为是同心圆
double param1,//canny edge detection low threshold
double param2,//中心点累加器阈值,候选圆心
int minradius,//最小半径
int maxradius//最大半径
)
示例代码:(霍夫圆检测)
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace cv;
using namespace std;
int main(int argc, char* argv) {
Mat src, dst;
src = imread("添加图片路径");
if (!src.data) {
cout << "could not load image..." << endl;
return -1;
}
char INPUT_WIN[] = "input image";
char OUTPUT_WIN[] = "Hough Demo";
namedWindow(INPUT_WIN, WINDOW_AUTOSIZE);
namedWindow(OUTPUT_WIN, WINDOW_AUTOSIZE);
imshow(INPUT_WIN, src);
//中值滤波
Mat moutput;
medianBlur(src, moutput, 3);
cvtColor(moutput, moutput, COLOR_BGR2GRAY);
//霍夫圆检测
vector<Vec3f> pcircles;//定义存储潜在的圆心坐标和半径(a,b,r)的向量组
HoughCircles(moutput, pcircles, HOUGH_GRADIENT, 1, 30, 100, 25, 2 ,50);
src.copyTo(dst);
for (size_t i = 0; i < pcircles.size(); i++) {//将圆心和圆做标记
Vec3f cc = pcircles[i];//提取第i个潜在圆的信息
circle(dst, Point(cc[0], cc[1]), cc[2], Scalar(0, 0, 255), 2, LINE_AA);//画出圆的边界,(cc[0],cc[1])存储的是圆心坐标,cc[2]存储的是半径
circle(dst, Point(cc[0], cc[1]), 2, Scalar(0, 255, 0), 2, LINE_AA);
}//画出圆心
imshow(OUTPUT_WIN, dst);
waitKey(0);
return 0;
}
输出结果显示如下:
上一篇: opencv20-霍夫圆检测
下一篇: Tomcat认知