1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
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.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
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.
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.
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.
41 ///////////////////////////////////////////////
42 //// Created by Khudyakov V.A. bober@gorodok.net
43 //////////////////////////////////////////////
45 #include "precomp.hpp"
46 #include "_facedetection.h"
48 Face::Face(FaceTemplate * lpFaceTemplate)
50 //init number of face elements;
51 m_lFaceFeaturesNumber = lpFaceTemplate->GetCount();
53 //init array of numbers of foundet face elements of each type
54 m_lplFaceFeaturesCount = new long[m_lFaceFeaturesNumber];
55 memset(m_lplFaceFeaturesCount,0,m_lFaceFeaturesNumber*sizeof(long));
57 //init array of ideal face features
58 m_lpIdealFace = new FaceFeature[m_lFaceFeaturesNumber];
60 //init array of founded features
61 m_lppFoundedFaceFeatures = new FaceFeature*[m_lFaceFeaturesNumber];
63 for (int i = 0;i < m_lFaceFeaturesNumber;i ++)
65 m_lppFoundedFaceFeatures[i] = (new FaceFeature[3*MAX_LAYERS]);
71 }//Face::Face(FaceTemplate * lpFaceTemplate)
75 for (int i = 0;i < m_lFaceFeaturesNumber;i ++)
77 delete [] (m_lppFoundedFaceFeatures[i]);
79 delete [] m_lppFoundedFaceFeatures;
82 delete [] m_lplFaceFeaturesCount;
83 delete [] m_lpIdealFace;
93 //class RFace(rect based face)
95 RFace::RFace(FaceTemplate * lpFaceTemplate):Face(lpFaceTemplate)
98 FaceFeature * lpTmp = lpFaceTemplate->GetFeatures();
100 for (int j = 0;j < m_lFaceFeaturesNumber;j ++)
102 CvRect * lpTmpRect = NULL;
103 lpTmpRect = new CvRect;
104 *lpTmpRect = *(CvRect*)lpTmp[j].GetContour();
106 m_lpIdealFace[j].SetContour( lpTmpRect );
107 m_lpIdealFace[j].SetWeight( lpTmp[j].GetWeight() );
108 m_lpIdealFace[j].SetFeature( lpTmp[j].isFaceFeature() );
112 m_bIsGenerated = false;
113 }//RFace::RFace(FaceTemplate * lpFaceTemplate)
120 inline bool RFace::isPointInRect(CvPoint p,CvRect rect)
122 if ( (p.x >= rect.x) && (p.y >= rect.y) && (p.x <= rect.x + rect.width) && (p.y <= rect.y + rect.height) )
126 }//inline bool RFace::isPointInRect(CvPoint,CvRect rect)
128 double RFace::GetWeight()
131 }//double RFace::GetWeight()
134 bool RFace::CheckElem(void * lpCandidat,void * lpIdeal)
137 CvRect IdealRect = *(CvRect*)lpIdeal;
138 CvRect Rect = *(CvRect*)lpCandidat;
140 if (Rect.height > Rect.width)
143 long SizeIdeal = IdealRect.width*IdealRect.height;
144 long Size = Rect.width*Rect.height;
146 if ( (Size > SizeIdeal) || ( Size < (SizeIdeal/5) ) )
151 // ResizeRect(IdealRect,&UpRect,UP_SCALE,7);
152 // ResizeRect(IdealRect,&DownRect,DOWN_SCALE,7);
154 long x = Rect.x + cvRound(Rect.width/2);
155 long y = Rect.y + cvRound(Rect.height/2);
157 if ( isPointInRect(cvPoint(x,y),IdealRect) )
160 // if ( isPointInRect(cvPoint(Rect.x,Rect.y),UpRect) &&
161 // isPointInRect(cvPoint(Rect.x + Rect.width,Rect.y + Rect.height),UpRect ) &&
162 // isPointInRect(cvPoint(DownRect.x,DownRect.y),Rect) &&
163 // isPointInRect(cvPoint(DownRect.x + DownRect.width,DownRect.y + DownRect.height),Rect) )
167 // if ( isPointInRect(cvPoint(Rect.x,Rect.y),IdealRect) &&
168 // isPointInRect(cvPoint(Rect.x + Rect.width,Rect.y + Rect.height),IdealRect ) )
172 }//inline bool RFace::CheckElem(CvRect rect)
176 void RFace::CalculateError(FaceData * lpFaceData)
178 CvRect LeftEyeRect = lpFaceData->LeftEyeRect;
179 CvRect RightEyeRect = lpFaceData->RightEyeRect;
180 CvRect MouthRect = lpFaceData->MouthRect;
182 long LeftSquare = LeftEyeRect.width*LeftEyeRect.height;
183 long RightSquare = RightEyeRect.width*RightEyeRect.height;
185 long dy = LeftEyeRect.y - RightEyeRect.y;
187 long dx1 = LeftEyeRect.x + LeftEyeRect.width/2 - MouthRect.x;
188 long dx2 = RightEyeRect.x + RightEyeRect.width/2 - MouthRect.x - MouthRect.width;
191 lpFaceData->Error = (double)(LeftSquare - RightSquare)*(double)(LeftSquare - RightSquare)/((double)(LeftSquare + RightSquare)*(LeftSquare + RightSquare)) +
192 (double)(dy*dy)/((double)(LeftEyeRect.height + RightEyeRect.height)*(LeftEyeRect.height + RightEyeRect.height)) +
193 (double)(dx1*dx1)/((double)MouthRect.width*MouthRect.width) +
194 (double)(dx2*dx2)/((double)MouthRect.width*MouthRect.width);
196 }//void RFace::CalculateError(FaceData * lpFaceData)
198 #define MAX_ERROR 0xFFFFFFFF
200 void RFace::CreateFace(void * lpData)
203 memset(&Data, 0, sizeof(FaceData));
205 double Error = MAX_ERROR;
206 double CurError = MAX_ERROR;
208 FaceData * lpFaceData = (FaceData*)lpData;
210 int im = 0;//mouth was find
211 int jl = 0;//left eye was find
212 int kr = 0;//right eye was find
214 long MouthNumber = 0;
215 long LeftEyeNumber = 0;
216 long RightEyeNumber = 0;
218 for (int i = 0;i < m_lplFaceFeaturesCount[0] + 1;i ++)
221 if ( !m_lplFaceFeaturesCount[0] )
222 Data.MouthRect = *(CvRect*)m_lpIdealFace[0].GetContour();
225 if ( i != m_lplFaceFeaturesCount[0] )
226 Data.MouthRect = *(CvRect*)m_lppFoundedFaceFeatures[0][i].GetContour();
231 for (int j = 0;j < m_lplFaceFeaturesCount[1] + 1;j ++)
234 if ( !m_lplFaceFeaturesCount[1] )
235 Data.LeftEyeRect = *(CvRect*)m_lpIdealFace[1].GetContour();
238 if (j != m_lplFaceFeaturesCount[1] )
239 Data.LeftEyeRect = *(CvRect*)m_lppFoundedFaceFeatures[1][j].GetContour();
244 for (int k = 0;k < m_lplFaceFeaturesCount[2] + 1;k ++)
247 if ( !m_lplFaceFeaturesCount[2] )
248 Data.RightEyeRect = *(CvRect*)m_lpIdealFace[2].GetContour();
251 if (k != m_lplFaceFeaturesCount[2] )
252 Data.RightEyeRect = *(CvRect*)m_lppFoundedFaceFeatures[2][k].GetContour();
256 CalculateError(&Data);
258 if ( (im + jl + kr) )
260 Error = Data.Error/(im + jl + kr);
264 if (CurError > Error)
279 if ( m_lplFaceFeaturesCount[0] )
280 lpFaceData->MouthRect = *(CvRect*)m_lppFoundedFaceFeatures[0][MouthNumber].GetContour();
282 lpFaceData->MouthRect = *(CvRect*)m_lpIdealFace[0].GetContour();
284 if ( m_lplFaceFeaturesCount[1] )
285 lpFaceData->LeftEyeRect = *(CvRect*)m_lppFoundedFaceFeatures[1][LeftEyeNumber].GetContour();
287 lpFaceData->LeftEyeRect = *(CvRect*)m_lpIdealFace[1].GetContour();
289 if ( m_lplFaceFeaturesCount[2] )
290 lpFaceData->RightEyeRect = *(CvRect*)m_lppFoundedFaceFeatures[2][RightEyeNumber].GetContour();
292 lpFaceData->RightEyeRect = *(CvRect*)m_lpIdealFace[2].GetContour();
294 lpFaceData->Error = CurError;
296 }//void * RFace::CreateFace()
298 void RFace::Show(IplImage * Image)
300 for (int i = 0;i < m_lFaceFeaturesNumber;i ++)
302 if (m_lplFaceFeaturesCount[i])
304 for (int j = 0;j < m_lplFaceFeaturesCount[i];j ++)
306 CvRect rect = *(CvRect*)m_lppFoundedFaceFeatures[i][j].GetContour();
307 CvPoint p1 = cvPoint(rect.x,rect.y);
308 CvPoint p2 = cvPoint(rect.x + rect.width,rect.y + rect.height);
309 cvRectangle(Image,p1,p2,CV_RGB(255,0,0),1);
314 }//void RFace::Show(IplImage * Image)
316 void RFace::ShowIdeal(IplImage* Image)
318 for (int i = 0;i < m_lFaceFeaturesNumber;i ++)
320 CvRect Rect = *(CvRect*)m_lpIdealFace[i].GetContour();
321 CvPoint p1 = cvPoint(Rect.x,Rect.y);
322 CvPoint p2 = cvPoint(Rect.x + Rect.width,Rect.y + Rect.height);
323 cvRectangle(Image,p1,p2,CV_RGB(0,0,255),1);
325 }//void RFace::ShowIdeal(IplImage* Image)
328 inline void RFace::ResizeRect(CvRect Rect,CvRect * lpRect,long lDir,long lD)
330 if (lDir == UP_SCALE)
332 lpRect->x = Rect.x - lD;
333 lpRect->y = Rect.y - lD;
334 lpRect->width = Rect.width + 2*lD;
335 lpRect->height = Rect.height + 2*lD;
337 if (lDir == DOWN_SCALE)
339 lpRect->x = Rect.x + lD;
340 lpRect->y = Rect.y + lD;
341 if (Rect.width - 2*lD >= 0)
343 lpRect->width = Rect.width - 2*lD;
347 if (Rect.height - 2*lD >= 0)
349 lpRect->height = Rect.height - 2*lD;
354 }// inline void RFace::ResizeRect(CvRect * lpRect,long lDir,long lD)