成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

簡單實現一個虛擬形象系統

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

本文為來自 字節教育-成人與創新前端團隊 成員的文章,已授權 ELab 發布。

?前言?

上周啟動居家開會的時候,看到有人通過「虛擬形象」功能,給自己帶上了口罩、眼鏡之類,于是想到了是不是也可以搞一個簡單的虛擬形象系統。

大致想來,分為以下幾個部分:

圖片

?卷積神經網絡(CNN)?

下面講解一下三層CNN網絡模型:

圖片

卷積層——提取特征

卷積層的運算過程如下圖,用一個卷積核掃完整張圖片:

圖片

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

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

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

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

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

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

圖片

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

總結:池化層相比 卷積 層可以更有效的降低數據維度,不僅可減少運算量,還可以避免 過擬合 。

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

圖片

全連接層——輸出結果

全鏈接層是將我們最后一個池化層的輸出連接到最終的輸出節點上。假設,上述CNN的最后一個池化層的輸出大小為 [5×5×4],即 5×5×4=100 個節點。對于當前任務(僅識別??、??、??),我們的輸出會是一個三維向量,輸出層共 3 個節點,如輸出[0.89, 0.1, 0.001],表示0.89的概率為貓。在實際應用中,通常全連接層的節點數會逐層遞減,最終變為n維向量。

舉個例子

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

圖片

最終結果如下:

圖片

Q&A環節

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

圖片

?face-api.js?

face-api.js 是基于 tensorflow.js 實現的,內置了一些訓練好的模型,這些模型應該是這個方案的核心,通過這些預先訓練好的模型,我們可以直接使用而不需要自己再去標注、訓練,極大的降低了成本。

主要提供的功能如下:

  • 人臉檢測:獲取一張或多張人臉的邊界,可用于確認人臉的位置、數量和大小
  • 人臉特征檢測:包含68個人臉特征點位,獲取眉毛、眼睛、鼻子、嘴、嘴唇、下巴等的位置和形狀
  • 人臉識別:返回人臉特征向量,可用于辨別人臉
  • 人臉表情識別:獲取人臉表情特征

性別和年齡檢測:判斷年齡和性別。其中“性別”是判斷人臉的女性化或男性化偏向,與真實性別不一定掛鉤

人臉檢測

針對人臉檢測,face-api 提供了 SSD Mobilenet V1 和 The Tiny Face Detector 兩個人臉檢測模型:

SSD Mobilenet V1:能夠計算圖像中每個人臉的位置,并返回邊界框以及每個框內包含人臉的概率,但是這個模型有 5.4M,加載需要比較長的時間,弱網環境下加載過于耗時。

The Tiny Face Detector :這個模型性能非常好,可以做實時的人臉檢測,且只有190kB,但是檢測準確性上不如 SSD Mobilenet V1,且在檢測比較小的人臉時不太可靠。相對而言,比較適合移動端或者設備資源優先的條件下。

人臉特征檢測

針對人臉特征檢測, 提供了 68 點人臉特征檢測模型,檢測這 68 個點的作用是為了后續的人臉對齊,為后續人臉識別做準備,這里提供了兩個大小的模型供選擇:350kb和80kb,大的模型肯定是更準確,小的模型適合對精確度要求不高,對資源要求占用不高的場景。其輸出的區域特征點區間固定如下:

區域

區間

下巴

[1, 16]

左眉

[18, 22]

右眉

[23, 27]

鼻梁

[28, 31]

鼻子

[32, 26]

左眼

[37, 42]

右眼

[43, 48]

外嘴唇

[49, 60]

內嘴唇

[61, 68]

圖片

人臉識別

經過人臉檢測以及人臉對齊以后,將檢測到的人臉輸入到人臉識別網絡進行識別,從而獲得一個128維的人臉特征向量。通過計算兩個向量之間的距離(余弦值),就可以判斷相似度。

圖片

圖片

?虛擬形象系統?

獲取人臉圖像

目前主流瀏覽器提供了WebRTC能力,我們可以調用getUserMedia?方法指定設備采集音視頻數據。其中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)

獲取人臉特征

根據官方文檔介紹,The Tiny Face Detector?模型與人臉特征識別模型組合的效果更好,故本文使用的人臉檢測模型是The Tiny Face Detector。

這個模型有兩個參數可以調整,包括 inputSize? 和 scoreThreshold,默認值是 416 和 0.5。

  • inputSize:表示檢測范圍(人臉邊框),值越小檢測越快,但是對小臉的檢測準確不足,可能會檢測不出,如果是針對視頻的實時檢測,可以設置比較小的值。
  • scoreThreshold:是人臉檢測得分的閾值,假如在照片中檢測不到人臉,可以將這個值調低。

