32f1a9893f17442b22d59dd95e56654032625a44
[platform/upstream/opencv.git] / modules / legacy / src / _facedetection.h
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
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 FaceDetectionListElem
300 {
301 public:
302     FaceDetectionListElem();
303     FaceDetectionListElem(Face * pFace,FaceDetectionListElem * pHead);
304     virtual ~FaceDetectionListElem();
305     FaceDetectionListElem * m_pNext;
306     FaceDetectionListElem * m_pPrev;
307     Face * m_pFace;
308 };//class FaceDetectionListElem
309
310 class FaceDetectionList
311 {
312 public:
313     FaceDetectionList();
314     int AddElem(Face * pFace);
315     virtual ~FaceDetectionList();
316     Face* GetData();
317         long m_FacesCount;
318 private:
319     FaceDetectionListElem * m_pHead;
320     FaceDetectionListElem * m_pCurElem;
321 };//class FaceDetectionList
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     FaceDetectionList * 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_)