功能

  第一阶段实现对图片中人脸的识别并打上标签(比如:人名)

  第二阶段使用摄像头实现对人物的识别,比如典型的应用做一个人脸考勤的系统

资源

  Face-api.js 是一个 JavaScript API,是基于 tensorflow.js 核心 API 的人脸检测和人脸识别的浏览器实现。它实现了一系列的卷积神经网络(CNN),针对网络和移动设备进行了优化。非常牛逼,简单好用

  是一个 JavaScript 文件上传库。可以拖入上传文件,并且会对图像进行优化以加快上传速度。让用户体验到出色、进度可见、如丝般顺畅的用户体验。确实很酷的一款上传图片的开源产品

  是一个 JavaScript 库,它以优雅的方式展示图片,视频和一些 html 内容。它包含你所期望的一切特性 —— 支持触屏,响应式和高度自定义

设计思路

  1. 准备一个人脸数据库,上传照片,并打上标签(人名),最好但是单张脸的照片,测试的时候可以同时对一张照片上的多个人物进行识别
  2. 提取人脸数据库中的照片和标签进行量化处理,转化成一堆数字,这样就可以进行比较匹配
  3. 使用一张照片来测试一下匹配程度

最终的效果

Demo  http://221.224.21.30:2020/FaceLibs/Index   密码:123456

注意:红框中的火箭浣熊,钢铁侠,战争机器没有正确的识别,虽然可以通过调整一些参数可以识别出来,但还是其它的问题,应该是训练的模型中缺少对带面具的和动漫人物的人脸数据。

实现过程

还是先来看看代码吧,做这类开发,并没有想象中的那么难,因为难的核心别人都已经帮你实现了,所以和普通的程序开发没有什么不同,熟练掌握这些api的方法和功能就可以做出非常实用并且非常酷炫的产品。

1、准备素材

  下载每个人物的图片进行分类

2、上传服务器数据库

3、测试

代码解析

  这里对face-api.js类库代码做一下简单的说明

function dodetectpic() {
$.messager.progress();
//加载训练好的模型(weight,bias)
Promise.all([
faceapi.nets.faceRecognitionNet.loadFromUri('https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights'),
faceapi.nets.faceLandmark68Net.loadFromUri('https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights'),
faceapi.nets.faceLandmark68TinyNet.loadFromUri('https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights'),
faceapi.nets.ssdMobilenetv1.loadFromUri('https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights'),
faceapi.nets.tinyFaceDetector.loadFromUri('https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights'),
faceapi.nets.mtcnn.loadFromUri('https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights'),
//faceapi.nets.tinyYolov.loadFromUri('https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights')
]).then(async () => {
//在原来图片容器中添加一层用于显示识别的蓝色框框
const container = document.createElement('div')
container.style.position = 'relative'
$('#picmodal').prepend(container)
//先加载维护好的人脸数据(人脸的特征数据和标签,用于后面的比对)
const labeledFaceDescriptors = await loadLabeledImages()
//比对人脸特征数据
const faceMatcher = new faceapi.FaceMatcher(labeledFaceDescriptors, 0.6)
//获取输入图片
let image = document.getElementById('testpic')
//根据图片大小创建一个图层,用于显示方框
let canvas = faceapi.createCanvasFromMedia(image)
//console.log(canvas);
container.prepend(canvas)
const displaySize = { width: image.width, height: image.height }
faceapi.matchDimensions(canvas, displaySize)
//设置需要使用什么算法和参数进行扫描识别图片的人脸特征
const options = new faceapi.SsdMobilenetv1Options({ minConfidence: 0.38 })
//const options = new faceapi.TinyFaceDetectorOptions()
//const options = new faceapi.MtcnnOptions()
//开始获取图片中每一张人脸的特征数据
const detections = await faceapi.detectAllFaces(image, options).withFaceLandmarks().withFaceDescriptors()
//根据人脸轮廓的大小,调整方框的大小
const resizedDetections = faceapi.resizeResults(detections, displaySize)
//开始和事先准备的标签库比对,找出最符合的那个标签
const results = resizedDetections.map(d => faceMatcher.findBestMatch(d.descriptor))
console.log(results)
results.forEach((result, i) => {
//显示比对的结果
const box = resizedDetections[i].detection.box
const drawBox = new faceapi.draw.DrawBox(box, { label: result.toString() })
drawBox.draw(canvas)
console.log(box, drawBox)
})
$.messager.progress('close'); }) }
//读取人脸标签数据
async function loadLabeledImages() {
//获取人脸图片数据,包含:图片+标签
const data = await $.get('/FaceLibs/GetImgData');
//对图片按标签进行分类
const labels = [...new Set(data.map(item => item.Label))]
console.log(labels);
return Promise.all(
labels.map(async label => {
const descriptions = []
const imgs = data.filter(item => item.Label == label);
for (let i = ; i < imgs.length; i++) {
const item = imgs[i];
const img = await faceapi.fetchImage(`${item.ImgUrl}`)
//console.log(item.ImgUrl, img);
//const detections = await faceapi.detectSingleFace(img).withFaceLandmarks().withFaceDescriptor()
//识别人脸的初始化参数
const options = new faceapi.SsdMobilenetv1Options({ minConfidence:0.38})
//const options = new faceapi.TinyFaceDetectorOptions()
//const options = new faceapi.MtcnnOptions()
//扫描图片中人脸的轮廓数据
const detections = await faceapi.detectSingleFace(img, options).withFaceLandmarks().withFaceDescriptor()
console.log(detections);
if (detections) {
descriptions.push(detections.descriptor)
} else {
console.warn('Unrecognizable face')
}
}
console.log(label, descriptions);
return new faceapi.LabeledFaceDescriptors(label, descriptions)
})
) }

