基于Haar特征的Adaboost级联人脸检测分类器
基于Haar特征的Adaboost级联人脸检测分类器,简称haar分类器。通过这个算法的名字,我们可以看到这个算法其实包含了几个关键点:Haar特征、Adaboost、级联。理解了这三个词对该算法基本就掌握了。
1        算法要点
Haar分类器 = Haar-like特征 + 积分图方法 + AdaBoost +级联;
Haar分类器算法的要点如下:
a)        使用Haar-like特征做检测。
b)       使用积分图(IntegralImage)对Haar-like特征求值进行加速。
c)        使用AdaBoost算法训练区分人脸和非人脸的强分类器。
d)       使用筛选式级联把分类器级联到一起,提高准确率。
2        历史
  在2001年,Viola和Jones两位大牛发表了经典的《Rapid Object Detectionusing a Boosted Cascade of Simple Features》和《Robust Real-Time Face Detection》,在AdaBoost算法的基础上,使用Haar-like小波特征和积分图方法进行人脸检测,他俩不是最早使用提出小波特征的,但是他们设计了针对人脸检测更有效的特征,并对AdaBoost训练出的强分类器进行级联。这可以说是人脸检测史上里程碑式的一笔了,也因此当时提出的这个算法被称为Viola-Jones检测器。又过了一段时间,RainerLienhart和Jochen
