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.
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:
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:
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).
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?
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)