Friday, December 21, 2007

OpenCV: Build background with cvRunningAvg

Use running average to build background image and detect motions. This method is OK to show the demo but it's far away to be good. In the following codes, you may check the input avi file to make sure the codec is working with the opencv function

#include <stdio.h>
#include <cv.h>
#include <highgui.h>

int main( int argc, char** argv )
{
IplImage* pFrame = 0;
IplImage* pFrImg = 0;
IplImage* pFrImg2 = 0;
IplImage* pBkImg = 0;
IplImage* pBkImg2 = 0;

CvMat* pFrameMat = NULL;
CvMat* pFrMat = NULL;
CvMat* pBkMat = NULL;

CvCapture* pCapture = NULL;
int nFrmNum = 0;

cvNamedWindow("video", 1);
cvNamedWindow("background",1);
cvNamedWindow("foreground",1);
cvMoveWindow("video", 30, 0);
cvMoveWindow("background", 360, 0);
cvMoveWindow("foreground", 690, 0);

if( !(pCapture = cvCaptureFromFile("smith.avi")))
{
fprintf(stderr, "Can not open file %s\n", argv[1]);
return -2;
}

while(pFrame = cvQueryFrame( pCapture ))
{
nFrmNum++;
if(nFrmNum == 1)
{
pBkImg = cvCreateImage(cvSize(pFrame->width,
pFrame->height), IPL_DEPTH_8U,1);
pFrImg = cvCreateImage(cvSize(pFrame->width,
pFrame->height), IPL_DEPTH_8U,1);
pBkImg2 = cvClone(pBkImg);
pFrImg2 = cvClone(pFrImg);
pBkMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
pFrMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
pFrameMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);

cvCvtColor(pFrame, pBkImg, CV_BGR2GRAY);
cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);

cvConvert(pFrImg, pFrameMat);
cvConvert(pFrImg, pFrMat);
cvConvert(pFrImg, pBkMat);
}
else
{
cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
cvConvert(pFrImg, pFrameMat);
cvAbsDiff(pFrameMat, pBkMat, pFrMat);
cvThreshold(pFrMat, pFrImg, 60, 255.0, CV_THRESH_BINARY);
cvRunningAvg(pFrameMat, pBkMat, 0.003, 0);
cvConvert(pBkMat, pBkImg);
cvShowImage("video", pFrame);
cvFlip(pBkImg, pBkImg2, 0);
cvShowImage("background", pBkImg2);
cvFlip(pFrImg, pFrImg2, 0);
cvShowImage("foreground", pFrImg2);
if( cvWaitKey(1) >= 0 )
break;
}
}

cvDestroyWindow("video");
cvDestroyWindow("background");
cvDestroyWindow("foreground");
cvReleaseImage(&pFrImg);
cvReleaseImage(&pFrImg2);
cvReleaseImage(&pBkImg);
cvReleaseImage(&pBkImg2);
cvReleaseMat(&pFrameMat);
cvReleaseMat(&pFrMat);
cvReleaseMat(&pBkMat);

return 0;
}

6 comments:

  1. Very helpful for me.

    ReplyDelete
  2. thanks its really help .
    Is that mean, it gives motion of objects .

    ReplyDelete
  3. I tried this to get the foreground moving objects in same way according to above program ,

    but result is not good . Can any one please see that

    #include
    #include
    #include
    #include

    int main( int argc, char** argv )
    {
    IplImage* pFrame = 0; //originla frame
    IplImage* pFrImg = 0;
    IplImage* pFrImg2 = 0;
    IplImage* pBkImg = 0;
    IplImage* pBkImg2 = 0;

    IplImage* hsvThreshy = 0;
    IplImage* pHSVImg = 0;

    CvMat* pFrameMat = NULL;
    CvMat* pFrMat = NULL;
    CvMat* pBkMat = NULL;

    CvCapture* pCapture = NULL;
    int nFrmNum = 0;

    cvNamedWindow("video", 1);
    cvNamedWindow("background",1);
    cvNamedWindow("foreground",1);
    cvMoveWindow("video", 30, 0);
    cvMoveWindow("background", 360, 0);
    cvMoveWindow("foreground", 690, 0);

    pCapture = cvCreateCameraCapture(0);

    if(!pCapture)
    {
    return 0;
    }

    //Only for hand skin values
    double h1 =0, s1 = 30, v1 = 80;
    double h2 =20, s2 = 150, v2 = 255;

    CvScalar const minVal = cvScalar( h1,s1,v1 );
    CvScalar const maxVal = cvScalar( h2,s2,v2 );


    while(pFrame = cvQueryFrame( pCapture ))
    {
    nFrmNum++;
    if(nFrmNum == 1)
    {
    pBkImg = cvCreateImage(cvSize(pFrame->width,pFrame->height), IPL_DEPTH_8U,1);

    pFrImg = cvCreateImage(cvSize(pFrame->width,pFrame->height), IPL_DEPTH_8U,1);

    pBkImg2 = cvCloneImage(pBkImg);
    pFrImg2 = cvCloneImage(pFrImg);

    //create a background , foreground and frame Matrix
    pBkMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
    pFrMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
    pFrameMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);

    //HSV and thresold image
    pHSVImg = cvCreateImage(cvSize(pFrame->width,pFrame->height), IPL_DEPTH_8U,3);
    hsvThreshy = cvCreateImage(cvSize(pFrame->width,pFrame->height), IPL_DEPTH_8U,1);


    cvCvtColor( pFrame , pHSVImg ,CV_BGR2HSV );

    cvInRangeS( pFrame , minVal , maxVal , hsvThreshy );

    pBkImg = cvCloneImage( hsvThreshy );
    pFrImg = cvCloneImage( hsvThreshy );

    //cvCvtColor( pFrame, pHSVImg, CV_BGR2HSV);
    //cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);

    cvConvert(pFrImg, pFrameMat);//convert forground to farme Matrix
    cvConvert(pFrImg, pFrMat); //convert foreground to foreground matrix
    cvConvert(pFrImg, pBkMat); //convert forground to background matrix
    }
    else
    {
    cvCvtColor(pFrame, pHSVImg, CV_BGR2HSV);
    cvInRangeS( pFrame , minVal , maxVal , pFrImg );

    cvConvert(pFrImg, pFrameMat); //convert the hsv frame to frameMat
    cvAbsDiff(pFrameMat, pBkMat, pFrMat);




    cvRunningAvg(pFrameMat, pBkMat, 0.003, 0);
    cvConvert(pBkMat, pBkImg);
    cvShowImage("video", pFrame);
    cvFlip(pBkImg, pBkImg2, 0);
    cvShowImage("background", pBkImg2);
    cvFlip(pFrImg, pFrImg2, 0);
    cvShowImage("foreground", pFrImg2);
    if( cvWaitKey(1) >= 0 )
    break;
    }
    }

    cvDestroyWindow("video");
    cvDestroyWindow("background");
    cvDestroyWindow("foreground");
    cvReleaseImage(&pFrImg);
    cvReleaseImage(&pFrImg2);
    cvReleaseImage(&pBkImg);
    cvReleaseImage(&pBkImg2);
    cvReleaseMat(&pFrameMat);
    cvReleaseMat(&pFrMat);
    cvReleaseMat(&pBkMat);

    _getch();

    return 0;
    }

    thanks

    ReplyDelete
  4. Many thanks for post

    ReplyDelete
  5. Many thanks for post

    ReplyDelete