首页 > 其他分享 >face-api.js 学习笔记

face-api.js 学习笔记

时间:2023-02-02 22:22:43浏览次数:63  
标签:canvas const face api js faceapi

https://www.cnblogs.com/keatkeat/p/15106226.html

参考

Build Real Time Face Detection With JavaScript (youtube get started)

face-api.js — JavaScript API for Face Recognition in the Browser with tensorflow.js

教程 | face-api.js:在浏览器中进行人脸识别的JavaScript接口 (有提到相似度)

face-api.js github

face-api.js documentation

 

注意事项: 

由于 face-api.js 作者从 2020 Apr 之后就没有维护了, 以至于在 node.js 的时候无法使用最新的 @tensorflow/tfjs-node (issue 在这里)

后来有个好心人 folk 出来改. 所以推荐大家使用新的版本 @vladmandic/face-api      

 

Get started

Build Real Time Face Detection With JavaScript (youtube get started)

这篇主要是叫一些 basic 入门. 

流程: 

加载需要的 models 

开启 webcam 

把 webcam 源放入 video 做显示

通过 faceapi 扫描 video

做一个定位 canvas 画布

通过 faceapi draw 人脸位置, 轮廓, 表情.

代码:

复制代码
import * as faceapi from 'face-api.js';

const video = document.querySelector<HTMLVideoElement>('#js-video')!;

video.addEventListener('play', () => {
  // 制作定位 canvas
  const canvas = document.createElement('canvas');
  canvas.style.position = 'absolute';
  document.body.append(canvas);

  // 配置显示尺寸
  const displaySize = { width: video.width, height: video.height };
  faceapi.matchDimensions(canvas, displaySize);

  // 每 100ms 去绘制
  setInterval(async () => {
    // 识别位置, 路阔, 表情
    const detections = await faceapi
      .detectAllFaces(video, new faceapi.TinyFaceDetectorOptions())
      .withFaceLandmarks()
      .withFaceExpressions();

    // 调整尺寸
    const resizedDetections = faceapi.resizeResults(detections, displaySize);

    canvas.getContext('2d')?.clearRect(0, 0, canvas.width, canvas.height); // 清空画布
    faceapi.draw.drawDetections(canvas, resizedDetections); // 位置
    faceapi.draw.drawFaceLandmarks(canvas, resizedDetections); // 路阔
    faceapi.draw.drawFaceExpressions(canvas, resizedDetections); // 表情
  }, 100);
});

setTimeout(async () => {
  // 加载 models
  await Promise.all([
    faceapi.nets.tinyFaceDetector.loadFromUri('/face-api-models'),
    faceapi.nets.faceLandmark68Net.loadFromUri('/face-api-models'),
    faceapi.nets.faceRecognitionNet.loadFromUri('/face-api-models'),
    faceapi.nets.faceExpressionNet.loadFromUri('/face-api-models'),
  ]);
  // 开启 webcam, 把 webcam 的流引入 video 显示
  navigator.getUserMedia(
    { video: {} },
    stream => {
      video.srcObject = stream;
    },
    error => console.log('error', error)
  );
}, 1000);
复制代码

 提醒: Webpack + face-api.js warning

如果使用 Webpack 可能会看见一个 warning 显示 Can't resolve 'fs'

这是因为 face-api.js 的代码时 node.js 和游览器公用的, 在 node.js 的环境下 fs 是必要的. 但是游览器是不需要的. 忽略掉这个 warning 就可以了.

github issue 看这里.

 

人脸识别 + 相似度

通过获取 2 张图片的人脸信息就可以做一个相似度对比. 如果 < 0.6 就表示很可能是同一个人 (这个度没有规范, 只是一个参考值)

这里顺便补上了一个 detect age 的功能.

复制代码
// import * as faceapi from 'face-api.js';
import * as faceapi from '@vladmandic/face-api';

