d949cd594d9f31df2c287b943af0281472229e09
[ozzloy@gmail.com/oble] / oble.cpp
1 //use the camera to aid the decision to sleep.
2 //Copyright 2009 Daniel Watson
3 /*
4 use a camera to prevent screensaver
5 Copyright (C) 2009 daniel watson, ozzloy@gmail.com
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20 /*
21 This file is part of oble.
22
23 oble is free software: you can redistribute it and/or modify
24 it under the terms of the GNU General Public License as published by
25 the Free Software Foundation, either version 3 of the License, or
26 (at your option) any later version.
27
28 oble is distributed in the hope that it will be useful,
29 but WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 GNU General Public License for more details.
32
33 You should have received a copy of the GNU General Public License
34 along with oble. If not, see <http://www.gnu.org/licenses/>.
35
36 */
37 #include <cv.h>
38 #include <highgui.h>
39 #include <stdio.h>
40 #include <iostream>
41 #include <time.h>
42 #include <unistd.h>
43 #include "oble.h"
44 #include "idle_x11.h"
45
46 using namespace std;
47
48 static string cascade_filename = "";
49
50 // argument for cvFlip(src, dest, FLIP_TYPE)
51 #define MIRROR 1
52
53 #define DEBUG 0
54
55 CvHaarClassifierCascade* load_object_detector(const char* cascade_path)
56 {
57 return (CvHaarClassifierCascade*)cvLoad(cascade_path);
58 }
59
60 void detect_and_draw_objects(IplImage* image,
61 CvHaarClassifierCascade* cascade,
62 int do_pyramids)
63 {
64 IplImage* small_image = image;
65 CvMemStorage* storage = cvCreateMemStorage(0);
66 CvSeq* faces;
67 int i, scale = 1;
68 static int saw_last_time = 0;
69
70 /* if the flag is specified, down-scale the input image to get a
71 performance boost w/o loosing quality (perhaps) */
72 if(do_pyramids)
73 {
74 small_image = cvCreateImage(cvSize(image->width/2,image->height/2),
75 IPL_DEPTH_8U, 3);
76 cvPyrDown(image, small_image, CV_GAUSSIAN_5x5);
77 scale = 2;
78 }
79
80 /* use the fastest variant */
81 faces = cvHaarDetectObjects(small_image, cascade, storage, 1.2, 2,
82 CV_HAAR_DO_CANNY_PRUNING);
83
84 if(0 < faces->total)
85 {
86 t_current = time(NULL);
87 if(DEBUG)
88 {
89 printf(":) face \n");
90 }
91 if(saw_last_time)
92 {
93 if(DEBUG)printf("\t\tpoking\n");
94 reset_idle_time();
95 system("gnome-screensaver-command --poke");
96 }
97 saw_last_time = 1;
98 }
99 else
100 {
101 saw_last_time = 0;
102 if(DEBUG)
103 {
104 printf(":( no face \n");
105 }
106 }
107
108 /* draw all the rectangles */
109 for(i = 0; i < faces->total; i++)
110 {
111 /* extract the rectangles only */
112 CvRect face = *(CvRect*)cvGetSeqElem(faces, i);
113 CvPoint upperLeft = cvPoint(face.x * scale, face.y * scale);
114 CvPoint bottomRight = cvPoint((face.x + face.width) * scale,
115 (face.y + face.height) * scale);
116 cvRectangle(image, upperLeft, bottomRight, CV_RGB(255,0,0), 3);
117 }
118
119 if(small_image != image)
120 cvReleaseImage(&small_image);
121 cvReleaseMemStorage(&storage);
122 }
123
124 void screensave(time_t t_current)
125 {
126 static int last_elapse = 0;
127 static int activated = 0;
128 int elapse = difftime(time(NULL), t_current);
129 int timeout = 10;
130 if(elapse > timeout && elapse != last_elapse)
131 {
132 last_elapse = elapse;
133 if(DEBUG)
134 {
135 printf("elapse = %d\n", elapse);
136 }
137 if(!activated)
138 {
139 printf("activated\n");
140 activated = 1;
141 system("gnome-screensaver-command -a");
142 }
143 }
144 if(elapse < timeout && activated)
145 {
146 printf("deactivated\n");
147 activated = 0;
148 system("gnome-screensaver-command -d");
149 }
150 }
151
152 int parse_opts(int argc, char **argv)
153 {
154 int index, c;
155 //int opterr=0, optopt=0, optind=0;
156 //char *optarg;
157 // int getopt(int argc, char **argv, const char *options);
158 opterr = 0;
159 const char *options = "c:";
160 while((c = getopt(argc, argv, options)) != -1)
161 switch(c)
162 {
163 case 'c':
164 cascade_filename = string(optarg);
165 printf("option c, argument = %s\n", optarg);
166 case '?':
167 if(optopt == 'c')
168 printf("option -%c requires an argument.\n", optopt);
169 else if(isprint (optopt))
170 printf("unknown option `-%c'.\n", optopt);
171 else
172 printf("unknown option char `\\x%x'.\n", optopt);
173 goto known_args_processed;
174 default:
175 abort();
176 }
177 known_args_processed:
178
179 for(index = optind; index < argc; index++)
180 printf("Non-option arg %s\n", argv[index]);
181
182 return 0;
183 }
184
185 // A Simple Camera Capture Framework.
186 int main(int argc, char** argv)
187 {
188 if(parse_opts(argc, argv)) return 0;
189
190 if(cascade_filename == "") cascade_filename = string(argv[1]);
191 CvHaarClassifierCascade* cascade =
192 load_object_detector(cascade_filename.c_str());
193
194 CvCapture* capture = cvCaptureFromCAM(CV_CAP_ANY);
195 if(!capture) {
196 cerr << "ERROR: capture is NULL " << endl;
197 getchar();
198 return -1;
199 }
200
201 // Create a window in which the captured images will be presented
202 cvNamedWindow("mywindow", CV_WINDOW_AUTOSIZE);
203
204 IplImage* frame = cvQueryFrame(capture);
205 if(!frame) {
206 cerr << "ERROR: frame is null..." << endl;
207 getchar();
208 return -1;
209 }
210 IplImage* mirrored =
211 cvCreateImage(cvGetSize(frame), frame->depth, frame->nChannels);
212 t_current = time(NULL);
213 // Show the image captured from the camera in the window and repeat
214 while(1) {
215 // Get one frame
216 frame = cvQueryFrame(capture);
217 if(!frame) {
218 cerr << "ERROR: frame is null..." << endl;
219 getchar();
220 break;
221 }
222
223 //flip the image so displayed right/left corresponds to physical right/left
224 cvFlip(frame, mirrored, MIRROR);
225
226 detect_and_draw_objects(mirrored, cascade, 1);
227 cvShowImage("mywindow", mirrored);
228 // Do not release the frame!
229 //screensave(t_current);
230
231 //If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version),
232 //remove higher bits using AND operator
233 if((cvWaitKey(100) & 255) == 27) break;
234 }
235
236 // Release the capture device housekeeping
237 cvReleaseCapture(&capture);
238 cvDestroyWindow("mywindow");
239 cvReleaseImage(&mirrored);
240 return 0;
241 }