人脸检测和识别opencv_使用Node.js和OpenCV构建人脸检测应用

人脸检测和识别opencv

人类具有检测,处理和识别脸部的天生能力-我们与生俱来。 计算机也可以做到这一点-它只需要一些聪明的算法,大量代码和一些算法训练。

人脸检测是识别数字图像中人脸的过程。 不应将其与面部识别相混淆(即,尝试从照片中找出谁是谁),但这是过程的第一步。 面部识别再次成为一个巨大的话题,但是面部检测是本文的主题。

为了说明这一过程,这是一个示例图像:

NASA宇航员组15 —面部检测之前的原始图像

…这是人脸检测的作用:

NASA宇航员第15组-面部检测后突出显示面部

(来自维基百科的原始图片)

人脸检测的应用

人脸检测有许多应用。 一些现代生物识别系统先检测面部,然后使用面部识别将这些面部与数据库中的图像进行比较,以便尝试识别某人,而不必求助于老式的密码。 有些相机使用脸部侦测进行自动对焦。 像很多东西一样,它在营销中也有应用。

在本教程中,我们将复制一个功能,如果您是Facebook用户,您可能会使用自己的功能。 当您上传朋友的照片时,Facebook经常以突出显示任何面Kong的方式将照片显示给您,以提示您“标记”其中的人。 我们将构建类似的东西。

一点背景

在深入研究代码之前,让我们看一下将要使用的一些工具和概念。

OpenCV和Viola-Jones对象检测算法

OpenCV (开源计算机视觉)是包含数百种计算机视觉算法的开源库。 尽管OpenCV是用C ++编写的,但由于有opencv软件包,我们可以在Node.js应用程序中使用它。

在OpenCV中实现的算法中有Viola-Jones对象检测框架 ,该框架用于检测图像中的特征。

人脸检测只是特征(对象)检测的子集,但是该算法专门针对在检测人脸方面所涉及的挑战。

当然,当我们在这种情况下谈论特征检测时,它与Modernizr和yepnope之类的库提供的那种特征检测无关!

由Paul Viola和Michael J. Jones在2004年的文章中首次提出,这种方法已成为面部检测的事实上的标准。

您将在本教程后面的“ 进一步阅读”下找到该框架上的其他资源。

级联和分类器

Viola-Jones算法的一个重要方面是分类器的级联,它被描述为“具有类似哈尔特征的增强型分类器的级联”。 实际上,这意味着OpenCV已经过“训练”以在图像中寻找一组视觉特征,以识别特定类型的对象(在我们的情况下为面部)。 您可以在文档中找到有关级联和分类器的更多信息。 我们为实现过程提供了一个专门为识别人脸而设计的级联。

安装

在开始使用面部检测之前,我们需要安装一些先决条件。

启动和运行的最简单(也是推荐的方法)是使用Vagrant。 您将在本文随附的存储库中找到必要的配置和配置脚本。 如果使用这种方法,则无需完成这些安装步骤。

安装OpenCV

Linux(基于Debian的系统)

免费学习PHP!

全面介绍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,则安装就像从网站下载并运行可执行文件一样简单。 您可以在此处找到指向最新版本(在撰写本文时)的直接链接。

Mac OSX

在OSX上安装的最简单方法是使用Homebrew

brew tap homebrew/science
brew install opencv

您可以在此处找到更多说明。

影像魔术师

您还需要Imagemagick,它是我们将要使用的图像处理库的依赖项。

基于Debian的系统
apt-get install imagemagick
Mac OSX
brew install imagemagick
视窗

从此页面下载并运行适当的Windows Binary Release(它是一个可执行文件)。

建立我们的应用程序

提醒您,本教程的所有源代码都可以在Github上找到

让我们从定义一些依赖关系开始:

因此,事不宜迟,这是我们的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。 面部检测代码暂时被忽略了。 我们待会儿讨论。

我不会对此过程进行过多的介绍,因为它不是本文的重点-但是,如果您想了解发生了什么,请查看multereasyimage文档。

接下来,我们需要使用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变量将包含一个哈希表数组,每个发现的哈希表都有一个。 每个哈希将包含xy坐标( 0,0是图像的左上角)以及widthheight -从而定义了图像中被认为遮盖脸部的区域。

集成到我们的异步“瀑布”中后,它将如下所示:

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">&larr; 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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值