The OpenCV Library     
by Gary Bradski

Listing One
//Collect background mean and std  of each pixel for background differencing
void captureBackground(IplImage *IvidIm, IplImage *IstdFP, 
                                               IplImage *Iu, IplImage *Istd)
{
    int height = IvidIm->height;
    int width = IvidIm->width;
    int i;
    //Create background mask (find mean and variance of color background):
        IplImage *Imean = iplCreateImageHeader(3, 0, 
                    IPL_DEPTH_32F, "RGB", "BGR", 
                    IPL_DATA_ORDER_PIXEL, IPL_ORIGIN_BL, IPL_ALIGN_QWORD,
                    width, height, NULL, NULL, NULL, NULL);
      iplAllocateImageFP(Imean, 1,0.0);
    int len = width*height*3;
    for(i = 0; i<45; i++) //take statistics over 45 frames (~1.5 secs)
    {
        grabIm(IvidIm);
        ippiAcc8u32f((unsigned char *)IvidIm->imageData, 
                                         (float *)Imean->imageData,len);
        ippiSquareAcc8u32f((unsigned char *)IvidIm->imageData, 
(float *)IstdFP->imageData, len);
    }
    //find mean and vars
    iplMultiplySFP(Imean, Imean, (float)1.0/i);     //meanI
    iplMultiplySFP(IstdFP,  IstdFP,  (float)1.0/i); //meanI^2
    IplImage* ImeanSqr = iplCloneImage(Imean);
    iplSquare(ImeanSqr, ImeanSqr); 
    iplSubtract(IstdFP, ImeanSqr, IstdFP);      //Ivar = meanI^2 - (meanI)^2
        iplDeallocate(ImeanSqr, IPL_IMAGE_ALL);
    //IstdFP = sqrt(Ivar)
    ippibSqrt32f((const float*)IstdFP->imageData, 
                                    (float*)IstdFP->imageData, len);
    //since we use Istd as a threshold, get rid of very low thresholds:
    float *pIstdFP = (float *)IstdFP->imageData;
    for(i=0; i<len; i++)
    {
        if(*pIstdFP < 0.3)
            *pIstdFP = 0.3;
        pIstdFP++;
    }
    iplMultiplySFP(IstdFP,  IstdFP,  backThresh);   //meanI^2
    //convert to 8u images
    convert32Fto8U(Imean,Iu);
    convert32Fto8U(IstdFP,Istd);
        iplDeallocate(Imean, IPL_IMAGE_ALL);
}


Listing Two
//Extract the foreground and fill in holes
//Ii         Video input image  BGR
//Im         Mean image of background  BGR
//Is         Standard deviation of background from mean BGR
//Io         Output image            -- Grayscale
//Iot        Temporary output image  -- Grayscale
//It1,It2    Temporary images of same size, depth and number of channels BGR
//numIterations Number of dialations to preform on foreground
void backsubCVL(IplImage *Ii, IplImage *Im, IplImage *Is, IplImage *Io, 
             IplImage *Iot, IplImage *It1, IplImage *It2, int numIterations)
{
    //Get |Ii-Im|
    iplSubtract(Ii,Im,It1);
    iplSubtract(Im,Ii,It2);
    iplAdd(It1,It2,It1);
    //Get Raw foreground = |Ii-Im| > Is ? 255 : 0;
    iplSubtract(It1,Is,It1);
    iplThreshold(It1, It1, 1);
    iplColorToGray(It1, Io);
    iplThreshold(Io,Iot,1);
    //Fill up holes in the foreground
    iplDilate(Iot,Io, numIterations);
}


Listing Three
// Get the largest region in the silhouette image
// Isil     Image with "foreground" regions in it 8uC1
// width,height Of image
// MIN_REG...   Minimum size acceptable to declare a foreground object
// cc2      Return: The bounding box and area of found region
//
//Returns  Area of largest region found, 
          else 0 = nothing found greater than MIN_REGION_SIZE
int growRegionCVL(IplImage *Isil, int width, int height, 
               int MIN_REGION_SIZE, IppiConnectedComp &cc2)
{   
    cc2.area = 0.0;
    int biggestNum=0,biggestLocX=0,biggestLocY=0;
    int haveOne=0;
    int x = 0,y = 0;
    ippiPixelPosition8u sil;
    ippSize silSize;
    silSize.width = width;
    silSize.height = height;
    unsigned char * pI = (unsigned char *)Isil->imageData;
    IPPI_INIT_PIXEL_POS(sil,pI,Isil->widthStep,silSize,0,0,IPL_ORIGIN_TL);
    int stride = Isil->widthStep;
    ippPoint xy;
    for(y=0; y<height; y++)
    {
        for(x=0; x<width; x++)
        {
                    // check if used yet
            if(*(sil.currline + sil.x) == 255)
            {
                xy.x = x;
                xy.y = y;
                ippiFloodFill8uC1R((unsigned char *)Isil->imageData, stride, 
                                            silSize, xy, 100, 0,0,&cc2);
                        // if size is too small remove that region
                        // Also, keep only the biggest region!!!
                    if(((int)(cc2.area)<MIN_REGION_SIZE)||
                    ((int)(cc2.area)<biggestNum) )
                            {
                             // remove it
                    ippiFloodFill8uC1R((unsigned char *)Isil->imageData, 
                                         stride, silSize, xy, 0, 0,0,&cc2);
                            }                              
                            else // for keeping just the largest
                            {
                     // remove previous max
                    if(haveOne)
                    {
                        xy.x = biggestLocX;
                        xy.y = biggestLocY;
                        ippiFloodFill8uC1R((unsigned char *)
                        Isil->imageData, stride, silSize, xy, 0, 0,0,&cc2);
                    }
                    else
                        haveOne=1;
                    biggestNum=(int)(cc2.area);
                    biggestLocX=x;
                    biggestLocY=y;
                }
            }//end if potential point found
            IPPI_MOVE_RIGHT_WRAP(sil, 1);
                }//end for x
        IPPI_MOVE_DOWN(sil, 1);
    }//end for y
    if(haveOne)
    {
        xy.x = biggestLocX;
        xy.y = biggestLocY;
        ippiFloodFill8uC1R((unsigned char *)Isil->imageData, 
                           stride, silSize, xy, 255, 1,1,&cc2);
        return(biggestNum);
    }
    else
        return(0);
}                     


Listing Four
//UPDATE THE MOTION HISTORY IMAGE
ippiUpdateMHIByTime32fC1R((unsigned char *)IsilIm->imageData,IsilIm->widthStep,
   (float *)ImhiIm->imageData, ImhiIm->widthStep, roi_Update, 
   timestamp, MHI_DURATION);
//CREATE MOTION GRADIENT ORIENATIONS FROM THE tMHI
ippiCalcMotionGradient32fC1R((float *)ImhiIm->imageData, ImhiIm->widthStep,
  (unsigned char *)Imask->imageData, Imask->widthStep,
  (float *)Iorient->imageData, Iorient->widthStep,
  roi_MotGrad, 3, MAX_TIME_DELTA,MIN_TIME_DELTA, ORIGIN);

//CALCULATE THE MOTION ORIENTATION
ippiCalcGlobalOrientation32fC1R((float *)Iorient->imageData, 
    Iorient->widthStep, (unsigned char *)Imask->imageData,Imask->widthStep,
   (float *)ImhiIm->imageData, ImhiIm->widthStep,
   roi_GlobOrient, timestamp, MHI_DURATION, &globalDir);



3


