# Using BackgroundSubtractorMOG2 for images

Hi,

I am pretty new to OpenCV and I am stuck at the moment. Since I will have same background in my project, I thought it would be easier to work, if I could remove my background. But first, I have to ask one thing. Can I use BackgroundSubtractorMOG2 for images? Because it is under video analysis/motion analysis title.

I read the documentation on opencv.org and looked through countless examples/tutorials but I am still having difficulty understanding how MOG2 works.

Quick question: What is history that in parameters?

So, I have written a simple code. I get a foreground mask. So, what is next step? How can I remove the background and left with my object only? Shouldn't I load my background first, then the actual image, so that MOG2 could do the background subtraction?

I am using OpenCV 2.4.11.

Code:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/background_segm.hpp>

using namespace cv;
using namespace std;

//global variables
int history = 1;
float varThreshold = 16;

Mat src; //source image
Ptr<BackgroundSubtractor> pMOG2; //MOG2 Background subtractor

int main(int argc, char* argv[])
{
//create GUI windows
namedWindow("Source");

//create Background Subtractor objects
pMOG2 = new BackgroundSubtractorMOG2(history, varThreshold, bShadowDetection); //MOG2 approach
pMOG2->setInt("nmixtures", 3);
pMOG2->setDouble("fTau", 0.5);

imshow("Source", src);

waitKey(0);

return 0;
}


Source image:

fgMask that I get from MOG2:

edit retag close merge delete

I'm not very good in english so may be I miss something in your message. Are you using video or a fixed image?

( 2015-07-12 09:43:50 -0500 )edit

@LBerger fixed image.

( 2015-07-12 09:57:25 -0500 )edit

So I don't think you are on a good way. Background substractors are used for video. It means when something is moving in your video you will have two images one is background and another foreground with only things moving for example in this video I think you want for example measure surface, perimeter of your object using one image. Is It?

( 2015-07-12 10:13:43 -0500 )edit

@LBerger My project is about feature detection, like width/height of an object etc. I am able to do that with some filtering and then using Canny. But Canny sometimes doesn't work good when the object has shadow. So I was looking for a way to remove shadows and I found out that MOG2 could remove shadows. That's why I tried to use it mostly. And also, since the background will be same, it would be nice to eliminate the background and work with the object itself only. Any suggestions?

( 2015-07-12 10:32:43 -0500 )edit

@LBerger Or, my other problem is that I want this feature-detection thing to be done automatically. When I tried to use Canny, I saw different adjustments were needed for different objects. For example, I needed to set threshold1 value of Canny to 100 for the picture above ,blue paper, but when I tried another object ,which was a pink paper, I needed to set the value to 53. I have a question regarding to this here: http://answers.opencv.org/question/65...

So I came up with the idea of removing the background.

( 2015-07-12 10:37:09 -0500 )edit

Yes you can try remove background but becarefull of shadow here you can see a video. You can make a linear or a quadric model of your background. May be you use HSV model if your object are in color and work in Hue plan

( 2015-07-12 11:03:22 -0500 )edit

Sort by » oldest newest most voted

Hi.

Yes you can use both BackgroundSubtractorMOG and BackgroundSubtractorMOG2 with still images. The trick is to feed the algorithm with one of more background images before you start the detection (using learning rate > 0), and then apply the background extraction algorithm using learning rate 0. I have done it for a project on which I work with my team. I don't have the C++ code, but have the code in Python, I hope it will help...

#coding=utf8

import numpy as np
import cv2
import sys

# both MOG and MOG2 can be used, with different parameter values
backgroundSubtractor = cv2.BackgroundSubtractorMOG()

#backgroundSubtractor = cv2.BackgroundSubtractorMOG(history=100, nmixtures=5, backgroundRatio=0.7, noiseSigma=0)
#backgroundSubtractor = cv2.BackgroundSubtractorMOG2(history=500, varThreshold=500)
#backgroundSubtractor = cv2.BackgroundSubtractorMOG2()

# apply the algorithm for background images using learning rate > 0
for i in range(1, 16):
bgImageFile = "data/backgrounds/bg_%03d.jpg" % i
print "Opening background", bgImageFile
backgroundSubtractor.apply(bg, learningRate=0.5)

# apply the algorithm for detection image using learning rate 0

# show both images
cv2.imshow("original", cv2.resize(stillFrame, (0, 0), fx=0.5, fy=0.5))
cv2.waitKey()
cv2.destroyAllWindows()


Here is an example result...

One of the background images used:

Detection image:

Result:

more

Official site

GitHub

Wiki

Documentation