So verwenden Sie Gesichtsbewegungen, um mit Typografie zu interagieren

Veröffentlicht: 2022-03-10
Kurze Zusammenfassung ↬ In diesem Artikel behandeln wir, wie man maschinelles Lernen, variable Schriftarten und CSS-Raster kombiniert, um Layouts zu erstellen, die auf die Nähe, die Neigung und die Anzahl der Gesichter der Benutzer reagieren.

Webdesigner suchen immer nach neuen Wegen, um die Darstellung des Inhalts einer Seite zu verbessern. Manchmal kann dies zu genialen Lösungen führen oder mit Technologien interagieren, die oft vom Designbereich ferngehalten werden. In diesem Artikel bringen wir Typografie in Kontakt mit künstlicher Intelligenz, indem wir maschinelles Lernen verwenden, um Dinge wie die Nähe des Gesichts des Benutzers zu erkennen, um die Lesbarkeit des Textes zu verbessern.

Wir werden experimentieren, wie man die Gesichtserkennung mit Tensorflow verwendet, um einige Informationen aus der Kamera zu extrahieren, wie z. B. den Abstand zwischen dem Bildschirm und dem Gesicht des Benutzers oder die Anzahl der Personen, die die Seite lesen. Anschließend übergeben wir diese Daten an CSS, um die Typografie anzupassen und das Seitenlayout anzupassen.

Was ist Tensorflow?

Tensorflow ist eine Open-Source-Plattform von Google für maschinelles Lernen. Maschinelles Lernen ist ein Gebiet der Informatik, das Algorithmen untersucht, die lernen, komplexe Zusammenhänge und wiederkehrende Muster aus Bildern, Tonspuren, Zeitreihen, natürlichem Text und Daten im Allgemeinen zu erkennen. Diese Algorithmen generieren mathematische Modelle (auch trainierte Modelle genannt), bei denen es sich um eine Art Schema handelt, das verwendet werden kann, um Entscheidungen auf der Grundlage von Eingabedaten zu treffen. Wenn Sie sich dem Thema nähern möchten, Charlie Gerard hat hier im Smashing Mag über ML für Frontend-Entwickler geschrieben.

Tensorflow bietet viele Tools für KI-Entwickler, Datenwissenschaftler und Mathematiker, aber keine Panik, wenn die Datenanalyse nicht Ihr tägliches Brot ist! Die gute Nachricht ist, dass Sie kein Experte sein müssen, um es zu verwenden, solange Sie vorgefertigte Modelle verwenden, so wie wir es tun werden.

Tensorflow-Modelle können mit ihrem JavaScript-SDK im Web verwendet werden.

Aufstellen

Um mit der Verwendung von Gesichtserkennungsalgorithmen zu beginnen, müssen wir einige Schritte befolgen:

  • Laden Sie das Tensorflow-SDK.
  • Laden Sie die Facemesh-Bibliothek, die das mathematische Modell enthält.
  • Greifen Sie auf die Kamera des Benutzers zu und streamen Sie sie an ein HTML-Videoelement. Facemesh analysiert Frames aus dem Video-Tag, um das Vorhandensein von Gesichtern zu erkennen.

In diesem Projekt werden wir Tensorflow über CDN verwenden, aber es ist auch auf NPM verfügbar, wenn Sie den Bundler-Weg bevorzugen:

 <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-core"></script> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-converter"></script> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-webgl"></script>

Tensorflow macht den Trick nicht selbst, also müssen wir Facemesh hinzufügen, eine Bibliothek, die auf dem ML-Framework aufbaut und ein bereits trainiertes Modell für die Gesichtserkennung bereitstellt:

 <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/facemesh"></script>

Der nächste Schritt besteht darin, die Facemesh-Bibliothek einzurichten, um das trainierte Modell zu laden und die Funktion zu definieren, die Gesichtsdaten aus einem Videostream auswertet:

 // create and place the video const video = document.createElement('video'); document.body.appendChild(video); // setup facemesh const model = await facemesh.load({ backend: 'wasm', maxFaces: 1, }); async function detectFaces() { const faces = await model.estimateFaces(video); console.log(faces); // recursively detect faces requestAnimationFrame(detectFaces); }

