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

1.原理

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

公式

OpenCV——霍夫圆实现简单的圆检测_第1张图片


2.API介绍

cv::HoughCircles

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

3.代码(VS2017+OpenCV3.4)

#include 
#include 
#include 

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 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)