Kreis und Linie mit zufälliger Anordung in einer Bitmap finden // diverse Filter
-
Bilder !!!
@Sobel
Input -> VertFilter -> Output
Output -> HorizFilter -> FinalOutAls Input natürlich das Bild nehmen was du durch die anderen Filter bereits erhalten hast.
@std::sort
Ja, genau wegen diesem Fehler in deinem sort lgo sollte halt der Erste Blick immer erst in die Bibliotheken sein. Man spart SEHR viel Zeit damit die stl zu benutzen anstatt nen sort algo, ne verkettete Liste, nen dynamisches Array, ne Map, nen Stack etc... zu implementieren. Ausserdem weiss man das diese algo's und strukturen Fehlerfrei sind(naja, meißtens jedenfalls, einige MS implementierungen der STL sind echt buggy, aber das sollte bei deinem Gebrauch nicht auffallen und tut hier auch nichts zur Sache).
-
Also der Sobel Filter hat mich nicht wirklich überzeugt.
hier ist das Ergebnis:
http://img164.imageshack.us/my.php?image=mitsobel9yg.jpg
Ich habe den Median Filter hinter den Sobel geschrieben. Das hat noch zu den besten Ergebnissen geführt.
Wen es interessiert wie es geht:
for (int y=0; y<240/*bmih.biHeight*/; y++) { for (int x=0; x<320/*bmih.biWidth*/; x++) { input[x][y] = output[x][y]; } } for (int y=0; y<240/*bmih.biHeight*/; y++) { for (int x=0; x<320/*bmih.biWidth*/; x++) { output[x][y] = abs( (-1 * input[x-1][y+1]) + (1 * input[x+1][y+1]) + (-2 * input[x-1][y] ) + (2 * input[x+1][y] ) + (-1 * input[x-1][y-1]) + (1 * input[x+1][y-1])); } } // Kanten in Y-Richtung for (int y=0; y< 240/*bmih.biHeight*/; y++) { for (int x=0; x< 320/*bmih.biWidth*/; x++) { input[x][y] = output[x][y]; } } for (int y=0; y< 240/*bmih.biHeight*/; y++) { for (int x=0; x< 320/*bmih.biWidth*/; x++) { output[x][y] = abs( (-1 * input[x-1][y+1]) + (1 * input[x-1][y-1]) +(-2 * input[x] [y+1]) + (2 * input[x] [y-1]) +(-1 * input[x+1][y+1]) + (1 * input[x+1][y-1])); } }
-
Ehm, das was Du da gemacht hast ist kein wirklicher Sobel. Also die einzelnen Teile schon, aber du sollst nicht beide zusammen auf das Bild anwenden.
Erst Sobel-X, dann wieder auf das Originalbild(!) den Sobel-Y. Das gesambild erhältst Du nun, indem Du an jeder Stelle sqrt(Sobel-X^2 + Sobel-Y^2) hinschreibst.
-
Ob ich das Ergebnis für meine Anwendung gebrauchen kann muss ich noch herausfinden. Aber hier ist das Resultat des nun hoffentlich richtigen Sobel Filters.
http://img161.imageshack.us/my.php?image=mitsobel1lb.jpg
die Linien um das Teil herum sind meine Finger.
und hier das vielleicht interessantere,.... der Code:
//---- Sobel Filter --------------------------------------------------------- // -1 0 1 -1 -2 -1 // -2 0 2 x Filtermatrix 0 0 0 y Filtermatrix // -1 0 1 1 2 1 for (int y=0; y<240/*bmih.biHeight*/; y++) { for (int x=0; x<320/*bmih.biWidth*/; x++) { sobelX[x][y] = output[x][y]; sobelY[x][y] = output[x][y]; } } // Kanten in X-Richtung for (int y=0; y<240/*bmih.biHeight*/; y++) { for (int x=0; x<320/*bmih.biWidth*/; x++) { sobelX[x][y] = abs( (-1 * input[x-1][y+1]) + (1 * input[x+1][y+1]) + (-2 * input[x-1][y] ) + (2 * input[x+1][y] ) + (-1 * input[x-1][y-1]) + (1 * input[x+1][y-1])); } } // Kanten in Y-Richtung for (int y=0; y< 240/*bmih.biHeight*/; y++) { for (int x=0; x< 320/*bmih.biWidth*/; x++) { sobelY[x][y] = abs( (-1 * input[x-1][y+1]) + (1 * input[x-1][y-1]) +(-2 * input[x] [y+1]) + (2 * input[x] [y-1]) +(-1 * input[x+1][y+1]) + (1 * input[x+1][y-1])); } } for (int y=0; y< 240/*bmih.biHeight*/; y++) { for (int x=0; x< 320/*bmih.biWidth*/; x++) { output[x][y] = sqrt(sobelX[x][y] * sobelX[x][y] + sobelY[x][y] * sobelY[x][y]); } } //------------------------------------------------------------------------------
-
Na das sieht doch schon eher nach Sobel aus. Sorry, das mit dem falschen Sobel war mein Fehler, hatte es falsch beschrieben.
for (int y=0; y<240/*bmih.biHeight*/; y++) { for (int x=0; x<320/*bmih.biWidth*/; x++) { sobelX[x][y] = output[x][y]; sobelY[x][y] = output[x][y]; } }Dafür könntest auch mal n memcpy nehmen, und das ganze hin und her midde Speicher kannste gut über Pointer vereinfachen und ne Menge Performance rausholen, aber das tut ja erstmal noch nichts zur Sache.
Ob du das Bild gebrauchen kannst, nunja, ich muss gestehen das ich momentan nichts mehr auf dem Bild erkenne. Ich denke du musst einfach ein bisschen mit den Filtern experimentieren welches Anti-Noise Filter am besten dein Bild bereinigt und beim Sobeln vielleicht den Kernel vergrössern, oder sogar den Filter mehrmals drüber jagen um die Kanten noch stärker hervor zu heben ...
Du musst am Ende eine gute Mischung zwischen den Filtern finden so das die unwichtigen Linien herausfliegen und nur deine Kugel übrig bleibt. Ich denke darauf ein paar mal den Sobel angewendet sollte dir dann schon richtig scharfe linien geben die du dann testen kannst.
-
Also ich würde das mit dem Sobel lassen
... das bringt zwar nachher bei der Linienerkennung nen bischen geschwindigkeit aber sonst wäre mir für deine Aufgabe kein weiterer vorteil bekannt (was natürlich nichts heißt) ...Ich würde das Bild Binarisieren, oder wie man das nennt, und dann die linien mit so einer Art LaPlace Filter erkennen. Nur das der Laplace Filter eventl. werte außerhalb von 0-255 liefert ... deswegen würde ich sowas machen...
abs(input[x-1][y]-input[x][y])Das ganze dann so wie beim Sobelfilter aus X und Y Richtung und man sollte die linien schön erkennen können

