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 (at) 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 70 inline void FaceFeature::SetFeature(bool bIsFeature) 71 { 72 m_bIsFaceFeature = bIsFeature; 73 } 74 75 inline bool FaceFeature::isFaceFeature() 76 { 77 return m_bIsFaceFeature; 78 }//inline bool FaceFeature::isFaceFeature() 79 80 inline void * FaceFeature::GetContour() 81 { 82 return m_lpContour; 83 }//inline void * FaceFeature::GetContour() 84 85 inline double FaceFeature::GetWeight() 86 { 87 return m_dWeight; 88 }//inline long FaceFeature::GetWeight() 89 90 inline void FaceFeature::SetContour(void * lpContour) 91 { 92 m_lpContour = lpContour; 93 }//inline void FaceFeature::SetContour(void * lpContour) 94 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: 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 118 inline long FaceTemplate::GetCount() 119 { 120 return m_lFeaturesCount; 121 }//inline long FaceTemplate::GetCount() 122 123 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 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 224 virtual void Show(IplImage * /*Image*/){}; 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 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(); 331 void SetBoosting(bool bBoosting) {m_bBoosting = bBoosting;} 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 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); 379 ~BoostingFaceTemplate() {}; 380 };//class RFaceTemplate:public FaceTemplate 381 382 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