Matrix Transformation

Marschal

Großer Enumerator
Hallo Community,

Ich habe ein Problem was in kein Forum so richtig reinpasst, deshalb hab ichs mal im Coders Talk gepostet.

Ausgangspunkt:
(Ich erkläre es prinziepiell ohne zu sehr auf den Kram drum rum einzugehen)

Ich habe eine Kamera, die irgendwie im Raum angeordnet ist. Diese betrachtet eine Projektionsfläche (aus irgendeinem Winkel).
Vllt noch schnell was genau das werden soll. Im Prinziep ein Whiteboard, jedoch nur auf optischer Basis, dh keine touchfläche also, deswegen auch die Kamera.
Somit soll dann (mit einer Lichtquelle z.B.) auf der Projektionsfläche ein optisches Signal erfolgen. dieses Muss die Kamera erfassen (tut sie auch:) ) und in einen (für den Anfang "nur") Mouseklick auf dem mit dem Beamer verbundenen Rechner erfolgen.

Hoffe es ist klar, was ich meine. Hab im Anhang eine einfache Darstellung des Aufbaus.

Mein Problem ist nun folgendes:
Ich brauche eine Mathematische rechen operation, die das (gezerrte Bild, welches die Kammera wahrnimmt, da sie ja irgendwie angeordnet ist) wieder in ein quadratisches (also Bilschirmauflösung) umrechnet.

Ich hatte mir eine 4-Punkt kalibrierung gedacht. Also, man geht mit dem Zeigegerät zur Projektionsfläche und klickt auf die 4 Eckpunkte. Somit erhält man auch vier Koordinaten von der Kamara (nähmlich die, wo die einzelnen Eckpunkte landen). Nach der Kalibrierung muss irgendeine Matrix vorhanden sein (so hab ich mir das gedacht) die dan jeden Beliebigen Punkt auf der Projektionsfläche auf den analogen Punkt auf dem Bildschrim umrechen.

Hier ist also eher ein logisches Problem, programmiert krieg ich das nähmlich, ich hab aber irgendwie Fehler in meinem Ansatz.

Ich würde mich sehr über Diskusion und Anregung freuen.

MfG

EDIT: Zum Bild. Es ist klar, der Beamer stellt ein Recheckiges Bild dar, so wies sein soll, die Kamera sieht jedoch ein ein gezertes Bild, also ein Trapez oder ähnliches. Hoffe es ist klar was gemeint ist, und dass jemand helfen kann:)

EDIT2: Auf dem zweiten Bild habe ich nochmal schematisch dargestellt worum es geht.

MfG
 

Anhänge

  • Untitled.jpg
    Untitled.jpg
    130,3 KB · Aufrufe: 84
  • Unbenannt-1.jpg
    Unbenannt-1.jpg
    837,6 KB · Aufrufe: 109
Zuletzt bearbeitet:

Vereth

Erfahrenes Mitglied
Rein geometrisch betrachtet möchtest du ein allgemeines Ur-Viereck in ein Bild-Viereck umwandeln, das folgende Eigenschaften hat:
  • es hat zwei zueinander parallele Streckenpaare
  • die Streckenpaare haben eine definierte Länge
Gegeben hast du zwei Streckenpaare, die im allgemeinen nicht parallel sind und die paarweise unterschiedliche Längen haben. Jedes dieser Streckenpaare hat dann einen Fluchtpunkt, der nicht im Unendlichen ist. Dann musst du folgende Transformationen ausführen
  1. Rotation um den Fluchtpunkt, damit die Winkelhalbierende parallel zu einer Kante eines Bild-Streckenpaares ist
  2. Trapez-Verzerrung, damit dieses Streckenpaar parallel ist
  3. Scherung, damit die Winkelhalbierende des zweiten Streckenpaares parallel zu einer Kante des anderen Bild-Streckenpaares ist
  4. Trapez-verzerrung, damit das zweite Streckenpaar parallel ist
  5. Skalierung und Translation (Verschiebung), damit das Bild-Viereck die geforderte Größe und Lage hat
Das ist eine sehr anspruchsvolle Problemstellung, und ich wünsche dir viel Erfolg bei der Realisierung.
 

Marschal

Großer Enumerator
Hi, erstmal danke für deine Antwort.

Ich verstehe was du meinst, jedoch glaube ich nicht dass mir das wirklich was bringen würde?!

Ich muss ja nicht nur ein 4-Eck transformieren, sondern auch jeden Punkt proporional korrekt abbilden. Da müsst ich ja ständig neue Berechnungen anstellen.

Gedacht hatte ich mir das so, dass ich irgendwie aus diesen 4 Punkten (Kalibrierung) eine oder auch mehrere Matrizen ausrechne und dann einenbeliebigen Vektor innerhalb des Ur-Bilds mit der Matrix verrchnen kann und dan einen korrekten Bildvektor erhalte. Was mir fehlt ist dieses "irgendwie":)

Ich hatte folgenen Ansatz:

v1 * m1 = v1'

v1 sei eine matrix, bzw ein Vektor (je nach Dimension) der die Input, also Ur-Bild koordinaten (4-Eckpunkte) beinhaltet.
m1 ist die auszurechnende Hypermatrix (beinhaltet 4 2*2 Matrizen, immer eine pro Eckpunkt, der Rest Null)
v1' ist der Vektor, bzw Matrix mit dem Entzerrten Bild, also meine Bildschirm Koordinaten (In meinem Fall die Echpunkte eines 1400*900 4-Ecks)

v1 wird eingelesen von der Kamera, v1' kenn ich auch, m1 ist unbekannt. Das Problem, m1 ist nicht bestimmbar, da beim Aufstellen eines liniaren Gleichungssystems acht Gleichungen mit je 2 Unbekannten entstehen. Auslo nicht lösbar. In meinem Ansatz fehlt irgendwas, was das Ganze lösbar macht.

MfG
 

Vereth

Erfahrenes Mitglied
So einfach kannst du dir das nicht machen.
Deine Punkte, mit denen du arbeitest, sind keine mathematischen Punkte, sondern Pixel, und diese sind examplarische Punkte für als atomar anzusehende Teilflächen deines Gerätes (Bildschirm, Drucker etc.). Die Abbildung ist also nicht bijektiv, weil zwischen den Pixeln im allgemeinen eine m:n-Relation besteht, die außerdem noch gewichtet werden muss, weil nicht jedes Ur-Pixel in Gänze Teil eines Bild-Pixels sein muss. Die oben genannten Transformationsschritte sind voneinander abhängig, weil die Parameter einer Transformation von den Ergebnissen der vorherigen beeinflußt wird. Die Verknüpfung ist also nicht assoziativ, was bei einer Matrixmultiplikation der Fall sein müsste. Das ist deswegen so, weil Matrizen nur für affine Abbildungen geeignet sind, aber z.B. die Trapez-Transformation ist nicht affin.
 

Marschal

Großer Enumerator
Hört sich (theoretisch) gut an was du sagst;)

Ehm Trapetzformation scheint also mein Ansatz zur Problemlösung zu sein.

Zu den Pixeln, logisch, meine Bildschirm Koordinaten sind pixel, die der Kamera jedoch auch (auch wenns eine andere Auflösung ist, ist aber egal).
Gut, dass das mit der Matrix nicht klappt ist mir schon irgendwie aufgefallen:) Klar, dass nicht jedes Pixel transformiert werden kann, doch das kann ja aproximiert werden, die leichte toleranz lässt sich verkraften.

Mein mathe Dok hat mir was von Clustertn erzählt. ich müsse immer Kleine Cluster Transformieren, doch das ginge laut einer Vorstellung mit Hilfe einer Matrix, was ja nicht geht, wie die Praxis zeigt.

Könntest du deine Theorie etwas exemplarischer ausformulieren? Wäre dir sehr dankbar dafür. Ich schau mal, was ich zu den von dir genannten Begriffeim Netz finden kann.

Danke für die Hilfe auf alle Fälle:)

MfG
 

Vereth

Erfahrenes Mitglied
Ich habe dir hier mal ein Bildchen gemacht, das dir die Resultate der einzelnen Schritte veranschaulicht. Die Genauigkeit ist nicht besonder hoch, aber es dürfte dir einen passenden Eindruck vermitteln, wie so etwas aussehen könnte.
 

Anhänge

  • Transfo.jpg
    Transfo.jpg
    8,7 KB · Aufrufe: 75

Marschal

Großer Enumerator
Vielen Dank ersteinaml für deine Hilfe. Ich weis zwar noch nicht wie man das umsetzen könnte, werd aber mein bestes geben:)

Ich denke mal, wir sprechen uns montag nochmal;)
 

lui7172

Mitglied
Mal so einfach gebrainstormt;
Wenn Du eine 5-Punkt-Kalibrierung durchführst, alle vier Ecken plus Mitte, dann erhälst Du für jeden Quadranten einen Streckungsfaktor für x und y, anhand dessen Du jede Position umrechnen kannst.Den Mittelpunkt des Rechteckes würde ich auf 0/0 setzen. So lange es sich nur um (lineare) Streckung und Stauchung handelt sollte das doch ausreichen? Bei Rotation wird es aufwendiger.

Sicher bin ich mir nicht, ist alles so lange her :) Aber vlt. ein einfacher Ansatz.
 

Marschal

Großer Enumerator
Nun, schau mal, wp ist da der unterschied. 4 Kalibrirungspunkte -> ich erhalte ein Viersck, velches (nur mal theoretisch) transformiert werden muss.

5 Kalibrierungspunkte -> ich erhalte 4 vierecke, bei denen ich für jedes das gleiche tun muss.

Num wenn man deine Idee vprtführt, dann müsste man immer mehr und mehr vier-Ecke nehmen, was den Rechenaufwand, die zeit die benötigt wird, so wie die Rechenleistung exponential in die Höhe schießen lässt - wenn man ein gescheites halbwegs präzises ergebniss erhalten will.

Ich fäd halt auch eine Lösung schön, bei der nur einmal, Beispielsweise bei der Kalibrierung, die ganze Rechnerei erfolgt, danach immer nur noch jeder Punkt einzeln (nicht mehr rechenaufwändig) transformiert werden kann. Bei deine Idee hieße dass, ich muss für jeden Punkt immer wieder alles neu berechnen.

Aber trotzdem danke;)

So langsam kommen hier ja Ideen;) Ich würde mich freuen, wenn wir das hier zu einer schönen Diskussionsrunde ausweiten könnten, vllt hab ich ja dank vieler verschiedenen und kreativen Ideen irgendwann einen Einfall, wie man das Problem schön und elegant realisieren könnte:)

MfG

EDIT: Eigentlich garnicht übel deine Idee, ich glaube jetzt weis ich was mein Mathe Doktor Ingeneur so meinte mit den Clustern;)
Ich breauch den Punkt in der Mitte doch garnicht. Ich kann doch einfach die zwei Diagonalen kreuzen lassen, da das ein liniares Verhältniss ist, kommt auch immer ein Schnittpunkt, und zwar genau der Mittelpunkt dabei raus;)

Mal sehen, vllt kann man das ja erst einmal für eine Beta-Version so programmieren, wird auffwändig werden;)

EDIT2: Ach du sch***e, da erhalte ich ja Datenmengen von gigantischem Ausmaß;) Gut, dass ich 4GB Ram und nen zwei Kern habe:p
 
Zuletzt bearbeitet:
Hi,

du suchst die über vier Bild-/Urbild-Punktpaare eindeutig festgelegte projektive Abbildung. Seien A, B, C und D die Urbildpunkte (Eckpunkte auf dem verzerrten Kamerabild), A', B', C' und D' die entsprechenden Bildpunkte, alle in homogenen Koordinaten[1]. Bestimme nun die Lösung der beiden folgenden Gleichungssysteme:
lgs1.png
lgs2.png

Die gesuchte Matrix M der projektiven Abbildung ist dann
ergebnis.png

Einen Punkt P = (x, y) auf dem Kamerabild wandelst dann wie folgt in Bildschirmkoordinaten um:
  1. Erweiterung des Punktes auf homogene Koordinaten (Anhängen einer 1)
  2. Anwendung der Matrix: P' = (x', y', z') = M ? P
  3. Zurückführen auf einen 2D-Punkt: (x' / z', y' / z')

Grüße,
Matthias

[1]: Man erhält man die homogenen Koordinaten eines 2D-Punktes (x, y), indem man ihn durch Anhängen der z-Koordinate 1 in einen 3D-Punkt (x, y, 1) umwandelt.