Bilderkennung



  • Hallo,
    mein Informatik LK Lehrer hat heute verschiedene Themen für die Facharbeit angesprochen.
    Dabei vielen z.B. die Stichworte Muster- und Bilderkennung.
    Da ich mich damit aber noch nie beschäftigt habe wäre ich ganz dankbar wenn da mal jemand nen Paar Gedanken im Bezug auf Komplexität, Schwierigkeit etc. ablassen könnte.

    In einem anderen Thread habe ich gelesen:

    "Kleine Tipp das mit der Lego-Cam ist schon und gut aber zei probleme. Rechner ist umt usb Kamara sehr ausgelasste d.h. der Process brauch viel rechen zeit zur bedieng des usb ports. Zweitens sie sind sehr langsam. ich hoffe ich habe dir weiter geholfen."

    Also spontan hatte ich eigentlich genau vor die Bilder einer usb (web) cam zu nehmen.Ist das Ratsam oder doch eher nicht so?

    Außerdem wäre ich für jeden Link dankbar auf dem das Thema etwas näher erläutert wird und auch evtl. Beispiele genannt werden.

    Aso und last but sicher nicht least:
    Geht das Ganze überhaupt mit Java oder muss ich das Projekt schon mit c++ angehen?

    Vielen Dank
    Romeo



  • Sag mal genauer, was du vorhast. "Bilderkennung" ist erstmal ein sehr weiter Begriff, da variiert die Komplexität etc. von "recht leicht" bis "extrem schwer"



  • Dass du das Projekt in Java machen möchtest rechnen wir dir hier hoch an allerdings für die Basics - also bis zum Zeitpunkt der tatsächlichen Implementation - bist du wahrscheinlich in "Rund um die Programmierung" besser aufgehoben, oder?

    Aus diesem Grund verschiebe ich dich vorerst mal dorthin. Sobald es an das eingemachte mit Java geht sind deine Fragen hier jederzeit willkommen! 🙂



  • Hi,

    ich habe auch mal eine Bilderkennung geschrieben. Ich habe das so angepackt:
    Lies einfache die einzelnen RGB Werte eines BMP´s ein und entscheide dann mit einem Algowelche Farbe dominiert. Formen erkennst du vielleicht daran, wenn du jeden stärkeren Farbübergang als Linie definierst. Ich weis nicht ob das Ganze in Java zu machen ist aber so ne Bilderkennung braucht halt ziemlich viel Rechenpower.
    Ich hoffe ich habe dir nichts gesagt was du nicht eh schon weist.

    Erni



  • Was genau möchtest du denn erkennen?
    Ich habe mal an einem Fingerprint System gearbeitet.
    Die 2 Möglichkeiten haben am besten abgeschnitten:
    - Vectorisieren, der Hervorstechenden Informationen, dann vergleichen. Eine Prozentzahl gibt die Hemschwelle zwischen ok und false an
    - Oder per Genetischen System einen Algo berechnen lassen



  • Das ist doch ein tolles anwendungsgebiet für neurale Netze. Vor kurzem hatten wir hier einen Thread zu diesem Thema.



  • Also ich denke mal, dass sich diese Geschichte leichter per C++ realisieren lässt, auch wenn ihr zu diesem Thema noch nicht wirklich Bezug genommen habt.

    Was ich genau damit vor habe kann ich nicht sagen,weil ich es auch noch nicht genau weiss. Ein interessantes Thema wäre ein Prog, das die Augenzahl auf einem Würfel zählen kann.

    Mich würde auch mal wirklich ne Realisierung interessieren.
    Wie ließt man beispielsweise die RGB-Werte aus?
    Wie kann ich jedes Bild der Cam in ein BMP umwandeln?
    Was für ne Cam habt ihr benutzt?

    Sowas in der rRichtung würde mich mal interessieren.

    Danke und Bye
    Romeo



  • Ich empfehle dir, vorerst ohne Kamera zu arbeiten, sondern nur mit einzelnen Bildern. Kamera heißt für mich, dass das Ganze mehr oder weniger in Echtzeit ablaufen soll. Das ist eine zusätzliche Schwierigkeit, die du am Schluss immernoch einbauen kannst, falls du dann der Meinung bist, dass dein Algorithmus schnell genug dafür arbeitet.

    Die Augenzahl eines Würfels zählen sollte eigentlich machbar sein. Das hört sich auch für eine Facharbeit angemessen an.



  • Verzichte erst auf die Cam. Mache ein paar Snapshots, konvertiere diese, und vergleiche. Wenn die Resultate stimmen mit einer geringen Fehlerquote, dann kannst du ja einen schritt weiter gehen.
    Wenn das klappt, kannst du Cam support immer noch einbauen



  • Na dann mal Butter bei die Fische.

    Habe mir nen paar Texte zur Theorie durchgelsen, wie man z.B. aus dem Startbild durch Logik ein reines Konturenbild erzeugen kann aber wie sieht es in der Praxis aus?

    Wüsste schon wie man so einiges machen könnte aber mir fehlt ein entscheidender Baustein.
    Wie lese ich die RGB-Werte aus einem bestimmten BMP aus?

    Das dürfte mich schon nen großen Schritt weiter bringen.
    Danke

    Romeo



  • Öhm - unter welchem OS arbeitest du?

    Du könntest die BMP selbst laden - siehe hier: http://www.c-plusplus.net/forum/viewtopic.php?p=339246#339246

    Wenn die Daten erstmal RAW im Speicher sind, kannst du sie ohne Probleme auslesen. Wenn ich mich recht entsinne war BMP im BGR modus geschrieben. Das wirst du aber schnell feststellen, wenn die Farben nicht stimmen 😉

    Somit sind die Daten immer

    8Bit B | 8Bit G | 8Bit R | ... usw.

    Hope this helps



  • Hallo Romeo-G,

    ich beschäftige mich auf Arbeit sehr viel mit Bilderkennung und Verarbeitung im industriellen Bereich. Im Normalfall wird so ein Bild in ein Graustufenbild umgewandelt und dann erst weiterverarbeitet. Es sei den man will zum Bsp. die Augenfarbe erkennen 😃 .

    In deinem Fall (Augenzahl der Würfel) wäre folgendes vorgehen zu empfehlen und programmiertechnisch auch total leicht umzusetzen (auch mit Java).

    1. Umwandlung des Bildes in ein Grauwertbild

    2. Erstellung eines Grauwerthistogrammes aus dem Bild

    3. Bestimmen einer Binärschwelle (unterteilt die Bildbereiche in logisch hell und logisch dunkel) anhand des Histogrammes

    4. erstellen eines Binärbildes aus dem Grauwertbild und der Binärschwelle. (dannach hast du ein schwarz/weis Bild mit den Augen)

    5. Suche nach Objekten Anhand des Binärbildes und diese zählen.

    Gruss Bigwill



  • Bei dem Vorschlag von Bigwill solltest du aber sehr auf die Lichtverhältnisse beim Aufnehmen des Würfels achten (keine Reflektionen, gleichmäßige Ausleuchtung,...). Wenn du darauf nicht achten willst, dann wird es so einfach vermutlich nur in wenigen Fällen funktionieren.



  • Stabile Lichtverhältnisse brauch man eigentlich immer um aus einem Bild Informationen extrahieren zu können (das is nun mal das A & O bei der Sache), deswegen hatte ich das wohl vergessen zu erwähnen.
    Aber ich glaube ohne diese wirst du bei einer anderen Methode eben auch nicht glücklich.



  • Na das ist dochmal ein Ansatz.
    Nur leider gehts dadurch noch nicht wirklich weite.
    Da ich euch aber auch nicht endlos nerven will bitte ich euch mir zu sagen ob es irgendwo auch dazu Tuts gibt.

    Denn in diesem Bereich habe ich noch gar keine Ahung.
    Wie soll ich nen Bild in Graustufen umwandeln?
    Und kann mir nicht mal jemand nen Code geben mit dem ich das Pic in den RAW laden kann ?
    Und wie sieht der RAW aus? Sieht das wie ein Array aus wo dann immer xy Koordinate und Grauwert zusammen stehen ?
    Oder wie soll ich mir das vorstellen ?

    Danke nochmals



  • Bigwill schrieb:

    Stabile Lichtverhältnisse brauch man eigentlich immer um aus einem Bild Informationen extrahieren zu können (das is nun mal das A & O bei der Sache), deswegen hatte ich das wohl vergessen zu erwähnen.
    Aber ich glaube ohne diese wirst du bei einer anderen Methode eben auch nicht glücklich.

    Naja, man kann da schon etwas machen. "adaptive histogram equalization" ist hier das Stichwort. Das dauert aber sehr lange, da kann man die Cam also in jedem Fall vergessen. Sicherlich gibt es auch noch andere Dinge, die man gegen nicht sehr gute Lichtverhältnisse machen kann.



  • Romeo-G schrieb:

    Da ich euch aber auch nicht endlos nerven will bitte ich euch mir zu sagen ob es irgendwo auch dazu Tuts gibt.

    Ich kann dir da nur 2 Bücher nennen. Beide setzen eine Menge mathematisches Vorwissen voraus und haben IMHO ein recht hohes Niveau.

    1. "Digitale Bildverarbeitung" von Bernd Jähne (Springer)

    2. "Image Processing, Analysis, and Machine Vision" von Milan Sonka, Vaclav Hlavac und Roger Boyle (PWS)

    Das 2. Buch ist eigentlich verständlicher geschrieben, dafür ist es in Englisch, extrem teuer und nur über Import zu bekommen.



  • Also RAW ist einfach ein 1D Array oder 2D. Wobei ich 1D bevorzuge.

    Raw kannst du dir simpel vorstellen:

    01 . . . . 5 . . . . 10
    11. . . . 15. . . . 20
    .
    .
    41
    .
    

    Jeder Zahl sind bei RGB 3 * 8 Bits bzw. 3 * 1 Byte zugeordnet für R G und B.

    Eine einfache Möglichkeit, ein Graustufenbild zu erzeugen ist einfach. Ist aber nur als Ansatz gedacht. Zu Artikeln usw. müßtest du selbst mal suchen. Ich lege das ganze mal auf 256 Farben BW aus.

    unsigned char sw = 0;
    
    sw = r[pos] / 3 + g[pos] / 3 + b[pos] / 3;
    


  • Also, ich persönl. arbeite mit dem Borland C++Builder und log. dann auch C++.

    http://www.c-plusplus.net/forum/viewtopic.php?t=11093&start=0&postdays=0&postorder=asc&highlight=graustufen Da steht was zum umwandeln.

    Mit was arbeitest du den nun eigentlich? C oder Java? Danach richtet sich ja auch der Zugriff auf die Bilder.

    Ein Grauwerthistogramm ist im Prinzip nix anderes als eine Mengenverteilung der Grauwerte aus einem Bild. Man geht also alle 255 Grauwerte durch und zählt wie oft diese in dem Bild (als Pixel) vorkommen.
    Wenn man sich diese dann als Diagramm (Grauwert 1 Menge - Grauwert 255 Menge)darstellt, kann man gut erkennen welcher Grauwert als Schwelle für die Binarisierung dienen sollte.

    Versuche das alles erstma Schrittweise umzusetzen, also eine Funktion die dir das Bild umwandelt und eine die dir das Grauwerthistogramm errechnet, dannach kann man dann weitersehen.



  • Also habe mir das hier mal angeschaut, 100%ig schlau werde ich daraus nur leider nicht.

    //--------------------------------------------------------------------------- 
    // funktion mach aus einen RGB-bild ein Graustufen-Bild 
    //--------------------------------------------------------------------------- 
    void __fastcall TForm1::RGBToGray(Graphics::TBitmap *bmp) 
    { 
      Graphics::TBitmap *bmp_gray = new Graphics::TBitmap(); 
    
      bmp_gray->Assign(bmp); 
    
      // über die höhe 
      for (int j = 0; j < bmp_gray->Height; j++) 
      { 
        // eine zeile des bildes einlesen 
        RGBTRIPLE *SL = (RGBTRIPLE *) bmp_gray->ScanLine[j]; 
    
        // über die breite 
        for (int i = 0; i < bmp_gray->Width; i++) 
        { 
          BYTE gray; 
    
          // bild normal ausgrauen oder mit helligkeitsanpassung  
          // (ist für menschliches auge besser erkennbar) 
          if (CheckBox3->Checked) 
            gray = (SL[i].rgbtRed * 0.299) + (SL[i].rgbtGreen * 0.587) + (SL[i].rgbtBlue * 0.114); 
          else 
            gray = (SL[i].rgbtRed + SL[i].rgbtGreen + SL[i].rgbtBlue) / 3; 
    
          // farbwerte wieder zuweisen 
          SL[i].rgbtRed   = gray; 
          SL[i].rgbtGreen = gray; 
          SL[i].rgbtBlue  = gray; 
        } 
      } 
    
      // bild auf formular anzeigen 
      Image1->Picture->Bitmap->Width  = bmp_gray->Width; 
      Image1->Picture->Bitmap->Height = bmp_gray->Height; 
      Image1->Picture->Bitmap         = bmp_gray; 
    
      delete bmp_gray; 
    }
    

    Also hiermit soll das Bild erstmal in Graustufen umgewandelt werden.
    Nur irgendwie fehlt hier noch ne Menge zu bis das Prog ein Bild wirklich umwandelt, oder?

    z.B. welche Headerfiles brauche ich?
    Wo sage ich dem Code wie das BMP File heißt das er umconvertieren soll?
    Oder könnt ihr sonst nochmal 2-3 Takte zu dem Code sagen?

    Danke


Anmelden zum Antworten