2 #pragma package <opencv>
12 IplImage *image = 0, *hsv = 0, *hue = 0, *mask = 0, *backproject = 0, *histimg = 0;
13 CvHistogram *hist = 0;
15 int backproject_mode = 0;
16 int select_object = 0;
23 CvConnectedComp track_comp;
25 float hranges_arr[] = {0,180};
26 float* hranges = hranges_arr;
27 int vmin = 10, vmax = 256, smin = 30;
29 void on_mouse( int event, int x, int y, int flags, void* param )
35 y = image->height - y;
39 selection.x = MIN(x,origin.x);
40 selection.y = MIN(y,origin.y);
41 selection.width = selection.x + CV_IABS(x - origin.x);
42 selection.height = selection.y + CV_IABS(y - origin.y);
44 selection.x = MAX( selection.x, 0 );
45 selection.y = MAX( selection.y, 0 );
46 selection.width = MIN( selection.width, image->width );
47 selection.height = MIN( selection.height, image->height );
48 selection.width -= selection.x;
49 selection.height -= selection.y;
54 case CV_EVENT_LBUTTONDOWN:
55 origin = cvPoint(x,y);
56 selection = cvRect(x,y,0,0);
59 case CV_EVENT_LBUTTONUP:
61 if( selection.width > 0 && selection.height > 0 )
68 CvScalar hsv2rgb( float hue )
70 int rgb[3], p, sector;
71 static const int sector_data[][3]=
72 {{0,2,1}, {1,2,0}, {1,0,2}, {2,0,1}, {2,1,0}, {0,1,2}};
73 hue *= 0.033333333333333333333333333333333f;
74 sector = cvFloor(hue);
75 p = cvRound(255*(hue - sector));
76 p ^= sector & 1 ? 255 : 0;
78 rgb[sector_data[sector][0]] = 255;
79 rgb[sector_data[sector][1]] = 0;
80 rgb[sector_data[sector][2]] = p;
82 return cvScalar(rgb[2], rgb[1], rgb[0],0);
85 int main( int argc, char** argv )
87 CvCapture* capture = 0;
89 if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
90 capture = cvCaptureFromCAM( argc == 2 ? argv[1][0] - '0' : 0 );
92 capture = cvCaptureFromAVI( argv[1] );
96 fprintf(stderr,"Could not initialize capturing...\n");
100 printf( "Hot keys: \n"
101 "\tESC - quit the program\n"
102 "\tc - stop the tracking\n"
103 "\tb - switch to/from backprojection view\n"
104 "\th - show/hide object histogram\n"
105 "To initialize tracking, select the object with mouse\n" );
107 cvNamedWindow( "Histogram", 1 );
108 cvNamedWindow( "CamShiftDemo", 1 );
109 cvSetMouseCallback( "CamShiftDemo", on_mouse, 0 );
110 cvCreateTrackbar( "Vmin", "CamShiftDemo", &vmin, 256, 0 );
111 cvCreateTrackbar( "Vmax", "CamShiftDemo", &vmax, 256, 0 );
112 cvCreateTrackbar( "Smin", "CamShiftDemo", &smin, 256, 0 );
119 frame = cvQueryFrame( capture );
125 /* allocate all the buffers */
126 image = cvCreateImage( cvGetSize(frame), 8, 3 );
127 image->origin = frame->origin;
128 hsv = cvCreateImage( cvGetSize(frame), 8, 3 );
129 hue = cvCreateImage( cvGetSize(frame), 8, 1 );
130 mask = cvCreateImage( cvGetSize(frame), 8, 1 );
131 backproject = cvCreateImage( cvGetSize(frame), 8, 1 );
132 hist = cvCreateHist( 1, &hdims, CV_HIST_ARRAY, &hranges, 1 );
133 histimg = cvCreateImage( cvSize(320,200), 8, 3 );
137 cvCopy( frame, image, 0 );
138 cvCvtColor( image, hsv, CV_BGR2HSV );
142 int _vmin = vmin, _vmax = vmax;
144 cvInRangeS( hsv, cvScalar(0,smin,MIN(_vmin,_vmax),0),
145 cvScalar(180,256,MAX(_vmin,_vmax),0), mask );
146 cvSplit( hsv, hue, 0, 0, 0 );
148 if( track_object < 0 )
151 cvSetImageROI( hue, selection );
152 cvSetImageROI( mask, selection );
153 cvCalcHist( &hue, hist, 0, mask );
154 cvGetMinMaxHistValue( hist, 0, &max_val, 0, 0 );
155 cvConvertScale( hist->bins, hist->bins, max_val ? 255. / max_val : 0., 0 );
156 cvResetImageROI( hue );
157 cvResetImageROI( mask );
158 track_window = selection;
162 bin_w = histimg->width / hdims;
163 for( i = 0; i < hdims; i++ )
165 int val = cvRound( cvGetReal1D(hist->bins,i)*histimg->height/255 );
166 CvScalar color = hsv2rgb(i*180.f/hdims);
167 cvRectangle( histimg, cvPoint(i*bin_w,histimg->height),
168 cvPoint((i+1)*bin_w,histimg->height - val),
173 cvCalcBackProject( &hue, backproject, hist );
174 cvAnd( backproject, mask, backproject, 0 );
175 cvCamShift( backproject, track_window,
176 cvTermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ),
177 &track_comp, &track_box );
178 track_window = track_comp.rect;
180 if( backproject_mode )
181 cvCvtColor( backproject, image, CV_GRAY2BGR );
183 track_box.angle = -track_box.angle;
184 cvEllipseBox( image, track_box, CV_RGB(255,0,0), 3, CV_AA, 0 );
187 if( select_object && selection.width > 0 && selection.height > 0 )
189 cvSetImageROI( image, selection );
190 cvXorS( image, cvScalarAll(255), image, 0 );
191 cvResetImageROI( image );
194 cvShowImage( "CamShiftDemo", image );
195 cvShowImage( "Histogram", histimg );
203 backproject_mode ^= 1;
212 cvDestroyWindow( "Histogram" );
214 cvNamedWindow( "Histogram", 1 );
221 cvReleaseCapture( &capture );
222 cvDestroyWindow("CamShiftDemo");
228 main(1,"camshiftdemo.c");