由于最近的事情一直有涉及霍夫圆变换,免得老翻书,这里记录下:
不用多说,OpenCV利用的是梯度法Python的API函数如下:
cv2.HoughCircles(image,method,dp,minDist[, circles[,param1, param2[,minRadius[,maxRadius]]]]])
其返回N个圆的信息储存在1×N×的ndarray。
- image 不用多说,输入矩阵
- method cv2.HOUGH_GRADIENT 也就是霍夫圆检测,梯度法
- dp 计数器的分辨率图像像素分辨率与参数空间分辨率的比值(官方文档上写的是图像分辨率与累加器分辨率的比值,它把参数空间认为是一个累加器,毕竟里面存储的都是经过的像素点的数量),dp=1,则参数空间与图像像素空间(分辨率)一样大,dp=2,参数空间的分辨率只有像素空间的一半大
- minDist 圆心之间最小距离,如果距离太小,会产生很多相交的圆,如果距离太大,则会漏掉正确的圆
- param1 canny检测的双阈值中的高阈值,低阈值是它的一半
- param2 最小投票数(基于圆心的投票数)
- minRadius 需要检测院的最小半径
- maxRadius 需要检测院的最大半径
在上我以前写的代码
from PIL import Image
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread('05.jpg')
GrayImage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
GrayImage= cv2.medianBlur(GrayImage,5)
ret,th1 = cv2.threshold(GrayImage,127,255,cv2.THRESH_BINARY)
th2 = cv2.adaptiveThreshold(GrayImage,255,cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY,3,5)
th3 = cv2.adaptiveThreshold(GrayImage,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY,3,5)
kernel = np.ones((5,5),np.uint8)
erosion = cv2.erode(th2,kernel,iterations=1)
dilation = cv2.dilate(erosion,kernel,iterations=1)
imgray=cv2.Canny(erosion,30,100)
circles = cv2.HoughCircles(imgray,cv2.HOUGH_GRADIENT,1,20,
param1=50,param2=30,minRadius=20,maxRadius=40)
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
# draw the outer circle
cv2.circle(img,(i[0],i[1]),i[2],(0,255,0),2)
# draw the center of the circle
cv2.circle(img,(i[0],i[1]),2,(0,0,255),3)
print(len(circles[0,:]))
cv2.imshow('detected circles',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
下面是效果图:
版权声明:本文为dz4543原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。