Skip to content
Snippets Groups Projects
Select Git revision
  • 8efbe93f6269eb26985682ddefbcd84110f05f4c
  • master default protected
  • beta
  • dev
  • andrewssobral-patch-1
  • update
  • thomas-fork
  • 2.0
  • v3.2.0
  • v3.1.0
  • v3.0
  • bgslib_py27_ocv3_win64
  • bgslib_java_2.0.0
  • bgslib_console_2.0.0
  • bgslib_matlab_win64_2.0.0
  • bgslib_qtgui_2.0.0
  • 2.0.0
  • bgs_console_2.0.0
  • bgs_matlab_win64_2.0.0
  • bgs_qtgui_2.0.0
  • v1.9.2_x86_mfc_gui
  • v1.9.2_x64_java_gui
  • v1.9.2_x86_java_gui
23 results

Demo.cpp

  • user avatar
    .
    am0ebe authored
    8efbe93f
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    Demo.cpp 20.86 KiB
    /*
    bgs_demo -i ../../dataset/video.tar -a 100 -o ../../output -c ../../config/centerConfigFile.xml -p ../../config/camParam.xml
    */
    
    //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>
    #include <signal.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <archive.h>
    #include <archive_entry.h>
    #include <fcntl.h>
    #include <string.h>
    #include <unistd.h>
    
    #include <regex> //cpp 11X
    
    #define PROCESS_CENTER_VERSION_MAJOR 2
    #define PROCESS_CENTER_VERSION_MINOR 0
    #define PROCESS_CENTER_VERSION_MINOR_FIXES 1
    
    #include <opencv2/opencv.hpp> //opencv
    #include "../src/algorithms/algorithms.h" //bgs
    
    using namespace bgslibrary::algorithms;
    using namespace cv;
    using namespace std;
    
    Scalar color_red( 0,0,255,255 );
    
    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
    int toFrameNumber(string filename);
    
    int main(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"))
    	{
    		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;
    	}
    
    	char *testFile = getCmdOption(argv, argv + argc, "-i");
    	string inputFile(".");
    	if (testFile)
    	{
    		//test dir exists
    		inputFile = string(testFile);
    	}
    
    	int amountFiles = -1;
    	char *testFileAmount = getCmdOption(argv, argv + argc, "-a");
    	if (testFileAmount)
    	{
    		string s(testFileAmount);
    		stringstream foo(s);
    		foo >> amountFiles;
    	}
    
    
    	char *centerFile = getCmdOption(argv, argv + argc, "-c");
    	string centerFileString(".");
    	if (centerFile)
    	{
    		//test dir exists
    		centerFileString = string(centerFile);
    	}
    
    	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 cameraParameterFile(".");
    	if (camerFile)
    	{
    		//test dir exists
    		cameraParameterFile = string(camerFile);
    	}
    
    
    	cout << "args: -i " << inputFile << " -a " << amountFiles << " -c" << centerFileString << " -o " << outputDir << " -p " << cameraParameterFile << endl;
    	//!**** end parse input***********/
    
    	//libarchive things
    
    	struct archive *archive;
    	struct archive *ext;
    	struct archive_entry *entry;
    	int r;
    	int flags = ARCHIVE_EXTRACT_TIME; // see https://linux.die.net/man/3/archive_write_disk for more flags
    	const char *filename = testFile;
    
    	archive = archive_read_new();
    	ext = archive_write_disk_new();
    	archive_write_disk_set_options(ext, flags);
    
    	archive_read_support_format_tar(archive);
    
    	//we get the filename
    	if (filename != NULL && strcmp(filename, "-") == 0)
    		filename = NULL;
    
    	//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
    
    
    	//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();
    
    
    	cout << "here" << endl;
    	system("pause");
    
    
    	//open camera config file
    	cv::String  camParam (cameraParameterFile);
    	Mat intrinsicsCameraMatrix, distortionCoeff;
    	{
    		cout  << "read cam parameter of: " << cameraParameterFile << endl;
    		FileStorage fs;
    		fs.open(camParam, FileStorage::READ);
    		if (!fs.isOpened())
    		{
    			cerr << "error during open " << cameraParameterFile << " will abort" << endl;
    			return -1;
    		}
    
    		fs["camera_matrix"] >> intrinsicsCameraMatrix;
    		fs["distortion_coefficients"] >> distortionCoeff;
    
    		// intrinsicsCameraMatrix = (int) fs["camera_matrix"];
    		// intrinsicsCameraMatrix = fs["camera_matrix"].mat();
    		cout << "camera_matrix = " << intrinsicsCameraMatrix << endl;
    
    		// distortionCoeff = (int) fs["distortion_coefficients"];
    		// distortionCoeff = fs["distortion_coefficients"].mat();
    		cout << "distortion_coefficients = " << distortionCoeff << endl;
    	}
    
    	cout << "a) we process all frames " << endl;
    
    	int everyPic= 60*5;
    	//string fileName;
    	int frameCounter=0;
    	int myFileTarWriterHeaderCounter = 0;
    	int frameCounterOld = -1;
    	vector<string> myFileErrorList;//list for pure io error
    	vector<string> myFileListNoContour; //list for no contours found;
    	vector<string> myFileListAfterContourSelection; //list for no contours found after selection;
    
    	//loop over _all_ picture of the tar archive
    	for (;;)
    	{
    
    		//measure time consumption
    		//sa opencv tick timer:
    		//	https://docs.opencv.org/4.x/d9/d6f/classcv_1_1TickMeter.html#details
    		clock_t begin = clock();  //for every single file
    		vector<char> vec;
    
    		//we read the next header
    		r = archive_read_next_header(archive, &entry);
    		if (r == ARCHIVE_EOF)
    			break;
    		if (r != ARCHIVE_OK)
    		{
    			cerr << "archive_read_next_header: error: " << archive_error_string(archive) << " will abort" << endl;
    			exit(1);
    		}
    		cout << "here2" << endl;
    
    		// get filename
    		const char *fileNamePtr = archive_entry_pathname(entry);
    		string filename(fileNamePtr,strlen(fileNamePtr) );
    		//cout << "fileName: " << filename << endl;
    		// convert it to a framenumber
    		frameCounter = toFrameNumber(filename);
    
    		if(frameCounterOld>frameCounter)
    		{
    			cerr << " error during read in the file number, we do have non montonic order, will abort";
    			exit(1);
    		}
    
    		frameCounterOld = frameCounter;
    
    		r = archive_write_header(ext, entry);
    		if (r != ARCHIVE_OK)
    		{
    			cerr << "archive_write_header() error: " << archive_error_string(ext)<< endl;
    			myFileTarWriterHeaderCounter++;
    			continue; //we overjump all in our for loop
    		}
    
    		vec = copyDataInBuffer(archive);
    		if(vec.empty())
    			cerr << "error during load data into buffer";
    
    		r = archive_write_finish_entry(ext);
    		if (r != ARCHIVE_OK)
    		{
    			cerr << "archive_write_finish_entry: error: " << archive_error_string(ext) << " will abort" << endl;
    			exit(1);
    		}
    
    		// read the image buffer as a jpg picture and decode it
    		Mat img_input = imdecode(Mat(vec), 1);
    
    		//        //we define the type better to prevent error
    		//        fileName = string(inputFile + TToolBox::getFileName(frameCounter));
    		//        cv::String fileNameCV(fileName);
    
    		cout << "\t" << frameCounter << "\tof \t" << amountFiles << "  load file :" << filename << endl;
    
    		//of data is present
    		if(img_input.data )
    		{
    
    			//! step 0 we take care about the lense distortion
    			//! correct lense distortion
    			Mat imgLenseCorrection = img_input.clone();
    			//see https://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html#undistort
    			cv::undistort(img_input, imgLenseCorrection, intrinsicsCameraMatrix, distortionCoeff);
    
    			//! we cut out a smaller ROI,
    			//! step 1)
    			img_input = TToolBox::cropImageCircle(imgLenseCorrection,circleCenterX,circleCenterY,circleRadius);
    
    			//!  normal bgs processing
    			//! step 2)
    			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
    
    			//! step 3) apply edge detection
    			//TODO make this in a function, how many times is this listed ??
    			//TODO read from tapter config
    			//TODO all parameter from applyCannyEdgeAndCalcCountours also !!
    			double threshholdMin = 150;
    			double threshholdMax = 200;
    			int apertureSize = 3;
    			vector<vector<Point> > contours = TToolBox::applyCannyEdgeAndCalcCountours(img_mask,threshholdMin,threshholdMax,apertureSize);
    
    			//define what will be written
    			vector<vector<Point> > contourSelection;
    			vector<Point2f> massCenters;
    			vector<Point> conHull;
    			Point2f muConvexHullMassCenter(0.0,0.0);
    
    			if(!contours.empty())
    			{
    
    				//! step 4) we make a selection out of all contours with area sizes******************************
    
    				//calc all min rotated  rectangles for all contour from canny edge detect
    				//exclude very small/big
    				vector<RotatedRect> minRect( contours.size() );
    
    				//calc boxes around the contours
    				for( size_t i = 0; i < contours.size(); i++ )
    					minRect[i] = minAreaRect( Mat(contours[i]) ); //may use boundingRect ?? to use fix non rotated rectangles ?
    
    				vector<Point2f> recCenterPoints;
    				float areaMinThreshold = 150;
    				float areaMaxThreshold = 300000; //old max threshold was to small //TODO apply moving filter ??, an more adaptive approach
    
    				//iterate all rectangles
    				for( size_t i = 0; i< minRect.size(); i++ )
    				{
    					Point2f rect_points[4];
    					//get all points of the retange
    					minRect[i].points( rect_points );
    
    					//construct contour based on rectangle points because contour != rectangle with points
    					vector<Point> contourRect;
    					for(int j=0;j<4;j++)
    						contourRect.push_back(rect_points[j]);
    
    					//calc the area of the contour
    					double area0 = contourArea(contourRect);
    					//over stepp all small areas
    					if(area0<areaMinThreshold||area0>areaMaxThreshold)
    					{
    						//cout << i << ":area0:" << area0 << " dismissed " << endl;
    						//skipe if the area is too small
    						continue;
    					}
    					else
    					{
    						//cout << i << ":area0:" << area0 << " choose " << endl;
    
    						//get the center of this rectangle
    						Point2f center = minRect[i].center;
    						recCenterPoints.push_back(center);
    
    						//we also add the this contour to a selection
    						contourSelection.push_back(contours[i]);
    
    					}
    				}//end iterate all min rectangle
    
    				if(!contourSelection.empty())
    				{
    					//! step 5) we calc the moments from the contour selection
    					vector<Moments> mu(contourSelection.size() );
    					for( size_t i = 0; i < contourSelection.size(); i++ )
    					{
    						mu[i] = moments( contourSelection[i], false );
    					}
    
    					//  Get the mass centers:
    					massCenters =  vector<Point2f>( contourSelection.size() );
    					for( size_t i = 0; i < contourSelection.size(); i++ )
    					{
    						massCenters[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 );
    					}
    
    					//! step 6) calc convex hull of all points of the contour selection *********
    					//TODO produce center of convex hull of all polygones
    					//TODO double check if ne contour sharing a center point ? nearby ??
    
    					//we merge all points
    					vector<Point> allContourPoints;
    					for (size_t cC = 0; cC < contourSelection.size(); ++cC)
    						for(size_t cP =0; cP < contourSelection[cC].size(); cP++)
    						{
    							Point currentContourPixel = contourSelection[cC][cP];
    							allContourPoints.push_back(currentContourPixel);
    						}
    
    					// calc the hull ******************
    						conHull = vector<Point>(allContourPoints.size());
    						convexHull( Mat(allContourPoints), conHull, false );
    					//    Point roiCenter;
    					//    float roiRadius;
    
    					//calc the min circle around
    					//minEnclosingCircle(conHull,roiCenter,roiRadius);
    					//we calc the mass center of the convex hull
    
    					///we calc the mass center of the convex hull
    						Moments muConvexHull;
    						if(!conHull.empty())
    						{
    							muConvexHull = moments(conHull, true );
    							muConvexHullMassCenter = Point2f( muConvexHull.m10/muConvexHull.m00 , muConvexHull.m01/muConvexHull.m00 );
    						}
    					}
    				else //end after selection is empty
    				{
    					cerr << "error, no contour found after selection in file: " << filename << endl;
    					myFileListAfterContourSelection.push_back(filename);
    				}
    			}//end if contours are empty, to canny edge found nothing
    			else
    			{
    				cerr << "error, no contour found at all in file: " << filename << endl;
    				myFileListNoContour.push_back(filename);
    
    			}
    #ifdef  MC_SHOW_STEP_ANALYSE
    
    			if(!conHull.empty())//if we any elements, we process further
    			{
    				Mat imgConvexHull = Mat::zeros( img_input.size(), CV_8UC3 );
    				imgConvexHull =  Scalar(255,255,255); //fill the picture
    
    				polylines(imgConvexHull, hullComplete, true, color_red, 1, 8);
    
    				//draw circle around
    				//circle( imgConvexHull, roiCenter, (int) roiRadius, color_red, 2, 8, 0 );
    
    				//we draw it
    				cv::String outpath2 =  outputDir;
    				ostringstream convert2;
    				convert2 << outpath2 << TToolBox::mNzero(frameCounter) << "_convex_hull.jpg";
    				cv::imwrite(convert2.str().c_str(), imgConvexHull);
    			}
    			else
    				cout << "convex hull has no points will skip file: " << i << endl;
    
    #endif
    
    			//cout << " found center at : " << massCenters.at(0).x << ";" << massCenters.at(0).y << endl;
    			//! step 8: we write down all our results in yml file
    			string nameOutPutFileData =  outputDir + TToolBox::mNzero(frameCounter) + ".yml";
    
    			//cout << "output file:" << nameOutPutFileData;
    
    			FileStorage fs(nameOutPutFileData.c_str(), FileStorage::WRITE);
    			fs << "masscenters" << massCenters;
    			fs << "polygonselection" << contourSelection;
    			fs << "convexhull" << conHull;
    			fs << "masscenterconvexhull" << muConvexHullMassCenter;
    			fs.release();
    
    			//! occasionaly write a dbg picture
    			if(frameCounter%everyPic==0)
    			{
    				RNG rng(4344234);
    				Mat imgDebugPaint2 = Mat::zeros( img_input.size(), CV_8UC3 );
    				imgDebugPaint2 =  Scalar(255,255,255); //fill the picture white
    
    				// write all polyies of the selection and the mass centers with a random color
    				for( size_t i = 0; i< contourSelection.size(); i++ )
    				{
    					//random color
    					Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
    					//contour
    					drawContours( imgDebugPaint2, contourSelection, i, color, 1, LINE_AA);
    					//draw the center
    					circle( imgDebugPaint2, massCenters[i], 4, color, -1, 8, 0 );
    				}
    
    				// write the convex hull
    				if(!conHull.empty())
    				{
    					//the poly
    					polylines(imgDebugPaint2, conHull, true, color_red, 1, 8);
    					//the center
    					circle( imgDebugPaint2,muConvexHullMassCenter, 4, color_red, -1, 8, 0 );
    				}
    
    				// copy
    				Mat imgOverlay2 = img_input.clone();
    				// add overlay of paintings
    				addWeighted( imgDebugPaint2, 0.7, imgOverlay2, 0.3, 0.0, imgOverlay2);
    				// writeout file
    				string nameOutPutFileDBGpic =  outputDir + TToolBox::mNzero(frameCounter) + string(".jpg");
    
    				imwrite(nameOutPutFileDBGpic.c_str(),imgOverlay2);
    
    			}//end if dbg picture
    
    
    		}//end if the loaded picture has data
    		else
    		{
    			cerr << "error loading file: " << filename << ", will skip this file" << endl;
    			myFileErrorList.push_back(filename);
    		}
    
    		//calc the time which we used for a picture //TODO move out of loop
    		clock_t end = clock();
    		double elapsedSecs = double(end - begin) / CLOCKS_PER_SEC;
    
    
    		//calc the time which was used for all pictures
    		clock_t endAll = clock();
    		double elapsedSecTotal = double(endAll - beginAll) / CLOCKS_PER_SEC;
    		cout << "process single pic:\t" << elapsedSecs << " s  - \t\t" << (int)(elapsedSecTotal/60)<< " min -\t" << (int)(elapsedSecTotal/60/60)<< " h" << endl;
    
    		if(g_badSignalFlagAbort)
    			frameCounter = amountFiles; // abort
    
    		//if(frameCounter>10)exit(0); //the test abort function
    
    	}//end for ever loop
    
    	//finishing time
    	clock_t endAll = clock();
    	double elapsed = double(endAll - beginAll) / CLOCKS_PER_SEC;
    	cout << "process : " << amountFiles << " files took:\t" << (int)(elapsed/60)<< " min -\t" << (int)(elapsed/60/60)<< " h \n in total" << endl;
    
    	//    //we write the random file list to a file
    	//    string nameOutRandomFile =  outputDir + "randlist.yml";
    	//    FileStorage fs(nameOutRandomFile.c_str(), FileStorage::WRITE);
    	//    fs << "randomlist" << myRandomTrainList;
    	//    fs.release();
    
    	//TODO we should merge the file
    
    	cout << "amount of libarchive read header errors :" << myFileTarWriterHeaderCounter;
    
    	// write the random file list to a file
    	string nameOutErrorList =  outputDir + "fileErrorList.yml";
    	cout << "amount of file errors: " << myFileErrorList.size()<< endl;
    	FileStorage fs2(nameOutErrorList.c_str(), FileStorage::WRITE);
    	fs2 << "fileErrorIOs" << myFileErrorList;
    
    	// write error list no contours found in file
    	cout << "amount contour errors with canny edge: " << myFileListNoContour.size() << endl;
    	fs2 << "fileErrorNoContours" << myFileListNoContour;
    
    	// write error list no contours found in file
    	cout << "amount contour errors after selection: " << myFileListAfterContourSelection.size() << endl;
    	fs2 << "fileErrorNoContoursAfterSelections" << myFileListAfterContourSelection;
    
    	// bgs related things
    	delete bgs;
    
    	// opencv related things
    	fs2.release();
    
    	cvDestroyAllWindows();
    
    	//close lib archive related things
    	archive_read_close(archive);
    	archive_read_free(archive);
    
    	archive_write_close(ext);
    	archive_write_free(ext);
    
    	return 0;
    }
    
    
    
    vector<char> copyDataInBuffer(struct archive *aw)
    {
    	int r;
    	const void *buff;
    	vector<char> vec;
    	size_t size;
    #if ARCHIVE_VERSION_NUMBER >= 3000000
    	int64_t offset;
    #else
    	off_t offset;
    #endif
    	//forever till we get a specific return
    	for (;;) {
    		r = archive_read_data_block(aw, &buff, &size, &offset);
    		if (r == ARCHIVE_EOF)
    		{
    			return vec; // everything fine, were are just at the end
    		}
    
    		if (r != ARCHIVE_OK)
    		{
    			cerr << "error during read archive " << endl;
    			return vec;
    		}
    
    		//a good discussion :  https://stackoverflow.com/questions/259297/how-do-you-copy-the-contents-of-an-array-to-a-stdvector-in-c-without-looping
    		// Method 4: vector::insert
    		{
    			//we rename our pointer to avoid a weird compiler warning
    			char *foo = (char*) buff;
    			vec.insert(vec.end(), &foo[0], &foo[size]);
    		}
    
    	}
    
    	return vec;
    }
    
    void my_handler(int signum)
    {
    	if (signum == SIGUSR1)
    	{
    		g_badSignalFlagAbort = 1;
    		cerr << "receive signal to abort" << endl;
    	}
    }
    
    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;
    
    	//we cut out all non needed substrings
    	filename = regex_replace(filename, regex("/"), "");
    	filename = regex_replace(filename, regex("data_sized"), "");
    	filename = regex_replace(filename, regex("jpg"), "");
    	filename = regex_replace(filename, regex("\\."), "");
    
    	retVal = stoi( filename );
    
    	//cout << "filename out:" << filename << " number: " << retVal << endl;
    
    	return retVal;
    }