eba0b71beaa7cacff1e1aec40b7a1cea2bb4f842
[platform/upstream/opencv.git] / samples / c / bgfg_codebook.cpp
1 // Background average sample code done with averages and done with codebooks
2 // (adapted from the OpenCV book sample)
3 //
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.
6 //
7 // Gary Bradski Oct 3, 2008.
8 //
9 /* *************** License:**************************
10    Oct. 3, 2008
11    Right to use this code in any way you want without warrenty, support or any guarentee of it working.
12
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
17
18    AVAILABLE AT:
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 ************************************************** */
23 #include "opencv2/core.hpp"
24 #include "opencv2/core/utility.hpp"
25 #include "opencv2/video/background_segm.hpp"
26 #include "opencv2/imgproc/imgproc_c.h"
27 #include "opencv2/highgui/highgui_c.h"
28 #include "opencv2/legacy.hpp"
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <ctype.h>
33
34 using namespace std;
35 using namespace cv;
36
37 //VARIABLES for CODEBOOK METHOD:
38 CvBGCodeBookModel* model = 0;
39 const int NCHANNELS = 3;
40 bool ch[NCHANNELS]={true,true,true}; // This sets what channels should be adjusted for background bounds
41
42 static void help()
43 {
44     printf("\nLearn background and find foreground using simple average and average difference learning method:\n"
45             "Originally from the book: Learning OpenCV by O'Reilly press\n"
46         "\nUSAGE:\n"
47         "   bgfg_codebook [--nframes(-nf)=300] [--movie_filename(-mf)=tree.avi] [--camera(-c), use camera or not]\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"
53         "\ts    - single step\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"
67         );
68 }
69
70 //
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
73 //
74 const char *keys =
75 {
76     "{nf nframes   |300        |frames number}"
77     "{c  camera    |false      |use the camera or not}"
78     "{mf movie_file|tree.avi   |used movie video file}"
79 };
80 int main(int argc, const char** argv)
81 {
82     help();
83
84     CommandLineParser parser(argc, argv, keys);
85     int nframesToLearnBG = parser.get<int>("nf");
86     bool useCamera = parser.has("c");
87     string filename = parser.get<string>("mf");
88     IplImage* rawImage = 0, *yuvImage = 0; //yuvImage is for codebook method
89     IplImage *ImaskCodeBook = 0,*ImaskCodeBookCC = 0;
90     CvCapture* capture = 0;
91
92     int c, n, nframes = 0;
93
94     model = cvCreateBGCodeBookModel();
95
96     //Set color thresholds to default values
97     model->modMin[0] = 3;
98     model->modMin[1] = model->modMin[2] = 3;
99     model->modMax[0] = 10;
100     model->modMax[1] = model->modMax[2] = 10;
101     model->cbBounds[0] = model->cbBounds[1] = model->cbBounds[2] = 10;
102
103     bool pause = false;
104     bool singlestep = false;
105
106     if( useCamera )
107     {
108         printf("Capture from camera\n");
109         capture = cvCaptureFromCAM( 0 );
110     }
111     else
112     {
113         printf("Capture from file %s\n",filename.c_str());
114         capture = cvCreateFileCapture( filename.c_str() );
115     }
116
117     if( !capture )
118     {
119         printf( "Can not initialize video capturing\n\n" );
120         help();
121         return -1;
122     }
123
124     //MAIN PROCESSING LOOP:
125     for(;;)
126     {
127         if( !pause )
128         {
129             rawImage = cvQueryFrame( capture );
130             ++nframes;
131             if(!rawImage)
132                 break;
133         }
134         if( singlestep )
135             pause = true;
136
137         //First time:
138         if( nframes == 1 && rawImage )
139         {
140             // CODEBOOK METHOD ALLOCATION
141             yuvImage = cvCloneImage(rawImage);
142             ImaskCodeBook = cvCreateImage( cvGetSize(rawImage), IPL_DEPTH_8U, 1 );
143             ImaskCodeBookCC = cvCreateImage( cvGetSize(rawImage), IPL_DEPTH_8U, 1 );
144             cvSet(ImaskCodeBook,cvScalar(255));
145
146             cvNamedWindow( "Raw", 1 );
147             cvNamedWindow( "ForegroundCodeBook",1);
148             cvNamedWindow( "CodeBook_ConnectComp",1);
149         }
150
151         // If we've got an rawImage and are good to go:
152         if( rawImage )
153         {
154             cvCvtColor( rawImage, yuvImage, CV_BGR2YCrCb );//YUV For codebook method
155             //This is where we build our background model
156             if( !pause && nframes-1 < nframesToLearnBG  )
157                 cvBGCodeBookUpdate( model, yuvImage );
158
159             if( nframes-1 == nframesToLearnBG  )
160                 cvBGCodeBookClearStale( model, model->t/2 );
161
162             //Find the foreground if any
163             if( nframes-1 >= nframesToLearnBG  )
164             {
165                 // Find foreground by codebook method
166                 cvBGCodeBookDiff( model, yuvImage, ImaskCodeBook );
167                 // This part just to visualize bounding boxes and centers if desired
168                 cvCopy(ImaskCodeBook,ImaskCodeBookCC);
169                 cvSegmentFGMask( ImaskCodeBookCC );
170             }
171             //Display
172             cvShowImage( "Raw", rawImage );
173             cvShowImage( "ForegroundCodeBook",ImaskCodeBook);
174             cvShowImage( "CodeBook_ConnectComp",ImaskCodeBookCC);
175         }
176
177         // User input:
178         c = cvWaitKey(10)&0xFF;
179         c = tolower(c);
180         // End processing on ESC, q or Q
181         if(c == 27 || c == 'q')
182             break;
183         //Else check for user input
184         switch( c )
185         {
186         case 'h':
187             help();
188             break;
189         case 'p':
190             pause = !pause;
191             break;
192         case 's':
193             singlestep = !singlestep;
194             pause = false;
195             break;
196         case 'r':
197             pause = false;
198             singlestep = false;
199             break;
200         case ' ':
201             cvBGCodeBookClearStale( model, 0 );
202             nframes = 0;
203             break;
204             //CODEBOOK PARAMS
205         case 'y': case '0':
206         case 'u': case '1':
207         case 'v': case '2':
208         case 'a': case '3':
209         case 'b':
210             ch[0] = c == 'y' || c == '0' || c == 'a' || c == '3';
211             ch[1] = c == 'u' || c == '1' || c == 'a' || c == '3' || c == 'b';
212             ch[2] = c == 'v' || c == '2' || c == 'a' || c == '3' || c == 'b';
213             printf("CodeBook YUV Channels active: %d, %d, %d\n", ch[0], ch[1], ch[2] );
214             break;
215         case 'i': //modify max classification bounds (max bound goes higher)
216         case 'o': //modify max classification bounds (max bound goes lower)
217         case 'k': //modify min classification bounds (min bound goes lower)
218         case 'l': //modify min classification bounds (min bound goes higher)
219             {
220             uchar* ptr = c == 'i' || c == 'o' ? model->modMax : model->modMin;
221             for(n=0; n<NCHANNELS; n++)
222             {
223                 if( ch[n] )
224                 {
225                     int v = ptr[n] + (c == 'i' || c == 'l' ? 1 : -1);
226                     ptr[n] = cv::saturate_cast<uchar>(v);
227                 }
228                 printf("%d,", ptr[n]);
229             }
230             printf(" CodeBook %s Side\n", c == 'i' || c == 'o' ? "High" : "Low" );
231             }
232             break;
233         }
234     }
235
236     cvReleaseCapture( &capture );
237     cvDestroyWindow( "Raw" );
238     cvDestroyWindow( "ForegroundCodeBook");
239     cvDestroyWindow( "CodeBook_ConnectComp");
240     return 0;
241 }