Suche einen Algorithmus zum entfernen des Fischaugeneffekts
-
Hallo,
wie der Titel berits aussagt, bin ich auf der Suche nach einem Algorithmus zum entfernen des Fischaugeneffekts bei Kamerabildern. Ich denke ihr könnt damit etwas anfangen?
Kann mir da jemand weiterhelfen oder evtl. den Source Code für so eine Korrektur geben? Mir ist nicht geholfen wenn ihr mir jetzt den Namen von ein paar Tools gebt die das machen.
Ich müsste das selbst implementieren, da ich die Korektur von mehreren Bildern pro Stunde automatisiert durchführen muss.
Gruß
Denis
-
Also mit Photoshop geht das sicherlich, und damit kannst du auch Arbeitsabläufe einspeichern und automatisieren, dann musst du das auch nicht immer selbst machen.
-
Ich denke du findest unter dem Stichwort Kamerakalibrierung einige Dinge.
Google spuckte zum Besipiel diese Arbeit aus:
http://www2.inf.fh-rhein-sieg.de/mi/lv/smibi/ss05/stud/klaeser/klaeser_ausarbeitung.pdfVielleicht hilft dir dort der Punkt "Radialverzerrung" weiter..
-
das schlagwort heisst barrel distortion
-
Habt erstmal schönen Dank für eure Antworten!
@Blue5teel
Der Algorithmus auf Seite 7 ist soweit nachvollziehbar, bis auf die Sache mit der Annäherung L(r) mittels der Taylorreihe. Leider verweist er dabei auf eine Quelle sodass ich das nicht nachvollziehen kann. In der Taylorreihe müsste doch auch die Brennweite bei dieser Korrektur mit berücksichtigt werden - oder?Ich bin nach viel Recherche auch auf dieses Dokument gestoßen: http://www.liebsch.gmxhome.de/robo/DSP_Abschlussbericht.pdf
Auf Seite 17 wird auch ein anderer Algorhitmus beschrieben. Ich habe den wie folgt in C# implementiert:double Korrekturfaktor = 0, r = 0, rk = 0.000000208; int x, y, zx, zy, nx, ny; //------------- WebcamBild laden ------------- Bitmap WebcamBild = new Bitmap("C:\\test.jpg"); //WebcamBild kopieren für weitere Verarbeitung Bitmap EntzerrtesBild = new Bitmap(WebcamBild); //------------- Entzerrung ------------- //Bildmittelpunkt berechnen zx = WebcamBild.Width / 2; zy = WebcamBild.Height / 2; //Pixel für Pixel durchgehen for (y = 0; y < WebcamBild.Height; y++) { for (x = 0; x < WebcamBild.Width; x++) { r = Math.Sqrt(Math.Pow((zx-x),2)+Math.Pow((zy-y),2)); //Abstand r zum Bildmittelpunkt Korrekturfaktor = Math.Asin(r / rk) / r / rk; nx = Convert.ToInt32(x * Korrekturfaktor); ny = Convert.ToInt32(y * Korrekturfaktor); EntzerrtesBild.SetPixel(nx, ny, WebcamBild.GetPixel(x, y)); } x = 0; }
Bei der Berechnung des "Korrekturfaktors" erhalte ich aber immer den Wert "NaN" da der Zwischenwert beim Arcussinus nicht zwischen -1 und 1 liegt. Habe ich einen Fehler drin oder kennt noch jemand einen anderen Algorithmus?
Gruß
Denis
-
dein faktor rk ist deutlich groesser als dein bildausmass zu waehlen.
damit erledigt sich auch das:erhalte ich aber immer den Wert "NaN" da der Zwischenwert beim Arcussinus nicht zwischen -1 und 1 liegt
-
Wir groß ich rk wählen muss weiß ich leider nicht. Den Wert dort habe ich mir mal ausgedacht zum probieren. Die Brennweite der Webcam beträgt 22mm. Wie kann ich mir anhand dieser Größe rk brechnen?
-
erweitert man die oberflaeche der kameralinse zu einer kugel, ist die brennweite deren radius rk.
jetzt musst du dir nur noch ueberlegen, wie gross im vergleich dazu dein bild ist, wenn du es auf die oberflaeche der linse projezierst.
-
So ganz durchsteigen tue ich nocht nicht...
Mein Bild hat die Auflösung 1268x950 Pixel. Die Brennweite beträgt 22 mm.
Muss ich da jetzt die 22mm in Pixel umrechnen? Und dieses Ergebnis ist dann mein gesuchtes "rk"?Oder könntest du mir das mal bitte vorrechnen? Die Größen dazu sind ja alle bekannt. Das "r" (Abstand zum Bildmittelpunkt (634,475)) beträgt beim Pixel (0,0) =792 Pixel.
-
Kann mir niemand weiterhelfen?
-
Hilft das weiter?
http://www.markerink.org/WJM/HTML/fishyfaq.htm
http://de.wikipedia.org/wiki/FisheyeIch selber hab danach was im BCB (mit VCL) gemacht.
Gruss
Frank
-
Hmm naja nie so richtig. Mir is noch unklar, wie ich "rk" berechne/umrechne.
hellihjb schrieb ja, dass "rk" der Radius der Kameralinse ist, wenn ich diese zu einer Kugel erweitern würde. Aber die 22mm kann ich ja so nicht in die Formel einsetzen. Er meinte das ich die 22mm ins Verhältnis zur Bild größe setzen soll. Sofern ich das richtig verstanden habe...
Hier ist nochmal der Auszug aus dem PDF inkl. der Formeln:
Das Kamerabild wird als auf einer Kugel, mit Radius rk, liegend interpretiert, von Robotererkennung gelieferte Koordinaten werden anhand dieses Modells in die Ebene projiziert. Dabei wird für jeden Punkt
der Abstand r vom Kameraaufpunkt (Bildmitte) und abhängig davon ein Korrekturfaktor bestimmt. Dieses Modell gibt die Gegebenheiten hinreichend wieder, wenig Verzerrung in der Mitte, zu den Rändern hin zunehmend.Die Korrekturvorschrift ist radialsymmetrisch. Der Abstand r eines Punktes vom Ursprung wird senkrecht auf die Kugel projiziert. Es ergibt sich eine
Bogenlänge L auf der Kugel, die im Verhältinis zu r den Korrekturfaktor ergibt.Korrekturfaktor = arcsin(r/rk)/(r/rk), gibt das Verhältnis L/r an.
rk[x,y] = r[x,y]*Korrekturfaktor, ergibt die korrigierten Koordinaten.
@hellihjb: Könntest du mir das mal bitte genauer erläutern bzw. vorrechnen?
-
Also ich habe schonmal folgende nährungsweise Kalibierung erfolgreich verwendet:
Kappa musste aber von Hand für jedes Objektiv bestimmen. Zum Beispiel unter Verwendung von Karopapier: Solage justieren bis alle Linien, Geraden sind.
-
@Hirsch_H
Danke erstmal für deinen neuen Ansatz.
Ich habe aber noch zwei Fragen dazu:
-
Das r entspricht dem Abstand zum Bildmittelpunkt?
-
In welcher Größenordnung war denn das Kappa bei dir? Ist das ein sehr kleiner oder sehr großer Wert?
-
-
Er meinte das ich die 22mm ins Verhältnis zur Bild größe setzen soll. Sofern ich das richtig verstanden habe...
Du rechnest mit verschiedenen Groessen, naemlich "r" (Abstand vom Mittelpunkt) in Pixel und "rk" (entspricht ungefaehr der Brennweite) in mm. Du musst also eins von beiden ins andere umrechnen.
Die Brennweite ist der Punkt wo sich alle Strahlen treffen, die durch die Oberflaeche der Linse verlaufen. Du kannst also zwischen Schnittpunkt, Bogen und aeusseren Strahlen ein gleichschenkliges Dreieck bilden und die Laenge der fehlenden Kante (als Annaeherung der Bildgroesse auf der Linsenoberflaeche) berechnen. Da der CCD-Sensor aber auch nicht punktfoermig ist, wird das so oder so nur eine Naeherung. Du wirst das tatsaechliche "rk" also nur durch Ausprobieren (Anhand eines geeigneten Testbildes) ermitteln koennen.
-
Denis103 schrieb:
@Hirsch_H
Danke erstmal für deinen neuen Ansatz.
Ich habe aber noch zwei Fragen dazu:
-
Das r entspricht dem Abstand zum Bildmittelpunkt?
-
In welcher Größenordnung war denn das Kappa bei dir? Ist das ein sehr kleiner oder sehr großer Wert?
zu 1) Ja, r ist der Abstand zum Mittelpunkt. Musst halt noch die koordinaten in den Mittelpunkt verschieben.
zu 2) Kappa ist ziemlich klein, um die 1e8 kannste noch multiplizieren um es handhabbar zu machen.
-
-
@ __HIRSCH_H__
Könnte es sein, dass dieser Algorithmus zum erzeugen eines Fischaugeneffektes dient, anstatt ihn zu entfernen? Nach dem Verschieben des Koordinatenursprungs (Bildmitte ist nun (0,0)) und einigen Tests wird der Effekt bei mir immer nur verstärkt, anstatt ihn zu beseitigen. Die Ecken werden also mehr gestaucht als die Mitten der Bildränder. Zum entfernen müsste dies ja genau andersherum sein. Die Ecken bleiben wo sie sind und die Pixel an den Bildränder rücken Richtung Bildzentrum.
-
Versuchs mal mit negativem Kappa
-
@ __HIRSCH_H__
Es lag am Vorzeichen. Bei postiven Kappa zieht er es auseinander und die Kurven werden zu Geraden und bei negativen Kappa erzeugt er diesen Fischaugeneffekt.
Ich bin aber nicht so ganz zufrieden damit, weil das Bild gezogen wird, wodurch Stellen entstehen an denen keine Pixel mehr vorhanden sind. Gibts dafür noch eine Lösung? Vielleicht eine Art Filter?
-
Du berechnest vorwärts? Rechne lieber rückwärts, ähnlich wie beim texture-mapping.
Wenn Du wissen willst welche Farbe an der Stelly (x,y) in deinem Bild sein muß, dann verzerre es fischaugen-mäßig zu (x',y') und schau die Farbe dann im Fischaugenbild nach. Dadurch kriegste für jedes Pixel ne Farbinformation und nicht für manche mehrere und für manche garkeine.