<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          簡(jiǎn)單實(shí)現(xiàn)一個(gè)虛擬形象系統(tǒng)

          共 5424字,需瀏覽 11分鐘

           ·

          2022-12-03 09:53

          術(shù)  堅(jiān)  


          前言

          上周啟動(dòng)居家開會(huì)的時(shí)候,看到有人通過「虛擬形象」功能,給自己帶上了口罩、眼鏡之類,于是想到了是不是也可以搞一個(gè)簡(jiǎn)單的虛擬形象系統(tǒng)。

          大致想來(lái),分為以下幾個(gè)部分:

          卷積神經(jīng)網(wǎng)絡(luò)(CNN)

          下面講解一下三層CNN網(wǎng)絡(luò)模型:

          卷積層——提取特征

          卷積層的運(yùn)算過程如下圖,用一個(gè)卷積核掃完整張圖片:

          通過動(dòng)圖能夠更好的理解卷積過程,使用一個(gè)卷積核(過濾器)來(lái)過濾圖像的各個(gè)小區(qū)域,從而得到這些小區(qū)域的特征值。

          在具體應(yīng)用中,往往有多個(gè)卷積核,每個(gè)卷積核代表了一種圖像模式(特征規(guī)則),如果某個(gè)圖像塊與此卷積核卷積出的值大,則認(rèn)為此圖像塊十分接近于此卷積核。如果有N個(gè)卷積核,那么就認(rèn)為圖像中有N種底層紋理(特征),即用這N種基礎(chǔ)紋理就能描繪出一副圖像。

          總結(jié): 卷積 層的通過卷積核的過濾提取出圖片中局部的特征。

          疑問:上圖卷積后,存在邊緣數(shù)據(jù)特征提取減少,大家能想到什么方式處理呢?

          池化層(下采樣)——數(shù)據(jù)降維,避免過擬合

          池化層通常也被叫做下采樣,目的是降低數(shù)據(jù)的維度,減少數(shù)據(jù)處理量。其過程大致如下:

          上圖輸入時(shí)是20×20的,先進(jìn)行卷積采樣,卷積核為10×10,采用最大池化的方式,輸出為一個(gè)2×2大小的特征圖。這樣可將數(shù)據(jù)維度減少了10倍,方便后續(xù)模塊處理。

          總結(jié):池化層相比 卷積 層可以更有效的降低數(shù)據(jù)維度,不僅可減少運(yùn)算量,還可以避免 過擬合

          過擬合是指訓(xùn)練誤差和測(cè)試誤差之間的差距太大。換句換說,就是模型復(fù)雜度高于實(shí)際問題,模型在訓(xùn)練集上表現(xiàn)很好,但在測(cè)試集上卻表現(xiàn)很差。模型對(duì)訓(xùn)練集"死記硬背"(記住了不適用于測(cè)試集的訓(xùn)練集性質(zhì)或特點(diǎn)),沒有理解數(shù)據(jù)背后的規(guī)律,泛化能力差。

          全連接層——輸出結(jié)果

          全鏈接層是將我們最后一個(gè)池化層的輸出連接到最終的輸出節(jié)點(diǎn)上。假設(shè),上述CNN的最后一個(gè)池化層的輸出大小為 [5×5×4],即 5×5×4=100 個(gè)節(jié)點(diǎn)。對(duì)于當(dāng)前任務(wù)(僅識(shí)別??、??、??),我們的輸出會(huì)是一個(gè)三維向量,輸出層共 3 個(gè)節(jié)點(diǎn),如輸出[0.89, 0.1, 0.001],表示0.89的概率為貓。在實(shí)際應(yīng)用中,通常全連接層的節(jié)點(diǎn)數(shù)會(huì)逐層遞減,最終變?yōu)閚維向量。

          舉個(gè)例子??

          假設(shè)我們有2個(gè)檢測(cè)的特征為「水平邊緣」和「垂直邊緣」。「垂直邊緣」卷積過程如下:

          最終結(jié)果如下:

          Q&A環(huán)節(jié)

          沒錯(cuò)啦,前面的問題的答案就是邊緣填充。

          face-api.js

          face-api.js 是基于 tensorflow.js 實(shí)現(xiàn)的,內(nèi)置了一些訓(xùn)練好的模型,這些模型應(yīng)該是這個(gè)方案的核心,通過這些預(yù)先訓(xùn)練好的模型,我們可以直接使用而不需要自己再去標(biāo)注、訓(xùn)練,極大的降低了成本。

          主要提供的功能如下:

          • 人臉檢測(cè):獲取一張或多張人臉的邊界,可用于確認(rèn)人臉的位置、數(shù)量和大小
          • 人臉特征檢測(cè):包含68個(gè)人臉特征點(diǎn)位,獲取眉毛、眼睛、鼻子、嘴、嘴唇、下巴等的位置和形狀
          • 人臉識(shí)別:返回人臉特征向量,可用于辨別人臉
          • 人臉表情識(shí)別:獲取人臉表情特征
          • 性別和年齡檢測(cè):判斷年齡和性別。其中“性別”是判斷人臉的女性化或男性化偏向,與真實(shí)性別不一定掛鉤

          人臉檢測(cè)

          針對(duì)人臉檢測(cè),face-api 提供了 SSD Mobilenet V1 和 The Tiny Face Detector 兩個(gè)人臉檢測(cè)模型:

          • SSD Mobilenet V1:能夠計(jì)算圖像中每個(gè)人臉的位置,并返回邊界框以及每個(gè)框內(nèi)包含人臉的概率,但是這個(gè)模型有 5.4M,加載需要比較長(zhǎng)的時(shí)間,弱網(wǎng)環(huán)境下加載過于耗時(shí)。
          • The Tiny Face Detector :這個(gè)模型性能非常好,可以做實(shí)時(shí)的人臉檢測(cè),且只有190kB,但是檢測(cè)準(zhǔn)確性上不如 SSD Mobilenet V1,且在檢測(cè)比較小的人臉時(shí)不太可靠。相對(duì)而言,比較適合移動(dòng)端或者設(shè)備資源優(yōu)先的條件下。

          人臉特征檢測(cè)

          針對(duì)人臉特征檢測(cè), 提供了 68 點(diǎn)人臉特征檢測(cè)模型,檢測(cè)這 68 個(gè)點(diǎn)的作用是為了后續(xù)的人臉對(duì)齊,為后續(xù)人臉識(shí)別做準(zhǔn)備,這里提供了兩個(gè)大小的模型供選擇:350kb和80kb,大的模型肯定是更準(zhǔn)確,小的模型適合對(duì)精確度要求不高,對(duì)資源要求占用不高的場(chǎng)景。其輸出的區(qū)域特征點(diǎn)區(qū)間固定如下:

          區(qū)域區(qū)間
          下巴[1, 16]
          左眉[18, 22]
          右眉[23, 27]
          鼻梁[28, 31]
          鼻子[32, 26]
          左眼[37, 42]
          右眼[43, 48]
          外嘴唇[49, 60]
          內(nèi)嘴唇[61, 68]

          人臉識(shí)別

          經(jīng)過人臉檢測(cè)以及人臉對(duì)齊以后,將檢測(cè)到的人臉輸入到人臉識(shí)別網(wǎng)絡(luò)進(jìn)行識(shí)別,從而獲得一個(gè)128維的人臉特征向量。通過計(jì)算兩個(gè)向量之間的距離(余弦值),就可以判斷相似度。

          虛擬形象系統(tǒng)

          獲取人臉圖像

          目前主流瀏覽器提供了WebRTC能力,我們可以調(diào)用getUserMedia方法指定設(shè)備采集音視頻數(shù)據(jù)。其中constrains詳情參考 MediaTrackConstraints - Web APIs | MDN[1]

          const constraints = { audio: true, video: { width: 1280, height: 720 } };
          const setLocalMediaStream = (mediaStream: MediaStream) => {
              videoRef.current.srcObject = mediaStream;
          }
          navigator
              .mediaDevices
              .getUserMedia(constraints)
              .then(setLocalMediaStream)

          獲取人臉特征

          根據(jù)官方文檔介紹,The Tiny Face Detector模型與人臉特征識(shí)別模型組合的效果更好,故本文使用的人臉檢測(cè)模型是The Tiny Face Detector

          這個(gè)模型有兩個(gè)參數(shù)可以調(diào)整,包括 inputSizescoreThreshold,默認(rèn)值是 416 和 0.5。

          • inputSize:表示檢測(cè)范圍(人臉邊框),值越小檢測(cè)越快,但是對(duì)小臉的檢測(cè)準(zhǔn)確不足,可能會(huì)檢測(cè)不出,如果是針對(duì)視頻的實(shí)時(shí)檢測(cè),可以設(shè)置比較小的值。
          • scoreThreshold:是人臉檢測(cè)得分的閾值,假如在照片中檢測(cè)不到人臉,可以將這個(gè)值調(diào)低。
          1. 首先我們要選擇并加載模型(這里使用官網(wǎng)訓(xùn)練好的模型和權(quán)重參數(shù))
          // 加載人臉檢測(cè)模型
          await faceApi.nets.tinyFaceDetector.loadFromUri(
              'xxx/weights/',
          );
          // 加載特征檢測(cè)模型
          await faceApi.nets.faceLandmark68Net.loadFromUri(
              'xxx/weights/',
          );
          1. 轉(zhuǎn)換人臉檢測(cè)模型。face-api的人臉檢測(cè)模型默認(rèn)是 SSD Mobilenet v1,這里需要顯式調(diào)整為The Tiny Face Detector模型。
          const options = new faceApi.TinyFaceDetectorOptions({
            inputSize,
            scoreThreshold,
          });

          // 人臉68點(diǎn)位特征集
          const result = await faceApi
            .detectSingleFace(videoEl, options) // 人臉檢測(cè)
            .withFaceLandmarks(); // 特征檢測(cè)

          形象繪制

          經(jīng)過上述計(jì)算,我們已經(jīng)拿到了人臉68點(diǎn)位特征集。需要先計(jì)算點(diǎn)位相對(duì)坐標(biāo)信息,然后進(jìn)行形象繪制。

          const canvas = canvasRef.current;
          const canvasCtx = canvas.getContext('2d');
          const dims = faceApi.matchDimensions(canvas, videoEl, true);
          const resizedResult = faceApi.resizeResults(result, dims);

          本文使用的是一張256*256的口罩圖片,選取1號(hào)和16號(hào)點(diǎn)位繪制口罩,根據(jù)兩點(diǎn)位之間的距離縮放口罩大小。

          這里主要調(diào)研了兩種方式,分別是canvas繪制和媒體流繪制。

          canvas繪制

          首先想到的一種方式,video和canvas大小和位置固定,定時(shí)抓取video媒體流中圖片,進(jìn)行識(shí)別人臉,然后繪制在canvas上。

          const { positions } = resizedResult.landmarks;
          const leftPoint = positions[0];
          const rightPoint = positions[16];
          const length = Math.sqrt(
              Math.pow(leftPoint.x - rightPoint.x, 2) +
                Math.pow(leftPoint.y - rightPoint.y, 2),
          );
          canvasCtx?.drawImage(
              mask,
              0,
              0,
              265,
              265,
              leftPoint.x,
              leftPoint.y,
              length,
              length,
          );

          媒體流繪制

          canvas提供了一個(gè)api叫做 captureStream[2],會(huì)返回一個(gè)繼承MediaStream的實(shí)例,實(shí)時(shí)視頻捕獲畫布上的內(nèi)容(媒體流)。我們可以在canvas上以固定幀率進(jìn)行圖像繪制,獲取視頻軌道。

          這樣我們僅需保證video和canvas大小一致,位置無(wú)需固定,甚至canvas可以離屏不渲染。

          const stream = canvasRef.current.captureStream()!;
            mediaStream = res[0].clone();
            mediaStream.addTrack(stream.getVideoTracks()[0]);
            videoRef.current!.srcObject = mediaStream;

          對(duì)比

          • canvas繪制兼容性更好,但在實(shí)時(shí)通信場(chǎng)景下,需傳遞點(diǎn)位信息或端重復(fù)計(jì)算,容易受網(wǎng)絡(luò)波動(dòng)以及硬件設(shè)備影響,導(dǎo)致實(shí)際繪制出現(xiàn)偏差(依賴端能力)
          • 媒體流繪制兼容性較差,但是在直播等場(chǎng)景下效果會(huì)更好,在輸出端做好已經(jīng)做好媒體流融合,接收端依托媒體能力播放即可。同時(shí)內(nèi)容也不易篡改

          實(shí)際效果

          因?yàn)檫@里僅使用了2個(gè)點(diǎn)位的信息,所以效果一般般。我們完全可以充分利用68個(gè)點(diǎn)位全面換膚,實(shí)現(xiàn)各種效果。

          延伸思考

          1. 測(cè)評(píng)場(chǎng)景下:判斷人臉數(shù)量、是否是用戶本人,自動(dòng)提醒用戶,異常狀態(tài)記錄日志,監(jiān)控人員可以后臺(tái)查看
          1. 學(xué)習(xí)場(chǎng)景下:判斷用戶是否離開屏幕等,提醒用戶返回學(xué)習(xí)狀態(tài)。
          1. 彈幕場(chǎng)景下:檢測(cè)人臉,解決彈幕遮擋問題

          ...(歡迎補(bǔ)充)

          ?? 謝謝支持

          以上便是本次分享的全部?jī)?nèi)容,希望對(duì)你有所幫助^_^

          喜歡的話別忘了 分享、點(diǎn)贊、收藏 三連哦~。


          從零搭建全棧可視化大屏制作平臺(tái)V6.Dooring

          從零設(shè)計(jì)可視化大屏搭建引擎

          Dooring可視化搭建平臺(tái)數(shù)據(jù)源設(shè)計(jì)剖析

          可視化搭建的一些思考和實(shí)踐

          基于Koa + React + TS從零開發(fā)全棧文檔編輯器(進(jìn)階實(shí)戰(zhàn)




          點(diǎn)個(gè)在看你最好看


          瀏覽 68
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲精品久久久久蜜桃 | 综合久久黄色 | 精品国产一区二区有限公司 | 蜜臀av秘 一区二区三区 | 欧美天天干天天女人 |