Home | History | Annotate | Download | only in src
      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