diff --git a/examples/Demo.cpp b/examples/Demo.cpp index 73cee3e3758217969578b92025e1614a2359767b..d3e2c1c8d070333bf92c80744fa02d1bc3cc5fcc 100644 --- a/examples/Demo.cpp +++ b/examples/Demo.cpp @@ -1,5 +1,26 @@ /* bgs_demo -i ../../dataset/video.tar -a 100 -o ../../output -c ../../config/centerConfigFile.xml -p ../../config/camParam.xml + + +#### Background Subtraction Methods ##### + + Codebook is new! + Tapter is TBoy! + + List of all algorithms: + AdaptiveBackgroundLearning,AdaptiveSelectiveBackgroundLearning,CodeBook,DPAdaptiveMedian,DPEigenbackground, + DPGrimsonGMM,DPMean,DPPratiMediod,DPTexture,DPWrenGA,DPZivkovicAGMM,FrameDifference,FuzzyChoquetIntegral, + FuzzySugenoIntegral,GMG,IndependentMultimodal,KDE,KNN,LBAdaptiveSOM,LBFuzzyAdaptiveSOM,LBFuzzyGaussian, + LBMixtureOfGaussians,LBP_MRF,LBSimpleGaussian,LOBSTER,MixtureOfGaussianV2,MixtureOfGaussianV1,MultiCue, + MultiLayer,PAWCS,PixelBasedAdaptiveSegmenter,SigmaDelta,StaticFrameDifference,SuBSENSE,T2FGMM_UM,T2FGMM_UV, + T2FMRF_UM,T2FMRF_UV,TwoPoints,ViBe,VuMeter,WeightedMovingMean,WeightedMovingVariance + + (Note that some of these algorithms are available only for a specific version of OpenCV, see algorithms.h) + +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 (tapter?) */ //cpp c @@ -32,102 +53,157 @@ using namespace bgslibrary::algorithms; using namespace cv; using namespace std; +String camParamFile, centerFile, outputDir, inputFile; +int amountFiles; + +const string ABOUT_STRING=R"("Camtron Software B v2.0.0 + +the software extracts the position of individuals in a single frame +work-flow: +a) load image +b) make lens correction for image with calibration data +c) uses background subtraction method “PixelBasedAdaptiveSegmenter” to get region of interest in picture Hofmann et. a. 2012 “Background Segmentation with Feedback: The Pixel-Based Adaptive Segmenter” +(framework bgslib BGSLibrary version 2.0.0 ) +(choosen because TOP 5 in paper Andrews Sobral 2014 et. al. “A comprehensive review of background subtraction algorithms evaluated with synthetic and real videos”) +d) apply gaussian filter to smooth the image (framework opencv version 3.2.) +d) use canny edge detection to extract polygon of interest +Canny 1986. A Computational Approach to Edge Detection +(framework opencv version 3.2.) +e) made a selection of all extracted polygons to reduce wrong positives +remove all polygons with area of bounding rectangles lower threshold min ( 150 pixel x pixel) + and bigger than threshold max ( 300 000 pixel x pixel ) +f) calculate convex hull of all remaining points of all polygones +g) calculate Hu invariants of convex hull +Hu 1962 “Visual Pattern Recognition by Moment Invariants “ +(framework opencv version 3.2.) +g) calculate the Centroid of convex hull with hu invariants +e) save the remaining centroids for a frame to file +)"; + +// +// GLOBALS +// + Scalar color_red( 0,0,255,255 ); const int FILE_ERROR = -3; - int g_badSignalFlagAbort = 0; void my_handler(int signum); -char* getCmdOption(char ** begin, char ** end, const string & option); - -bool cmdOptionExists(char** begin, char** end, const string& option); - vector<char> copyDataInBuffer(struct archive *aw); -//! we convert our actual jpg file number to framenumber +//! convert our actual jpg file number to framenumber int toFrameNumber(string filename); -//my custom pretty print. For now: just print all elements of a vector -// template<typename T> -void pp(Mat input) +void checkFiles(std::vector<String> files_or_dirs) { - std::cout << input << endl; + bool ret = false; + for (auto f : files_or_dirs) { + if (!std::filesystem::exists(f)) + { + std::cerr << f << " doesn't exist!" << std::endl; + ret = true; + } + } + if (ret) + exit(1); } -int main(int argc, char * argv[]) +void parse(int argc, char** argv) { - signal(SIGUSR1, my_handler); - - cout << "Using OpenCV " << CV_MAJOR_VERSION << "." << CV_MINOR_VERSION << "." << CV_SUBMINOR_VERSION << endl; - cout << "Using processcenter " << PROCESS_CENTER_VERSION_MAJOR << "." << PROCESS_CENTER_VERSION_MINOR << "." << PROCESS_CENTER_VERSION_MINOR_FIXES << endl << endl; - - //!** parse programm input****************/ - - if( cmdOptionExists(argv, argv+argc, "-h") - || cmdOptionExists(argv, argv+argc, "-?") - || !cmdOptionExists(argv, argv+argc, "-i") - || !cmdOptionExists(argv, argv+argc, "-a") - || !cmdOptionExists(argv, argv+argc, "-o") - || !cmdOptionExists(argv, argv+argc, "-p")) + const String keys = + "{help h usage ? || " + String(argv[0]) + " -i=in.tar -a=10 -c=center.xml -o=outPath -p=camparameterFile.xml }" + "{i|| input tarfile/dir containing tars? }" + "{o|.| output path / dir }" + "{a|-1| amount of files/frames }" + "{p|camparam.yml| camera parameter file }" + "{c|<none>| exact center xml-conf file }" + ; + + CommandLineParser parser(argc, argv, keys); + parser.about(ABOUT_STRING); + + if (parser.has("help")) { - cout << " Usage:" << endl; - cout << " " << argv[0] << " -i in.tar -a amount -c center.xml -o outPath -p camparameterFile.xml" << endl << endl; - cout << " Options:" << endl; - cout << " i - input tarfile/dir containing tars ?" << endl; - cout << " a - amount of files/frames ?" << endl; - cout << " c - exact center xml-conf file" << endl; - cout << " o - output path / dir" << endl; - cout << " p - camparameterFile ?" << endl; - - return EXIT_FAILURE; + parser.printMessage(); + exit(0); } - char *testFile = getCmdOption(argv, argv + argc, "-i"); - string inputFile("."); - if (testFile) - { - //test dir exists - inputFile = string(testFile); - } + inputFile = parser.get<String>("i"); + outputDir = parser.get<String>("o"); + amountFiles = parser.get<int>("a"); + camParamFile = parser.get<String>("p"); + centerFile = parser.get<String>("c"); - int amountFiles = -1; - char *testFileAmount = getCmdOption(argv, argv + argc, "-a"); - if (testFileAmount) + if (!parser.check()) { - string s(testFileAmount); - stringstream foo(s); - foo >> amountFiles; + parser.printErrors(); + exit(1); } + checkFiles({camParamFile, centerFile, outputDir, inputFile}); - char *centerFile = getCmdOption(argv, argv + argc, "-c"); - string centerFileString("."); - if (centerFile) - { - //test dir exists - centerFileString = string(centerFile); - } + // cout << "args: -i " << inputFile << " -a " << amountFiles << " -c" << centerFileString << " -o " << outputDir << " -p " << camParamFile << endl; + std::cout << "inputFile: " << inputFile << std::endl; + std::cout << "outputDir: " << outputDir << std::endl; + std::cout << "amountFiles: " << amountFiles << std::endl; + std::cout << "camParamFile: " << camParamFile << std::endl; + std::cout << "centerFile: " << centerFile << std::endl; + std::cout << "######################################" << endl; - char *testOutputDir = getCmdOption(argv, argv + argc, "-o"); - string outputDir("."); - if (testOutputDir) - { - //test dir exists - outputDir = string(testOutputDir); - } +} - char *camerFile = getCmdOption(argv, argv + argc, "-p"); - string camParamFile("."); - if (camerFile) +void init() +{ + signal(SIGUSR1, my_handler); + srand (time(NULL)); //init the random number generator +} + +void read_camParamFile(Mat& distCoeffs, Mat& cameraMatrix) +{ + std::string camParamFile = cameraParameterFile; + FileStorage fs(camParamFile, FileStorage::READ); + if (!fs.isOpened()) + { + std::cerr << "error opening '" << camParamFile << "' will abort" << endl; + return FILE_ERROR; + } + + fs["camera_matrix"] >> cameraMatrix; + fs["distortion_coefficients"] >> distCoeffs; + + cout << cameraMatrix << endl << distCoeffs << endl; +} //fs.release(); + +void read_centerFile(int circleCenterX=880, int circleCenterY=750, int circleRadius=700) +{ + //! read the center config file to cut out the ROI + // TODO merge this config with the Tapter.xml ?? + FileStorage fsCen; + fsCen.open(centerFile, FileStorage::READ); + if (!fsCen.isOpened()) { - //test dir exists - camParamFile = string(camerFile); + cout << "error during open " << centerFileString << " will abort" << endl; + return EXIT_FAILURE; } + circleCenterX = (int) fsCen["circleCenterX"]; + circleCenterY = (int) fsCen["circleCenterY"]; + circleRadius = (int) fsCen["circleRadius"];\ - cout << "args: -i " << inputFile << " -a " << amountFiles << " -c" << centerFileString << " -o " << outputDir << " -p " << camParamFile << endl; - //!**** end parse input***********/ + cout << "circleRadius: " << circleRadius << endl; + cout << "circleCenterX: " << circleCenterX << endl; + cout << "circleCenterY: " << circleCenterY << endl; + +} //fsCen.release(); + +int main(int argc, char * argv[]) +{ + parse(argc, argv); + init(); + + cout << "Using OpenCV " << CV_MAJOR_VERSION << "." << CV_MINOR_VERSION << "." << CV_SUBMINOR_VERSION << endl; + cout << "Using processcenter " << PROCESS_CENTER_VERSION_MAJOR << "." << PROCESS_CENTER_VERSION_MINOR << "." << PROCESS_CENTER_VERSION_MINOR_FIXES << endl << endl; //libarchive things @@ -144,94 +220,26 @@ int main(int argc, char * argv[]) archive_read_support_format_tar(archive); - //we get the filename + // get the filename if (filename != NULL && strcmp(filename, "-") == 0) filename = NULL; - //and open the handler + // and open the handler if ((r = archive_read_open_filename(archive, filename, 10240))) { cerr << "archive_read_open_filename: error: " << archive_error_string(archive) << " will abort" << endl; exit(1); } - - - /* #### Background Subtraction Methods ##### - - Codebook is new! - Tapter is TBoy! - - List of all algorithms: - AdaptiveBackgroundLearning,AdaptiveSelectiveBackgroundLearning,CodeBook,DPAdaptiveMedian,DPEigenbackground, - DPGrimsonGMM,DPMean,DPPratiMediod,DPTexture,DPWrenGA,DPZivkovicAGMM,FrameDifference,FuzzyChoquetIntegral, - FuzzySugenoIntegral,GMG,IndependentMultimodal,KDE,KNN,LBAdaptiveSOM,LBFuzzyAdaptiveSOM,LBFuzzyGaussian, - LBMixtureOfGaussians,LBP_MRF,LBSimpleGaussian,LOBSTER,MixtureOfGaussianV2,MixtureOfGaussianV1,MultiCue, - MultiLayer,PAWCS,PixelBasedAdaptiveSegmenter,SigmaDelta,StaticFrameDifference,SuBSENSE,T2FGMM_UM,T2FGMM_UV, - T2FMRF_UM,T2FMRF_UV,TwoPoints,ViBe,VuMeter,WeightedMovingMean,WeightedMovingVariance - - (Note that some of these algorithms are available only for a specific version of OpenCV, see algorithms.h) - */ IBGS *bgs = new FrameDifference; // IBGS *bgs = new PixelBasedAdaptiveSegmenter; // TODO + Mat distCoeffs, cameraMatrix; + read_camParamFile(distCoeffs, cameraMatrix); - //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 (tapter?) - - //init the random number generator - srand (time(NULL)); - - clock_t beginAll = clock(); - - //! read the center config file to cut out the ROI - //TODO merge this config with the Tapter.xml ?? - //circle param - int circleCenterX = 880; - int circleCenterY = 750; - int circleRadius = 700; - cv::String configFileNameCenter(centerFileString); - //read the config - cout << "parameter of centerConfigFile.xml" << endl; - - FileStorage fsCen; - fsCen.open(configFileNameCenter, FileStorage::READ); - if (!fsCen.isOpened()) - { - cout << "error during open " << centerFileString << " will abort" << endl; - return EXIT_FAILURE; - } - - circleCenterX = (int) fsCen["circleCenterX"]; - cout << "circleCenterX: " << circleCenterX << endl; - - circleCenterY = (int) fsCen["circleCenterY"]; - cout << "circleCenterY: " << circleCenterY << endl; - - circleRadius = (int) fsCen["circleRadius"]; - cout << "circleRadius: " << circleRadius << endl; - fsCen.release(); - - - //open camera config file - Mat distCoeffs; - Mat cameraMatrix; - { - std::string camParamFile = cameraParameterFile; - FileStorage fs(camParamFile, FileStorage::READ); - if (!fs.isOpened()) - { - std::cerr << "error opening '" << camParamFile << "' will abort" << endl; - return FILE_ERROR; - } - - fs["camera_matrix"] >> cameraMatrix; - fs["distortion_coefficients"] >> distCoeffs; + int circleCenterX, circleCenterY, circleRadius; + read_centerFile(circleCenterX, circleCenterY, circleRadius); - cout << cameraMatrix << endl << distCoeffs << endl; - } //fs.release(); system( "echo 'sleep a bit... ' && sleep 12" ); exit(EXIT_SUCCESS); @@ -247,7 +255,9 @@ int main(int argc, char * argv[]) vector<string> myFileListNoContour; //list for no contours found; vector<string> myFileListAfterContourSelection; //list for no contours found after selection; - //loop over _all_ pictures in the tar archive + clock_t beginAll = clock(); + + // loop over _all_ pictures in the tar archive for (;;) { @@ -288,7 +298,7 @@ int main(int argc, char * argv[]) { cerr << "archive_write_header() error: " << archive_error_string(ext)<< endl; myFileTarWriterHeaderCounter++; - continue; //we overjump all in our for loop + continue; // overjump all in for loop } vec = copyDataInBuffer(archive); @@ -308,7 +318,7 @@ int main(int argc, char * argv[]) cout << "\t" << frameCounter << "\tof \t" << amountFiles << " load file :" << filename << endl; //of data is present - if(img_input.data ) + if(img_input.data) { //! step 0 correct lense distortion @@ -648,21 +658,6 @@ void my_handler(int signum) } } -char* getCmdOption(char ** begin, char ** end, const string & option) -{ - char ** itr = find(begin, end, option); - if (itr != end && ++itr != end) - { - return *itr; - } - return 0; -} - -bool cmdOptionExists(char** begin, char** end, const string& option) -{ - return find(begin, end, option) != end; -} - int toFrameNumber(string filename) { int retVal = -1;