Ich versuche, die Anzahl der Rohre in diesem Bild zu ermitteln. Dafür verwende ich OpenCV und Python-basierte Erkennung. Basierend auf vorhandenen Antworten auf ähnliche Fragen konnte ich die folgenden Schritte entwickeln
- Öffnen Sie das Bild
- Filtern Sie es
- Kantenerkennung anwenden
- Konturen verwenden
- Überprüfen Sie die Anzahl
Die Gesamtzahl der Pfeifen beträgt ~ 909, wenn wir sie manuell zählen. Geben oder Nehmen 4.
Nach dem Auftragen des Filters
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
Ich bekomme dieses maskierte Bild
Dies sieht in Bezug auf die Anzahl der angezeigten sichtbaren Rechtecke ziemlich genau aus. Wenn ich jedoch versuche, die Zählung vorzunehmen und den Begrenzungsrahmen über dem Bild zu zeichnen, werden auch viele unerwünschte Bereiche ausgewählt. Für Kreise hat HoughCircles eine Möglichkeit, den maximalen und minimalen Radius zu definieren. Gibt es etwas Ähnliches für Rechtecke, das die Genauigkeit verbessern kann? Ich bin auch offen für Vorschläge für alternative Ansätze für dieses Problem.
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)
UPDATE Basierend auf der zweiten Antwort habe ich den C ++ - Code in Python-Code konvertiert und habe genauere Ergebnisse erzielt, aber immer noch ein paar offensichtliche Rechtecke verpasst.