我正在尝试检测这张图片中的某些圆圈:
这是我成功的最好结果:
您可以看到有4个圆圈检测到我没有检测到,有1个圆圈错过了。
这是我使用的代码:
def draw_circles(img, circles):
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
for i in circles[0,:]:
# draw the outer circle
cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2)
# draw the center of the circle
cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)
cv2.putText(cimg,str(i[0])+str(',')+str(i[1]), (i[0],i[1]), cv2.FONT_HERSHEY_SIMPLEX, 0.4, 255)
return cimg
def detect_circles(image_path):
gray = cv2.imread(image_path, 0)
gray_blur = cv2.medianBlur(gray, 13) # Remove noise before laplacian
gray_lap = cv2.Laplacian(gray_blur, cv2.CV_8UC1, ksize=5)
dilate_lap = cv2.dilate(gray_lap, (3, 3)) # Fill in gaps from blurring. This helps to detect circles with broken edges.
# Furture remove noise introduced by laplacian. This removes false pos in space between the two groups of circles.
lap_blur = cv2.bilateralFilter(dilate_lap, 5, 9, 9)
# Fix the resolution to 16. This helps it find more circles. Also, set distance between circles to 55 by measuring dist in image.
# Minimum radius and max radius are also set by examining the image.
circles = cv2.HoughCircles(lap_blur, cv2.HOUGH_GRADIENT, 16, 80, param2=450, minRadius=20, maxRadius=40)
cimg = draw_circles(gray, circles)
print("{} circles detected.".format(circles[0].shape[0]))
# There are some false positives left in the regions containing the numbers.
# They can be filtered out based on their y-coordinates if your images are aligned to a canonical axis.
# I'll leave that to you.
return cimg
plt.imshow(detect_circles('test.jpeg'))
我尝试过使用最小和最大半径参数,但是没有真正的成功,任何建议都会有所帮助。
答案 0 :(得分:3)
我不明白为什么您需要所有这些预处理。您的图片中有完美的圆,您知道它们的确切半径...
您要做的所有预处理就是将良好的输入转换为不良的输入。您删除了已有的漂亮圆圈轮廓,然后尝试将图像中值至死后从剩下的内容中重新创建它们:)
def detect_circles(image_path):
gray = cv2.imread(image_path, 0)
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 2, 60, param2=100, minRadius=20, maxRadius=40)
cimg = draw_circles(gray, circles)
print("{} circles detected.".format(circles[0].shape[0]))
return cimg
我认为您应该真正研究那些算法的工作方式。您的代码看起来像是盲目地应用了在网上找到的内容。
答案 1 :(得分:1)
也许此解决方案会有所帮助。
def draw_circles(img, circles):
cimg = img.copy()
for i in circles[0,:]:
# draw the outer circle
cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2)
# draw the center of the circle
cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)
cv2.putText(cimg,str(i[0])+str(',')+str(i[1]), (i[0],i[1]), cv2.FONT_HERSHEY_SIMPLEX, 0.4, 255)
return cimg
def detect_circles(image_path):
# open color image
image = cv2.imread(image_path)
image_blur = cv2.medianBlur(image, 3)
# find edges
edges = cv2.Canny(image_blur, 5, 50)
# let's clean the neighboring pixels
edges = cv2.medianBlur(edges, 3)
circles = cv2.HoughCircles(edges, cv2.HOUGH_GRADIENT, 2, 80, param1=100, param2=45, minRadius=20, maxRadius=40)
cimg = draw_circles(image, circles)
print("{} circles detected.".format(circles[0].shape[0]))
return cimg