Objekterkennung mit OpenCV

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Malta
User
Beiträge: 83
Registriert: Samstag 8. Januar 2011, 23:51

Hallo, suche ein Programm mit GUI das mit Hilfe der OpenCV,
Objekte mit einer Webkamera erkennen und auswerten kann.

So ähnlich die dieses Projekt, das einen Laserstrahl analysieren kann.
https://github.com/ptomato/Beams
deets

Man merkt, dass du von dem Thema CV keine Ahnung hast. "Objekterkennung" gibt es nicht. Es gibt "erkenne rote Baelle von gruenem Hintergrund", oder sehr schoen auch "unterscheide Eichhoernchen von Voegeln (und beschiess sie mit Wasser)"

http://www.slideshare.net/kgrandis/pyco ... rel-hordes

Und so weiter. OpenCV ist ein Baukasten, und du musst wissen, was fure Bauteile fuer dein Problem helfen.

Und was heisst "mit GUI"? Ist die reiner Selbstzweck, oder hat die was bestimmtes zu leisten? Soll sie zB Katzenbilder darstellen, oder Shakespear-Zitate durch's Bild laufen lassen?
Malta
User
Beiträge: 83
Registriert: Samstag 8. Januar 2011, 23:51

Ich möchte von den Kamerabild drei Ecken erkennen und dann denn Winkel ausrechnen.
Hab mir das so vorgestellt das ich drei Suchfenster defenieren kann und die dann das Suchfenster in einer bestimmten Richtung durchsuchen und dann den ersten Punkt bei einem bestimmten Farbwert bzw. Grauwert festlegt,

Als Antwort möchte ich dann die drei Punkte bekommen mit dennen ich weiterrechnen kann.

Ich hab auch das Beispiel vom deinem Link Seite 10 ausprobiert, aber leider hat es nicht geklappt.
Edit: Habe den fehlerhaften Code gelöscht, Der richtige Code steht weiter unten.
Zuletzt geändert von Malta am Donnerstag 5. April 2012, 13:32, insgesamt 1-mal geändert.
BlackJack

@Malta: Was jetzt nicht wirklich überraschend ist…
deets

@Malta

BlackJack hat ja schon klargemacht, dass dein Fehler trivialst ist. Inhaltlich ist immer noch nicht klar, was du willst - wie waere es, wenn du mal ein Beispielbild zeigst, und wie so eine Analyse dann aussehen soll?
Malta
User
Beiträge: 83
Registriert: Samstag 8. Januar 2011, 23:51

Ich möchte das bei einem Bild den höchsten Punkte eines Übergänge erkannt wird,
Dabei möchte ich das Suchfenster und die Suchrichtung vorgeben.
Auf dem Bild die grünen Rechtecke und die Suchrichtung zu der offenen Seite hin.

Und möchte vorgeben ob schwarz/weiss oder weiss/schwarz Übergänge gesucht werden.
Als Rückgange möchte ich die Punkte bekommen,
P1= 75/250, P2 = 150/150, P3 = 200/150, P4 = 250/280

Bild
deets

Sind das deine echten Daten, bzw. ein echtes Bild? Ohne die bunten Teile natuerlich. Du redest ja von ner WebCam, die liefert solche Bilder wohl kaum...

Wenn ja, dann sehe ich da relative wenig Ram fuer die OpenCV. Klar, du kannst nen CannyEdge drueberlaufen lassen. Aber im Grunde kannst du da ja schon mit "haendischem" Code die Kante langlaufen. Und dann ist die Frage, was einen Punkt und die Suchrichtung ausmacht. So wie das aktuelle Bild aussieht, koennte da das Vorzeichen der Ableitung und der Betrag der Aenderung der Ableitung von Interesse sein. Fuer sowas gibt's hier bestimmt noch bessere Experten, die zB Poylgon-Fittings oder sowas kenne, das einem da hilft.
Malta
User
Beiträge: 83
Registriert: Samstag 8. Januar 2011, 23:51

Das ist kein Bild von der Webcam, das ist eine Skizze um das Problem zu verdeutlichen.

@deets: Ich habe deinen Post nicht verstanden. Wie soll das händisch absuchen funktionieren?

Vielleicht habe ich mein Problem nicht deutlich genug beschrieben, oder mein Problem zu hoch gesteckt.

Vielleicht vereinfacht gesagt, ich suche eine Funktion,
die den ersten Punkt an einem Übergang von weiss auf scharz herausfindet.
Noch zu vereinfachen, ich sagen das Suchfenster ist das ganze Bild (oben weiss unten schwarz) und ich taste zeilenweise das Bild von oben nach unten ab. Und der erste Punkt der schwarz ist ist mein Ergebniss.

Gibt es da eine Funktion, oder ein Beispiel?
deets

Seufz. Einfach gesagt, schwierig getan - ich hatte gehofft, das haette ich schon klar genug ausgedrueckt. Es gibt keine Funktion, die dein Problem loest. Du musst schon *GENAU* sagen, was du brauchst. Und selbst dann kann man dir im Zweifel nicht so einfach helfen, weil man viele Bilder braucht, um eine robuste Loesung zu finden. Was man aber ganz bestimmt nicht brauchen kann sind Skizzen, welche ein Problem abstrahieren.