(async () => {
  await Promise.all([
    faceapi.nets.tinyFaceDetector.loadFromUri('/face-api-models'),
    faceapi.nets.faceLandmark68Net.loadFromUri('/face-api-models'),
    faceapi.nets.faceRecognitionNet.loadFromUri('/face-api-models'),
    faceapi.nets.faceExpressionNet.loadFromUri('/face-api-models'),
    faceapi.nets.ageGenderNet.loadFromUri('/face-api-models'),
  ]);
  const processAsync = async (image: HTMLImageElement) => {
    const imageContainer = image.parentElement!;
    const canvas = document.createElement('canvas');
    canvas.style.position = 'absolute';
    canvas.style.left = '0';
    canvas.style.top = '0';
    imageContainer.append(canvas);
    const displaySize = { width: image.width, height: image.height };
    faceapi.matchDimensions(canvas, displaySize);

    const faceDetection = (
      await faceapi
        .detectAllFaces(image, new faceapi.TinyFaceDetectorOptions())
        .withFaceLandmarks()
        .withFaceDescriptors()
        .withFaceExpressions()
        .withAgeAndGender()
    )[0]; // 假设图片只会有一张脸
    // 或者用 detectSingleFace 拿最像脸的脸, 提醒: withFaceDescriptor <- 没有 s 了
    // const faceDetection = await faceapi
    //   .detectSingleFace(image, new faceapi.TinyFaceDetectorOptions())
    //   .withFaceLandmarks()
    //   .withFaceDescriptor()
    //   .withFaceExpressions()
    //   .withAgeAndGender();

    if (faceDetection === undefined) {
      throw new Error(`no faces detected`);
    }
    const resizedDetection = faceapi.resizeResults(faceDetection, displaySize);
    faceapi.draw.drawDetections(canvas, resizedDetection);
    faceapi.draw.drawFaceLandmarks(canvas, resizedDetection);
    faceapi.draw.drawFaceExpressions(canvas, resizedDetection);
    const box = resizedDetection.detection.box;
    const drawBox = new faceapi.draw.DrawBox(box, {
      label: Math.round(resizedDetection.age) + ' year old ' + resizedDetection.gender,
    });
    drawBox.draw(canvas);
    return faceDetection;
  };
  const [fd1, fd2] = await Promise.all([
    processAsync(document.querySelector<HTMLImageElement>('#js-image1')!),
    processAsync(document.querySelector<HTMLImageElement>('#js-image2')!),
  ]);

  const distance = faceapi.euclideanDistance(fd1.descriptor, fd2.descriptor);
  if (distance < 0.6) {
    console.log('same person');
  } else {
    console.log('different person');
  }
})();
复制代码

关键就在最后几句.

 

Node.js 运行

安装

要在 Node.js 上运行 (Windows 机) 有些事情要留意, 我也不确定是不是要装到完

npm install -g --production windows-build-tools (Local machine PowerShell administrator 安装, 在 windows server 我是用 cmd without admin 安装的, 它大概装了 10 分钟, 虽然看上去没有什么跑,但其实 CPU 是有跑的, 要留意哦)

安装 Python (我是通过 visual studio installer 安装的 3.x 版本, windows server 的话通过 installer 安装 2.x 版本 (可能 3.x 也是 ok), 在配置的时候记得选要 setup path)

set environment variables path

常见问题

代码

参考: face-api.js docs 

yarn add @tensorflow/tfjs-node @vladmandic/face-api canvas

这里用的是 CommonJS, 因为我目前还没有 migration 到 es module

复制代码
require('@tensorflow/tfjs-node');
const canvas = require('canvas');
const faceapi = require('@vladmandic/face-api');

// 这个是官方推荐做法 monkeyPatch
const { Canvas, Image, ImageData } = canvas;
faceapi.env.monkeyPatch({ Canvas, Image, ImageData });

