混合高斯模型背景显示

刚才又找到一篇文章,贴出来分享:http://blog.csdn.net/duliang_wu/article/details/7317740 

相信许多朋友多用过了opencv2.3版本中的混合高斯模型,大部分人可能多碰到了这样一个问头,2.3版本中的,混合高斯模型,不能读取模型建立的背景。

我上网搜了一下,发现了解决方法(这篇文章算不上原创啦大笑)。

这是中文提示的网站http://blog.pzxbc.com/?p=176,该文中所提及的解决方法来自外国网站https://code.ros.org/trac/opencv/ticket/317

接下来就是我在vs2010下编好的代码,一定能跑!

#include<stdio.h>
#include<cv.h>
#include<cxcore.h>
#include<highgui.h>
#include<cvaux.h>
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);
            }
        }
    }
}
int main(int argc,char **argv){
    IplImage *pFrame=NULL;
    IplImage *pFrImg=NULL;
    IplImage *pBkImg=NULL;
    CvCapture *pCapture=NULL;
    CvBGStatModel *bg_model=NULL;
    int nFrmNum=0;
    //int region_count=0;
    
    cvNamedWindow("video",1);
    cvNamedWindow("background",1);
    cvNamedWindow("foreground",1);
    cvMoveWindow("video",30,0);
    cvMoveWindow("background",450,0);
    cvMoveWindow("foreground",900,0);
    pCapture=cvCaptureFromFile(argv[1]);
    while(pFrame=cvQueryFrame(pCapture)){
        nFrmNum++;
        if(nFrmNum==1){
            pBkImg=cvCreateImage(cvGetSize(pFrame),IPL_DEPTH_8U,3);
            pFrImg=cvCreateImage(cvGetSize(pFrame),IPL_DEPTH_8U,1);
            bg_model=(CvBGStatModel*)cvCreateGaussianBGModel(pFrame,0);
        }
        else{
            cvUpdateBGStatModel(pFrame,(CvBGStatModel*)bg_model);
            updateBackground((CvGaussBGModel*)bg_model);
            cvClearMemStorage(bg_model->storage);
            cvCopy(bg_model->foreground,pFrImg,0);
            cvCopy(bg_model->background,pBkImg,0);
        }
        cvShowImage("video",pFrame);
        cvShowImage("background",pBkImg);
        cvShowImage("foreground",pFrImg);
        if(cvWaitKey(22)>=0)
            break;
    }
  
    cvReleaseBGStatModel((CvBGStatModel**)&bg_model);
    cvDestroyAllWindows();
    cvReleaseImage(&pFrImg);
    cvReleaseImage(&pBkImg);
    cvReleaseCapture(&pCapture);
    return 0;
}

本人在VS2008+opencv2.1环境中运行了一遍该代码,觉得背景更新的比较慢,检测效果没有http://www.cnblogs.com/yingying0907/archive/2012/07/22/2603452.html这里面提到的好,最好把两种代码结合一下,期待看到不一样的效果。

经过具体实验,发现上一篇里面的代码中,送入高斯建模的图片只有亮度通道,建模效果较好;而本篇里的代码送入高斯模型的就是RGB图片,效果差一点;

但若在本篇里将图片改为只有亮度通道的话,程序无法正常执行,

 bg_model->background->imageData[pos+m] = (uchar) (mean[m]+0.5);这一句里的Data值无法计算,本人也没找出本质原因。。。

如何修改程序???发现是数组维数不匹配的问题,将mean[3]和variance[3]变为mean[1]和variance[1],并修改初始化为mean[1]={0.0}即可。。

不过貌似结果还是那样。。。先就这样吧

原文地址:https://www.cnblogs.com/yingying0907/p/2605489.html