首頁 >web前端 >js教程 >抖音很火紅的圖片選擇題特效,用前端快速實現!

抖音很火紅的圖片選擇題特效,用前端快速實現!

藏色散人
藏色散人轉載
2023-01-20 15:56:353584瀏覽

這篇文章為大家帶來了關於前端圖片特效的相關知識,其中主要給大家介紹前端如何實現一個最近抖音很火的圖片選擇題特效,非常全面詳細,下面一起來看一下,希望對需要的朋友有幫助。

抖音很火紅的圖片選擇題特效,用前端快速實現!

抖音很火紅的圖片選擇題特效,用前端快速實現!

金塊因安全原因沒有在iframe標籤上設定allow="microphone *;camera *"導致攝影機打開失敗!請點擊右上角「查看詳情」查看!或點選下方連結查看

//复制链接预览
https://code.juejin.cn/pen/7160886403805970445

前言

最近抖音特效中有個圖片選擇題特別火,今天就來講一下前端如何實現,下面我主要講一下如何判斷左右擺頭

架構與概念

抽象整體的實作想法如下

抖音很火紅的圖片選擇題特效,用前端快速實現!

#MediaPipe Face Mesh是一個解決方案,即使在行動裝置上也能即時估計468個3D臉部地標。它使用機器學習(ML)來推斷3D面部表面,只需要一個相機輸入,而無需專用的深度感測器。該解決方案利用輕量級模型架構以及整個管道中的GPU加速,為即時體驗提供了至關重要的即時效能。

引入

import '@mediapipe/face_mesh';
import '@tensorflow/tfjs-core';
import '@tensorflow/tfjs-backend-webgl';
import * as faceLandmarksDetection from '@tensorflow-models/face-landmarks-detection';

建立人臉模型

引入tensorflow訓練好的人臉特徵點偵測模型,預測486個3D 人臉特徵點,推論出人臉的近似面部幾何圖形。

  • maxFaces 預設為1。模型將檢測到的最大人臉數量。傳回的臉孔數量可以小於最大值(例如,當輸入中沒有人臉時)。強烈建議將此值設為預期的最大人臉數量,否則模型將繼續搜尋缺少的臉孔,這可能會減慢性能。
  • refineLandmarks 預設為false。如果設定為真,則細化眼睛和嘴唇周圍的地標座標,並在虹膜周圍輸出其他地標。 (這裡我可以設定false,因為我們沒有用到眼部座標)
  • #solutionPath 通往am二進位檔案和模型檔案所在位置的路徑。 (強烈建議將模型放到國內的物件儲存裡面,首次載入可以節省大量時間,大小大概10M)
async createDetector(){
    const model = faceLandmarksDetection.SupportedModels.MediaPipeFaceMesh;
    const detectorConfig = {
        maxFaces:1, //检测到的最大面部数量
        refineLandmarks:false, //可以完善眼睛和嘴唇周围的地标坐标,并在虹膜周围输出其他地标
        runtime: 'mediapipe',
        solutionPath: 'https://cdn.jsdelivr.net/npm/@mediapipe/face_mesh', //WASM二进制文件和模型文件所在的路径
    };
    this.detector = await faceLandmarksDetection.createDetector(model, detectorConfig);
}

抖音很火紅的圖片選擇題特效,用前端快速實現!

人臉辨識

傳回的臉孔清單包含影像中每個臉孔的偵測面。如果模型無法偵測到任何面孔,清單將是空的。 對於每個面,它包含一個偵測到的臉孔的邊界框,以及一個關鍵點陣列。 MediaPipeFaceMesh返回468個關鍵點。每個關鍵點都包含x和y,以及一個名稱。

現在,您可以使用偵測器來偵測人臉。 estimateFaces方法接受多種格式的圖像和視頻,包括:HTMLVideoElementHTMLImageElementHTMLCanvasElementTensor3D

  • flipHorizo​​ntal 可選。預設為false。當影像資料來自相機時,結果必須水平翻轉。
async renderPrediction() {
    var video = this.$refs['video'];
    var canvas = this.$refs['canvas'];
    var context = canvas.getContext('2d');
    context.clearRect(0, 0, canvas.width, canvas.height);
    const Faces = await this.detector.estimateFaces(video, {
        flipHorizontal:false, //镜像
    });
    if (Faces.length > 0) {
        this.log(`检测到人脸`);
    } else {
        this.log(`没有检测到人脸`);
    }
}

抖音很火紅的圖片選擇題特效,用前端快速實現!

該框表示圖像像素空間中臉部的邊界框,xMin、xMax表示x-bounds、yMin、yMax表示y-bounds,寬度、高度表示邊界框的尺寸。 對於關鍵點,x和y表示影像像素空間中的實際關鍵點位置。 z表示頭部中心為原點的深度,數值越小,鍵點離相機越近。 Z的大小使用與x大致相同的比例。 這個名字為一些關鍵點提供了一個標籤,例如“嘴唇”、“左眼”等。請注意,並非每個關鍵點都有標籤。

如何判斷

找到人臉上的兩個兩點

第一個點額頭中心位置第二點下巴中心位置

const place1 = (face.keypoints || []).find((e,i)=>i===10); //额头位置
const place2 = (face.keypoints || []).find((e,i)=>i===152); //下巴位置
/*
              x1,y1
                |
                |
                |
  x2,y2  -------|------- x4,y4
              x3,y3
 */
 const [x1,y1,x2,y2,x3,y3,x4,y4] = [
      place1.x,place1.y,
      0,place2.y,
      place2.x,place2.y,
      this.canvas.width, place2.y
 ];

透過canvas.width 額頭中心位置下巴中心位置計算x1,y1,x2,y2,x3 ,y3,x4,y4

抖音很火紅的圖片選擇題特效,用前端快速實現!

#
getAngle({ x: x1, y: y1 }, { x: x2, y: y2 }){
    const dot = x1 * x2 + y1 * y2
    const det = x1 * y2 - y1 * x2
    const angle = Math.atan2(det, dot) / Math.PI * 180
    return Math.round(angle + 360) % 360
}
const angle = this.getAngle({
        x: x1 - x3,
        y: y1 - y3,
    }, {
        x: x2 - x3,
        y: y2 - y3,
    });
console.log('角度',angle)

抖音很火紅的圖片選擇題特效,用前端快速實現!

通过获取角度,通过角度的大小来判断左右摆头。

推荐:《web前端开发视频教程

以上是抖音很火紅的圖片選擇題特效,用前端快速實現!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.im。如有侵權,請聯絡admin@php.cn刪除