OpenCV-霍夫圆检测HoughCircles

OpenCV-霍夫圆检测HoughCircles

霍夫圆检测原理

从平面坐标到极坐标转换三个参数 C(x0,y0,r) C ( x 0 , y 0 , r ) 其中 x0,y0 x 0 , y 0 是圆心
假设平面坐标的任意一个圆上的点,转换到极坐标中: C(x0,y0,r) C ( x 0 , y 0 , r ) 处有最大值,霍夫变换正是利用这个原理实现圆的检测。

现实考量:

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


import cv2
import numpy as np
import time
import matplotlib as plt

def dectect_circle_demo(image):
    # dst = cv2.bilateralFilter(image, 0, 150, 5)
    # 高斯双边模糊
    # cv2.imshow("1", dst)
    # dst = cv2.pyrMeanShiftFiltering(image, 5, 100)
    # 均值迁移,EPT边缘保留滤波
    # cv2.imshow("2", dst)
    # dst = cv2.GaussianBlur(image, (13, 15), 15)
    # 使用高斯模糊
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 20, param1=80, param2=20, minRadius=12, maxRadius=25)
    circles = np.uint16(np.around(circles))
    for i in circles[0, :]:
        # 圆心加到图中
        cv2.circle(image, (i[0], i[1]), i[2], (0, 0, 255), 2)
        # 圆圈加到图中
        cv2.circle(image, (i[0], i[1]), 2, (255, 0, 0), 2)

    cv2.namedWindow("detect_circle_demo", cv2.WINDOW_NORMAL)
    cv2.imshow("detect_circle_demo", image)


if __name__ == "__main__":

    start = time.clock()
    file = '0101_1'
    name = '.jpeg'
    filename = file + name

    # img = cv2.imread(filename, 0)
    # 参数零代表读取的图片为灰度图
    img = cv2.imread(filename)
    cv2.namedWindow("input", cv2.WINDOW_NORMAL)
    # 设置窗口大小为NORMAL 避免大照片窗口太大
    cv2.imshow("input", img)
    dectect_circle_demo(img)
    end = time.clock()
    print('Running time: %s Seconds' % (end - start))
    while (1):
        k = (cv2.waitKey() & 0xFF)
        if k == ord('q') or k == 27:
            cv2.destroyAllWindows()
            break
        elif k == ord('s'):
            cv2.imwrite(file + '_out' + name, img)
            break

函数 HoughCircles相关参数,
手册中的declaration

def HoughCircles(image, method, dp, minDist, circles=None, param1=None, param2=None, minRadius=None, maxRadius=None): # real signature unknown; restored from __doc__
    """
    HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]]) -> circles
    .   @brief Finds circles in a grayscale image using the Hough transform.
    .   
    .   The function finds circles in a grayscale image using a modification of the Hough transform.
    .   
    .   Example: :
    .   @code
    .   #include 
    .   #include 
    .   #include 
    .   
    .   using namespace cv;
    .   using namespace std;
    .   
    .   int main(int argc, char** argv)
    .   {
    .   Mat img, gray;
    .   if( argc != 2 || !(img=imread(argv[1], 1)).data)
    .   return -1;
    .   cvtColor(img, gray, COLOR_BGR2GRAY);
    .   // smooth it, otherwise a lot of false circles may be detected
    .   GaussianBlur( gray, gray, Size(9, 9), 2, 2 );
    .   vector circles;
    .   HoughCircles(gray, circles, HOUGH_GRADIENT,
    .   2, gray.rows/4, 200, 100 );
    .   for( size_t i = 0; i < circles.size(); i++ )
    .   {
    .   Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
    .   int radius = cvRound(circles[i][2]);
    .   // draw the circle center
    .   circle( img, center, 3, Scalar(0,255,0), -1, 8, 0 );
    .   // draw the circle outline
    .   circle( img, center, radius, Scalar(0,0,255), 3, 8, 0 );
    .   }
    .   namedWindow( "circles", 1 );
    .   imshow( "circles", img );
    .   
    .   waitKey(0);
    .   return 0;
    .   }
    .   @endcode
    .   
    .   @note Usually the function detects the centers of circles well. However, it may fail to find correct
    .   radii. You can assist to the function by specifying the radius range ( minRadius and maxRadius ) if
    .   you know it. Or, you may set maxRadius to a negative number to return centers only without radius
    .   search, and find the correct radius using an additional procedure.
    .   
    .   @param image 8-bit, single-channel, grayscale input image.
    .   @param circles Output vector of found circles. Each vector is encoded as a 3-element
    .   floating-point vector \f$(x, y, radius)\f$ .
    .   @param method Detection method, see #HoughModes. Currently, the only implemented method is #HOUGH_GRADIENT
    .   @param dp Inverse ratio of the accumulator resolution to the image resolution. For example, if
    .   dp=1 , the accumulator has the same resolution as the input image. If dp=2 , the accumulator has
    .   half as big width and height.
    .   @param minDist Minimum distance between the centers of the detected circles. If the parameter is
    .   too small, multiple neighbor circles may be falsely detected in addition to a true one. If it is
    .   too large, some circles may be missed.
    .   @param param1 First method-specific parameter. In case of #HOUGH_GRADIENT , it is the higher
    .   threshold of the two passed to the Canny edge detector (the lower one is twice smaller).
    .   @param param2 Second method-specific parameter. In case of #HOUGH_GRADIENT , it is the
    .   accumulator threshold for the circle centers at the detection stage. The smaller it is, the more
    .   false circles may be detected. Circles, corresponding to the larger accumulator values, will be
    .   returned first.
    .   @param minRadius Minimum circle radius.
    .   @param maxRadius Maximum circle radius. If <= 0, uses the maximum image dimension. If < 0, returns
    .   centers without finding the radius.
    .   
    .   @sa fitEllipse, minEnclosingCircle
    """


method:输入图像(灰度图)
method:指定检测方法,目前OpenCV中只有霍夫梯度法
dp:累加器图像的反比分辨 =1 即可默认
minDist = src_gray.row/8: 检测到圆心之间的最小距离,经验值。这个大了,那么多个圆就被认为是一个圆
param_1 : canny边缘函数的高阈值
param_2 : 圆心检测阈值,根据图像中的圆的大小设置,当这张图片中的圆越小,那么此值就应该设置越小。当设置的越小,那么检测出的圆越多,在检测较大的圆时,则会产生很多噪声。所以要根据检测圆的大小变化
min_radius = 0 : 能检测到的最小圆半径,默认为0.
max_radius = 0 : 能检测到的最大圆半径,默认为0.

你可能感兴趣的:(Python,OpenCV,数字图像处理,OpenCV,Python)