face-api.js

face-api 类库介绍

  face-api 有几个非常重要的方法下面说明一下都是来自 https://github.com/justadudewhohacks/face-api.js/ 的介绍

  在使用这些方法前必须先加载训练好的模型,这里并不需要自己照片进行训练了,face-api.js应该是在tensorflow.js上改的所以这些训练好的模型应该和python版的tensorflow都是通用的,所有可用的模型都在https://github.com/justadudewhohacks/face-api.js/tree/master/weights 可以找到

//加载训练好的模型(weight,bias)
// ageGenderNet 识别性别和年龄
// faceExpressionNet 识别表情,开心,沮丧,普通
// faceLandmark68Net 识别脸部特征用于mobilenet算法
// faceLandmark68TinyNet 识别脸部特征用于tiny算法
// faceRecognitionNet 识别人脸
// ssdMobilenetv1 google开源AI算法除库包含分类和线性回归
// tinyFaceDetector 比Google的mobilenet更轻量级,速度更快一点
// mtcnn 多任务CNN算法,一开浏览器就卡死
// tinyYolov2 识别身体轮廓的算法,不知道怎么用
Promise.all([
faceapi.nets.faceRecognitionNet.loadFromUri('https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights'),
faceapi.nets.faceLandmark68Net.loadFromUri('https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights'),
faceapi.nets.faceLandmark68TinyNet.loadFromUri('https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights'),
faceapi.nets.ssdMobilenetv1.loadFromUri('https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights'),
faceapi.nets.tinyFaceDetector.loadFromUri('https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights'),
faceapi.nets.mtcnn.loadFromUri('https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights'),
//faceapi.nets.tinyYolov.loadFromUri('https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights')
]).then(async () => {})

  非常重要参数设置,在优化识别性能和比对的正确性上很有帮助,就是需要慢慢的微调。

