| /*M/////////////////////////////////////////////////////////////////////////////////////// |
| // |
| // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. |
| // |
| // By downloading, copying, installing or using the software you agree to this license. |
| // If you do not agree to this license, do not download, install, |
| // copy or use the software. |
| // |
| // |
| // Intel License Agreement |
| // For Open Source Computer Vision Library |
| // |
| // Copyright (C) 2000, Intel Corporation, all rights reserved. |
| // Third party copyrights are property of their respective owners. |
| // |
| // Redistribution and use in source and binary forms, with or without modification, |
| // are permitted provided that the following conditions are met: |
| // |
| // * Redistribution's of source code must retain the above copyright notice, |
| // this list of conditions and the following disclaimer. |
| // |
| // * Redistribution's in binary form must reproduce the above copyright notice, |
| // this list of conditions and the following disclaimer in the documentation |
| // and/or other materials provided with the distribution. |
| // |
| // * The name of Intel Corporation may not be used to endorse or promote products |
| // derived from this software without specific prior written permission. |
| // |
| // This software is provided by the copyright holders and contributors "as is" and |
| // any express or implied warranties, including, but not limited to, the implied |
| // warranties of merchantability and fitness for a particular purpose are disclaimed. |
| // In no event shall the Intel Corporation or contributors be liable for any direct, |
| // indirect, incidental, special, exemplary, or consequential damages |
| // (including, but not limited to, procurement of substitute goods or services; |
| // loss of use, data, or profits; or business interruption) however caused |
| // and on any theory of liability, whether in contract, strict liability, |
| // or tort (including negligence or otherwise) arising in any way out of |
| // the use of this software, even if advised of the possibility of such damage. |
| // |
| //M*/ |
| /////////////////////////////////////////////// |
| //// Created by Khudyakov V.A. bober@gorodok.net |
| // FaceDetection.h: interface for the FaceDetection class. |
| // |
| ////////////////////////////////////////////////////////////////////// |
| |
| #ifndef _CVFACEDETECTION_H_ |
| #define _CVFACEDETECTION_H_ |
| |
| #define MAX_LAYERS 64 |
| |
| class FaceFeature |
| { |
| public: |
| FaceFeature(double dWeight,void * lpContour,bool bIsFeature); |
| FaceFeature(); |
| virtual ~FaceFeature(); |
| inline bool isFaceFeature(); |
| inline void * GetContour(); |
| inline double GetWeight(); |
| inline void SetContour(void * lpContour); |
| inline void SetWeight(double dWeight); |
| inline void SetFeature(bool bIsFeature); |
| private: |
| double m_dWeight; |
| void * m_lpContour; |
| bool m_bIsFaceFeature; |
| };//class FaceFeature |
| |
| inline void FaceFeature::SetFeature(bool bIsFeature) |
| { |
| m_bIsFaceFeature = bIsFeature; |
| } |
| |
| inline bool FaceFeature::isFaceFeature() |
| { |
| return m_bIsFaceFeature; |
| }//inline bool FaceFeature::isFaceFeature() |
| |
| inline void * FaceFeature::GetContour() |
| { |
| return m_lpContour; |
| }//inline void * FaceFeature::GetContour() |
| |
| inline double FaceFeature::GetWeight() |
| { |
| return m_dWeight; |
| }//inline long FaceFeature::GetWeight() |
| |
| inline void FaceFeature::SetContour(void * lpContour) |
| { |
| m_lpContour = lpContour; |
| }//inline void FaceFeature::SetContour(void * lpContour) |
| |
| inline void FaceFeature::SetWeight(double dWeight) |
| { |
| m_dWeight = dWeight; |
| }//inline void FaceFeature::SetWeight(double * dWeight) |
| |
| |
| |
| class FaceTemplate |
| { |
| public: |
| FaceTemplate(long lFeatureCount) {m_lFeaturesCount = lFeatureCount; m_lpFeaturesList = new FaceFeature[lFeatureCount];}; |
| virtual ~FaceTemplate(); |
| |
| inline long GetCount(); |
| inline FaceFeature * GetFeatures(); |
| |
| protected: |
| FaceFeature * m_lpFeaturesList; |
| private: |
| long m_lFeaturesCount; |
| };//class FaceTemplate |
| |
| |
| inline long FaceTemplate::GetCount() |
| { |
| return m_lFeaturesCount; |
| }//inline long FaceTemplate::GetCount() |
| |
| |
| inline FaceFeature * FaceTemplate::GetFeatures() |
| { |
| return m_lpFeaturesList; |
| }//inline FaceFeature * FaceTemplate::GetFeatures() |
| |
| //////////// |
| //class RFaceTemplate |
| /////////// |
| |
| class MouthFaceTemplate:public FaceTemplate |
| { |
| public: |
| inline MouthFaceTemplate(long lNumber,CvRect rect,double dEyeWidth,double dEyeHeight,double dDistanceBetweenEye,double dDistanceEyeAboveMouth); |
| ~MouthFaceTemplate(); |
| };//class MouthFaceTemplate:public FaceTemplate |
| |
| |
| inline MouthFaceTemplate::MouthFaceTemplate(long lNumber,CvRect rect,double dEyeWidth,double dEyeHeight, |
| double dDistanceBetweenEye,double dDistanceEyeAboveMouth):FaceTemplate(lNumber) |
| { |
| |
| CvRect MouthRect = rect; |
| |
| |
| CvRect LeftEyeRect = cvRect(cvRound(rect.x - (dEyeWidth + dDistanceBetweenEye/(double)2 - (double)rect.width/(double)2)), |
| cvRound(rect.y - dDistanceEyeAboveMouth - dEyeHeight), |
| cvRound(dEyeWidth), |
| cvRound(dEyeHeight) ); |
| |
| CvRect RightEyeRect = cvRect(cvRound(rect.x + (double)rect.width/(double)2 + dDistanceBetweenEye/(double)2), |
| cvRound(rect.y - dDistanceEyeAboveMouth - dEyeHeight), |
| cvRound(dEyeWidth), |
| cvRound(dEyeHeight) ); |
| |
| // CvRect NoseRect = cvRect(cvRound(rect.x + (double)rect.width/(double)4), |
| // cvRound(rect.y - (double)rect.width/(double)2 - (double)rect.height/(double)4), |
| // cvRound((double)rect.width/(double)2), |
| // cvRound((double)rect.width/(double)2) ); |
| /* |
| CvRect CheenRect = cvRect(rect.x,rect.y + 3*rect.height/2,rect.width,rect.height); |
| |
| */ |
| |
| CvRect * lpMouthRect = new CvRect(); |
| *lpMouthRect = MouthRect; |
| m_lpFeaturesList[0].SetContour(lpMouthRect); |
| m_lpFeaturesList[0].SetWeight(1); |
| m_lpFeaturesList[0].SetFeature(false); |
| |
| |
| CvRect * lpLeftEyeRect = new CvRect(); |
| *lpLeftEyeRect = LeftEyeRect; |
| m_lpFeaturesList[1].SetContour(lpLeftEyeRect); |
| m_lpFeaturesList[1].SetWeight(1); |
| m_lpFeaturesList[1].SetFeature(true); |
| |
| CvRect * lpRightEyeRect = new CvRect(); |
| *lpRightEyeRect = RightEyeRect; |
| m_lpFeaturesList[2].SetContour(lpRightEyeRect); |
| m_lpFeaturesList[2].SetWeight(1); |
| m_lpFeaturesList[2].SetFeature(true); |
| |
| |
| // CvRect * lpNoseRect = new CvRect(); |
| // *lpNoseRect = NoseRect; |
| // m_lpFeaturesList[3].SetContour(lpNoseRect); |
| // m_lpFeaturesList[3].SetWeight(0); |
| // m_lpFeaturesList[3].SetFeature(true); |
| |
| /* CvRect * lpCheenRect = new CvRect(); |
| *lpCheenRect = CheenRect; |
| m_lpFeaturesList[4].SetContour(lpCheenRect); |
| m_lpFeaturesList[4].SetWeight(1); |
| m_lpFeaturesList[4].SetFeature(false); |
| |
| */ |
| |
| }//constructor MouthFaceTemplate(long lNumFeatures,CvRect rect,double dEyeWidth,double dEyeHeight,double dDistanceBetweenEye,double dDistanceEyeAboveMouth); |
| |
| |
| typedef struct CvContourRect |
| { |
| int iNumber; |
| int iType; |
| int iFlags; |
| CvSeq *seqContour; |
| int iContourLength; |
| CvRect r; |
| CvPoint pCenter; |
| int iColor; |
| } CvContourRect; |
| |
| class Face |
| { |
| public: |
| Face(FaceTemplate * lpFaceTemplate); |
| virtual ~Face(); |
| |
| inline bool isFeature(void * lpElem); |
| |
| virtual void Show(IplImage * /*Image*/){}; |
| virtual void ShowIdeal(IplImage* /*Image*/){}; |
| |
| virtual void CreateFace(void * lpData) = 0; |
| virtual bool CheckElem(void * lpCandidat,void * lpIdeal) = 0; |
| virtual double GetWeight() = 0; |
| protected: |
| FaceFeature * m_lpIdealFace;//ideal face definition |
| long m_lFaceFeaturesNumber; //total number of diferent face features |
| long * m_lplFaceFeaturesCount;//number of each features fouded for this face |
| FaceFeature ** m_lppFoundedFaceFeatures;//founded features of curen face |
| double m_dWeight; |
| }; |
| |
| inline bool Face::isFeature(void * lpElem) |
| { |
| for (int i = 0;i < m_lFaceFeaturesNumber;i ++) |
| { |
| void * lpIdeal = m_lpIdealFace[i].GetContour(); |
| |
| if ( CheckElem( lpElem,lpIdeal) ) |
| { |
| if (m_lplFaceFeaturesCount[i] < 3*MAX_LAYERS) |
| { |
| double dWeight = m_lpIdealFace[i].GetWeight(); |
| bool bIsFeature = m_lpIdealFace[i].isFaceFeature(); |
| |
| |
| if (bIsFeature) |
| { |
| m_lppFoundedFaceFeatures[i][m_lplFaceFeaturesCount[i]].SetWeight(dWeight); |
| m_lppFoundedFaceFeatures[i][m_lplFaceFeaturesCount[i]].SetContour(lpElem); |
| m_lppFoundedFaceFeatures[i][m_lplFaceFeaturesCount[i]].SetFeature(bIsFeature); |
| m_lplFaceFeaturesCount[i] ++; |
| } |
| |
| m_dWeight += dWeight; |
| |
| if (bIsFeature) |
| return true; |
| } |
| } |
| |
| } |
| |
| return false; |
| }//inline bool RFace::isFeature(void * lpElem); |
| |
| |
| struct FaceData |
| { |
| CvRect LeftEyeRect; |
| CvRect RightEyeRect; |
| CvRect MouthRect; |
| double Error; |
| };//struct FaceData |
| |
| class RFace:public Face |
| { |
| public: |
| RFace(FaceTemplate * lpFaceTemplate); |
| virtual ~RFace(); |
| virtual bool CheckElem(void * lpCandidat,void * lpIdeal); |
| virtual void CreateFace(void * lpData); |
| virtual void Show(IplImage* Image); |
| virtual void ShowIdeal(IplImage* Image); |
| virtual double GetWeight(); |
| private: |
| bool isPointInRect(CvPoint p,CvRect rect); |
| bool m_bIsGenerated; |
| void ResizeRect(CvRect Rect,CvRect * lpRect,long lDir,long lD); |
| void CalculateError(FaceData * lpFaceData); |
| }; |
| |
| |
| class ListElem |
| { |
| public: |
| ListElem(); |
| ListElem(Face * pFace,ListElem * pHead); |
| virtual ~ListElem(); |
| ListElem * m_pNext; |
| ListElem * m_pPrev; |
| Face * m_pFace; |
| };//class ListElem |
| |
| class List |
| { |
| public: |
| List(); |
| int AddElem(Face * pFace); |
| virtual ~List(); |
| Face* GetData(); |
| long m_FacesCount; |
| private: |
| ListElem * m_pHead; |
| ListElem * m_pCurElem; |
| };//class List |
| |
| |
| class FaceDetection |
| { |
| public: |
| void FindFace(IplImage* img); |
| void CreateResults(CvSeq * lpSeq); |
| FaceDetection(); |
| virtual ~FaceDetection(); |
| void SetBoosting(bool bBoosting) {m_bBoosting = bBoosting;} |
| bool isPostBoosting() {return m_bBoosting;} |
| protected: |
| |
| IplImage* m_imgGray; |
| IplImage* m_imgThresh; |
| int m_iNumLayers; |
| CvMemStorage* m_mstgContours; |
| CvSeq* m_seqContours[MAX_LAYERS]; |
| CvMemStorage* m_mstgRects; |
| CvSeq* m_seqRects; |
| |
| bool m_bBoosting; |
| List * m_pFaceList; |
| |
| protected: |
| void ResetImage(); |
| void FindContours(IplImage* imgGray); |
| void AddContours2Rect(CvSeq* seq, int color, int iLayer); |
| void ThresholdingParam(IplImage* imgGray, int iNumLayers, int& iMinLevel, int& iMaxLevel, int& iStep); |
| void FindCandidats(); |
| void PostBoostingFindCandidats(IplImage * FaceImage); |
| }; |
| |
| inline void ReallocImage(IplImage** ppImage, CvSize sz, long lChNum) |
| { |
| IplImage* pImage; |
| if( ppImage == NULL ) |
| return; |
| pImage = *ppImage; |
| if( pImage != NULL ) |
| { |
| if (pImage->width != sz.width || pImage->height != sz.height || pImage->nChannels != lChNum) |
| cvReleaseImage( &pImage ); |
| } |
| if( pImage == NULL ) |
| pImage = cvCreateImage( sz, IPL_DEPTH_8U, lChNum); |
| *ppImage = pImage; |
| } |
| |
| //////////// |
| //class RFaceTemplate |
| /////////// |
| |
| class BoostingFaceTemplate:public FaceTemplate |
| { |
| public: |
| inline BoostingFaceTemplate(long lNumber,CvRect rect); |
| ~BoostingFaceTemplate() {}; |
| };//class RFaceTemplate:public FaceTemplate |
| |
| |
| inline BoostingFaceTemplate::BoostingFaceTemplate(long lNumber,CvRect rect):FaceTemplate(lNumber) |
| { |
| long EyeWidth = rect.width/5; |
| long EyeHeight = EyeWidth; |
| |
| CvRect LeftEyeRect = cvRect(rect.x + EyeWidth,rect.y + rect.height/2 - EyeHeight,EyeWidth,EyeHeight); |
| CvRect RightEyeRect = cvRect(rect.x + 3*EyeWidth,rect.y + rect.height/2 - EyeHeight,EyeWidth,EyeHeight); |
| CvRect MouthRect = cvRect(rect.x + 3*EyeWidth/2,rect.y + 3*rect.height/4 - EyeHeight/2,2*EyeWidth,EyeHeight); |
| |
| CvRect * lpMouthRect = new CvRect(); |
| *lpMouthRect = MouthRect; |
| m_lpFeaturesList[0].SetContour(lpMouthRect); |
| m_lpFeaturesList[0].SetWeight(1); |
| m_lpFeaturesList[0].SetFeature(true); |
| |
| CvRect * lpLeftEyeRect = new CvRect(); |
| *lpLeftEyeRect = LeftEyeRect; |
| m_lpFeaturesList[1].SetContour(lpLeftEyeRect); |
| m_lpFeaturesList[1].SetWeight(1); |
| m_lpFeaturesList[1].SetFeature(true); |
| |
| CvRect * lpRightEyeRect = new CvRect(); |
| *lpRightEyeRect = RightEyeRect; |
| m_lpFeaturesList[2].SetContour(lpRightEyeRect); |
| m_lpFeaturesList[2].SetWeight(1); |
| m_lpFeaturesList[2].SetFeature(true); |
| |
| }//inline BoostingFaceTemplate::BoostingFaceTemplate(long lNumber,CvRect rect):FaceTemplate(lNumber) |
| |
| #endif // !defined(AFX_FACEDETECTION_H__55865033_D8E5_4DD5_8925_34C2285BB1BE__INCLUDED_) |