霍夫圓檢測


笛卡爾坐標系中,圓的方程為(x-a)^2+(y-b)^2=r^2

其中(a,b)是圓心,r是半徑

也可以表示為

x=a+rcosθ

y=b+rsinθ

 

再進行一次轉換

a=x-rcosθ

b=y-rsinθ

此時由於xy是給定的,將abr看成變量,映射到abr的三維坐標系中如圖

 

 所有經過(x,y)點的圓都可以用這條曲線表示

同樣,在xy坐標系中的所有圓都可以在這個三維坐標系中用曲線表示出來

 

假設空間中有三個點ABC,經過ABC三點的圓都是無數多的,在abr坐標系中可以可以表示為三條曲線,但是如果有一個圓同時過ABC三點,那么在abr坐標系中,它對應三條曲線的交點

因此,在xy坐標系中的一個圓上的所有點的圓方程,他們在abr坐標系中會交於同一點,通過判斷abr坐標系中該點有多少條直線相交,大於一定閾值的點就認定為圓

 

代碼演示

#include"pch.h"
#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(int argc, char **argv)
{
    Mat src, dst;
    src = imread("2.jpg");
    if (!src.data)
    {
        printf("Error\n");
        return -1;
    }

    char INPUT_TITLE[] = "input_image";
    char OUTPUT_TITLE[] = "hough_circle_demo";
    namedWindow(INPUT_TITLE, CV_WINDOW_AUTOSIZE);
    namedWindow(OUTPUT_TITLE, CV_WINDOW_AUTOSIZE);
    imshow(INPUT_TITLE, src);

    //中值濾波
    Mat mlf_opt;
    medianBlur(src, mlf_opt, 3);//ksize取3
    cvtColor(mlf_opt, mlf_opt, CV_BGR2GRAY);

    //霍夫圓檢測
    vector<Vec3f> pcircles;//可能的圓心
    HoughCircles(mlf_opt, pcircles, CV_HOUGH_GRADIENT, 1, 10, 100, 35, 5, 50);
    cout << pcircles[1] << endl;
    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, 255), 2, LINE_AA);
        circle(dst, Point(cc[0], cc[1]), 1, Scalar(198, 20, 255), 2, LINE_AA);

    }
    imshow(OUTPUT_TITLE, dst);
    waitKey(0);
    return 0;
}

 

 

 

 

函數帶有以下自變量:

  • src_gray: 輸入圖像 (灰度圖)
  • circles: 存儲下面三個參數: x_{c}, y_{c}, r 集合的容器來表示每個檢測到的圓.
  • CV_HOUGH_GRADIENT: 指定檢測方法. 現在OpenCV中只有霍夫梯度法
  • dp = 1: 累加器圖像的反比分辨率
  • min_dist = src_gray.rows/10: 檢測到圓心之間的最小距離
  • param_1 = 100: Canny邊緣函數的高閾值
  • param_2 = 35: 圓心檢測閾值.
  • min_radius = 5: 能檢測到的最小圓半徑, 默認為0.
  • max_radius = 50: 能檢測到的最大圓半徑, 默認為0

 circle打印圓,第一個打印邊界,第二個打印圓心(半徑調小)


免責聲明!

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



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