(async () => {
  await Promise.all([
    // 换成了 from disk
    faceapi.nets.tinyFaceDetector.loadFromDisk('face-api-models'),
    faceapi.nets.faceLandmark68Net.loadFromDisk('face-api-models'),
    faceapi.nets.faceRecognitionNet.loadFromDisk('face-api-models'),
    faceapi.nets.faceExpressionNet.loadFromDisk('face-api-models'),
  ]);

  // 通过 canvas.loadImage 读取图片
  const image1 = await canvas.loadImage('klc-face/1.jpg');
  const image2 = await canvas.loadImage('klc-face/2.jpg');
  const fd1 = await faceapi
    .detectSingleFace(image1, new faceapi.TinyFaceDetectorOptions())
    .withFaceLandmarks()
    .withFaceDescriptor();

  const fd2 = await faceapi
    .detectSingleFace(image2, new faceapi.TinyFaceDetectorOptions())
    .withFaceLandmarks()
    .withFaceDescriptor();

  const distance = faceapi.euclideanDistance(fd1.descriptor, fd2.descriptor);
  console.log('distance', distance);
})();
复制代码

 如果要用 es module 的话, 到 package.json 加 { "type": "module" }, 下面这个是 es module 版本

 View Code

 

标签:canvas,const,face,api,js,faceapi
From: https://www.cnblogs.com/chinasoft/p/17087596.html

相关文章

  • 用Python连接IBM量子API实现的量子算法——Deutsch-Jozsa算法
    Prefix我是看这篇文章:​​不再神秘的量子计算,用Python就能实现(视频+代码),希望能run上面的代码。量子代码地址:​​https://github.com/llSourcell/quantum_computing​​结果......
  • 常用对象API(基本数据类型对象包装类)
    概述为了方便操作基本数据类性值,将其封装成了对象,在对象中定义了属性和行为丰富了改数据的操作。用于描述该对象的类就称为基本数据类型对象包装类类型类byte......
  • 常用对象API(集合框架Collection)★★★★★
    目录概述体系&共性功能Collection接口的常见方法:迭代器的使用IteratorList和Set的特点使用集合的一些技巧List接口List接口的常见方法ListIterator接口数组和链表Vector集......
  • 常用对象API(集合框架)★★★★★
    目录目录目录集合框架Collection概述体系&共性功能Collection接口的常见方法:迭代器的使用IteratorList和Set的特点使用集合的一些技巧List接口List接口的常见方法ListIter......
  • 其他对象API
    System类API———java.lang.System:属性和行为都是静态的。longcurrentTimeMillis();//返回当前时间毫秒值//作用演示longl1=1335664696656l;//System.curr......
  • 常用对象API(String类)
    目录StringBuffer字符串缓冲区特点&添加功能增删改查和可变数组长度StringBuilder类StringBuilder练习:String类String类特点:构造函数字符串常见方法获取转换判断比较inter......
  • 【博学谷学习记录】超强总结,用心分享 | 前端开发 JS基础(三)
    JavaScript基础(3)if多分支语句和switch的区别:共同点都能实现多分支选择,多选1大部分情况下可以互换区别:switch…case语句通常处理case为比较确定值的情况......
  • stream操作常用API 示例详解
    简介从JDK8开始,增加了一新特性Stream流式操作,Stream中提供了非常多的API供大家使用,灵活的使用这些API,可以非常的方便且优美的实现我们的代码逻辑。最终型toArraytoArray......
  • cache API简介
    cacheAPI是一个很强大的API,它可以在window环境和serviceWorker环境使用,配合serviceWorker可以让我们自己来管理缓存。cachescaches是一个全局接口,可以在window和worker......
  • 常用API大全分享!赶紧收藏起来!
    一、短信发送短信的应用可以说是非常的广泛了,短信API也是当下非常热门的API~短信验证码:可用于登录、注册、找回密码、支付认证等等应用场景。支持三大运营商,3秒可达,99.9......