16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*M///////////////////////////////////////////////////////////////////////////////////////
26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  By downloading, copying, installing or using the software you agree to this license.
66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  If you do not agree to this license, do not download, install,
76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  copy or use the software.
86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        Intel License Agreement
116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                For Open Source Computer Vision Library
126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2000, Intel Corporation, all rights reserved.
146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners.
156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without modification,
176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are permitted provided that the following conditions are met:
186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's of source code must retain the above copyright notice,
206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer.
216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's in binary form must reproduce the above copyright notice,
236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer in the documentation
246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     and/or other materials provided with the distribution.
256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * The name of Intel Corporation may not be used to endorse or promote products
276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     derived from this software without specific prior written permission.
286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is" and
306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// any express or implied warranties, including, but not limited to, the implied
316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// warranties of merchantability and fitness for a particular purpose are disclaimed.
326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In no event shall the Intel Corporation or contributors be liable for any direct,
336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// indirect, incidental, special, exemplary, or consequential damages
346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services;
356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused
366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability,
376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of
386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage.
396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//M*/
416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn///////////////////////////////////////////////
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//// Created by Khudyakov V.A. bober@gorodok.net
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//////////////////////////////////////////////
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cvaux.h"
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cvfacedetection.h"
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennFace::Face(FaceTemplate * lpFaceTemplate)
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    //init number of face elements;
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_lFaceFeaturesNumber = lpFaceTemplate->GetCount();
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    //init array of numbers of foundet face elements of each type
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_lplFaceFeaturesCount = new long[m_lFaceFeaturesNumber];
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memset(m_lplFaceFeaturesCount,0,m_lFaceFeaturesNumber*sizeof(long));
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    //init array of ideal face features
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_lpIdealFace = new FaceFeature[m_lFaceFeaturesNumber];
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    //init array of founded features
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_lppFoundedFaceFeatures = new FaceFeature*[m_lFaceFeaturesNumber];
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (int i = 0;i < m_lFaceFeaturesNumber;i ++)
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_lppFoundedFaceFeatures[i] = (new FaceFeature[3*MAX_LAYERS]);
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    //set start weight 0
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_dWeight = 0;
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}//Face::Face(FaceTemplate * lpFaceTemplate)
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennFace::~Face()
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (int i = 0;i < m_lFaceFeaturesNumber;i ++)
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        delete [] (m_lppFoundedFaceFeatures[i]);
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    delete [] m_lppFoundedFaceFeatures;
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    delete [] m_lplFaceFeaturesCount;
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    delete [] m_lpIdealFace;
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}//Face::~Face()
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define UP_SCALE    1
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define DOWN_SCALE  2
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn////////////
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//class RFace(rect based face)
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn////////////
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennRFace::RFace(FaceTemplate * lpFaceTemplate):Face(lpFaceTemplate)
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    //init ideal face
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    FaceFeature * lpTmp = lpFaceTemplate->GetFeatures();
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (int j = 0;j < m_lFaceFeaturesNumber;j ++)
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvRect * lpTmpRect = NULL;
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        lpTmpRect = new CvRect;
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *lpTmpRect = *(CvRect*)lpTmp[j].GetContour();
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_lpIdealFace[j].SetContour( lpTmpRect );
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_lpIdealFace[j].SetWeight( lpTmp[j].GetWeight() );
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_lpIdealFace[j].SetFeature( lpTmp[j].isFaceFeature() );
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_bIsGenerated = false;
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}//RFace::RFace(FaceTemplate * lpFaceTemplate)
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennRFace::~RFace()
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}//RFace::~RFace()
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renninline bool RFace::isPointInRect(CvPoint p,CvRect rect)
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if ( (p.x >= rect.x) && (p.y >= rect.y) && (p.x <= rect.x + rect.width) && (p.y <= rect.y + rect.height) )
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return true;
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return false;
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}//inline bool RFace::isPointInRect(CvPoint,CvRect rect)
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renndouble RFace::GetWeight()
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return m_dWeight;
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}//double RFace::GetWeight()
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool RFace::CheckElem(void * lpCandidat,void * lpIdeal)
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvRect IdealRect = *(CvRect*)lpIdeal;
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvRect Rect = *(CvRect*)lpCandidat;
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if (Rect.height > Rect.width)
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return false;
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    long SizeIdeal = IdealRect.width*IdealRect.height;
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    long Size = Rect.width*Rect.height;
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if ( (Size > SizeIdeal) || ( Size < (SizeIdeal/5) ) )
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return false;
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  CvRect UpRect;
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  CvRect DownRect;
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  ResizeRect(IdealRect,&UpRect,UP_SCALE,7);
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  ResizeRect(IdealRect,&DownRect,DOWN_SCALE,7);
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    long x = Rect.x + cvRound(Rect.width/2);
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    long y = Rect.y + cvRound(Rect.height/2);
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if ( isPointInRect(cvPoint(x,y),IdealRect) )
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return true;
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  if ( isPointInRect(cvPoint(Rect.x,Rect.y),UpRect) &&
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//       isPointInRect(cvPoint(Rect.x + Rect.width,Rect.y + Rect.height),UpRect ) &&
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//       isPointInRect(cvPoint(DownRect.x,DownRect.y),Rect) &&
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//       isPointInRect(cvPoint(DownRect.x + DownRect.width,DownRect.y + DownRect.height),Rect) )
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      return true;
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  if ( isPointInRect(cvPoint(Rect.x,Rect.y),IdealRect) &&
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//       isPointInRect(cvPoint(Rect.x + Rect.width,Rect.y + Rect.height),IdealRect ) )
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      return true;
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return false;
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}//inline bool RFace::CheckElem(CvRect rect)
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid RFace::CalculateError(FaceData * lpFaceData)
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvRect LeftEyeRect = lpFaceData->LeftEyeRect;
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvRect RightEyeRect = lpFaceData->RightEyeRect;
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvRect MouthRect = lpFaceData->MouthRect;
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    long LeftSquare = LeftEyeRect.width*LeftEyeRect.height;
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    long RightSquare = RightEyeRect.width*RightEyeRect.height;
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    long dy = LeftEyeRect.y - RightEyeRect.y;
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    long dx1 = LeftEyeRect.x + LeftEyeRect.width/2 - MouthRect.x;
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    long dx2 = RightEyeRect.x + RightEyeRect.width/2 - MouthRect.x - MouthRect.width;
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    lpFaceData->Error = (double)(LeftSquare - RightSquare)*(double)(LeftSquare - RightSquare)/((double)(LeftSquare + RightSquare)*(LeftSquare + RightSquare)) +
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        (double)(dy*dy)/((double)(LeftEyeRect.height + RightEyeRect.height)*(LeftEyeRect.height + RightEyeRect.height)) +
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        (double)(dx1*dx1)/((double)MouthRect.width*MouthRect.width) +
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        (double)(dx2*dx2)/((double)MouthRect.width*MouthRect.width);
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}//void RFace::CalculateError(FaceData * lpFaceData)
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define MAX_ERROR 0xFFFFFFFF
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid  RFace::CreateFace(void * lpData)
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    FaceData Data;
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double Error = MAX_ERROR;
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double CurError = MAX_ERROR;
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    FaceData * lpFaceData = (FaceData*)lpData;
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int im = 0;//mouth was find
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int jl = 0;//left eye was find
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int kr = 0;//right eye was find
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    long MouthNumber = 0;
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    long LeftEyeNumber = 0;
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    long RightEyeNumber = 0;
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (int i = 0;i < m_lplFaceFeaturesCount[0] + 1;i ++)
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if ( !m_lplFaceFeaturesCount[0] )
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            Data.MouthRect = *(CvRect*)m_lpIdealFace[0].GetContour();
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if ( i != m_lplFaceFeaturesCount[0] )
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                Data.MouthRect = *(CvRect*)m_lppFoundedFaceFeatures[0][i].GetContour();
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            im = 1;
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for (int j = 0;j < m_lplFaceFeaturesCount[1] + 1;j ++)
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if ( !m_lplFaceFeaturesCount[1] )
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                Data.LeftEyeRect = *(CvRect*)m_lpIdealFace[1].GetContour();
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if (j != m_lplFaceFeaturesCount[1] )
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    Data.LeftEyeRect = *(CvRect*)m_lppFoundedFaceFeatures[1][j].GetContour();
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                jl = 1;
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for (int k = 0;k < m_lplFaceFeaturesCount[2] + 1;k ++)
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if ( !m_lplFaceFeaturesCount[2] )
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    Data.RightEyeRect = *(CvRect*)m_lpIdealFace[2].GetContour();
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if (k != m_lplFaceFeaturesCount[2] )
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        Data.RightEyeRect = *(CvRect*)m_lppFoundedFaceFeatures[2][k].GetContour();
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    kr = 1;
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CalculateError(&Data);
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if ( (im + jl + kr) )
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    Error = Data.Error/(im + jl + kr);
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }else
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    Error = MAX_ERROR;
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if (CurError > Error)
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CurError = Error;
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    MouthNumber = i;
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    LeftEyeNumber = j;
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    RightEyeNumber = k;
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if ( m_lplFaceFeaturesCount[0] )
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        lpFaceData->MouthRect = *(CvRect*)m_lppFoundedFaceFeatures[0][MouthNumber].GetContour();
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        lpFaceData->MouthRect = *(CvRect*)m_lpIdealFace[0].GetContour();
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if ( m_lplFaceFeaturesCount[1] )
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        lpFaceData->LeftEyeRect = *(CvRect*)m_lppFoundedFaceFeatures[1][LeftEyeNumber].GetContour();
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        lpFaceData->LeftEyeRect = *(CvRect*)m_lpIdealFace[1].GetContour();
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if ( m_lplFaceFeaturesCount[2] )
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        lpFaceData->RightEyeRect = *(CvRect*)m_lppFoundedFaceFeatures[2][RightEyeNumber].GetContour();
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        lpFaceData->RightEyeRect = *(CvRect*)m_lpIdealFace[2].GetContour();
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    lpFaceData->Error = CurError;
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}//void * RFace::CreateFace()
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid RFace::Show(IplImage * Image)
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (int i = 0;i < m_lFaceFeaturesNumber;i ++)
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if (m_lplFaceFeaturesCount[i])
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for (int j = 0;j < m_lplFaceFeaturesCount[i];j ++)
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvRect rect = *(CvRect*)m_lppFoundedFaceFeatures[i][j].GetContour();
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvPoint p1 = cvPoint(rect.x,rect.y);
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvPoint p2 = cvPoint(rect.x + rect.width,rect.y + rect.height);
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvRectangle(Image,p1,p2,CV_RGB(255,0,0),1);
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}//void RFace::Show(IplImage * Image)
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid RFace::ShowIdeal(IplImage* Image)
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (int i = 0;i < m_lFaceFeaturesNumber;i ++)
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvRect Rect = *(CvRect*)m_lpIdealFace[i].GetContour();
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvPoint p1 = cvPoint(Rect.x,Rect.y);
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvPoint p2 = cvPoint(Rect.x + Rect.width,Rect.y + Rect.height);
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvRectangle(Image,p1,p2,CV_RGB(0,0,255),1);
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}//void RFace::ShowIdeal(IplImage* Image)
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renninline void RFace::ResizeRect(CvRect Rect,CvRect * lpRect,long lDir,long lD)
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if (lDir == UP_SCALE)
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        lpRect->x = Rect.x - lD;
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        lpRect->y = Rect.y - lD;
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        lpRect->width = Rect.width + 2*lD;
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        lpRect->height = Rect.height + 2*lD;
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if (lDir == DOWN_SCALE)
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        lpRect->x = Rect.x + lD;
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        lpRect->y = Rect.y + lD;
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if (Rect.width - 2*lD >= 0)
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            lpRect->width = Rect.width - 2*lD;
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }else
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            lpRect->width = 0;
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if (Rect.height - 2*lD >= 0)
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            lpRect->height = Rect.height - 2*lD;
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }else
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            lpRect->height = 0;
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}// inline void RFace::ResizeRect(CvRect * lpRect,long lDir,long lD)
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
355