生活随笔
收集整理的這篇文章主要介紹了
吗咿呀嘿-用js来搞个简单的人脸识别
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
緣起 “螞蟻呀嘿,螞蟻呀呼,螞蟻呀哈” 相信最近好多人的朋友圈或者抖音都被類似視頻刷過屏! 類似的效果最早是在2020年初,那個(gè)時(shí)候大家應(yīng)該還都記得,幾乎所有的人都因?yàn)橐咔樵虮黄染€上辦公! 工作當(dāng)然離不開開會(huì)了,這點(diǎn)歪果仁和中國很像,國內(nèi)我們一般用qq或者釘釘來個(gè)在線視頻會(huì)議!歪果仁也會(huì)經(jīng)常開線上會(huì)議,不過他們用的最多的是zoom這個(gè)軟件。經(jīng)常的在線會(huì)會(huì)讓人很煩躁,為什么呢?原本在家辦公就不用洗頭了,但是為了開在線視頻會(huì)議還得去專門洗個(gè)頭! so,一個(gè)來自俄羅斯程序猿就想了一個(gè)招數(shù)惡搞一下他的同事。他基于 first-order-model 做了一個(gè)叫做Avatarify 的軟件,并且放在了全世界做大的同性交友網(wǎng)站github上。First Order Motion Model for Image Animation 簡單來說就是把一張圖片變成動(dòng)態(tài)的。Avatarify ,看起來很熟悉的名字,你肯定聽過一部叫阿凡達(dá)的電影!之后程序猿小哥又基于Avatarify 做了一個(gè)蘋果app,在網(wǎng)上掀起了嗎咿呀嘿旋風(fēng),不過在上架appstore7天后在中國區(qū)就被下架了,原因不得而知。 來看一下 First Order Motion Model上的圖片動(dòng)畫結(jié)果 First Order Motion Model上的swap face結(jié)果 看完以后大概能明白為什么被下架了!如果東西能被普通人隨便使用,那么我們的表情甚至動(dòng)作都能被別人模擬出來,只要他有一張你的照片!所以說人臉識(shí)別不是絕對(duì)安全,什么都可以被模擬!這兩天的315晚會(huì)不知道大家看沒有看,好多商家都在非法收集的臉部信息! 上面我們提到的庫都是python的,app實(shí)現(xiàn)這樣的功能都是把圖片或者視頻傳輸給服務(wù)器,然后服務(wù)器處理文件。 瀏覽器環(huán)境人臉識(shí)別 我們今天要在瀏覽器環(huán)境下面實(shí)現(xiàn)一個(gè)簡單的人臉識(shí)別,我們會(huì)用到Tracking.js ,這是一個(gè)獨(dú)立的JavaScript庫,用于跟蹤從相機(jī)或者圖片實(shí)時(shí)收到的數(shù)據(jù)。跟蹤的數(shù)據(jù)既可以是顏色,也可以是人,也就是說我們可以通過檢測到某特定顏色,或者檢測一個(gè)人體/臉的出現(xiàn)與移動(dòng),來觸發(fā)JavaScript 事件。 trankingjs下載 我們需要先點(diǎn)擊后面的標(biāo)簽下載trankingjs trankingjs使用-識(shí)別圖片 引入 tracking-min.js人臉識(shí)別庫 引入face-min.js,eye-min.js,mouth-min.js 臉部,眼睛,嘴巴等模型文件 創(chuàng)建html文件,內(nèi)容如下
< ! DOCTYPE html
>
< html lang
= "en" >
?
< head
> < meta charset
= "UTF-8" > < meta name
= "viewport" content
= "width=device-width, initial-scale=1.0" > < title
> Document
< / title
> < script src
= "./build/tracking-min.js" > < / script
> < script src
= "./build/data/face-min.js" > < / script
> < script src
= "./build/data/mouth-min.js" > < / script
> < script src
= "./build/data/eye-min.js" > < / script
> < style
> . rect
{ border
: 2 px solid #a64ceb
; left
: - 1000 px
; position
: absolute
; top
: - 1000 px
; }
?
. demo
- container
{ width
: 100 % ; height
: 530 px
; position
: relative
; background
: #eee
; overflow
: hidden
; border
- bottom
- right
- radius
: 10 px
; border
- bottom
- left
- radius
: 10 px
; }
?
< / style
>
< / head
>
?
< body
> < div
class = "demo-container" > < img src
= "./imgs/2.png" alt
= "" id
= "img" > < / div
>
?
< script
> window
. onload
= function ( ) {
?var tracker
= new tracking
. ObjectTracker ( [ 'face' , 'eye' , 'mouth' ] ) ; tracker
. setStepSize ( 1.7 ) ; tracking
. track ( '#img' , tracker
) ; tracker
. on ( 'track' , function ( event
) { event
. data
. forEach ( function ( rect
) {
?window
. plot ( rect
. x
, rect
. y
, rect
. width
, rect
. height
) ; } ) ; } ) ;
?window
. plot
= function ( x
, y
, w
, h
) { var rect
= document
. createElement ( 'div' ) ; document
. querySelector ( '.demo-container' ) . appendChild ( rect
) ; rect
. classList
. add ( 'rect' ) ; rect
. style
. width
= w
+ 'px' ; rect
. style
. height
= h
+ 'px' ; rect
. style
. left
= ( img
. offsetLeft
+ x
) + 'px' ; rect
. style
. top
= ( img
. offsetTop
+ y
) + 'px' ; } ; }
?
< / script
>
?
< / body
>
?
< / html
>
?
html和css比較簡單,這里我們主要來看js代碼。 注意js代碼必須一定要寫在window.onload 回調(diào)函數(shù)里面,否者獲取不到圖片的數(shù)據(jù),就沒有辦法對(duì)圖片進(jìn)行識(shí)別! 創(chuàng)建識(shí)別對(duì)象
var tracker
= new tracking
. ObjectTracker ( [ 'face' , 'eye' , 'mouth' ] ) ; tracking
. track ( '#img' , tracker
) ; tracker
. on ( 'track' , function ( event
) { event
. data
. forEach ( function ( rect
) { window
. plot ( rect
. x
, rect
. y
, rect
. width
, rect
. height
) ; } ) ; } ) ;
獲取的event.data是一個(gè)數(shù)組 ,數(shù)組存放識(shí)別處理出來的臉部數(shù)據(jù),數(shù)據(jù)結(jié)構(gòu)如下 {width: 61, height: 61, x: 244, y: 125} x和y是識(shí)別出來元素的坐標(biāo),width和height是識(shí)別出來元素的寬度 處理識(shí)別結(jié)果 接下來我們只要需要把得到的結(jié)果標(biāo)記到圖片的對(duì)應(yīng)的位置即可,通過plot函數(shù)創(chuàng)建一個(gè)div,給定對(duì)應(yīng)的坐標(biāo)和寬高
window
. plot
= function ( x
, y
, w
, h
) { var img
= document
. querySelector ( '#img' ) var rect
= document
. createElement ( 'div' ) ; document
. querySelector ( '.demo-container' ) . appendChild ( rect
) ; rect
. classList
. add ( 'rect' ) ; rect
. style
. width
= w
+ 'px' ; rect
. style
. height
= h
+ 'px' ; rect
. style
. left
= ( img
. offsetLeft
+ x
) + 'px' ; rect
. style
. top
= ( img
. offsetTop
+ y
) + 'px' ; } ;
然后就會(huì)看到這樣的結(jié)果,會(huì)識(shí)別出照片的眼睛、鼻子、嘴巴 trankingjs使用-識(shí)別攝像頭數(shù)據(jù) 創(chuàng)建html文件,寫入如下代碼
< ! doctype html
>
< html
>
?
< head
> < meta charset
= "utf-8" > < title
> demo
< / title
>
?
< script src
= "./build/tracking-min.js" > < / script
> < script src
= "./build/data/face-min.js" > < / script
> < style
> video
, canvas
{ position
: absolute
; }
?
< / style
>
< / head
>
?
< body
>
?
< div
class = "demo-container" > < video id
= "video" width
= "320" height
= "240" preload autoplay loop muted
> < / video
> < canvas id
= "canvas" width
= "320" height
= "240" > < / canvas
> < / div
>
?
< script
> window
. onload
= function ( ) { var video
= document
. getElementById ( 'video' ) ; var canvas
= document
. getElementById ( 'canvas' ) ; var context
= canvas
. getContext ( '2d' ) ;
?var tracker
= new tracking
. ObjectTracker ( 'face' ) ; tracker
. setInitialScale ( 4 ) ; tracker
. setStepSize ( 2 ) ; tracker
. setEdgesDensity ( 0.1 ) ;
?tracking
. track ( '#video' , tracker
, { camera
: true } ) ;
?tracker
. on ( 'track' , function ( event
) { context
. clearRect ( 0 , 0 , canvas
. width
, canvas
. height
) ; event
. data
. forEach ( function ( rect
) { context
. strokeStyle
= '#a64ceb' ; context
. strokeRect ( rect
. x
, rect
. y
, rect
. width
, rect
. height
) ; } ) ; } ) ;
?
?
} ;
?
< / script
>
?
< / body
>
?
< / html
>
核心js代碼解釋如下 創(chuàng)建識(shí)別對(duì)象 創(chuàng)建識(shí)別對(duì)象并且啟用攝像頭,將攝像頭內(nèi)容輸出到video標(biāo)簽上
var video
= document
. getElementById ( 'video' ) ; var tracker
= new tracking
. ObjectTracker ( 'face' ) ; tracker
. setInitialScale ( 4 ) ; tracker
. setStepSize ( 2 ) ; tracker
. setEdgesDensity ( 0.1 ) ; tracking
. track ( '#video' , tracker
, { camera
: true } ) ;
?
注意:這里的識(shí)別放大比例,步長,邊緣密度等值可以根據(jù)攝像頭距離物體遠(yuǎn)近自己調(diào)整。 處理識(shí)別結(jié)果
var canvas
= document
. getElementById ( 'canvas' ) ; var context
= canvas
. getContext ( '2d' ) ; tracker
. on ( 'track' , function ( event
) { context
. clearRect ( 0 , 0 , canvas
. width
, canvas
. height
) ; event
. data
. forEach ( function ( rect
) { context
. strokeStyle
= '#a64ceb' ; context
. strokeRect ( rect
. x
, rect
. y
, rect
. width
, rect
. height
) ; } ) ; } ) ;
然后啟動(dòng)起來,瀏覽器會(huì)提示是否允許開啟攝像頭!點(diǎn)擊允許,就會(huì)看到你英俊瀟灑(沉魚落雁)的臉龐!
總結(jié)
以上是生活随笔 為你收集整理的吗咿呀嘿-用js来搞个简单的人脸识别 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。