Bildsegmentierung

Status
Nicht offen für weitere Antworten.

Tyvan

Mitglied
Hallo,

hat jemand von euch Ahnung mit der Verarbeitung von Bildern unter Java.

Vor allem mit der Bildsegmentierung. Ich habe das Ziel ein normales farbiges Bild zu segmentieren und das nur nach bestimmten Farben. Also ich möchte auf dem Bild nur die Farben Schwarz, Weiss, Rot, Grün, Magenta, Cyan und Gelb segmentieren.

Meine bisherigen Versuche der Schwellwertangaben scheiterten. Auch die ConvolveOp Klassen helfen mir nicht, da es immer ein Helligkeitsproblem gibt und Farben verloren gehen.

Ich habe oft im Internet gesehen, wie Leute sogar schwierige Bilder sehr gut segmentiert haben, bzw. bestimmte Objekte irgendwie registriert haben.

Jede Hilfe bzw. Info ist mir recht.



N8. :?
 

0xdeadbeef

Top Contributor
Wenn Du nach Farben segmentieren sollst, ist das Sinnvollste wohl ein Agglomerationsverfahren (Flächenwachstum):
Du wählst einen Pixel, der eindeutig die Anforderung für eine bestimmte Klassifizierung erfüllt (rote Fläche) und untersuchst dessen Nachbarn, ob sie innerhalb eines Toleranzfensters bezüglich der Farbvariation liegen. Mal vorausgesetzt, die Flächen sind nicht 100% homogen bezüglich ihrer Farbe, ansonsten ist es natürlich noch einfacher (keine Toleranz). Die Pixel, die die Kriterien erfüllen, ordnest Du der Fläche zu und untersuchst wiederum deren Nachbarn. Die Pixel der Fläche kannst Du z.B. in einer ArrayList oder einem Vector ablegen. Außerdem markierst Du die bereits klassifizierten Pixel, damit sie nicht erneut klassifiziert werden (z.B. in der Original-Bitmap löschen).
 

Tyvan

Mitglied
0xdeadbeef hat gesagt.:
Wenn Du nach Farben segmentieren sollst, ist das Sinnvollste wohl ein Agglomerationsverfahren (Flächenwachstum):
Du wählst einen Pixel, der eindeutig die Anforderung für eine bestimmte Klassifizierung erfüllt (rote Fläche) und untersuchst dessen Nachbarn, ob sie innerhalb eines Toleranzfensters bezüglich der Farbvariation liegen. Mal vorausgesetzt, die Flächen sind nicht 100% homogen bezüglich ihrer Farbe, ansonsten ist es natürlich noch einfacher (keine Toleranz). Die Pixel, die die Kriterien erfüllen, ordnest Du der Fläche zu und untersuchst wiederum deren Nachbarn. Die Pixel der Fläche kannst Du z.B. in einer ArrayList oder einem Vector ablegen. Außerdem markierst Du die bereits klassifizierten Pixel, damit sie nicht erneut klassifiziert werden (z.B. in der Original-Bitmap löschen).

Aber mit RGB Werten gibt es ja 256*256*256 Bereiche die ich beachten muss.
Das Foto das ich geliefert kriege ist nicht gerade toll.
Das wo es eigentlich rot, das ist es irgendwie alles mögliche. Lila, Violett, Braun, es gibt auch mal Pixel die Grau sind oder Weiss. Das wäre hammer viel Arbeit bis ich erst mal gute Toleranzen habe.
ICh dachte eher daran, ob es vielleicht nicht ne gute Methode gibt, oder so ne Art Transformation mit der ich alles einfacher machen kann.
 

0xdeadbeef

Top Contributor
Habe (vor 150 Jahren) meine Diplomarbeit in diesem Themenkreis gemacht und meine Erkenntnis daraus: Automatische Bildverabeitung/Segmentierung/Objekterkennung funktioniert dann gut, wenn man das Bildmaterial so konditioniert, daß die Verarbeitung einfach geht. In erster Linie ist man daher in der Praxis bemüht, die Erzeugung des Bildes bereits so zu normieren/beeinflussen, daß die Interpretation einfacher wird (Verwendung spezieller Schriften, entsprechende Beleuchtung, starke Farben/Kontraste usw.).

