Il vous faudra beaucoup de temps pour résoudre ceci si vous essayez de faire varier les paramètres sans comprendre ce qu'ils font.
Cette description est de here
minDist: Minimum distance between the center (x, y) coordinates of detected circles. If the minDist is too small, multiple circles in the same neighborhood as the original may be (falsely) detected. If the minDist is too large, then some circles may not be detected at all.
param1: Gradient value used to handle edge detection in the Yuen et al. method.
param2: Accumulator threshold value for the cv2.HOUGH_GRADIENT method. The smaller the threshold is, the more circles will be detected (including false circles). The larger the threshold is, the more circles will potentially be returned.
minRadius: Minimum size of the radius (in pixels).
maxRadius: Maximum size of the radius (in pixels).
Vous pouvez clairement voir que les cercles dans l'image ont un rayon fixe et ont min distance qui les sépare. Si vous définissez ces deux, vous pouvez améliorer vos résultats. Il est donc important de lire les documents.
Et à propos de votre problème, Si vous avez besoin d'utiliser spécifiquement Houghcircles allez-y et affinez-le. Les choses que vous pourriez faire pour améliorer sont, pré-traiter en utilisant gaussianblur, utilisez adaptivethreshold au lieu de simplement le seuil.
S'il n'est pas nécessaire d'utiliser des cercles Hough, je vous suggère plutôt d'utiliser des contours. Parce qu'il est plus robuste et généralise bien aux différentes images. Voici les résultats que j'ai obtenus en utilisant des contours. Les cercles apparaissent plus petits parce que j'ai utilisé l'érosion pour 6 itérations et la dilatation seulement pour 3 itérations.
Voici le code je.
import numpy as np
import cv2
image_color= cv2.imread("Ye3gs.png")
image_ori = cv2.cvtColor(image_color,cv2.COLOR_BGR2GRAY)
lower_bound = np.array([0,0,10])
upper_bound = np.array([255,255,195])
image = image_color
mask = cv2.inRange(image_color, lower_bound, upper_bound)
# mask = cv2.adaptiveThreshold(image_ori,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
# cv2.THRESH_BINARY_INV,33,2)
kernel = np.ones((3, 3), np.uint8)
#Use erosion and dilation combination to eliminate false positives.
#In this case the text Q0X could be identified as circles but it is not.
mask = cv2.erode(mask, kernel, iterations=6)
mask = cv2.dilate(mask, kernel, iterations=3)
closing = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
contours = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)[0]
contours.sort(key=lambda x:cv2.boundingRect(x)[0])
array = []
ii = 1
print len(contours)
for c in contours:
(x,y),r = cv2.minEnclosingCircle(c)
center = (int(x),int(y))
r = int(r)
if r >= 6 and r<=10:
cv2.circle(image,center,r,(0,255,0),2)
array.append(center)
cv2.imshow("preprocessed", image_color)
cv2.waitKey(0)
Hope this helps :)
Merci d'aider, mais il me donne une erreur: 'contours.sort (key = lambda x: cv2.boundingRect (x) [0]) TypeError: ' clé » est un argument de mot-clé non valide pour cette fonction ' –
Merci beaucoup, il a travaillé pour moi quand j'ai ajouté cette fonction 'def get_contour_precedence (contour, CLO): tolerance_factor = 10 origine = cv2.boundingRect (contour) retour ((origine [1] // tolerance_factor) * tolerance_factor) * cols + origine [0] ' –
Je suggère d'utiliser les contours + minEnclosingC fonction de cercle, puis comparez la limite/surface du cercle avec le contour détecté pour filtrer les contours non circulaires – Micka