vibe前景提取方法学习

来源:互联网 发布:经济数据分析论文 编辑:程序博客网 时间:2024/05/23 19:21

vibe在opencv的2.3.1以上,但在2.4.6下有提供这个算法。但是必须在gpu模式下,这个比较蛋疼。首先要重新编译opencv,再就要学习c++接口的opencv,原始的c接口的是不行的。显卡的配置也要求比较高,我测试时是使用GeForce 660测试的,再低端的显卡不知道可不可以。效率跟vibe算法作者提供的程序类似。如果项目的预算不是很高,可以使用我改的程序,预算高的话可以使用opencv的gpu_vibe函数。

vibe官方提供的程序的运行截图:


命令的输入简图:

由于网上可以找到vibe的实现的源代码,所以我也下了一个。

原始的代码地址在:http://pan.baidu.com/share/link?shareid=409860&uk=3373051938   但是在网友“开心每一天的提醒下,发现代码有问题,于是我自己改了改。,原来的代码的随机数产生有问题。

更改后的代码如下:

//vibe.cpp#include "stdafx.h"#include "hanshu.h"#include <opencv2/opencv.hpp>#include "highgui.h"#include <math.h>#include <iostream>using namespace std;using namespace cv;static int c_xoff[9] = {-1,  0,  1, -1, 1, -1, 0, 1, 0};//x的邻居点static int c_yoff[9] = {-1,  0,  1, -1, 1, -1, 0, 1, 0};//y的邻居点float samples[1024][1024][defaultNbSamples+1];//保存每个像素点的样本值//初始化void Initialize(CvMat* pFrameMat,RNG rng){//记录随机生成的 行(r) 和 列(c)int rand,r,c;//对每个像素样本进行初始化for(int y=0;y<pFrameMat->rows;y++){//Heightfor(int x=0;x<pFrameMat->cols;x++){//Widthfor(int k=0;k<defaultNbSamples;k++){//随机获取像素样本值//rand=rng.uniform( 0, 9 );//r=y+c_yoff[rand]; if(r<0) r=0; if(r>=pFrameMat->rows) r=pFrameMat->rows-1;//行//c=x+c_xoff[rand]; if(c<0) c=0; if(c>=pFrameMat->cols) c=pFrameMat->cols-1;//列rand = rng.uniform(-1,1);r=y+rand;if(r<0) r=0; if(r>=pFrameMat->rows) r=pFrameMat->rows-1;//行rand = rng.uniform(-1,1);c= x+rand; if(c<0) c=0; if(c>=pFrameMat->cols) c=pFrameMat->cols-1;//列//存储像素样本值samples[y][x][k]=CV_MAT_ELEM(*pFrameMat,float,r,c);}samples[y][x][defaultNbSamples]=0;}}}//更新函数void update(CvMat* pFrameMat,CvMat* segMat,RNG rng,int nFrmNum){for(int y=0;y<pFrameMat->rows;y++){//Heightfor(int x=0;x<pFrameMat->cols;x++){//Width//用于判断一个点是否是背景点,index记录已比较的样本个数,count表示匹配的样本个数int count=0,index=0;float dist=0;//while((count<defaultReqMatches) && (index<defaultNbSamples)){dist=CV_MAT_ELEM(*pFrameMat,float,y,x)-samples[y][x][index];if(dist<0) dist=-dist;if(dist<defaultRadius) count++;index++;}if(count>=defaultReqMatches){//判断为背景像素,只有背景点才能被用来传播和更新存储样本值samples[y][x][defaultNbSamples]=0;//??????????*((float *)CV_MAT_ELEM_PTR(*segMat,y,x))=background;int rand=rng.uniform(0,defaultSubsamplingFactor-1);if(rand==0){rand=rng.uniform(0,defaultNbSamples-1);///////////////samples[y][x][rand]=CV_MAT_ELEM(*pFrameMat,float,y,x);}rand=rng.uniform(0,defaultSubsamplingFactor-1);if(rand==0){int xN,yN;//rand=rng.uniform(0,9);yN=y+c_yoff[rand];if(yN<0) yN=0; if(yN>=pFrameMat->rows) yN=pFrameMat->rows-1;//rand=rng.uniform(0,9);xN=x+c_xoff[rand];if(xN<0) xN=0; if(xN>=pFrameMat->cols) xN=pFrameMat->cols-1;rand = rng.uniform(-1,1);yN = y+rand ;if(yN<0) yN=0; if(yN>=pFrameMat->rows) yN=pFrameMat->rows-1;rand = rng.uniform(-1,1);xN = x+rand ;if(xN<0) xN=0; if(xN>=pFrameMat->cols) xN=pFrameMat->cols-1;rand=rng.uniform(0,defaultNbSamples-1);samples[yN][xN][rand]=CV_MAT_ELEM(*pFrameMat,float,y,x);} }else {//判断为前景像素*((float *)CV_MAT_ELEM_PTR(*segMat,y,x))=foreground;samples[y][x][defaultNbSamples]++;if(samples[y][x][defaultNbSamples]>50){int rand=rng.uniform(0,defaultNbSamples);if(rand==0){rand=rng.uniform(0,defaultNbSamples);samples[y][x][rand]=CV_MAT_ELEM(*pFrameMat,float,y,x);}}}}}}

vibe的头文件没有更改,和原来的一样。

vibe.h
#include "stdafx.h"#include <opencv2/opencv.hpp>#include "highgui.h"#include <iostream>using namespace std;using namespace cv;#define defaultNbSamples 20//每个像素点的样本个数#define defaultReqMatches 2//#min指数#define defaultRadius 20//Sqthere半径#define defaultSubsamplingFactor 16//子采样概率#define background 0//背景像素#define foreground 255//前景像素void Initialize(CvMat* pFrameMat,RNG rng);//初始化void update(CvMat* pFrameMat,CvMat* segMat,RNG rng,int nFrmNum);//更新