SsdMobilenetv1Options
export interface ISsdMobilenetv1Options {
// minimum confidence threshold
// default: 0.5
minConfidence?: number // maximum number of faces to return
// default: 100
maxResults?: number
} // example
const options = new faceapi.SsdMobilenetv1Options({ minConfidence: 0.8 })
TinyFaceDetectorOptions
export interface ITinyFaceDetectorOptions {
// size at which image is processed, the smaller the faster,
// but less precise in detecting smaller faces, must be divisible
// by 32, common sizes are 128, 160, 224, 320, 416, 512, 608,
// for face tracking via webcam I would recommend using smaller sizes,
// e.g. 128, 160, for detecting smaller faces use larger sizes, e.g. 512, 608
// default: 416
inputSize?: number // minimum confidence threshold
// default: 0.5
scoreThreshold?: number
} // example
const options = new faceapi.TinyFaceDetectorOptions({ inputSize: })
MtcnnOptions
export interface IMtcnnOptions {
// minimum face size to expect, the higher the faster processing will be,
// but smaller faces won't be detected
// default: 20
minFaceSize?: number // the score threshold values used to filter the bounding
// boxes of stage 1, 2 and 3
// default: [0.6, 0.7, 0.7]
scoreThresholds?: number[] // scale factor used to calculate the scale steps of the image
// pyramid used in stage 1
// default: 0.709
scaleFactor?: number // number of scaled versions of the input image passed through the CNN
// of the first stage, lower numbers will result in lower inference time,
// but will also be less accurate
// default: 10
maxNumScales?: number // instead of specifying scaleFactor and maxNumScales you can also
// set the scaleSteps manually
scaleSteps?: number[]
} // example
const options = new faceapi.MtcnnOptions({ minFaceSize: , scaleFactor: 0.8 })

  最常用的图片识别方法,想要识别什么就调用相应的方法就好了

// all faces
await faceapi.detectAllFaces(input)
await faceapi.detectAllFaces(input).withFaceExpressions()
await faceapi.detectAllFaces(input).withFaceLandmarks()
await faceapi.detectAllFaces(input).withFaceLandmarks().withFaceExpressions()
await faceapi.detectAllFaces(input).withFaceLandmarks().withFaceExpressions().withFaceDescriptors()
await faceapi.detectAllFaces(input).withFaceLandmarks().withAgeAndGender().withFaceDescriptors()
await faceapi.detectAllFaces(input).withFaceLandmarks().withFaceExpressions().withAgeAndGender().withFaceDescriptors() // single face
await faceapi.detectSingleFace(input)
await faceapi.detectSingleFace(input).withFaceExpressions()
await faceapi.detectSingleFace(input).withFaceLandmarks()
await faceapi.detectSingleFace(input).withFaceLandmarks().withFaceExpressions()
await faceapi.detectSingleFace(input).withFaceLandmarks().withFaceExpressions().withFaceDescriptor()
await faceapi.detectSingleFace(input).withFaceLandmarks().withAgeAndGender().withFaceDescriptor()
await faceapi.detectSingleFace(input).withFaceLandmarks().withFaceExpressions().withAgeAndGender().withFaceDescriptor()

学习AI资源

  ml5js.org https://ml5js.org/ 这里有很多封装好的详细的例子,非常好。

接下来我准备第二部分功能,通过摄像头快速识别人脸,做一个人脸考勤的应用。应该剩下的工作也不多了,只要接上摄像头就可以了