首先我們要選擇并加載模型(這里使用官網訓練好的模型和權重參數)

// 加載人臉檢測模型
await faceApi.nets.tinyFaceDetector.loadFromUri(
'xxx/weights/',
);
// 加載特征檢測模型
await faceApi.nets.faceLandmark68Net.loadFromUri(
'xxx/weights/',
);

轉換人臉檢測模型。face-api的人臉檢測模型默認是SSD Mobilenet v1?,這里需要顯式調整為The Tiny Face Detector模型。

const options = new faceApi.TinyFaceDetectorOptions({
inputSize,
scoreThreshold,
});

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

形象繪制

經過上述計算,我們已經拿到了人臉68點位特征集。需要先計算點位相對坐標信息,然后進行形象繪制。

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號和16號點位繪制口罩,根據兩點位之間的距離縮放口罩大小。

圖片

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

canvas繪制

首先想到的一種方式,video和canvas大小和位置固定,定時抓取video媒體流中圖片,進行識別人臉,然后繪制在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提供了一個api叫做 captureStream[2],會返回一個繼承MediaStream的實例,實時視頻捕獲畫布上的內容(媒體流)。我們可以在canvas上以固定幀率進行圖像繪制,獲取視頻軌道。

圖片

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

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

對比

canvas繪制兼容性更好,但在實時通信場景下,需傳遞點位信息或端重復計算,容易受網絡波動以及硬件設備影響,導致實際繪制出現偏差(依賴端能力)

媒體流繪制兼容性較差,但是在直播等場景下效果會更好,在輸出端做好已經做好媒體流融合,接收端依托媒體能力播放即可。同時內容也不易篡改

?實際效果?

因為這里僅使用了2個點位的信息,所以效果一般般。我們完全可以充分利用68個點位全面換膚,實現各種效果。

?延伸思考?

測評場景下:判斷人臉數量、是否是用戶本人,自動提醒用戶,異常狀態記錄日志,監控人員可以后臺查看

學習場景下:判斷用戶是否離開屏幕等,提醒用戶返回學習狀態。

彈幕場景下:檢測人臉,解決彈幕遮擋問題

責任編輯:武曉燕 來源: ELab團隊
相關推薦

2019-12-11 10:45:08

Python 開發編程語言

2018-09-18 10:11:21

前端vue.jsjavascript

2021-07-20 10:30:46

Golanghttp語言

2016-11-08 18:53:08

編譯器

2011-04-08 10:29:04

AccessMIS管理系統

2016-09-21 12:54:10

CAAS系統鏡像

2020-06-04 12:55:44

PyTorch分類器神經網絡

2024-05-07 09:02:47

2021-01-28 07:21:13

算法虛擬DOM前端

2023-03-01 09:39:40

調度系統

2021-05-20 07:56:35

Bean容器Spring

2019-06-27 09:50:49

高性能秒殺系統

2023-02-27 09:31:00

streamlitst.sidebar菜單

2021-01-26 10:33:45

前端開發技術

2022-01-26 16:30:47

代碼虛擬機Linux

2011-03-24 09:34:41

SPRING

2011-09-08 13:41:53

Widget

2022-09-19 08:01:45

數據庫SQLitePostgreSQL

2022-10-21 14:21:46

JavaScript筆記技能

2022-12-29 12:06:28

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: h视频免费看 | 成人小视频在线观看 | 国产一区二区三区久久 | 欧美一区二区 | 久久久一 | 国产色婷婷精品综合在线播放 | 在线播放亚洲 | 中文字幕国产一区 | 免费亚洲成人 | 国产精品久久777777 | 欧美日韩一区二区在线 | 亚洲视频国产视频 | 久久亚洲一区二区三区四区 | 色资源站| 日韩免费视频 | 射欧美 | 成人精品久久久 | 国产一区久久精品 | 天天操,夜夜爽 | 久久精品一区 | 亚洲444kkkk在线观看最新 | 国产精品一区三区 | 久久婷婷国产香蕉 | 91在线看片| 秋霞在线一区 | 美女天堂av| 99久久亚洲 | 欧美精品网站 | a网站在线观看 | 精产国产伦理一二三区 | 久久久久久美女 | 精品国产乱码久久久久久闺蜜 | 亚洲协和影视 | 成人免费视频久久 | 中文字幕亚洲精品在线观看 | 一区二区影院 | 中文字幕日韩欧美一区二区三区 | 亚洲精品一区二区三区蜜桃久 | 日日操日日干 | 日韩精品一区二区三区免费观看 | 亚洲免费网 |