hough圆检测

方法1:

  1. 如下图所示,确定一个圆需要3个参数:半径,圆心的横坐标,圆心的纵坐标

 

  2.所以我们可以以如下方式进行投票:

 

 

 遍历图像上的所有像素点,选取不同的半径进行投票,选择投票数超过阈值的那个像素点作为圆心,如下图所示:

 

 缺点:计算量太大

方法二:霍夫梯度法

原理:

如下图所示:

 

圆的边缘点切线的垂直方向,也就是梯度方向过圆点,所以我们可以遍历图像的所有点,对每个像素点计算梯度,比如Sobel算子,对该直线上的所有像素点进行投票,最后选取超过阈值的某个像素点,为了避免选取过多的圆心,可以把一个像素点周围相差不大的像素点看做成一个圆心,确定圆心后再计算以改点为圆心的最佳半径,结果如下:

 

 该方法优点:速度快

缺点:圆心可能会有偏差,这个方法对噪声比较敏感,所以可以先做中值滤波,做完之后再用hough圆变换

 

 

 原图直接处理的代码:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
#include <vector>
using namespace cv;
using namespace std;

Mat src, dst,dst2,gray_src;
char* INPUT_WIN = "input image";
char* OUTPUT_WIN = "binary image";
int t1_value = 50;
int max_value = 255;




int main()
{

    src = imread(".//pic//0.jpg");

    namedWindow(INPUT_WIN, CV_WINDOW_AUTOSIZE);
    imshow(INPUT_WIN, src);

    
    Mat moutput;
    //转成灰度图
    cvtColor(src, moutput, CV_BGR2GRAY);

    //霍夫圆检测
    vector<Vec3f> pcircles;
    HoughCircles(moutput, pcircles, CV_HOUGH_GRADIENT, 1, 30, 100, 30, 110, 200);

    src.copyTo(dst);
    for (size_t i = 0; i < pcircles.size(); i++)
    {
        Vec3f cc = pcircles[i];
        circle(dst, Point(cc[0], cc[1]), cc[2], Scalar(0, 0, 2), 2, LINE_AA);
        circle(dst, Point(cc[0], cc[1]), cc[2], Scalar(0, 255, 0), 2, LINE_AA);
    }
    imshow("Hough检测后", dst);

    waitKey(0);
    return 0; 
}

 

 转成灰度图再处理的代码:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
#include <vector>
using namespace cv;
using namespace std;

Mat src, dst,dst2,gray_src;
char* INPUT_WIN = "input image";
char* OUTPUT_WIN = "binary image";
int t1_value = 50;
int max_value = 255;




int main()
{

    src = imread(".//pic//0.jpg");

    namedWindow(INPUT_WIN, CV_WINDOW_AUTOSIZE);
    imshow(INPUT_WIN, src);

    
    Mat moutput;
    //转成灰度图
    cvtColor(src, moutput, CV_BGR2GRAY);
    //中值滤波
    medianBlur(moutput, moutput, 3);
    imshow("中值滤波后", moutput);
    //边缘检测
    Canny(moutput, dst2, 100, 100 * 2, 3, false);
    imshow("canny", dst2);

    //霍夫圆检测
    vector<Vec3f> pcircles;
    HoughCircles(dst2, pcircles, CV_HOUGH_GRADIENT, 1, 10, 100, 30, 110, 200);

    src.copyTo(dst);
    for (size_t i = 0; i < pcircles.size(); i++)
    {
        Vec3f cc = pcircles[i];
        circle(dst, Point(cc[0], cc[1]), cc[2], Scalar(0, 0, 2), 2, LINE_AA);
        circle(dst, Point(cc[0], cc[1]), cc[2], Scalar(0, 255, 0), 2, LINE_AA);
    }
    imshow("Hough检测后", dst);

    waitKey(0);
    return 0; 
}

 

posted @ 2019-12-12 13:03  喵小喵~  阅读(1836)  评论(0编辑  收藏  举报