2016-05-03 26 views
3

Ich benutze die OpenCV-Bibliothek für Python, um die Kreise in einem Bild zu erkennen. Als Testfall bin ich mit dem folgenden Bild:Überlappende Kreise in OpenCV erkennen

Boden des Bechers:

enter image description here

ich den folgenden Code geschrieben haben, die das Bild vor der Erfassung angezeigt werden sollen, dann das Bild anzeigen mit den erfassten Kreisen hinzugefügt:

import cv2 
import numpy as np 

image = cv2.imread('can.png') 
image_rgb = image.copy() 
image_copy = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) 
grayscaled_image = cv2.cvtColor(image_copy, cv2.COLOR_GRAY2BGR) 

cv2.imshow("confirm", grayscaled_image) 
cv2.waitKey(0) 

cv2.destroyAllWindows() 


circles = cv2.HoughCircles(image_copy, cv2.HOUGH_GRADIENT, 1.3, 20, param1=60, param2=33, minRadius=10,maxRadius=28) 


if circles is not None: 
    print("FOUND CIRCLES") 
    circles = np.round(circles[0, :]).astype("int") 
    print(circles) 
    for (x, y, r) in circles: 
     cv2.circle(image, (x, y), r, (255, 0, 0), 4) 
     cv2.rectangle(image, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1) 
    cv2.imshow("Test", image + image_rgb) 
    cv2.waitKey(0) 

cv2.destroyAllWindows() 

bekomme ich diese: resultierende Bild

enter image description hereIch glaube, dass mein Problem in der Verwendung der HoughCircles() Funktion liegt Es ist Nutzung ist:

cv2.HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]])

wo minDist ein Wert größer als 0 ist, die Kreise erfasst erfordert voneinander in einem bestimmten Abstand zu sein. Mit dieser Anforderung wäre es für mich unmöglich, alle Kreise auf dem Boden der Dose richtig zu erkennen, da sich die Mitte jedes Kreises an der gleichen Stelle befindet. Wären Konturen eine Lösung? Wie kann ich Konturen in Kreise umwandeln, damit ich die Koordinaten ihrer Mittelpunkte verwenden kann? Was muss ich tun, um die Kreisobjekte für jeden Ring am Boden der Dose am besten zu erkennen?

+0

nicht Teil des Problems, sondern auch für die Zukunft: 'image_copy = cv2.cvtColor (Bild, cv2.COLOR_RGB2GRAY) 'sollte' image_copy = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) 'stattdessen ich denke). – Micka

Antwort

1

Nicht alle, aber eine Mehrheit der Kreise können das Bild durch adaptive Schwellwertbildung erfasst werden, um die Konturen zu finden und dann einen minimalen umschließenden Kreis für Konturen Einpassen Fläche größer als ein Schwellenwert

import cv2 
import numpy as np 

block_size,constant_c ,min_cnt_area = 9,1,400 
img = cv2.imread('viMmP.png') 
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 
thresh = cv2.adaptiveThreshold(img_gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,block_size,constant_c) 
thresh_copy = thresh.copy() 
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) 
for cnt in contours: 
    if cv2.contourArea(cnt)>min_cnt_area: 
     (x,y),radius = cv2.minEnclosingCircle(cnt) 
     center = (int(x),int(y)) 
     radius = int(radius) 
     cv2.circle(img,center,radius,(255,0,0),1) 
cv2.imshow("Thresholded Image",thresh_copy) 
cv2.imshow("Image with circles",img) 
cv2.waitKey(0) 

nun dieses Skript Ausbeuten das Ergebnis:

enter image description here

enter image description here

Aber ther e sind bestimmte Abwägungen wie, wenn die block_size und constant_c-11 bzw. 2 dann die Skript Ausbeuten geändert werden:

enter image description here

enter image description here

sollten Sie versuchen, mit einem Kern richtige Form der Anwendung Erosion die überlappenden Kreise in dem schwellen Bild zu trennen

Sie unter den folgenden Links sehen können mehr über adaptive Schwellwertbildung und Konturen zu verstehen:

Threshlding Beispiele: http://docs.opencv.org/3.1.0/d7/d4d/tutorial_py_thresholding.html

Thresholding Referenz: http://docs.opencv.org/2.4/modules/imgproc/doc/miscellaneous_transformations.html

Contour Beispiele: http://docs.opencv.org/3.1.0/dd/d49/tutorial_py_contour_features.html

+0

Wenn ich also die genaue Größe jedes Rings nicht genau erkennen kann, gibt es eine Möglichkeit, das Bild als Ganzes zu erkennen? Sag mal, wenn ich meine Webcam benutze und ein Bild von der Dose hochhebe, würde das Programm genau dieses Bild erkennen? – user5705019

+0

Ja, Sie können das Bild in HSV konvertieren und dann das Bild mit einem geeigneten Schwellenwert schwellen. Wenden Sie den Schließvorgang (Erosion + Dilatation) auf das mit einem Schwellenwert versehene Bild an, um die unerwünschten Hintergrundgeräusche verursachenden Komponenten zu entfernen. Suchen Sie dann die äußeren Konturen dieser Maske mit RETR_EXTERNAL. Wenn im Bild keine störenden Komponenten vorhanden sind, erhalten Sie den äußeren Kreis. Auch hier können Sie den Konturbereich verwenden, um alle störenden Komponenten zu entfernen. Wenn Sie die Dose in einem schwarzen Hintergrund dann bitweise und die Maske erhalten möchten, nachdem Sie mit dem ursprünglichen BGR-Bild geschlossen haben. –

+0

Ich schätze die Antwort sehr, aber ich habe keine Ahnung, wie ich das machen soll. Ich bin neu bei OpenCV und ich kann keinen Qualitätsleitfaden finden, wie man es benutzt. Würden Sie irgendetwas empfehlen? Wie hast du es gelernt? – user5705019