Hast du dich ueberhaupt schonmal mit CV Themen beschaeftigt?
Malta
User
Beiträge: 83
Registriert: Samstag 8. Januar 2011, 23:51

Ich habe die Funktion bei der Industriellen Bildverarbeitung gesehen.
S. 44 Das Rechteckfeld und die Suchrichtung
und S. 143 Einlernen Punkte antasten
S. 44 http://books.google.de/books?id=BG7-m-Xr-H4C&pg=PA44
S. 143 http://books.google.de/books?id=BG7-m-Xr-H4C&pg=PA143

Und möchte die Funktion mit einer Webcam nachstellen.
deets

Ok, ich bin raus. Mit so wenig Input kann ich nichts machen.
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Naja. Du siehst ja schon, dass die Beispiele anhand von stark vereinfachter schwarz-weißer Bilder demonstriert wurden. Allein schon Webcam-Input derartig anzupassen, wird problematisch genug sein.
Malta
User
Beiträge: 83
Registriert: Samstag 8. Januar 2011, 23:51

Ich hab das mit den canny Filter hinbekommen.

Code: Alles auswählen

import cv
#quelle = cv.LoadImage("Images/pear.png")
quelle1 = cv.CaptureFromCAM(0)
#Größe der Kamerabilder ermitteln
size = (int(cv.GetCaptureProperty(quelle1, cv.CV_CAP_PROP_FRAME_WIDTH)),
        int(cv.GetCaptureProperty(quelle1, cv.CV_CAP_PROP_FRAME_HEIGHT)))
print size
quelle = cv. QueryFrame (quelle1)
grau = cv.CreateImage( size, cv.IPL_DEPTH_8U, 1 )
cv.CvtColor(quelle, grau, cv.CV_BGR2GRAY)
cannyImg = cv.CreateImage(size, cv.IPL_DEPTH_8U, 1)
cv.Canny(grau, cannyImg, 50, 150, 3)
canny2Img = cv.CreateImage(size, cv.IPL_DEPTH_8U, 1)
cv.Canny(grau, canny2Img, 5, 30, 3)
cv.NamedWindow("quelle", 1)
cv.NamedWindow("canny",1)
cv.ShowImage("quelle", quelle)
cv.ShowImage("canny", cannyImg)
cv.ShowImage("canny2", canny2Img)
cv.WaitKey(0)
cv.DestroyWindow("quelle")
cv.DestroyWindow("canny")
cv.DestroyWindow("canny2")
Das Bild:
Bild

Und ich möchte nun wissen welche Kordinaten die obere Spitze hat.
Oder habe ich mich zu sehr in OpenCV verrannt, vielleicht gibt es eine andere Möglichkeit,
das Bild Pixel für Pixel und Zeile für Zeile abzusuchen nach einem Grauwert und
dann wenn ich das erste Pixel gefunden habe das den Grauwert überschreitet,
das muss dann die Spitze sein und mein Ergebniss ist die Position des Pixels.
deets

Da kann man schon mit der OpenCV weitermachen. ZB mit hough-Lines, und basierend auf denen kann man dann versuchen einen Schnittpunkt zu finden.

http://opencv.itseez.com/doc/tutorials/ ... lines.html

Oder du versuchst aus dem Canny-Edge gefilterten Bild mittels Vectorization ein Polygon zu machen, und arbeitest darauf.
Malta
User
Beiträge: 83
Registriert: Samstag 8. Januar 2011, 23:51

Hab es mit den hough-Lines ausprobiert, und es klappt.

Aber das Ganze ist recht langsam.
Wie kann ich es optimieren? Oder den Suchbereich verkleinern?
deets

Tjoa, so Sachen halt. Bild verkleinern, wenn du den Suchbereich eingrenzen kannst natuerlich auch das.
Benutzeravatar
Dobi
User
Beiträge: 31
Registriert: Mittwoch 28. September 2011, 17:04

Also wenn du wirklich nur in dem von dir geposteten Canny-Bild den obersten nicht-schwarzen Pixel finden willst, probiers doch einfach mal so, wie du es schon selbst geschrieben hattest. Die aufwendige Hough-Transformation ist erst nötig wenn du noch andere Informationen brauchst.

Code: Alles auswählen

def find_uppermost_white_pixel(image):
    for y in range(0, image.height):
        for x in range(0, image.width):
            if cv.Get2D(image, y, x)[0] > 0:
                return (x,y)
    return (-1,-1)
Malta
User
Beiträge: 83
Registriert: Samstag 8. Januar 2011, 23:51

Ja genau nach sowas hab ich gesucht.
Benutzeravatar
Dobi
User
Beiträge: 31
Registriert: Mittwoch 28. September 2011, 17:04

Wenn das noch zu langsam ist, und du keine Lust hast, dafür extra irgendwas in C++ zu schreiben und einzubinden, kannst du übrigens auch testen, ob es flotter geht, wenn du dir mit cv.FindContours die Punkte der Randkurve geben lässt, und dir dann von diesen den mit dem kleinsten Y-Wert nimmst.
Antworten