1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
21 //
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
25 //
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41 ///////////////////////////////////////////////
42 //// Created by Khudyakov V.A. bober@gorodok.net
43 // FaceDetection.h: interface for the FaceDetection class.
44 //
45 //////////////////////////////////////////////////////////////////////
46
47 #ifndef _CVFACEDETECTION_H_
48 #define _CVFACEDETECTION_H_
49
50 #define MAX_LAYERS 64
51
52 class FaceFeature
53 {
54 public:
55 FaceFeature(double dWeight,void * lpContour,bool bIsFeature);
56 FaceFeature();
57 virtual ~FaceFeature();
58 inline bool isFaceFeature();
59 inline void * GetContour();
60 inline double GetWeight();
61 inline void SetContour(void * lpContour);
62 inline void SetWeight(double dWeight);
63 inline void SetFeature(bool bIsFeature);
64 private:
65 double m_dWeight;
66 void * m_lpContour;
67 bool m_bIsFaceFeature;
68 };//class FaceFeature
69
SetFeature(bool bIsFeature)70 inline void FaceFeature::SetFeature(bool bIsFeature)
71 {
72 m_bIsFaceFeature = bIsFeature;
73 }
74
isFaceFeature()75 inline bool FaceFeature::isFaceFeature()
76 {
77 return m_bIsFaceFeature;
78 }//inline bool FaceFeature::isFaceFeature()
79
GetContour()80 inline void * FaceFeature::GetContour()
81 {
82 return m_lpContour;
83 }//inline void * FaceFeature::GetContour()
84
GetWeight()85 inline double FaceFeature::GetWeight()
86 {
87 return m_dWeight;
88 }//inline long FaceFeature::GetWeight()
89
SetContour(void * lpContour)90 inline void FaceFeature::SetContour(void * lpContour)
91 {
92 m_lpContour = lpContour;
93 }//inline void FaceFeature::SetContour(void * lpContour)
94
SetWeight(double dWeight)95 inline void FaceFeature::SetWeight(double dWeight)
96 {
97 m_dWeight = dWeight;
98 }//inline void FaceFeature::SetWeight(double * dWeight)
99
100
101
102 class FaceTemplate
103 {
104 public:
FaceTemplate(long lFeatureCount)105 FaceTemplate(long lFeatureCount) {m_lFeaturesCount = lFeatureCount; m_lpFeaturesList = new FaceFeature[lFeatureCount];};
106 virtual ~FaceTemplate();
107
108 inline long GetCount();
109 inline FaceFeature * GetFeatures();
110
111 protected:
112 FaceFeature * m_lpFeaturesList;
113 private:
114 long m_lFeaturesCount;
115 };//class FaceTemplate
116
117
GetCount()118 inline long FaceTemplate::GetCount()
119 {
120 return m_lFeaturesCount;
121 }//inline long FaceTemplate::GetCount()
122
123
GetFeatures()124 inline FaceFeature * FaceTemplate::GetFeatures()
125 {
126 return m_lpFeaturesList;
127 }//inline FaceFeature * FaceTemplate::GetFeatures()
128
129 ////////////
130 //class RFaceTemplate
131 ///////////
132
133 class MouthFaceTemplate:public FaceTemplate
134 {
135 public:
136 inline MouthFaceTemplate(long lNumber,CvRect rect,double dEyeWidth,double dEyeHeight,double dDistanceBetweenEye,double dDistanceEyeAboveMouth);
137 ~MouthFaceTemplate();
138 };//class MouthFaceTemplate:public FaceTemplate
139
140
MouthFaceTemplate(long lNumber,CvRect rect,double dEyeWidth,double dEyeHeight,double dDistanceBetweenEye,double dDistanceEyeAboveMouth)141 inline MouthFaceTemplate::MouthFaceTemplate(long lNumber,CvRect rect,double dEyeWidth,double dEyeHeight,
142 double dDistanceBetweenEye,double dDistanceEyeAboveMouth):FaceTemplate(lNumber)
143 {
144
145 CvRect MouthRect = rect;
146
147
148 CvRect LeftEyeRect = cvRect(cvRound(rect.x - (dEyeWidth + dDistanceBetweenEye/(double)2 - (double)rect.width/(double)2)),
149 cvRound(rect.y - dDistanceEyeAboveMouth - dEyeHeight),
150 cvRound(dEyeWidth),
151 cvRound(dEyeHeight) );
152
153 CvRect RightEyeRect = cvRect(cvRound(rect.x + (double)rect.width/(double)2 + dDistanceBetweenEye/(double)2),
154 cvRound(rect.y - dDistanceEyeAboveMouth - dEyeHeight),
155 cvRound(dEyeWidth),
156 cvRound(dEyeHeight) );
157
158 // CvRect NoseRect = cvRect(cvRound(rect.x + (double)rect.width/(double)4),
159 // cvRound(rect.y - (double)rect.width/(double)2 - (double)rect.height/(double)4),
160 // cvRound((double)rect.width/(double)2),
161 // cvRound((double)rect.width/(double)2) );
162 /*
163 CvRect CheenRect = cvRect(rect.x,rect.y + 3*rect.height/2,rect.width,rect.height);
164
165 */
166
167 CvRect * lpMouthRect = new CvRect();
168 *lpMouthRect = MouthRect;
169 m_lpFeaturesList[0].SetContour(lpMouthRect);
170 m_lpFeaturesList[0].SetWeight(1);
171 m_lpFeaturesList[0].SetFeature(false);
172
173
174 CvRect * lpLeftEyeRect = new CvRect();
175 *lpLeftEyeRect = LeftEyeRect;
176 m_lpFeaturesList[1].SetContour(lpLeftEyeRect);
177 m_lpFeaturesList[1].SetWeight(1);
178 m_lpFeaturesList[1].SetFeature(true);
179
180 CvRect * lpRightEyeRect = new CvRect();
181 *lpRightEyeRect = RightEyeRect;
182 m_lpFeaturesList[2].SetContour(lpRightEyeRect);
183 m_lpFeaturesList[2].SetWeight(1);
184 m_lpFeaturesList[2].SetFeature(true);
185
186
187 // CvRect * lpNoseRect = new CvRect();
188 // *lpNoseRect = NoseRect;
189 // m_lpFeaturesList[3].SetContour(lpNoseRect);
190 // m_lpFeaturesList[3].SetWeight(0);
191 // m_lpFeaturesList[3].SetFeature(true);
192
193 /* CvRect * lpCheenRect = new CvRect();
194 *lpCheenRect = CheenRect;
195 m_lpFeaturesList[4].SetContour(lpCheenRect);
196 m_lpFeaturesList[4].SetWeight(1);
197 m_lpFeaturesList[4].SetFeature(false);
198
199 */
200
201 }//constructor MouthFaceTemplate(long lNumFeatures,CvRect rect,double dEyeWidth,double dEyeHeight,double dDistanceBetweenEye,double dDistanceEyeAboveMouth);
202
203
204 typedef struct CvContourRect
205 {
206 int iNumber;
207 int iType;
208 int iFlags;
209 CvSeq *seqContour;
210 int iContourLength;
211 CvRect r;
212 CvPoint pCenter;
213 int iColor;
214 } CvContourRect;
215
216 class Face
217 {
218 public:
219 Face(FaceTemplate * lpFaceTemplate);
220 virtual ~Face();
221
222 inline bool isFeature(void * lpElem);
223
Show(IplImage *)224 virtual void Show(IplImage * /*Image*/){};
ShowIdeal(IplImage *)225 virtual void ShowIdeal(IplImage* /*Image*/){};
226
227 virtual void CreateFace(void * lpData) = 0;
228 virtual bool CheckElem(void * lpCandidat,void * lpIdeal) = 0;
229 virtual double GetWeight() = 0;
230 protected:
231 FaceFeature * m_lpIdealFace;//ideal face definition
232 long m_lFaceFeaturesNumber; //total number of diferent face features
233 long * m_lplFaceFeaturesCount;//number of each features fouded for this face
234 FaceFeature ** m_lppFoundedFaceFeatures;//founded features of curen face
235 double m_dWeight;
236 };
237
isFeature(void * lpElem)238 inline bool Face::isFeature(void * lpElem)
239 {
240 for (int i = 0;i < m_lFaceFeaturesNumber;i ++)
241 {
242 void * lpIdeal = m_lpIdealFace[i].GetContour();
243
244 if ( CheckElem( lpElem,lpIdeal) )
245 {
246 if (m_lplFaceFeaturesCount[i] < 3*MAX_LAYERS)
247 {
248 double dWeight = m_lpIdealFace[i].GetWeight();
249 bool bIsFeature = m_lpIdealFace[i].isFaceFeature();
250
251
252 if (bIsFeature)
253 {
254 m_lppFoundedFaceFeatures[i][m_lplFaceFeaturesCount[i]].SetWeight(dWeight);
255 m_lppFoundedFaceFeatures[i][m_lplFaceFeaturesCount[i]].SetContour(lpElem);
256 m_lppFoundedFaceFeatures[i][m_lplFaceFeaturesCount[i]].SetFeature(bIsFeature);
257 m_lplFaceFeaturesCount[i] ++;
258 }
259
260 m_dWeight += dWeight;
261
262 if (bIsFeature)
263 return true;
264 }
265 }
266
267 }
268
269 return false;
270 }//inline bool RFace::isFeature(void * lpElem);
271
272
273 struct FaceData
274 {
275 CvRect LeftEyeRect;
276 CvRect RightEyeRect;
277 CvRect MouthRect;
278 double Error;
279 };//struct FaceData
280
281 class RFace:public Face
282 {
283 public:
284 RFace(FaceTemplate * lpFaceTemplate);
285 virtual ~RFace();
286 virtual bool CheckElem(void * lpCandidat,void * lpIdeal);
287 virtual void CreateFace(void * lpData);
288 virtual void Show(IplImage* Image);
289 virtual void ShowIdeal(IplImage* Image);
290 virtual double GetWeight();
291 private:
292 bool isPointInRect(CvPoint p,CvRect rect);
293 bool m_bIsGenerated;
294 void ResizeRect(CvRect Rect,CvRect * lpRect,long lDir,long lD);
295 void CalculateError(FaceData * lpFaceData);
296 };
297
298
299 class ListElem
300 {
301 public:
302 ListElem();
303 ListElem(Face * pFace,ListElem * pHead);
304 virtual ~ListElem();
305 ListElem * m_pNext;
306 ListElem * m_pPrev;
307 Face * m_pFace;
308 };//class ListElem
309
310 class List
311 {
312 public:
313 List();
314 int AddElem(Face * pFace);
315 virtual ~List();
316 Face* GetData();
317 long m_FacesCount;
318 private:
319 ListElem * m_pHead;
320 ListElem * m_pCurElem;
321 };//class List
322
323
324 class FaceDetection
325 {
326 public:
327 void FindFace(IplImage* img);
328 void CreateResults(CvSeq * lpSeq);
329 FaceDetection();
330 virtual ~FaceDetection();
SetBoosting(bool bBoosting)331 void SetBoosting(bool bBoosting) {m_bBoosting = bBoosting;}
isPostBoosting()332 bool isPostBoosting() {return m_bBoosting;}
333 protected:
334
335 IplImage* m_imgGray;
336 IplImage* m_imgThresh;
337 int m_iNumLayers;
338 CvMemStorage* m_mstgContours;
339 CvSeq* m_seqContours[MAX_LAYERS];
340 CvMemStorage* m_mstgRects;
341 CvSeq* m_seqRects;
342
343 bool m_bBoosting;
344 List * m_pFaceList;
345
346 protected:
347 void ResetImage();
348 void FindContours(IplImage* imgGray);
349 void AddContours2Rect(CvSeq* seq, int color, int iLayer);
350 void ThresholdingParam(IplImage* imgGray, int iNumLayers, int& iMinLevel, int& iMaxLevel, int& iStep);
351 void FindCandidats();
352 void PostBoostingFindCandidats(IplImage * FaceImage);
353 };
354
ReallocImage(IplImage ** ppImage,CvSize sz,long lChNum)355 inline void ReallocImage(IplImage** ppImage, CvSize sz, long lChNum)
356 {
357 IplImage* pImage;
358 if( ppImage == NULL )
359 return;
360 pImage = *ppImage;
361 if( pImage != NULL )
362 {
363 if (pImage->width != sz.width || pImage->height != sz.height || pImage->nChannels != lChNum)
364 cvReleaseImage( &pImage );
365 }
366 if( pImage == NULL )
367 pImage = cvCreateImage( sz, IPL_DEPTH_8U, lChNum);
368 *ppImage = pImage;
369 }
370
371 ////////////
372 //class RFaceTemplate
373 ///////////
374
375 class BoostingFaceTemplate:public FaceTemplate
376 {
377 public:
378 inline BoostingFaceTemplate(long lNumber,CvRect rect);
~BoostingFaceTemplate()379 ~BoostingFaceTemplate() {};
380 };//class RFaceTemplate:public FaceTemplate
381
382
BoostingFaceTemplate(long lNumber,CvRect rect)383 inline BoostingFaceTemplate::BoostingFaceTemplate(long lNumber,CvRect rect):FaceTemplate(lNumber)
384 {
385 long EyeWidth = rect.width/5;
386 long EyeHeight = EyeWidth;
387
388 CvRect LeftEyeRect = cvRect(rect.x + EyeWidth,rect.y + rect.height/2 - EyeHeight,EyeWidth,EyeHeight);
389 CvRect RightEyeRect = cvRect(rect.x + 3*EyeWidth,rect.y + rect.height/2 - EyeHeight,EyeWidth,EyeHeight);
390 CvRect MouthRect = cvRect(rect.x + 3*EyeWidth/2,rect.y + 3*rect.height/4 - EyeHeight/2,2*EyeWidth,EyeHeight);
391
392 CvRect * lpMouthRect = new CvRect();
393 *lpMouthRect = MouthRect;
394 m_lpFeaturesList[0].SetContour(lpMouthRect);
395 m_lpFeaturesList[0].SetWeight(1);
396 m_lpFeaturesList[0].SetFeature(true);
397
398 CvRect * lpLeftEyeRect = new CvRect();
399 *lpLeftEyeRect = LeftEyeRect;
400 m_lpFeaturesList[1].SetContour(lpLeftEyeRect);
401 m_lpFeaturesList[1].SetWeight(1);
402 m_lpFeaturesList[1].SetFeature(true);
403
404 CvRect * lpRightEyeRect = new CvRect();
405 *lpRightEyeRect = RightEyeRect;
406 m_lpFeaturesList[2].SetContour(lpRightEyeRect);
407 m_lpFeaturesList[2].SetWeight(1);
408 m_lpFeaturesList[2].SetFeature(true);
409
410 }//inline BoostingFaceTemplate::BoostingFaceTemplate(long lNumber,CvRect rect):FaceTemplate(lNumber)
411
412 #endif // !defined(AFX_FACEDETECTION_H__55865033_D8E5_4DD5_8925_34C2285BB1BE__INCLUDED_)
413