Kreis und Linie mit zufälliger Anordung in einer Bitmap finden // diverse Filter
-
Danke,.... für die vielen schnellen Antworten!!!
stimmt, es ist einfacher als ich dachte. da hätte ich auch selbst drauf kommen können.

-
....so einfach war es dann soch nicht. Zum Glück sieht in der Theorie immer alles anders aus wie in der Praxis.
Das Problem ist, dass die Teile einen Schatten auf den Tisch werfen. Dieser Schatten ist natürlich auch schwarz, oder zumindest so dunkel, dass ichdas erste Pixel nicht genau erfassen kann. Außerdem sind die Übergänge von schwarz auf weiß sehr weich, da es sich um ein Photo handelt.
Ich habe hier noch einmal eine Aufnahme des Teils, die ich mit der Webcam gemacht habe.
http://img199.imageshack.us/my.php?image=photolinse8ef.jpg
Jetzt habe ich mir überlegt ob ich dies vielleicht mit Canny Edge machen könnte. Kann ich damit meine Kanten klar und sauber definieren?
-
bei dieser auflösung darfst du nichts erwarten ;), du brauchst dafür ne gute cam (hoche auflösung, wenig rauschen), sonst wird das ganze sehr ungenau bleiben.
edgedetection wird eventuell auch den schatten als kante erkennen.
nimm einfach irgendwas auffälliges, was sich vom rest absetzt, ein knalliges orange z.b.
-
Um die Kante zu entdecken würde ich's mal mit ner Hough-Transformation versuchen. Für den Kreis bietet sich eigentlich ein Matched-Filter an, gerade weil Du den Radius kennst und ein gedrehter Kreis halt immer noch ein Kreis ist.
edit: evtl zuvor schon binarisieren.
-
rapso schrieb:
nimm einfach irgendwas auffälliges, was sich vom rest absetzt, ein knalliges orange z.b.
->Danke, das Teil kann ich nicht ändern, aber vielleicht die Unterlage.
Außerdem ist das Kamerabild ein wenig besser als es auf dem Photo scheint.Jester schrieb:
Hough-Transformation
-> die Hough-Transformation schaut gut aus. Das muss ich mir unbedingt anschauen. Du weisst nicht reinzufällig wo man einen Beispielcode finden kann? Wenn nicht ist auch niocht schlimm. Dann muss ich halt selbst suchen.
-
Kenn die Hough Transformation jetzt nicht, aber lies dir einfach mal was zu den dithering Verfahren durch, automatischer Kontrastausgleich mit nem Graustufenhistogramm, scharfzeichnen mit nem Laplace Filter oder besser noch Sobel Filter.
Ich denke wenn du ein paar von den Dinger am Anfang mal testweise drüber laufen lässt und am ende den SobelFilter drüber jagst solltest du nen ziemlich schafes Bild bekommen, wo alle Details weggeschnitten sind.
Dann kannst du mit Rapsos Vorschlag vom Anfang arbeiten, mit nem kleinen Toleranz Bereich sollte es dann auch bei dieser Auflösung möglich sein.Nachtrag: Mit nem Max/Min Filter kannst du vorher noch das Rauschen entfernen.
-
Nen Beispielcode zur Hough-Trafo hab ich leider grad nicht zur Hand. Aber die ist eigentlich recht einfach zu bauen. Geht übrigens ziemlich analog auch für Kreise.

Aber da Du den Radius kennst ist für Dich vermutlich ein matched Filter besser geeignet.
Vorteil der Houghtrafo ist, daß es ein Verfahren ist, das nach Geradenhaften Strukturen sucht und nicht einzelne Pixel als Kantenpixel identifiziert. Die einzige geradenhafte Struktur in diesem Bild ist das gesuchte Teil. Min-Max-Filterung (also Binarisierung) ist auf jeden Fall sinnvoll!
-
da du ja ein foto machst, wenn ich jetzt alles richtig verstanden habe, dann wäre es eventuell auch sinnvoll die beleuchtung zu korrigieren
schlagschatten ect lassen sich bestimmt so schon vorher verhindern, was die ganze sache erleichtern sollte
-
Danke für diese vielen Antworten, ich glaube für mich gibt es nun wirklich viel zu lesen

-> ...und was die Beleuchung anbetrifft, ich werde immer einen Schatten haben!
-
vielleicht wäre es besser für diese Frage ein neues Thema im im forum zu öffen. Ich stelle sie aber hier rein, da hier die ganzen Filter angesprochen sind.
Ich glaube ich habe den Sobel Filter nicht richtig verstanden.
Nachdem was ich bisher gelesen habe muss ich beim Sobel Filter jedes einzelne Pixel, und die 8 Pixel darum herum mit zwei Filtermatrizen multiplizieren und dann die Summe der in das Pixel in der Mitte schreiben. dies mache ich einmal für die X- und einmal für die Y-Richtung und lege dann die beiden Bilder übereinander.
Danach sollte ich ein Graustufenbild mit den erkannten Kanten erhalten (?????)Bei einer Bitmap ist es doch so, dass ich pro Pixel drei Farbwerte (rot, grün, blau) von 0-255 habe. Heißt das jetzt für mich, dass ich das gerade Beschriebene dreimal, d.h. für jede Farbe, machen muss?
Oder muss ich zurst ein Graustufenbild (wenn es so etwas gibt??) aus meiner Bitmap erzeugen? Ich habe zwar noch nie etwas mit Graustufenbilder gemacht, aber ich könnte mir vorstellen, dass es für so ein Bild nur eine Information pro Pixel gibt und alles viel einfacher wäre.
-
Mach ein Graustufen Bild daraus !
Ich weiss nicht ob der "MedianCut" Algo dafür geeignet ist oder du einfach eine "Graustufenkonvertierung" durchführen solltest.@Graustufen
Ganz einfach, vielleicht mal mit folgenden Werten testen.
z.B. wahrnehmungsorientiert:
Luminanz = 0.299·P.rot + 0.587·P.grün + 0.114·P.blau
Graustufenkonvertierung nach dem NTSC-Standard:
Luminanz = 0.176·P.rot + 0.81·P.grün + 0.011·P.blauOder selber googlen...
Danach noch einen Max oder Min Filter drüber jagen um den Noise wegzubekommen, und immer wieder schaun wie es aussieht.
Dann den Sobel drüber laufen lassen. Weiss grad nicht mehr ob man die 2 Filter hintereinander durchlaufen lassen muss oder ob man beide gleichzeitig drüber jagen kann ...
Anstatt der Max/Min Filter könntest du nochmal nach nem Median Filter suchen, der sollte auch zur NoiseReduktion funktionieren und net soo schwer sein.
PS: Wenn irgendwas schon durchgelaufen ist zeig mal die Ergebnisse, wäre cool !
-
Jester schrieb:
Nen Beispielcode zur Hough-Trafo hab ich leider grad nicht zur Hand. Aber die ist eigentlich recht einfach zu bauen. Geht übrigens ziemlich analog auch für Kreise.

Die Hough-Transformation für Kreise hat den Nachteil, dass sie nur Kreise mit einem bestimmten Radius findet. Wenn du nur knapp daneben liegst, bilden sich die Peaks nicht mehr besonders deutlich heraus; bei größerer Abweichung klappts gar nicht.
-
ChaosAngel schrieb:
PS: Wenn irgendwas schon durchgelaufen ist zeig mal die Ergebnisse, wäre cool !
-> ist versprochen!!!!
Bis es soweit ist, werde ich euch aber noch ein paar mal fragen müssen

das 1. Ergebnis kann ich schon liefern:
http://img85.imageshack.us/my.php?image=schwarzweiss5dc.jpg
ich habe die Graustufenkonvertierung nach dem NTSC-Standard benutzt:
Luminanz = 0.176·P.rot + 0.81·P.grün + 0.011·P.blauIch bin mit der Kamera näher and das Teil herangefahren. Außerdem istist das gezeigte Bild eine eine JPEG Datei und keine Bitmap. Ich bearbeite aber die Bitmap. da ist die Qualität noch viel besser.

