人脸检测和识别opencv
人类具有检测,处理和识别脸部的天生能力-我们与生俱来。 计算机也可以做到这一点-它只需要一些聪明的算法,大量代码和一些算法训练。
人脸检测是识别数字图像中人脸的过程。 不应将其与面部识别相混淆(即,尝试从照片中找出谁是谁),但这是过程的第一步。 面部识别再次成为一个巨大的话题,但是面部检测是本文的主题。
为了说明这一过程,这是一个示例图像:

…这是人脸检测的作用:

(来自维基百科的原始图片)
人脸检测有许多应用。 一些现代生物识别系统先检测面部,然后使用面部识别将这些面部与数据库中的图像进行比较,以便尝试识别某人,而不必求助于老式的密码。 有些相机使用脸部侦测进行自动对焦。 像很多东西一样,它在营销中也有应用。
在本教程中,我们将复制一个功能,如果您是Facebook用户,您可能会使用自己的功能。 当您上传朋友的照片时,Facebook经常以突出显示任何面Kong的方式将照片显示给您,以提示您“标记”其中的人。 我们将构建类似的东西。
在深入研究代码之前,让我们看一下将要使用的一些工具和概念。
OpenCV (开源计算机视觉)是包含数百种计算机视觉算法的开源库。 尽管OpenCV是用C ++编写的,但由于有opencv软件包,我们可以在Node.js应用程序中使用它。
在OpenCV中实现的算法中有Viola-Jones对象检测框架 ,该框架用于检测图像中的特征。
人脸检测只是特征(对象)检测的子集,但是该算法专门针对在检测人脸方面所涉及的挑战。
当然,当我们在这种情况下谈论特征检测时,它与Modernizr和yepnope之类的库提供的那种特征检测无关!
由Paul Viola和Michael J. Jones在2004年的文章中首次提出,这种方法已成为面部检测的事实上的标准。
您将在本教程后面的“ 进一步阅读”下找到该框架上的其他资源。
Viola-Jones算法的一个重要方面是分类器的级联,它被描述为“具有类似哈尔特征的增强型分类器的级联”。 实际上,这意味着OpenCV已经过“训练”以在图像中寻找一组视觉特征,以识别特定类型的对象(在我们的情况下为面部)。 您可以在文档中找到有关级联和分类器的更多信息。 我们为实现过程提供了一个专门为识别人脸而设计的级联。
在开始使用面部检测之前,我们需要安装一些先决条件。
启动和运行的最简单(也是推荐的方法)是使用Vagrant。 您将在本文随附的存储库中找到必要的配置和配置脚本。 如果使用这种方法,则无需完成这些安装步骤。

