opencv 高斯背景建模

来源:互联网 发布:手机淘宝店铺怎么发货 编辑:程序博客网 时间:2024/05/28 05:15

opencv中背景建模的方法:

#define CV_BG_MODEL_FGD     0
#define CV_BG_MODEL_MOG     1
#define CV_BG_MODEL_FGD_SIMPLE   2

 

CV_BG_MODEL_FGD是opencv里的一种背景建模方法,
是基于一篇文献:Foreground Object Detection from Videos Containing Complex Background.
发表于2003年的ACM international conference on Multimedia

 

CV_BG_MODEL_MOG    使用高斯背景建模

//

创建高斯背景模型

cvCreateGaussianBGModel( IplImage* first_frame, CvGaussBGStatModelParams* parameters )
{
    //CvGaussBGModel在cvaux.h中有定义,是一个结构体
    CvGaussBGModel* bg_model = 0;
   
    CV_FUNCNAME( "cvCreateGaussianBGModel" );//在cxerror.h定义,定义cvFuncName宏变量
                                             //cvFuncName定义为和函数名称相同cvCreateGaussianBGModel
   
    __BEGIN__;//开始处理(是必须接在这个CV_FUNCNAME之后的)
   
    double var_init;
    CvGaussBGStatModelParams params;//定义初始化变量,在cvaux.h中定义的结构体CvGaussBGStatModelParams
    int i, j, k, n, m, p;
   
    //init parameters
    if( parameters == NULL )
    {
        params.win_size = CV_BGFG_MOG_WINDOW_SIZE;//CV_BGFG_MOG_WINDOW_SIZE=200,和学习率的关系1/200=0.005
        params.bg_threshold = CV_BGFG_MOG_BACKGROUND_THRESHOLD;//CV_BGFG_MOG_BACKGROUND_THRESHOLD=0.7(判断是否为背景点的阈值)
        params.std_threshold = CV_BGFG_MOG_STD_THRESHOLD;//CV_BGFG_MOG_STD_THRESHOLD=2.5(标准阈值)
        params.weight_init = CV_BGFG_MOG_WEIGHT_INIT;//CV_BGFG_MOG_WEIGHT_INIT=0.05(权值)
        params.variance_init = CV_BGFG_MOG_SIGMA_INIT*CV_BGFG_MOG_SIGMA_INIT;//CV_BGFG_MOG_SIGMA_INIT=30(方差)
        params.minArea = CV_BGFG_MOG_MINAREA;//CV_BGFG_MOG_MINAREA=15.f(检测出的前景物体的面积)
        params.n_gauss = CV_BGFG_MOG_NGAUSSIANS;//CV_BGFG_MOG_NGAUSSIANS=5(高斯模型数量)
    }
    else
    {
        params = *parameters;
    }
    //CV_IS_IMAGE在cxtypes.h中定义,在这里估计是判断是否有读入图象帧
    //CV_StsBadArg=-5,代表函数有问题,或者输入的参数有问题,-5为错误状态
    if( !CV_IS_IMAGE(first_frame) )
        CV_ERROR( CV_StsBadArg, "Invalid or NULL first_frame parameter" );//设置错误状态为指定的值(通过 cvSetErrStatus) 
   
    //CV_CALL在cxerror.h中有定义,这里用来确认一下调用是否正确
    CV_CALL( bg_model = (CvGaussBGModel*)cvAlloc( sizeof(*bg_model) ));
    memset( bg_model, 0, sizeof(*bg_model) );
    bg_model->type = CV_BG_MODEL_MOG;//这个在cvGaussBGModel中定义的CV_BG_STAT_MODEL_FIELDS()函数中都有,存在type,release,update,foreground,background等
    bg_model->release = (CvReleaseBGStatModel)icvReleaseGaussianBGModel;
    bg_model->update = (CvUpdateBGStatModel)icvUpdateGaussianBGModel;
   
    bg_model->params = params;
   
    //分配存储空间
    CV_CALL( bg_model->g_point = (CvGaussBGPoint*)cvAlloc(sizeof(CvGaussBGPoint)*
        ((first_frame->width*first_frame->height) + 256)));//这个是参与的点数,以及存放这些点需要的空间   //256应该是保证分配的内存不溢出
 

    CV_CALL( bg_model->background = cvCreateImage(cvSize(first_frame->width,
        first_frame->height), IPL_DEPTH_8U, first_frame->nChannels));//给背景分配存储空间
    CV_CALL( bg_model->foreground = cvCreateImage(cvSize(first_frame->width,
        first_frame->height), IPL_DEPTH_8U, 1));//给前景分配存储空间
   
    CV_CALL( bg_model->storage = cvCreateMemStorage());//分配存储空间
   
    //初始化

    var_init = 2 * params.std_threshold * params.std_threshold;//方差设置为2倍标准差的平方
    CV_CALL( bg_model->g_point[0].g_values =
        (CvGaussBGValues*)cvAlloc( sizeof(CvGaussBGValues)*params.n_gauss*
        (first_frame->width*first_frame->height + 128)));//这个是给g_value分配足够的存储空间 加128?
   
   //程序说明
   //g_values[0],g_values[1],g_values[2]....存放5个高斯混合模型的变量
   //g_values[].weight(权重) g_values[].mean[](均值) g_values[].variance[](方差)
   //具体安排是每一个象素点都有3个通道,
   //然后每一个象素点有5个高斯模型
   //模型0的权重为1,方差为2倍的标准差的平方,均值为当前象素点的值
   //模型1的权重为0,方差为2倍的标准差的平方,均值为0
   //模型2的权重为0,方差为2倍的标准差的平方,均值为0
   //g_point指的是参加高斯背景建模的象素点的个数
    for( i = 0, p = 0, n = 0; i < first_frame->height; i++ )//n 像素点数,p通道数
    {
        for( j = 0; j < first_frame->width; j++, n++ )
        {
            bg_model->g_point[n].g_values =
                bg_model->g_point[0].g_values + n*params.n_gauss;
            bg_model->g_point[n].g_values[0].weight = 1;    //the first value seen has weight one
            bg_model->g_point[n].g_values[0].match_sum = 1;

//三个颜色通道
            for( m = 0; m < first_frame->nChannels; m++)
            {
                bg_model->g_point[n].g_values[0].variance[m] = var_init;
                bg_model->g_point[n].g_values[0].mean[m] = (unsigned char)first_frame->imageData[p + m];
            }
            for( k = 1; k < params.n_gauss; k++)
            {
                bg_model->g_point[n].g_values[k].weight = 0;
                bg_model->g_point[n].g_values[k].match_sum = 0;
                for( m = 0; m < first_frame->nChannels; m++){
                    bg_model->g_point[n].g_values[k].variance[m] = var_init;
                    bg_model->g_point[n].g_values[k].mean[m] = 0;
                }
            }
            p += first_frame->nChannels;
        }
    }
   
    bg_model->countFrames = 0;
   
    __END__;
   
    if( cvGetErrStatus() < 0 )
    {
        CvBGStatModel* base_ptr = (CvBGStatModel*)bg_model;
       
        if( bg_model && bg_model->release )
            bg_model->release( &base_ptr );
        else
            cvFree( &bg_model );
        bg_model = 0;
    }
   
    return (CvBGStatModel*)bg_model;
}

这整个函数就是对结构体cvGaussBGModel里面的参数:CV_BG_STAT_MODEL_FIELDS(),params,g_point,countFrames赋值,实际上也是可以把其复制过来,自己修改初时的参数。

 

原创粉丝点击