Update the trunk to the OpenCV's CVS (2008-07-14)
[opencv] / samples / python / facedetect.py
1 #!/usr/bin/python
2 """
3 This program is demonstration for face and object detection using haar-like features.
4 The program finds faces in a camera image or video stream and displays a red box around them.
5
6 Original C implementation by:  ?
7 Python implementation by: Roman Stanchak
8 """
9 import sys
10 from opencv.cv import *
11 from opencv.highgui import *
12
13
14 # Global Variables
15 cascade = None
16 storage = cvCreateMemStorage(0)
17 cascade_name = "../../data/haarcascades/haarcascade_frontalface_alt.xml"
18 input_name = "../c/lena.jpg"
19
20 # Parameters for haar detection
21 # From the API:
22 # The default parameters (scale_factor=1.1, min_neighbors=3, flags=0) are tuned 
23 # for accurate yet slow object detection. For a faster operation on real video 
24 # images the settings are: 
25 # scale_factor=1.2, min_neighbors=2, flags=CV_HAAR_DO_CANNY_PRUNING, 
26 # min_size=<minimum possible face size
27 min_size = cvSize(20,20)
28 image_scale = 1.3
29 haar_scale = 1.2
30 min_neighbors = 2
31 haar_flags = 0
32
33
34 def detect_and_draw( img ):
35     # allocate temporary images
36     gray = cvCreateImage( cvSize(img.width,img.height), 8, 1 );
37     small_img = cvCreateImage( cvSize( cvRound (img.width/image_scale),
38                                                                cvRound (img.height/image_scale)), 8, 1 );
39
40     # convert color input image to grayscale
41     cvCvtColor( img, gray, CV_BGR2GRAY );
42
43     # scale input image for faster processing
44     cvResize( gray, small_img, CV_INTER_LINEAR );
45
46     cvEqualizeHist( small_img, small_img );
47     
48     cvClearMemStorage( storage );
49
50     if( cascade ):
51         t = cvGetTickCount();
52         faces = cvHaarDetectObjects( small_img, cascade, storage,
53                                      haar_scale, min_neighbors, haar_flags, min_size );
54         t = cvGetTickCount() - t;
55         print "detection time = %gms" % (t/(cvGetTickFrequency()*1000.));
56         if faces:
57             for face_rect in faces:
58                 # the input to cvHaarDetectObjects was resized, so scale the 
59                 # bounding box of each face and convert it to two CvPoints
60                 pt1 = cvPoint( int(face_rect.x*image_scale), int(face_rect.y*image_scale))
61                 pt2 = cvPoint( int((face_rect.x+face_rect.width)*image_scale),
62                                int((face_rect.y+face_rect.height)*image_scale) )
63                 cvRectangle( img, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 );
64
65     cvShowImage( "result", img );
66
67
68 if __name__ == '__main__':
69
70     if len(sys.argv) > 1:
71
72         if sys.argv[1].startswith("--cascade="):
73             cascade_name = sys.argv[1][ len("--cascade="): ]
74             if len(sys.argv) > 2:
75                 input_name = sys.argv[2]
76
77         elif sys.argv[1] == "--help" or sys.argv[1] == "-h":
78             print "Usage: facedetect --cascade=\"<cascade_path>\" [filename|camera_index]\n" ;
79             sys.exit(-1)
80
81         else:
82             input_name = sys.argv[1]
83     
84     # the OpenCV API says this function is obsolete, but we can't
85     # cast the output of cvLoad to a HaarClassifierCascade, so use this anyways
86     # the size parameter is ignored
87     cascade = cvLoadHaarClassifierCascade( cascade_name, cvSize(1,1) );
88     
89     if not cascade:
90         print "ERROR: Could not load classifier cascade"
91         sys.exit(-1)
92     
93
94     if input_name.isdigit():
95         capture = cvCreateCameraCapture( int(input_name) )
96     else:
97         capture = cvCreateFileCapture( input_name ); 
98
99     cvNamedWindow( "result", 1 );
100
101     if( capture ):
102         frame_copy = None
103         while True: 
104             frame = cvQueryFrame( capture );
105             if( not frame ):
106                 break;
107             if( not frame_copy ):
108                 frame_copy = cvCreateImage( cvSize(frame.width,frame.height),
109                                             IPL_DEPTH_8U, frame.nChannels );
110             if( frame.origin == IPL_ORIGIN_TL ):
111                 cvCopy( frame, frame_copy );
112             else:
113                 cvFlip( frame, frame_copy, 0 );
114             
115             detect_and_draw( frame_copy );
116
117             if( cvWaitKey( 10 ) >= 0 ):
118                 break;
119
120     else:
121         image = cvLoadImage( input_name, 1 );
122
123         if( image ):
124             
125             detect_and_draw( image );
126             cvWaitKey(0);
127     
128     cvDestroyWindow("result");