OpenCV Python cv2.BackgroundSubtractor 参数
总结
看起来,调整BackgroundSubtractorMOG的参数并没有改变算法的结果。
我使用的是Python: 2.7.6 | Anaconda 2.1.0 (64位)
OpenCV: '2.4.10'
操作系统: Windows 7 x64
这个算法的默认参数是:
history=200, nmixtures=5, backgroundRatio=0.7
所以,用不同的参数创建背景减除器应该会得到不同的结果。但是我无论使用默认参数还是自定义参数,得到的结果(前景掩码)总是一样。
重现问题
首先,创建两个背景减除器对象,使用不同的参数:
bg1 = cv2.BackgroundSubtractorMOG()
bg2 = cv2.BackgroundSubtractorMOG(history=3, nmixtures=5, backgroundRatio=0.0001)
然后,创建两个“VideoCapture”对象:
cap = cv2.VideoCapture('video.mp4')
cap2 = cv2.VideoCapture('different_video.mp4')
测试结果:
# 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)
运行这段代码一段时间后,窗口会显示第一个背景减除器的结果、第二个的结果以及它们之间的差异。
因为两个掩码是一样的,所以它们的差异(第三个窗口)就是一整张黑色的画面:
然后,突然改变视频源(第二个VideoCapture对象):
# 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)
再运行这段代码一段时间后,你会看到:
两个前景掩码看起来是一样的,这就是为什么第三个窗口是整张黑色的画面。
但是在运行最后一段代码超过3帧后,第二个窗口的结果应该会变得更黑(因为在创建bg2
对象时设置了history=3
)。但两个背景减除器的结果依然是一样的(第三个窗口依然是整张黑色的画面)。
替代方案
我也尝试过用以下方式修改它们的参数:
bg2.setInt('history')
但是结果还是一样。
而且我总是能看到我设置的参数(例如):
>>>bg2.getInt('history')
3
我是不是漏掉了什么?
1 个回答
我发现,从某个版本的OpenCV开始,当我调用BackgroundSubtractorMOG
对象的apply
方法时,它默认使用的learningRate
参数是0.0
。这就导致背景减除器没有“学习”新的画面,而是一直停留在第一次使用的画面上。
为了避免这个问题,我需要在调用apply
方法时,明确指定一个learningRate
参数,这样它就能像以前那样正常工作了。
所以在启动代码后:
bg1 = cv2.BackgroundSubtractorMOG()
cap = cv2.VideoCapture('video.mp4')
frame = cap.read()[1]
...而不是这样做:
fg1 = bg1.apply(frame)
我应该这样做:
fg1 = bg1.apply(frame, learningRate=0.001)