-
Bashar schrieb:
Die Hough-Transformation für Kreise hat den Nachteil, dass sie nur Kreise mit einem bestimmten Radius findet. Wenn du nur knapp daneben liegst, bilden sich die Peaks nicht mehr besonders deutlich heraus; bei größerer Abweichung klappts gar nicht.
Ja, aber er sagte, der Radius sei bekannt. Außerdem kann man die Trafo natürlich auch mit variablem Radius durchführen. Ist halt etwas mehr Rechenaufwand. Aber um den Kreis zu finden würde ich eher ein matched-Filter verwenden.
-
ok, ....entweder ich finde keinen passenden Median Filter oder ich bin zu blöd ihn zu verstehen.
Ich zeige euch einmal was ich gemacht habe um mein Graustufenbild zu erzeugen. Vielleicht habe ich auch da schon etwas falsch verstanden, aber es funktioniert:
//---- Schwarz- / Weisbild daraus machen ------------------------------------ for (int i=0; i< 240/*bmih.biHeight*/; i++) { for (int j=0; j< 320/*bmih.biWidth*/; j++) { luminanz = picture[j][i].rgbBlue * 0.299 + picture[j][i].rgbRed * 0.587 + picture[j][i].rgbGreen * 0.114; picture[j][i].rgbBlue = luminanz; picture[j][i].rgbRed = luminanz; picture[j][i].rgbGreen = luminanz; picture[j][i].rgbReserved = 0; } }dies erzeugt mir ein wunderbares s/w-Bild. Vielleicht sollte ich noch erklären, dass in picture [j][i].rgbBlue/Red/Green die jeweiligen Farbwerte für jedes einzelne Pixel stehen. Da ich nun ein Graustufenbild habe sind nun alle drei Werte gleich.
Wer verrät mir nun, wie ich dazu einen Median Filter schreibe?
Oder was sollte ich anders machen?
Ich weiss gerade wirklich nicht weiter.
-
Hab leider grad garkeine Zeit, muss zur Uni, mach mal nur kurz Copy und Paste ausm \1:
Ersetzt den Wert eines Pixel mit dem Median der Werte der Pixel in
der n×n-Nachbarschaft.
-----Shit Formel lässt sich net kopieren ....
Hier mal die Ränge auf dem Bild was hier steht für 3x3
3 8 5
2 4 9
1 7 6So, muss nu los, vielleicht hilft wiki ...
ByeEdit:
Sorry, hab grad Gülle geschrieben !
Du nimmst imho einfach alle Pixel in deiner n x n Umgebung sortierst die Werte der Grösse nach und nimmst das mittlere Element. Lässt sich natürlich optimieren.Desweiteren solltest du für das Filtern vielleicht mit nem 8bit Bild rechnen und net mit 3 mal den selben Wert berechnen für das 24bit Bild.
-
ok,.........wie ich sehe bist du in der Uni angekommen. Bin übrigends schon seit 7.15 in meiner FH.
Wie der Opa schon gesagt hat:Zitat meines Großvaters schrieb:
"Du musst den Feierabend in der Früh suchen,...mein Sohn"
Aber nun zurück zu meinem Problem:
ChaosAngel schrieb:
Desweiteren solltest du für das Filtern vielleicht mit nem 8bit Bild rechnen und net mit 3 mal den selben Wert berechnen für das 24bit Bild.
Ich weiss nicht ob dass geht, wenn ich am Ende meines Progarmes wieder eine Bitmap haben muss. Oder gibt es eine 8 bit Bitmap?
ChaosAngel schrieb:
Du nimmst imho einfach alle Pixel in deiner n x n Umgebung sortierst die Werte der Grösse nach und nimmst das mittlere Element. Lässt sich natürlich optimieren.
Ich nehme an, dass ich diese Matrix um mein Pixel legen muss. Mein Pixel ersetze ich dann durch mein durch das mittlere Element.
-
Jetzt habe ich ein komplett weises Bild. Meiner Meinung habe ich aber genau das gemacht (einmal abgesehen von dem 8 bit Bitmap) was ChaosAngel geschrieben hat.
ich habe mir eine Matrize, 3x3, um das aktuell zu bearbeitende Pixel gelegt und diese dann mit einem Bubblesort sortiert. Den mittleren Wert habe ich dann in das Pixel geschrieben.
for (int y=0; y< 240/*bmih.biHeight*/; y++) { for (int x=0; x< 320/*bmih.biWidth*/; x++) { filterfeldX[x][y] = picture[x][y].rgbRed; // hier habe ich nur Rot genommen, da blau und grün = rot sind } } for (int y=0; y< 240/*bmih.biHeight*/; y++) { for (int x=0; x< 320/*bmih.biWidth*/; x++) { f = 0; for (int my=y-1; my<y+1; my++) { for (int mx=x-1; mx<x+1; mx++) { feld[f]= filterfeldX[mx][my]; f++; } } int temp; for (int i=0; i<8; i++) { for (int j=0; j < 8-i; j++) { if ( feld[j] > feld[j+1]) { temp = feld[j]; feld[j] = feld[j+1]; feld[j+1] = temp; } } } mittelWert = feld[5]; picture[x][y].rgbBlue = mittelWert; picture[x][y].rgbRed = mittelWert; picture[x][y].rgbGreen = mittelWert; } }das Resultat ist ein komplett weises Bild.
Ich hoffe mit dem mittleren Wert wurde nicht der durchschnitt aller Pixel gemeint.
Interessatnt ist, dass wenn ich schreibe mittelWert = feld[0]; dann bekomme ich ein Graustufenbild. Habe ich so einen Min- Filter geschrieben?
Ab dem feld[4] ist das Bild dann komplett weis.
Der Bubbelsort müsste aber richtig funktionieren.
-
1. Ich glaube du greifst auf bereiche zu die nicht zum Bild gehören...
weil du wenn du z.B. in der ersten Spalte bist auf das -1 element zugreifst ... du solltest also schreiben:for (int y=1; y< 240-1/*bmih.biHeight*/; y++) { for (int x=1; x< 320-1/*bmih.biWidth*/; x++) {Das -i macht doch irgendwie alles kaputt ? Wenn das stärkste element ganz vorne ist, sollte es so doch nie bis ganz nach hinten kommen ?
for (int i=0; i<8; i++) { for (int j=0; j < 8-i; j++)Naja ich weiß nicht genau was ein min oder max filter macht, aber könnte es nicht besser sein das ganze in eine "neue" bitmap zu schreiben?
Kann mich bei den Sachen auch irren .. bin nicht so der pro

-
du musst das auf jeden fall in eine neue bitmap schreiben...
stell dir vor:
du machst in der linken oberen 'Ecke mal so ein medianfilter drauf, dann hat die linke obere Ecke ja die Farbe des Medians der n*n Pixel drum herum (bzw. nur n/2 weil es ja die ecke ist). Wenn du jetzt einen Pixel weiter nach rechts gehst und wieder median machst, dann wird ja schon die neue Farbe der linken oberen Ecke verwendet und der median des ixels daneben stimmt gar nicht mehr. Deshalb: aus der einen bm lesen, und in die neue bm schreiben, zum schluss die alte durch die neue erstezten oder auch behalten, wie dus brauchst