1.cv.HoughCircles:圆形霍夫变换-OpenCV
基本原理:
对于圆周上的每一个点,求其梯度,根据梯度可做出关于此点的切线,与切线垂直的方向就是梯度样方向,每个点的梯度方向的交点就是圆心,然后根据圆心的位置可以确定其半径。
circles=cv.HoughCircles(image, method, dp, minDist[, param1[, param2[, minRadius[, maxRadius]]]]])
image:灰度图像
method:一般为cv.HOUGH_GRADIENT
dp:累加器分辨率与图像分辨率的反比,一般为1
minDist:不同圆心直接的最小距离,太大会遗漏一些圆形,太小会产生许多无关的圆
param1:传递给 canny 边缘检测算子的高阀值,而低阀值为高阀值的一半
param2:是检测阶段圆心的累加阀值。越小可以检测到更多的假圆。越大能通过检测的圆就更加接近完美的圆形。
minRadius:最小半径
maxRadius:最大半径
2.OpenCV circle()函数
cvCircle(CvArr* img, CvPoint center, int radius, CvScalar color, int thickness=1, int lineType=8, int shift=0)
img为源图像指针
center为画圆的圆心坐标
radius为圆的半径
color为设定圆的颜色,规则根据B(蓝)G(绿)R(红)
thickness 如果是正数,表示组成圆的线条的粗细程度。否则,-1表示圆是否被填充
line_type 线条的类型。默认是8
shift 圆心坐标点和半径值的小数点位数
以下为在圈出水表圆盘过程的代码,将表盘框出然后裁剪并重新设置大小为600*600,这是学习的过程,可能一些用法比较繁琐
img_list = os.listdir(data_list_path)
#for i in range(len(img_list)):
i=140
img=cv.imread(data_list_path+'/'+img_list[i])
imgcopy = img.copy()
gray = cv.cvtColor(imgcopy,cv.COLOR_BGR2GRAY)
dst = cv.calcHist([gray], [0], None, [256], [0, 256])
gray1 = cv.equalizeHist(gray)
dst1 = cv.calcHist([gray1], [0], None, [256], [0, 256])
# plt.subplot(211), plt.plot(dst)
# #plt.subplot(312), plt.plot(dst1)
# plt.subplot(212), plt.plot(dst1)
# plt.show()
print(np.shape(gray),min(np.shape(gray)))
sy,sx=np.shape(gray)
td=min(np.shape(gray))
minD=int(td/4)
minR=int(td/4)
maxR=int(td/2)
# 将图进行中值模糊,检测圆的效果更好
gray = cv.medianBlur(gray,5)
th=170
err=0
#thresh1=cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY,9, 2)
ret2,thresh2=cv.threshold(gray,th,255,cv.THRESH_TRUNC)
#binary = cv.adaptiveThreshold(gray, 127, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 9, 30)
circles = cv.HoughCircles(thresh2,cv.HOUGH_GRADIENT,dp=1,minDist=minD,
param1=50,param2=60
,minRadius=minR,maxRadius=maxR)
try:
# 将变换后的浮点值转换为整数
detected_circles = np.int16(np.around(circles))
except TypeError:
err=1
print(np.shape(detected_circles)[1])
while err==1 or np.shape(detected_circles)[1]!=1:
print('running')
th-=10
ret2, thresh2 = cv.threshold(gray, th, 255, cv.THRESH_TRUNC)
# binary = cv.adaptiveThreshold(gray, 127, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 9, 30)
circles = cv.HoughCircles(thresh2, cv.HOUGH_GRADIENT, dp=1, minDist=minD,
param1=50, param2=60
, minRadius=minR, maxRadius=maxR)
try:
# 将变换后的浮点值转换为无符号整数
detected_circles = np.int16(np.around(circles))
except TypeError:
err = 1
else:
err=0
#c=c.append(np.shape(detected_circles))
print(np.shape(detected_circles)[1])
print(np.shape(detected_circles),detected_circles)
# if (len(detected_circles)!=1):
# continue
for (x,y,r) in detected_circles[0,:]:
cv.circle(imgcopy,(x,y),r,(0,255,0),3)
#画个圆心
cv.circle(imgcopy,(x,y),2,(0,255,255),3)
x1=(x-r) if (x-r)>0 else 0
x2=(x+r) if (x+r)<sx else sx
y1=(y-r) if (y-r)>0 else 0
y2=(y+r) if (y+r)<sy else sy
print((x1,x2),(y1,y2))
cropImg = img[y1:y2, x1:x2]