Python OpenCV:从霍夫圆检测中获取统计数据
Python OpenCV: Getting Stats out of Hough Circle Detection
我和一个同学正在通过图像处理制作硬币计数器。我们使用两种方法将硬币识别为圆圈。一方面使用 Stats 连接组件,另一方面 Hough 变换。 CC w/ Stats 的优点是所有重要参数(例如像素区域)的直接输出。然而,CC 在图像中触摸硬币时 w/stats 减弱(硬币的中心未被正确识别)。霍夫变换没有这个问题,可以轻松正确地检测到每个圆。但是,我们不知道如何在这里使用检测到的对象的数据。那么有没有一种方法可以用另一个函数获取数据,或者甚至有一种方法可以从 CC w/ Stats 和 Hough 转换生成混合代码?
import cv2
import numpy as np
import matplotlib.pyplot as plt
image='17.png'
img=cv2.imread(image,1)
img_orig=img.copy()
img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img=cv2.GaussianBlur(img,(21,21),cv2.BORDER_DEFAULT)
all_circs=cv2.HoughCircles(img, cv2.HOUGH_GRADIENT,1,500,param1=110,param2=35,minRadius=200,maxRadius=600)
all_circs_rounded=np.uint32(np.around(all_circs))
count = 1
for i in all_circs_rounded[0, :]:
cv2.circle(img_orig,(i[0],i[1],),i[2],(255,0,0),3)
cv2.circle(img_orig,(i[0],i[1],),2,(255,0,0),3)
cv2.putText(img_orig,"Coin"+str(count),(i[0]-70,i[1]+30),cv2.FONT_HERSHEY_SIMPLEX,1.1,(255,0,0),2)
count+=1
print (all_circs_rounded)
print (all_circs_rounded.shape)
print ('I have found ' + str(all_circs_rounded.shape[1]) + ' coins')
plt.rcParams["figure.figsize"]=(16,9)
plt.imshow(img_orig)
这个问题有几种可能的解决方案
您可以使用 image segmentation with watershed。这种方法的优点是能够在图像中找到接触的硬币,因为您可以轻松地将硬币彼此分开。此外,分水岭可以让你获得硬币的中心,在那里你可以做额外的处理。
继续使用Hough Circle Transform. The function returns various parameters such as the radius which you can use to find the circle's area. Here's a quick example to obtain the radius which you can use the find the area using the classic formula。这种方法也可以让你轻松获得圆心
# detect circles in the image
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1.2, 100)
# ensure at least some circles were found
if circles is not None:
# convert the (x, y) coordinates and radius of the circles to integers
circles = np.round(circles[0, :]).astype("int")
# loop over the (x, y) coordinates and radius of the circles
for (x, y, r) in circles:
# draw the circle in the output image, then draw a rectangle
# corresponding to the center of the circle
cv2.circle(output, (x, y), r, (0, 255, 0), 4)
cv2.rectangle(output, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)
# calculate area here
...
完全旋转并使用带过滤的轮廓检测。可能的步骤是
- 将图像转换为灰度
- 高斯模糊
- 执行canny edge detection or threshold获取二值图像
- 执行 morphological transformations 例如
cv2.dilate()
或 cv2.erode()
- 使用
cv2.contourArea()
查找轮廓、过滤和查找区域
- 要找到硬币的中心,您可以使用image moments找到质心
我和一个同学正在通过图像处理制作硬币计数器。我们使用两种方法将硬币识别为圆圈。一方面使用 Stats 连接组件,另一方面 Hough 变换。 CC w/ Stats 的优点是所有重要参数(例如像素区域)的直接输出。然而,CC 在图像中触摸硬币时 w/stats 减弱(硬币的中心未被正确识别)。霍夫变换没有这个问题,可以轻松正确地检测到每个圆。但是,我们不知道如何在这里使用检测到的对象的数据。那么有没有一种方法可以用另一个函数获取数据,或者甚至有一种方法可以从 CC w/ Stats 和 Hough 转换生成混合代码?
import cv2
import numpy as np
import matplotlib.pyplot as plt
image='17.png'
img=cv2.imread(image,1)
img_orig=img.copy()
img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img=cv2.GaussianBlur(img,(21,21),cv2.BORDER_DEFAULT)
all_circs=cv2.HoughCircles(img, cv2.HOUGH_GRADIENT,1,500,param1=110,param2=35,minRadius=200,maxRadius=600)
all_circs_rounded=np.uint32(np.around(all_circs))
count = 1
for i in all_circs_rounded[0, :]:
cv2.circle(img_orig,(i[0],i[1],),i[2],(255,0,0),3)
cv2.circle(img_orig,(i[0],i[1],),2,(255,0,0),3)
cv2.putText(img_orig,"Coin"+str(count),(i[0]-70,i[1]+30),cv2.FONT_HERSHEY_SIMPLEX,1.1,(255,0,0),2)
count+=1
print (all_circs_rounded)
print (all_circs_rounded.shape)
print ('I have found ' + str(all_circs_rounded.shape[1]) + ' coins')
plt.rcParams["figure.figsize"]=(16,9)
plt.imshow(img_orig)
这个问题有几种可能的解决方案
您可以使用 image segmentation with watershed。这种方法的优点是能够在图像中找到接触的硬币,因为您可以轻松地将硬币彼此分开。此外,分水岭可以让你获得硬币的中心,在那里你可以做额外的处理。
继续使用Hough Circle Transform. The function returns various parameters such as the radius which you can use to find the circle's area. Here's a quick example to obtain the radius which you can use the find the area using the classic formula。这种方法也可以让你轻松获得圆心
# detect circles in the image
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1.2, 100)
# ensure at least some circles were found
if circles is not None:
# convert the (x, y) coordinates and radius of the circles to integers
circles = np.round(circles[0, :]).astype("int")
# loop over the (x, y) coordinates and radius of the circles
for (x, y, r) in circles:
# draw the circle in the output image, then draw a rectangle
# corresponding to the center of the circle
cv2.circle(output, (x, y), r, (0, 255, 0), 4)
cv2.rectangle(output, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)
# calculate area here
...
完全旋转并使用带过滤的轮廓检测。可能的步骤是
- 将图像转换为灰度
- 高斯模糊
- 执行canny edge detection or threshold获取二值图像
- 执行 morphological transformations 例如
cv2.dilate()
或cv2.erode()
- 使用
cv2.contourArea()
查找轮廓、过滤和查找区域
- 要找到硬币的中心,您可以使用image moments找到质心