OpenCV20---霍夫圆检测

二十、霍夫圆检测

1、霍夫圆检测原理

  • 从平面坐标到极坐标转换3个参数C( x 0 x_0 x0, y 0 y_0 y0, r r r),其中 x 0 x_0 x0 y 0 y_0 y0是圆心。
  • 假设平面坐标的任意一个圆上的点,转换到极坐标中:C( x 0 x_0 x0, y 0 y_0 y0, r r r)处有最大值,霍夫变换正是利用这个原理实现圆的检测。


霍夫圆检测先检测边缘,将非边缘处都变为零值。遍历所有非零值,将其投影为(a,b,r)空间的一个圆,笛卡尔坐标中同一个圆上的所有点投影到(a,b,r)空间将交于一点,这一点为笛卡尔坐标中这个圆的圆心。(a,b,r)中空间中每一个点有一个累加器,有一条线经过该点,累加器加1,根据阈值(大于某一个阈值)找到所有可能的圆心。
( ( x − - a ) 2 )^2 )2+ ( ( y − - b ) 2 )^2 )2 = r 2 r^2 r2
( ( a − - xo ) 2 )^2 )2+ ( ( b − - yo ) 2 )^2 )2 = r 2 r^2 r2

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;
}

输出结果显示如下:

在这里插入图片描述

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在Qt中使用OpenCV库实现霍夫圆检测的步骤如下: 1.在Qt项目中添加OpenCV库,可以通过Qt Creator的“添加库”功能或手动添加库文件实现。 2.在Qt项目中添加图片读取功能,OpenCV库支持多种图片格式,可以使用cv::imread()函数读取图片。 3.在Qt项目中添加霍夫圆检测功能,可以使用cv::HoughCircles()函数实现,该函数需要传入原始图片、检测到的圆的输出参数、霍夫圆检测算法的参数等。 4.在Qt项目中实现圆的绘制功能,可以使用Qt自带的绘图功能,也可以使用OpenCV库中的cv::circle()函数。 下面是一个简单的示例代码: ```cpp #include <opencv2/opencv.hpp> #include <QImage> cv::Mat qimageToMat(QImage image) { return cv::Mat(image.height(), image.width(), CV_8UC4, image.bits(), image.bytesPerLine()).clone(); } QImage matToQImage(cv::Mat image) { QImage qimage(image.data, image.cols, image.rows, image.step, QImage::Format_RGB888); return qimage.rgbSwapped(); } void houghCircleDetection(QImage image) { cv::Mat matImage = qimageToMat(image); cv::Mat grayImage; cv::cvtColor(matImage, grayImage, cv::COLOR_BGR2GRAY); cv::GaussianBlur(grayImage, grayImage, cv::Size(9, 9), 2, 2); std::vector<cv::Vec3f> circles; cv::HoughCircles(grayImage, circles, cv::HOUGH_GRADIENT, 1, grayImage.rows/8, 200, 100); for(size_t i = 0; i < circles.size(); i++) { cv::Vec3i circle = circles[i]; cv::circle(matImage, cv::Point(circle[0], circle[1]), circle[2], cv::Scalar(0, 0, 255), 2); } QImage resultImage = matToQImage(matImage); // 显示或保存结果 } ``` 在这个示例中,我们首先将QImage类型的图片转换成cv::Mat类型的图片。然后,我们将图片转换成灰度图,并进行高斯模糊处理,以便更好地检测圆。 接着,我们调用cv::HoughCircles()函数进行霍夫圆检测,并将圆的位置和半径保存在std::vector<cv::Vec3f>类型的变量circles中。 最后,我们在原始图片上绘制圆,并将结果转换成QImage类型的图片保存或显示。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值