![1f43b7af7b9e439ccf04354cc55ff621.png](https://i-blog.csdnimg.cn/blog_migrate/60d957e04d5ea1db6ae08509fc091603.jpeg)
长按扫描维码关注
EDC.CV计算机视觉研究院专栏
作者:Edison_G
参考 face-api.js https://github.com/justadudewhohacks/face-api.js#face-api.js-for-the-browse
关注并星标
从此不迷路
计算机视觉研究院![66921b845584ee5e3eef1699ec4e2bab.gif](https://i-blog.csdnimg.cn/blog_migrate/58d9af6f84f84205e74725016767c74b.gif)
功能
第一阶段实现对图片中人脸的识别并打上标签(比如:人名) 第二阶段使用摄像头实现对人物的识别,比如典型的应用做一个人脸考勤的系统资源
- face-api.js https://github.com/justadudewhohacks/face-api.js/
- filepond https://github.com/pqina/filepond
- fancyBox https://fancyapps.com/fancybox/3/
设计思路
准备一个人脸数据库,上传照片,并打上标签(人名),最好但是单张脸的照片,测试的时候可以同时对一张照片上的多个人物进行识别;
提取人脸数据库中的照片和标签进行量化处理,转化成一堆数字,这样就可以进行比较匹配;
- 使用一张照片来测试一下匹配程度。
还是先来看看代码吧,做这类开发,并没有想象中的那么难,因为难的核心别人都已经帮你实现了,所以和普通的程序开发没有什么不同,熟练掌握这些api的方法和功能就可以做出非常实用并且非常酷炫的产品。
1、准备素材:下载每个人物的图片进行分类
2、上传服务器数据库
3、测试
Face Landmark Detection
Face Recognition
Face Expression Recognition
Running the Examples
Clone the repository:
git clone https://github.com/justadudewhohacks/face-api.js.git
Running the Browser Examples
cd face-api.js/examples/examples-browser
npm i
npm start
Browse to http://localhost:3000/.
Running the Nodejs Examples
cd face-api.js/examples/examples-nodejs
npm i
Now run one of the examples using ts-node:
ts-node faceDetection.ts
Or simply compile and run them with node:
tsc faceDetection.ts
node faceDetection.js
代码·解析
这里对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 = 0; 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 类库介绍
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 () => {})
非常重要参数设置,在优化识别性能和比对的正确性上很有帮助,就是需要慢慢的微调。
SsdMobilenetv1Optionsexport interface ISsdMobilenetv1Options { // minimum confidence threshold // default: 0.5 minConfidence?: number // maximum number of faces to return // default: 100 maxResults?: number}// exampleconst options = new faceapi.SsdMobilenetv1Options({ minConfidence: 0.8 })TinyFaceDetectorOptionsexport 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}// exampleconst options = new faceapi.TinyFaceDetectorOptions({ inputSize: 320 })MtcnnOptionsexport 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[]}// exampleconst options = new faceapi.MtcnnOptions({ minFaceSize: 100, scaleFactor: 0.8 })
最常用的图片识别方法,想要识别什么就调用相应的方法就好了。
// all facesawait 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 faceawait 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()
Detecting Faces
Detect all faces in an image. Returns Array:
const detections = await faceapi.detectAllFaces(input)
Detect the face with the highest confidence score in an image. Returns FaceDetection | undefined:
const detection = await faceapi.detectSingleFace(input)
By default detectAllFaces and detectSingleFace utilize the SSD Mobilenet V1 Face Detector. You can specify the face detector by passing the corresponding options object:
const detections1 = await faceapi.detectAllFaces(input, new faceapi.SsdMobilenetv1Options())const detections2 = await faceapi.detectAllFaces(input, new faceapi.TinyFaceDetectorOptions())
具体可以参考官方Github具体步骤!
/End.
![dd3405c1b1e5031e523011fb16e85551.gif](https://i-blog.csdnimg.cn/blog_migrate/64b945630496673c2525507cb9f05abe.gif)
我们开创“计算机视觉协会”知识星球一年有余,也得到很多同学的认可,我们定时会推送实践型内容与大家分享,在星球里的同学可以随时提问,随时提需求,我们都会及时给予回复及给出对应的答复。
![1f43b7af7b9e439ccf04354cc55ff621.png](https://i-blog.csdnimg.cn/blog_migrate/60d957e04d5ea1db6ae08509fc091603.jpeg)
长按扫描维码关注我们
EDC.CV