www.pudn.com > bgfg_codebook.rar > bgfg_codebook.cpp, change:2008-10-13,size:8284b


// Background average sample code done with averages and done with codebooks 
// (adapted from the OpenCV book sample) 
//  
// NOTE: To get the keyboard to work, you *have* to have one of the video windows be active 
//       and NOT the consule window. 
// 
// Gary Bradski Oct 3, 2008. 
//  
/* *************** License:************************** 
   Oct. 3, 2008 
   Right to use this code in any way you want without warrenty, support or any guarentee of it working. 
 
   BOOK: It would be nice if you cited it: 
   Learning OpenCV: Computer Vision with the OpenCV Library 
     by Gary Bradski and Adrian Kaehler 
     Published by O'Reilly Media, October 3, 2008 
  
   AVAILABLE AT:  
     http://www.amazon.com/Learning-OpenCV-Computer-Vision-Library/dp/0596516134 
     Or: http://oreilly.com/catalog/9780596516130/ 
     ISBN-10: 0596516134 or: ISBN-13: 978-0596516130     
************************************************** */ 
 
#include "cvaux.h" 
#include "cxmisc.h" 
#include "highgui.h" 
#include <stdio.h> 
#include <stdlib.h> 
#include <ctype.h> 
 
//VARIABLES for CODEBOOK METHOD: 
CvBGCodeBookModel* model = 0; 
const int NCHANNELS = 3; 
bool ch[NCHANNELS]={true,true,true}; // This sets what channels should be adjusted for background bounds 
 
void help(void) 
{ 
    printf("\nLearn background and find foreground using simple average and average difference learning method:\n" 
        "\nUSAGE:\nbgfg_codebook [--nframes=300] [movie filename, else from camera]\n" 
        "***Keep the focus on the video windows, NOT the consol***\n\n" 
        "INTERACTIVE PARAMETERS:\n" 
        "\tESC,q,Q  - quit the program\n" 
        "\th	- print this help\n" 
        "\tp	- pause toggle\n" 
        "\ts	- single step\n" 
        "\tr	- run mode (single step off)\n" 
        "=== AVG PARAMS ===\n" 
        "\t-    - bump high threshold UP by 0.25\n" 
        "\t=    - bump high threshold DOWN by 0.25\n" 
        "\t[    - bump low threshold UP by 0.25\n" 
        "\t]    - bump low threshold DOWN by 0.25\n" 
        "=== CODEBOOK PARAMS ===\n" 
        "\ty,u,v- only adjust channel 0(y) or 1(u) or 2(v) respectively\n" 
        "\ta	- adjust all 3 channels at once\n" 
        "\tb	- adjust both 2 and 3 at once\n" 
        "\ti,o	- bump upper threshold up,down by 1\n" 
        "\tk,l	- bump lower threshold up,down by 1\n" 
        "\tSPACE - reset the model\n" 
        ); 
} 
 
