1 //use the camera to aid the decision to sleep.
2 //Copyright 2009 Daniel Watson
4 This file is part of oble.
6 oble is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 oble is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with oble. If not, see <http://www.gnu.org/licenses/>.
31 static string cascade_filename
= "";
32 static int verbose
= 0;
34 // argument for cvFlip(src, dest, FLIP_TYPE)
37 CvHaarClassifierCascade
* load_object_detector(const char* cascade_path
)
39 return (CvHaarClassifierCascade
*)cvLoad(cascade_path
);
42 void detect_and_draw_objects(IplImage
* image
,
43 CvHaarClassifierCascade
* cascade
,
46 IplImage
* small_image
= image
;
47 CvMemStorage
* storage
= cvCreateMemStorage(0);
51 /* if the flag is specified, down-scale the input image to get a
52 performance boost w/o loosing quality (perhaps) */
55 small_image
= cvCreateImage(cvSize(image
->width
/2,
58 cvPyrDown(image
, small_image
, CV_GAUSSIAN_5x5
);
62 /* use the fastest variant */
63 faces
= cvHaarDetectObjects(small_image
, cascade
, storage
, 1.2, 2,
64 CV_HAAR_DO_CANNY_PRUNING
);
66 update_idle(faces
->total
);
68 /* draw all the rectangles */
69 for(i
= 0; i
< faces
->total
; i
++)
71 /* extract the rectangles only */
72 CvRect face
= *(CvRect
*)cvGetSeqElem(faces
, i
);
73 CvPoint upperLeft
= cvPoint(face
.x
* scale
, face
.y
* scale
);
74 CvPoint bottomRight
= cvPoint((face
.x
+ face
.width
) * scale
,
75 (face
.y
+ face
.height
) * scale
);
76 cvRectangle(image
, upperLeft
, bottomRight
, CV_RGB(255,0,0), 3);
79 if(small_image
!= image
)
80 cvReleaseImage(&small_image
);
81 cvReleaseMemStorage(&storage
);
84 void update_idle(int faces_total
)
86 static int saw_last_time
= 0;
90 t_current
= time(NULL
);
97 if(verbose
)printf("\t\tpoking\n");
107 printf(":( no face \n");
113 void screensave(time_t t_current
)
115 static int last_elapse
= 0;
116 static int activated
= 0;
117 int elapse
= difftime(time(NULL
), t_current
);
119 if(elapse
> timeout
&& elapse
!= last_elapse
)
121 last_elapse
= elapse
;
124 printf("elapse = %d\n", elapse
);
128 printf("activated\n");
130 system("gnome-screensaver-command -a");
133 if(elapse
< timeout
&& activated
)
135 printf("deactivated\n");
137 system("gnome-screensaver-command -d");
141 int parse_opts(int argc
, char **argv
)
145 const char *options
= "vc:\x0";
146 while((c
= getopt(argc
, argv
, options
)) != -1)
150 case 'v': verbose
= 1; break;
151 case 'c': cascade_filename
= string(optarg
); break;
155 printf("option -%c requires an argument.\n", optopt
);
157 else if(isprint (optopt
))
159 printf("unknown option `-%c'.\n", optopt
);
163 printf("unknown option char `\\x%x'.\n", optopt
);
166 case '\x0': break; //ignore. not sure why this shows up. maybe zsh?
171 for(index
= optind
; index
< argc
; index
++)
172 printf("Non-option arg %s\n", argv
[index
]);
174 if(cascade_filename
== "")
176 printf("you must supply a filename with -c option. example:\n");
180 "/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml"
184 if(verbose
) printf("SILENT ALARM ACTIVATED!!!\n");
188 int get_frames(CvCapture
* capture
, CvHaarClassifierCascade
* cascade
)
190 int got_null_frame
= 0;
191 IplImage
* frame
= NULL
;
192 get_one_frame(capture
, frame
);
195 cvCreateImage(cvGetSize(frame
), frame
->depth
, frame
->nChannels
);
196 // Show the image captured from the camera in the window and repeat
197 while(!(got_null_frame
= get_one_frame(capture
, frame
)))
199 //so displayed right/left corresponds to physical right/left:
200 cvFlip(frame
, mirrored
, MIRROR
);
202 detect_and_draw_objects(mirrored
, cascade
, 1);
203 cvShowImage("mywindow", mirrored
);
204 // Do not release the frame!
205 //screensave(t_current);
207 //If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version),
208 //remove higher bits using AND operator
209 if((cvWaitKey(100) & 255) == 27) break;
211 cvReleaseImage(&mirrored
);
212 return got_null_frame
;
217 int got_null_capture
= 0;
218 CvHaarClassifierCascade
* cascade
=
219 load_object_detector(cascade_filename
.c_str());
221 CvCapture
* capture
= cvCaptureFromCAM(CV_CAP_ANY
);
223 cerr
<< "ERROR: capture is NULL " << endl
;
227 // Create a window in which the captured images will be presented
228 cvNamedWindow("mywindow", CV_WINDOW_AUTOSIZE
);
229 t_current
= time(NULL
);
230 while(get_frames(capture
, cascade
))
232 cerr
<< "resetting capture." << endl
;
233 cvReleaseCapture( &capture
);
234 capture
= cvCaptureFromCAM( CV_CAP_ANY
);
237 got_null_capture
= 1;
242 // Release the capture device housekeeping
243 if(!got_null_capture
)
245 cvReleaseCapture(&capture
);
247 cvDestroyWindow("mywindow");
248 return got_null_capture
;
251 int get_one_frame(CvCapture
* capture
, IplImage
* &frame
)
253 int got_null_frame
= 0;
254 frame
= cvQueryFrame(capture
);
257 cerr
<< "ERROR: frame is null..., trying again" << endl
;
258 frame
= cvQueryFrame(capture
);
261 cerr
<< "ERROR: frame is still null... maybe reset capture?" << endl
;
265 return got_null_frame
;
268 // A Simple Camera Capture Framework.
269 int main(int argc
, char** argv
)
271 if(parse_opts(argc
, argv
)) return 0;