00001
00002 #include "facedetect.h"
00003
00010 DLLEXPORT void requestVideoImage(HDC hdc)
00011 {
00012 destinationHDC = hdc;
00013 isImageRequested = 1;
00014 }
00015
00019 DLLEXPORT void initiateVideo(int camNumber)
00020 {
00021 capture = cvCaptureFromCAM( camNumber );
00022
00023 cascade = (CvHaarClassifierCascade*)cvLoad( "./haarcascade_frontalface_alt2.xml", NULL, NULL, NULL );
00024 if( !cascade )
00025 {
00026 fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
00027 isInitiated = 0;
00028 return;
00029 }
00030
00031 storage = cvCreateMemStorage(0);
00032
00033 isInitiated = 1;
00034 }
00035
00040 DLLEXPORT int getVideoSizeX()
00041 {
00042 return videoSizeX;
00043 }
00044
00049 DLLEXPORT int getVideoSizeY()
00050 {
00051 return videoSizeY;
00052 }
00053
00060 DLLEXPORT int getMajorFacePosX()
00061 {
00062 return majorFacePosX;
00063 }
00064
00071 DLLEXPORT int getMajorFacePosY()
00072 {
00073 return majorFacePosY;
00074 }
00075
00082 DLLEXPORT double getMajorFaceRelativeX()
00083 {
00084 if((!image)|| (majorFacePosX < 0))
00085 {
00086 return -1.0;
00087 }
00088 else
00089 {
00090 return ((double)majorFacePosX / (double)image->width);
00091 }
00092 }
00093
00100 DLLEXPORT double getMajorFaceRelativeY()
00101 {
00102 if((!image)|| (majorFacePosY < 0))
00103 {
00104 return -1.0;
00105 }
00106 else
00107 {
00108 return ((double)majorFacePosY / (double)image->height);
00109 }
00110 }
00111
00115 DLLEXPORT void processVideoFrame()
00116 {
00117 if (isInitiated)
00118 {
00119 if( !capture )
00120 {
00121 fprintf(stderr,"Could not initialize capturing...\n");
00122 isInitiated = 0;
00123 return;
00124 }
00125
00126 frame = cvQueryFrame( capture );
00127 if( frame )
00128 {
00129 if( !image )
00130 {
00131
00132 image = cvCreateImage( cvGetSize(frame), 8, 3 );
00133 image->origin = frame->origin;
00134
00135 videoSizeX = image->width;
00136 videoSizeY = image->height;
00137 panelImage.Create(image->width, image->height, 8, image->origin);
00138 }
00139
00140
00141
00142 cvCopy( frame, image, 0 );
00143 isBusy = 1;
00144 detect_and_draw( image );
00145 isBusy = 0;
00146
00147
00148 if (isImageRequested)
00149 {
00150 panelImage.CopyOf(image, -1);
00151 RECT r;
00152 if (frame->origin)
00153 {
00154 r.bottom = 0;
00155 r.left = 0;
00156 r.top = 240;
00157 r.right = 320;
00158 }
00159 else
00160 {
00161 r.bottom = 240;
00162 r.left = 0;
00163 r.top = 0;
00164 r.right = 320;
00165 }
00166
00167 panelImage.DrawToHDC(destinationHDC, &r);
00168
00169 isImageRequested = 0;
00170 }
00171
00172 }
00173
00174 }
00175 }
00176
00180 DLLEXPORT void closeVideo()
00181 {
00182 if (capture) cvReleaseCapture( &capture );
00183 if (image) cvReleaseImage( &image );
00184 if (&panelImage) panelImage.~CvvImage();
00185 if (storage) cvReleaseMemStorage( &storage );
00186 if (cascade) cvReleaseHaarClassifierCascade( &cascade );
00187 }
00188
00195 DLLEXPORT int getNumberOfFaces()
00196 {
00197 if (isBusy) return -1;
00198 else return numberOfFaces;
00199 }
00200
00201
00208 void detect_and_draw( IplImage* img )
00209 {
00210 double scale = 4.0;
00211 IplImage* gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );
00212 IplImage* small_img = cvCreateImage( cvSize( cvRound (img->width/scale),
00213 cvRound (img->height/scale)),
00214 8, 1 );
00215 int i;
00216
00217 cvCvtColor( img, gray, CV_BGR2GRAY );
00218 cvResize( gray, small_img, CV_INTER_LINEAR );
00219 cvEqualizeHist( small_img, small_img );
00220 cvClearMemStorage( storage );
00221
00222 if( cascade )
00223 {
00224
00225 if(img->origin) cvFlip(small_img, small_img, 0);
00226
00227 faces = cvHaarDetectObjects( small_img, cascade, storage,
00228 1.1, 2, 0,
00229 cvSize(30, 30) );
00230
00231 faceSize = 0;
00232 majorFacePosX = -1;
00233 majorFacePosY = -1;
00234
00235 numberOfFaces = faces->total;
00236
00237
00238 for( i = 0; i < (faces ? faces->total : 0); i++ )
00239 {
00240 CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
00241
00242
00243 CvPoint center;
00244 int height;
00245 int width;
00246 center.x = cvRound(((double)r->x + (double)r->width * 0.5) * scale);
00247 center.y = cvRound(((double)r->y + (double)r->height * 0.5) * scale);
00248
00249 int newSize = cvRound(r->height * r->width * scale);
00250 if (newSize > faceSize)
00251 {
00252 faceSize = newSize;
00253 majorFacePosX = center.x;
00254 if (img->origin) majorFacePosY = img->height - center.y;
00255 else majorFacePosY = center.y;
00256 }
00257
00258 width = cvRound(r->width*scale * 0.7) ;
00259 height = cvRound(r->height*scale * 1.2);
00260
00261 if(img->origin)
00262 {
00263 cvRectangle( img, cvPoint(center.x-width/2,img->height-(center.y-height/2)),
00264 cvPoint(center.x+width/2,img->height-(center.y+height/2)),
00265 cvScalar(0,255,0), 2, 8, 0 );
00266 }
00267 else
00268 {
00269 cvRectangle( img, cvPoint(center.x-width/2,center.y-height/2),
00270 cvPoint(center.x+width/2,center.y+height/2),
00271 cvScalar(0,255,0), 2, 8, 0 );
00272 }
00273
00274
00275 }
00276
00277 }
00278
00279
00280 cvReleaseImage( &gray );
00281 cvReleaseImage( &small_img );
00282
00283
00284 }
00285
00286
00287
00288
00289