Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use ViBe algorithm, implemented in opencv, for systema without GPU?

I want to test ViBe algorithm for Background Subtraction. Currently I am using opencv libraries. I found out a sample implementation in opencv/samples/gpu/bgfg_segm.cpp and bgfg_vibe.cpp files. These files are under gpu module. Now I have a system without GPU. And when I try to run the code, it crashes on the initialization of the first frame. Can anybody tell me how to solve this issue?

Thanks in advance.

like image 451
sam18 Avatar asked Feb 18 '23 05:02

sam18


1 Answers

pseudo codes suck big time! here's the un-pseudo/ed version. results?:there is only try or try not

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;
}
like image 107
Zaw Lin Avatar answered May 12 '23 17:05

Zaw Lin