c++ - Eye Blinking Detection -
some warnings appear in terminal during running:
opencv error: assertion failed(s>=0) in setsize, file /home/me/opencv2.4/modules/core/src/matrix.cpp, line 116
the program compiled without error , executes, problem eye roi size changes when user moves closer/farther away webcam, due changing of size, warning appears. managed solve these warnings setting eye roi size equal eye template size. however, ends program fails classify user's eyes open/close because minval
obtained 0
. method used opencv template matching. alternatively, fix distance webcam , fix eye template size avoid warning. every time warning appears, program fails classify open/close eyes. program doesn't work because mistakenly classifies open eyes closed , vice versa.
questions:
is there alternative identify open , close eyes other template matching?
any ideas how improve program in classification of blinking?
any working example know in opencv c/c++ api can classify open , close eyes , count accurately blinking times?
static cvmemstorage* storage = 0; // create new haar classifier static cvhaarclassifiercascade* cascade = 0; // function prototype detecting , drawing object image bool detect_and_draw( iplimage* image ,cvhaarclassifiercascade* cascade); const char *cascade_name[1]={"eyes.xml"}; cv::mat roiimg; int threshold_value = 200; int threshold_type = 3;; int const max_value = 255; int const max_type = 4; int const max_binary_value = 255; int hough_thr = 35; cv::mat src_gray, dst; using namespace cv; mat img1; mat img2; mat templ; mat result; const char* image_window = "source image"; const char* result_window = "result window"; int match_method=0; int max_trackbar = 5; int eye_open=0; int eye_close=0; //matching 2 images ,eye closed or open void matchingmethod(cv::mat templ,int id ) { /// source image display cv::mat img_display; roiimg.copyto( img_display ); /// create result matrix int result_cols = roiimg.cols - templ.cols + 1; int result_rows = roiimg.rows - templ.rows + 1; result.create( result_cols, result_rows, cv_32fc1 ); /// matching , normalize cv::matchtemplate( roiimg, templ, result, match_method ); cv::normalize( result, result, 0, 1, norm_minmax, -1, mat() ); /// localizing best match minmaxloc double minval; double maxval; point minloc; point maxloc; cv::point matchloc; cv::minmaxloc( result, &minval, &maxval, &minloc, &maxloc, mat() ); ///justing checkin match template value reaching threashold if(id == 0 && (minval < 0)) { eye_open=eye_open+1; if(eye_open == 1) { std::cout<<"eye open"<<std::endl; eye_open=0; eye_close=0; } } else if(id == 1 && (minval < 0)) eye_close=eye_close+1; if(eye_close == 1) { std::cout<<"eye closed"<<std::endl; eye_close=0; system("python send_arduino.py"); } /// sqdiff , sqdiff_normed, best matches lower values. other methods, higher better if( match_method == cv_tm_sqdiff || match_method == cv_tm_sqdiff_normed ) { matchloc = minloc; } else { matchloc = maxloc; } /// show me got cv::rectangle( img_display, matchloc, point( matchloc.x + templ.cols , matchloc.y + templ.rows ), scalar::all(0), 2, 8, 0 ); cv::rectangle( result, matchloc, point( matchloc.x + templ.cols , matchloc.y + templ.rows ), scalar::all(0), 2, 8, 0 ); cv::imshow( image_window, img_display ); cv::imshow( result_window, result ); return; } void detect_blink(cv::mat roi) { try { matchingmethod(img1,0); matchingmethod(img2,1); } catch( cv::exception& e ) { std::cout<<"an exception occued"<<std::endl; } } // main function, defines entry point program. int main( int argc, char** argv ) { if(argc <= 1) { std::cout<<"\n "<<std::endl; std::cout<<"\n ------------------------------------\n"<<std::endl; std::cout<<"./blink_detect open_eye.jpg close_eye.jpg\n"<<std::endl; std::cout<<"eg :: ./blink_detect 2.jpg 3.jpg\n"<<std::endl; std::cout<<"\n ------------------------------------\n"<<std::endl; exit(0); } // structure getting video camera or avi cvcapture* capture = 0; // images capture frame video or camera or file iplimage *frame, *frame_copy = 0; // used calculations int optlen = strlen("--cascade="); // input file name avi or image file. const char* input_name; img1 = imread( argv[1], 1 ); img2 = imread( argv[2], 1 ); // load haarclassifiercascade /// create windows cv::namedwindow( image_window, cv_window_autosize ); cv::namedwindow( result_window, cv_window_autosize ); // allocate memory storage storage = cvcreatememstorage(0); capture = cvcapturefromcam( 0); // create new named window title: result cvnamedwindow( "original_frame", 1 ); // if loaded succesfully, then: if( capture ) { // capture camera. for(;;) { // capture frame , load in iplimage if( !cvgrabframe( capture )) break; frame = cvretrieveframe( capture ); // if frame not exist, quit loop if( !frame ) break; // allocate framecopy same size of frame if( !frame_copy ) frame_copy = cvcreateimage( cvsize(frame->width,frame->height), ipl_depth_8u, frame->nchannels ); // check origin of image. if top left, copy image frame frame_copy. if( frame->origin == ipl_origin_tl ) cvcopy( frame, frame_copy, 0 ); // else flip , copy image for(int i=0;i<1;i++) { cascade = (cvhaarclassifiercascade*)cvload( cascade_name[i], 0, 0, 0 ); // check whether cascade has loaded successfully. else report , error , quit if( !cascade ) { fprintf( stderr, "error: not load classifier cascade\n" ); return -1; } // call function detect , draw face if(detect_and_draw(frame_copy,cascade)) { std::cout<<"detected"<<std::endl; } } // wait while before proceeding next frame if( cvwaitkey( 1 ) >= 0 ) break; } // release images, , capture memory cvreleasehaarclassifiercascade(&cascade); cvreleaseimage( &frame_copy ); cvreleasecapture( &capture ); cvreleasememstorage(&storage); } return 0; } // function detect , draw faces present in image bool detect_and_draw( iplimage* img,cvhaarclassifiercascade* cascade ) { int scale = 1; // create new image based on input image iplimage* temp = cvcreateimage( cvsize(img->width/scale,img->height/scale), 8, 3 ); // create 2 points represent face locations cvpoint pt1, pt2; int i; // clear memory storage used before cvclearmemstorage( storage ); // find whether cascade loaded, find faces. if yes, then: if( cascade ) { // there can more 1 face in image. create growable sequence of faces. // detect objects , store them in sequence cvseq* faces = cvhaardetectobjects( img, cascade, storage, 1.1, 8, cv_haar_do_canny_pruning, cvsize(40, 40) ); // loop number of faces found. for( = 0; < (faces ? faces->total : 0); i++ ) { // create new rectangle drawing face cvrect* r = (cvrect*)cvgetseqelem( faces, ); // find dimensions of face,and scale if necessary pt1.x = r->x*scale; pt2.x = (r->x+r->width)*scale; pt1.y = r->y*scale; pt2.y = (r->y+r->height)*scale; // draw rectangle in input image cvrectangle( img, pt1, pt2, cv_rgb(255,0,0), 3, 8, 0 ); cv::mat image(img); cv::rect rect; rect = cv::rect(pt1.x,pt1.y,(pt2.x-pt1.x),(pt2.y-pt1.y)); roiimg = image(rect); cv::imshow("roi",roiimg); ///send arduino detect_blink(roiimg); } } cvshowimage( "original_frame", img ); if(i > 0) return 1; else return 0; cvreleaseimage( &temp ); }
reference: website referred
Comments
Post a Comment