Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

27.02.2011, 00:34

Verfahren einfacher Bilderkennung

Hallo.

Ich muss derzeit ein Programm schreiben, dass in der Lage ist Sandrippel zu vermessen (also die Wellenlänge zu bestimmen - Im Anhang mal ein Bild).
Dies ist jedoch schwieriger als gedacht.

Aktueller Stand:

Mit OpenCV kann ich auf meine Webcam zugreifen und ich komme an die Pixeldaten heran. Es ist mit einigermaßen gelungen den Verlauf der Sandwelle nachzuzeichnen. Dies mache ich momentan einfach, in dem ich die Farbwertsteigung berechne von jeder Spalte und die größte Steigung raussuche. Danach schicke ich die Ergebnisse noch durch einen Weichzeichnungsfilter, sodass eine einigermaßen glatte Kurve entsteht.

Um die Position der Extremstellen zu bestimmen ermittlere ich einen Mittelwert und schaue ob die Y-Positionen der Sandwelle überhalb (1) oder unterhalb (0) liegen. Zwischen den Schnittpunkten liegt dann ein Extrempunkt.

Problem:
Generell habe ich zwei Probleme:
1) Die fehlerrate ist zu hoch. Dies kommt wahrscheinlich durch das Rauschen der Kamera.
2) Das Verfahren mit dem Mittelwert ist eher suboptimal, da auch kleinere Sandrippel existieren können, die komplett unterhalb der Mittellinie liegen können.

Frage:
Habt ihr zufällig eine Idee wie man das Problem lösen könnte, bzw. den Vorgang verbessern könnte?


Anmerkungen zum Bild:
In Grün sieht man den Analysebereich. Nur die Werte in diesem Bereich werden beachtet. In Weiß befinden sich die reinen Y-Koordinaten der Welle, die durch die "Steigungsmethode" bestimmt wurden. In grau ist die geglättete Kurve zu sehen. Die blauen Kreise sind die Extrema. die roten senkrechten Striche sind die Übergänge zwischen 0 und 1.


Ich hoffe ihr habt ein paar Ideen, denn mit dem Ergebnis kann ich noch nichts anfangen. Es muss so genau wie möglich sein.




(Link)


mfg F-Wölkchen
»F-Wölkchen« hat folgendes Bild angehängt:
  • Unbenassssnnt.png

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

2

27.02.2011, 01:06

Also mir fällt dazu eigentlich gerade nur Least squares ein. Das eignet sich um Datenpunkte, welche mit Messfehler behaftet sind auszubügeln.

Wenn du mir mal ein (paar) Sets von Daten (x,y) gibst, dann schaue ich mal wie gut es darauf funktioniert.

btw:
Coole Aufgabe. Wie kommst du dazu so etwas zu machen? :)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

3

27.02.2011, 01:19

Um Ausreißer loszuwerden bietet es sich vielleicht an mit dem Median anstatt dem Mittelwert zu arbeiten. "Ausbügeln" ist da wohl immer schlecht da man, egal was man tut, immer die Ausreißer mit einberechnet. Besser also die Ausreißer wegschmeißen ;)

xardias

Community-Fossil

Beiträge: 2 731

Wohnort: Santa Clara, CA

Beruf: Software Engineer

  • Private Nachricht senden

4

27.02.2011, 12:03

Hm, kein sonderlich einfaches problem aber dein Ansatz ist schonmal gar nicht verkehrt. Das Problem ist die Erkennung der Kanten, da dein Algorithmus hier zwischen verschiedenen Kanten hin und her springt. Dadurch kommen die starken Ausreißer.

Das Problem lässt sich denke ich allgemein in 3 Schritte unterteilen:

A) Bildverbesserung.
Ich würde versuchen den Kontrast zu verbessern oder vielleicht, falls möglich per Thresholdingden Hintergrund von der Sandbank genau zu extrahieren. Sollte dies möglich sein wird das ganze sehr einfach. Der Threshold sollte per User Interface wählbar sein damit man den an die Beleuchtung anpassen kann.
Da das Rauschen ein Problem darstellt kann man entweder ein zeitlichen Median bilden oder man kann das Bild z.b. mit einer Gauss Funktion Tiefpassfiltern.

B) Feature Extraction.
Das beste Ergebniss sollte hier ein Canny Edge Detector geben. Der Garantiert, dass die Kanten zusammenhängend sind. ist jedoch recht aufwändig zu implementieren. Eventuell reicht es aber schon den Laplace Filter mit einem Edge-Thinning Filter zu verwenden.
Solltest du aber per Thresholding ein binäres Bild kriegen welches die Sandbank genau vom Hintergrund trennt ist dies nicht nötig. Dann reicht ein einfacher 1D Laplace operator für horizontale Kanten ohne Edge Thinning.


C) Parametrisierung
Hier wirds schwieriger. Wenn die Pixelweise Erkennung der Kanten nicht alles ist was du brauchst könnte man die Sandbank durch Polynome approximieren um eine mathematische Beschreibung der Sandbank zu bekommen. Dann kannst du die Extremwerte sehr genau bestimmen.
Dies lässt sich entweder durch minimieren des Quadratischen Fehlers machen oder auch mit der Hough Transformation.


