Parallaxeeffekt im Browser mit TensorFlow.js + WASM + Three.js

Erinnern Sie sich, wie Apple iOS7 mit Parallaxeeffekt eingeführt hat? Jetzt kann es direkt im Browser gemacht werden.

Parallaxe Webcam ThreeJs



Alle Laptops und Telefone verfügen jetzt über eine Kamera, sodass Sie Kopf- und Augenpositionen mit Tensoflow-Modellen analysieren können. In einem neuen Artikel zu SIGGRAPH 2020 wird außerdem erläutert, wie Datensätze mit Photogrammetrie für den Parallaxeneffekt geeignet sind.



Wahrscheinlich weiß jeder, dass es eine Tensorflow-Bibliothek für neuronale Netze gibt, die unter den Sprachen Python und Javascript funktioniert. Der Faltungsprozess in neuronalen Netzen ist eine ziemlich schwere Berechnung, die gut parallel ist, und es gibt Versionen nicht nur für die CPU, sondern auch für CUDA für Python und WebGL / WebGPU für Javascript. Es ist lustig, aber wenn Sie nicht über NVidia verfügen, funktioniert der offizielle Build von Tensorflow in Javascript auf dem PC schneller, da es keinen offiziellen Build mit OpenGL-Unterstützung gibt. Glücklicherweise verfügt TF 2.0 über eine modulare Architektur, mit der Sie nur über das Wesentliche nachdenken können und nicht über die Sprache, in der es ausgeführt wird. Es gibt auch Konverter 1.0 -> 2.0.







Derzeit gibt es zwei offizielle Modelle für die Gesichtserkennung: Facemesh und Blazeface. Der erste ist besser für Gesichtsausdrücke und Masken geeignet, der zweite ist schneller und definiert einfach ein Quadrat und charakteristische Punkte wie Augen, Ohren, Mund. Also nahm ich die leichte Version - Blazeface. Warum unnötige Informationen? Im Allgemeinen kann das vorhandene Modell möglicherweise noch weiter reduziert werden, da ich außer der Position der Augen nichts anderes benötige.



Derzeit befinden sich 5 Backends im Browser: CPU, Wasm, Webgl, Wasm-Simd, Webgpu. Die erste CPU ist zu langsam und sollte jetzt auf keinen Fall verwendet werden. Die letzten beiden sind zu innovativ und befinden sich in der Phase der Vorschläge und arbeiten unter Flaggen, sodass Endkunden keine Unterstützung haben. Daher habe ich zwischen zwei gewählt: WebGL und WASM.







Anhand vorhandener Benchmarks können Sie erkennen, dass WASM bei kleinen Modellen manchmal schneller ist als WebGL. Darüber hinaus kann Parallaxe mit 3D-Szenen verwendet werden. Durch Ausführen des WASM-Backends wurde mir klar, dass WASM viel besser funktioniert, da diskrete Laptop-Grafikkarten nicht gleichzeitig neuronale Netze und 3D-Szenen exportieren. Dafür habe ich eine einfache Szene mit 75 Globen in .glb gemacht. Der Link ist anklickbar und es gibt WASM.







Wenn Sie auf den Link geklickt haben, haben Sie wahrscheinlich bemerkt, dass der Browser um Erlaubnis zum Zugriff auf den Camcorder gebeten hat. Die Frage ist: Was passiert, wenn der Benutzer auf Nein klickt? In diesem Fall ist es ratsam, nichts zu laden und auf die Steuerung der Maus / des Kreisels zurückzugreifen. Ich habe die ESM-Version von tfjs-core und tfjs-converter nicht gefunden, also habe ich mich anstelle eines dynamischen Imports für ein ziemlich gruseliges Konstrukt mit der fetchInject-Bibliothek entschieden, bei dem die Reihenfolge, in der die Module geladen werden, eine Rolle spielt.



Kriechkonstruktion
, (Promise.All), , , .

fetchInject([
  'https://cdn.jsdelivr.net/npm/@tensorflow-models/blazeface@0.0.5/dist/blazeface.min.js'
], fetchInject([
  'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-converter@2.0.1/dist/tf-converter.min.js',
  'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@2.0.1/dist/tfjs-backend-wasm.wasm'
], fetchInject([
  'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-core@2.0.1/dist/tf-core.min.js'
]))).then(() => {

  tf.wasm.setWasmPath('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@2.0.1/dist/tf-backend-wasm.min.js');

  //some other code

}




Um die Position des Blicks zu finden, nehme ich den Durchschnitt zwischen den beiden Augen. Und es ist leicht zu verstehen, dass der Abstand zum Kopf aufgrund der Ähnlichkeit der Seiten des Dreiecks proportional zum Abstand zwischen den Augen im Video ist. Die Augenpositionsdaten, die vom Modell stammen, sind ziemlich verrauscht. Bevor ich die Berechnungen durchführte, habe ich sie mit dem EMA (Exponential Moving Average) geglättet:



pos = (1 - smooth) * pos + smooth * nextPos;


Oder anders schreiben:



pos *= 1 - smooth;
pos += nextPos * smooth;


Somit erhalten wir die Koordinaten x, y, z in einem bestimmten sphärischen Koordinatensystem mit dem Zentrum in der Kamera. Darüber hinaus sind x und y durch den Blickwinkel der Kamera begrenzt, und z ist der ungefähre Abstand vom Kopf zum Kopf. Bei kleinen Drehwinkelnsin(α)αso dass x und y als Ecken betrachtet werden können.



pushUpdate({
  x: (eyes[0] + eyes[2]) / video.width - 1,
  y: 1 - (eyes[1] + eyes[3]) / video.width,
  z: defautDist / dist
});


Photogrammetrie



Ziemlich lustiges Datum aus SIGGRAPH 2020 Immersives Lichtfeldvideo mit einer geschichteten Netzdarstellung. Sie haben Bilder speziell gemacht, damit Sie die Kamera in einem bestimmten Bereich bewegen können, der ideal zur Idee der Parallaxe passt. Parallaxenbeispiel.







Hier wird eine 3D-Szene in Ebenen erstellt und auf jede Ebene eine Textur angewendet. Das Gerät, mit dem sie Photogrammetrie erstellt haben, sieht nicht weniger lustig aus. Sie kauften 47 billige Yi 4K-Actionkameras für jeweils 10.000 Rubel und platzierten sie in Form eines Ikosaeders auf der Halbkugel, in dem sich das Dreiecksnetz verdreifacht. Danach wurde alles auf ein Stativ gestellt und die Kameras für die Aufnahme synchronisiert.







Links






All Articles