混合高斯模型不显示背景

sample bgfg_segm.cpp don't display background in 2.1.0 version

The following function fills model->background image when model is MOG (cvCreateGaussianBGModel). I hope this helps those who encounter this problem in the meanwhile

typedef struct MyCvGaussBGValues
{
    float match_sum;
    float weight;
    float mean[3];
    float variance[3];
}
MyCvGaussBGValues;

static void updateBackground(CvGaussBGModel* bg_model)
{
        int K = bg_model->params.n_gauss;
        int nchannels = bg_model->background->nChannels;
        int height = bg_model->background->height;
        int width = bg_model->background->width;
        MyCvGaussBGValues *g_point = (MyCvGaussBGValues *) ((CvMat*)(bg_model->g_point))->data.ptr;
        MyCvGaussBGValues *mptr = g_point;

    for(int y=0; y<height; y++)
    {
        for (int x=0; x<width; x++, mptr+=K)
        {
                        int pos = bg_model->background->widthStep*y + x*nchannels;
                        float mean[3] = {0.0, 0.0, 0.0};
                        
                        for(int k=0; k<K; k++)
                        {
                                for(int m=0; m<nchannels; m++)
                                {
                                        mean[m] += mptr[k].weight * mptr[k].mean[m];
                                }
                        }

                        for(int m=0; m<nchannels; m++)
                        {
                                bg_model->background->imageData[pos+m] = (uchar) (mean[m]+0.5);
                        }
                }
        }
}

Call just after cvUpdateBGStatModel(), as this:

cvUpdateBGStatModel( tmp_frame, bg_model, update_bg_model ? -1 : 0 );
updateBackground((CvGaussBGModel*)bg_model);

Improved previous version:

typedef struct MixData1
{
        float match_sum;
        float weight;
        float mean;
        float variance;
}
MixData1;

typedef struct MixData3
{
        float match_sum;
        float weight;
        float mean[3];
        float variance[3];
}
MixData3;

void BackgroundThread::update8uC1(CvGaussBGModel* bg_model)
{
        int K = bg_model->params.n_gauss;
        float T = bg_model->params.bg_threshold;
        int height = bg_model->background->height;
        int width = bg_model->background->width;
        MixData1 *g_point = (MixData1 *) ((CvMat*)(bg_model->g_point))->data.ptr;
        MixData1 *mptr = g_point;

        for(int y=0; y<height; y++)
        {
                for (int x=0; x<width; x++, mptr+=K)
                {
                        int pos = bg_model->background->widthStep*y + x;
                        float mean = 0.0;
                        float wsum = 0.0;
                        int kForeground = K;

                        for(int k=0; k<K; k++)
                        {
                                wsum += mptr[k].weight;
                                if (wsum > T)
                                {
                                        kForeground = k+1;
                                        break;
                                }
                        }

                        for(int k=0; k<kForeground; k++)
                        {
                                mean += mptr[k].weight * mptr[k].mean;
                        }

                        bg_model->background->imageData[pos] = (uchar) (mean/wsum);
                }
        }
}

void BackgroundThread::update8uC3(CvGaussBGModel* bg_model)
{
        int K = bg_model->params.n_gauss;
        float T = bg_model->params.bg_threshold;
        int nchannels = bg_model->background->nChannels;
        int height = bg_model->background->height;
        int width = bg_model->background->width;
        MixData3 *g_point = (MixData3 *) ((CvMat*)(bg_model->g_point))->data.ptr;
        MixData3 *mptr = g_point;

        for(int y=0; y<height; y++)
        {
                for (int x=0; x<width; x++, mptr+=K)
                {
                        int pos = bg_model->background->widthStep*y + x*nchannels;
                        float mean[3] = {0.0, 0.0, 0.0};
                        float wsum = 0.0;
                        int kForeground = K;

                        for(int k=0; k<K; k++)
                        {
                                wsum += mptr[k].weight;
                                if (wsum > T)
                                {
                                        kForeground = k+1;
                                        break;
                                }
                        }

                        for(int k=0; k<kForeground; k++)
                        {
                                for(int m=0; m<nchannels; m++)
                                {
                                        mean[m] += mptr[k].weight * mptr[k].mean[m];
                                }
                        }

                        for(int m=0; m<nchannels; m++)
                        {
                                bg_model->background->imageData[pos+m] = (uchar) (mean[m]/wsum); //+0.5
                        }
                }
        }
}

Call just after cvUpdateBGStatModel(), as this:

cvUpdateBGStatModel(image, model, -1);
update8uC3((CvGaussBGModel*)model);

https://code.ros.org/trac/opencv/ticket/317

文章摘自上面链接,本人测试还没有通过,程序编译没问题,但运行时会崩溃。可能是内存或指针的问题吧,检查中.....

posted @ 2012-07-23 18:13  微雪  阅读(465)  评论(0编辑  收藏  举报