Ask Your Question
0

Using BackgroundSubtractorMOG2 for images

asked 2015-07-12 09:19:47 -0500

vitruvius gravatar image

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.

Thanks in advance.

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;
bool bShadowDetection = true;

Mat src; //source image
Mat fgMaskMOG2; //fg mask generated by MOG2 method
Ptr<BackgroundSubtractor> pMOG2; //MOG2 Background subtractor

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

    src = imread("bluePaper1.png", 1);

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

    pMOG2->operator()(src, fgMaskMOG2);

    imshow("Source", src);
    imshow("FG Mask MOG 2", fgMaskMOG2);

    waitKey(0);

    return 0;
}

Source image:

bluePaper1.png

fgMask that I get from MOG2: fgMask.png

edit retag flag offensive close merge delete

Comments

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

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

@LBerger fixed image.

vitruvius gravatar imagevitruvius ( 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?

LBerger gravatar imageLBerger ( 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?

vitruvius gravatar imagevitruvius ( 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.

vitruvius gravatar imagevitruvius ( 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

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

1 answer

Sort by ยป oldest newest most voted
0

answered 2016-06-26 09:30:56 -0500

xmak gravatar image

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
    bg = cv2.imread(bgImageFile)
    backgroundSubtractor.apply(bg, learningRate=0.5)

# apply the algorithm for detection image using learning rate 0
stillFrame = cv2.imread("data/test_bg.jpg")
fgmask = backgroundSubtractor.apply(stillFrame, learningRate=0)

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

Here is an example result...

One of the background images used:

image description

Detection image:

image description

Result:

image description

edit flag offensive delete link more
Login/Signup to Answer

Question Tools

2 followers

Stats

Asked: 2015-07-12 09:19:47 -0500

Seen: 12,822 times

Last updated: Jul 12 '15