Background Subtraction OpenCV这两个参数有什么区别
What is the difference of these two parameters in Background Subtraction OpenCV
我使用 OpenCV 进行前景检测,但我有一个问题,是否有人可以提供帮助。
问题出在这两个参数:
- 学习率 在:
bst.apply(currentFame, foregroungMask, learnRate); // -1 for auto, and the range is 0~1
- 比率
bst.setBackgroundRatio(double ratio) // default is 0.8xxx
问题是这两个参数是否相同,如果答案是NO那么第二个参数可以做什么?
当我看到 setBackgroundRatio(double ratio)
方法在 BackgroundSubtractorKNN
class 中不存在而仅在 BackgroundSubtractorMOG2
class 中存在时,问题就来了。但是它们在apply()
方法中都有学习率参数。
注:我在Java
中使用OpenCV
不,两者不一样。
学习率:
0 到 1 之间的值,表示背景模型的学习速度。负参数值使算法使用一些自动选择的学习率。 0表示背景模型根本不更新,1表示背景模型从上一帧开始完全重新初始化。
比率:
BackgroundSubtractorMOG2
和 BackgroundSubtractorKNN
是两种不同背景减法算法的两种不同实现。因此,BackgroundSubtractorKNN
算法不需要 setBackgroundRatio
。这个参数没怎么查到,看了这个算法的代码好像是一个总权重封顶参数。不允许总重量超过此阈值。从 c++ impelentation 中查看这段代码:
void BackgroundSubtractorMOG2Impl::getBackgroundImage(OutputArray backgroundImage) const
{
if (opencl_ON)
{
CV_OCL_RUN(opencl_ON, ocl_getBackgroundImage(backgroundImage))
opencl_ON = false;
return;
}
int nchannels = CV_MAT_CN(frameType);
CV_Assert(nchannels == 1 || nchannels == 3);
Mat meanBackground(frameSize, CV_MAKETYPE(CV_8U, nchannels), Scalar::all(0));
int firstGaussianIdx = 0;
const GMM* gmm = bgmodel.ptr<GMM>();
const float* mean = reinterpret_cast<const float*>(gmm + frameSize.width*frameSize.height*nmixtures);
std::vector<float> meanVal(nchannels, 0.f);
for(int row=0; row<meanBackground.rows; row++)
{
for(int col=0; col<meanBackground.cols; col++)
{
int nmodes = bgmodelUsedModes.at<uchar>(row, col);
float totalWeight = 0.f;
for(int gaussianIdx = firstGaussianIdx; gaussianIdx < firstGaussianIdx + nmodes; gaussianIdx++)
{
GMM gaussian = gmm[gaussianIdx];
size_t meanPosition = gaussianIdx*nchannels;
for(int chn = 0; chn < nchannels; chn++)
{
meanVal[chn] += gaussian.weight * mean[meanPosition + chn];
}
totalWeight += gaussian.weight;
if(totalWeight > backgroundRatio)
break;
}
float invWeight = 1.f/totalWeight;
switch(nchannels)
{
case 1:
meanBackground.at<uchar>(row, col) = (uchar)(meanVal[0] * invWeight);
meanVal[0] = 0.f;
break;
case 3:
Vec3f& meanVec = *reinterpret_cast<Vec3f*>(&meanVal[0]);
meanBackground.at<Vec3b>(row, col) = Vec3b(meanVec * invWeight);
meanVec = 0.f;
break;
}
firstGaussianIdx += nmixtures;
}
}
meanBackground.copyTo(backgroundImage);
}
在 c++ 实现中,backgroundRatio 用于限制其下的权重。默认 0.8。我认为使用这个默认值你会得到预期的结果
在 opencv background_segm.hpp 文件中发现的有趣评论似乎不太重要,标准做法是使用默认值:
/////////////////////////
// less important parameters - things you might change but be carefull
////////////////////////
float backgroundRatio;
我使用 OpenCV 进行前景检测,但我有一个问题,是否有人可以提供帮助。 问题出在这两个参数:
- 学习率 在:
bst.apply(currentFame, foregroungMask, learnRate); // -1 for auto, and the range is 0~1
- 比率
bst.setBackgroundRatio(double ratio) // default is 0.8xxx
问题是这两个参数是否相同,如果答案是NO那么第二个参数可以做什么?
当我看到 setBackgroundRatio(double ratio)
方法在 BackgroundSubtractorKNN
class 中不存在而仅在 BackgroundSubtractorMOG2
class 中存在时,问题就来了。但是它们在apply()
方法中都有学习率参数。
注:我在Java
中使用OpenCV不,两者不一样。
学习率:
0 到 1 之间的值,表示背景模型的学习速度。负参数值使算法使用一些自动选择的学习率。 0表示背景模型根本不更新,1表示背景模型从上一帧开始完全重新初始化。
比率:
BackgroundSubtractorMOG2
和 BackgroundSubtractorKNN
是两种不同背景减法算法的两种不同实现。因此,BackgroundSubtractorKNN
算法不需要 setBackgroundRatio
。这个参数没怎么查到,看了这个算法的代码好像是一个总权重封顶参数。不允许总重量超过此阈值。从 c++ impelentation 中查看这段代码:
void BackgroundSubtractorMOG2Impl::getBackgroundImage(OutputArray backgroundImage) const
{
if (opencl_ON)
{
CV_OCL_RUN(opencl_ON, ocl_getBackgroundImage(backgroundImage))
opencl_ON = false;
return;
}
int nchannels = CV_MAT_CN(frameType);
CV_Assert(nchannels == 1 || nchannels == 3);
Mat meanBackground(frameSize, CV_MAKETYPE(CV_8U, nchannels), Scalar::all(0));
int firstGaussianIdx = 0;
const GMM* gmm = bgmodel.ptr<GMM>();
const float* mean = reinterpret_cast<const float*>(gmm + frameSize.width*frameSize.height*nmixtures);
std::vector<float> meanVal(nchannels, 0.f);
for(int row=0; row<meanBackground.rows; row++)
{
for(int col=0; col<meanBackground.cols; col++)
{
int nmodes = bgmodelUsedModes.at<uchar>(row, col);
float totalWeight = 0.f;
for(int gaussianIdx = firstGaussianIdx; gaussianIdx < firstGaussianIdx + nmodes; gaussianIdx++)
{
GMM gaussian = gmm[gaussianIdx];
size_t meanPosition = gaussianIdx*nchannels;
for(int chn = 0; chn < nchannels; chn++)
{
meanVal[chn] += gaussian.weight * mean[meanPosition + chn];
}
totalWeight += gaussian.weight;
if(totalWeight > backgroundRatio)
break;
}
float invWeight = 1.f/totalWeight;
switch(nchannels)
{
case 1:
meanBackground.at<uchar>(row, col) = (uchar)(meanVal[0] * invWeight);
meanVal[0] = 0.f;
break;
case 3:
Vec3f& meanVec = *reinterpret_cast<Vec3f*>(&meanVal[0]);
meanBackground.at<Vec3b>(row, col) = Vec3b(meanVec * invWeight);
meanVec = 0.f;
break;
}
firstGaussianIdx += nmixtures;
}
}
meanBackground.copyTo(backgroundImage);
}
在 c++ 实现中,backgroundRatio 用于限制其下的权重。默认 0.8。我认为使用这个默认值你会得到预期的结果
在 opencv background_segm.hpp 文件中发现的有趣评论似乎不太重要,标准做法是使用默认值:
/////////////////////////
// less important parameters - things you might change but be carefull
////////////////////////
float backgroundRatio;