本文编写了一种轮廓对比方法检测圆形,比霍夫检测更准确一些。
输入为路径,如果有圆,则返回圆的轮廓点,还可以画出来。
备注: cnt2 是圆的集合点,我事先把圆的集合点保存为了numpy格式,在调用就ok。
import numpy as np
import cv2
def img_read(path): #读图片,返回二值图
image = cv2.imread(path)
img_gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
ret,th1 = cv2.threshold(img_gray,200,255,cv2.THRESH_BINARY)
return th1
def img_erosion(image,k): #图像腐蚀 增强线条 k为核大小
kernel = np.ones((k,k),np.uint8)
erosion = cv2.erode(image,kernel,iterations = 1)
# dilation = cv2.dilate(th1,kernel,iterations = 1)
return erosion
def drawContours(image,counts): #根据点画出点图像
color = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
dst = cv2.drawContours(color, counts, -1, (0,255,0), 2)
cv2.imshow("dst", dst)
cv2.waitKey(0)
path="test_images/26.jpg" #图片路径
#path2="test_images/20.jpg"
def circle(path): #检测圆,返回圆的列表
img1=img_read(path)
img_er=img_erosion(img1,3) #图像增强
img1,contours1,hierarchy1=cv2.findContours(img_er,cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE) #找轮廓点
ret_list=[] #相似率
cnt_list=[] #圆的点
for contour in contours1:
cnt1 = contour
cnt2 = np.load("counts2.npy")
ret = cv2.matchShapes(cnt1,cnt2,1,0.0) #图片1与cnt2(标准圆的轮廓点)做匹配对比
if ret<0.005: #阀值设置 #越小,则越像圆
ret_list.append(ret)
cnt_list.append(cnt1)
# print(ret_list)
drawContours(img1,cnt_list) #画出图像
return cnt_list
circle(path) #运行程序