Jetzt können wir den Benutzer um die Erlaubnis bitten, mithilfe eines Video-Tags auf seinen Kamerastream zuzugreifen:

 // enable autoplay video.setAttribute('autoplay', ''); video.setAttribute('muted', ''); video.setAttribute('playsinline', ''); // start face detection when ready video.addEventListener('canplaythrough', detectFaces); // stream the camera video.srcObject = await navigator.mediaDevices.getUserMedia({ audio: false, video: { facingMode: 'user', }, }); // let's go! video.play();

Die Methode navigator.mediaDevices.getUserMedia fragt nach der Berechtigung und beginnt, die Kamera in das Videoelement zu streamen. Nach der Annahme beginnt die Kamera mit dem Streamen zum Video-Tag, während die Browserkonsole die von Facemesh erkannten Gesichtsinformationen protokolliert.

Bitte beachten Sie, dass Kameraberechtigungen eine sichere https-Verbindung oder localhost erfordern: Sie können die Datei index.html nicht einfach öffnen. Wenn Sie sich nicht sicher sind, wie Sie einen lokalen Server einrichten, checken Sie den http-Server für Node aus oder folgen Sie dieser Anleitung für Python oder dieser Anleitung für PHP.

Mehr nach dem Sprung! Lesen Sie unten weiter ↓

Fall 1. Passen Sie die Typografie mit der Smartphone-Kamera an

Wir navigieren mit unserem Smartphone überall im Internet. Vor nicht allzu langer Zeit sind wir in überfüllten Zügen oder Bussen gefahren und haben das Smartphone ganz dicht vor die Augen gehalten, weil kein Platz war. In vielen Momenten und an vielen Orten unseres Tages ändern wir oft die Position und Neigung des Smartphones, selbst wenn wir dieselbe Seite ansehen. Der Abstand zwischen Augen und Smartphone beeinflusst unsere Lesefähigkeit. Durch die Bewertung dieser Entfernung können wir die Mikrotypografie anpassen, um Glyphen für eine nähere oder weiter entfernte Lesung zu optimieren.

