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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM