EasyAR in einer 3D-Engine verwenden
Um EasyAR in einer 3D-Engine zu verwenden, müssen das Kamerabild und virtuelle Objekte gerendert werden. Die gerenderten virtuellen Objekte müssen mit dem Kamerabild ausgerichtet sein. Beim Rendern des Kamerabildes stimmen einige Parameter bei der Bilderzeugung und Anzeige möglicherweise nicht überein. Beispielsweise können Position, Ausrichtung, Bildgröße, aspect ratio und andere Parameter der physischen Kamera vom Displaybild abweichen und müssen beim Rendering berücksichtigt werden. Wenn EasyAR in eine nicht unterstützte 3D-Engine integriert werden soll, beachten Sie die folgenden Details besonders.
Padding an den Rändern des Kamerabildes zuschneiden
Das Zuschneiden, Transponieren und Codieren von Bildern erfordert erheblichen Rechenaufwand. Um Rechenaufwand und latency zu reduzieren, werden normalerweise relativ rohe Formate verwendet. Zur einfacheren video encoding werden von physischen Kameras ausgegebene Bilder häufig an Raster wie 8x8, 16x16, 32x32 oder 64x64 ausgerichtet. Wenn beispielsweise auf einigen Telefonen eine Auflösung von 1920x1080 gewählt wird, kann das Ausgabebild 1920x1088 werden, weil 1080 kein Vielfaches von 64 ist.

Dies erfordert, dass diese zusätzlichen Padding-Bereiche beim Rendering entfernt werden. Es gibt mehrere mögliche Ansätze. Einer besteht darin, beim Hochladen des Bildes in den Videospeicher die Breite anzugeben, zum Beispiel in OpenGL mit glPixelStorei(GL_PACK_ROW_LENGTH, ...). Ein anderer besteht darin, die UV-Koordinaten im fragment shader manuell zu berechnen und den überschüssigen Teil beim Sampling aus dem Bild abzuschneiden.
Entsprechend der Bildschirmrotation rendern
Auf Mobiltelefonen ist das von der physischen Kamera aufgezeichnete Bild normalerweise relativ zum Gerätegehäuse fixiert und ändert sich nicht mit der Anzeigeausrichtung des Bildschirms. Änderungen der Gehäuseausrichtung des Telefons beeinflussen jedoch, wie wir oben, unten, links und rechts im Bild definieren. Beim Rendering beeinflusst auch die aktuelle Anzeigeausrichtung des Bildschirms die Richtung des angezeigten Bildes.
Normalerweise muss beim Rendering ein Rotationswinkel des Kamerabildes relativ zur Anzeigeausrichtung des Bildschirms bestimmt werden.
Wenn \(\theta_{screen}\) die Radiant beschreibt, um die das Bildschirmbild relativ zur natürlichen Bildschirmausrichtung im Uhrzeigersinn gedreht ist, \(\theta_{phycam}\) die Radiant beschreibt, um die das Bild der physischen Kamera im Uhrzeigersinn gedreht werden muss, damit es auf einem Bildschirm in natürlicher Ausrichtung korrekt angezeigt wird, und \(\theta\) die Radiant beschreibt, um die das Bild der physischen Kamera im Uhrzeigersinn gedreht werden muss, damit es auf dem aktuellen Bildschirm angezeigt wird.
Für die rückseitige Kamera gilt:
Beispielsweise gilt auf einem Android-Telefon bei Verwendung in natürlicher Ausrichtung: \(\theta_{screen} = 0, \theta_{phycam} = \frac{\pi}{2}\), also \(\theta = \frac{\pi}{2}\).
Für die Frontkamera gilt, wenn nach Abschluss der Rotation horizontal gespiegelt wird:
Anmerkung
Wenn das Bildschirmbild rotiert, muss \(\theta\) sofort im ersten Frame nach der Rotation neu berechnet werden; andernfalls kann die Bildrichtung kurzzeitig falsch sein.
Rendering von Kamerahintergrund und virtuellen Objekten
Beim Rendern virtueller Objekte auf einem Mobiltelefon müssen die virtuellen Objekte mit dem Kamerabild ausgerichtet werden. Dazu müssen render camera und Objekte in einem virtuellen Raum platziert werden, der dem realen Raum vollständig entspricht, und mit demselben field of view und aspect ratio wie die physische Kamera gerendert werden. Die perspective projection transforms des Kamerabildes und der virtuellen Objekte sind fast identisch. Der einzige Unterschied besteht darin, dass der größte Teil der perspective projection transform des Kamerabildes in der physischen Kamera stattfindet, während die perspective projection transform virtueller Objekte vollständig ein Rechenprozess ist.
Im Folgenden werden OpenGL-Konventionen verwendet. Wenn andere Konventionen verwendet werden, ist eine entsprechende Koordinatenachsen-Zuordnung erforderlich. Angenommen, die Achsen des Kamerakoordinatensystems sind wie folgt definiert: Die x-Achse zeigt nach rechts, die y-Achse nach oben und die z-Achse aus dem Bildschirm heraus. Die Achsen des clip coordinate system sind wie folgt definiert: Die x-Achse zeigt nach rechts, die y-Achse nach oben, die z-Achse aus dem Bildschirm heraus, und die w-Achse ist eine virtuelle Achse.
Die perspective projection transform matrix, die zum Rendern des Kamerabildes benötigt wird, lautet:
Dabei gibt flip an, ob das Bild horizontal gespiegelt wird. Der Wert ist 1 bei Spiegelung und 0 ohne Spiegelung. \(\theta\) ist der Rotationswinkel des Bildes im Uhrzeigersinn in Radiant. \(s_x\) und \(s_y\) sind Skalierungsfaktoren für proportional scaling oder proportional filling und ändern sich mit \(\theta\). Diese Transformationsmatrix skaliert zunächst das Kamerabild, rotiert es danach und spiegelt es zuletzt. Beim Rendering sollte ein Rechteck verwendet werden, das den Bildschirm ausfüllt. In OpenGL können die Rechteckscheitel beispielsweise bei \((-1, -1, 0)\), \((1, -1, 0)\), \((1, 1, 0)\) und \((-1, 1, 0)\) platziert werden; die UV-Koordinaten werden an den entsprechenden vier Ecken gesetzt, anschließend wird mit dieser perspective projection matrix gerendert.
Die perspective projection matrix, die zum Rendern virtueller Objekte benötigt wird, lautet:
Dabei sind \(n\) und \(f\) die near clipping- und far clipping-Parameter, die üblicherweise in perspective projection matrices für 3D-Rendering verwendet werden. \(w\) und \(h\) sind Pixelbreite und Pixelhöhe des Kamerabildes. \(f_x\), \(f_y\), \(c_x\) und \(c_y\) sind gängige intrinsische Parameter im Kameramodell, wobei \(f_x\) und \(f_y\) die Brennweiten in Pixeln und \(c_x\) und \(c_y\) die Pixelpositionen des principal point sind. Diese projection matrix führt nacheinander die folgenden Transformationen aus: perspective projection transform der Kameraintrinsics (da im OpenCV-Bildkoordinatensystem die Richtungen der y- und z-Achse dem OpenGL-Kamerakoordinatensystem entgegengesetzt sind, werden zwei Koordinatensystemtransformationen durchgeführt), Transformation vom Bildpixelkoordinatensystem in das Bildrechteck-Koordinatensystem, near clipping- und far clipping-Transformation sowie die perspective projection transform, die beim Rendern des Kamerabildes verwendet wird.
Nach der Vereinfachung ergibt sich:
Aus dem obigen Prozess ist ersichtlich, dass Rendering normalerweise in zwei Durchgängen durchgeführt werden muss: Ein Durchgang rendert das Kamerabild, ein Durchgang rendert die virtuellen Objekte, wobei die virtuellen Objekte über dem Kamerabild liegen.
Einige 3D-Engines stellen die perspective projection matrix durch Parameter wie horizontal field of view und aspect ratio dar. Wenn Rotation und Spiegelung nicht berücksichtigt und die Verschiebung des principal point ignoriert werden, lassen sich diese berechnen: Der horizontale field of view ist \(\alpha=2 arctan{\frac{w}{2 f_x}}\), und das aspect ratio ist \(r=\frac{w}{h}\).
Beachten Sie, dass camera distortion in diesem Prozess nicht berücksichtigt wird, da die camera distortion der meisten aktuellen Mobiltelefone sehr gering ist.