00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00048
00049
00050
00051
00052
00053
00055
00056 #include "CvFaceDetect.hh"
00057
00058 CvFaceDetect::CvFaceDetect(int min, int max)
00059 {
00060 this->started = false;
00061 this->vrfilter = new CvVrFilter(min, max);
00062
00063
00064 this->storage = cvCreateMemStorage(0);
00065
00066 }
00067
00068 CvFaceDetect::~CvFaceDetect()
00069 {
00070 cvReleaseImage( &this->skin_locus_map );
00071 #ifdef DETECT
00072 cvReleaseImage( &this->ycc );
00073 cvReleaseImage( &this->y );
00074 cvReleaseImage( &this->mouth_map );
00075 cvReleaseImage( &this->mouth_map_bin );
00076 cvReleaseImage( &this->eyes_map );
00077 cvReleaseImage( &this->eyes_map_bin );
00078 #endif
00079
00080 cvReleaseMemStorage( &this->storage );
00081 }
00082
00083 void
00084 CvFaceDetect::cvFaceDetect(IplImage * image, int DRAW_TYPE)
00085 {
00086 if(started)
00087 {
00088
00089 cvReleaseImage( &this->skin_locus_map );
00090
00091 #ifdef DETECT
00092 cvReleaseImage( &this->ycc );
00093 cvReleaseImage( &this->y );
00094 cvReleaseImage( &this->mouth_map );
00095 cvReleaseImage( &this->mouth_map_bin );
00096 cvReleaseImage( &this->eyes_map );
00097 cvReleaseImage( &this->eyes_map_bin );
00098 #endif
00099 cvClearMemStorage(this->storage);
00100
00101
00102
00103 }
00104
00105
00106
00107 this->started = true;
00108 this->size = cvGetSize(image);
00109 this->source = image ;
00110
00111 this->faces = cvCreateSeq( 0,
00112 sizeof(CvSeq),
00113 sizeof(Cvface),
00114 storage
00115 );
00116
00117 this->skin_locus_map = this->vrfilter->cvVrFilter(image, this->storage, this->faces);
00118
00119
00120 #ifdef DETECT
00121
00122
00123 ycc = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3 );
00124 cvCvtColor( this->skin_locus_map , ycc, CV_BGR2YCrCb );
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 }
00175
00176 if (DRAW_TYPE == DRAW_EYES || DRAW_TYPE == DRAW_ALL)
00177 {
00178 for (int i= 0 ; i < 2; i++)
00179 {
00180 if ( &face->eyes_box[i] != 0)
00181 {
00182
00183
00184
00185 cvEllipse( image,
00186 cvPoint((int) face->eyes_box[i].center.x ,
00187 (int) face->eyes_box[i].center.y) ,
00188 cvSize( (int) face->eyes_box[i].size.width ,
00189 (int) face->eyes_box[i].size.height),
00190 (double)(360 * face->eyes_box[i].angle)/ (2 * CV_PI) - 90,
00191 0, 360,
00192 cvScalar( 0, 255, 0 ),
00193 1, CV_AA );
00194 }
00195 }
00196 }
00197
00198 if (DRAW_TYPE == DRAW_MOUTH || DRAW_TYPE == DRAW_ALL)
00199 {
00200 if ( &face->mouth_box != 0)
00201 {
00202
00203
00204 cvEllipse( image,
00205 cvPoint((int) face->mouth_box.center.x ,
00206 (int) face->mouth_box.center.y) ,
00207 cvSize( (int) face->mouth_box.size.width ,
00208 (int) face->mouth_box.size.height),
00209 (double)(360 * face->mouth_box.angle)/ (2 * CV_PI) - 90,
00210 0, 360,
00211 cvScalar( 0, 255, 255 ),
00212 1, CV_AA );
00213
00214
00215 }
00216
00217 }
00218
00219 if (DRAW_TYPE == DRAW_ALL)
00220 {
00221 float angle = 0;
00222
00223 if (&face->eyes_box[0] != 0 && &face->eyes_box[1] != 0)
00224 {
00225 cvLine( image,
00226 cvPoint((int) face->eyes_box[0].center.x ,
00227 (int) face->eyes_box[0].center.y),
00228 cvPoint((int) face->eyes_box[1].center.x ,
00229 (int) face->eyes_box[1].center.y),
00230 cvScalar( 231, 169, 0 ),
00231 2, CV_AA, 0 );
00232
00233 angle = (float)(atan2((face->eyes_box[1].center.y - face->eyes_box[0].center.y),
00234 (face->eyes_box[1].center.x - face->eyes_box[0].center.x))
00235 + CV_PI/2);
00236
00237
00238
00239 }
00240
00241 if (&face->mouth_box != 0 )
00242 {
00243 int mult = (int)(MAX(face->skin_face.skin_box.size.width,
00244 face->skin_face.skin_box.size.height ) /2);
00245
00246 cvLine( image,
00247 cvPoint((int) ((face->mouth_box.center.x) - mult *
00248 cos(angle)),
00249 (int) ((face->mouth_box.center.y) - mult *
00250 sin(angle))),
00251 cvPoint((int) ((face->mouth_box.center.x) + mult *
00252 cos(angle)),
00253 (int) ((face->mouth_box.center.y) + mult *
00254 sin(angle))),
00255 cvScalar( 186, 114, 8 ),
00256 2, CV_AA, 0 );
00257 }
00258
00259 }
00260
00261 }
00262 }
00263 #endif
00264
00265 }
00266
00267 void
00268 CvFaceDetect::icvMouthMap(IplImage * image)
00269 {
00270 this->mouth_map = cvCreateImage(this->size, IPL_DEPTH_32F, 1 );
00271
00272 int _cr, _cb ;
00273 for ( int j = 0; j < this->size.height; j++ ) {
00274 for ( int i=0; i < this->size.width; i++ ) {
00275
00276 _cr = CV_IMAGE_ELEM(ycc, unsigned char, j, 3*i +1);
00277 _cb = CV_IMAGE_ELEM(ycc, unsigned char, j, 3*i +2);
00278
00279 CV_IMAGE_ELEM( this->mouth_map, float, j, i ) =
00280 (float) ( _cr * (255 - (_cr - _cb) ) * _cr ) ;
00281
00282 }
00283 }
00284 }
00285
00286 void
00287 CvFaceDetect::icvMouthMask()
00288 {
00289 this->mouth_map_bin = cvCreateImage(this->size, IPL_DEPTH_8U, 1 );
00290
00291 IplImage * _mouth_map_bin;
00292 _mouth_map_bin = cvCreateImage(this->size, IPL_DEPTH_8U, 1 );
00293
00294
00295 double map_min = 0 , map_max = 0 , map_range;
00296 cvMinMaxLoc( this->mouth_map, &map_min , &map_max );
00297 map_range = map_max - ( map_max * 0.06 );
00298
00299 cvThreshold( this->mouth_map, _mouth_map_bin, map_range, 255, CV_THRESH_BINARY );
00300
00301
00302
00303
00304
00305
00306
00307
00308 IplConvKernel* kernelOp = cvCreateStructuringElementEx( 4, 3, 1, 1, CV_SHAPE_CROSS, NULL );
00309 cvDilate( _mouth_map_bin , this->mouth_map_bin, kernelOp, 1 );
00310
00311
00312
00313
00314
00315
00316
00317
00318 #ifdef MOUTH
00319 cvNamedWindow("mouth", 1);
00320 cvShowImage("mouth", this->mouth_map_bin);
00321 #endif
00322
00323 cvReleaseImage( &_mouth_map_bin );
00324 }
00325
00326 void
00327 CvFaceDetect::icvMouthDetect()
00328 {
00329
00330 int mouth = 0 ;
00331 int x , y, width, height, count;
00332 double angle ;
00333
00334 Cvface *face;
00335
00336 for (int i = 0; i < faces->total; i++)
00337 {
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 face = (Cvface *)cvGetSeqElem( this->faces, i);
00372
00373 cvSetImageROI(this->mouth_map_bin, face->skin_face.skin_rect );
00374
00375 x = y = height = width = count = 0;
00376 angle = 0;
00377
00378 mouth = cvFindContours( this->mouth_map_bin , this->storage, &(this->contour) ,
00379 sizeof(CvContour), CV_RETR_EXTERNAL ,
00380 CV_CHAIN_APPROX_SIMPLE ,
00381 cvPoint( face->skin_face.skin_rect.x,face->skin_face.skin_rect.y ) );
00382
00383
00384 if (mouth == 0)
00385 {
00386 continue;
00387 }
00388
00389
00390 for(CvSeq* temp_contour = this->contour; temp_contour != 0; temp_contour = temp_contour->h_next )
00391 {
00392 CvBox2D box = cvMinAreaRect2( temp_contour );
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 count ++;
00412 x += (int)box.center.x ;
00413 y += (int)box.center.y ;
00414 width = MAX ((int)box.size.width, width) ;
00415 height= MAX((int)box.size.height, height );
00416 angle += box.angle ;
00417
00418
00419 }
00420
00421 if (count > 0)
00422 {
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 face->mouth_box.center = cvPoint2D32f( x/count , y/count);
00433 face->mouth_box.size = cvSize2D32f( width , height );
00434 face->mouth_box.angle = (float) angle /count ;
00435
00436
00437
00438 }
00439
00440
00441
00442
00443
00444
00445 }
00446
00447
00448
00449
00450 }
00451
00452 void
00453 CvFaceDetect::icvEyesMap(IplImage * image)
00454 {
00455 this->eyes_map = cvCreateImage(this->size, IPL_DEPTH_8U, 1 );
00456 this->y = cvCreateImage(this->size, IPL_DEPTH_8U, 1 );
00457
00458 cvSplit (ycc, y, 0, 0, 0);
00459
00460 IplImage *cb2, *cr_2, *cbcr ;
00461 cb2 = cvCreateImage(cvGetSize(image), IPL_DEPTH_32F, 1 );
00462 cr_2 = cvCreateImage(cvGetSize(image), IPL_DEPTH_32F, 1 );
00463 cbcr = cvCreateImage(cvGetSize(image), IPL_DEPTH_32F, 1 );
00464
00465
00466 int _cr, _cb ;
00467 for ( int j = 0; j < this->size.height; j++ ) {
00468 for ( int i=0; i < this->size.width; i++ ) {
00469
00470 _cr = CV_IMAGE_ELEM(ycc, unsigned char, j, 3*i +1);
00471 _cb = CV_IMAGE_ELEM(ycc, unsigned char, j, 3*i +2);
00472
00473 CV_IMAGE_ELEM( cb2, float, j, i ) = (float)(_cb * _cb) ;
00474 CV_IMAGE_ELEM( cr_2, float, j, i ) = (float)(255 - _cr) * (255 - _cr) ;
00475 CV_IMAGE_ELEM( cbcr, float, j, i ) = (float)(_cb / _cr) ;
00476
00477 }
00478 }
00479
00480
00481 double cb2_min = 0 , cb2_max = 0 , cr_2_min = 0, cr_2_max = 0 , cbcr_min = 0 , cbcr_max = 0;
00482
00483 cvMinMaxLoc( cb2, &cb2_min , &cb2_max );
00484 cvMinMaxLoc( cr_2, &cr_2_min , &cr_2_max );
00485 cvMinMaxLoc( cbcr, &cbcr_min , &cbcr_max );
00486
00487
00488 IplImage *cb2_norm, *cr_2_norm, *cbcr_norm ;
00489 cb2_norm = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1 );
00490 cr_2_norm = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1 );
00491 cbcr_norm = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1 );
00492
00493
00494 float _cbcr , _cb2, _cr_2 ;
00495 double cr_2_range = cr_2_max - cr_2_min;
00496 double cbcr_range = cbcr_max - cbcr_min;
00497 double cb2_range = cb2_max - cb2_min;
00498
00499 for ( int j = 0; j < this->size.height; j++ ) {
00500 for ( int i=0; i < this->size.width; i++ ) {
00501
00502 _cb2 = CV_IMAGE_ELEM( cb2 , float, j, i ) ;
00503 _cr_2 = CV_IMAGE_ELEM( cr_2, float, j, i ) ;
00504 _cbcr = CV_IMAGE_ELEM( cbcr, float, j, i ) ;
00505
00506
00507
00508 CV_IMAGE_ELEM( cb2_norm , unsigned char, j, i ) =
00509 (unsigned char)(( (_cb2 - cb2_min) / cb2_range) * 255);
00510 CV_IMAGE_ELEM( cr_2_norm , unsigned char, j, i ) =
00511 (unsigned char)(( (_cr_2 - cr_2_min) / cr_2_range) * 255);
00512 CV_IMAGE_ELEM( cbcr_norm , unsigned char, j, i ) =
00513 (unsigned char)(( (_cbcr - cbcr_min) / cbcr_range) * 255);
00514
00515 }
00516 }
00517
00518
00519 for ( int j = 0; j < this->size.height; j++ ) {
00520 for ( int i=0; i < this->size.width; i++ ) {
00521
00522 _cb2 = CV_IMAGE_ELEM( cb2_norm , unsigned char, j, i ) ;
00523 _cr_2 = CV_IMAGE_ELEM( cr_2_norm, unsigned char, j, i ) ;
00524 _cbcr = CV_IMAGE_ELEM( cbcr_norm, unsigned char, j, i ) ;
00525
00526 CV_IMAGE_ELEM( this->eyes_map , unsigned char, j, i ) =
00527 (unsigned char) ( (_cb2 + _cr_2 + _cbcr ) / 3 ) ;
00528
00529 }
00530 }
00531
00532 cvReleaseImage( &cb2 );
00533 cvReleaseImage( &cr_2 );
00534 cvReleaseImage( &cbcr );
00535 cvReleaseImage( &cb2_norm );
00536 cvReleaseImage( &cr_2_norm );
00537 cvReleaseImage( &cbcr_norm );
00538 }
00539
00540 void
00541 CvFaceDetect::icvEyesMask(){
00542
00543 IplImage *_eyes_map_bin, *eyes_map_y , *eyes;
00544
00545 eyes_map_bin = cvCreateImage(this->size, IPL_DEPTH_8U, 1 );
00546
00547 _eyes_map_bin = cvCreateImage(this->size, IPL_DEPTH_8U, 1 );
00548 eyes_map_y = cvCreateImage(this->size, IPL_DEPTH_8U, 1 );
00549 eyes = cvCreateImage(this->size, IPL_DEPTH_8U, 1 );
00550
00551
00552 double map_min = 0 , map_max = 0 , map_range;
00553 cvMinMaxLoc( this->eyes_map, &map_min , &map_max );
00554 map_range = map_max - ( map_max * 0.60 );
00555
00556
00557
00558 cvThreshold( this->eyes_map, _eyes_map_bin, map_range, 255, CV_THRESH_BINARY );
00559
00560
00561 cvThreshold( this->y , eyes_map_y, 80, 255, CV_THRESH_BINARY_INV);
00562
00563 cvAnd( _eyes_map_bin, eyes_map_y, eyes );
00564
00565
00566
00567
00568 cvDilate( eyes , eyes_map_bin, NULL , 1 );
00569
00570 #ifdef EYES
00571 cvNamedWindow( "eyes", 1 );
00572 cvShowImage( "eyes", eyes_map_bin);
00573 #endif
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589 cvReleaseImage( &_eyes_map_bin );
00590 cvReleaseImage( &eyes_map_y );
00591 cvReleaseImage( &eyes );
00592 }
00593
00594 void
00595 CvFaceDetect::icvEyesDetect()
00596 {
00597
00598 int eyes = 0 ;
00599
00600
00601
00602
00603 Cvface *face;
00604
00605
00606
00607
00608
00609 for (int i = 0; i < this->faces->total ; i++)
00610 {
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644 face = (Cvface *)cvGetSeqElem( this->faces, i);
00645
00646 cvSetImageROI(this->eyes_map_bin, face->skin_face.skin_rect );
00647
00648
00649
00650 eyes = cvFindContours( this->eyes_map_bin , this->storage, &(this->contour) ,
00651 sizeof(CvContour), CV_RETR_EXTERNAL ,
00652 CV_CHAIN_APPROX_SIMPLE ,
00653 cvPoint( face->skin_face.skin_rect.x, face->skin_face.skin_rect.y ) );
00654
00655
00656 if (eyes == 0) continue;
00657
00658 int _ey = 0;
00659
00660 for(CvSeq* temp_contour = this->contour; temp_contour != 0; temp_contour = temp_contour->h_next )
00661 {
00662 CvBox2D box = cvMinAreaRect2( temp_contour );
00663
00664
00665
00666
00667
00668 if (box.size.width < (face->skin_face.skin_rect.width)/16 ||
00669 box.size.height < (face->skin_face.skin_rect.height)/16
00670
00671
00672
00673 )
00674 continue;
00675
00676
00677
00678
00679 face->eyes_box[_ey%2] = box ;
00680
00681 _ey++;
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700 }
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718 }
00719
00720
00721 }
00722
00723 void
00724 CvFaceDetect::icvMouthEyesMap(IplImage * image)
00725 {
00726 this->eyes_map = cvCreateImage(this->size, IPL_DEPTH_8U, 1 );
00727 this->y = cvCreateImage(this->size, IPL_DEPTH_8U, 1 );
00728 this->mouth_map = cvCreateImage(this->size, IPL_DEPTH_32F, 1 );
00729
00730 cvSplit (ycc, y, 0, 0, 0);
00731
00732 IplImage *cb2, *cr_2, *cbcr ;
00733 cb2 = cvCreateImage(cvGetSize(image), IPL_DEPTH_32F, 1 );
00734 cr_2 = cvCreateImage(cvGetSize(image), IPL_DEPTH_32F, 1 );
00735 cbcr = cvCreateImage(cvGetSize(image), IPL_DEPTH_32F, 1 );
00736
00737
00738 int _cr, _cb ;
00739 for ( int j = 0; j < this->size.height; j++ ) {
00740 for ( int i=0; i < this->size.width; i++ ) {
00741
00742 _cr = CV_IMAGE_ELEM(ycc, unsigned char, j, 3*i +1);
00743 _cb = CV_IMAGE_ELEM(ycc, unsigned char, j, 3*i +2);
00744
00745 CV_IMAGE_ELEM( cb2, float, j, i ) = (float)(_cb * _cb) ;
00746 CV_IMAGE_ELEM( cr_2, float, j, i ) = (float)(255 - _cr) * (255 - _cr) ;
00747 CV_IMAGE_ELEM( cbcr, float, j, i ) = (float)(_cb / _cr) ;
00748
00749
00750 CV_IMAGE_ELEM( this->mouth_map, float, j, i ) =
00751 (float) ( _cr * (255 - (_cr - _cb) ) * _cr ) ;
00752
00753 }
00754 }
00755
00756
00757 double cb2_min = 0 , cb2_max = 0 , cr_2_min = 0, cr_2_max = 0 , cbcr_min = 0 , cbcr_max = 0;
00758
00759 cvMinMaxLoc( cb2, &cb2_min , &cb2_max );
00760 cvMinMaxLoc( cr_2, &cr_2_min , &cr_2_max );
00761 cvMinMaxLoc( cbcr, &cbcr_min , &cbcr_max );
00762
00763
00764 IplImage *cb2_norm, *cr_2_norm, *cbcr_norm ;
00765 cb2_norm = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1 );
00766 cr_2_norm = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1 );
00767 cbcr_norm = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1 );
00768
00769
00770 float _cbcr , _cb2, _cr_2 ;
00771 double cr_2_range = cr_2_max - cr_2_min;
00772 double cbcr_range = cbcr_max - cbcr_min;
00773 double cb2_range = cb2_max - cb2_min;
00774
00775 for ( int j = 0; j < this->size.height; j++ ) {
00776 for ( int i=0; i < this->size.width; i++ ) {
00777
00778 _cb2 = CV_IMAGE_ELEM( cb2 , float, j, i ) ;
00779 _cr_2 = CV_IMAGE_ELEM( cr_2, float, j, i ) ;
00780 _cbcr = CV_IMAGE_ELEM( cbcr, float, j, i ) ;
00781
00782
00783
00784 CV_IMAGE_ELEM( cb2_norm , unsigned char, j, i ) =
00785 (unsigned char)(( (_cb2 - cb2_min) / cb2_range) * 255);
00786 CV_IMAGE_ELEM( cr_2_norm , unsigned char, j, i ) =
00787 (unsigned char)(( (_cr_2 - cr_2_min) / cr_2_range) * 255);
00788 CV_IMAGE_ELEM( cbcr_norm , unsigned char, j, i ) =
00789 (unsigned char)(( (_cbcr - cbcr_min) / cbcr_range) * 255);
00790
00791 }
00792 }
00793
00794
00795 for ( int j = 0; j < this->size.height; j++ ) {
00796 for ( int i=0; i < this->size.width; i++ ) {
00797
00798 _cb2 = CV_IMAGE_ELEM( cb2_norm , unsigned char, j, i ) ;
00799 _cr_2 = CV_IMAGE_ELEM( cr_2_norm, unsigned char, j, i ) ;
00800 _cbcr = CV_IMAGE_ELEM( cbcr_norm, unsigned char, j, i ) ;
00801
00802 CV_IMAGE_ELEM( this->eyes_map , unsigned char, j, i ) =
00803 (unsigned char) ( (_cb2 + _cr_2 + _cbcr ) / 3 ) ;
00804
00805 }
00806 }
00807
00808 cvReleaseImage( &cb2 );
00809 cvReleaseImage( &cr_2 );
00810 cvReleaseImage( &cbcr );
00811 cvReleaseImage( &cb2_norm );
00812 cvReleaseImage( &cr_2_norm );
00813 cvReleaseImage( &cbcr_norm );
00814 }
00815
00816 void
00817 CvFaceDetect::icvMouthEyesMask()
00818 {
00819 this->mouth_map_bin = cvCreateImage(this->size, IPL_DEPTH_8U, 1 );
00820 this->eyes_map_bin = cvCreateImage(this->size, IPL_DEPTH_8U, 1 );
00821
00822 IplImage * _mouth_map_bin;
00823 _mouth_map_bin = cvCreateImage(this->size, IPL_DEPTH_8U, 1 );
00824
00825 IplImage *_eyes_map_bin, *eyes_map_y , *eyes;
00826 _eyes_map_bin = cvCreateImage(this->size, IPL_DEPTH_8U, 1 );
00827 eyes_map_y = cvCreateImage(this->size, IPL_DEPTH_8U, 1 );
00828 eyes = cvCreateImage(this->size, IPL_DEPTH_8U, 1 );
00829
00830
00831 double map_min = 0 , map_max = 0 , map_range;
00832 cvMinMaxLoc( this->mouth_map, &map_min , &map_max );
00833 map_range = map_max - ( map_max * 0.04 );
00834
00835 cvThreshold( this->mouth_map, _mouth_map_bin, map_range, 255, CV_THRESH_BINARY );
00836
00837 IplConvKernel* kernelOp = cvCreateStructuringElementEx( 4, 3, 1, 1, CV_SHAPE_CROSS, NULL );
00838 cvDilate( _mouth_map_bin , this->mouth_map_bin, kernelOp, 1 );
00839
00840
00841 #ifdef MOUTH
00842 cvNamedWindow("mouth map bin", 1);
00843 cvShowImage("mouth", this->mouth_map_bin);
00844 cvWaitKey(0);
00845 #endif
00846
00847
00848 cvMinMaxLoc( this->eyes_map, &map_min , &map_max );
00849 map_range = map_max - ( map_max * 0.60 );
00850
00851
00852 cvThreshold( this->eyes_map, _eyes_map_bin, map_range, 255, CV_THRESH_BINARY );
00853
00854
00855 cvThreshold( this->y , eyes_map_y, 80, 255, CV_THRESH_BINARY_INV);
00856
00857 cvAnd( _eyes_map_bin, eyes_map_y, eyes );
00858
00859
00860
00861
00862 cvDilate( eyes , eyes_map_bin, NULL , 1 );
00863
00864 #ifdef EYES
00865 cvNamedWindow( "eyes", 1 );
00866 cvShowImage( "eyes", eyes_map_bin);
00867 #endif
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883 cvReleaseImage( &_eyes_map_bin );
00884 cvReleaseImage( &eyes_map_y );
00885 cvReleaseImage( &eyes );
00886
00887 cvReleaseImage( &_mouth_map_bin );
00888 }
00889
00890 void
00891 CvFaceDetect::icvMouthEyesDetect()
00892 {
00893 int mouth = 0 ;
00894 int eyes = 0 ;
00895
00896 int x , y, width, height, count;
00897 double angle ;
00898
00899 Cvface *face ;
00900
00901 for (int i = 0; i < this->faces->total; i++)
00902 {
00903
00904 face = (Cvface *)cvGetSeqElem( this->faces, i);
00905
00906 cvSetImageROI(this->mouth_map_bin, face->skin_face.skin_rect );
00907 cvSetImageROI(this->eyes_map_bin, face->skin_face.skin_rect );
00908
00909 x = y = height = width = count = 0;
00910 angle = 0;
00911
00912 mouth = cvFindContours( this->mouth_map_bin , this->storage, &(this->contour) ,
00913 sizeof(CvContour), CV_RETR_EXTERNAL ,
00914 CV_CHAIN_APPROX_SIMPLE ,
00915 cvPoint( face->skin_face.skin_rect.x,face->skin_face.skin_rect.y ) );
00916
00917
00918 if (mouth == 0)
00919 {
00920 continue;
00921 }
00922
00923
00924 for(CvSeq* temp_contour = this->contour; temp_contour != 0; temp_contour = temp_contour->h_next )
00925 {
00926 CvBox2D box = cvMinAreaRect2( temp_contour );
00927
00928
00929 if (box.size.width > (face->skin_face.skin_rect.width)/2.5 ||
00930 box.size.height > (face->skin_face.skin_rect.height)/4 ||
00931 box.size.width < (face->skin_face.skin_rect.width)/14 ||
00932 box.size.height < (face->skin_face.skin_rect.height)/14
00933 )
00934 continue;
00935
00936
00937 count ++;
00938 x += (int)box.center.x ;
00939 y += (int)box.center.y ;
00940 width = MAX ((int)box.size.width, width) ;
00941 height= MAX((int)box.size.height, height );
00942 angle += box.angle ;
00943
00944
00945 }
00946
00947 if (count > 0)
00948 {
00949
00950
00951 face->mouth_box.center = cvPoint2D32f( x/count , y/count);
00952 face->mouth_box.size = cvSize2D32f( width , height );
00953 face->mouth_box.angle = (float) angle /count ;
00954
00955
00956
00957 }
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013 }
01014 }
01015
01016