PS: Kannst du das Lichtsetup ändern? Wenn du das ganze von oben stark beleuchtest solltest du eine sehr genau erkennbare Kante am Rand der Sandbank kriegen. Eine gute Aufnahme macht das Problem wesentlich einfacher. Dann sollte es kein Problem sein das Bild mittels Thresholding zu Segmentieren.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »xardias« (27.02.2011, 12:11)


dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

27.02.2011, 12:24

Vielleicht könnte man auch z.B. eine Fouriertransformation machen und dann einfach die hohen Frequenzen wegschmeißen.

xardias

Community-Fossil

Beiträge: 2 731

Wohnort: Santa Clara, CA

Beruf: Software Engineer

  • Private Nachricht senden

6

27.02.2011, 12:35

Vielleicht könnte man auch z.B. eine Fouriertransformation machen und dann einfach die hohen Frequenzen wegschmeißen.

Das ist genau das was Weichzeichnen macht. Darum heißt es auch Tiefpass ;) Sieht im Frequenzbereich in etwa so aus:

(Link)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

7

27.02.2011, 12:38

Das ist mir klar nur wenn man mit der Fouriertrafo arbeitet bekommt man direkt die Frequenzen aka Wellenlänge raus ;)

xardias

Community-Fossil

Beiträge: 2 731

Wohnort: Santa Clara, CA

Beruf: Software Engineer

  • Private Nachricht senden

8

27.02.2011, 12:41

Hm... stimmt, das maximum im Frequenzbereich könnte die gesuchte Wellenlänge sein. Gute Idee, bin ich nicht drauf gekommen :D

9

27.02.2011, 14:06

Also mir fällt dazu eigentlich gerade nur Least squares ein. Das eignet sich um Datenpunkte, welche mit Messfehler behaftet sind auszubügeln.



Wenn du mir mal ein (paar) Sets von Daten (x,y) gibst, dann schaue ich mal wie gut es darauf funktioniert.



btw:

Coole Aufgabe. Wie kommst du dazu so etwas zu machen? :)

Das Projekt ist im Rahmen meiner Facharbeit. Wir untersuchen Oszillationsrippel im Sand. Im Anhang habe ich mal die Rohdaten dazugepackt. Es sind nur die Y-Koordinaten der Sandwelle ermittlet mit der "Farbwertsteigung". Zu lesen sind diese wie folgt:
Zeilennummer = x gemessen von der linken Kante des Bildes und der Wert der Zeile ist die Y-Koordinate gemessen von der Unterkante des Bildes (nicht vom Messbereich!).
Wenn du lust und Zeit hast, dann kannst du gerne mal dein Algorithmus
drauf los lassen.
Um Ausreißer loszuwerden bietet es sich vielleicht an mit dem Median anstatt dem Mittelwert zu arbeiten. "Ausbügeln" ist da wohl immer schlecht da man, egal was man tut, immer die Ausreißer mit einberechnet. Besser also die Ausreißer wegschmeißen ;)
Den Medianfilter zu benutzen kam mir auch schon in den Sinn. Doch dieser hatte komischer Weise meinen Graphen vollkommen über den Haufen geworfen und es traten merkwürdige Effekte auf. Vermutlich war mein Algorithmus falsch umgesetzt.
Ich werde es auf jedenfall nochmal ausprobieren.

Kannst du das Lichtsetup ändern? Wenn du das ganze von oben stark beleuchtest solltest du eine sehr genau erkennbare Kante am Rand der Sandbank kriegen.
In der Tat. Ich habe die Sandmarke mal von oben, statt von der Seite beleuchtet und die Konturen werden um einiges besser. Die Idee mit dem Schwellenwert ist gut. Im Anhang mal die Variante mit dem Schwellenwert.

Da das Rauschen ein Problem darstellt kann man entweder ein zeitlichen Median bilden oder man kann das Bild z.b. mit einer Gauss Funktion Tiefpassfiltern.
Einen Weichzeichner werde ich nachher auch mal einbauen.

Das beste Ergebniss sollte hier ein Canny Edge Detector geben. Der Garantiert, dass die Kanten zusammenhängend sind. ist jedoch recht aufwändig zu implementieren.
Mit OpenCV ist die Canny-Kantendetektion implementiert und ich könnte sie nutzen. Ich werde es mal versuchen.

Das ist mir klar nur wenn man mit der Fouriertrafo arbeitet bekommt man direkt die Frequenzen aka Wellenlänge raus ;)
Hmm... also den Wikibeitrag zur Fouriertransformation kann ich leider nicht wirklich nachvollziehen. Gäb es noch andere Möglichkeiten oder einen guten Link, der die Fouriertransformation gut erklärt?

mfg F-Wölkchen
»F-Wölkchen« hat folgende Bilder angehängt:
  • Unbenannt2.png
  • Unbenannt3.png
  • Unbenannt10.png
»F-Wölkchen« hat folgende Datei angehängt:
  • Messreihe.txt (2,24 kB - 161 mal heruntergeladen - zuletzt: 12.04.2024, 00:51)

10

27.02.2011, 15:25

Ich habe jetzt mal den Canny-Algorythmus von OpenCV genommen und ein sehr gutes Ergebnis erzielt.

Doch wie kann ich nun genau am geschicktesten die Wellenlänge bestimmen?

mfg F-Wölkchen
»F-Wölkchen« hat folgendes Bild angehängt:
  • Unbenannt12.png

Werbeanzeige