Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
Demo.cpp 8.56 KiB
/*
./bgs_demo -i test45/ -a 100 -o test45/results/
based  on original demo.cpp
*/

//cpp c
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <stdio.h>      /* printf, scanf, puts, NULL */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */
#include <ctime>

//opencv
#include <opencv2/opencv.hpp>
//bgslibrary
#include "package_bgs/bgslibrary.h"
//my class
#include "package_bgs/Tapter.h"
#include "package_bgs/ttoolbox.h"

//std::string mNzero(int i)
//{
//    std::ostringstream convert;
//    convert << i ;
//    std::string numberString = convert.str();
//    std::string newNumberString = std::string(10 - numberString.length(), '0') + numberString;
//    return newNumberString;
//}
//std::string getFileName(int i)
//{
//    //cv::String inputPath=  "/homes/tb55xemi/work/bugTrainingSet/testRec/rec04379437pp/data/";
//    std::string fileName = "/data/"+  mNzero(i) + ".jpg";
//    return fileName;
//}


char* getCmdOption(char ** begin, char ** end, const std::string & option)
{
    char ** itr = std::find(begin, end, option);
    if (itr != end && ++itr != end)
    {
        return *itr;
    }
    return 0;
}

bool cmdOptionExists(char** begin, char** end, const std::string& option)
{
    return std::find(begin, end, option) != end;
}

