在计算机视觉领域中,人脸检测或者物体检测一直是一个非常受关注的领域,而在人脸检测中,Viola-Jones人脸检测算法可以说是非常经典的一个算法,所有从事人脸检测研究的人,都会熟悉了解这个算法,Viola-Jones算法在2001年的CVPR上提出,因为其高效而快速的检测即使到现在也依然被广泛使用,OpenCV 和 Matlab中都将这个算法写进了函数库可以很方便的直接调用。虽然VJ人脸检测算法最初都是用来检测正面的人脸图像,对于侧脸图像的检测不是很稳健,不过这个算法依然有值得研究的价值。

这个算法包含以下几个重要的部分:

1 利用Haar 特征描述人脸的共有属性;

2 建立了一种称为积分图像的特征,并且基于积分图像,可以快速获取几种不同的矩形特征;

3 利用Adaboost 算法进行训练;

4 建立层级分类器。

利用Haar 特征描述人脸的共有属性 

一般来说,人脸会有一些基本的共性,比如眼睛区域会比脸颊区域要暗很多,鼻子一般属于脸部的高光区域,鼻子会比周围的脸颊要亮很多,一张正脸图像,眼睛,眉毛,鼻子,嘴巴等的相对位置是有规律可循的。Haar 特征考虑的是某一特定位置相邻的矩形区域,把每个矩形区域的像素相加然后再相减,总得来说,基本对应以下几种情形:

[−1,1],[1,−1],[1,−1,1],[−1,1,−1]
[1−1−11]

我们以前都是针对单一像素做,现在需要针对矩形区域,相当于是把单个像素变成矩形区域,所以要对每个矩形区域先求和,然后再利用上面的算子做运算,这种特征称之为Haar-like 特征。

积分图像与矩形特征 

正如上一节所说,为了计算Haar-like特征,需要对矩形区域的所有像素求和,一个图像所能形成的矩形区域有大有小,如果每个矩形区域都用遍历所有像素再求和的运算方法,无疑这个运算负担将非常巨大,所有VJ人脸检测算法用到了一种非常巧妙的数据结构,称为integral image(积分图像),积分图像的原理非常简单,总得来说,就是对于图像中的任何一点,该点的积分图像值等于位于该点左上角的所有像素之和,表达式如下:

I(x,y)=∑x′≤x∑y′≤yf(x′,y′)

  

并且积分图像满足如下关系:

I(x,y)=f(x,y)+I(x−1,y)+I(x,y−1)−I(x−1,y−1)

其中I 表示积分图像,f 表示原来的图像,x,y,x′,y′表示像素的位置。所以一张图像的积分图像记录了这张图像上每一个像素点其左上角所有像素的和,如果把一张图像的左上角看做坐标原点,那么上面的表达式就是原点到该像素点之间的所有像素点的离散求和,这可以看成是一种积分,所以这也是积分图像名称的由来。 利用积分图像,我们可以计算一张图像上任意一个矩形区域的像素和,积分图像的计算matlab 有一个库函数integralImage 可以直接调用,

I=intergralImage(img) 

如下图所示,左边的图表示人脸图像,右边的图表示归一化之后积分图像。

  

有了积分图像,就可以很方便的计算图像中任何一个矩形区域的像素和,如下图所示:

  

为了计算矩形ABCD的像素和,利用积分图像可以表示如下:

Sabcd=I(D)−I(B)−I(C)+I(A)

 

这意味着,任何一个矩形区域的像素和,都可以由积分图像 I 上面的四个点来表示。VJ人脸检测算法用到了三种不同的矩形特征,分别是二邻接,三邻接,四邻接矩形,如下图所示:

很显然一个矩形可以由四个点来表示,二邻接矩形需要六个点表示,三邻接矩形需要八个点,而四邻接矩形需要九个点。

下面我们来看看,给定一张图像,有多少个矩形特征,VJ 算法里用到的是 24×24 的图像大小,我们可以计算一个24×24 的图像可以产生多少矩形特征。考虑水平方向与垂直方向,二邻接矩形有两种情况1×2 和 2×1,三邻接矩形也有两种情况 1×3 和 3×1,而四邻接矩形只有一种情况2×2。

