Tipografi ile Etkileşim İçin Yüz Hareketi Nasıl Kullanılır?

Yayınlanan: 2022-03-10
Kısa özet ↬ Bu makalede, yakınlığa, eğime ve kullanıcı yüzlerinin sayısına yanıt veren düzenler oluşturmak için Makine Öğrenimi, değişken yazı tipleri ve CSS ızgaralarının nasıl birleştirileceğini ele alacağız.

Web tasarımcıları her zaman bir sayfanın içeriğinin sunumunu iyileştirmenin yeni yollarını ararlar. Bazen bu, dahiyane çözümlere veya genellikle tasarım alanından uzak tutulan teknolojilerle etkileşime yol açabilir. Bu makalede, metnin okunabilirliğini iyileştirmek için kullanıcının yüzünün yakınlığı gibi şeyleri algılamak için makine öğrenimini kullanarak tipografiyi Yapay Zeka ile ilişkilendireceğiz.

Ekran ile kullanıcının yüzü arasındaki mesafe veya sayfayı okuyan kişi sayısı gibi bazı bilgileri kameradan çıkarmak için Tensorflow ile yüz tanımanın nasıl kullanılacağını deneyeceğiz. Ardından, tipografiyi uyarlamak ve sayfa düzenini ayarlamak için bu verileri CSS'ye aktaracağız.

Tensorflow Nedir?

Tensorflow, Google'ın Makine Öğrenimi için sunduğu açık kaynaklı bir platformdur. Makine Öğrenimi, görüntülerden, ses parçalarından, zaman serilerinden, doğal metinlerden ve genel olarak verilerden karmaşık ilişkileri ve yinelenen kalıpları tanımayı öğrenen algoritmaları inceleyen bir Bilgisayar Bilimi alanıdır. Bu algoritmalar, girdi verilerine dayalı kararlar vermek için kullanılabilecek bir tür şema olan matematiksel modeller (eğitilmiş modeller olarak da adlandırılır) üretir. Konuya yaklaşmak isterseniz, Charlie Gerard, Smashing Mag'de ön uç geliştiriciler için ML hakkında yazdı.

Tensorflow, AI geliştiricileri, veri bilimcileri, matematikçiler için birçok araç sağlar, ancak veri analizi günlük ekmeğiniz değilse panik yapmayın! İyi haber şu ki, tıpkı bizim yapacağımız gibi, önceden oluşturulmuş modelleri kullandığınız sürece, kullanmak için uzman olmanıza gerek yok.

Tensorflow modelleri, JavaScript SDK'ları ile Web'de kullanılabilir.

Kurmak

Yüz tanıma algoritmalarını kullanmaya başlamak için birkaç adımı izlememiz gerekiyor:

  • Tensorflow SDK'yı yükleyin.
  • matematiksel modeli içeren Facemesh kitaplığını yükleyin.
  • kullanıcının kamerasına erişin ve onu bir HTML video öğesine aktarın. Facemesh, yüzlerin varlığını algılamak için video etiketindeki kareleri analiz eder.

Bu projelerde Tensorflow'u CDN aracılığıyla kullanacağız, ancak paketleyici yolunu tercih ederseniz NPM'de de mevcut:

 <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 hileyi kendisi yapmaz, bu nedenle ML çerçevesinin üzerine inşa edilmiş ve yüz tanıma için önceden eğitilmiş bir model sağlayan bir kitaplık olan Facemesh'i eklememiz gerekiyor:

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

Bir sonraki adım, eğitilmiş modeli yüklemek ve bir video akışından yüz verilerini değerlendirecek işlevi tanımlamak için Facemesh kitaplığını kurmaktır:

 // 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); }

Artık kullanıcıdan bir video etiketi kullanarak kamera akışına erişim izni istemeye hazırız:

 // 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();

navigator.mediaDevices.getUserMedia yöntemi izin ister ve kamerayı video öğesine aktarmaya başlar. Kabul edildiğinde, kamera video etiketine akış yapmaya başlarken tarayıcı konsolu Facemesh tarafından algılanan yüz bilgilerini günlüğe kaydeder.

Lütfen kamera izinlerinin güvenli bir https bağlantısı veya yerel ana bilgisayar gerektirdiğini unutmayın: index.html dosyasını basitçe açamazsınız. Düğüm için yerel bir sunucu satın alma http sunucusunu nasıl kuracağınızdan emin değilseniz veya Python için bu kılavuzu veya PHP için bu kılavuzu izleyin.

