2014-04-20 15 views
5

Ich bin neu bei OpenCV und habe ein paar Fragen. Ich muss eine Flasche oder eine Dose basierend auf ihrer Form erkennen. Dazu benutze ich ein Raspberry Pi Board und eine Pi Kamera. Der Hintergrund ist immer schwarz und ändert sich nicht. Ich habe viele mögliche Lösungen für dieses Problem versucht, konnte aber keine zufriedenstellenden Ergebnisse erzielen. Die Dinge, die ich versucht habe, sind Kantenerkennung, morphologische Transformationen, matchShapes(), matchTemplate(). Bitte lassen Sie mich wissen, ob ich diese Aufgabe effizient und mit höchster Genauigkeit erledigen kann.Erkennen einer Dose oder Flasche in opencv

Ein Beispielbild:

enter image description here

+0

So wird es kein Objekt in der Szene, außer der Flasche ?. – Haris

+0

Es wird zu einem bestimmten Zeitpunkt keinen anderen Gegenstand als eine Flasche oder eine Dose geben. – user3553000

+1

Wenden Sie dann [binäre Invertierungsschwelle] (http://docs.opencv.org/doc/tutorials/imgproc/threshold/threshold.html#threshold-binary-inverted) mit niedrigem Wert an, um den Vordergrund zu erhalten. – Haris

Antwort

3

ich mit einem Ansatz kam, die helfen können! Wenn Sie mehr über die Dose wissen, d. H. Das Verhältnis von Breite zu Höhe, kann sie robuster sein, indem Sie die Rechteckgröße anpassen!

Ansatz

  • Convert Bild HSV Farbraum. Erhöhen Sie V um einen Faktor von 2, um mehr sichtbare Dinge zu haben.
  • Finden Sobel Derivate in x und y Richtung. Berechnen Sie die Größe mit gleichem Gewicht für beide Richtungen.
  • Schwellwert Ihr Bild mit Otsu Methode.
  • Wenden Sie Closing auf Ihr Bild an.
  • Wenden Sie Canny Kantendetektor an.
  • Suchen Hough Line Transform.
  • Finden Sie Begrenzungsrechteck Ihres Linienbildes.
  • Superimpose es auf Ihrem Bild (Endlich fertig: P).

-Code

image = cv2.imread('image3.jpg', cv2.IMREAD_COLOR) 
original = np.copy(image) 
if image is None: 
    print 'Can not read/find the image.' 
    exit(-1) 

hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) 
H,S,V = hsv_image[:,:,0], hsv_image[:,:,1], hsv_image[:,:,2] 
V = V * 2 

hsv_image = cv2.merge([H,S,V]) 
image = cv2.cvtColor(hsv_image, cv2.COLOR_HSV2RGB) 
image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) 
# plt.figure(), plt.imshow(image) 

Dx = cv2.Sobel(image,cv2.CV_8UC1,1,0) 
Dy = cv2.Sobel(image,cv2.CV_8UC1,0,1) 
M = cv2.addWeighted(Dx, 1, Dy,1,0) 

# plt.subplot(1,3,1), plt.imshow(Dx, 'gray'), plt.title('Dx') 
# plt.subplot(1,3,2), plt.imshow(Dy, 'gray'), plt.title('Dy') 
# plt.subplot(1,3,3), plt.imshow(M, 'gray'), plt.title('Magnitude') 

ret, binary = cv2.threshold(M,10,255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) 
# plt.figure(), plt.imshow(binary, 'gray') 

binary = binary.astype(np.uint8) 
binary = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (20, 20))) 
edges = cv2.Canny(binary, 50, 100) 
# plt.figure(), plt.imshow(edges, 'gray') 

lines = cv2.HoughLinesP(edges,1,3.14/180,50,20,10)[0] 
output = np.zeros_like(M, dtype=np.uint8) 
for line in lines: 
    cv2.line(output,(line[0],line[1]), (line[2], line[3]), (100,200,50), thickness=2) 
# plt.figure(), plt.imshow(output, 'gray') 

points = np.array([np.transpose(np.where(output != 0))], dtype=np.float32) 
rect = cv2.boundingRect(points) 
cv2.rectangle(original,(rect[1],rect[0]), (rect[1]+rect[3], rect[0]+rect[2]),(255,255,255),thickness=2) 
original = cv2.cvtColor(original,cv2.COLOR_BGR2RGB) 
plt.figure(), plt.imshow(original,'gray') 


plt.show() 

HINWEIS: Sie können die Linien zu zeigen, das Ergebnis jeder Schritt Kommentar- können! Ich erwähne sie nur aus Gründen der Lesbarkeit.

Ergebnis

Result Image

HINWEIS: Wenn Sie das Seitenverhältnis Ihres wissen kann, man kann es beheben besser!

Ich hoffe, dass das helfen wird. Viel Glück :)

+1

Vielen Dank für Ihren Kommentar. Ich denke, ich kann das Seitenverhältnis einer Dose oder einer Flasche berechnen. Ich sollte die Höhe und Breite des Rechtecks ​​mit Standarddosengrößen vergleichen. – user3553000