整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          face-api.js:在瀏覽器中進(jìn)行人臉識(shí)別的Ja

          face-api.js:在瀏覽器中進(jìn)行人臉識(shí)別的JavaScript接口

          自IT Next,作者:Vincent Mühler,機(jī)器之心編譯,參與:Geek AI、張倩。

          本文將為大家介紹一個(gè)建立在「tensorflow.js」內(nèi)核上的 javascript API——「face-api.js」,它實(shí)現(xiàn)了三種卷積神經(jīng)網(wǎng)絡(luò)架構(gòu),用于完成人臉檢測(cè)、識(shí)別和特征點(diǎn)檢測(cè)任務(wù),可以在瀏覽器中進(jìn)行人臉識(shí)別。

          號(hào)外!號(hào)外!現(xiàn)在人們終于可以在瀏覽器中進(jìn)行人臉識(shí)別了!本文將為大家介紹「face-api.js」,這是一個(gè)建立在「tensorflow.js」內(nèi)核上的 javascript 模塊,它實(shí)現(xiàn)了三種卷積神經(jīng)網(wǎng)絡(luò)(CNN)架構(gòu),用于完成人臉檢測(cè)、識(shí)別和特征點(diǎn)檢測(cè)任務(wù)。

          • face-api.js:https://github.com/justadudewhohacks/face-api.js
          • TensorFlow.js:https://github.com/tensorflow/tfjs-core

          像往常一樣,我們將查看一個(gè)簡(jiǎn)單的代碼示例,這將使你能立即通過(guò)短短幾行代碼中的程序包開(kāi)始了解這個(gè) API。讓我們開(kāi)始吧!

          我們已經(jīng)有了「face-recognition.js」,現(xiàn)在又來(lái)了另一個(gè)同樣的程序包?

          如果你閱讀過(guò)本文作者另一篇關(guān)于「node.js」環(huán)境下進(jìn)行人臉識(shí)別的文章《Node.js + face-recognition.js : Simple and Robust Face Recognition using Deep Learning》(Node.js + face-recognition.js:通過(guò)深度學(xué)習(xí)實(shí)現(xiàn)簡(jiǎn)單而魯棒的人臉識(shí)別)(https://medium.com/@muehler.v/node-js-face-recognition-js-simple-and-robust-face-recognition-using-deep-learning-ea5ba8e852),你就會(huì)知道他在之前組裝過(guò)一個(gè)類似的程序包,例如「face-recgnition.js」,從而為「node.js」引入了人臉識(shí)別功能。

          起初,作者并沒(méi)有預(yù)見(jiàn)到 JavaScript 社區(qū)對(duì)與人臉識(shí)別程序包的需求程度如此之高。對(duì)許多人而言,「face-recognition.js」似乎是一個(gè)不錯(cuò)的、能夠免費(fèi)試用的開(kāi)源選項(xiàng),它可以替代由微軟或亞馬遜等公司提供的付費(fèi)人臉識(shí)別服務(wù)。但是作者曾多次被問(wèn)道:是否有可能在瀏覽器中運(yùn)行完整的人臉識(shí)別的工作流水線?

          多虧了「tensorflow.js」,這種設(shè)想最終變?yōu)榱爽F(xiàn)實(shí)!作者設(shè)法使用「tf.js

          」內(nèi)核實(shí)現(xiàn)了部分類似的工具,它們能得到和「face-recognition.js」幾乎相同的結(jié)果,但是作者是在瀏覽器中完成的這項(xiàng)工作!而且最棒的是,這套工具不需要建立任何的外部依賴,使用它非常方便。并且這套工具還能通過(guò) GPU 進(jìn)行加速,相關(guān)操作可以使用 WebGL 運(yùn)行。

          這足以讓我相信,JavaScript 社區(qū)需要這樣的一個(gè)為瀏覽器環(huán)境而編寫的程序包!可以設(shè)想一下你能通過(guò)它構(gòu)建何種應(yīng)用程序。

          如何利用深度學(xué)習(xí)解決人臉識(shí)別問(wèn)題

          如果想要盡快開(kāi)始實(shí)戰(zhàn)部分,那么你可以跳過(guò)這一章,直接跳到代碼分析部分去。但是為了更好地理解「face-api.js」中為了實(shí)現(xiàn)人臉識(shí)別所使用的方法,我強(qiáng)烈建議你順著這個(gè)章節(jié)閱讀下去,因?yàn)槲页31蝗藗儐?wèn)到這個(gè)問(wèn)題。

          為簡(jiǎn)單起見(jiàn),我們實(shí)際想要實(shí)現(xiàn)的目標(biāo)是在給定一張人臉的圖像時(shí),識(shí)別出圖像中的人。為了實(shí)現(xiàn)這個(gè)目標(biāo),我們需要為每一個(gè)我們想要識(shí)別的人提供一張(或更多)他們的人臉圖像,并且給這些圖像打上人臉主人姓名的標(biāo)簽作為參考數(shù)據(jù)。現(xiàn)在,我們將輸入圖像和參考數(shù)據(jù)進(jìn)行對(duì)比,找到與輸入圖像最相似的參考圖像。如果有兩張圖像都與輸入足夠相似,那么我們輸出人名,否則輸出「unknown」(未知)。

          聽(tīng)起來(lái)確實(shí)是個(gè)好主意!然而,這個(gè)方案仍然存在兩個(gè)問(wèn)題。首先,如果我們有一張顯示了多人的圖像,并且我們需要識(shí)別出其中所有的人,將會(huì)怎樣呢?其次,我們需要建立一種相似度度量手段,用來(lái)比較兩張人臉圖像。

          人臉檢測(cè)

          我們可以從人臉檢測(cè)技術(shù)中找到第一個(gè)問(wèn)題的答案。簡(jiǎn)單地說(shuō),我們將首先定位輸入圖像中的所有人臉。「face-api.js」針對(duì)人臉檢測(cè)工作實(shí)現(xiàn)了一個(gè) SSD(Single Shot Multibox Detector)算法,它本質(zhì)上是一個(gè)基于 MobileNetV1 的卷積神經(jīng)網(wǎng)絡(luò)(CNN),在網(wǎng)絡(luò)的頂層加入了一些人臉邊框預(yù)測(cè)層。

          該網(wǎng)絡(luò)將返回每張人臉的邊界框,并返回每個(gè)邊框相應(yīng)的分?jǐn)?shù),即每個(gè)邊界框表示一張人臉的概率。這些分?jǐn)?shù)被用于過(guò)濾邊界框,因?yàn)榭赡艽嬖谝粡垐D片并不包含任何一張人臉的情況。請(qǐng)注意,為了對(duì)邊界框進(jìn)行檢索,即使圖像中僅僅只有一個(gè)人,也應(yīng)該執(zhí)行人臉檢測(cè)過(guò)程。

          人臉特征點(diǎn)檢測(cè)及人臉對(duì)齊

          在上文中,我們已經(jīng)解決了第一個(gè)問(wèn)題!然而,我想要指出的是,我們需要對(duì)齊邊界框,從而抽取出每個(gè)邊界框中的人臉居中的圖像,接著將其作為輸入傳給人臉識(shí)別網(wǎng)絡(luò),因?yàn)檫@樣可以使人臉識(shí)別更加準(zhǔn)確!

          為了實(shí)現(xiàn)這個(gè)目標(biāo),「face-api.js」實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的卷積神經(jīng)網(wǎng)絡(luò)(CNN),它將返回給定圖像的 68 個(gè)人臉特征點(diǎn):

          從特征點(diǎn)位置上看,邊界框可以將人臉居中。你可以從下圖中看到人臉檢測(cè)結(jié)果(左圖)與對(duì)齊后的人臉圖像(右圖)的對(duì)比:

          人臉識(shí)別

          現(xiàn)在,我們可以將提取出的對(duì)齊后的人臉圖像輸入到人臉識(shí)別網(wǎng)絡(luò)中,該網(wǎng)絡(luò)基于一個(gè)類似于 ResNet-34 的架構(gòu),基本上與 dlib(https://github.com/davisking/dlib/blob/master/examples/dnn_face_recognition_ex.cpp)中實(shí)現(xiàn)的架構(gòu)一致。該網(wǎng)絡(luò)已經(jīng)被訓(xùn)練去學(xué)習(xí)出人臉特征到人臉描述符的映射(一個(gè)包含 128 個(gè)值的特征向量),這個(gè)過(guò)程通常也被稱為人臉嵌入。

          現(xiàn)在讓我們回到最初對(duì)比兩張人臉圖像的問(wèn)題:我們將使用每張抽取出的人臉圖像的人臉描述符,并且將它們與參考數(shù)據(jù)的人臉描述符進(jìn)行對(duì)比。更確切地說(shuō),我們可以計(jì)算兩個(gè)人臉描述符之間的歐氏距離,并根據(jù)閾值判斷兩張人臉圖像是否相似(對(duì)于 150*150 的圖像來(lái)說(shuō),0.6 是一個(gè)很好的閾值)。使用歐氏距離的效果驚人的好,當(dāng)然,你也可以選用任何一種分類器。下面的 gif 動(dòng)圖可視化了通過(guò)歐氏距離比較兩張人臉圖像的過(guò)程:

          至此,我們已經(jīng)對(duì)人臉識(shí)別的理論有所了解。接下來(lái)讓我們開(kāi)始編寫一個(gè)代碼示例。

          是時(shí)候開(kāi)始編程了!

          在這個(gè)簡(jiǎn)短的示例中,我們將看到如何一步步地運(yùn)行人臉識(shí)別程序,識(shí)別出如下所示的輸入圖像中的多個(gè)人物:

          導(dǎo)入腳本

          首先,從 dist/face-api.js 獲得最新的版本(https://github.com/justadudewhohacks/face-api.js/tree/master/dist),或者從 dist/face-api.min.js 獲得縮減版,并且導(dǎo)入腳本:

          <script src="face-api.js"></script>

          如果你使用 npm 包管理工具,可以輸入如下指令:

          npm i face-api.js

          加載模型數(shù)據(jù)

          你可以根據(jù)應(yīng)用程序的要求加載你需要的特定模型。但是如果要運(yùn)行一個(gè)完整的端到端的示例,我們還需要加載人臉檢測(cè)、人臉特征點(diǎn)檢測(cè)和人臉識(shí)別模型。相關(guān)的模型文件可以在代碼倉(cāng)庫(kù)中找到,鏈接如下:https://github.com/justadudewhohacks/face-api.js/tree/master/weights。

          其中,模型的權(quán)重已經(jīng)被量化,文件大小相對(duì)于初始模型減小了 75%,使你的客戶端僅僅需要加載所需的最少的數(shù)據(jù)。此外,模型的權(quán)重被分到了最大為 4 MB 的數(shù)據(jù)塊中,使瀏覽器能夠緩存這些文件,這樣它們就只需要被加載一次。

          模型文件可以直接作為你的 web 應(yīng)用中的靜態(tài)資源被使用,或者你可以將它們存放在另外的主機(jī)上,通過(guò)指定的路徑或文件的 url 鏈接來(lái)加載。假如你將它們與你在 public/models 文件夾下的資產(chǎn)共同存放在一個(gè) models 目錄中:

          const MODEL_URL='/models'

          await faceapi.loadModels(MODEL_URL)

          或者,如果你僅僅想要加載特定的模型:

          const MODEL_URL='/models'

          await faceapi.loadFaceDetectionModel(MODEL_URL)

          await faceapi.loadFaceLandmarkModel(MODEL_URL)

          await faceapi.loadFaceRecognitionModel(MODEL_URL)

          從輸入圖像中得到對(duì)所有人臉的完整描述

          該神經(jīng)網(wǎng)絡(luò)可以接收 HTML 圖像、畫布、視頻元素或張量(tensor)作為輸入。為了檢測(cè)出輸入圖像中分?jǐn)?shù)(score)大于最小閾值(minScore)的人臉邊界框,我們可以使用下面的簡(jiǎn)單操作:

          const minConfidence=0.8

          const fullFaceDescriptions=await faceapi.allFaces(input, minConfidence)

          一個(gè)完整的人臉描述符包含了檢測(cè)結(jié)果(邊界框+分?jǐn)?shù)),人臉特征點(diǎn)以及計(jì)算出的描述符。正如你所看到的,「faceapi.allFaces」在底層完成了本文前面的章節(jié)所討論的所有工作。然而,你也可以手動(dòng)地獲取人臉定位和特征點(diǎn)。如果這是你的目的,你可以參考 github repo 中的幾個(gè)示例。

          請(qǐng)注意,邊界框和特征點(diǎn)的位置與原始圖像/媒體文件的尺寸有關(guān)。當(dāng)顯示出的圖像尺寸與原始圖像的尺寸不相符時(shí),你可以簡(jiǎn)單地通過(guò)下面的方法重新調(diào)整它們的大小:

          const resized=fullFaceDescriptions.map(fd=> fd.forSize(width, height))

          我們可以通過(guò)將邊界框在畫布上繪制出來(lái)對(duì)檢測(cè)結(jié)果進(jìn)行可視化:

          fullFaceDescription.forEach((fd, i)=> {

          faceapi.drawDetection(canvas, fd.detection, { withScore: true })

          })

          可以通過(guò)下面的方法將人臉特征點(diǎn)顯示出來(lái):

          fullFaceDescription.forEach((fd, i)=> {

          faceapi.drawLandmarks(canvas, fd.landmarks, { drawLines: true })

          })

          通常,我會(huì)在 img 元素的頂層覆蓋一個(gè)具有相同寬度和高度的絕對(duì)定位的畫布(想獲取更多信息,請(qǐng)參閱 github 上的示例)。

          人臉識(shí)別

          當(dāng)我們知道了如何得到給定的圖像中所有人臉的位置和描述符后,我們將得到一些每張圖片顯示一個(gè)人的圖像,并且計(jì)算出它們的人臉描述符。這些描述符將作為我們的參考數(shù)據(jù)。

          假設(shè)我們有一些可以用的示例圖片,我們首先從一個(gè) url 鏈接處獲取圖片,然后使用「faceapi.bufferToImage」從它們的數(shù)據(jù)緩存中創(chuàng)建 HTML 圖像元素:

          // fetch images from url as blobs

          const blobs=await Promise.all(

          ['sheldon.png' 'raj.png', 'leonard.png', 'howard.png'].map(

          uri=> (await fetch(uri)).blob()

          )

          )

          // convert blobs (buffers) to HTMLImage elements

          const images=await Promise.all(blobs.map(

          blob=> await faceapi.bufferToImage(blob)

          ))

          接下來(lái),在每張圖像中,正如我們之前對(duì)輸入圖像所做的那樣,我們對(duì)人臉進(jìn)行定位、計(jì)算人臉描述符:

          const refDescriptions=await Promsie.all(images.map(

          img=> (await faceapi.allFaces(img))[0]

          ))

          const refDescriptors=refDescriptions.map(fd=> fd.descriptor)

          現(xiàn)在,我們還需要做的就是遍歷我們輸入圖像的人臉描述符,并且找到參考數(shù)據(jù)中與輸入圖像距離最小的描述符:

          const sortAsc=(a, b)=> a - b

          const labels=['sheldon', 'raj', 'leonard', 'howard']

          const results=fullFaceDescription.map((fd, i)=> {

          const bestMatch=refDescriptors.map(

          refDesc=> ({

          label: labels[i],

          distance: faceapi.euclideanDistance(fd.descriptor, refDesc)

          })

          ).sort(sortAsc)[0]

          return {

          detection: fd.detection,

          label: bestMatch.label,

          distance: bestMatch.distance

          }

          })

          正如前面提到的,我們?cè)谶@里使用歐氏距離作為一種相似度度量,這樣做的效果非常好。我們?cè)谳斎雸D像中檢測(cè)出的每一張人臉都是匹配程度最高的。

          最后,我們可以將邊界框和它們的標(biāo)簽一起繪制在畫布上,顯示檢測(cè)結(jié)果:

          // 0.6 is a good distance threshold value to judge

          // whether the descriptors match or not

          const maxDistance=0.6

          results.forEach(result=> {

          faceapi.drawDetection(canvas, result.detection, { withScore: false })

          const text=`${result.distance < maxDistance ? result.className : 'unkown'} (${result.distance})`

          const { x, y, height: boxHeight }=detection.getBox()

          faceapi.drawText(

          canvas.getContext('2d'),

          x,

          y + boxHeight,

          text

          )

          })

          至此,我希望你對(duì)如何使用這個(gè) API 有了一個(gè)初步的認(rèn)識(shí)。同時(shí),我也建議你看看文中給出的代碼倉(cāng)庫(kù)中的其它示例。好好地把這個(gè)程序包玩?zhèn)€痛快吧!


          者:JavaScript

          轉(zhuǎn)發(fā)鏈接:https://www.kancloud.cn/dennis/tgjavascript/241852

          著技術(shù)的日新月異,為開(kāi)發(fā)人員提供了令人難以置信的新工具API。但據(jù)了解,在100 多個(gè) API中,只有5%被開(kāi)發(fā)人員積極使用。


          讓我們來(lái)看看一些有用的Web API,它們可以幫助您將網(wǎng)站推向月球!

          1、 截屏接口

          Screen Capture API,顧名思義,允許您捕獲屏幕的內(nèi)容,使構(gòu)建屏幕錄像機(jī)的過(guò)程變得輕而易舉。

          您需要一個(gè)視頻元素來(lái)顯示捕獲的屏幕。開(kāi)始按鈕將開(kāi)始屏幕捕獲

          <video id="preview" autoplay>
            Your browser doesn't support HTML5.
          </video>
          <button id="start" class="btn">Start</button>
          const previewElem=document.getElementById("preview");
          const startBtn=document.getElementById("start");
          
          async function startRecording() {
            previewElem.srcObject=await navigator.mediaDevices.getDisplayMedia({
                video: true,
                audio: true,
              });
          }
          
          startBtn.addEventListener("click", startRecording);

          2、網(wǎng)絡(luò)共享API

          Web Share API允許您將**網(wǎng)頁(yè)中的文本鏈接甚至文件**共享到設(shè)備上安裝的其他應(yīng)用程序。

          async function shareHandler() {
            navigator.share({
              title: "Tapajyoti Bose | Portfolio",
              text: "Check out my website",
              url: "https://tapajyoti-bose.vercel.app/",
            });
          }

          注意:要使用Web Share API,您需要用戶進(jìn)行交互。例如,按鈕點(diǎn)擊觸摸事件

          3、路口觀察器API

          Intersection Observer API允許您檢測(cè)元素何時(shí)進(jìn)入或離開(kāi)視口。這對(duì)于實(shí)現(xiàn)無(wú)限滾動(dòng)非常有用。

          在線瀏覽地址:https://codepen.io/ruppysuppy/pen/abBeZwj



          注意:由于我個(gè)人的喜好,該演示使用React ,但您可以使用**任何框架vanilla JavaScript**。

          4、剪貼板API

          剪貼板API允許您讀取數(shù)據(jù)并將數(shù)據(jù)寫入剪貼板這對(duì)于實(shí)現(xiàn)復(fù)制到剪貼板功能很有用。

          async function copyHandler() {
            const text="https://tapajyoti-bose.vercel.app/";
            navigator.clipboard.writeText(text);
          }

          注意:如果頁(yè)面已經(jīng)在屏幕上可見(jiàn),您只能使用屏幕喚醒鎖定 API 。否則,它會(huì)拋出錯(cuò)誤。

          5.屏幕喚醒鎖定API

          有沒(méi)有想過(guò)YouTube如何防止屏幕在播放視頻時(shí)被關(guān)閉?好吧,那是因?yàn)?/span>Screen Wake Lock API

          let wakeLock=null;
          
          async function lockHandler() {
            wakeLock=await navigator.wakeLock.request("screen");
          }
          
          async function releaseHandler() {
            await wakeLock.release();
            wakeLock=null;
          }

          注意:如果頁(yè)面已經(jīng)在屏幕上可見(jiàn),您只能使用屏幕喚醒鎖定 API 。否則,它會(huì)拋出錯(cuò)誤。

          6、屏幕方向API

          Screen Orientation API允許您檢查屏幕的當(dāng)前方向,甚至**可以將其鎖定**到特定方向。

          async function lockHandler() {
            await screen.orientation.lock("portrait");
          }
          
          function releaseHandler() {
            screen.orientation.unlock();
          }
          
          function getOrientation() {
            return screen.orientation.type;



          7、全屏API

          全屏API允許您**全屏**顯示一個(gè)元素或整個(gè)頁(yè)面。

          async function enterFullscreen() {
            await document.documentElement.requestFullscreen();
          }
          
          async function exitFullscreen() {
            await document.exitFullscreen();
          }

          注意:要也使用全屏 API,您需要用戶進(jìn)行交互。

          謝謝閱讀,如果對(duì)你有幫助,記得點(diǎn)贊支持!


          主站蜘蛛池模板: 久久久精品人妻一区二区三区| 国产av福利一区二区三巨| 日韩美一区二区三区| 久久99精品波多结衣一区| 福利电影一区二区| 日韩成人无码一区二区三区| 无码国产精成人午夜视频一区二区 | 少妇精品无码一区二区三区| 日韩人妻无码一区二区三区久久99 | 日韩精品一区二区三区国语自制| 亚洲国产一区二区三区青草影视| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 日韩一区二区免费视频| 五十路熟女人妻一区二区| 一区二区三区视频在线观看| 亚洲日韩精品一区二区三区| 中文字幕色AV一区二区三区 | 蜜桃传媒视频麻豆第一区| 国产一区二区三区高清在线观看 | 国产麻豆精品一区二区三区| 国产精品一区二区久久精品| 精品黑人一区二区三区| 久久久久人妻一区二区三区| 精品一区二区三区四区在线播放| 亚洲视频一区网站| 亚洲国产成人久久一区二区三区 | 日本福利一区二区| 国产一区二区三区电影| 日本免费精品一区二区三区| 成人区人妻精品一区二区不卡视频 | 国产高清视频一区二区| 无码精品人妻一区| 日韩精品无码视频一区二区蜜桃| 久久精品一区二区三区不卡| 末成年女A∨片一区二区| 国内精自品线一区91| 国产精久久一区二区三区| 国产在线精品一区二区在线观看 | 色国产在线视频一区| 国产情侣一区二区三区| 亚洲电影唐人社一区二区|