Atlamadan sonra daha fazlası! Aşağıdan okumaya devam edin ↓

Durum 1. Akıllı Telefon Kamerasını Kullanarak Tipografiyi Ayarlayın

Akıllı telefonumuzla internette her yerde geziniyoruz. Çok uzun olmayan bir zaman önce, kalabalık trenlere veya otobüslere bindiğimiz ve yer olmadığı için akıllı telefonu gözümüze çok yakın tuttuğumuz bir zaman vardı. Günümüzün birçok anında ve yerinde, aynı siteyi izliyor olsak bile, akıllı telefonun konumunu ve eğimini sık sık değiştiriyoruz. Gözler ve akıllı telefon arasındaki mesafe okuma yeteneklerimizi etkiler. Bu mesafeyi değerlendirerek, daha yakın veya daha uzak bir okuma için glifleri optimize etmek amacıyla mikrotipografiyi ayarlayabiliriz.

Yüz algılama, elbette, gözlerin konumunu da algılama anlamına gelir. Facemesh tarafından sağlanan verileri, kamera tarafından çekilen resmin tamamıyla ilgili olarak yüzümüzün boyutunu hesaplamak için kullanabiliriz. Yüzümüz ne kadar büyükse ekrana o kadar yakın olduğumuzu varsayabiliriz. 0'dan (bir kol uzakta - yüz kameranın yaklaşık yarısını kaplar) 1'e (ekrana yapıştırılmış) bir ölçek ayarlayabilir ve segmentlerin bölünmesiyle mevcut değeri tespit edebiliriz:

 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); }
Kullanıcının yüzünün bölümlere göre temsili, ekranın ne kadar alanının yüz tarafından kaplandığını belirtmek için bir akıllı telefonun çerçevesine yerleştirilir.
Facemesh tarafından tespit edilen göz, burun ve ağzın konumu ve eğimi gibi özelliklere iki örnek. Akıllı telefon kamerasına olan yakınlığı hesaplamak için noktalar arasındaki alanı kullanabiliriz. (Büyük önizleme)

Şimdi ratio hesapladığımıza göre, değeri stil sayfasına ileterek biraz sihir yapmanın zamanı geldi:

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

Bu değer ve biraz kireç ile yazı tipi ağırlığına, boyutuna ve belki stiline kolayca küçük değişiklikler uygulayabiliriz, ancak daha da iyi bir şey yapabiliriz. Gliflerin şekillerini ve boşluklarını parametreli hale getiren bir font olan değişken bir font kullanarak, optik boyut varyasyonunu güncelleyerek her glifin algısını ayarlayabiliriz.

Her değişken yazı tipi optik boyut değerleri için kendi ölçeğini kullandığından, oran değerimizi o ölçekle ilişkilendirmemiz gerekir. Ayrıca, sadece küçük iyileştirmeler sağlamak için mevcut optik boyutun bir alt kümesi arasında hareket etmek isteyebiliriz.

 .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); }

Burada canlı olarak görebilirsiniz. Lütfen bu örneğin teknolojinin nasıl çalıştığının bir gösterimi olduğunu unutmayın. Gerçekten daha iyi bir okuyucu deneyimi sağlamak için tipografik değişiklikler kullanıcının gözünde neredeyse algılanamaz olmalıdır. Burada glif şekillerinden yararlandık, ancak kontrastları artırmak veya azaltmak için renkleri kullanmak, denenecek başka bir iyi çözümdür. Başka bir deney, okumanın perspektifini hesaplamak için yüzün açısını tespit etmekti, yükselenleri, inenleri ve harflerin yüksekliğini değiştirerek:

Edoardo Cavazza'nın kalemine [Yüz ve yükselenler/inenlere](https://codepen.io/smashingmag/pen/oNxrYop) bakın.

Edoardo Cavazza'nın Pen Facemesh ve yükselen/inenlere bakın.

Vaka #2: Bakan Kişi Sayısı Değiştiğinde Düzeni Ayarlama

Bu ikinci durumda, ekranı izleyen kişi sayısına göre düzeni değiştireceğiz. Bir lise sınıfı bağlamında Etkileşimli Beyaz Tahta üzerinde görüntülenen bir makale hayal edebiliriz. İzleyen öğrenci sayısı 10'dan küçük veya daha büyükse sayfanın düzenini ayarlamak istediğimizden, bu senaryo, kullanımdan kaldırılan projeksiyon ortamı sorgusu tarafından algılanandan sessizce farklıdır. Sınıfta yalnızca birkaç öğrenci olduğunda, onlar tahtaya güvenle yaklaşabilir, ancak tüm sınıf mevcutsa, muhtemelen alan yeterli değildir ve düzeni daha az (ve daha büyük) gösterecek şekilde değiştirmemiz gerekir.