Maydt两位大牛将这个检测器进行了扩展,最终形成了OpenCV现在的Haar分类器。
AdaBoost是Freund和Schapire在1995年提出的算法,是对传统Boosting算法的一大提升。Boosting算法的核心思想,是将弱学习方法提升成强学习算法,也就是“三个臭皮匠顶一个诸葛亮”
3        Haar特征
  什么是特征,特征就是分类器的输入。把它放在下面的情景中来描述,假设在人脸检测时我们需要有这么一个子窗口在待检测的图片窗口中不断的移位滑动,子窗口每到一个位置,就会计算出该区域的特征,然后用我们训练好的级联分类器对该特征进行筛选,一旦该特征通过了所有强分类器的筛选,则判定该区域为人脸。
  1 clc;
  2 clear; 
  3 close all;
  4 
  5 % Haar-like特征矩形计算
  6 
  7 board = 24                                              % 检测窗口宽度
  8 num = 24                                                % 检测窗口分划数
  9 
 10 show = 1;                                               % 1为作图
 11 time = 0.001;                                           % 作图间隔
 12 
 13 %%
 14 
 15 if mod(board,num)~=0
 16     error('检测窗口宽度必须是分划数的整数倍')
 17 else
 18     delta = board/num                                   % 滑动步进值 
 19 end
 20 
 21 % Haar特征1:左白,右黑,(s,t)=(1,2)
 22 
 23 s = 1;
 24 t = 2;
 25 R = s:s:floor(num/s)*s;                                 % Haar窗口高
 26 C = t:t:floor(num/t)*t;                                 % Haar窗口宽
 27 NUM = 0;                                                % Haar特征总数
 28 
 29 % '---- Haar特征1:左白,右黑,(s,t)=(1,2) ---'
 30 for I = 1:length(R)
 31     for J = 1:length(C)
 32        
 33         r = R(I)*delta;                                   % Haar窗口高
 34         c = C(J)*delta;                                  % Haar窗口宽
 35         nr = num-R(I)+1;                                 % 行方向移动个数
 36         nc = num-C(J)+1;                                 % 列方向移动个数
 37        
 38         Px0 = [0 r];                                     % 矩形坐标初始化
 39         Py0 = [0 c/2 c];
 40         for i = 1:nr
 41             for j = 1:nc
 42                 Px = Px0+(i-1)*delta;                    % 滑动取点
 43                 Py = Py0+(j-1)*delta;
 44                 NUM = NUM+1;
 45                
 46                 if show
 47                     plot([0 board],repmat((0:delta:board)',1,2),'k'); hold on;
 48                     plot(repmat((0:delta:board)',1,2),[0 board],'k'); axis tight; axis square;
 49                     title('Haar矩形遍历演示');xlabel('x');ylabel('y');
 50                    
 51                     plot(Px,repmat(Py',1,2),'r','LineWidth',5)
 52                     plot(repmat(Px,2,1),repmat([Py(1) Py(end)]',1,2),'r','LineWidth',5); hold off
 53                     pause(time)
 54                 end
 55                
 56             end
 57         end
 58        
 59     end
 60 end
 61 NUM
 62 %% Haar特征2:上白,下黑,(s,t)=(2,1)
 63 s = 2;
 64 t = 1;
 65 R = s:s:floor(num/s)*s;                                 % Haar窗口高
 66 C = t:t:floor(num/t)*t;                                 % Haar窗口宽
 67 NUM = 0;                                                % Haar特征总数
 68 '---- Haar特征2:上白,下黑,(s,t)=(2,1) ---'
 69 for I = 1:length(R)
 70     for J = 1:length(C)
 71        
 72         r = R(I)*delta;                                  % Haar窗口高
 73         c = C(J)*delta;                                  % Haar窗口宽
 74         nr = num-R(I)+1;                                 % 行方向移动个数
 75         nc = num-C(J)+1;                                 % 列方向移动个数
 76        
 77         Px0 = [0 r/2 r];                                 % 矩形坐标初始化
 78         Py0 = [0 c];
 79         for i = 1:nr
 80             for j = 1:nc
 81                 Px = Px0+(i-1)*delta;                    % 滑动取点
 82                 Py = Py0+(j-1)*delta;
 83                 NUM = NUM+1;
 84                 if show
 85                     plot([0 board],repmat((0:delta:board)',1,2),'k'); hold on;
 86                     plot(repmat((0:delta:board)',1,2),[0 board],'k'); axis tight; axis square;
 87                     title('Haar矩形遍历演示');xlabel('x');ylabel('y');
 88                    
 89                     plot(repmat(Px,2,1),repmat(Py',1,length(Px)),'r','LineWidth',3);
 90                     plot(repmat([Px(1) Px(end)]',1,2),repmat(Py,2,1),'r','LineWidth',3); hold off
 91                     pause(time)
 92                 end
 93                
 94             end
 95         end
 96        
 97     end
 98 end
 99 NUM
100 %% Haar特征3:左右白,中间黑,(s,t)=(1,3)
101 s = 1;
102 t = 3;
103 R = s:s:floor(num/s)*s;                                 % Haar窗口高
104 C = t:t:floor(num/t)*t;                                 % Haar窗口宽
105 NUM = 0;                                                % Haar特征总数
106 '---- Haar特征3:左右白,中间黑,(s,t)=(1,3) ---'
107 for I = 1:length(R)
108     for J = 1:length(C)
109        
110         r = R(I)*delta;                                  % Haar窗口高
111         c = C(J)*delta;                                  % Haar窗口宽
112         nr = num-R(I)+1;                                 % 行方向移动个数
113         nc = num-C(J)+1;                                 % 列方向移动个数
114        
115         Px0 = [0 r];                                     % 矩形坐标初始化
116         Py0 = [0 c/3 c*2/3 c];
117         for i = 1:nr
118             for j = 1:nc
119                 Px = Px0+(i-1)*delta;                    % 滑动取点
120                 Py = Py0+(j-1)*delta;
121                 NUM = NUM+1;
122                
123                 if show
124                     plot([0 board],repmat((0:delta:board)',1,2),'k'); hold on;
125                     plot(repmat((0:delta:board)',1,2),[0 board],'k'); axis tight; axis square;
126                     title('Haar矩形遍历演示');xlabel('x');ylabel('y');
127                    
128                     plot(Px,repmat(Py',1,2),'r','LineWidth',5)
129                     plot(repmat(Px,2,1),repmat([Py(1) Py(end)]',1,2),'r','LineWidth',5); hold off
130                     pause(time)
131                 end
132             end
133         end
134        
135     end
136 end
137 NUM
138 %% Haar特征4:左右白,中间黑(2倍宽度),(s,t)=(1,4)
139 s = 1;
140 t = 4;
141 R = s:s:floor(num/s)*s;                                 % Haar窗口高
142 C = t:t:floor(num/t)*t;                                 % Haar窗口宽
143 NUM = 0;                                                % Haar特征总数
144 '---- Haar特征4:左右白,中间黑(2倍宽度),(s,t)=(1,4) ---'
145 for I = 1:length(R)
146     for J = 1:length(C)
147        
148         r = R(I)*delta;                                  % Haar窗口高
149         c = C(J)*delta;                                  % Haar窗口宽
150         nr = num-R(I)+1;                                 % 行方向移动个数
151         nc = num-C(J)+1;                                 % 列方向移动个数
152        
153         Px0 = [0 r];                                     % 矩形坐标初始化
154         Py0 = [0 c/4 c*3/4 c];
155         for i = 1:nr
156             for j = 1:nc
157                 Px = Px0+(i-1)*delta;                    % 滑动取点
158                 Py = Py0+(j-1)*delta;
159                 NUM = NUM+1;
160        
161                 if show
162                     plot([0 board],repmat((0:delta:board)',1,2),'k'); hold on;
163                     plot(repmat((0:delta:board)',1,2),[0 board],'k'); axis tight; axis square;
164                     title('Haar矩形遍历演示');xlabel('x');ylabel('y');
165                    
166                     plot(Px,repmat(Py',1,2),'r','LineWidth',5)
167                     plot(repmat(Px,2,1),repmat([Py(1) Py(end)]',1,2),'r','LineWidth',5); hold off
168                     pause(time)
169                 end
170                
171             end
172         end
173        
174     end
175 end
176 NUM
177 %% Haar特征5:上下白,中间黑,(s,t)=(3,1)
178 s = 3;
179 t = 1;
180 R = s:s:floor(num/s)*s;                                 % Haar窗口高
181 C = t:t:floor(num/t)*t;                                 % Haar窗口宽
182 NUM = 0;                                                % Haar特征总数
183 '---- Haar特征5:上下白,中间黑,(s,t)=(3,1) ---'
184 for I = 1:length(R)
185     for J = 1:length(C)
186        
187         r = R(I)*delta;                                  % Haar窗口高
188         c = C(J)*delta;                                  % Haar窗口宽
189         nr = num-R(I)+1;                                 % 行方向移动个数
190         nc = num-C(J)+1;                                 % 列方向移动个数
191        
192         Px0 = [0 r/3 r*2/3 r];                           % 矩形坐标初始化
193         Py0 = [0 c];
194         for i = 1:nr
195             for j = 1:nc
196                 Px = Px0+(i-1)*delta;                    % 滑动取点
197                 Py = Py0+(j-1)*delta;
198                 NUM = NUM+1;
199                
200                 if show
201                     plot([0 board],repmat((0:delta:board)',1,2),'k'); hold on;
202                     plot(repmat((0:delta:board)',1,2),[0 board],'k'); axis tight; axis square;
203                     title('Haar矩形遍历演示');xlabel('x');ylabel('y');
204                    
205                     plot(repmat(Px,2,1),repmat(Py',1,length(Px)),'r','LineWidth',3);
206                     plot(repmat([Px(1) Px(end)]',1,2),repmat(Py,2,1),'r','LineWidth',3); hold off
207                     pause(time)
208                 end
209                
210             end
211         end
212        
213     end
214 end
215 NUM
216 %% Haar特征6:上下白,中间黑(2倍宽度),(s,t)=(4,1)
217 s = 4;
218 t = 1;
219 R = s:s:floor(num/s)*s;                                 % Haar窗口高
220 C = t:t:floor(num/t)*t;                                 % Haar窗口宽
221 NUM = 0;                                                % Haar特征总数
222 '---- Haar特征6:上下白,中间黑(2倍宽度),(s,t)=(4,1) ---'
223 for I = 1:length(R)
224     for J = 1:length(C)
225        
226         r = R(I)*delta;                                  % Haar窗口高
227         c = C(J)*delta;                                 % Haar窗口宽
228         nr = num-R(I)+1;                                 % 行方向移动个数
229         nc = num-C(J)+1;                                 % 列方向移动个数
230        
231         Px0 = [0 r/4 r*3/4 r];                           % 矩形坐标初始化
232         Py0 = [0 c];
233         for i = 1:nr
234             for j = 1:nc
235                 Px = Px0+(i-1)*delta;                    % 滑动取点
236                 Py = Py0+(j-1)*delta;
237                 NUM = NUM+1;
238                 if show
239                     plot([0 board],repmat((0:delta:board)',1,2),'k'); hold on;
240                     plot(repmat((0:delta:board)',1,2),[0 board],'k'); axis tight; axis square;
241                     title('Haar矩形遍历演示');xlabel('x');ylabel('y');
242                    
243                     plot(repmat(Px,2,1),repmat(Py',1,length(Px)),'r','LineWidth',3);
244                     plot(repmat([Px(1) Px(end)]',1,2),repmat(Py,2,1),'r','LineWidth',3); hold off
245                     pause(time)
246                 end
247                
248             end
249         end
250        
251     end
252 end
253 NUM
254 %% Haar特征7:左上右下白,其它黑,(s,s)=(2,2)
255 
256 s = 2;
257 t = 2;
258 R = s:s:floor(num/s)*s;                                 % Haar窗口高
259 C = t:t:floor(num/t)*t;                                 % Haar窗口宽
260 NUM = 0;                                                % Haar特征总数
261 '---- Haar特征7:左上右下白,其它黑,(s,s)=(2,2) ---'
262 for I = 1:length(R)
263     for J = 1:length(C)
264        
265         r = R(I)*delta;                                  % Haar窗口高
266         c = C(J)*delta;                                  % Haar窗口高
267         nr = num-R(I)+1;                                 % 行方向移动个数
268         nc = num-C(J)+1;                                 % 行方向移动个数
269        
270         Px0 = [0 r/2 r];                           % 矩形坐标初始化
271         Py0 = [0 c/2 c];                           % 矩形坐标初始化
272         for i = 1:nr
273             for j = 1:nc
274                 Px = Px0+(i-1)*delta;                    % 滑动取点
275                 Py = Py0+(j-1)*delta;
276                 NUM = NUM+1;
277                
278                 if show
279                     plot([0 board],repmat((0:delta:board)',1,2),'k'); hold on;
280                     plot(repmat((0:delta:board)',1,2),[0 board],'k'); axis tight; axis square;
281                     title('Haar矩形遍历演示');xlabel('x');ylabel('y');
282                    
283                     plot(repmat(Px,3,1),repmat(Py',1,length(Px)),'r','LineWidth',3);
284                     plot(repmat([Px(1) Px(end)]',1,3),repmat(Py,2,1),'r','LineWidth',3); hold off
285                     pause(time)
286                 end
287                
288             end
289         end
290        
291     end
292 end
293 NUM
294 %% Haar特征8:四周白,中间黑,(s,s)=(3,3)
295 s = 3;
296 t = 3;
297 R = s:s:floor(num/s)*s;                                 % Haar窗口高
298 C = t:t:floor(num/t)*t;                                 % Haar窗口宽
299 NUM = 0;                                                % Haar特征总数
300 '---- Haar特征8:四周白,中间黑,(s,s)=(3,3) ---'
301 for I = 1:length(R)
302     for J = 1:length(C)
303        
304         r = R(I)*delta;                                  % Haar窗口高
305         c = C(J)*delta;                                  % Haar窗口高
306         nr = num-R(I)+1;                                 % 行方向移动个数
307         nc = num-C(J)+1;                                 % 行方向移动个数
308        
309         Px0 = [0 r/3 r*2/3 r];                           % 矩形坐标初始化
310         Py0 = [0 c/3 c*2/3 c];                           % 矩形坐标初始化
311         for i = 1:nr
312             for j = 1:nc
313                 Px = Px0+(i-1)*delta;                    % 滑动取点
314                 Py = Py0+(j-1)*delta;
315                 NUM = NUM+1;
316                
317                 if show
318                     plot([0 board],repmat((0:delta:board)',1,2),'k'); hold on;
319                     plot(repmat((0:delta:board)',1,2),[0 board],'k'); axis tight; axis square;
320                     title('Haar矩形遍历演示');xlabel('x');ylabel('y');
321                    
322                     plot(repmat(Px,4,1),repmat(Py',1,length(Px)),'r','LineWidth',3);
323                     plot(repmat([Px(1) Px(end)]',1,4),repmat(Py,2,1),'r','LineWidth',3); hold off
324                     pause(time)
325                 end
326                
327             end
328         end
329        
330     end
331 end
332 NUM
View Code

运行效果部分动态图如下

基于Haar特征的Adaboost级联人脸检测分类器

 


  那么这个特征如何表示呢?好了,这就是大牛们干的好事了。后人称这他们搞出来的这些东西叫Haar-Like特征。
Viola大牛在[1]中提出的haar特征如下:

相关文章: