人脸Haar特征与快速计算神器:积分图

背景介绍

iPhone十周年纪念之作iPhoneX刚刚发布,其搭载的“刷脸解锁”功能再次将“人脸识别”技术带入大众视野。

借iPhoneX的东风,今天给大家介绍一下人脸检测的关键特征:Haar特征,并讲解如何快速计算待检测图像对应的积分图。

iPhoneX

Haar特征

想象一下现在你手上有一张图像需要用来做人脸检测,在人脸检测时有一个子窗口在待检测的图片中不断地移动,计算出对应位置的特征。将计算出的特征送到人脸分类器(本文主要讲解Haar特征及其计算,分类器的训练不涉及)中进行判断,通过筛选的区域则判断为人脸,反之则不是人脸。

那么,这个特征如何表示呢?

Viola、Lienhart等大牛提出了Haar特征。

其实,Haar特征本身并不复杂,就是用图中黑色矩形区域内所有像素值的和减去白色矩形区域内所有像素值的和,得到的值称为人脸特征值,如果Haar矩形放到非人脸区域,那么计算出的值和人脸特征值是不一样的。

但是,在实际使用Haar特征的过程中我们发现,Haar矩形特征是与矩形模版类别、矩形位置和矩形大小这三个变量的函数。随着矩形模板类别、大小和位置的变化,使得在检测的过程中会产生大量的特征值,如:在24*24像素大小的检测窗口内产生的矩形特征数量就超过10万个了。那么,如何可以快速计算出大量的Haar特征值呢?

下面,就需要介绍人脸检测中的神器——积分图!

积分图

首先给出积分图的定义:对于一张积分图ii(i,j),其位置(i,j)处的值ii(i,j)是是原图像i(i,j)左上角方向所有像素的和。

积分图的构建算法:

1. 用s(i,j)表示行方向的累加和,初始化s(i,-1)=0;

2. 用ii(i,j)表示一个积分图像,初始化ii(-1,j)=0;

3. 逐行扫描图像,计算每个像素(i,j)行方向的累加和s(i,j)和积分图像ii(i,j)的值:

s(i,j)=s(i,j-1)+i(i,j)

ii(i,j)=ii(i-1,j)+s(i,j)

4. 扫描图像一遍,当到达图像右下角像素时,积分图像ii就构造好了。

构造好积分图后,记图像中某一矩形区域A的四个顶点为a,b,c,d(左上角标为a,其余顶点按照顺时针次序标记),矩形区域A的像素和S(比如用某个Haar特征模板扫描图像时,需要计算白色区域或黑色区域的像素和)就可以这样计算:S=ii(a)+ii(c)-ii(b)-ii(d)(建议读者自行画图体会这个公式的妙处~)

这样,对于任意大小的矩形模板,只需查找积分图像4次就可以求得任意矩形的像素值的和,大大减少了计算量!

同时,只需要遍历一边图像,就可以计算得到所有子窗口的的Haar特征值,真可谓神器也!

OpenCV实现人脸检测

#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/objdetect/objdetect.hpp"
using namespace cv;
using namespace std;
string face_cascade_name = "haarcascade_frontalface_alt2.xml";
CascadeClassifier face_cascade;
string window_name = "人脸实时检测程序";
void detectAndDisplay(Mat frame){
   std::vector<Rect> faces;
   Mat frame_gray;
   cvtColor(frame, frame_gray, CV_BGR2GRAY);
   equalizeHist(frame_gray, frame_gray);
   face_cascade.detectMultiScale(frame_gray, 
        faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));
   for (int i = 0; i < faces.size(); i++){
      Point center(faces[i].x + faces[i].width*0.5, 
         faces[i].y + faces[i].height*0.5);
      ellipse(frame, center, Size(faces[i].width*0.5, 
   faces[i].height*0.5), 0, 0, 360, Scalar(255, 0, 255), 4, 8, 0);
   }
   imshow(window_name, frame);
}

int main(int argc, char* argv[])
{
   VideoCapture cap(0);
   if (!cap.isOpened())
      return -1;
   Mat edges;
   //namedWindow("edges", 1);
   if (!face_cascade.load(face_cascade_name)){
      printf("[error] 无法加载级联分类器文件!\n");
      return -1;
   }
   int nTick = 0;
   for (;;)
   {
      if (!cap.isOpened())
      {//等等摄像头打开
         continue;
      }
      Mat frame;
      nTick = getTickCount();
      cap >> frame; // get a new frame from camera
      if (frame.data == NULL)
      {//等到捕获到数据
         continue;
      }
      cvtColor(frame, edges, CV_BGR2BGRA);
      detectAndDisplay(edges);
      if (waitKey(30) >= 0) break;
   }
   return 0;
}

运行效果

(PS.保护舍友安全,舍友太帅,已经有女朋友了......)

原文发布于微信公众号 - 机器学习算法全栈工程师(Jeemy110)

原文发表时间:2017-09-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏计算机视觉战队

Deep Learning(深度学习)神经网络为啥可以识别?

今天看到一些感兴趣的东西,现在总结了给大家分享一下,如果有错,希望大家指正批评,谢谢!那就开始进入正题。 先从简单的说起来吧! 一、基本变换:层 一般的神经...

2706
来自专栏SIGAI学习与实践平台

OCR技术简介

光学字符识别(Optical Character Recognition, OCR)是指对文本资料的图像文件进行分析识别处理,获取文字及版面信息的过程。亦即将图...

6861
来自专栏WD学习记录

K-means中K值的选取

以下博文转自:https://blog.csdn.net/qq_15738501/article/details/79036255  感谢

1382
来自专栏CVer

[计算机视觉论文速递] ECCV 2018 专场11

Amusi 将日常整理的论文都会同步发布到 daily-paper-computer-vision 上。名字有点露骨,还请见谅。喜欢的童鞋,欢迎star、for...

1493
来自专栏机器之心

ICML 2018 | MILA提出防御增强型网络:简单修改已有网络即可提升防攻击能力

选自arXiv 作者:Alex Lamb, Jonathan Binas, Anirudh Goyal, Dmitriy Serdyuk, Sandeep Su...

3065
来自专栏用户2442861的专栏

Deep Learning(深度学习)学习笔记整理系列之(二)

1)该Deep Learning的学习系列是整理自网上很大牛和机器学习专家所无私奉献的资料的。具体引用的资料请看参考文献。具体的版本声明也参考原文献。

621
来自专栏AI研习社

谷歌发布TensorFlow Lattice:得益于先验知识,提升模型泛化能力

AI研习社消息,近日,谷歌科学家发布TensorFlow Lattice,这是一套预建的TensorFlow Estimators,易于使用,它相当于是Tens...

3929
来自专栏新智元

Goodfellow回谷歌后首篇GAN论文:可迁移性对抗样本空间

【新智元导读】昨天 Ian Goodfellow 和他在斯坦福大学以及宾夕法尼亚州立大学的合作者在 arXiv 上传了 Ian Goodfellow 回到谷歌后...

52617
来自专栏大数据互联网思维

HDR关键技术:逆色调映射

HDR技术近年来发展迅猛,在未来将会成为图像与视频领域的主流。当前HDR内容非常短缺,限制了HDR视听节目的广泛应用。逆色调映射(Inverse Tone Ma...

1360
来自专栏人工智能头条

张雨石:关于深度学习中的dropout的两种理解

2092

扫码关注云+社区