web 端的人脸识别

人脸识别

今天给大家分享的内容是纯 javascript 实现的人脸识别。希望体验一下今天 web 端技术的飞速发展。

人脸识别

简单创建一个项目,引入两个关键文件和文件夹


项目结构
  • models 是训练出来模型,这些模型是通过大量图片训练出来的。
  • face-api.min.js 引入依赖文件

创建一个 video 标签来捕捉我这张老脸。

    <video id="video" width="720" height="560" autoplay muted></video>

简单地给样式

    <style>
        body {
            margin: 0;
            padding: 0;
            width: 100vw;
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }
    </style>
    <script defer src="./face-api.min.js"></script>
    <script defer src="./app.js"></script>

这里注意一下引用顺序,我们需要引入 face-api.min.js 这个依赖。

通过摄像头捕捉视频

function startVideo(){
    navigator.getUserMedia(
        {video:{}},
        stream => video.srcObject = stream,
        err => console.log(err)
    )
}

startVideo();

这里我们使用 navigator 的 getUserMedia 获取设备的多媒体设备,传入 video 表示要获取视频流,然后将视频流传入到 video 标签来显示。

导入训练好的模型

Promise.all([
    faceapi.nets.tinyFaceDetector.loadFromUri('/models'),
    faceapi.nets.faceLandmark68Net.loadFromUri('/models'),
    faceapi.nets.faceRecognitionNet.loadFromUri('/models'),
    faceapi.nets.faceExpressionNet.loadFromUri('/models'),
]).then(startVideo());

通过 Promise 的 all 将这些文件同时进行异步加载,

  • tinyFaceDetector 这是轻量级可以快速识别人脸的模型
  • faceLandmark68Net 用于对人脸不同部位识别的模型
  • faceRecognitionNet 识别出人脸的位置,和覆盖的范围
  • faceExpressionNet 用于识别人的情绪,是高兴呀还是高兴呀 呵呵

所有模型都加载完毕后再启动我们的视频

获取识别数据

video.addEventListener('play',()=>{
    setInterval(async()=>{
        const detections = await faceapi.detectAllFaces(video,
            new faceapi.TinyFaceDetectorOptions())
            .withFaceLandmarks()
            // .withFaceExpressions()
            console.log(detections);

    },100)
})
  • 识别是个耗时的操作,所有用异步方法获取识别数据,调用 faceapi 的 detectAllFaces 方法,传入要识别的资源,也就是视频,然后我们要识别什么可以传入一个 options 告诉识别器我们要识别什么。打印识别出来的结果数据。


    识别数据

绘制人脸识别框

这里我们创建一个 canvas 用于将识别出来数据绘制到视频上,canvas 可以用 js 动态创建

    canvas {
      position: absolute;
      top: 0;
      left: 0;
    }

这里需要给 canvas 一个绝对定位,以便和我们视频对其。

    const canvas = faceapi.createCanvasFromMedia(video);
    document.body.appendChild(canvas);
    const displaySize = { width: video.width, height: video.height};
  • faceapi.createCanvasFromMedia(video) 创建 canvas
video.addEventListener('play',()=>{

    const canvas = faceapi.createCanvasFromMedia(video);
    document.body.appendChild(canvas);
    const displaySize = { width: video.width, height: video.height};

    faceapi.matchDimensions(canvas,displaySize);

    setInterval(async()=>{
        const detections = await faceapi.detectAllFaces(video,
            new faceapi.TinyFaceDetectorOptions())
            .withFaceLandmarks()
        const resizedDetections = faceapi.resizeResults(detections,displaySize)

        canvas.getContext('2d').clearRect(0,0,canvas.width,canvas.height);
        faceapi.draw.drawDetections(canvas,resizedDetections);
            // .withFaceExpressions()
            // console.log(detections);
    },100)
})
const displaySize = { width: video.width, height: video.height} 

让 canvas 与我们 vidoe 大小匹配

const resizedDetections = faceapi.resizeResults(detections,displaySize)

将我们测试的框结果与显示大小相匹配。

canvas.getContext('2d').clearRect(0,0,canvas.width,canvas.height);

清除上一次绘制的结果,下面就是讲结果绘制到视频上

 faceapi.draw.drawDetections(canvas,resizedDetections);
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,474评论 1 45
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,097评论 1 32
  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,758评论 0 15
  • 今次看一部电影《永无止境》(Limitless)。 我难得看一部电影看得很起劲儿,这部就挺好看。有意思的地方在于,...
    中华小小生阅读 233评论 0 0
  • 你在徒有虚名的家伙 是地地道道的 假 大 空代言 吃一口 可以糊弄别人的眼 吃一块 可以糊弄别人的嘴 吃一袋 可...
    夕阳在山阅读 104评论 0 1