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