Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV Python cv2.BackgroundSubtractor parameters

Summary

It seems like changing the parametes of BackgroundSubtractorMOG doesn't affect the results of the algorithm.

I'm usign Python: 2.7.6 |Anaconda 2.1.0 (64-bit)
OpenCV: '2.4.10'
OS: Windows 7 x64

The default parameters for the algorithm are:

history=200, nmixtures=5, backgroundRatio=0.7

So, creating the background subtractor with different parameters should give different results. But I always get the same result (foreground mask) with default parameters and with custom parameters.


Reproducing the problem

First, Create two background subtractor objects with different parameters:

bg1 = cv2.BackgroundSubtractorMOG()
bg2 = cv2.BackgroundSubtractorMOG(history=3, nmixtures=5, backgroundRatio=0.0001)

Create 2 "VideoCaptrue" objects:

cap = cv2.VideoCapture('video.mp4')
cap2 = cv2.VideoCapture('different_video.mp4')

Test the results:

# Get a frame from the first capturing object:
frame = cap.read()[1]

# Get the foreground mask from both background subtractors:
fg1 = bg1.apply(frame)
fg2 = bg2.apply(frame)

# Show both results and the difference between them:
cv2.imshow('Window name', np.hstack((fg1, fg2, fg1 - fg2)))
cv2.waitKey(30)

After running that block of code for some frames, the window shows results from the first background subtractor, results from the second and the difference of the two.

Because both masks are the same, the result of their difference (the third pane) is a full black frame:

2 BackgroundSubtractorMOG and difference

Then, suddenly change the source of the video (the second VideoCapture object):

# Get a frame from the second capturing object:
frame = cap2.read()[1]

# Get the foreground mask from both background subtractors:
fg1 = bg1.apply(frame)
fg2 = bg2.apply(frame)

# Show both results and the difference between them:
cv2.imshow('Window name', np.hstack((fg1, fg2, fg1 - fg2)))
cv2.waitKey(30)

And after running that block of code for some frames you get:

2 BackgroundSubtractorMOG and difference with new video

The two foreground masks look the same, and that's why the third pane is a full black frame.

But after running the last block of code for more than 3 frames the results of the second pane should become blacker again (because of the history=3 in the creation of the bg2 object). But both background subtractors keep getting the same results (as shown by the third full black pane).


Alternatives

I have also tried modifying their parameters with:

bg2.setInt('history')

But I get the same results.

And I always get the paremeters I did "set" (e.g.):

>>>bg2.getInt('history')
3

Is there anything I'm missing?

like image 541
tiangolo Avatar asked Nov 04 '14 17:11

tiangolo


1 Answers

I found that (since some version of OpenCV) when I call the method apply from the BackgroundSubtractorMOG object, it is using a default learningRate parameter set at 0.0, so the BackgroundSubtractor is not "learning" the new frames, it just sticks to the first frame used.

To avoid it, I have to call the method apply with an explicit learningRate parameter, then it works as it worked before.

So after starting the code:

bg1 = cv2.BackgroundSubtractorMOG()
cap = cv2.VideoCapture('video.mp4')
frame = cap.read()[1]

...instead of doing:

fg1 = bg1.apply(frame)

I should do:

fg1 = bg1.apply(frame, learningRate=0.001)
like image 184
tiangolo Avatar answered Nov 03 '22 09:11

tiangolo