Red-eye detection



  • evtl. kannst du zuerst die Suche einschränken indem du einfach sämtliche Bereiche nicht mit berechnest, die nicht rot sind (beispielsweise g+b >= r)


  • Mod

    man braucht keine 3k*2k um redeyes zu finden, da kannst du es auch runterskalieren und suchen, am ende musst du nur beim 3k*2k einen etwas groesseren kreis machen und dort alles rote entfernen, bei ca 512*384 muesste das ausreichend gut sein.

    esseiden du photographierst menschenmengen bei dunkelheit und willst dafuer redeyes entfernen *hehe*

    btw. die idee mit dem hautdetektor ist suboptimal, du hast nun schon probleme ein markantes rot zu finden, wie willst du von weiss bis schwarz die haut von anderen gegenstaenden unterscheiden 😕 .



  • Ich habe die Bilder auch mal runter skaliert gehabt, aber dann wurde die Maske einfach nicht mehr so schön: Entweder waren die Pupillen zu wenig korrigiert und ein roter Rand blieb übrig oder die Haut drumherum wurde mit korrigiert... die Lösung fand ich damals nicht so zufriedenstellend.
    Vielleicht gehe ich das alles aber auch falsch an, im Moment laufe ich ein Bild folgendermaßen durch:

    1. Einlesen
    2. lowpass filter drüberlaufen lassen
    3. Bild Pixel für Pixel scannen ob Farbwert Roter-Augen-Kandidat -> Maske
    4. Die Maske durchlaufen und mittels "connected components labeling" zusammenhängende Flächen finden, Bereiche < Schwellwert fliegen raus -> Maske aktualisieren
    5. Bild kopieren und Grünkanal über Rotkanal kopieren
    6. Kopie des Bildes mit der erstellten Maske über das Original legen

    Vielleicht kennt ihr ja effektivere Wege, eine so große Datenmenge zu scannen?



  • DocJunioR schrieb:

    Dann gehst du dein Bild pixelweise durch und schaust, ob sich an entsprechender Stelle ein Randpixel befindet (du brauchst also ein Binärbild- der Sobelfilter ist ganz gut). Hier errechnest du alle möglichen Kreise, von denen dies ein Randpixel sein kann und trägst diese in den hough space ein.

    Hmm wenn ich die Maske wie oben gezeigt binär vorliegen habe (also ohne Sobel-Filter), kann ich dann auch mit dem Hough arbeiten?



  • Könnte man nicht eventuell die Flächen rausfiltern indem man prüft, ob zu angrenzenden pixeln ein entsprechend hoher kontrast besteht? rote augen werden ja immer durch einen deutlich dunkleren rand begrenzt.



  • Und was ist dann mit sagen wir roten Vierecken, die auf einem schwarzen Hintergrund sind? Das wäre dann eine rote Fläche mit dunklem Rand... also Skin-Detection und Ellipse-Detection muss schon sein, aber ist leider auch alles so lahm...



  • Hmm ich bekomme immer einen Segmentation-Fault wenn ich ein großes Array anlegen will.
    Beispiel: Ich möchte ein Array anlegen, das so groß wie mein Bild ist. Sagen wir ich öffne ein 3008x2272 Bild, dann bekomme ich beim Starten des Programms immer einen SegFault.

    float test[3008][2272]
    

    Kann ich denn nicht einfach so einen Array erzeugen? Irgendwie muss ich doch auch die ganzen Werte für einen Hough-Raum in so was Großem abspeichern, das sollte doch möglich sein?


  • Mod

    soviel auf dem stack ist nicht moeglich, der beste workaround ist entweder std::vector oder float* test=new float[3008*2272];



  • TheGrudge schrieb:

    Und was ist dann mit sagen wir roten Vierecken, die auf einem schwarzen Hintergrund sind? Das wäre dann eine rote Fläche mit dunklem Rand... also Skin-Detection und Ellipse-Detection muss schon sein, aber ist leider auch alles so lahm...

    Haut sollte sich eigentlich recht gut und einfach über die Farbe im HSI-Farbraum erkennen lassen. Brauchst Du wirklich Ellipsenerkennung? Vielleicht funktionieren auch Kreise? -- Dann könntest Du es mal mit ner schnelleren (aber ungenaueren) Version von Houghtransformation versuchen: FSR (fast radial symmetry). Mußt halt schaun, wie die Qualität davon wird.



  • Mein Problem ist generell das ich ein wenig zu doof zum programmieren bin, ich mache das leider viel zu wenig und weiß nie wie ich an sowas ran gehen soll. Ich habe schon so oft versucht den Hough umzusetzen und nun gerade den Canny-Edge-Detector, aber irgendwie klappt das alles nie so gut und schön programmiert ist es auch nicht.
    Ich dachte Ellipse weil manchmal sind die Augen halb geschlossen und dann ist es eher eine Ellipse als ein Kreis.



  • Benutz doch OpenCV, da ist Hough schon fertig implementiert. 🙂
    Generell kann ich nur empfehlen soviel fertige Software wie möglich einzusetzen, um mehr experimentieren zu können. Wenn Du dann ein funktionierendes System hast kannste immer noch überlegen, ob es sinnvoll ist einiges davon doch noch selbst zu schreiben um es zu optimieren oder an spezielle Bedürfnisse anzupassen.



  • Hmm jetzt habe ich mich schon so in CImg eingearbeitet... naja mal sehen...



  • OK ich bekomme OpenCV nicht kompiliert, immer der selbe Error:

    cvcap_ffmpeg.cpp:248: error: integer constant is too large for 'long' type
    cvcap_ffmpeg.cpp:252: error: integer constant is too large for 'long' type
    cvcap_ffmpeg.cpp:256: error: integer constant is too large for 'long' type
    cvcap_ffmpeg.cpp:256: error: integer constant is too large for 'long' type
    In file included from cvcap_ffmpeg.cpp:46:
    /usr/include/ffmpeg/avformat.h: In function 'void av_init_packet(AVPacket*)':
    /usr/include/ffmpeg/avformat.h:66: error: 'INT64_C' was not declared in this scope
    cvcap_ffmpeg.cpp: In function 'int icvOpenAVI_FFMPEG(CvCaptureAVI_FFMPEG*, const char*)':
    cvcap_ffmpeg.cpp:121: warning: comparison between signed and unsigned integer expressions
    cvcap_ffmpeg.cpp: In function 'const IplImage* icvRetrieveFrameAVI_FFMPEG(CvCaptureAVI_FFMPEG*)':
    cvcap_ffmpeg.cpp:218: warning: 'img_convert' is deprecated (declared at /usr/include/ffmpeg/avcodec.h:2636)
    cvcap_ffmpeg.cpp:222: warning: 'img_convert' is deprecated (declared at /usr/include/ffmpeg/avcodec.h:2636)
    cvcap_ffmpeg.cpp: In function 'double icvGetPropertyAVI_FFMPEG(CvCaptureAVI_FFMPEG*, int)':
    cvcap_ffmpeg.cpp:248: error: 'INT64_C' was not declared in this scope
    cvcap_ffmpeg.cpp:252: error: 'INT64_C' was not declared in this scope
    cvcap_ffmpeg.cpp:256: error: 'INT64_C' was not declared in this scope
    cvcap_ffmpeg.cpp: In function 'CvCapture* cvCaptureFromFile_FFMPEG(const char*)':
    cvcap_ffmpeg.cpp:359: warning: dereferencing type-punned pointer will break strict-aliasing rules
    cvcap_ffmpeg.cpp: In function 'int cvWriteFrame(CvVideoWriter*, const IplImage*)':
    cvcap_ffmpeg.cpp:716: warning: 'img_convert' is deprecated (declared at /usr/include/ffmpeg/avcodec.h:2636)
    cvcap_ffmpeg.cpp:718: warning: 'img_convert' is deprecated (declared at /usr/include/ffmpeg/avcodec.h:2636)
    cvcap_ffmpeg.cpp: In function 'void cvReleaseVideoWriter(CvVideoWriter**)':
    cvcap_ffmpeg.cpp:777: warning: comparison between signed and unsigned integer expressions
    make[3]: *** [cvcap_ffmpeg.lo] Error 1
    make[3]: Leaving directory /var/abs/local/opencv/src/opencv-1.0.0/otherlibs/highgui' make[2]: *** [all-recursive] Error 1 make[2]: Leaving directory/var/abs/local/opencv/src/opencv-1.0.0/otherlibs'
    make[1]: *** [all-recursive] Error 1
    make[1]: Leaving directory `/var/abs/local/opencv/src/opencv-1.0.0'
    make: *** [all] Error 2
    ==> ERROR: Build Failed. Aborting...

    Anscheinend wird da irgendwas mit 64bit-Unterstützung kompiliert?



  • OK ich habe einfach mal die Unterstützung für ffmpeg abgeschaltet, das brauche ich hoffentlich eh nicht.



  • Ich komme einfach nicht weiter über Hough und Edge Detection.
    Ich nutze im Moment OpenCV und dachte mir nun, ich baue mir ein eigenes Testset für HaarDetection auf.
    Denn die eingebaute Facedetection funktioniert leider immer nur, wenn das Gesicht nicht von der Seite zu sehen ist, in meinem Fall brauche ich aber wirklich zuverlässige Erkennung. Also dachte ich mir ich baue eine Datenbank aus Augen auf, von vorne, schräg, von der Seite usw. Nur bin ich mir noch nicht ganz darüber klar, welche Referenzen ich nehmen soll.
    Rote Augen als positive Templates und normale als negative oder einfach nur Augen als positive Templates und alles andere (Bäume, Landschaften usw) als negative Templates?
    Was meint ihr? Gleich auf rote Augen trainieren oder nur Augen und dann mit einer anderen Funktion gucken, ob die Pupille rot ist?



  • Für sowas gibt's keine allgemeingültige Regel. Da mußt Du einfach ausprobieren was besser funktioniert.



  • Ist es sinnvoller Bilder mit Augen so zu zuschneiden, das nur das Gesicht darauf ist oder macht das keinen Unterschied? Wie bekomme ich am Besten die Bounding-Boxes? Muss ich jedes mal ein Bildbearbeitungsprogramm aufrufen, um die Koordinaten zu finden? Das wird ja eine sch***s Arbeit 😃 Habe bis jetzt 2800 Bilder mit Gesichtern und 1000 normale Hintergründe.



  • Um so kleiner Deine Bilder sind, umso schneller kannst Du Sachen testen... andererseits sind auf den Bildern vielleicht noch andere Dinge drauf, die eben nicht erkannt werden sollen. Wenn Du die abschneidest kannst du schlecht kontrollieren, ob dein algorithmus die vielleicht fälschlicherweise erkennt.

    Was dieses Koordinaten-Zeug angeht: Schreib Dir dafür doch ein kleines Tool, mit dem man in Bildern Rechtecke markieren kann. Die legst Du für Bild.jpg einfach in Bild.txt ab. Dann noch nen Weiter- und nen Zurückknopf mit dem Du durch die Bilder im aktuellen Verzeichnis durchschalten kannst und schon kannst Du wesentlich effizienter arbeiten. Klar, 1000 Bilder anschaun ist schon aufwendig. Aber ein paar Daten sollte man schon haben. Mach halt immer mal 100 oder so.



  • Für Windows scheint es das Tool objectmarker zu geben, aber ich nutze Linux und da ist es im OpenCV-Paket nicht dabei, damn. Naja mal schauen.
    Macht es Sinn die Bilder zu skalieren oder kann es dann sein das er anders lernt als wenn ich alle Bilder auf 3008x2000px lasse?



  • Das kommt auf's verfahren an. Benutzt Du immer noch template-matching? Da kommt es auf die Größe wohl nicht zu sehr an. Und template-matching ist für große Bilder extrem langsam. Insofern sind kleine Bilder da nicht schlecht. Andererseits schadet es nicht die großen Bilder zu labeln. Das Labeling der kleinen Bilder lässt sich daraus ja berechnen. Allerdings scheint mir 3000x2000px doch sehr übertrieben. 640x480 sollte eigentlich auch noch locker reichen, wenn die Objekte die Du erkennen willst nicht gerade sehr klein sind.


Anmelden zum Antworten