下面列出每种邻接矩形可能的size大小。

二邻接矩形 (1×2): 1×2, 1×4, 1×6, … 1×24 , 2×2, 2×4, 2×6, … 2×24 … 24×24 矩形的长以2的倍数增加,宽逐渐增加。

三邻接矩形 (1×3): 1×3, 1×6, 1×9, … 24×24 矩形的长是以3的倍数增加,宽逐渐增加。

四邻接矩形 (2×2): 2×2, 2×4, 2×8, 2×16, … 24×24 矩形的长宽都是以2的倍数增加。

根据卷积定理,我们知道一个W×H 的图像与 m×n 的filter 做卷积,新生成的图像大小为

(W−m+1)×(H−n+1), 新图像的每一个像素其实就是原图一个m×n 的local patch与 m×n 的filter 的乘积和。新图像有多少个像素,就对应着原图多少个m×n 的矩形。

我们用一段代码来求一个24×24 图像会产生多少个矩形特征: 因为 1×2 和 2×1 的情形是一样的,1×3 和 3×1 的情形也是一样,所以我们只要分别计算一种情况,再乘以2就行了。

import numpy as np

a = np.zeros((3, 2), dtype=int)
Count = np.zeros(3, dtype=int)
a[0, :] = [1, 2]
a[1, :] = [1, 3]
a[2, :] = [2, 2]
Img_size = 24 for ii in range(3):
rec_h = a[ii, 0]
rec_w = a[ii, 1]
for xx in range(rec_h, Img_size+1, rec_h):
for yy in range(rec_w, Img_size+1, rec_w):
Count[ii] = Count[ii]+(Img_size-xx+1)*(Img_size-yy+1)
print Count[ii] Total = Count[0]*2+Count[1]*2+Count[2]
print ("Total: ", Total)

最后可以得到:

1×2: 43200

1×3: 27600

2×2: 20736

所以最终总的矩形特征为 43200×2+27600×2+20736=162336

可以看到,一个 24×24 的图像最终会产生162336个矩形特征,这个维度远远高于图像本身的维度。不可能将所有的矩形特征都用,所有需要做特征选择,下一篇,我们将探讨如何利用AdaBoost来做特征选择与训练。

机器学习: Viola-Jones 人脸检测算法解析(一)的更多相关文章

  1. 机器学习: Viola-Jones 人脸检测算法解析(二)

    上一篇博客里,我们介绍了VJ人脸检测算法的特征,就是基于积分图像的矩形特征,这些矩形特征也被称为Haar like features, 通常来说,一张图像会生成一个远远高于图像维度的特征集,比如一个 ...

  2. 重磅!刷新两项世界纪录的腾讯优图人脸检测算法DSFD开源了!

    近日,知名开源社区Github上有个名为DSFD(Dual Shot Face Detector)的算法引起了业内关注,它正是来自于腾讯优图.目前,该算法已经被计算机视觉顶级会议CVPR 2019接收 ...

  3. Python机器学习笔记:异常点检测算法——LOF(Local Outiler Factor)

    完整代码及其数据,请移步小编的GitHub 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/MachineLearningNote 在数据挖掘方面,经常需 ...

  4. 基于Adaboost的人脸检测算法

    AdaBoost算法是一种自适应的Boosting算法,基本思想是选取若干弱分类器,组合成强分类器.根据人脸的灰度分布特征,AdaBoost选用了Haar特征[38].AdaBoost分类器的构造过程 ...

  5. 机器学习--详解人脸对齐算法SDM-LBF

    引自:http://blog.csdn.net/taily_duan/article/details/54584040 人脸对齐之SDM(Supervised Descent Method) 人脸对齐 ...

  6. 吴恩达机器学习笔记55-异常检测算法的特征选择(Choosing What Features to Use of Anomaly Detection)

    对于异常检测算法,使用特征是至关重要的,下面谈谈如何选择特征: 异常检测假设特征符合高斯分布,如果数据的分布不是高斯分布,异常检测算法也能够工作,但是最好还是将数据转换成高斯分布,例如使用对数函数:

  7. yolo类检测算法解析——yolo v3

    每当听到有人问“如何入门计算机视觉”这个问题时,其实我内心是拒绝的,为什么呢?因为我们说的计算机视觉的发展史可谓很长了,它的分支很多,而且理论那是错综复杂交相辉映,就好像数学一样,如何学习数学?这问题 ...

  8. win10+anaconda+cuda配置dlib,使用GPU对dlib的深度学习算法进行加速(以人脸检测为例)

    在计算机视觉和机器学习方向有一个特别好用但是比较低调的库,也就是dlib,与opencv相比其包含了很多最新的算法,尤其是深度学习方面的,因此很有必要学习一下.恰好最近换了一台笔记本,内含一块GTX1 ...

  9. 基于AdaBoost算法——世纪晟结合Haar-like特征训练人脸检测识别

      AdaBoost 算法是一种快速人脸检测算法,它将根据弱学习的反馈,适应性地调整假设的错误率,使在效率不降低的情况下,检测正确率得到了很大的提高.   系统在技术上的三个贡献: 1.用简单的Haa ...