使用face-api.js实现人脸识别(一)的更多相关文章

  1. 百度人脸识别api及face++人脸识别api测试(python)

    一.百度人脸识别服务 1.官方网址:http://apistore.baidu.com/apiworks/servicedetail/464.html 2.提供的接口包括: 2.1 多人脸比对:请求多 ...

  2. face-api.js 前端人脸识别,人脸检测,登录认证

    1.参考face-api.js https://github.com/justadudewhohacks/face-api.js#face-api.js-for-the-browser

  3. PHP实现人脸识别技术

    这次人脸识别技术,是实现在微信端的,也就是说利用公众微信平台,调用第三的API来实现人脸识别这项技术的. 实现的思路: 首先呢,将收集的照片,建立一个照片库,然后利用在微信平台发送的照片,去到照片库进 ...

  4. opencv实现人脸识别(一)opencv的相关知识了解

    这回进行了人脸识别的项目,对学习过程进行记录. 首先进行的就是一系列环境的配置,如 python3.7的安装, python的IDE  pycharm的安装,然后进行opencv库的安装,可以通过py ...

  5. 转《在浏览器中使用tensorflow.js进行人脸识别的JavaScript API》

    作者 | Vincent Mühle 编译 | 姗姗 出品 | 人工智能头条(公众号ID:AI_Thinker) [导读]随着深度学习方法的应用,浏览器调用人脸识别技术已经得到了更广泛的应用与提升.在 ...

  6. 基于node.js人脸识别之人脸对比

    基于node.js人脸识别之人脸对比 Node.js简介 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. Node.js 使用了一个事件驱动.非阻塞式 I/O ...

  7. trackingjs+websocket+百度人脸识别API,实现人脸签到

    在公司做了个年会的签到.抽奖系统.用java web做的,用公司的办公app扫二维码码即可签到,扫完码就在大屏幕上显示这个人的照片.之后领导让我改得高大上一点,用人脸识别来签到,就把扫二维码的步骤改成 ...

  8. 高级web网页人脸识别tracking.js

    what?你没有看错,强大的JavaScript也可以实现人脸识别功能.小编精心整理了一个人脸识别的JavaScript库(tracking.js),通过这篇文章,你可以了解到如何在网页中实现一个人脸 ...

  9. 日常API之C#百度人脸识别

    最近看到一只我家徒儿发来的链接,原来是一堆百度AI的SDK,于是一时兴起就做了一只人脸识别,喵喵喵(●'◡'●) 一.准备工作 首先,当然是下载SDK啦:http://ai.baidu.com/sdk ...

随机推荐

  1. 云原生生态周报 Vol. 21 | Traefik 2.0 正式发布

    作者 | 浔鸣.心水.元毅.源三.衷源 业界要闻 CNCF 计划将 TOC 升至 11 人 技术监督委员会(TOC)是 CNCF 的三大核心管理机构之一,从 2020 年 1 月起,TOC 将从 9 ...

  2. 基于MFCC的语音数据特征提取概述

    1. 概述 语音是人类之间沟通交流的最直接也是最快捷方便的一种手段,而实现人类与计算机之间畅通无阻的语音交流,一直是人类追求的一个梦想. 伴随着移动智能设备的普及,各家移动设备的厂家也开始在自家的设备 ...

  3. 自定义构建基于.net core 的基础镜像

    先说一个问题 首先记录一个问题,今天在用 Jenkins 构建项目的时候突然出现包源的错误: /usr/share/dotnet/sdk/2.2.104/NuGet.targets(114,5): e ...

  4. CF #579 (Div. 3) D1.Remove the Substring (easy version)

    D1.Remove the Substring (easy version) time limit per test2 seconds memory limit per test256 megabyt ...

  5. Spring 梳理-webApplicationContext 与servletContext

    1.WebApplicationContext的研究 ApplicationContext是spring的核心,Context通常解释为上下文环境,用“容器”来表述更容易理解一些,Applicatio ...

  6. Linux——基本命令

    目录 一.目录切换命令 二.目录操作命令(增删改查) 2.1增加目录 2.2查看目录 2.3寻找目录(搜索) 2.4修改目录名称 2.5移动目录位置(剪切) 2.6拷贝目录 2.7删除目录 三.文件的 ...

  7. Java后台开发方向面试题集合

    内容会不断更新. 初衷是每次看面经肯定都会有一些一时反应不过来的问题,希望集中记录一下便于自己查看. 而答案部分谷歌就很好,当然有些问题可能需要多次谷歌. 对于一些记不住的答案,我也会持续写上一些. ...

  8. 【Visual Studio】关于vs 打开网站时报错 配置iis express失败 无法访问IIS元数据库...

    关于vs 打开网站时报错 配置iis express失败 无法访问IIS元数据库... 我安装了vs2015,一开始创建项目,网站都没问题,有一次突然打开项目时报错,瞬间懵逼,我啥都没干啊!!! 网上 ...

  9. 网页布局——Flex弹性框布局

    布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现. 需要安卓4.4及以上版本可以使用 ...

  10. 【POJ2001】Shortest Prefixes

    Shortest Prefixes Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 18724   Accepted: 810 ...