python opencv之 Hough圆变换

原博客地址:https://blog.csdn.net/tengfei461807914/article/details/77507820

https://blog.csdn.net/Tina_Wei/article/details/78202694

内容来自OpenCV-Python Tutorials 自己翻译整理

目标:

使用霍夫变换在图像中寻找圆
使用函数cv2.HoughCircles()

原理:

圆形的表达式为(x−xcenter)2+(y−ycenter)2=r2(x−xcenter)2+(y−ycenter)2=r2,一个圆环的确定需要三个参数。那么霍夫变换的累加器必须是三维的,但是这样的计算效率很低。
这里opencv中使用霍夫梯度的方法,这里利用了边界的梯度信息。

首先对图像进行canny边缘检测,对边缘中的每一个非0点,通过Sobel算法计算局部梯度。那么计算得到的梯度方向,实际上就是圆切线的法线。三条法线即可确定一个圆心,同理在累加器中对圆心通过的法线进行累加,就得到了圆环的判定。

cv2.HoughCircles函数的参数

cv2.HoughCircles(image, method, dp, minDist, circles, param1, param2, minRadius, maxRadius)
  • dp,用来检测圆心的累加器图像的分辨率于输入图像之比的倒数,且此参数允许创建一个比输入图像分辨率低的累加器。上述文字不好理解的话,来看例子吧。例如,如果dp= 1时,累加器和输入图像具有相同的分辨率。如果dp=2,累加器便有输入图像一半那么大的宽度和高度。
  • minDist,为霍夫变换检测到的圆的圆心之间的最小距离,即让我们的算法能明显区分的两个不同圆之间的最小距离。这个参数如果太小的话,多个相邻的圆可能被错误地检测成了一个重合的圆。反之,这个参数设置太大的话,某些圆就不能被检测出来了。
  • param1,有默认值100。它是method设置的检测方法的对应的参数。对当前唯一的方法霍夫梯度法,它表示传递给canny边缘检测算子的高阈值,而低阈值为高阈值的一半。
  • param2,也有默认值100。它是method设置的检测方法的对应的参数。对当前唯一的方法霍夫梯度法,它表示在检测阶段圆心的累加器阈值。它越小的话,就可以检测到更多根本不存在的圆,而它越大的话,能通过检测的圆就更加接近完美的圆形了。
  • minRadius,默认值0,表示圆半径的最小值。
  • maxRadius,也有默认值0,表示圆半径的最大值。

源代码

import cv2
import numpy as np

img = cv2.imread('image/1.jpg', 0)
img = cv2.medianBlur(img, 5)
cimg = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)

circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 100,
                            param1=100, param2=30, minRadius=40, maxRadius=70)

circles = np.uint16(np.around(circles))

for i in circles[0,:]:
    # draw the outer circle
    cv2.circle(cimg, (i[0], i[1]), i[2], (0, 255, 0), 2)
    print('圆心坐标:', i[0], i[1])
    print('圆半径:', i[2])
    # draw the center of the circle
    cv2.circle(cimg, (i[0], i[1]), 2, (0, 0, 255), 3)


cv2.imshow('detected circles', cimg)
cv2.imwrite('image/ceshi.jpg', cimg)
cv2.waitKey(0)
cv2.destroyAllWindows()


在给一个使用摄像头进行寻找圆 的代码

import cv2
import numpy as np

def circle(image):

    img = cv2.medianBlur(image, 5)
    cimg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    print('the shape of cimg: ', cimg.shape)
    # circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,100,
    #                             param1=100,param2=30,minRadius=40, maxRadius=70)
    circles = cv2.HoughCircles(cimg, cv2.HOUGH_GRADIENT, 1, 100,
                                param1=100, param2=30, minRadius=40, maxRadius=100)

    # print('circles: ', circles)
    if circles is None:
        return image
    circles = np.uint16(np.around(circles))
    for i in circles[0,:]:
        # draw the outer circle
        image1 = cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)
        print('圆心坐标:', i[0], i[1])
        print('圆心半径:', i[2])
        # draw the center of the circle
        images = cv2.circle(image1, (i[0], i[1]), 2, (0, 0, 255), 3)

    return images



if __name__ == '__main__':
    cap = cv2.VideoCapture(0)
    cap.set(3, 960)
    cap.set(4, 960)

    while(1):
        # get a frame
        ret, frame = cap.read()
        if not ret:
            print('video read error')

        frame = circle(frame)
        # show a frame
        cv2.imshow("capture", frame)
        print('hi')

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    cap.release()
    cv2.destroyAllWindows()

猜你喜欢

转载自blog.csdn.net/pursuit_zhangyu/article/details/82842211