随机推荐

  1. Dll的链接使用细节

    关于Dll Dll.Exe 都是PE格式的二进制文件. Dll相当于Linux操作系统下的so文件 1 基地址(Base Address)和相对地址(RelativeVirtual Address) ...

  2. 今天竟然有人模仿我的QQ号进行骗钱

    今天下午,CoderGeek同学告诉我,有个叫"小雷FansUnion"的QQ正在找他要钱,他直接和我这个正宗的"小雷FansUnion"探听虚实.这时才发现, ...

  3. [Recompose] Show a Spinner While a Component is Loading using Recompose

    Learn how to use the 'branch' and 'renderComponent' higher-order components to show a spinner while ...

  4. php实现数组中的逆序对(归并排序实现:排序 辅助数组)

    php实现数组中的逆序对(归并排序实现:排序 辅助数组) 一.总结 这题用归并排序  线段树   树状数组 等操作的复杂度应该都是小于n方的 二.php实现数组中的逆序对 题目描述 在数组中的两个数字 ...

  5. Android 监听软键盘按键的三种方式

    前言: 我们在Android手机上面有时候会遇到监听手机软键盘按键的时候,例如:我们在浏览器输入url完毕后可以点击软键盘右下角的“Go”按键加载url页面:在点击搜索框的时候,点击右下角的searc ...

  6. ios 第一篇文章-xcode6.2键盘调不出来

    ios 第一篇文章 不晓得有没有人遇到过ios代码内调用键盘(keyboard)调不出来的情况,反正我是遇到了,按官方文档的说法调用键盘事件非常easy事实上: 我用了之后,不晓得为嘛,键盘就是不显示 ...

  7. Android JNI--基础篇(二)

    编写一个可以与C代码交互的android工程需要如下步骤: 1.JAVA代码中写声明native 方法 2. 创建jni目录,编写c代码,方法名字要对应 3.编写Android.mk文件(交叉编译的规 ...

  8. 微信小程序开发实战视频教程

    微信小程序开发实战视频教程发布  有全套的 pan.baidu.com/s/1o8GuJOY 密码:2dbo 腾讯终于发布了没有APPid,无需申请也可以进行微信小程序开发的视频教程了,我在在第一时间 ...

  9. ios9 xcode7以后编译需要进行的几项设置

    http://blog.csdn.net/hero82748274/article/details/48629461 1.库后缀变了:.dylib->tbd libsqlite3.0.dylib ...

  10. Expression Blend 的点滴(1)--ListBox华丽大变身

    原文:Expression Blend 的点滴(1)--ListBox华丽大变身 最近,在园子里有不少朋友写了关于Blend的优秀并且实用的文章,在此,我先代表silverlight的爱好者感谢他们的 ...