4

I have to make almost what is said in Efficient Background subtraction with OpenCV (Background subtraction with the foreground with colour except with a camera and not a video file). The problem is that in that topic there is no explanation on background subtraction phase itself.

I have looked on the official openCV book and on the internet, and the simple Frame Differencing isn't enough for what I need. I tried to understand the more elaborate Averaging Background Method but i get lost after the cvAcc of the frames to get the average :/

If anyone could help me a bit I would really appreciate it..

Thanks!

EDIT with code I have by now:

Sum

cvCvtScale( currentFrame, currentFloat, 1, 0 ); 
if(totalFrames == 0) 
 cvCopy(currentFloat, sum); 
else 
 cvAcc(currentFloat, sum);

average

cvConvertScale( sum, imgBG, (double)(1.0/totalFrames) );

adapted background (with alpha being 0.05 in a #define)

cvRunningAvg(currentFrame, imgBG, alpha); 

Creating the final image with foregrond only (far from perfect!)

void createForeground(IplImage* imgDif,IplImage * currentFrame)
{
cvCvtColor(imgDif, grayFinal, CV_RGB2GRAY);
cvSmooth(grayFinal, grayFinal);
cvThreshold(grayFinal, grayFinal, 40, 255, CV_THRESH_BINARY);

unsigned char *greyData= reinterpret_cast<unsigned char *>(grayFinal->imageData);
unsigned char *currentData= reinterpret_cast<unsigned char *>(currentFrame->imageData);
unsigned char *fgData= reinterpret_cast<unsigned char *>(currentFrame->imageData);

int i=0;
for(int j=0 ; j<(grayFinal->width*grayFinal->height) ; j++)
{
        if(greyData[j]==0) 
        {
            fgData[i]=0;
            fgData[i+1]=0;
            fgData[i+2]=0;
            i=i+3;
        }
        else 
        {
            fgData[i]= currentData[i];
            fgData[i+1]= currentData[i+1];
            fgData[i+2]= currentData[i+2];
            i=i+3;
        }
}
cvSetData( imgFG , fgData , imgFG->width*imgFG->nChannels);
}

PROBLEM NOW!

The greatest problem now is that when i have a lightbolb somewhere in the picture, after I keep my hand "on top" of it for a few seconds, when i take it away, the light keeps in the foreground for a lot of time.. any help on this?

Community
  • 1
  • 1
StinkyCat
  • 1,236
  • 1
  • 17
  • 31

2 Answers2

4

Simple Background Subtraction(Foreground extraction) methods.

1.Let say if your video having static background(i.e small variations in the back ground almost constant background ), then consider a N number of frames and average it.Then U can get the Background image i.e Img_BG.

    Img_BG = (1/N)*sum(framesFrom1 to N);

2.If your video having any illumination changes from time to time then your background image is updated as follows, it is called as running avg.

    Img_ApdatedBG =(1- alpha)*Img_BG+(alpha)*CurrentFrame;
    Img_BG =  Img_ApdatedBG;

alpha is a weight giving to current frame, typically it is around 0.05 to 0.1. This method using less memory as compare with 1 method.

3.You can calculate the Background image as calculating the median of N frames.

surya
  • 287
  • 1
  • 6
  • 14
  • thks @surya, i'll give it a try this afternoon and then I'll post back with my results. – StinkyCat May 29 '12 at 13:41
  • Ok, so i tried this way. the code for the **sum** is: **cvCvtScale( currentFrame, currentFloat, 1, 0 ); if(totalFrames == 0) cvCopy(currentFloat, sum); else cvAcc(currentFloat, sum);** | The code for the average is: **cvConvertScale( sum, imgBG, (double)(1.0/totalFrames) );** | And the code for the **adapted background** is **cvRunningAvg(currentFrame, imgBG, alpha);** (with alpha being 0.05 up to 0.1 in a #define. The **results** are: if i get in front of the camera at first i don't show up and after a little i'm a ghost. I think the background is fine now. – StinkyCat May 29 '12 at 16:51
  • What i want now is the final image to be the foreground (me walking in front of the camera) with colour and the rest in black. What do you say? I tried **cvAbsDiff(currentFloat, imgBG, finalFloat);** but it's not as good as I was expecting... thks :) it's rolling the project eheh **EDIT:**what about using a mask? i read on the web that could help me, but i don't know how to use it.. – StinkyCat May 29 '12 at 16:54
  • So i kept on with the project, albeit not using masks. I followed this website [link](http://derek.simkowiak.net/motion-tracking-with-python/) and the program is running nice, but far from perfect. The greatest problem now is that when i have a lightbolb somewhere in the picture, after I keep my hand "on top" of it for a few seconds, when i take it away, the light keeps in the foreground for a lot of time.. any help on this? – StinkyCat May 30 '12 at 00:49
3

You can try wiht this implementation of background subtraction using Mixture of Gaussians. The wiki explains the OpenCV functions used on each step.

This is a robust method of background subtraction that deals with light changes and objects coming and going out of the scene.

I hope this helps.

Jav_Rock
  • 22,059
  • 20
  • 123
  • 164