测试用的main函数如下:

//main.cpp#include "stdafx.h"#include <opencv2/opencv.hpp>#include "highgui.h"#include "hanshu.h"#include <iostream>using namespace std;using namespace cv;int nFrmNum = 0;//记录帧数int Width;//记录帧的宽度int Height;//记录帧的高度int FrameRate;//记录视频帧率int main(int argc, char* argv[]){IplImage* pFrame=NULL;CvMat* pFrameMat = NULL;//pFrame对象IplImage* pAfter=NULL;CvMat* pAfterMat=NULL;//保存pFrame对应的灰度图像IplImage* segMap=NULL;CvMat* segMat=NULL;//保存处理后的信息//要读取的视频文件和保存的视频文件路径char* openfile="video.avi";char* outfile="out.avi";char filename[100];//保存的图像位置和名称//打开视频文件CvCapture* pCapture=cvCreateFileCapture(openfile);//CvCapture* pCapture= cvCreateCameraCapture(-1);if(pCapture==NULL) {cout<<"video file open error!"<<endl;return -1;}int array_cross[] ={    0,  0xff,   0,                              0xff,0xff,  0xff,                              0   ,0xff,  0                          };      IplConvKernel * rectCross= cvCreateStructuringElementEx(3,3,1,1,CV_SHAPE_CROSS,array_cross); //获取视频相关信息,帧率和大小double fps=cvGetCaptureProperty(pCapture,CV_CAP_PROP_FPS);CvSize size=cvSize((int)cvGetCaptureProperty(pCapture,CV_CAP_PROP_FRAME_WIDTH)*3,(int)cvGetCaptureProperty(pCapture,CV_CAP_PROP_FRAME_HEIGHT));//创建输出视频文件CvVideoWriter* Save_result=NULL;Save_result=cvCreateVideoWriter(outfile,CV_FOURCC('X','V','I','D'),fps,size,1);IplImage* dstImg=cvCreateImage(size,IPL_DEPTH_8U,3);//创建要保存的图像//创建窗口cvNamedWindow("video",CV_WINDOW_AUTOSIZE);//创建一个随机数生成器RNG rng(0xFFFFFFFF);//定义字体CvFont font;cvInitFont( &font, CV_FONT_HERSHEY_COMPLEX_SMALL ,1, 1, 0, 1, 8);//逐帧读取视频并进行处理while(pFrame = cvQueryFrame( pCapture )){nFrmNum++;//如果是第一帧,申请内存并进行初始化if(nFrmNum==1){segMap = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);segMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);pAfter=cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);pAfterMat=cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);//转化成单通道图像再处理cvCvtColor(pFrame, pAfter, CV_BGR2GRAY);cvConvert(pAfter, pAfterMat);//Initialize(pAfterMat,rng);}else {cvCvtColor(pFrame,pAfter,CV_BGR2GRAY);cvConvert(pAfter,pAfterMat);update(pAfterMat,segMat,rng,nFrmNum);//更新背景cvConvert(segMat,segMap);//载入原图像到目标图像cvSetImageROI(dstImg, cvRect(0, 0, pFrame->width, pFrame->height));cvCopy(pFrame, dstImg);cvResetImageROI(dstImg);//将segMap转换成三通道图像存在pFrame中cvCvtColor(segMap,pFrame,CV_GRAY2BGR);//载入检测后的图像到目标图像cvSetImageROI(dstImg, cvRect(pFrame->width, 0, pFrame->width, pFrame->height));cvCopy(pFrame, dstImg);cvResetImageROI(dstImg);cvSetImageROI(dstImg,cvRect(pFrame->width*2,0,pFrame->width,pFrame->height));cvDilate(pFrame,dstImg);cvResetImageROI(dstImg);//显示提示文字cvPutText(dstImg, "Origin Video", cvPoint(0,pFrame->height-5), &font,CV_RGB(255,255,0));cvPutText(dstImg, "ViBe Video", cvPoint(pFrame->width,pFrame->height-5),&font,CV_RGB(255,255,0));//保存视频和输出//cvWriteFrame(Save_result,dstImg);/*输出图片if(nFrmNum<11)sprintf(filename,"E:\\Result\\Vibe\\AVSS_PV_Easy_Divx_Xvid\\000%d_Vibe.jpg",nFrmNum-1);else if(nFrmNum<101)sprintf(filename,"E:\\Result\\Vibe\\AVSS_PV_Easy_Divx_Xvid\\00%d_Vibe.jpg",nFrmNum-1);else if(nFrmNum<1001)sprintf(filename,"E:\\Result\\Vibe\\AVSS_PV_Easy_Divx_Xvid\\0%d_Vibe.jpg",nFrmNum-1);else if(nFrmNum<10001)sprintf(filename,"E:\\Result\\Vibe\\AVSS_PV_Easy_Divx_Xvid\\%d_Vibe.jpg",nFrmNum-1);cvSaveImage(filename,dstImg);*/cvShowImage("video",dstImg);cvWaitKey();//if(cvWaitKey(5)>=0) break;}}cvReleaseImage(&pFrame);cvReleaseMat(&pFrameMat);cvReleaseImage(&pAfter);cvReleaseMat(&pAfterMat);cvReleaseImage(&segMap);cvReleaseMat(&segMat);cvReleaseVideoWriter(&Save_result);cvReleaseImage(&dstImg);cvDestroyWindow("video");return 0;}

运行的结果如下:






原创粉丝点击