+//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 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.
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ 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 <http://www.gnu.org/licenses/>.
+
+*/
+#include <cv.h>
+#include <highgui.h>
+#include <stdio.h>
+#include <iostream>
+#include <time.h>
+
+static time_t t_last = time(NULL);
+static time_t t_current = time(NULL);
+static time_t t_tmp = time(NULL);
+
+using namespace std;
+
+// argument for cvFlip(src, dest, FLIP_TYPE)
+#define MIRROR 1
+
+CvHaarClassifierCascade* load_object_detector(const char* cascade_path)
+{
+ return (CvHaarClassifierCascade*)cvLoad(cascade_path);
+}
+
+void detect_and_draw_objects(IplImage* image,
+ 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;
+ }
+
+ /* use the fastest variant */
+ faces = cvHaarDetectObjects(small_image, cascade, storage, 1.2, 2,
+ CV_HAAR_DO_CANNY_PRUNING);
+
+ if(0 < faces->total)
+ {
+ t_current = time(NULL);
+ }
+
+ /* 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(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)
+ {
+ last_elapse = elapse;
+ printf("elapse = %d\n", elapse);
+ if(!activated)
+ {
+ 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)
+{
+ CvHaarClassifierCascade* cascade = load_object_detector(argv[1]);
+
+ CvCapture* capture = cvCaptureFromCAM(CV_CAP_ANY);
+ if(!capture) {
+ cerr << "ERROR: capture is NULL " << endl;
+ getchar();
+ return -1;
+ }
+
+ // Create a window in which the captured images will be presented
+ cvNamedWindow("mywindow", CV_WINDOW_AUTOSIZE);
+
+ 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;
+ }
+
+ // Release the capture device housekeeping
+ cvReleaseCapture(&capture);
+ cvDestroyWindow("mywindow");
+ cvReleaseImage(&mirrored);
+ return 0;
+}