-
ChaosAngel schrieb:
Dafür könntest auch mal n memcpy nehmen, und das ganze hin und her midde Speicher kannste gut über Pointer vereinfachen und ne Menge Performance rausholen, aber das tut ja erstmal noch nichts zur Sache.
Ne ganze Menge Performance dürfte sich auch rausholen lassen, indem man den Sobel-Filter zerlegt:
(-1 0 1) (1) (-2 0 2) = (2) ** (1 0 -1) (-1 0 1) (1)** bezeichnet die Faltung. Also erst Kanten suchen und dann Mit Binomial-TP glätten. Der für waagrechte Kanten geht analog. Müßte man mal probieren, ob's was bringt. Bei größeren Matrizen ist der Vorteil größer.
Weißt Du eigentlich schon, wie's danach weitergehen soll? Außer "Linien suchen"? Falls nein, schau doch nochmal nach, ob Du nicht eine der bereits vorgeschlagenen Ideen ausprobieren möchtest.
-
[quote="Jester]
Weißt Du eigentlich schon, wie's danach weitergehen soll? Außer "Linien suchen"? Falls nein, schau doch nochmal nach, ob Du nicht eine der bereits vorgeschlagenen Ideen ausprobieren möchtest.-> Wie was weitergehen soll??? Und welche vorgeschlagene Ideen???
Meinst du damit irgendwelche Filter? Oder generell, wie ich die Koodinaten der Linien herausbekomme?
Bis zum Sobelfilter habe ich bis ketzt schließlich alles schon gemacht.Was vielleicht noch interessant wäre, ist die Hough Transformation zur Erkennung von Kreisen.
Ich glaube es ist besser, wenn man den Median Filter anch dem Sobel anwendet
-
gramboler schrieb:
-> Wie was weitergehen soll??? Und welche vorgeschlagene Ideen???
Meinst du damit irgendwelche Filter? Oder generell, wie ich die Koodinaten der Linien herausbekomme?
Bis zum Sobelfilter habe ich bis ketzt schließlich alles schon gemacht.Und, wie funktionierte die Kantenerkennung mit Hough? War das Ergebnis des matched-Filters zu was zu gebrauchen?
Der Median-Filter ist hier übrigens vermutlich nicht so geeignet. Ein Gauß-Tiefpaß wäre vermutlich besser geeignet um das Rauschen zu unterdrücken. Ein Binomialtiefpaß könnte hinteressant sein.
-
Die Hough Transformation habe ich ncht nicht durchgeführt. Ich werde aber darüber berichten, sobald ich das gemacht habe.
Ich muss mich gerade ein wenig um mein Studium kümmern, dass ich durch die rumprogrammierei ein wenig vernachlässigt habe.Mein momentaner Stand ist:
- Bild über Webcam einlesen
- Videostream in einem Fenster ablaufen lassen
- ein Schwarz/Weis Bild daraus machen
- Sobel Filter darüber laufen lassen
- Median Filter
- Bild als Datei abspeichernGeplant ist noch:
- Line zu erkennen
- Das Teil mit einem Anderen vergleichen und herausfinden ob es das richtige ist (darum die Linien- und Kreiserkennung, dient zur identifikation des Teils)
- ...ich weis nicht wie weit die Studienarbeit noch erweitert wird