Objekterkennung in einem Bild

  • VB.NET

Es gibt 28 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Objekterkennung in einem Bild

    Hallo ihr schlauen Leute da draußen :)

    ich (16 Jahre/Schüler) bastle gerade nach diesem Beitrag rn-wissen.de/index.php/Bildverarbeitung_Tutorial eine Art Kantenerkennung.
    Nach einigem probieren klappt das auch recht gut und schnell (ca. 500 ms für ein Testbild mit 300 * 300 px - reicht mir völlig)
    Mein Programm hebt mithilfe der horizontalen und vertikalen Soebel Faltungskern alle Kanten (in horiz. und vert. Richtng) weiß hervor, alles andere wird schwarz.

    Jetzt versuche ich schon seit längerem ein Rechteck (oder Kreuz oder Kreis) zu erkennen. Ich programmiere das ganze mit dem Ziel, nachher einen Fischertechnikroboter zu steuern (aber das kommt später).
    Es ist mir eigentlich egal welche Form erkannt wird, hauptsache sie wird erkannt :)

    Ich habe leider keine Ahnung wie ich das angehen soll. Mir ist klar dass mir hier keiner mit ner fertigen auf Geschwindigkeit optimieren Objekterkennungssource ankommt, aber vielleicht hat ja irgentjemand einen Ansatz bzw. ein Codebeispiel :)

    Google und SuFu haben bisher nicht geholfen...

    Gruß Dentox

    PS: Wenn irgendjemand Interesse an dem Code hat, könnt ihr gerne fragen! Allerdings ist er bisher nicht besonders "schön" im Sinne von geordnet :)

    Dentox schrieb:

    PS: Wenn irgendjemand Interesse an dem Code hat, könnt ihr gerne fragen! Allerdings ist er bisher nicht besonders "schön" im Sinne von geordnet :)

    Hallo Dentox und vor allem herzlich willkommen!

    Und zu dem zitierten Teil: oh ja - oh ja - jaaaaaaa :).
    Genau den RN Artikel hab ich gestern gelesen und... nicht wirklich verstanden.
    Ich möchte auch sehr gern Kanten erkennen und zwar nur vertikal und horizontal - keine Objekte.

    Also wäre ich hoch erfreut über Deinen bisherigen Code - egal wie er aussieht!

    Ansonsten wünschte ich sehr, Dir helfen zu können.
    Da ich wie gesagt die Kantenerkennungen nicht wirklich verstehe, habe ich viel mit Google gesucht und auch einiges gefunden.
    Die Geschwindigkeit der getesteten Routine war alles andere als gut.
    Wenn Du möchtest, wühle ich morgen nochmal für Dich im weiten Web herum und finde vielleicht das VB-Programm wieder?

    LG,
    Bruno

    PS: Habs wiedergefunden!
    Hier der Link: Edge detection in an image using sobel filter in VB.net and C#.net
    Dort ist oben gleich ein Link zum herunterladen des Projekts.
    Einfach mal ausprobieren, es werden die Kanten von 3 Pinguinen erkannt, aber das dauert furchtbar lange.
    Dann hab ich hier noch etwas interessantes: LINK und hier auch noch: LINK

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „diylab“ ()

    Hallo diylab,

    danke erstmal für die Links!
    Erwarte keinen besonders komplizierten Code, das ist eigentlich alles ganz easy :)
    Vielleicht werde ich demnächst auch ein Tutorial für den Soebel Operator in VB schreiben. Mal sehen ob meine Zeit reicht.

    Nur damit du erstmal weißt was mein Programm kann/macht:
    1. Schritt: Umwandlung des Bildes in ein Array. Das Array ist ein 2D PixelRGB Array (PixelRGB ist eine selbst gemachte Struktur mit 3 Parametern (r,g und b als integer). Diese funktioniert schneller als Color von .Net.
    2. Schritt Umwandlung des Arrays in den HSV Farbraum. Genauer gesagt in H vom HSV Farbraum (Warum ist in meinem Link oben gut beschrieben)(Das Array ist nun ein ByteArray)
    3. Schritt: Clonen des Arrays, um nachher 2 (oder mehr) Kerne anwenden zu können.
    4. Schritt: Anwenden der Faltungskerne.
    5. Schritt: Kombinieren der beiden Ausgangsbilder von der Anwendung der Faltungskerne.
    6. Schritt: Umwandlung des Arrays in ein Bild

    Eigentlich besteht das Projekt nur aus tausenden for Schleifen :)
    Ich werde das ganze noch sortieren und kommentieren aber im Moment ist das eher so ein Test ob und wie schnell das ganze funktioniert.

    Falls du aber gar nicht erwarten kannst hab ich das ganze mal hochgeladen: dentox.info/vb/kantenerkennung.rar

    PS: Wenn jemand fragen zum Code hat, könnt ich euch gerne bei mir melden.
    PPS: Wenn irgendjemand Lust hat mir bei dem Projekt zu helfen, hätte ich auch nichts dagegen. Ich denke eine Zusammenarbeit wäre ne feine Sache :)
    Dateien
    1. Schritt: Umwandlung des Bildes in ein Array. Das Array ist ein 2D PixelRGB Array (PixelRGB ist eine selbst gemachte Struktur mit 3 Parametern (r,g und b als integer). Diese funktioniert schneller als Color von .Net.

    Das wage ich stark zu bezweifeln, da Color auch eine Struktur darstellt...außerdem solltest du R,G und B als Byte definieren(spart speicher, vermeidet hoffentlich unvorhersehbare Fehler)...Das ganze machst du wahrscheinlich jedoch mit LockBits, welches die Farbinformationen als ByteArray einliest, diesen verwendest du dann wahrscheinlich um daraus die Farbinformationen in deine Strukture zu setzen...das was dabei schneller ist, ist LockBits, im Vergleich zu GetPixel...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Hallo,
    ich habe bereits sehr viele ansätze ausprobiert, ein Image in ein bytearray zu bekommen. Allerdings kam bei allen Versuchen nur Müll dabei raus (warsch. weil sich die Header Daten auch im Array befinden??). Deswegen mach ich das ganze per Schleife und getpixel. Allerdings benutze ich nicht getpixel direkt sondern eine Dll, die ich im Netz gefunden habe, die kann das ganze ziemlich schnell. Das mit dem PixelRGB structure hatte ich damals ersetzt, und meines Wissens nach einen starken geschwindigkeitszuwachs gebracht, kann aber auch sein dass ich gleichzeitig eine andere Änderung vorgenommen habe, die das ganze so beschleunigt hat.
    Ich arbeite schon ein wenig daran, das ganze schneller zu machen, denn gerade die ImageToArray und ArrayToImage funktionen brauchen viel Zeit, die sich sicherlich einsparen lässt, aber ich muss halt wirklich verlässlich die RGB Werte bekommen, und bei Test mit Streams u.Ä. ergaben sich eben nur "Sinnlose Zahlen" für mich (bei einem 3*3 Pixel Testbild komplett schwarz hatte ich nachher irgentwie 100 elemente im Array, und zwar nicht nur nullen ?!?!)
    Wenn also jemand einen guten Vorschlag hat was die Geschwindigkeit betrifft: Immer her damit! :)
    Was die Objekterkennung oder Stricherkennung oder wie auch immer man das nennen will angeht, hat da keiner ne Idee wie sich das bewerkstelligen lässt??

    Gruß Dentox


    EDIT: Ihr hattet recht, der Geschwindigkeitszuwachs lag nicht an Color. Deswegen hab ichs zur übersichtlichkeit wieder umprogrammiert. Achja: Wenn ich alle integers in Byte umwandle, bekomme ich an einigen Stellen "arithmetische Überläufe". Das liegt wohl daran, dass zwischendurch bei berechnungen größere Zahlen als 255 auftreten. Da sowieso keine Fehler aufgrunde der Integers aufkommen können (ich normalisiere alle Werte nach jeder Kritischen Funktion) hab ich das jetzt mal gelassen...

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Dentox“ ()

    Warum antwortet keine mehr?
    Hat echt niemand eine Idee?
    Ich hab mich mal weiter damit beschäftigt, und herausgefunden das man eine Objekterkennung (oder eine Linienerkennung) über eine Hough Transformation bewerkstelligen kann, hat dazu jmd was? Alles was ich bisher gefunden habe hab ich nich verstadnen.
    hmm also
    ich bin ja auch gerade dabei sowas ähnliches zu programmieren :D
    schön dass hier noch mehr aus der Robo welt rumschwieren

    ich verfolge allerdings ein etwas anderes ziel. vorallem aus dem Grund weil ich das mit der Kantenerkennung nicht so ganz gerafft hab^^

    ich will die Position meines robos mithilfe 2er Leuchtfeuer und einer Webcam bestimmen.
    hab dafür auch schon erste Ansätze gemacht. Siehe hier

    Mein Problem is zur zeit noch. Das Feintuning. Da je nach Hintergrund er meinen Lichtpunkt nicht richtig erkennt.
    Wenn ich das geschafft hab, werde ich an die Positionsbestimmung gehen. bis dahin sollten auch meine LEDs angekommen sein^^

    aber ich bin auch so vor gegangen. also mit getpixel und ner schleife alle RGB werte und dazugehördigen Koordinaten ausgelesen, in HSV umkonvertiert und dann nach dem hellsten roten Punkt gesucht und angezeigt.
    bei der Kanntenerkennung müsste das ähnlich gehen. Nur dass du nicht nur nen Punkt "isolierst" sondern eben ne Kante oder ne Fläche oder Form und abgleichst?
    Hallo,

    du beschreibst dass man nicht nur den Punkt isolieren soll, sondern gleich ne Fläche oder Kante mit einer (vorgegebenen) Form vergleichen. Allerdings hapert es bei mir ja schon daran, zusammenhängende Flächen zu erkennen. Außerdem hab ich es auch nicht hinbekommen ein anderes Bild mit teilen des zu erkennenden Bildes zu vergleichen. Wenn du dazu irgentwas hast wärs cool wenn du dich nochmal meldest.

    Gruß Dentox
    ja man kann dies erreichen, indem man mit den HSV werten rumspielt. also diese ändert.
    zb im kompletten Bild den H wert 50Punkte runter setzt oder so.
    und irgendwann hat man theoretisch nur die kante sichtbar. diese kann man dann wieder in ne Matrix übertragen. mit den einzelnen Punkten und kann daraus wieder rechnen.
    allerdings bin ich soweit auch nicht.
    aber so oder so ähnlich hat es der hier gemacht: techgeek.at/
    da gibs auch nen kleines video dazu.
    is nur relativ schwirig das programmiertechnisch umzusetzen, da sich ja der hintegrund ändert. aber daran bin ich auch zur zeit.
    ^^
    Danke für den Link zu techgeek.at, der Typ is ja mal genial.
    Das was er da gemacht hat in Punkto Lichtfleckerkennung ist zunächst sehr gut verständlich und auch nich all zu schwer (glaub ich :D) aber in welcher Geschwindigkeit das abläuft ist echt faszinierend! naja, mein Projekt ist n bisschen eingeschlafen, ich werd mich da aber auf jeden Fall nochmal reinhängen.
    Falls irgentjemand noch was in der Richtung findet, IMMER HER DAMIT!
    Gruß Dentox
    so ich hab mich nach langer zeit auch mal wieder mit dem thema beschäftigt
    das sind die Resultate:





    Wie man sieht erziehtl man mit einer Computergrafik ein sehr gutes ergebnis. Mit einem Live KameraBild leider nicht so sehr. da ist noch zu viel rauschen bzw falsche Kantenerkennung drin.
    vielleicht hat ja jemand ne idee wie man das abstellen kann?

    sonst bin ich soweit zu frieden damit.
    Vielleicht ist es notwendig und sinnvoll, Dich zunächst noch ein paar Minuten länger mit Bildverarbeitung zu beschäftigen. Es gibt nämlich nicht nur Sobelfilter.
    Einen Algorithmus zum Finden von Kanten habe ich so programmiert:
    1. Umwandlung in ein Graustufenbild (@Turtle10)
    2. Diskriminierung -> Umwandlung in ein reines schwarz-weiß-Bild, wobei die Lage der Schwelle vorgegeben werden kann
    3. Laplace-Filter
    Das Ergebnis ist eine 1-Pixel breite Kante
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    und wie findet man heraus, dass es ein Kreis ist?

    man kann schauen, ob es mit A = pi*r² bzw U = 2*PI*r übereinstimmt.

    Aber dann stellt sich die Frage, wie man den Mittelpunkt bestimmt.
    Bei Quadraten (Edit: und Rechtecken) wird das bestimmt noch lustiger
    :whistling:
    Visual Basic FTW :D
    Programmiere u.a. mit C# (XNA), Blitz Basic 3D, BlitzPlus , PHP.
    Mit Regression. :D :D :D
    Kreis: n Input-Werte (die Kantenpixel), 3 Zielgrößen: x0, y0, r und die Bedingung, dass die Standardabweichung minimal wird.
    Startwerte:
    x, y: Mittelwert aller x- bzw. y-Werte
    r: Wurzel aus ((x - x0) ^ 2 + (y - y0) ^ 2)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich wollte noch mal erläutern, warum ich denke, dass es besser wäre die Farben und nicht nur
    das Grausstufenbild zu betrachten:

    Es geht um Objekterkennung und nicht nur um Kantenerkennung!
    Meistens hat ein Objekt Kanten einer Farbe. Man stelle sich nur mal zwei
    Bücher vor, die senkrecht auf einander stehen. Der Buchrücken beider
    Bücher beschreibt dann 1e Kante. Würde man nun nur mit Graustufen
    arbeiten, könnte man je nach Farbwert die beiden Bücher eventuell nicht
    unterscheiden (jetzt mal ohne die Kante zwischen den Büchern
    zu beachten). Bei Farben hätte man einen zusätzlichen Untercheidungswert.
    Natürlich reicht für den Anfang ein Graustufenbild. Aber um wirklich
    Objekte zu unterscheiden, wird man später auch noch in die 3te Dimension
    mit den Berechnungen gehen müssen.