<source type="image/webp"><source><img src="https://s2.51cto.com/images/blog/202401/21000708_65abefacccb0839068.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=" alt="">
全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。 原价$ 11.95 您的完全免费
免费获得这本书
OpenCV本身具有许多先决条件,我们可以使用apt-get进行安装:
sudo apt-get install build-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev还有一些可选的依赖项:
sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev安装OpenCV本身最简单的方法是使用apt-get :
sudo apt-get install libopencv-dev在撰写本文时,它将安装版本2.4.8,尽管最新的2.x版本是2.4.11,并且当前存在版本3.0.0。 但是,当前版本3.0.0。上的Node.js包装器存在问题,因此此版本很好。
如果要从源代码构建,请先安装上面列出的依赖项,然后从“ 下载”页面下载文件并解压缩文件。
如上所述,3.0.0当前存在问题。 与Node.js模块结合使用,因此最好下载版本2.4.11。
现在我们需要构建它:
cd ~/opencv-2.4.11
mkdir release
cd release
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..
make
sudo make install请注意,最后一步可能需要一段时间!
如果您使用的是Windows,则安装就像从网站下载并运行可执行文件一样简单。 您可以在此处找到指向最新版本(在撰写本文时)的直接链接。
在OSX上安装的最简单方法是使用Homebrew :
brew tap homebrew/science
brew install opencv您可以在此处找到更多说明。
您还需要Imagemagick,它是我们将要使用的图像处理库的依赖项。
apt-get install imagemagickbrew install imagemagick从此页面下载并运行适当的Windows Binary Release(它是一个可执行文件)。
提醒您,本教程的所有源代码都可以在Github上找到 。
让我们从定义一些依赖关系开始:
我们使用express作为我们的Web应用程序的基础
把手是模板,随着快递车把
lodash实用程序库
multer是用于处理文件上传的中间件
easyimage是图像处理包
最后,我们使用异步来尝试避免回调地狱
因此,事不宜迟,这是我们的package.json :
{
"name": "sitepoint/face-detection",
"version": "1.0.0",
"description": "A simple application which demonstrates face detection in Node.js",
"main": "index.js",
"author": "Lukas White",
"license": "MIT",
"dependencies": {
"async": "^1.4.2",
"busboy": "^0.2.9",
"connect-busboy": "0.0.2",
"easyimage": "^2.0.3",
"express": "^4.13.3",
"express-handlebars": "^2.0.1",
"lodash": "^3.10.1",
"multer": "^1.0.3",
"opencv": "^3.0.0"
}
}使用npm install安装依赖项。
接下来,创建一些目录:
mkdir public
mkdir public/css
mkdir public/images
mkdir views
mkdir views/layouts
mkdir uploads现在为我们的应用程序创建一个基本布局( views/layouts/default.hbs ):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Face Detection Example</title>
<link rel="stylesheet" href="/css/bootstrap.min.css">
<link rel="stylesheet" href="/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="/css/styles.css">
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">Face Detection Example</a>
</div>
</div>
</nav>
<div id="main" class="container">
{{{body}}}
</div>
</body>
</html>我指的是Bootstrap框架来稍微修饰应用程序,但这是可选的。 您可以自己下载文件,也可以在本文随附的存储库中找到它们。
添加一些基本样式( public/css/styles.css ):
#main {
margin-top: 50px;
}
.frame {
position: relative;
}
.frame a {
display: block;
position: absolute;
border: solid 2px #fff;
border-radius: 50%;
}
.frame a:hover {
background: rgba(0,0,0,0.5);
}现在,让我们实现一个框架Express应用程序( index.js ):
var express = require('express')
, http = require('http')
, async = require('async')
, multer = require('multer')
, upload = multer({ dest: 'uploads/' })
, exphbs = require('express-handlebars')
, easyimg = require('easyimage')
, _ = require('lodash')
, cv = require('opencv');
// MIME types for image uploads
var exts = {
'image/jpeg': '.jpg',
'image/png' : '.png',
'image/gif' : '.gif'
};
var port = 8080;
var app = express();
app.use(express.static(__dirname + '/public'))
// Configure Handlebars
app.engine('.hbs', exphbs({ extname: '.hbs', defaultLayout: 'default' }));
app.set('view engine', '.hbs');
/**
* This is a placeholder for the application code
*/
http.createServer(app)
.listen(port, function(server) {
console.log('Listening on port %d', port);
});希望这些评论将使您对这里发生的事情有所了解。
我们还需要一个简单的GET路线:
app.get('/', function( req, res, next ) {
return res.render('index');
});相应的视图( views/index.hbs )本质上只是一个文件上传表单:
<div>
<h2>Please upload an image.</h2>
<p><em>Note: please ensure it's at least 960 x 300 pixels in size.</em></p>
</div>
<form method="post" action="/upload" enctype="multipart/form-data">
<div class="form-group">
<input type="file" name="file">
</div>
<div class="form-group">
<input type="submit" value="Submit" class="btn btn-primary">
</div>
</form>在进入人脸检测的本质之前,我们需要构建一个简单的文件上传机制。 这将允许用户上传图片,我们将其调整为合理的大小,然后将其显示回给他们。
这是代码:
// POST callback for the file upload form.
app.post('/upload', upload.single('file'), function(req, res, next){
// Use filename generated for us, plus the appropriate extension
var filename = req.file.filename + exts[req.file.mimetype]
// and source and destination filepaths
, src = __dirname + '/' + req.file.path
, dst = __dirname + '/public/images/' + filename;
async.waterfall(
[
function(callback){
// Check the mimetype to ensure the uploaded file is an image
if (!_.contains(['image/jpeg','image/png','image/gif'],req.file.mimetype)){
return callback(new Error(
'Invalid file - please upload an image (.jpg, .png, .gif).')
)
}
return callback();
},
function(callback){
// Get some information about the uploaded file
easyimg.info(src).then(
function(file){
// Check that the image is suitably large
if ((file.width我们在这里所做的就是抓取一个已上传的文件,确保它是图像,并检查其最小尺寸,如果是,则将其调整为960px。 面部检测代码暂时被忽略了。 我们待会儿讨论。
我不会对此过程进行过多的介绍,因为它不是本文的重点-但是,如果您想了解发生了什么,请查看multer和easyimage文档。
接下来,我们需要使用OpenCV库读取图像。 在幕后,这会将图像转换为像素矩阵,然后可以在其上运行特征检测算法。
我们用于执行此操作的方法具有以下签名:
cv.readImage(filepath, function(err, im){
// do something with the matrix referred to by the im variable
});因为我们使用的是async模块,所以我们可以简单地将回调作为第二个参数传递给它。 第一个参数是目的地dst ; 也就是说,调整大小的结果。 因此,有问题的函数如下所示:
function(callback){
//Use OpenCV to read the (resized) image
cv.readImage(dst, callback);
},接下来,我们需要运行特征检测算法,它是Matrix类的一种方法。 这是签名:
im.detectObject(classifier, options, function(err, faces){
// faces contains an array of data about any faces it's found
});一切都很好, faces变量将包含一个哈希表数组,每个发现的哈希表都有一个。 每个哈希将包含x和y坐标( 0,0是图像的左上角)以及width和height -从而定义了图像中被认为遮盖脸部的区域。
集成到我们的异步“瀑布”中后,它将如下所示:
function(im, callback){
// Run the face detection algorithm
im.detectObject(cv.FACE_CASCADE, {}, callback);
}请注意,我们正在指定一个专cv.FACE_CASCADE脸检测而设计的预制分类器( cv.FACE_CASCADE )。
在最后一个回调中( async.waterfall()的第二个参数async.waterfall() ,如果出现问题,我们将渲染错误模板,否则我们将渲染结果,将上传图像的文件名以及面部数据数组传递给我们。
总结了我们需要对index.js进行的更改。 请花一点时间在GitHub上查看完整的文件 。
我们需要做的最后一件事是定义剩下的两个视图。 错误视图( views/error.hbs )仅向用户显示消息:
<div class="alert alert-error" role="alert">
<strong>An error has occured:</strong>
{{ message }}
</div>
<a href="/" class="btn btn-default">← Go back and try again</a>结果视图( views\result.hbs )更加有趣:
{{#if faces.length}}
<div class="alert alert-success" role="alert">
I found <strong>{{faces.length}}</strong> face(s).
</div>
{{else}}
<div class="alert alert-warning" role="alert">
Sorry, but I couldn't find any faces...
</div>
{{/if}}
<div class="frame">
<img src="/images/{{ filename }}">
{{#each faces}}
<a href="#" style="width: {{ width }}px;
height: {{ height }}px;
left: {{ x }}px;
top: {{ y }}px;"></a>
{{/each}}
</div>
<a href="/" class="btn btn-default">Go back and try another</a><div> ,该图像已分配了position: relative
现在运行该应用程序:
node index.js请注意,您可能会看到以下警告:
libdc1394 error: Failed to initialize libdc1394由于libdc1394来实现我们的目的,因此您可以按照以下Stackoverflow答案中的说明 ,使用以下命令将其禁用:
sudo ln /dev/null /dev/raw1394请谨慎使用,因为它可能会影响系统上安装的其他应用程序
现在,在浏览器中访问该应用程序。 如果您使用的是Vagrant,则可以在以下位置找到它:
http://192.168.10.10:8080/一切顺利,您应该看到上传表格:

这是成功的面部检测尝试结果的示例:

您可以从此处获取屏幕快照中显示的图像,或者尝试使用自己的图像。 需要注意的一件事是,该方法要求正面朝上且直立,并且正面必须全貌。
总结和进一步阅读
到此结束了我们对人脸检测的简要介绍,在此期间,我们为Facebook的照片标签小部件的克隆奠定了基础。
如果您想要真正深入地了解Viola-Jones对象检测框架的实现指南,您可能会对丹麦技术大学的Ole Helvig Jensen的论文感兴趣。 您可能还会发现此YouTube视频有用的背景。
OpenCV还有很多值得探索的地方。 文档 (尤其是教程)是一个良好的开端; 但是请注意,这些主要是针对C ++的。
您还能提出其他哪些应用程序? 在评论中让我知道。
翻译自: https://www.sitepoint.com/face-detection-nodejs-opencv/
人脸检测和识别opencv
















