在智能视频分析中,混合高斯建模算法(GMM)是使用最为广泛的算法之一,近来项目对速度要求较高,原先研发的算法在实时性上无法满足需求,因此转向GMM。在Opencv中,有GMM算法的三个实现版本,分别是BackgroundSubtractorMOG、BackgroundSubtractorMOG2和BackgroundSubtractorGMG,在多种实际场景测试和比较中,发现BackgroundSubtractorMOG综合性能要优于其他两种,因此采用BackgroundSubtractorMOG为原型进行改写。
在该版本中,背景提取部分没有实现,其实也就是很简单的一个处理(不知道为什么OpenCV至今还没补充完善?),背景提取代码如下:
// 提取背景
void getBackgroundImage(OutputArray backgroundImage) const
{
int nchannels = CV_MAT_CN(frameType);
CV_Assert( nchannels == 3 );
Mat meanBackground(frameSize, CV_8UC3, Scalar::all(0));
const MixData<Vec3f>* mptr = (MixData<Vec3f>*)bgmodel.data;
for(int row=0; row<meanBackground.rows; row++)
{
for(int col=0; col<meanBackground.cols; col++, mptr += nmixtures)
{
Vec3f meanVal;
float totalWeight = 0.f;
for( int k = 0; k < nmixtures; k++ )
{
float w = mptr[k].weight;
if( w < FLT_EPSILON )
break;
totalWeight += w;
meanVal += mptr[k].mean*w;
if ( totalWeight> backgroundRatio)
break;
}
meanVal *= (1.f / totalWeight);
meanBackground.at<Vec3b>(row, col) = Vec3b(meanVal);
}
}
switch(CV_MAT_CN(frameType))
{
case 1:
{
vector<Mat> channels;
split(meanBackground, channels);
channels[0].copyTo(backgroundImage);
break;
}
case 3:
{
meanBackground.copyTo(backgroundImage);
break;
}
default:
CV_Error(CV_StsUnsupportedFormat, "");
}
}
实例很简单,就不跑了。