X-Git-Url: http://challenge-bot.com/repos/?a=blobdiff_plain;f=oble.cpp;h=be973e23c11704828e781a483c420365b2fd91c8;hb=HEAD;hp=ffc61f043191029890c37e4ff88915be3bf1f61f;hpb=124727d2f74737f74687c15ff824758dbebe7146;p=ozzloy%40gmail.com%2Foble diff --git a/oble.cpp b/oble.cpp index ffc61f0..be973e2 100644 --- a/oble.cpp +++ b/oble.cpp @@ -1,37 +1,20 @@ //use the camera to aid the decision to sleep. //Copyright 2009 Daniel Watson /* - use a camera to prevent screensaver - Copyright (C) 2009 daniel watson, ozzloy@gmail.com + This file is part of oble. - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + oble is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + oble is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ -/* - This file is part of oble. - - oble is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - oble is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with oble. If not, see . + You should have received a copy of the GNU General Public License + along with oble. If not, see . */ #include @@ -39,137 +22,253 @@ #include #include #include +#include #include "oble.h" +#include "idle_x11.h" using namespace std; +static string cascade_filename = ""; +static int verbose = 0; + // argument for cvFlip(src, dest, FLIP_TYPE) #define MIRROR 1 CvHaarClassifierCascade* load_object_detector(const char* cascade_path) { - return (CvHaarClassifierCascade*)cvLoad(cascade_path); + return (CvHaarClassifierCascade*)cvLoad(cascade_path); } void detect_and_draw_objects(IplImage* image, - CvHaarClassifierCascade* cascade, - int do_pyramids) + CvHaarClassifierCascade* cascade, + int do_pyramids) { - IplImage* small_image = image; - CvMemStorage* storage = cvCreateMemStorage(0); - CvSeq* faces; - int i, scale = 1; - - /* if the flag is specified, down-scale the input image to get a - performance boost w/o loosing quality (perhaps) */ - if(do_pyramids) - { - small_image = cvCreateImage(cvSize(image->width/2,image->height/2), - IPL_DEPTH_8U, 3); - cvPyrDown(image, small_image, CV_GAUSSIAN_5x5); - scale = 2; - } + IplImage* small_image = image; + CvMemStorage* storage = cvCreateMemStorage(0); + CvSeq* faces; + int i, scale = 1; + + /* if the flag is specified, down-scale the input image to get a + performance boost w/o loosing quality (perhaps) */ + if(do_pyramids) + { + small_image = cvCreateImage(cvSize(image->width/2, + image->height/2), + IPL_DEPTH_8U, 3); + cvPyrDown(image, small_image, CV_GAUSSIAN_5x5); + scale = 2; + } + + /* use the fastest variant */ + faces = cvHaarDetectObjects(small_image, cascade, storage, 1.2, 2, + CV_HAAR_DO_CANNY_PRUNING); + + update_idle(faces->total); - /* use the fastest variant */ - faces = cvHaarDetectObjects(small_image, cascade, storage, 1.2, 2, - CV_HAAR_DO_CANNY_PRUNING); + /* draw all the rectangles */ + for(i = 0; i < faces->total; i++) + { + /* extract the rectangles only */ + CvRect face = *(CvRect*)cvGetSeqElem(faces, i); + CvPoint upperLeft = cvPoint(face.x * scale, face.y * scale); + CvPoint bottomRight = cvPoint((face.x + face.width) * scale, + (face.y + face.height) * scale); + cvRectangle(image, upperLeft, bottomRight, CV_RGB(255,0,0), 3); + } - if(0 < faces->total) + if(small_image != image) + cvReleaseImage(&small_image); + cvReleaseMemStorage(&storage); +} + +void update_idle(int faces_total) +{ + static int saw_last_time = 0; + + if(0 < faces_total) + { + t_current = time(NULL); + if(verbose) { - t_current = time(NULL); + printf(":) face \n"); } - - /* draw all the rectangles */ - for(i = 0; i < faces->total; i++) + if(saw_last_time) { - /* extract the rectangles only */ - CvRect face = *(CvRect*)cvGetSeqElem(faces, i); - CvPoint upperLeft = cvPoint(face.x * scale, face.y * scale); - CvPoint bottomRight = cvPoint((face.x + face.width) * scale, - (face.y + face.height) * scale); - cvRectangle(image, upperLeft, bottomRight, CV_RGB(255,0,0), 3); + if(verbose)printf("\t\tpoking\n"); + reset_idle_time(); } + saw_last_time = 1; + } + else + { + saw_last_time = 0; + if(verbose) + { + printf(":( no face \n"); + } + } - if(small_image != image) - cvReleaseImage(&small_image); - cvReleaseMemStorage(&storage); } void screensave(time_t t_current) { - static int last_elapse = 0; - static int activated = 0; - int elapse = difftime(time(NULL), t_current); - int timeout = 10; - if(elapse > timeout && elapse != last_elapse) + static int last_elapse = 0; + static int activated = 0; + int elapse = difftime(time(NULL), t_current); + int timeout = 10; + if(elapse > timeout && elapse != last_elapse) + { + last_elapse = elapse; + if(verbose) { - last_elapse = elapse; - printf("elapse = %d\n", elapse); - if(!activated) - { - printf("activated\n"); - activated = 1; - system("gnome-screensaver-command -a"); - } + printf("elapse = %d\n", elapse); } - if(elapse < timeout && activated) + if(!activated) { - printf("deactivated\n"); - activated = 0; - system("gnome-screensaver-command -d"); + printf("activated\n"); + activated = 1; + system("gnome-screensaver-command -a"); } + } + if(elapse < timeout && activated) + { + printf("deactivated\n"); + activated = 0; + system("gnome-screensaver-command -d"); + } } -// A Simple Camera Capture Framework. -int main(int argc, char** argv) +int parse_opts(int argc, char **argv) { - CvHaarClassifierCascade* cascade = load_object_detector(argv[1]); - - CvCapture* capture = cvCaptureFromCAM(CV_CAP_ANY); - if(!capture) { - cerr << "ERROR: capture is NULL " << endl; - getchar(); - return -1; + int index, c; + opterr = 0; + const char *options = "vc:\x0"; + while((c = getopt(argc, argv, options)) != -1) + { + switch(c) + { + case 'v': verbose = 1; break; + case 'c': cascade_filename = string(optarg); break; + case '?': + if(optopt == 'c') + { + printf("option -%c requires an argument.\n", optopt); + } + else if(isprint (optopt)) + { + printf("unknown option `-%c'.\n", optopt); + } + else + { + printf("unknown option char `\\x%x'.\n", optopt); + } + break; + case '\x0': break; //ignore. not sure why this shows up. maybe zsh? + default: abort(); } + } - // Create a window in which the captured images will be presented - cvNamedWindow("mywindow", CV_WINDOW_AUTOSIZE); + for(index = optind; index < argc; index++) + printf("Non-option arg %s\n", argv[index]); - IplImage* frame = cvQueryFrame(capture); - if(!frame) { - cerr << "ERROR: frame is null..." << endl; - getchar(); - return -1; - } - IplImage* mirrored = - cvCreateImage(cvGetSize(frame), frame->depth, frame->nChannels); - t_current = time(NULL); - // Show the image captured from the camera in the window and repeat - while(1) { - // Get one frame - frame = cvQueryFrame(capture); - if(!frame) { - cerr << "ERROR: frame is null..." << endl; - getchar(); - break; - } - - //flip the image so displayed right/left corresponds to physical right/left - cvFlip(frame, mirrored, MIRROR); - - detect_and_draw_objects(mirrored, cascade, 1); - cvShowImage("mywindow", mirrored); - // Do not release the frame! - screensave(t_current); - - //If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version), - //remove higher bits using AND operator - if((cvWaitKey(100) & 255) == 27) break; - } + if(cascade_filename == "") + { + printf("you must supply a filename with -c option. example:\n"); + printf( + "%s -c %s\n", + argv[0], + "/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml" + ); + return 1; + } + if(verbose) printf("SILENT ALARM ACTIVATED!!!\n"); + return 0; +} + +int get_frames(CvCapture* capture, CvHaarClassifierCascade* cascade) +{ + int got_null_frame = 0; + IplImage* frame = NULL; + get_one_frame(capture, frame); + + IplImage* mirrored = + cvCreateImage(cvGetSize(frame), frame->depth, frame->nChannels); + // Show the image captured from the camera in the window and repeat + while(!(got_null_frame = get_one_frame(capture, frame))) + { + //so displayed right/left corresponds to physical right/left: + cvFlip(frame, mirrored, MIRROR); + + detect_and_draw_objects(mirrored, cascade, 1); + cvShowImage("mywindow", mirrored); + // Do not release the frame! + //screensave(t_current); + + //If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version), + //remove higher bits using AND operator + if((cvWaitKey(100) & 255) == 27) break; + } + cvReleaseImage(&mirrored); + return got_null_frame; +} + +int do_capture() +{ + int got_null_capture = 0; + CvHaarClassifierCascade* cascade = + load_object_detector(cascade_filename.c_str()); + + CvCapture* capture = cvCaptureFromCAM(CV_CAP_ANY); + if(!capture) { + cerr << "ERROR: capture is NULL " << endl; + return 1; + } + + // Create a window in which the captured images will be presented + cvNamedWindow("mywindow", CV_WINDOW_AUTOSIZE); + t_current = time(NULL); + while(get_frames(capture, cascade)) + { + cerr << "resetting capture." << endl; + cvReleaseCapture( &capture ); + capture = cvCaptureFromCAM( CV_CAP_ANY ); + if(!capture) + { + got_null_capture = 1; + break; + } + } + + // Release the capture device housekeeping + if(!got_null_capture) + { + cvReleaseCapture(&capture); + } + cvDestroyWindow("mywindow"); + return got_null_capture; +} + +int get_one_frame(CvCapture* capture, IplImage* &frame) +{ + int got_null_frame = 0; + frame = cvQueryFrame(capture); + if(!frame) + { + cerr << "ERROR: frame is null..., trying again" << endl; + frame = cvQueryFrame(capture); + if(!frame) + { + cerr << "ERROR: frame is still null... maybe reset capture?" << endl; + got_null_frame = 1; + } + } + return got_null_frame; +} + +// A Simple Camera Capture Framework. +int main(int argc, char** argv) +{ + if(parse_opts(argc, argv)) return 0; - // Release the capture device housekeeping - cvReleaseCapture(&capture); - cvDestroyWindow("mywindow"); - cvReleaseImage(&mirrored); - return 0; + return do_capture(); }