Is it possible to use the ViBe algorithm implemented in opencv for a system without a GPU?

I want to test the ViBe algorithm to subtract the background. I am currently using opencv libraries. I found an example implementation in the opencv / samples / gpu / bgfg_segm.cpp and bgfg_vibe.cpp files. These files are under the gpu module. Now I have a system without a GPU. And when I try to run the code, it crashes when initializing the first frame. Can someone tell me how to solve this problem?

Thanks in advance.

+4
source share
3 answers

pseudo codes suck big time! here's a non-pseudo version. results ?: have only try or not try

bgfg_vibe.hpp

#ifndef bgfg_vibe_hpp #define bgfg_vibe_hpp #include "opencv2/core/core.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" struct Model { cv::Mat*** samples; cv::Mat** fgch; cv::Mat* fg; }; class bgfg_vibe { #define rndSize 256 unsigned char ri; #define rdx ri++ public: bgfg_vibe(); int N,R,noMin,phi; void init_model(cv::Mat& firstSample); void setphi(int phi); cv::Mat* fg(cv::Mat& frame); private: bool initDone; cv::RNG rnd; Model* model; void init(); void fg1ch(cv::Mat& frame,cv::Mat** samples,cv::Mat* fg); int rndp[rndSize],rndn[rndSize],rnd8[rndSize]; }; #endif 

bgfg_vibe.cpp

 #include "bgfg_vibe.hpp" bgfg_vibe::bgfg_vibe():R(20),N(20),noMin(2),phi(0) { initDone=false; rnd=cv::theRNG(); ri=0; } void bgfg_vibe::init() { for(int i=0;i<rndSize;i++) { rndp[i]=rnd(phi); rndn[i]=rnd(N); rnd8[i]=rnd(8); } } void bgfg_vibe::setphi(int phi) { this->phi=phi; for(int i=0;i<rndSize;i++) { rndp[i]=rnd(phi); } } void bgfg_vibe::init_model(cv::Mat& firstSample) { std::vector<cv::Mat> channels; split(firstSample,channels); if(!initDone) { init(); initDone=true; } model=new Model; model->fgch= new cv::Mat*[channels.size()]; model->samples=new cv::Mat**[N]; model->fg=new cv::Mat(cv::Size(firstSample.cols,firstSample.rows), CV_8UC1); for(size_t s=0;s<channels.size();s++) { model->fgch[s]=new cv::Mat(cv::Size(firstSample.cols,firstSample.rows), CV_8UC1); cv::Mat** samples= new cv::Mat*[N]; for(int i=0;i<N;i++) { samples[i]= new cv::Mat(cv::Size(firstSample.cols,firstSample.rows), CV_8UC1); } for(int i=0;i<channels[s].rows;i++) { int ioff=channels[s].step.p[0]*i; for(int j=0;j<channels[0].cols;j++) { for(int k=0;k<1;k++) { (samples[k]->data + ioff)[j]=channels[s].at<uchar>(i,j); } (model->fgch[s]->data + ioff)[j]=0; if(s==0)(model->fg->data + ioff)[j]=0; } } model->samples[s]=samples; } } void bgfg_vibe::fg1ch(cv::Mat& frame,cv::Mat** samples,cv::Mat* fg) { int step=frame.step.p[0]; for(int i=1;i<frame.rows-1;i++) { int ioff= step*i; for(int j=1;j<frame.cols-1;j++) { int count =0,index=0; while((count<noMin) && (index<N)) { int dist= (samples[index]->data + ioff)[j]-(frame.data + ioff)[j]; if(dist<=R && dist>=-R) { count++; } index++; } if(count>=noMin) { ((fg->data + ioff))[j]=0; int rand= rndp[rdx]; if(rand==0) { rand= rndn[rdx]; (samples[rand]->data + ioff)[j]=(frame.data + ioff)[j]; } rand= rndp[rdx]; int nxoff=ioff; if(rand==0) { int nx=i,ny=j; int cases= rnd8[rdx]; switch(cases) { case 0: //nx--; nxoff=ioff-step; ny--; break; case 1: //nx--; nxoff=ioff-step; ny; break; case 2: //nx--; nxoff=ioff-step; ny++; break; case 3: //nx++; nxoff=ioff+step; ny--; break; case 4: //nx++; nxoff=ioff+step; ny; break; case 5: //nx++; nxoff=ioff+step; ny++; break; case 6: //nx; ny--; break; case 7: //nx; ny++; break; } rand= rndn[rdx]; (samples[rand]->data + nxoff)[ny]=(frame.data + ioff)[j]; } }else { ((fg->data + ioff))[j]=255; } } } } cv::Mat* bgfg_vibe::fg(cv::Mat& frame) { std::vector<cv::Mat> channels; split(frame,channels); for(size_t i=0;i<channels.size();i++) { fg1ch(channels[i],model->samples[i],model->fgch[i]); if(i>0 && i<2) { bitwise_or(*model->fgch[i-1],*model->fgch[i],*model->fg); } if(i>=2) { bitwise_or(*model->fg,*model->fgch[i],*model->fg); } } if(channels.size()==1) return model->fgch[0]; return model->fg; } 

main.cpp

 #include "bgfg_vibe.hpp" using namespace cv; int main(int argc, char ** argv) { Mat frame; bgfg_vibe bgfg; VideoCapture cap("c:/toprocess/frame_%04d.jpg"); cap >> frame; bgfg.init_model(frame); for(;;) { cap>>frame; Mat fg = *bgfg.fg(frame); imshow("fg",fg); waitKey(1); } return 0; } 
+7
source

I have the same problem with you: you want to use Vibe without a GPU in OpenCV. Unfortunately, the current version of OpenCV (2.4.3) does not have a non-gpu implementation. If I am wrong, let me know. So I implemented vibe based on the pseudo code presented in the document. It is not as difficult as I thought.

And I am pleased with this algorithm. This is great overall, but I think that additional work is still needed to solve the ghost problem.

0
source

Please note that ViBE is patented and that its use is subject to licensing. Go to vibeinmotion.com for a trial version and more information. I am responsible for developing the ViBE business, and you can contact me directly for more information. Best wishes.

0
source

All Articles