Gesichtserkennung bedeutet natürlich auch Augenpositionserkennung. Wir können die von Facemesh bereitgestellten Daten verwenden, um die Größe unseres Gesichts im Verhältnis zum gesamten von der Kamera aufgenommenen Bild zu berechnen. Wir können davon ausgehen, dass wir uns umso näher am Bildschirm befinden, je größer unser Gesicht ist. Wir können eine Skala von 0 (ein Arm entfernt – das Gesicht nimmt ungefähr eine Hälfte der Kamera ein) bis 1 (auf den Bildschirm geklebt) aufstellen und den aktuellen Wert mit einer Segmentteilung ermitteln:

 async function detectFaces() { const faces = await model.estimateFaces(video); if (faces.length === 0) { // is somebody out there? return requestAnimationFrame(detectFaces); } const [face] = faces; // extract face surface corners let { bottomRight, topLeft} = face.boundingBox; // calculate face surface size let width = bottomRight[0] - topLeft[0]; let height = bottomRight[1] - topLeft[1]; let videoWidth = video.videoWidth; let videoHeight = video.videoHeight; let adjustWidth = videoWidth / 2; let adjustHeight = videoHeight / 2; // detect the ratio between face and full camera picture let widthRatio = Math.max(Math.min((width - adjustWidth) / (videoWidth - adjustWidth), 1), 0); let heightRatio = Math.max(Math.min((height - adjustHeight) / (videoHeight - adjustHeight), 1), 0); let ratio = Math.max(widthRatio, heightRatio); // recursively detect faces requestAnimationFrame(detectFaces); }
Die Darstellung des Gesichts des Benutzers durch Segmente wird innerhalb des Rahmens eines Smartphones platziert, um anzuzeigen, wie viel Fläche des Bildschirms vom Gesicht eingenommen wird.
Zwei Beispiele für die von Facemesh erkannten Merkmale, wie Position und Neigung von Augen, Nase und Mund. Aus der Fläche zwischen den Punkten können wir die Nähe zur Smartphone-Kamera berechnen. (Große Vorschau)

Nachdem wir nun ratio berechnet haben, ist es an der Zeit, etwas Magie zu bewirken, indem wir den Wert an das Stylesheet übergeben:

 document.documentElement.style.setProperty('--user-distance', ratio);

Mit diesem Wert und ein wenig Berechnung könnten wir leicht leichte Änderungen an der Schriftstärke, -größe und vielleicht auch dem Stil vornehmen, aber wir können noch etwas besser machen. Unter Verwendung einer variablen Schriftart, einer Schriftart, die Formen und Abstände der Glyphen parametrisiert hat, können wir die Wahrnehmung jeder Glyphe anpassen, indem wir ihre optische Größenvariation aktualisieren.

Da jede variable Schriftart ihre eigene Skala für optische Größenwerte verwendet, müssen wir unseren Verhältniswert auf diese Skala beziehen. Darüber hinaus möchten wir möglicherweise nur zwischen einer Teilmenge der verfügbaren optischen Größe wechseln, um nur kleine Verbesserungen bereitzustellen.

 .main-text { --min-opsz: 10; --max-opsz: 15; --opsz: calc(var(--min-opsz) + (var(--user-distance) * (var(--max-opsz) - var(--min-opsz)))); ... font-family: 'Amstelvar', serif; font-variation-settings: 'opsz' var(--opsz); }

Hier könnt ihr es live sehen. Bitte beachten Sie, dass dieses Beispiel nur eine Demonstration der Funktionsweise der Technologie ist. Typografische Änderungen sollten für die Augen des Benutzers fast nicht wahrnehmbar sein, um wirklich ein besseres Leseerlebnis zu bieten. Hier haben wir Glyphenformen genutzt, aber die Verwendung von Farben zum Erhöhen oder Verringern von Kontrasten ist nur eine weitere gute Lösung, die Sie ausprobieren sollten. Ein weiteres Experiment bestand darin, den Winkel des Gesichts zu ermitteln, um die Perspektive des Lesens zu berechnen, indem Oberlängen, Unterlängen und die Höhe der Buchstaben modifiziert wurden:

Siehe den Stift [Facemesh and ascenders/descenders](https://codepen.io/smashingmag/pen/oNxrYop) von Edoardo Cavazza.

Siehe Pen Facemesh und Ober-/Unterlängen von Edoardo Cavazza.

Fall Nr. 2: Anpassen eines Layouts, wenn sich die Anzahl der Personen ändert, die zuschauen

In diesem zweiten Fall ändern wir das Layout basierend auf der Anzahl der Personen, die den Bildschirm betrachten. Wir können uns einen auf dem interaktiven Whiteboard angezeigten Aufsatz im Kontext eines Highschool-Klassenzimmers vorstellen. Dieses Szenario unterscheidet sich deutlich von dem, das von der veralteten Projektionsmedienabfrage erkannt wird, da wir das Layout der Seite anpassen möchten, wenn die Anzahl der zuschauenden Schüler kleiner oder größer als 10 ist. Wenn nur wenige Schüler im Klassenzimmer sind, sie kann sicher an die Tafel herangehen, aber wenn das ganze Klassenzimmer anwesend ist, reicht der Platz wahrscheinlich nicht aus und wir müssen das Layout ändern, um weniger (und größere) Dinge zu zeigen.

Wir brauchen nur ein paar Änderungen am vorherigen Skript, um die Anzahl der Gesichter, die am Whiteboard zusehen, korrekt zu erkennen. Zuerst müssen wir Facemesh anweisen, mehrere Gesichter zu erkennen:

 const model = await facemesh.load({ backend: 'wasm', maxFaces: 30, });

Und dann müssen wir diese Nummer an das Stylesheet übergeben:

 async function detectFaces() { const faces = await model.estimateFaces(video); document.documentElement.style.setProperty('--watching', faces.length); // recursively detect faces requestAnimationFrame(detectFace); }

Auch hier könnten wir diesen Wert verwenden, um einfach die Schriftgröße zu erhöhen, aber unser Ziel ist es, ein völlig anderes Layout bereitzustellen. CSS-Rasterlayouts können uns bei dieser Mission helfen. Dieses projizierte Dokument ist ein langes Formular mit einer Seite, die verwandte Bilder enthält:

 <section> <article> <h1>...</h1> <h2>...</h2> <p>...</p> </article> <aside> <img src="..." alt="..." /> </aside> </section>

Und dies ist das Standardlayout:

 section { display: grid; grid-template-columns: repeat(12, 1fr); grid-column-gap: 1em; width: 120ch; max-width: 100%; padding: 1em; } section article { grid-column: 1 / -5; } section aside { grid-column: 7 / -1; }
Links: Wenn mehr als 10 Personen zuschauen, priorisieren wir den Haupttext, indem wir alle verfügbaren Spalten verwenden und die Bilder nach dem Text verschieben. Rechts: Ein Seitenlayout mit 12 Spalten mit aktiven Firefox Grid Inspector Guides. Alle 12 Spalten werden für den Haupttext verwendet, 4 für Bilder danach.
Links : Das Standardlayout der Seite verwendet 8 von 12 Spalten für den Langtext und die restlichen 4 für Bilder. Rechts : Wenn mehr als 10 Personen zuschauen, priorisieren wir den Haupttext, indem wir alle verfügbaren Spalten verwenden und die Bilder nach dem Text verschieben. (Große Vorschau)

Wenn viele Leute zuschauen, müssen wir den Lesekontext in Langform privilegieren, indem wir der Hauptspalte mehr Platz geben, die Schriftgröße erhöhen und störende Elemente entfernen. Dazu erhöhen wir die Anzahl der überspannten Spalten, indem wir die Seite unter den Haupttext verschieben.

 :root { --watching: 10; } section { /** The maximum number of people watching for the default layout */ --switch: 10; /** The default number of columns for the text */ --text: 8; /** The default number of columns for the aside */ --aside: 4; grid-template-columns: repeat(calc(var(--text) + var(--aside)), 1fr); } section article { /** * Kinda magic calculation. * When the number of people watching is lower than --switch, it returns -2 * When the number of people watching is greater than --switch, it returns -1 * We are going to use this number for negative span calculation */ --layout: calc(min(2, (max(var(--switch), var(--watching)) - var(--switch) + 1)) - 3); /** * Calculate the position of the end column. * When --layout is -1, the calculation just returns -1 * When --layout is -2, the calculation is lower than -1 */ --layout-span: calc((var(--aside) * var(--layout)) + var(--aside) - 1); /** * Calculate the maximum index of the last column (the one "before" the aside) */ --max-span: calc(-1 * var(--aside) - 1); /** * get the max between --layout-span and the latest column index. * -1 means full width * --max-span means default layout */ --span: max(var(--max-span), var(--span)); grid-column-start: 1; grid-column-end: var(--span); }
  • Sie können es hier live sehen →

Umgekehrt, wenn eine kleine Gruppe von Schülern den Text in der Nähe der Tafel erlebt, könnten wir weitere Details angeben, wie z. B. Mediendateien und interaktive Aktionsauslöser.

Jenseits der Gesichtserkennung

Die Fälle, mit denen wir konfrontiert waren () sind nur zwei Beispiele dafür, wie wir die Gesichtserkennungstechnologie für Layout- oder typografische Bereiche verwenden können. Tensorflow bietet andere Modelle und Bibliotheken, die den Kamerastream in Variablen für unsere Seiten umwandeln können. Außerdem sollten wir nicht vergessen, dass es in unseren Smartphones viele andere Sensoren gibt, die wir mit den Sensor-APIs nutzen könnten: GPS, Beschleunigungsmesser, Umgebungslicht usw.

Da die Stimmung die Art und Weise beeinflusst, wie wir lesen, studieren und nach Informationen suchen, können wir mit maschinellem Lernen auch die Ausdrücke der Benutzer analysieren, um je nach Stimmung des Benutzers von minimalen zu detaillierten Layouts zu wechseln.

Seit vielen Jahren sind wir es gewohnt, CSS-Medienabfragen für responsives Webdesign zu verwenden. Die Größe des Viewports ist jedoch nur eine der Variablen der Benutzererfahrung. Kürzlich landete eine neue Art von prefers-reduced-motion , die darauf ausgelegt ist, Benutzerpräferenzen zu berücksichtigen, in den prefers-color-scheme , wie z. Dies gibt Designern und Entwicklern die Möglichkeit, in der Webdesign-Praxis einen Schritt nach vorne zu gehen, sodass sich die Webseite an die gesamte Umgebung anpassen kann, anstatt nur an das Gerät des Benutzers. Im Zeitalter von Big Data haben wir die Möglichkeit, über responsives und adaptives Design hinauszugehen. Unsere Webseiten können endlich „den Bildschirm verlassen“ und Teil der globalen Erfahrung des Benutzers werden. Das Interaktionsdesign wird all diese Möglichkeiten umfassen, daher wird es in den kommenden Jahren entscheidend sein, mit den möglichen Kombinationen zwischen Technologie und Webdesign zu experimentieren.