Hat man keinerlei Einfluß auf das erzeugte Bild, wird es einigermaßen hart und es ist schwer bis unmöglich zu garantieren, daß ein Algorithmus, der ein Bild erfolreich segmentiert im nächsten auch noch funktioniert. Dann kann man sich was zurechtkrampfen, um sich automatisch Schwellenwerte auszurechnen usw.

Haste mal einen Link zu einem der Bilder, die Du segmentieren sollst?
Mit ist auch noch nicht 100% klar, was exakt die Aufgabenstellung ist. Sollst Du ein Bild in farbige Flächen zerlegen oder alle Flächen einer Farbe finden oder was eigentlich genau?
 

Tyvan

Mitglied
Das ist für die Steuerung eines Roboters.

Dabei gibt es ein Strassennetz. Auf einem weissem Brett gibt es schwarzen Klebebänder die die Strasse darstellen.
Auf diesen Klebebändern gibt es dann wiederum an einigen Stellen grüne und rote Streifen. Grün bedeutet durchfahrbar, Rot bedeutet Einbahnstrasse. Und Grün und Rot sind immer nebeneinander, das heisst von der einen Richtung ist durchfahrbar aber nicht von der anderen. Die Roboter bekommen dann eine Farbmarkierung. Das wären Cyan/Gelb, Cyan/Magenta und Gelb/Magenta. Also mit dem Strassenetz sind es ja dann insgesamt 6 Farben (Weiss für KEIN Strassennetz, Schwarz für Strasse, Rot für Einbahnstrasse bzw. Stop, Grün für Einbahnstrasse und die 3 anderen Farben für die Markierungen.
Also Rot wäre ja 255,0,0 und Grün 0,255,0 und Weiss 255,255,255 und Schwarz 0,0,0 und Cyan 0,255,255 und Magenta 255,0,255 und Gelb 255,255,0.

Das blöde ist halt ich kann das Bild nicht ändern, ich bekomme es von ner Logitech Kamera mit ner Auflösung von 640x480. Und zum Beispiel die Farbe Rot kommt aufm Bild bei genauer Untersuchung in verschiedenen Farben an.

Ich habe schon eine eigene Methode geschrieben die einfach jeden einzelnen Pixel nimmt und durch die TOleranzen geht und am Ende diese Stelle eine dieser obigen eindeutigen Farben überweist, aber was am Ende rauskommt ist meistens Müll, vieles definiert er als SCHWARZ, da ich ganz am Ende falls alle meine Toleranzen nicht stimmen einfach Schwarz gemacht werden soll, das bedeutet, das die Schwellwerte überhaupt nicht passen. Obwohl die Toleranzen recht hoch gemacht habe. Das liegt einfach daran das ja manchmal ganz andere Farben da stehen obwohl das vielleicht ein Grün oder Rot sein sollte.

Und diese Gauss MEthoden mit der ich um ein Pixel herum abgleichungen machen kann, hilft nicht viel. Denn was ist wenn ich ein Pixel nehme und sehe das ist z.b der Farbwert 38,198,29 (das sollte eigentlich Grün sein) und passe dementsprechend die 3 Nachbarpixel an (also in diesem Fall 7x7 Bereiche) dann weiss ich nicht ob vielleicht der 3. Nachbarspixel schon in Wirklichkeit eine völlig andere Farbe sein soll, z.B. ROT.


Ich guck mal das ich ein Snaphot mache, dann koennt ihr mal sehen wie das aussieht.
Ich mach auch mal ein Snapshot von dem Bild das ich gefiltert habe, dann seht ihr mein "Müll". :bae:
 

Illuvatar

Top Contributor
Tyvan hat gesagt.:
Ich habe schon eine eigene Methode geschrieben die einfach jeden einzelnen Pixel nimmt und durch die TOleranzen geht und am Ende diese Stelle eine dieser obigen eindeutigen Farben überweist, aber was am Ende rauskommt ist meistens Müll, vieles definiert er als SCHWARZ, da ich ganz am Ende falls alle meine Toleranzen nicht stimmen einfach Schwarz gemacht werden soll, das bedeutet, das die Schwellwerte überhaupt nicht passen. Obwohl die Toleranzen recht hoch gemacht habe. Das liegt einfach daran das ja manchmal ganz andere Farben da stehen obwohl das vielleicht ein Grün oder Rot sein sollte.

Ich vermute, das ist das beste, vermutlich hattest du nur nen kleinen Fehler in der Berechnung. Berechne einfach mal zu den 6 Farben den "Abstand" (je Differenz addiert von r, g und b) und nimm das mit dem niedrigsten. Wenn du das so hinkriegst, müsste die Nulltoleranzsegmentierung "einfach" werden.
 

Tyvan

Mitglied
Das ist das Bild das ich segmentieren will. Dabei sind dort die Farben Schwarz, Weiss, Rot und Grün am wichtigsten.

normal.JPG
 

0xdeadbeef

Top Contributor
Naja, das rot ist in der Tat ein bisserl schwach und die gelben Streifen bei der Farbmarkierung sind etwas störend (Beleuchtung?), aber prinzipiell sieht das jetzt nicht SO problematisch aus. Wie gesagt: such Dir einen Anfangspunkt, der noch sicher als rot klassifiziert werden kann und untresuche dann die Nachbarn darauf, ob die eine zulässige Farbdifferenz zum Ausgangspixel haben, um noch als rot klassifiziert zu werden. Dann untersuchts Du wiederum die Nachbarn dieser Pixel, ob sie eine zulässige Farbdifferenz zum jeweiligen "Eltern"-Pixel haben.
Damit sind auch Helligkeitsverläufe, Rauschen und dergleichen gut beherrschbar.
Du brauchst halt zwei Schwellen (für jede Farbe): einen Schwellwert für die Anfangsfarbe und einen für die Farbdifferenz. Die Schwellwerte sind natürlich quasi Vektoren (im mathematischen Sinne), denn sie enthalten ja drei skalare Schwellwerte (R,B,G).
Kannst ja auch in einem ersten Schritt erstmal den Hintergrund (auf die gleiche Weise) als großes Objekt klassifizieren und als "erkannt" aus dem Bild löschen: damit bleiben alle verbleibenden "Inseln" interessante Objekte.
Wegen Rauschen, Artefakten (Schmutz auf der Linse, Dreck auf dem Spielfeld) kannst Du auch alle Objekte löschen, die eine gewisse Mindestgröße unterschreiten. Ist halt die Frage, ob der Abstand/Blickwinkel immer gleich bleibt, dann ist das einfach zu bewerkstelligen, ansonsten müßtest Du Dir überlegen, wie Du die minimale Objektgröße bestimmts (Kalibirierung? Wanddicke des Labyrinths?).
 

Tyvan

Mitglied
Hi,

@0xdeadbeaf:

Weisst du wie ich eine Kreuzungserkennung genau machen könnte. Ich dachte mir ich würde einfach das Bild jeweils in 4x4 Pixel untersuchen und nachschauen ob eine bestimmt Farbe (schwarz = strasse) oft vorkommt und diese Stelle als Kreuzung definieren. Aber das ist schlecht, da es viele Stellen mit viel Schwarz gibt die gar keine Kreuzung sind. Hast du da ne Ahnung.

Danke für deine bisherige Hilfe. :roll:
 
S

SPawn

Gast
meine Antwort kommt vllt ein bisschen spät:

schau dir mal den hsv farbraum. dieser ist wie ein zylinder aufgebaut und da kann man "stückchen" rausschneiden bzw. zu einem prototypen ordner.

MfG SPawn
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben