Image Processing15(Hough Circle Transform )

Goal

In this tutorial you will learn how to:

  • Use the OpenCV function HoughCircles() to detect circles in an image.
  • 使用OpenCV函数HoughCircles() 检测图像中的圆

Theory

Hough Circle Transform

  • The Hough Circle Transform works in a roughly analogous way to the Hough Line Transform explained in the previous tutorial.霍夫圆变换同上节内容大概相似。
  • In the line detection case, a line was defined by two parameters (r,θ). In the circle case, we need three parameters to define a circle:

    C:(xcenter,ycenter,r)

    where (xcenter,ycenter) define the center position (green point) and r is the radius, which allows us to completely define a circle, as it can be seen below:

  • 在直线中用两个参数表示,而在圆中使用了三个参数。
  • For sake of efficiency, OpenCV implements a detection method slightly trickier than the standard Hough Transform: The Hough gradient method, which is made up of two main stages. The first stage involves edge detection and finding the possible circle centers and the second stage finds the best radius for each candidate center. For more details, please check the book Learning OpenCV or your favorite Computer Vision bibliography
  • 霍夫圆变换使用了一个:霍夫梯度法。大概由两部分组成。第一步检测图像的边缘,第二步则是找到每一个候选圆的最佳半径。

补充

对于霍夫圆变换解释的很棒:https://blog.csdn.net/dcrmg/article/details/52506538

此外:霍夫梯度法如下

首先对图像应用边缘检测;

然后对于边缘图像中的每一个非零点,考虑其梯度。

利用得到的梯度,则指定的直线上的每一个点都在累加器中被累加(因为圆心肯定在这条直线上)。

当这些中心点大雨给定的阀值时,则认为是圆心。于是解决了圆心问题。

对于每一个中心,考虑所有的非零元素。

找到非零元素最支持的一条半径长度,则即是半径。

Code

#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
    const char* filename = argc >=2 ? argv[1] : "lena1.png";
    // Loads an image
    Mat src = imread( filename, IMREAD_COLOR );
    // Check if image is loaded fine
    if(src.empty()){
        printf(" Error opening image\n");
        printf(" Program Arguments: [image_name -- default %s] \n", filename);
        return -1;
    }
    Mat gray;
    cvtColor(src, gray, COLOR_BGR2GRAY);
    medianBlur(gray, gray, 5);//输入,输出,内核大小
    vector<Vec3f> circles;
    HoughCircles(gray, circles, HOUGH_GRADIENT, 1,
                 gray.rows/16,  // change this value to detect circles with different distances to each other
                 100, 30, 1, 30 // change the last two parameters
            // (min_radius & max_radius) to detect larger circles
    );
    //输入,输出,定义检测方法,用于设置累加器的分辨率,圆心之间最小的距离,阀值,圆心的累加器阀值,圆半径最小值,圆半径最大值。
    for( size_t i = 0; i < circles.size(); i++ )
    {
        Vec3i c = circles[i];
        Point center = Point(c[0], c[1]);
        // circle center
        circle( src, center, 1, Scalar(0,100,100), 3, LINE_AA);//圆心
        // circle outline
        int radius = c[2];
        circle( src, center, radius, Scalar(255,0,255), 3, LINE_AA);//圆
    }
    imshow("detected circles", src);
    waitKey();
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

set(CMAKE_CXX_FLAGS "-std=c++11")
project( DisplayImage )
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_executable( DisplayImage main.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBS} )


install(TARGETS DisplayImage RUNTIME DESTINATION bin

Results





猜你喜欢

转载自blog.csdn.net/qq_27806947/article/details/80302915