混合高斯模型背景显示
刚才又找到一篇文章,贴出来分享: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}即可。。
不过貌似结果还是那样。。。先就这样吧