///////////////////////////////////////////////////////// // // preparePhoto.cpp // this file prepare photo : crop, rotate, align, gray // for facial reco training // // This file is strongly inspired // from Philipp Wagner Phyton works // http://docs.opencv.org/trunk/modules/contrib/doc/facerec/tutorial/facerec_video_recognition.html // Thank you Philipp, you're good. // // This file is put as exemple - considered it as a draft source code // debug lines are still here. No memory optimization etc. // but it does the job // // Pierre Raufast - 2013 // (for a better world, read Giono's books) // ///////////////////////////////////////////////////////// #include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include #include #include #define TRACE 1 // for trace fonction #define DEBUG_MODE 0 //for debug trace #define DEBUG if (DEBUG_MODE==1) // for debug trace using namespace std; using namespace cv; /** Function Headers */ int detectAndDisplay( Mat frame ); // change opencv path here <--------------- string face_cascade_name = "/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml"; string glasses_cascade_name = "/usr/share/opencv/haarcascades/haarcascade_eye_tree_eyeglasses.xml"; string eyes_cascade_name = "/usr/share/opencv/haarcascades/haarcascade_eye.xml"; CascadeClassifier face_cascade; CascadeClassifier eyes_cascade; CascadeClassifier glasses_cascade; CvPoint Myeye_left; CvPoint Myeye_right; int bEqHisto; /////////////////////////////////////////////////// // trace fonction, output only if #define TRACE=1 /////////////////////////////////////////////////// void trace(string s) { if (TRACE==1) { cout< qualityType; qualityType.push_back(CV_IMWRITE_JPEG_QUALITY); qualityType.push_back(90); // equalize histo color ? bEqHisto = atoi(argv[5]); //-- 1. Load the cascades if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; }; if( !eyes_cascade.load( eyes_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; }; if( !glasses_cascade.load( glasses_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; }; // new size of picture int newSize = atoi(argv[4]); // read the current directory DIR * rep =opendir("."); if (rep==NULL) return 0; struct dirent *ent; int index=1; // pour tous les fichiers du repertoire while ((ent=readdir(rep)) != NULL) { int nLen = strlen(ent->d_name); char * imageName = ent->d_name; // read extention, only keep jpg file if (nLen>4) if ((imageName[nLen-1]=='g')&&(imageName[nLen-2]=='p')&&(imageName[nLen-3]=='j')) { // Read the video stream trace("lecture : "+string(imageName)); frame = imread(imageName,1); // resize picture if (frame.size().width>newSize) { trace("- image need to be resized"); resizePicture(frame,newSize); imwrite(imageName,frame,qualityType); } // Apply the classifier to the frame if( !frame.empty() ) { trace("- start detect"); int result = detectAndDisplay( frame ); if (result==0) trace("- no face detected"); else { // crop face trace ("- start cropFace"); if (CropFace(frame, Myeye_left, Myeye_right, Myoffset_pct,Mydest_sz)==1) { char newName[16]; sprintf(newName,"%s%d.jpg",argv[3],index); string newNameS(newName); // convert to grayscale Mat grayframe; trace("- transforme : gray"); cvtColor(frame, grayframe, CV_BGR2GRAY); // equalize histo color if (bEqHisto==1) { trace("- transforme : equalize histo"); equalizeHist( grayframe, grayframe); } // save face trace("- save image "+newNameS); imwrite(newNameS,grayframe,qualityType); } else { trace("- crop face failed"); } } } index ++; } } closedir(rep); return 0; } ////////////////////////////////////////////// // detectAndDisplay ////////////////////////////////////////////// int detectAndDisplay( Mat frame ) { std::vector faces; Mat frame_gray; //convert to gray scale cvtColor( frame, frame_gray, CV_BGR2GRAY ); if (bEqHisto==1) { equalizeHist( frame_gray, frame_gray ); } //-- Detect faces face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(50, 50) ); // simplify : we only take picture with one face ! DEBUG printf("(D) detectAndDisplay : nb face=%d\n",faces.size()); if (faces.size()==0) return 0; else for( size_t i = 0; i < 1; i++ ) // only first face ! { Point center( faces[i].x + faces[i].width/2, faces[i].y + faces[i].height/2 ); Mat faceROI = frame_gray( faces[i] ); std::vector eyes; //-- In each face, detect eyes eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(30, 30) ); // if no glasses if (eyes.size()==2) { trace("-- face without glasses"); // detect eyes for( size_t j = 0; j < 2; j++ ) { Point eye_center( faces[i].x + eyes[1-j].x + eyes[1-j].width/2, faces[i].y + eyes[1-j].y + eyes[1-j].height/2 ); if (j==0) // left eye { Myeye_left.x =eye_center.x; Myeye_left.y =eye_center.y; } if (j==1) // right eye { Myeye_right.x =eye_center.x; Myeye_right.y =eye_center.y; } } } else { // tests with glasses glasses_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(20, 20) ); if (eyes.size()!=2) return 0; else { trace("-- face with glasses"); for( size_t j = 0; j < 2; j++ ) { Point eye_center( faces[i].x + eyes[1-j].x + eyes[1-j].width/2, faces[i].y + eyes[1-j].y + eyes[1-j].height/2 ); if (j==0) // left eye { Myeye_left.x =eye_center.x; Myeye_left.y =eye_center.y; } if (j==1) // right eye { Myeye_right.x =eye_center.x; Myeye_right.y =eye_center.y; } } } } } // sometimes eyes are inversed ! we switch them if (Myeye_right.x