欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OpenCV——霍夫圆实现简单的圆检测

程序员文章站 2022-03-22 16:55:39
...

1.原理

圆周上任意三点所确定的圆,经Hough变换后在三维参数空间应对应一点。遍历圆周上所有点,任意三个点所确定的候选圆进行
投票。遍历结束后,得票数最高点(理论上圆周上任意三点确定的圆在Hough变换后均对应三维参数空间中的同一点)所确定的圆
即为该圆周上,绝大多数点所确定的圆(以下称为当选圆),即绝大多数点均在该当选圆的圆周上,以此确定该圆。

OpenCV——霍夫圆实现简单的圆检测

OpenCV——霍夫圆实现简单的圆检测


2.API介绍

cv::HoughCircles

  • 因为霍夫圆检测对噪声比较敏感,所以首先要对图像做中值滤波。
  • 基于效率考虑,Opencv中实现的霍夫变换圆检测是基于图像梯度的实现,分为两步:
    1. 检测边缘,发现可能的圆心
    2. 基于第一步的基础上从候选圆心开始计算最佳半径大小

3.代码(VS2017+OpenCV3.4)

#include <iostream>
#include <opencv2/opencv.hpp>
#include <math.h>

using namespace std;
using namespace cv;

Mat src;
Mat medianImg;
Mat grayImg;
Mat houghCirclesImg;

int main()
{
    src = imread("002.png");
    if (src.empty())
    {
        cout << "fail to load Img" << endl;
        return -1;
    }

    namedWindow("input_Img", 0);
    imshow("input_Img", src); 

    //中值滤波
    medianBlur(src, medianImg, 3);

    //灰度化处理
    cvtColor(medianImg, grayImg, CV_BGR2GRAY);

    //霍夫圆检测
    vector<Vec3f> pcircles;
    //输入,输出,方法(类型)-HOUGH_GRADIENT,dp(dp=1时表示霍夫空间与输入图像空间的大小一致,dp=2时霍夫空间是输入图像空间的一半,以此类推),最短距离-可以分辨是两个圆否 则认为是同心圆 ,边缘检测时使用Canny算子的高阈值,中心点累加器阈值—候选圆心(霍夫空间内累加和大于该阈值的点就对应于圆心),检测到圆的最小半径,检测到圆的的最大半径
    HoughCircles(grayImg,pcircles,CV_HOUGH_GRADIENT,1,10,100,30,5,50);

    //在原图画出圆心和圆
    for (size_t i = 0; i < pcircles.size(); i++)//size_t 无符号整数 unsigned int 
    {
        //提取圆心坐标
        Point center(cvRound(pcircles[i][0]), cvRound(pcircles[i][1]));//cvRound 返回和参数最接近的整数值
        //提取半径
        int radius = cvRound(pcircles[i][2]);
        //圆心
        circle(src, center, 3, Scalar(0, 255, 0), -1, 8, 0);
        //圆
        circle(src, center, radius, Scalar(0, 255, 0), 3, 8, 0);
    }

    namedWindow("circles", 0);
    imshow("circles", src);

    waitKey();
    return 0;
}

4.结果

检测结果和参数设置有很大的关系,不同图像的圆检测最好根据具体情况分析

原图
OpenCV——霍夫圆实现简单的圆检测
效果图
OpenCV——霍夫圆实现简单的圆检测

相关标签: OpenCV