J'essaie de détecter le nombre de tuyaux dans cette image. Pour cela, j'utilise OpenCV et la détection basée sur Python. Sur la base des réponses existantes à des questions similaires, j'ai pu trouver les étapes suivantes
- Ouvrez l'image
- Filtrer
- Appliquer la détection des contours
- Utiliser les contours
- Vérifiez le nombre
Le nombre total de tuyaux est ~ 909 lorsque nous le comptons donner ou prendre manuellement 4.
Après avoir appliqué le filtre
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread('images/input-rectpipe-1.jpg')
blur_hor = cv2.filter2D(img[:, :, 0], cv2.CV_32F, kernel=np.ones((11,1,1), np.float32)/11.0, borderType=cv2.BORDER_CONSTANT)
blur_vert = cv2.filter2D(img[:, :, 0], cv2.CV_32F, kernel=np.ones((1,11,1), np.float32)/11.0, borderType=cv2.BORDER_CONSTANT)
mask = ((img[:,:,0]>blur_hor*1.2) | (img[:,:,0]>blur_vert*1.2)).astype(np.uint8)*255
Je reçois cette image masquée
Cela semble assez précis en termes de nombre de rectangles visibles qu'il montre. Cependant, lorsque j'essaie de prendre le compte et de tracer le cadre de sélection au-dessus de l'image, il sélectionne également de nombreuses régions indésirables. Pour les cercles, HoughCircles a un moyen de définir le rayon max et min. Existe-t-il quelque chose de similaire pour les rectangles qui peut améliorer la précision. En outre, je suis ouvert aux suggestions d'approches alternatives à ce problème.
ret,thresh = cv2.threshold(mask,127,255,0)
contours,hierarchy = cv2.findContours(thresh, 1, 2)
count = 0
for i in range(len(contours)):
count = count+1
x,y,w,h = cv2.boundingRect(contours[i])
rect = cv2.minAreaRect(contours[i])
area = cv2.contourArea(contours[i])
box = cv2.boxPoints(rect)
ratio = w/h
M = cv2.moments(contours[i])
if M["m00"] == 0.0:
cX = int(M["m10"] / 1 )
cY = int(M["m01"] / 1 )
if M["m00"] != 0.0:
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
if (area > 50 and area < 220 and hierarchy[0][i][2] < 0 and (ratio > .5 and ratio < 2)):
#cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
cv2.circle(img, (cX, cY), 1, (255, 255, 255), -1)
count = count + 1
print(count)
cv2.imshow("m",mask)
cv2.imshow("f",img)
cv2.waitKey(0)
MISE À JOUR Sur la base de la deuxième réponse, j'ai converti le code c ++ en code python et obtenu des résultats plus proches, mais il manque toujours quelques rectangles évidents.