基于haar特征+adboost分类器的人脸检测算法----haar特征
冬天来了,春天还会远吗?
-----《西风颂》
haar特征
1 人脸识别方法
人脸检测由来已久 ,它属于计算机视觉范畴。在早期的人脸检测研究中主要侧重于人脸的识别和人物身份的鉴定,后来在复杂背景下的人脸检测需求越来越大,人脸检测也逐渐作为一个单独的研究方向发展起来。
目前人脸检测的方法主要有两大类:基于知识和基于统计。
基于知识的方法:主要利用先验知识将人脸看作器官特征的组合,根据眼睛、眉毛、嘴巴、鼻子等器官的特征以及相互之间的几何位置关系来检测人脸。主要包括模板匹配、人脸特征、形状与边缘、纹理特性、颜色特征等方法。
基于统计的方法:将人脸看作一个整体的模式——二维像素矩阵,从统计的观点通过大量人脸图像样本构造人脸模式空间,根据相似度量来判断人脸是否存在。主要包括主成分分析与特征脸、神经网络方法、支持向量机、隐马尔可夫模型、Adaboost算法等。
图1 人脸识别方法分类
2 原始haar特征
最早的haar like特征于2002年在美国的MIT生物与计算学习中心人工智能实验室由Constantine P. Papageorgiou Michael Oren Tomaso Poggio 三人发表的《A General Framework for Object Detection》中提出的一种用于杂乱场景静态图像目标检测的通用训练框架。
图2 早期的haar特征
如图2所示,a垂直特征,b为水平特征,c为对角特征。a,b,c可以理解成为一个窗口,这个窗口将在图像中做步长为1的滑动,最终遍历整个图像。当一次遍历结束后,窗口将在宽度或长度上成比例的放大,再重复之前遍历的步骤,直到放大到最后一个比例后结束。
3 扩展haar 特征
Haar特征最先由Paul Viola等人提出,后经过Rainer Lienhart等扩展引入45°倾斜特征。Haar特征分为三类:边缘特征、线性特征、中心和对角线特征组合成特征模板。
图3 扩展haar特征
如图3所示,为haar特征定义为特征原型,特征原型在待检测图像中的位置和尺寸可以变化,经过变化产生的特征定义为矩形特征。所以一个监测窗口可产生大量的矩形特征。Haar特征值定义为将haar特征模板放在图像上。用白色区域所覆盖的图像像素和减去黑色区域所覆盖图像中的像素和。
图4 haar特征在图像中演示
Haar特征值主要由三个关键因素决定:
1,当前haar特征模板
2,模板中矩形所在的位置
3,矩形模板的尺寸。
那么这些通过放大+平移的获得的子特征到底总共有多少个?
假设检测窗口大小为W*H,矩形特征大小为w*h,X和Y为表示矩形特征在水平和垂直方向的能放大的最大比例系数:
则总共可以获得的子特征数目为:
公式解释:
1. 特征框竖直放大1倍,即无放大,竖直方向有(H-h+1)个特征
2. 特征框竖直放大2倍,竖直方向有(H-2h+1)个特征
3. 特征框竖直放大3倍,竖直方向有(H-3h+1)个特征
4.如此到竖直放大Y=floor(H/h)倍,竖直方向有1个特征,即(H-Y*h+1) 那么竖直方向总共有(H-h+1)+(H-2h+1)+(H-3h+1)+……+(H-Y*h+1)=Y[H+1-h(1+Y)/2]个特征。
5.同理,在水平方向共有(W-w+1)+(W-2w+1)+(W-3w+1)+……+(W-X*w+1)=X[W+1-w(1+X)/2]。
6.由于水平方向和垂直方向相互独立,所以子特征数目为:子特征数目 = 水平方向数目X垂直方向数目 一般而言,haar特征值计算出来的值跨度很大,所以在实际的特征提取中时,一般会对haar特征再进行标准化,压缩特征值范围。
不同模板的Haar特征数量(24x24窗口)如下表1:
表1不同haar特征值的数量(24X24窗口)
Matlab代码计算1a的特征值数量:
clc;
clear all;
close all;
% Haar-like特征矩形计算
W = 24 % 检测窗口宽度 W,H
num = 24 % 检测窗口分划数
%%
if mod(W,num)~=0
error('检测窗口宽度必须是分划数的整数倍')
else
delta = W/num % 滑动步进值
end
%% Haar特征1:左白,右黑,(s,t)=(1,2)
s = 1;
t = 2;
R = s:s:floor(num/s)*s; % Haar窗口高
C = t:t:floor(num/t)*t; % Haar窗口宽
NUM = 0; % Haar特征总数
display('---- Haar特征1:左白,右黑,(s,t)=(1,2) ---');
for I = 1:length(R)
for J = 1:length(C)
r = R(I)*delta; % Haar窗口高
c = C(J)*delta; % Haar窗口宽
nr = num-R(I)+1; % 行方向移动个数
nc = num-C(J)+1; % 列方向移动个
Px0 = [0 r]; % 矩形坐标初始化
Py0 = [0 c/2 c];
for i = 1:nr
for j = 1:nc
Px = Px0+(i-1)*delta; % 滑动取点
Py = Py0+(j-1)*delta;
NUM = NUM+1;
end
end
end
end
display(NUM);
视频演示haar特征在24x24窗口中遍历
4 积分图
由于haar特征值数量庞大,所以引用积分图的计算方式提高人脸检测的速度。积分图的使用将haar特征值计算的复杂度由原来的与矩形像素数量相关降低为仅与积分图中几个数值相关,达到了提高检测速度的目的。
图5 点(x,y)处的积分图
如图5所示,积分图中任意一点(x,y)处的值等于原始图像中所有位于相同位置元素左边和上边像素的和,即原始图像中原点和(x,y)围成矩形区域中所有像素的和。
ii(x,y)表示积分图中点(x,y)处的值,i(x,y)表示原始图像中(x,y)处的值。
S(x,y)表示点(x,y)在所在第y列所有像素的和,并且有s(x,0) = 0,ii(0,y)=0.
图6矩形R4中像素和
由Haar特征值的定义可知,计算Haar特征值首先需要计算模型中每个矩形所覆盖的所有像素之和。如图6所示,计算矩形R4中像素和的计算公式:
其中iia,iib,iic,iid分别表示点a,b,c,d处的积分值,sum(R)表示矩形R中的像素和。即一个矩形所覆盖所有像素的和,可以由该矩形四个顶点在积分图相应位置的值计算得出。为了计算图4中1b所示Haar特征模板的特征值val_fe,首先需要求出图7中矩形R1和R2所覆盖像素之和。计算公式:
图7 haar特征值计算示意图
5 haar+adaboost实现人脸识别(opencv)
Opencv3 代码:
#include "opencv/cvaux.hpp"
using namespace std;
using namespace cv;
int main( int argc, char** argv)
{
if(argc != 2){
cout<<"NULL"<<endl;
return 0;
}
Mat src =imread(argv[1],-1);
if(src.empty()) return -1;
namedWindow("src",WINDOW_AUTOSIZE);
imshow("src",src);
CascadeClassifier face_cascade;
String file1 = "opencv/opencv-3.4.2/data/haarcascades/haarcascade_frontalface_alt.xml";
if( !face_cascade.load(file1) )
{
printf("can not load the file... xml\n");
return -1;
}
vector<Rect> faces;
Mat gray_image;
cvtColor( src, gray_image, CV_BGR2GRAY );
//直方图均衡化
equalizeHist( gray_image, gray_image );
face_cascade.detectMultiScale( gray_image, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(1, 1) );
//框选出脸部区域
for (int i = 0; i < faces.size(); i++)
{
RNG rng(i);
Scalar color = Scalar(rng.uniform(0,255), rng.uniform(0,255), 20);
rectangle(src, faces[static_cast<int>(i)], color, 2, 8, 0);
}
imshow("face", src );
waitKey(0);
return 0;
}
结果展示:
需要对haar-like有更多了解的同学,公众号内回复“haar”获得以下原文。
《A general framework for object detection》
《An extended set of Haar-like features for rapid object detection》
《Rapid Object Detection using a Boosted Cascade of SimpleFeatures 》
更多精彩推荐,请关注我们
上一篇: 简单的人脸分类实战