int main(int argc, char * argv[])
{
    std::cout << "Using OpenCV " << CV_MAJOR_VERSION << "." << CV_MINOR_VERSION << "." << CV_SUBMINOR_VERSION << std::endl;
    //!** parse programm input****************/
    if(cmdOptionExists(argv, argv+argc, "-h"))
    {
        cout <<" error: please use command as\n./bgs_demo -i pathToInputDir -a amountOfJpgFiles -o outPutPath"<<endl;
        return  EXIT_FAILURE;
    }
    if(!cmdOptionExists(argv, argv+argc, "-i")||!cmdOptionExists(argv, argv+argc, "-a")||!cmdOptionExists(argv, argv+argc, "-o") )
    {
        cout <<" error: please use command as\n./bgs_demo -i pathToInputDir -a amountOfJpgFiles -o outPutPath"<<endl;
        return  EXIT_FAILURE;
    }

    char *testInputDir = getCmdOption(argv, argv + argc, "-i");
    string inputDir(".");
    if (testInputDir)
    {
        //test dir exists
        inputDir = string(testInputDir);
    }
    int amountFiles = -1;
    char *testFileAmount = getCmdOption(argv, argv + argc, "-a");
    if (testFileAmount)
    {
        string s(testFileAmount);
        stringstream foo(s);
        foo >> amountFiles;
    }

    char *testOutputDir = getCmdOption(argv, argv + argc, "-o");
    string outputDir(".");
    if (testOutputDir)
    {
        //test dir exists
        outputDir = string(testOutputDir);
    }

    cout <<"args: -i "<<inputDir<<" -a "<<amountFiles <<" -o " << outputDir;
    //!**** end parse input***********/

    //./program -i pathToInputDir -a amountOfJpgFiles -o outPutPath

    //pathToInputDir
    //----should have
    //      -data/
    //          #which include all jpg and tt files
    //      first file mus be: 0000000000.jpg
    //      -bk.jpg
    //          #is the neutral bk file for training the bgs method
    //


//    VideoCapture capture;

//    if (argc > 1)
//    {
//        std::cout << "Openning: " << argv[1] << std::endl;
//        capture.open(argv[1]);
//    }
//    else
//        capture.open(0);

//    if (!capture.isOpened())
//    {
//        std::cerr << "Cannot initialize video!" << std::endl;
//        return -1;
//    }

    /* Background Subtraction Methods */
    //IBGS *bgs;

    //bgs = new FrameDifference;
    //bgs = new StaticFrameDifference;
    //bgs = new WeightedMovingMean;
    //bgs = new WeightedMovingVariance;
    //bgs = new MixtureOfGaussianV1; // only on OpenCV 2.x
    //bgs = new MixtureOfGaussianV2;
    //bgs = new AdaptiveBackgroundLearning;
    //bgs = new AdaptiveSelectiveBackgroundLearning;
    //bgs = new GMG; // only on OpenCV 2.x
    //bgs = new KNN; // only on OpenCV 3.x
    //bgs = new DPAdaptiveMedian;
    //bgs = new DPGrimsonGMM;
    //bgs = new DPZivkovicAGMM;
    //bgs = new DPMean;
    //bgs = new DPWrenGA;
    //bgs = new DPPratiMediod;
    //bgs = new DPEigenbackground;
    //bgs = new DPTexture;
    //bgs = new T2FGMM_UM;
    //bgs = new T2FGMM_UV;
    //bgs = new T2FMRF_UM;
    //bgs = new T2FMRF_UV;
    //bgs = new FuzzySugenoIntegral;
    //bgs = new FuzzyChoquetIntegral;
    //bgs = new MultiLayer;
    //bgs = new PixelBasedAdaptiveSegmenter;
    //bgs = new LBSimpleGaussian;
    //bgs = new LBFuzzyGaussian;
    //bgs = new LBMixtureOfGaussians;
    //bgs = new LBAdaptiveSOM;
    //bgs = new LBFuzzyAdaptiveSOM;
    //bgs = new LBP_MRF;
    //bgs = new VuMeter;
    //bgs = new KDE;
    //bgs = new IndependentMultimodal;
    //bgs = new MultiCue;
    //bgs = new SigmaDelta;
    //bgs = new SuBSENSE;
    //bgs = new LOBSTER;
    //bgs = new PAWCS;
    //bgs = new TwoPoints;
    //bgs = new ViBe;
    //bgs = new Tapter;

    Tapter *bgs = new Tapter;

    bgs->setPathOut(outputDir);
    bgs->setInitialFrameCounter(0);
    bgs->setFlagWrite(0);
    bgs->setFlagWriteDBGpic(0);


    //see paper https://dl.acm.org/citation.cfm?id=2321600
    //https://ieeexplore.ieee.org/document/4527178/
    //was in benchmark on top https://www.researchgate.net/publication/259340906_A_comprehensive_review_of_background_subtraction_algorithms_evaluated_with_synthetic_and_real_videos


    //my own adapter to use the model

    int i= 0;
    cv::Mat img_input;

    int begin = 0;
    int steps = amountFiles;
    //init the random number generator
    srand (time(NULL));

    //first the static pic**********
    //std::string fileName = getFileName(begin);
    std::string staticFile = inputDir+"/bk.jpg";
    cout <<"a) load first static background pic :"<< staticFile<<endl;
    img_input = imread(staticFile.c_str(), CV_LOAD_IMAGE_COLOR);
    if(img_input.data )
    {
        cv::Mat img_mask;
        cv::Mat img_bkgmodel;
        bgs->process(img_input, img_mask, img_bkgmodel);
    }
    else
    {
        cout<<"error loading file: "<< staticFile<<", will abort"<<endl;
        return  EXIT_FAILURE;
    }
    std::string fileName;

    //! we train with first 54 on random draws
    cout <<"b) we train the background with random choosen files"<< fileName<<endl;
    vector<string> myRandomTrainList; //we save all draws in a list which will save to the results
    for(i=0;i<54;i++) //TODO make 54 as parameter
    {
        //random index
        int index  = rand() % steps + begin; //TODO: double check no double draw ??
        fileName = inputDir +  TToolBox::getFileName(index);
        myRandomTrainList.push_back(fileName);

        cout <<"load rnd file :"<< fileName<<endl;
        img_input = imread(fileName.c_str(), CV_LOAD_IMAGE_COLOR);

        if(img_input.data )
        {
            //cv::imshow("input", img_input);
            cv::Mat img_mask;
            cv::Mat img_bkgmodel;
            bgs->process(img_input, img_mask, img_bkgmodel); // by default, it shows automatically the foreground mask image
        }
        else
        {
            cout<<"error loading file: "<< fileName<<", will abort"<<endl;
            return  EXIT_FAILURE;
        }
    }

    cout <<"c) we produce train the background with random choosen files"<< fileName<<endl;
    bgs->setInitialFrameCounter(0);
    bgs->setFlagWrite(1);
    bgs->setFlagWriteDBGpic(1);

    clock_t beginAll = clock();

    for(i=begin;i<begin+steps;i++)
    {

        clock_t begin = clock();

        fileName =  inputDir + TToolBox::getFileName(i);
        cout <<"load file :"<< fileName<<endl;
        //cv::imwrite(convert.str().c_str(), img_output);
        img_input = imread(fileName.c_str(), CV_LOAD_IMAGE_COLOR);

        if(img_input.data )
        {
            //cv::imshow("input", img_input);

            cv::Mat img_mask;
            cv::Mat img_bkgmodel;
            bgs->process(img_input, img_mask, img_bkgmodel); // by default, it shows automatically the foreground mask image
        }
        else
        {
            cout<<"error loading file: "<< fileName<<", will abort"<<endl;
            return  EXIT_FAILURE;
        }

        clock_t end = clock();
        double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;

        cout <<"process took:\t"<<elapsed_secs<<"s"<<endl;
    }

    clock_t endAll = clock();
    double elapsed_secs = double(endAll - beginAll) / CLOCKS_PER_SEC;
    cout <<"process"<<amountFiles<<" took:\t"<<(int)(elapsed_secs/60)<<" min"<<endl;
    //we write the random file list
    //format output file
    std::string nameOutRandomFile =  outputDir + "randlist.yml";

    FileStorage fs(nameOutRandomFile.c_str(), FileStorage::WRITE);
    fs << "randomlist" <<  myRandomTrainList;
    fs.release();

    delete bgs;

//    capture.release();
    cvDestroyAllWindows();

    return 0;
}