转译《opencv4nodejs人脸识别》

在本文中,我将向你展示如何使用face-recognition.js执行可靠的人脸检测和识别 。 我曾经试图找一个能够精确识别人脸的Node.js库,但是没有找到,因此,我决定自己搞一个! 

这个npm包基于dlib实现,因为我发现dlib的识别精度很高。 dlib库使用深度学习方法,并附带一些预训练的模型,这些预置的模型,在LFW人脸识别基准测试上可以达到惊人的准确度:99.38% 。

为什么要搞这个东西?

最近我一直在尝试使用Node.js来构建一个人脸识别应用程序,以便从《生活大爆炸》剧中来提取和识别人物的面部。最初,我想用OpenCV的人脸识别器来实现,思路类似于我在教程Node.js + OpenCV for Face Recognition中的类似。

但是,虽然这些人脸识别器能够提供快速的预测结果,但是我发现它们不够健壮。 更确切地说,虽然他们适用于正面的人脸图像,但只要人脸姿势略有不同,就会产生相当不靠谱的预测结果。

因此,我就开始寻找替代方案,然后发现了dlib这个 C ++库,我用它的Python API试了一下,结果给我留下了深刻的印象,最后我决定: 用Node.js来实现这个功能! 因此,我创建了这个npm包,提供一个简化的Node.js 的API用于人脸识别。

face-recognition.js是什么?

我开发face-recognitiontion.js的目的,是想提供一个这样的npm包:

  • 有一个简单的API,可以让人快速上手人脸识别
  • 如果需要的话仍然允许更细粒度的识别控制
  • 易于设置(最好敲一行命令就能安装,例如npm install)

虽然这个软件包还在开发中,现在已经可以用它做点事情了:

人脸检测

你可以使用深度神经网络进行人脸检测,也可以使用简单的正面人脸识别器进行快速但但不那么可靠的检测:

人脸识别

人脸识别器是一个深度神经网络,它使用我提到的模型来计算一个独特的人脸描述符。 这个人脸识别器用标注过的人脸图像进行训练后,就可以预测输入人脸图像的标签:

人脸特征点检测

你也可以使用这个包来检测面部的特征点(5个或68个):

实战效果!

好吧,正如我所说的,我开始时尝试用OpenCV,但没能完成这个任务。 现在我有一堆150x150大小的人脸图像(分别来自Sheldon 、Raj 、 Lennard 、Howard和Stuart),我将向你展示使用这些数据来训练人脸识别器、识别新面孔是多么的简单。 这个例子的代码可以在这个仓库上找到。

准备数据

剧中每个角色不同的姿态分别采集大概20张图像:

我们将分别使用每个人的10个图像来训练识别器,其余部分来评估识别器的准确性:

const path = require(‘path‘)
const fs = require(‘fs‘)
const fr = require(‘face-recognition‘)

const dataPath = path.resolve(‘./data/faces‘)
const classNames = [‘sheldon‘, ‘lennard‘, ‘raj‘, ‘howard‘, ‘stuart‘]

const allFiles = fs.readdirSync(dataPath)
const imagesByClass = classNames.map(c =>
  allFiles
    .filter(f => f.includes(c))
    .map(f => path.join(dataPath, f))
    .map(fp => fr.loadImage(fp))
)

const numTrainingFaces = 10
const trainDataByClass = imagesByClass.map(imgs => imgs.slice(0, numTrainingFaces))
const testDataByClass = imagesByClass.map(imgs => imgs.slice(numTrainingFaces))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

每个脸部图像的文件名中包含了人名,所以我们可以简单地实现图像和其分类的映射:

[‘sheldon‘, ‘lennard‘, ‘raj‘, ‘howard‘, ‘stuart‘]
  • 1

你可以使用fr.loadImage(fp)读取给定文件路径的图像。

检测人脸

正如我所说的,图像已经提取为150x150的大小,这是我事先用opencv4nodejs完成的。 但是你也可以用下面的代码来检测和提取人脸、保存并进行标注:

const image = fr.loadImage(‘image.png‘)
const detector = fr.FaceDetector()
const targetSize = 150
const faceImages = detector.detectFaces(image, targetSize)
faceImages.forEach((img, i) => fr.saveImage(img, `face_${i}.png`))
  • 1
  • 2
  • 3
  • 4
  • 5

训练识别器

现在我们有了数据,可以开始训练识别器:

const recognizer = fr.FaceRecognizer()