// 
//USAGE:  ch9_background startFrameCollection# endFrameCollection# [movie filename, else from camera] 
//If from AVI, then optionally add HighAvg, LowAvg, HighCB_Y LowCB_Y HighCB_U LowCB_U HighCB_V LowCB_V 
// 
int main(int argc, char** argv) 
{ 
    const char* filename = 0; 
    IplImage* rawImage = 0, *yuvImage = 0; //yuvImage is for codebook method 
    IplImage *ImaskCodeBook = 0,*ImaskCodeBookCC = 0; 
    CvCapture* capture = 0; 
 
    int c, n, nframes = 0; 
    int nframesToLearnBG = 300; 
 
    model = cvCreateBGCodeBookModel(); 
     
    //Set color thresholds to default values 
    model->modMin[0] = 3; 
    model->modMin[1] = model->modMin[2] = 3; 
    model->modMax[0] = 10; 
    model->modMax[1] = model->modMax[2] = 10; 
    model->cbBounds[0] = model->cbBounds[1] = model->cbBounds[2] = 10; 
 
    bool pause = false; 
    bool singlestep = false; 
 
    for( n = 1; n < argc; n++ ) 
    { 
        static const char* nframesOpt = "--nframes="; 
        if( strncmp(argv[n], nframesOpt, strlen(nframesOpt))==0 ) 
        { 
            if( sscanf(argv[n] + strlen(nframesOpt), "%d", &nframesToLearnBG) == 0 ) 
            { 
                help(); 
                return -1; 
            } 
        } 
        else 
            filename = argv[n]; 
    } 
 
    if( !filename ) 
    { 
        printf("Capture from camera\n"); 
        capture = cvCaptureFromCAM( 0 ); 
    } 
    else 
    { 
        printf("Capture from file %s\n",filename); 
        capture = cvCreateFileCapture( filename ); 
    } 
 
    if( !capture ) 
    { 
        printf( "Can not initialize video capturing\n\n" ); 
        help(); 
        return -1; 
    } 
 
    //MAIN PROCESSING LOOP: 
    for(;;) 
    { 
        if( !pause ) 
        { 
            rawImage = cvQueryFrame( capture ); 
            ++nframes; 
            if(!rawImage)  
                break; 
        } 
        if( singlestep ) 
            pause = true; 
         
        //First time: 
        if( nframes == 1 && rawImage ) 
        { 
            // CODEBOOK METHOD ALLOCATION 
            yuvImage = cvCloneImage(rawImage); 
            ImaskCodeBook = cvCreateImage( cvGetSize(rawImage), IPL_DEPTH_8U, 1 ); 
            ImaskCodeBookCC = cvCreateImage( cvGetSize(rawImage), IPL_DEPTH_8U, 1 ); 
            cvSet(ImaskCodeBook,cvScalar(255)); 
             
            cvNamedWindow( "Raw", 1 ); 
            cvNamedWindow( "ForegroundCodeBook",1); 
            cvNamedWindow( "CodeBook_ConnectComp",1); 
        } 
 
        // If we've got an rawImage and are good to go:                 
        if( rawImage ) 
        { 
            cvCvtColor( rawImage, yuvImage, CV_BGR2YCrCb );//YUV For codebook method 
            //This is where we build our background model 
            if( !pause && nframes-1 < nframesToLearnBG  ) 
                cvBGCodeBookUpdate( model, yuvImage ); 
 
            if( nframes-1 == nframesToLearnBG  ) 
                cvBGCodeBookClearStale( model, model->t/2 ); 
             
            //Find the foreground if any 
            if( nframes-1 >= nframesToLearnBG  ) 
            { 
                // Find foreground by codebook method 
                cvBGCodeBookDiff( model, yuvImage, ImaskCodeBook ); 
                // This part just to visualize bounding boxes and centers if desired 
                cvCopy(ImaskCodeBook,ImaskCodeBookCC);	 
                cvSegmentFGMask( ImaskCodeBookCC ); 
            } 
            //Display 
            cvShowImage( "Raw", rawImage ); 
            cvShowImage( "ForegroundCodeBook",ImaskCodeBook); 
            cvShowImage( "CodeBook_ConnectComp",ImaskCodeBookCC); 
        } 
 
        // User input: 
        c = cvWaitKey(10)&0xFF; 
        c = tolower(c); 
        // End processing on ESC, q or Q 
        if(c == 27 || c == 'q') 
            break; 
        //Else check for user input 
        switch( c ) 
        { 
        case 'h': 
            help(); 
            break; 
        case 'p': 
            pause = !pause; 
            break; 
        case 's': 
            singlestep = !singlestep; 
            pause = false; 
            break; 
        case 'r': 
            pause = false; 
            singlestep = false; 
            break; 
        case ' ': 
            cvBGCodeBookClearStale( model, 0 ); 
            nframes = 0; 
            break; 
            //CODEBOOK PARAMS 
        case 'y': case '0': 
        case 'u': case '1': 
        case 'v': case '2': 
        case 'a': case '3': 
        case 'b':  
            ch[0] = c == 'y' || c == '0' || c == 'a' || c == '3'; 
            ch[1] = c == 'u' || c == '1' || c == 'a' || c == '3' || c == 'b'; 
            ch[2] = c == 'v' || c == '2' || c == 'a' || c == '3' || c == 'b'; 
            printf("CodeBook YUV Channels active: %d, %d, %d\n", ch[0], ch[1], ch[2] ); 
            break; 
        case 'i': //modify max classification bounds (max bound goes higher) 
        case 'o': //modify max classification bounds (max bound goes lower) 
        case 'k': //modify min classification bounds (min bound goes lower) 
        case 'l': //modify min classification bounds (min bound goes higher) 
            { 
            uchar* ptr = c == 'i' || c == 'o' ? model->modMax : model->modMin; 
            for(n=0; n<NCHANNELS; n++) 
            { 
                if( ch[n] ) 
                { 
                    int v = ptr[n] + (c == 'i' || c == 'l' ? 1 : -1); 
                    ptr[n] = CV_CAST_8U(v); 
                } 
                printf("%d,", ptr[n]); 
            } 
            printf(" CodeBook %s Side\n", c == 'i' || c == 'o' ? "High" : "Low" ); 
            } 
            break; 
        } 
    }		 
     
    cvReleaseCapture( &capture ); 
    cvDestroyWindow( "Raw" ); 
    cvDestroyWindow( "ForegroundCodeBook"); 
    cvDestroyWindow( "CodeBook_ConnectComp"); 
    return 0; 
}