Beyaz tahtada izlenen yüzlerin sayısını doğru bir şekilde algılamak için önceki komut dosyasında birkaç değişikliğe ihtiyacımız var. İlk olarak, Facemesh'e birden fazla yüz algılaması için talimat vermemiz gerekiyor:

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

Ardından, bu sayıyı stil sayfasına iletmeliyiz:

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

Yine, bu değeri sadece yazı tipi boyutunu artırmak için kullanabiliriz, ancak amacımız tamamen farklı bir düzen sağlamaktır. CSS ızgara düzenleri bu görevde bize yardımcı olabilir. Bu yansıtılan belge, ilgili görüntüleri içeren bir kenara sahip uzun bir formdur:

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

Ve bu onun varsayılan düzenidir:

 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; }
Sol: 10'dan fazla kişi izlediğinde, mevcut tüm sütunları kullanarak ve görüntüleri metinden sonra taşıyarak ana metne öncelik veriyoruz. Sağda: Etkin Firefox kılavuz denetçisi kılavuzlarıyla 12 sütun kullanan bir sayfa düzeni. 12 sütunun tümü ana metin için, 4'ü de ondan sonraki resimler için kullanılır.
Sol : Sayfanın varsayılan düzeni, uzun biçimli metin için 12 sütundan 8'ini ve resimler için kalan 4 sütunu kullanır. Sağ : 10'dan fazla kişi izlediğinde, mevcut tüm sütunları kullanarak ve görüntüleri metinden sonra hareket ettirerek ana metne öncelik veriyoruz. (Büyük önizleme)

Çok sayıda insan izlediğinde, ana sütuna daha fazla yer vererek, yazı tipi boyutunu büyüterek ve rahatsız edici öğeleri kaldırarak uzun biçimli okuma bağlamına ayrıcalık tanımamız gerekir. Bunu yapmak için, yayılmış sütunların sayısını artırarak ana metnin altına kaydırıyoruz.

 :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); }
  • Buradan canlı olarak görebilirsiniz →

Viceversa, küçük bir öğrenci grubu tahtanın yanında metni deneyimlediğinde, medya dosyaları ve etkileşimli eylem tetikleyicileri gibi daha fazla ayrıntı verebiliriz.

Yüz Tanıma'nın Ötesinde

Karşılaştığımız durumlar (), düzen veya tipografik kapsamlar için yüz tanıma teknolojisini nasıl kullanabileceğimize dair sadece iki örnektir. Tensorflow, kamera akışını sayfalarımız için değişkenlere dönüştürebilen başka modeller ve kitaplıklar sağlar. Ayrıca, akıllı telefonlarımızda Sensör API'lerini kullanarak yararlanabileceğimiz birçok başka sensör olduğunu da unutmamalıyız: GPS, ivmeölçer, ortam ışığı vb.

Ruh hali, okuma, çalışma ve bilgi arama şeklimizi etkilediğinden, makine öğrenimi ile, kullanıcının ruhuna göre minimal düzenlerden ayrıntılı düzenlere geçmek için kullanıcı ifadelerini de analiz edebiliriz.

Uzun yıllardır duyarlı web tasarımı için CSS Media sorgularını kullanmaya alışkınız. Ancak, görünümün boyutu, kullanıcı deneyiminin değişkenlerinden yalnızca biridir. Son zamanlarda, tercihler prefers-color-scheme ve tercihler prefers-reduced-motion gibi kullanıcı tercihlerine saygı göstermek için tasarlanmış yeni bir tür medya sorgusu tarayıcılara indi. Bu, tasarımcılara ve geliştiricilere web tasarımı uygulamalarında bir adım ileriye gitmenin bir yolunu vererek, web sayfasının yalnızca kullanıcının cihazı yerine tüm ortama uyum sağlamasına olanak tanır. Büyük veri çağında, duyarlı ve uyarlanabilir tasarımın ötesine geçme fırsatımız var. Web sayfalarımız nihayet “ekrandan ayrılabilir” ve kullanıcının küresel deneyiminin bir parçası haline gelebilir. Etkileşim tasarımı tüm bu olasılıkları içerecek, bu nedenle teknoloji ve web tasarımı arasındaki olası kombinasyonları denemeye devam etmek önümüzdeki yıllarda çok önemli olacak.