Form-Erkennung in python mithilfe von OpenCV
Arbeite ich an einem Projekt, in dem ich Sie verwenden OpenCV, um zu erkennen, Formen und Ihre Farben.
Es gibt 5 Farben (rot, grün, gelb, blau und weiß) und in 4 Formen (Rechteck, Stern, Kreis und Herz). Ich habe in der Lage, zuverlässig zu erkennen, die Farben und ich kann erkennen, die Formen, wenn das verwendete Bild ist ein Bild gezeichnet wie diese
mit diesem code. Beachten Sie, das Bild ist nur zu Demonstrationszwecken, die range-Werte in meinem code sind nicht für diese Farben.
import cv2
import numpy as np
class Shape():
def __init__(self, color, shape, x, y, approx):
self.color = color
self.shape = shape
self.x = x
self.y = y
self.approx = approx
def closing(mask):
kernel = np.ones((7,7),np.uint8)
closing = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
return closing
def opening(mask):
kernel = np.ones((6,6),np.uint8)
opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
return opening
#Define Red
lower_red = np.array([0, 90, 60], dtype=np.uint8)
upper_red = np.array([10, 255, 255], dtype=np.uint8)
red = [lower_red, upper_red, 'red']
#Define Green
lower_green = np.array([60, 55, 0], dtype=np.uint8)
upper_green = np.array([100, 255, 120], dtype=np.uint8)
green = [lower_green, upper_green, 'green']
#Define Blue
lower_blue = np.array([90, 20, 60], dtype=np.uint8)
upper_blue = np.array([130, 255, 180], dtype=np.uint8)
blue = [lower_blue, upper_blue, 'blue']
#Define Yellow
lower_yellow = np.array([5, 110, 200], dtype=np.uint8)
upper_yellow = np.array([50, 255, 255], dtype=np.uint8)
yellow = [lower_yellow, upper_yellow, 'yellow']
#Define White
lower_white = np.array([0, 90, 60], dtype=np.uint8)
upper_white = np.array([10, 255, 255], dtype=np.uint8)
white = [lower_white, upper_white ,'white']
colors = [red, green, blue, yellow, white]
def detect_shapes(image_location):
#Open image
img = cv2.imread(image_location)
#Convert to hsv
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
#Shape list
shapes = []
#Lay over masks and detect shapes
for color in colors:
mask = cv2.inRange(hsv, color[0], color[1])
mask = closing(mask)
mask = opening(mask)
contours, h = cv2.findContours(mask, 1, cv2.CHAIN_APPROX_SIMPLE)
contours.sort(key = len)
for contour in contours[-3:]:
#Amount of edges
approx = cv2.approxPolyDP(contour, 0.01*cv2.arcLength(contour, True), True)
#Center locations
M = cv2.moments(contour)
if M['m00'] == 0.0:
continue
centroid_x = int(M['m10']/M['m00'])
centroid_y = int(M['m01']/M['m00'])
if len(approx) == 4:
shape_name = 'rectangle'
elif len(approx) == 10:
shape_name = 'star'
elif len(approx) >= 11:
shape_name = 'oval'
else:
shape_name ='undefined'
shape = Shape(color[2], shape_name, centroid_x, centroid_y, len(approx))
shapes.append(shape)
return shapes
Dies ist weitgehend auf der Grundlage der Antworten auf diese Frage.
Jedoch, wenn ich versuche zu erkennen, die Formen auf ein Aktuelles Foto ist, kann ich nicht zuverlässig nutzen. Die Menge der Kanten, die ich bekommen stark variiert. Diese ist ein Beispiel für ein Foto brauche ich, um zu erkennen die Formen auf.
Ich vermute, dies geschieht, weil der kleine Fehler an den Kanten der Formen, aber ich kann nicht herausfinden, wie ich den ungefähren diese Kanten mit geraden Linien, oder wie würde ich sicher erkennen-Kreisen. Was würde ich ändern muss im code, dies zu tun? Intensives googeln hat nicht mir eine Antwort noch nicht, aber das könnte sein, weil ich nicht die richtigen Begriffe in die Suche...
Auch, wenn diese Frage nicht korrekt formatiert ist, lassen Sie es mich wissen!
0.01
verwendet wird, bei der Berechnung approx
. Sie würde wahrscheinlich haben dann Probleme mit dem Kreis, Komponenten, jedoch, die vielleicht besser getrennt behandelt.Geben Sie einen Versuch auf Konvexe Hülle
Das funktioniert vielleicht für Kreise und Rechtecke, aber würde stars erkannt werden? Oder soll ich suchen für die Fünfecke dann?
Wenn Sie nicht über komplexe Formen können Sie mit approxPolyDP() wo man die 15 mehr-Punkt-Satz für Stern-Formen finden Sie in der Ergebnis ich habe hier grün erkannt wird, Formen.
Wow, das sieht wirklich gut aus. Könntest du erklären, was du getan hast? Konvexe Hülle die erste und dann approxPolyDP? Oder Canny? Ich habe gelesen darüber, aber konnte nicht herausfinden, ob es sinnvoll wäre für dieses problem.
InformationsquelleAutor Habba | 2014-02-25
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier ist der code, den ich gehen Sie mit Ihrem Bild, der code wird
Willkommen........
Könnten Sie erklären, ein bisschen mehr den fünften Schritt? Danke!
, Die Sie haben zu prüfen, wie viele Punkte gibt es innerhalb
contours_poly
was ist ein Vektor vom Typ cv::Point. contours_poly enthält Eckpunkte für jede Kontur. So dass Sie bestätigen können, ob Objekt ist star oder nicht.Dies ist in c++ Recht , ist der python-code um ? Einfach nur neugierig, ich schreib nicht c, ich kann es konvertieren python-trotzdem vielen Dank das ist großartig !
InformationsquelleAutor Haris