trainDataByClass.forEach((faces, label) => {
  const name = classNames[label]
  recognizer.addFaces(faces, name)
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

基本上这就是把每张人脸图像输入到神经网络中,神经网络输出面部的描述符并存储指定类别的所有描述符。 你还可以通过将numJitters指定为第三个参数来利用训练数据生成一些抖动后的图像,这个参数将应用旋转 、缩放和镜像等变换来创建每个输入人脸的不同版本图像。 增加抖动版本的数量可能有助于提高预测的准确性,但同时也会增加训练时间。

此外,我们可以存储识别器的状态,这样就不必在下次要用时重新进行训练了,只需要简单地从一个文件中加载训练好的模型:

保存:

const modelState = recognizer.serialize()
fs.writeFileSync(‘model.json‘, JSON.stringify(modelState))
  • 1
  • 2

加载:

const modelState = require(‘model.json‘)
recognizer.load(modelState)
  • 1
  • 2

识别新面孔

现在我们可以用剩余的样本数据来检查预测精度并记录结果:

const errors = classNames.map(_ => [])
testDataByClass.forEach((faces, label) => {
  const name = classNames[label]
  console.log()
  console.log(‘testing %s‘, name)
  faces.forEach((face, i) => {
    const prediction = recognizer.predictBest(face)
    console.log(‘%s (%s)‘, prediction.className, prediction.distance)

    // count number of wrong classifications
    if (prediction.className !== name) {
      errors[label] = errors[label] + 1
    }
  })
})

// print the result
const result = classNames.map((className, label) => {
  const numTestFaces = testDataByClass[label].length
  const numCorrect = numTestFaces - errors[label].length
  const accuracy = parseInt((numCorrect / numTestFaces) * 10000) / 100
  return `${className} ( ${accuracy}% ) : ${numCorrect} of ${numTestFaces} faces have been recognized correctly`
})
console.log(‘result:‘)
console.log(result)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

当前的预测是通过计算输入人脸图像的描述符向量到分类中每个描述符的欧式距离来完成的,同时也计算出所有距离的平均值 。 有人可能会说, kmeans聚类或SVM分类器将更适合这个任务,我也可能在将来实现这些算法。 但是现在使用欧几里德距离的实现,看起来执行速度很快而且效率够高。

调用predictionBest将输出具有最小距离(例如最高相似度)的结果。 输出看起来像这样:

{className:‘sheldon‘,距离:0.5} 
  • 1

如果你想获得所有分类的脸部描述符到输入的人脸图像的距离,可以简单地使用recognitionizer.predict(image) ,它将输出一个数组,其成员包含输入图像到每个分类的距离:

  [
  {className:‘sheldon‘,距离:0.5},
  {className:‘raj‘,距离:0.8},
  {className:‘howard‘,距离:0.7},
  {className:‘lennard‘,距离:0.69},
  {className:‘stuart‘,距离:0.75}
  ] 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

结果

运行上面的例子将给出以下结果。

使用10个面孔进行训练:

sheldon ( 90.9% ) : 10 of 11 faces have been recognized correctly
lennard ( 100% ) : 12 of 12 faces have been recognized correctly
raj ( 100% ) : 12 of 12 faces have been recognized correctly
howard ( 100% ) : 12 of 12 faces have been recognized correctly
stuart ( 100% ) : 3 of 3 faces have been recognized correctly
  • 1
  • 2
  • 3
  • 4
  • 5

每个训练只使用5个面孔 :

sheldon ( 100% ) : 16 of 16 faces have been recognized correctly
lennard ( 88.23% ) : 15 of 17 faces have been recognized correctly
raj ( 100% ) : 17 of 17 faces have been recognized correctly
howard ( 100% ) : 17 of 17 faces have been recognized correctly
stuart ( 87.5% ) : 7 of 8 faces have been recognized correctly
  • 1
  • 2
  • 3
  • 4
  • 5

结论

从结果看,即使只用一小组数据进行训练,也可以获得相当准确的结果。甚至对这些我从网上抓取的小尺寸图像(一些提取的脸部非常模糊), 结果也令人非常满意。

原文地址:https://www.cnblogs.com/ckAng/p/9334081.html

时间: 2024-10-08 11:05:42

转译《opencv4nodejs人脸识别》的相关文章

[译]Kubernetes 分布式应用部署和人脸识别 app 实例

原文地址:KUBERNETES DISTRIBUTED APPLICATION DEPLOYMENT WITH SAMPLE FACE RECOGNITION APP 原文作者:skarlso 译文出自:掘金翻译计划 好的,伙计,让我们静下心来.下面将会是一个漫长但充满希望和有趣的旅程. 我将使用 Kubernetes 部署分布式应用程序.我试图创建一个类似于真实世界 app 的应用程序.显然,由于时间和精力有限,我不得不忽略一些细节部分. 我的重点将放在 Kubernetes 和应用部署上.

Github开源人脸识别项目face_recognition

Github开源人脸识别项目face_recognition 原文:https://www.jianshu.com/p/0b37452be63e 译者注: 本项目face_recognition是一个强大.简单.易上手的人脸识别开源项目,并且配备了完整的开发文档和应用案例,特别是兼容树莓派系统. 为了便于中国开发者研究学习人脸识别.贡献代码,我将本项目README文件翻译成中文. 向本项目的所有贡献者致敬. 英译汉:同济大学开源软件协会 子豪兄Tommy Translator's note: f

「圣诞特辑」纯前端实现人脸识别自动佩戴圣诞帽

在线体验地址:hksite.cn/prjs/christmashat 源码地址:https://github.com/hk029/christmas-hat 写在开头 叮叮当,叮叮当,吊儿个郎当,一年一度的圣诞节到咯,我不由的回想起了前两年票圈被圣诞帽支配的恐惧.打开票圈全是各种@官方求帽子的: 票圈头像也瞬间被圣诞帽攻陷: 在那段时间,你没一顶圣诞帽还真不好意思发票圈 各种戴帽子的软件也如雨后春笋般浮现出来,不管是小程序还是美图软件无一例外的都增加了戴圣诞帽的功能.但是对于懒人的我来说,自己调

多维活体检测,让人脸识别更安全

今年的315晚会提到人脸识别领域的安全风险,主持人用现场合成的视频通过了活体检测和人脸验证,因此人脸识别的安全性引起大众关注.对于活体检测的安全隐患,腾讯优图团队一直保持高度关注,并依托多年积累的技术能力和业务运营经验,已经对人脸识别技术手段进行过多次安全升级,让人脸识别更安全. 一.目前人脸识别常见攻击手段有什么? 1 .纸片翻拍,通过打印用户的照片进行攻击: 2. 屏幕翻拍,一些3D建模技术可以驱动用户的单张照片或视频做出系统要求的摇头.张嘴.眨眼等动作: 3. 用户戴面具: 二.如何应对人

【下载】推荐一款免费的人脸识别SDK

现已进入刷脸的时代,例如,人脸支付.人脸识别的门禁.人流监控等等.如何在Firefly开源板上快速搭建DEMO,并快速产品化?为了让更多产品可以用上人脸识别技术,Firefly推出了一款高性能人脸识别SDK.此SDK的人脸识别的算法,运行效率高,识别精确度高,性能优异,可以直接应用于商业产品. 下文主要讲述如何在Firefly RK3399平台部署并测试OpenFace SDK,Let's GO!      一.Firefly RK3399开源板安装Ubuntu 16.04系统固件      系

趣拍云:助力APP一周上线人脸识别+动态贴纸

年初,某美图软件上线的"一秒变福娃"引发了全民COS狂潮.配合新年的欢乐气氛,人们纷纷拿起手机,将自己的照片P成福娃的模样,并发到朋友圈送出新年祝福.娱乐化的玩法,不仅收到了年轻粉丝群体的追捧,更带来了巨大的话题量和高流量.而就在近日,国内领先的移动视频云服务商趣拍云也将这一人脸贴图功能开放,可供开发者快速集成如同FaceU的短视频拍摄SDK,实现产品娱乐化与个性化. 开发"神器",助你轻松客服技术难题 立体化和高覆盖的话题营销,自然与产品独特的切入点密不可分.越来

【从零学习openCV】IOS7人脸识别实战

前言 接着上篇<IOS7下的人脸检測>,我们顺藤摸瓜的学习怎样在IOS7下用openCV的进行人脸识别,实际上非常easy,因为人脸检測部分已经完毕,剩下的无非调用openCV的方法对採集到的人脸样本进行训练,终于得到一个能够预測人脸的模型.可是当中的原理可谓是博大精深,因为快临最近末考试了,没时间去琢磨当中详细的细节,这次就先写个大概的demo,下次更新文章就得到6月20号之后了. 原理: 从OpenCV2.4之后,openCV增加了新的类FaceRecognizer,我们能够使用它便捷地进

FaceNet--Google的人脸识别

引入 随着深度学习的出现,CV领域突破很多,甚至掀起了一股CV界的创业浪潮,当次风口浪尖之时,Google岂能缺席.特贡献出FaceNet再次刷新LFW上人脸验证的效果记录. 本文是阅读FaceNet论文的笔记,所有配图均来自于论文. 转载请注明:http://blog.csdn.net/stdcoutzyx/article/details/46687471 FaceNet 与其他的深度学习方法在人脸上的应用不同,FaceNet并没有用传统的softmax的方式去进行分类学习,然后抽取其中某一层

支持向量机 人脸识别(SVM)SKLearn

#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import pylab as pl from sklearn import svm # we create 40 separable points np.random.seed(0)#每次运行结果不变 X = np.r_[np.random.randn(20, 2) - [2, 2], np.random.randn(20, 2) + [2, 2]] #randn2