1 // Background average sample code done with averages and done with codebooks
2 // (adapted from the OpenCV book sample)
4 // NOTE: To get the keyboard to work, you *have* to have one of the video windows be active
5 // and NOT the consule window.
7 // Gary Bradski Oct 3, 2008.
9 /* *************** License:**************************
11 Right to use this code in any way you want without warrenty, support or any guarentee of it working.
13 BOOK: It would be nice if you cited it:
14 Learning OpenCV: Computer Vision with the OpenCV Library
15 by Gary Bradski and Adrian Kaehler
16 Published by O'Reilly Media, October 3, 2008
19 http://www.amazon.com/Learning-OpenCV-Computer-Vision-Library/dp/0596516134
20 Or: http://oreilly.com/catalog/9780596516130/
21 ISBN-10: 0596516134 or: ISBN-13: 978-0596516130
22 ************************************************** */
28 #include <opencv2/core/core.hpp>
29 #include <opencv2/video/background_segm.hpp>
30 #include <opencv2/imgproc/imgproc_c.h>
31 #include <opencv2/highgui/highgui.hpp>
36 //VARIABLES for CODEBOOK METHOD:
37 CvBGCodeBookModel* model = 0;
38 const int NCHANNELS = 3;
39 bool ch[NCHANNELS]={true,true,true}; // This sets what channels should be adjusted for background bounds
43 printf("\nLearn background and find foreground using simple average and average difference learning method:\n"
44 "Originally from the book: Learning OpenCV by O'Reilly press\n"
46 "./bgfg_codebook [--nframes=300] \n"
47 " [--input = movie filename or camera index]\n"
48 "***Keep the focus on the video windows, NOT the consol***\n\n"
49 "INTERACTIVE PARAMETERS:\n"
50 "\tESC,q,Q - quit the program\n"
51 "\th - print this help\n"
52 "\tp - pause toggle\n"
54 "\tr - run mode (single step off)\n"
55 "=== AVG PARAMS ===\n"
56 "\t- - bump high threshold UP by 0.25\n"
57 "\t= - bump high threshold DOWN by 0.25\n"
58 "\t[ - bump low threshold UP by 0.25\n"
59 "\t] - bump low threshold DOWN by 0.25\n"
60 "=== CODEBOOK PARAMS ===\n"
61 "\ty,u,v- only adjust channel 0(y) or 1(u) or 2(v) respectively\n"
62 "\ta - adjust all 3 channels at once\n"
63 "\tb - adjust both 2 and 3 at once\n"
64 "\ti,o - bump upper threshold up,down by 1\n"
65 "\tk,l - bump lower threshold up,down by 1\n"
66 "\tSPACE - reset the model\n"
71 //USAGE: ch9_background startFrameCollection# endFrameCollection# [movie filename, else from camera]
72 //If from AVI, then optionally add HighAvg, LowAvg, HighCB_Y LowCB_Y HighCB_U LowCB_U HighCB_V LowCB_V
74 int main(int argc, const char** argv)
78 CommandLineParser parser(argc, argv);
80 string inputName = parser.get<string>("input", "0");
81 int nframesToLearnBG = parser.get<int>("nframes", 300);
83 IplImage* rawImage = 0, *yuvImage = 0; //yuvImage is for codebook method
84 IplImage *ImaskCodeBook = 0,*ImaskCodeBookCC = 0;
85 CvCapture* capture = 0;
86 int c, n, nframes = 0;
89 model = cvCreateBGCodeBookModel();
91 //Set color thresholds to default values
93 model->modMin[1] = model->modMin[2] = 3;
94 model->modMax[0] = 10;
95 model->modMax[1] = model->modMax[2] = 10;
96 model->cbBounds[0] = model->cbBounds[1] = model->cbBounds[2] = 10;
99 bool singlestep = false;
101 if( inputName.empty() || (isdigit(inputName.c_str()[0]) && inputName.c_str()[1] == '\0') )
103 printf("Capture from camera\n");
104 capture = cvCaptureFromCAM( inputName.empty() ? 0 : inputName.c_str()[0] - '0' );
105 int c = inputName.empty() ? 0 : inputName.c_str()[0] - '0' ;
108 printf ("Capture from CAM %d", c);
109 printf (" didn't work\n");
114 printf("Capture from file %s\n",inputName.c_str());
115 capture = cvCreateFileCapture(inputName.c_str());
118 printf ("Capture from file %s", inputName.c_str());
119 printf (" didn't work\n");
126 //MAIN PROCESSING LOOP:
131 rawImage = cvQueryFrame( capture );
140 if( nframes == 1 && rawImage )
142 // CODEBOOK METHOD ALLOCATION
143 yuvImage = cvCloneImage(rawImage);
144 ImaskCodeBook = cvCreateImage( cvGetSize(rawImage), IPL_DEPTH_8U, 1 );
145 ImaskCodeBookCC = cvCreateImage( cvGetSize(rawImage), IPL_DEPTH_8U, 1 );
146 cvSet(ImaskCodeBook,cvScalar(255));
148 cvNamedWindow( "Raw", 1 );
149 cvNamedWindow( "ForegroundCodeBook",1);
150 cvNamedWindow( "CodeBook_ConnectComp",1);
153 // If we've got an rawImage and are good to go:
156 cvCvtColor( rawImage, yuvImage, CV_BGR2YCrCb );//YUV For codebook method
157 //This is where we build our background model
158 if( !pause && nframes-1 < nframesToLearnBG )
159 cvBGCodeBookUpdate( model, yuvImage );
161 if( nframes-1 == nframesToLearnBG )
162 cvBGCodeBookClearStale( model, model->t/2 );
164 //Find the foreground if any
165 if( nframes-1 >= nframesToLearnBG )
167 // Find foreground by codebook method
168 cvBGCodeBookDiff( model, yuvImage, ImaskCodeBook );
169 // This part just to visualize bounding boxes and centers if desired
170 cvCopy(ImaskCodeBook,ImaskCodeBookCC);
171 cvSegmentFGMask( ImaskCodeBookCC );
174 cvShowImage( "Raw", rawImage );
175 cvShowImage( "ForegroundCodeBook",ImaskCodeBook);
176 cvShowImage( "CodeBook_ConnectComp",ImaskCodeBookCC);
180 c = cvWaitKey(10)&0xFF;
182 // End processing on ESC, q or Q
183 if(c == 27 || c == 'q')
185 //Else check for user input
195 singlestep = !singlestep;
203 cvBGCodeBookClearStale( model, 0 );
212 ch[0] = c == 'y' || c == '0' || c == 'a' || c == '3';
213 ch[1] = c == 'u' || c == '1' || c == 'a' || c == '3' || c == 'b';
214 ch[2] = c == 'v' || c == '2' || c == 'a' || c == '3' || c == 'b';
215 printf("CodeBook YUV Channels active: %d, %d, %d\n", ch[0], ch[1], ch[2] );
217 case 'i': //modify max classification bounds (max bound goes higher)
218 case 'o': //modify max classification bounds (max bound goes lower)
219 case 'k': //modify min classification bounds (min bound goes lower)
220 case 'l': //modify min classification bounds (min bound goes higher)
222 uchar* ptr = c == 'i' || c == 'o' ? model->modMax : model->modMin;
223 for(n=0; n<NCHANNELS; n++)
227 int v = ptr[n] + (c == 'i' || c == 'l' ? 1 : -1);
228 ptr[n] = cv::saturate_cast<uchar>(v);
230 printf("%d,", ptr[n]);
232 printf(" CodeBook %s Side\n", c == 'i' || c == 'o' ? "High" : "Low" );
238 cvReleaseCapture( &capture );
239 cvDestroyWindow( "Raw" );
240 cvDestroyWindow( "ForegroundCodeBook");
241 cvDestroyWindow( "CodeBook_ConnectComp");