Skip to content
Snippets Groups Projects
Commit fa15e033 authored by am0ebe's avatar am0ebe
Browse files

Initial commit 2021. Opencv 4.2 and bgs 3.0 + added changes from Thomas'...

Initial commit 2021. Opencv 4.2 and bgs 3.0 + added changes from Thomas' bgs-library-fork [WIP not buildable yet]

> forked/mirrored repo @ commit 4e47342e from bgslibrary (just after tag "v3.0")
> added changed Files from bgs-library-fork

see:
git@github.com:andrewssobral/bgslibrary.git
git@gitlab.idiv.de:tb55xemi/bgs-library-fork.git
parent 4e47342e
No related branches found
No related tags found
No related merge requests found
cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 2.8)
project(bgslibrary-examples)
project(bgslibrary)
set(CMAKE_CXX_STANDARD 14)
# cmake -D BGS_PYTHON_SUPPORT=ON ..
if(NOT DEFINED BGS_PYTHON_SUPPORT)
set(BGS_PYTHON_SUPPORT OFF)
elseif()
# add_definitions(-DBGS_PYTHON_SUPPORT)
endif()
message(STATUS "BGSLIBRARY WITH PYTHON SUPPORT: ${BGS_PYTHON_SUPPORT}")
if(UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
set(CMAKE_MACOSX_RPATH 1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
endif(UNIX)
# Avoid cmake warnings about changes in behavior of some Mac OS X path
# variable we don't care about.
if (POLICY CMP0042)
cmake_policy(SET CMP0042 NEW)
endif()
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
#set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules)
# compilation mode setup
......@@ -23,15 +22,8 @@ set(CMAKE_BUILD_TYPE Release)
#set(CMAKE_BUILD_TYPE Debug)
if(WIN32)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
set(BUILD_SHARED_LIBS TRUE)
#if(BGS_PYTHON_SUPPORT)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
#else()
# set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
# set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
#endif()
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
endif(WIN32)
set(bgs_out_dir ".")
......@@ -41,104 +33,121 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${bgs_out_dir})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${bgs_out_dir})
# Second, for multi-config builds (e.g. msvc)
foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${bgs_out_dir})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${bgs_out_dir})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${bgs_out_dir})
string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${bgs_out_dir})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${bgs_out_dir})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${bgs_out_dir})
endforeach(OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES)
if(UNIX)
# add some standard warnings
ADD_DEFINITIONS(-Wno-variadic-macros -Wno-long-long -Wall -Wextra -Winit-self -Woverloaded-virtual -Wsign-promo -Wno-unused-parameter -pedantic -Woverloaded-virtual -Wno-unknown-pragmas)
# add some standard warnings
ADD_DEFINITIONS(-Wno-variadic-macros -Wno-long-long -Wall -Wextra -Winit-self -Woverloaded-virtual -Wsign-promo -Wno-unused-parameter -pedantic -Woverloaded-virtual -Wno-unknown-pragmas)
# -ansi does not compile with sjn module
#ADD_DEFINITIONS(-ansi)
# -ansi does not compile with sjn module
#ADD_DEFINITIONS(-ansi)
# if you like to have warinings about conversions, e.g. double->int or double->float etc., or float compare
#ADD_DEFINITIONS(-Wconversion -Wfloat-equal)
# if you like to have warinings about conversions, e.g. double->int or double->float etc., or float compare
#ADD_DEFINITIONS(-Wconversion -Wfloat-equal)
endif(UNIX)
set(OpenCV_STATIC OFF)
find_package(OpenCV REQUIRED)
if(OpenCV_FOUND)
message(STATUS "")
message(STATUS "OpenCV library status:")
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}\n")
endif()
message(STATUS "OpenCV library status:")
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
# if(${OpenCV_VERSION} VERSION_EQUAL 3 OR ${OpenCV_VERSION} VERSION_GREATER 3)
# message(FATAL_ERROR "OpenCV version is not compatible: ${OpenCV_VERSION}")
# message(FATAL_ERROR "OpenCV version is not compatible: ${OpenCV_VERSION}")
# endif()
if(${OpenCV_VERSION} VERSION_LESS 2.3.1)
message(FATAL_ERROR "OpenCV version is not compatible: ${OpenCV_VERSION}")
message(FATAL_ERROR "OpenCV version is not compatible: ${OpenCV_VERSION}")
endif()
find_package(LibArchive REQUIRED)
message(STATUS "LibArchive library status:")
message(STATUS " version: ${LibArchive_VERSION}")
message(STATUS " libraries: ${LibArchive_LIBRARIES}")
message(STATUS " include path: ${LibArchive_INCLUDE_DIRS}")
if(BGS_PYTHON_SUPPORT)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost REQUIRED COMPONENTS python)
find_package(PythonLibs REQUIRED)
message(STATUS "Boost library status:")
message(STATUS " version: ${Boost_VERSION}")
message(STATUS " libraries: ${Boost_LIBRARIES}")
message(STATUS " include path: ${Boost_INCLUDE_DIRS}")
message(STATUS "Python library status:")
message(STATUS " version: ${PYTHON_VERSION}")
message(STATUS " libraries: ${PYTHON_LIBRARIES}")
message(STATUS " include path: ${PYTHON_INCLUDE_DIRS}")
endif()
#file(GLOB sources FrameProcessor.cpp PreProcessor.cpp VideoAnalysis.cpp VideoCapture.cpp)
file(GLOB main Main.cpp FrameProcessor.cpp PreProcessor.cpp VideoAnalysis.cpp VideoCapture.cpp)
file(GLOB demo Demo.cpp)
file(GLOB demo2 Demo2.cpp)
file(GLOB_RECURSE tools_src ../src/tools/*.cpp ../src/tools/*.c)
file(GLOB_RECURSE tools_inc ../src/tools/*.h ../src/tools/*.hpp)
file(GLOB_RECURSE utils_src ../src/utils/*.cpp ../src/utils/*.c)
file(GLOB_RECURSE utils_inc ../src/utils/*.h ../src/utils/*.hpp)
file(GLOB_RECURSE bgs_src ../src/algorithms/*.cpp ../src/algorithms/*.c)
file(GLOB_RECURSE bgs_inc ../src/algorithms/*.h ../src/algorithms/*.hpp)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${OpenCV_INCLUDE_DIRS})
# list(REMOVE_ITEM sources ${demo} ${demo2})
file(GLOB_RECURSE analysis_src package_analysis/*.cpp)
if(BGS_PYTHON_SUPPORT)
file(GLOB_RECURSE bgs_src package_bgs/*.cpp package_bgs/*.c wrapper_python/*.cpp)
file(GLOB_RECURSE bgs_include package_bgs/*.h wrapper_python/*.h)
include_directories(${CMAKE_SOURCE_DIR} ${OpenCV_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})
else()
file(GLOB_RECURSE bgs_src package_bgs/*.cpp package_bgs/*.c)
file(GLOB_RECURSE bgs_include package_bgs/*.h)
include_directories(${CMAKE_SOURCE_DIR} ${OpenCV_INCLUDE_DIRS} ${LibArchive_INCLUDE_DIRS})
endif()
# GMG is not available in older OpenCV versions
if(${OpenCV_VERSION} VERSION_LESS 2.4.3)
file(GLOB gmg ../src/algorithms/GMG.cpp)
list(REMOVE_ITEM bgs_src ${gmg})
file(GLOB gmg package_bgs/GMG.cpp)
list(REMOVE_ITEM bgs_src ${gmg})
endif()
add_library(bgslibrary_core SHARED ${bgs_src} ${tools_src} ${utils_src} ${bgs_inc} ${tools_inc} ${utils_inc})
# generates the export header bgslibrary_core_EXPORTS.h automatically
include(GenerateExportHeader)
GENERATE_EXPORT_HEADER(bgslibrary_core
BASE_NAME bgslibrary_core
EXPORT_MACRO_NAME bgslibrary_core_EXPORTS
EXPORT_FILE_NAME bgslibrary_core_EXPORTS.h
STATIC_DEFINE BGSLIBRARY_CORE_EXPORTS_BUILT_AS_STATIC)
target_link_libraries(bgslibrary_core ${OpenCV_LIBS})
set_property(TARGET bgslibrary_core PROPERTY PUBLIC_HEADER ${bgs_inc} ${tools_inc} ${utils_inc})
#if(WIN32)
# # set_property(TARGET bgslibrary_core PROPERTY SUFFIX ".lib")
# #if(BGS_PYTHON_SUPPORT)
# # set_property(TARGET bgslibrary_core PROPERTY SUFFIX ".pyd")
# #endif()
#else()
# set_property(TARGET bgslibrary_core PROPERTY OUTPUT_NAME "bgs")
#endif()
#if(APPLE)
# if(BGS_PYTHON_SUPPORT)
# set_property(TARGET bgslibrary_core PROPERTY SUFFIX ".so")
# set_target_properties(bgslibrary_core PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
# endif()
#endif()
if(BGS_PYTHON_SUPPORT)
#add_library(libbgs SHARED ${sources} ${bgs_src} ${analysis_src})
add_library(libbgs SHARED ${bgs_src} ${analysis_src})
target_link_libraries(libbgs ${OpenCV_LIBS} ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
target_compile_definitions(libbgs PRIVATE BGS_PYTHON_SUPPORT=1)
else()
#add_library(libbgs STATIC ${sources} ${bgs_src} ${analysis_src})
add_library(libbgs STATIC ${bgs_src} ${analysis_src})
target_link_libraries(libbgs ${OpenCV_LIBS})
endif()
set_property(TARGET libbgs PROPERTY PUBLIC_HEADER ${bgs_include})
if(WIN32)
# set_property(TARGET libbgs PROPERTY SUFFIX ".lib")
else()
set_property(TARGET libbgs PROPERTY OUTPUT_NAME "bgs")
endif()
add_executable(bgslibrary ${main})
target_link_libraries(bgslibrary ${OpenCV_LIBS} libbgs)
# set_target_properties(bgslibrary PROPERTIES OUTPUT_NAME bgs)
add_executable(bgs_demo ${demo})
target_link_libraries(bgs_demo ${OpenCV_LIBS} bgslibrary_core)
target_link_libraries(bgs_demo ${OpenCV_LIBS} ${LibArchive_LIBRARIES} libbgs)
add_executable(bgs_demo2 ${demo2})
target_link_libraries(bgs_demo2 ${OpenCV_LIBS} bgslibrary_core)
if(UNIX)
# to avoid: error while loading shared libraries: libbgslibrary_core.so
message(STATUS "You might need to run:")
message(STATUS "$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib")
message(STATUS "$ export LD_LIBRARY_PATH")
message(STATUS "after 'make install' to avoid error while loading libbgslibrary_core\n")
endif()
if(WIN32)
message(STATUS "You might need to add ${CMAKE_CURRENT_BINARY_DIR} to your PATH to be able to run your applications.")
message(STATUS "> set PATH=%PATH%;${CMAKE_CURRENT_BINARY_DIR}\n")
endif()
target_link_libraries(bgs_demo2 ${OpenCV_LIBS} ${LibArchive_LIBRARIES} libbgs)
install(TARGETS libbgs
bgslibrary
RUNTIME DESTINATION bin COMPONENT app
LIBRARY DESTINATION lib COMPONENT runtime
ARCHIVE DESTINATION lib COMPONENT runtime
PUBLIC_HEADER DESTINATION include/package_bgs COMPONENT dev
FRAMEWORK DESTINATION "/Library/Frameworks"
)
/*
./bgs_demo -i test45/ -a 100 -o test45/results
*/
//cpp c
#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
#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>
//cpp 11X
#include <regex>
#define PROCESS_CENTER_VERSION_MAJOR 2
#define PROCESS_CENTER_VERSION_MINOR 0
#define PROCESS_CENTER_VERSION_MINOR_FIXES 1
//opencv
#include <opencv2/opencv.hpp>
//bgslibrary
#include "package_bgs/bgslibrary.h"
//my class
#include "package_bgs/Tapter.h"
#include "package_bgs/ttoolbox.h"
using namespace cv;
using namespace std;
int g_badSignalFlagAbort = 0;
void my_handler(int signum);
char* getCmdOption(char ** begin, char ** end, const std::string & option);
bool cmdOptionExists(char** begin, char** end, const std::string& option);
std::vector<char> copyDataInBuffer(struct archive *aw);
//! we convert our actual jpg file number to framenumber
int toFrameNumber(std::string filename);
int main(int argc, char * argv[])
{
signal(SIGUSR1, my_handler);
std::cout << "using processcenter " <<PROCESS_CENTER_VERSION_MAJOR <<"."<< PROCESS_CENTER_VERSION_MINOR<<"."<<PROCESS_CENTER_VERSION_MINOR_FIXES<< endl;
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 inputTarFile -a amountOfJpgFiles -c exactCenterConfFile.xml -o outPutPath -p camparameterFile.xml"<<endl;
return EXIT_FAILURE;
}
if(!cmdOptionExists(argv, argv+argc, "-i")||!cmdOptionExists(argv, argv+argc, "-a")||!cmdOptionExists(argv, argv+argc, "-o") ||!cmdOptionExists(argv, argv+argc, "-p"))
{
cout <<" error: please use command as\n./bgs_demo -i inputTarFile -a amountOfJpgFiles -c exactCenterConfFile.xml -o outPutPath -p camparameterFile.xml"<<endl;
return EXIT_FAILURE;
}
char *testFile = getCmdOption(argv, argv + argc, "-i");
std::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");
std::string centerFileString(".");
if (centerFile)
{
//test dir exists
centerFileString = string(centerFile);
}
char *testOutputDir = getCmdOption(argv, argv + argc, "-o");
std::string outputDir(".");
if (testOutputDir)
{
//test dir exists
outputDir = string(testOutputDir);
}
char *camerFile = getCmdOption(argv, argv + argc, "-p");
std::string cameraParameterFile(".");
if (camerFile)
{
//test dir exists
cameraParameterFile = string(camerFile);
}
cout <<"args: -i "<<inputFile<<" -a "<<amountFiles << " -c" << centerFileString<<" -o " << outputDir <<" -p " << cameraParameterFile ;
//!**** 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 */
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;
//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
//init the random number generator
srand (time(NULL));
clock_t beginAll = clock();
//! we read the center config file for 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\n ";
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();
//we open the camera config file
cv::String camParam (cameraParameterFile);
Mat intrinsicsCameraMatrix, distortionCoeff;
{
cout << "read cam parameter of: "<< cameraParameterFile ;
FileStorage fs;
fs.open(camParam, FileStorage::READ);
if (!fs.isOpened())
{
cerr << "error during open " << cameraParameterFile << " will abort\n ";
return -1;
}
fs["camera_matrix"] >> intrinsicsCameraMatrix;
std::cout << "camera_matrix = "<< intrinsicsCameraMatrix<<endl;
fs["distortion_coefficients"] >> distortionCoeff;
std::cout << "distortion_coefficients"<< distortionCoeff<<endl;
}
cout <<"a) we process all frames "<<endl;
int everyPic= 60*5;
//std::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;
//the corruption check is done beforehand
//vector<string> myFileListCorrupted; //list all corrupted jpg files
//here we loop over all picture of the tar archive, independing how many this are
for (;;)
{
//measure time consumption
clock_t begin = clock(); //for every single file
std::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);
}
//we get the filename
const char *fileNamePtr = archive_entry_pathname(entry);
std::string filename(fileNamePtr,strlen(fileNamePtr) );
//cout << "fileName: "<< filename <<endl;
//we 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
}
//else
//{
//we copy all data to the buffer vector
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);
}
//}
//we 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 = std::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) we make we apply a 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;
std::vector<vector<Point> > contours = TToolBox::applyCannyEdgeAndCalcCountours(img_mask,threshholdMin,threshholdMax,apertureSize);
//define what we will write down
std::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 counters with area sizes******************************
//we calc all min rotated rectangles for all contour from candy egde detect
//we exlcude very small one and very big ones
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);
#include "../src/algorithms/algorithms.h"
//we also add the this contour to a selection
contourSelection.push_back(contours[i]);
#if CV_MAJOR_VERSION >= 4
#define CV_CAP_PROP_POS_FRAMES cv::CAP_PROP_POS_FRAMES
#define CV_CAP_PROP_FRAME_COUNT cv::CAP_PROP_FRAME_COUNT
}
}//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); //fille the picture
Scalar colorB( 0,0,255,255 );//red
polylines(imgConvexHull, hullComplete, true, colorB, 1, 8);
//draw circle around
//circle( imgConvexHull, roiCenter, (int) roiRadius, colorB, 2, 8, 0 );
//we draw it
cv::String outpath2= outputDir;
std::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
std::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();
//! we write from time to time a dbg picture
if(frameCounter%everyPic==0)
{
Scalar colorRed( 0,0,255,255 );//red
RNG rng(4344234);
Mat imgDebugPaint2 = Mat::zeros( img_input.size(), CV_8UC3 );
imgDebugPaint2 = Scalar(255,255,255); //fill the picture white
//we 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 );
}
//we write the convex hull
if(!conHull.empty())
{
//the poly
polylines(imgDebugPaint2, conHull, true, colorRed, 1, 8);
//the center
circle( imgDebugPaint2,muConvexHullMassCenter, 4, colorRed, -1, 8, 0 );
}
//we make a copy
Mat imgOverlay2 = img_input.clone();
//we add a overlay of our paitings
addWeighted( imgDebugPaint2, 0.7, imgOverlay2, 0.3, 0.0, imgOverlay2);
//we write the file down
std::string nameOutPutFileDBGpic = outputDir + TToolBox::mNzero(frameCounter) + std::string(".jpg");
imwrite(nameOutPutFileDBGpic.c_str(),imgOverlay2);
}//end if we write a dbg picture
}//end if the loaded picture has data
else
{
cerr<<"error loading file: "<< filename<<", will skip this file"<<endl;
myFileErrorList.push_back(filename);
}
// }//end if not corrupted picture
// else
// {
// cerr<<"error file: "<< fileName<<" is corrupted, will ignore it"<<endl;
// myFileListCorrupted.push_back(fileName);
// }
//we calc the time which we used for a picture
clock_t end = clock();
double elapsedSecs = double(end - begin) / CLOCKS_PER_SEC;
//we calc the time which was used for all picture
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; //we 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
// std::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;
//we write the random file list to a file
std::string nameOutErrorList = outputDir + "fileErrorList.yml";
cout <<"amount of file errors: "<< myFileErrorList.size()<<endl;
FileStorage fs2(nameOutErrorList.c_str(), FileStorage::WRITE);
fs2 << "fileErrorIOs" << myFileErrorList;
//we write error list no contours found in file
cout <<"amount contour errors with canny edge: "<< myFileListNoContour.size()<<endl;
fs2 << "fileErrorNoContours" << myFileListNoContour;
//we write error list no contours found in file
cout <<"amount contour errors after selection: "<< myFileListAfterContourSelection.size()<<endl;
fs2 << "fileErrorNoContoursAfterSelections" << myFileListAfterContourSelection;
// //we write error list no contours found in file
// cout <<"amount of corrupted jpg files: "<< myFileListCorrupted.size()<<endl;
// fs2 << "fileErrorIOcorruptFiles" << myFileListCorrupted;
//the bgs related things
delete bgs;
//opencv related things
fs2.release();
// capture.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;
}
std::vector<char> copyDataInBuffer(struct archive *aw)
{
int r;
const void *buff;
std::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
}
int main(int argc, char **argv)
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)
{
std::cout << "Using OpenCV " << CV_MAJOR_VERSION << "." << CV_MINOR_VERSION << "." << CV_SUBMINOR_VERSION << std::endl;
cv::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 */
auto algorithmsName = BGS_Factory::Instance()->GetRegisteredAlgorithmsName();
std::cout << "List of available algorithms:" << std::endl;
std::copy(algorithmsName.begin(), algorithmsName.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
for (const std::string& algorithmName : algorithmsName)
{
std::cout << "Running " << algorithmName << std::endl;
auto bgs = BGS_Factory::Instance()->Create(algorithmName);
cv::Mat img_input;
capture.set(CV_CAP_PROP_POS_FRAMES, 0); // Set index to 0 (start frame)
auto frame_counter = 0;
std::cout << "Press 's' to stop:" << std::endl;
auto key = 0;
while (key != 's')
{
// Capture frame-by-frame
capture >> img_input;
frame_counter += 1;
if (img_input.empty()) break;
cv::resize(img_input, img_input, cv::Size(380, 240), 0, 0, CV_INTER_LINEAR);
cv::imshow("input", img_input);
cv::Mat img_mask;
cv::Mat img_bkgmodel;
try
{
bgs->process(img_input, img_mask, img_bkgmodel); // by default, it shows automatically the foreground mask image
//if(!img_mask.empty())
// cv::imshow("Foreground", img_mask);
// do something
}
catch (std::exception& e)
{
std::cout << "Exception occurred" << std::endl;
std::cout << e.what() << std::endl;
}
key = cv::waitKey(33);
}
std::cout << "Press 'q' to exit, or anything else to move to the next algorithm:" << std::endl;
key = cv::waitKey(0);
if (key == 'q')
break;
cv::destroyAllWindows();
}
capture.release();
return 0;
if (signum == SIGUSR1)
{
g_badSignalFlagAbort = 1;
cerr << "receive signal to abort"<<endl;
}
}
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 toFrameNumber(std::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 = std::stoi( filename );
//cout <<"filename out:" << filename << " number: "<< retVal << endl;
return retVal;
}
/*
./bgs_demo -i test45/ -a 100 -o test45/results/
based on original demo.cpp
*/
// c
#include <sys/types.h>
#include <sys/stat.h>
#include <archive.h>
#include <archive_entry.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
//cpp c
#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <cstdlib>
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <ctime>
#define PROCESS_CENTER_VERSION_MAJOR 0
#define PROCESS_CENTER_VERSION_MINOR 2
//opencv
#include <opencv2/opencv.hpp>
//bgslibrary
#include "package_bgs/bgslibrary.h"
//my class
#include "package_bgs/Tapter.h"
#include "package_bgs/ttoolbox.h"
using namespace cv;
using namespace std;
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;
}
static std::vector<char> copyDataInBuffer(struct archive *aw);
//static void errmsg(const char *);
//static void fail(const char *, const char *, int);
//static void msg(const char *);
//static void warn(const char *, const char *);
#include "../src/algorithms/algorithms.h"
#if CV_MAJOR_VERSION >= 4
#define CV_LOAD_IMAGE_COLOR cv::IMREAD_COLOR
#endif
int main(int argc, char **argv)
int main(int argc, char * argv[])
{
std::cout << "Using OpenCV " << CV_MAJOR_VERSION << "." << CV_MINOR_VERSION << "." << CV_SUBMINOR_VERSION << std::endl;
std::string baseDir = "./dataset/frames";
if (argc > 1)
baseDir = argv[1];
std::cout << "Openning: " << baseDir << std::endl;
/* Background Subtraction Methods */
auto algorithmsName = BGS_Factory::Instance()->GetRegisteredAlgorithmsName();
std::cout << "List of available algorithms:" << std::endl;
std::copy(algorithmsName.begin(), algorithmsName.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
for (const std::string& algorithmName : algorithmsName)
{
std::cout << "Running " << algorithmName << std::endl;
auto bgs = BGS_Factory::Instance()->Create(algorithmName);
auto frame_counter = 0;
std::cout << "Press 's' to stop:" << std::endl;
auto key = 0;
while (key != 's')
std::cout << "using produce bk " <<PROCESS_CENTER_VERSION_MAJOR <<"."<< PROCESS_CENTER_VERSION_MINOR << endl;
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 -c exactCenterConfFile.xml -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 -c exactCenterConfFile.xml -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 *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);
}
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 = "data_sized.tar";
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)))
{
// Capture frame-by-frame
frame_counter++;
std::stringstream ss;
ss << frame_counter;
auto fileName = baseDir + "/" + ss.str() + ".png";
std::cout << "reading " << fileName << std::endl;
auto img_input = cv::imread(fileName, CV_LOAD_IMAGE_COLOR);
if (img_input.empty())
break;
cv::imshow("input", img_input);
cv::Mat img_mask;
cv::Mat img_bkgmodel;
try
{
bgs->process(img_input, img_mask, img_bkgmodel); // by default, it shows automatically the foreground mask image
//if(!img_mask.empty())
// cv::imshow("Foreground", img_mask);
// do something
}
catch (std::exception& e)
{
std::cout << "Exception occurred" << std::endl;
std::cout << e.what() << std::endl;
}
key = cv::waitKey(33);
cerr<<"archive_read_open_filename: error: "<< archive_error_string(archive) <<" will abort"<< endl;
exit(1);
// fail("archive_read_open_filename()",
// archive_error_string(a), r);
}
int counter = 0;
for (;;) {
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);
// fail("archive_read_next_header()",
// archive_error_string(a), 1);
}
//msg("x ");
///char *buffer = malloc (sizeof(char) * 400000);
//Mat img =Mat::zeros(1936,1456,CV_8UC3);
//new way
//std::ifstream file("img.jpg");
std::vector<char> vec;
// file >> std::noskipws;
// std::copy(std::istream_iterator<char>(file), std::istream_iterator<char>(), std::back_inserter(data));
const char *fileNamePtr = archive_entry_pathname(entry);
std::string filename(fileNamePtr,strlen(fileNamePtr) );
cout << "fileName: "<< filename <<endl;
//TODO we should test what file we have, this filenumber n = n - 1 ??
//msg(archive_entry_pathname(entry));
r = archive_write_header(ext, entry);
if (r != ARCHIVE_OK)
{
cerr<<"archive_write_header() error: "<< archive_error_string(ext)<<endl;
}
else
{
vec = copyDataInBuffer(archive);//no // we cast the data pointer to void, because we know what we do ??
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);
// fail("archive_write_finish_entry()",
// archive_error_string(ext), 1);
}
}
//we read the image buffer as a jpg picture and decode it
Mat img2 = imdecode(Mat(vec), 1);
// //here we could use our image
// //we show what we got
// namedWindow( "Display window", WINDOW_AUTOSIZE );// Create a window for display.
// imshow( "Display window", img2 ); // Show our image inside it.
// cv::imwrite("foo.jpg", img2);
// //msg("\n");
if(counter > 10) exit(1);
counter ++;
// waitKey(0);
}
archive_read_close(archive);
archive_read_free(archive);
archive_write_close(ext);
archive_write_free(ext);
return 0;
}
static std::vector<char> copyDataInBuffer(struct archive *aw)
{
int r;
const void *buff;
std::vector<char> vec;
size_t size;
#if ARCHIVE_VERSION_NUMBER >= 3000000
int64_t offset;
#else
off_t offset;
#endif
// unsigned int myOffsetCounter = 0;
// int counterIteration = 0;
// ofstream myfile;
// myfile.open ("tmpPicture.jpg", ios::out | ios::binary);
// if (!myfile.is_open())
// return vec;
for (;;) {
r = archive_read_data_block(aw, &buff, &size, &offset);
if (r == ARCHIVE_EOF)
{
return vec; // everything fine, were are just at the end
}
std::cout << "Press 'q' to exit, or anything else to move to the next algorithm:" << std::endl;
key = cv::waitKey(0);
if (key == 'q')
break;
if (r != ARCHIVE_OK)
{
cerr << "error during read archive "<<endl;
return vec;
}
//r = archive_write_data_block(aw, buff, size, offset);
//we mem copy the buffer
//cout <<counterIteration++<< " offset: "<< offset<< " size: "<< size<<endl;
cv::destroyAllWindows();
}
//memcpy( &buffer[myOffsetCounter], (char*) buff, size * sizeof( char ) );
//we simply copy it to the end
//std::copy ( buff, buff+size, vec.end() );
//myOffsetCounter += size;
return 0;
//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]);
}
//myfile.write ((char*)buff,size);
// if (r != ARCHIVE_OK) {
// warn("archive_write_data_block()",
// archive_error_string(aw));
// return (r);
// }
}
//myfile.close();
return vec;
}
//static void
//msg(const char *m)
//{
// write(1, m, strlen(m));
//}
//static void
//errmsg(const char *m)
//{
// write(2, m, strlen(m));
//}
//static void
//warn(const char *f, const char *m)
//{
// errmsg(f);
// errmsg(" failed: ");
// errmsg(m);
// errmsg("\n");
//}
//static void
//fail(const char *f, const char *m, int r)
//{
// warn(f, m);
// exit(r);
//}
### BGS Library Examples
## BGSLibrary
#### CMake on Linux or MacOS
```
cd build
cmake ..
make
cd ..
```
thomas fork of
for the records of 2018 and preprocessed records please use:
tag v.0.9.9 alias: 415d967eccf7b8f541cb647c99a2f26be2f3ddc7
i updated the version to include the lense correction in 2019
A Background Subtraction Library
[![bgslibrary](http://i.giphy.com/5A94AZahSIVOw.gif)](https://youtu.be/_UbERwuQ0OU)
Last Page Update: **18/03/2017**
Latest Library Version: **2.0.0** (see [Release Notes](https://github.com/andrewssobral/bgslibrary/wiki/Release-notes) for more info)
The **BGSLibrary** was developed by [Andrews Sobral](http://andrewssobral.wixsite.com/home) and provides an easy-to-use C++ framework based on [OpenCV](http://www.opencv.org/) to perform foreground-background separation in videos. The bgslibrary is compatible with OpenCV 2.x and 3.x, and compiles under Windows, Linux, and Mac OS X. Currently the library contains **40** algorithms. The source code is available under [GNU GPLv3 license](https://www.gnu.org/licenses/gpl-3.0.en.html), the library is free and open source for academic purposes.
***Note: The [opencv3](https://github.com/andrewssobral/bgslibrary/tree/opencv3) branch will be deprecated.***
* [List of available algorithms](https://github.com/andrewssobral/bgslibrary/wiki/List-of-available-algorithms)
* [Algorithms benchmark](https://github.com/andrewssobral/bgslibrary/wiki/Algorithms-benchmark)
* [Which algorithms really matter?](https://github.com/andrewssobral/bgslibrary/wiki/Which-algorithms-really-matter%3F)
* [Library architecture](https://github.com/andrewssobral/bgslibrary/wiki/Library-architecture)
* Installation instructions
* * [Windows installation](https://github.com/andrewssobral/bgslibrary/wiki/Installation-instructions---Windows)
* * [Ubuntu / OS X installation](https://github.com/andrewssobral/bgslibrary/wiki/Installation-instructions-Ubuntu-or-OSX)
* Graphical User Interface:
#### Running
* * [C++ MFC (Microsoft Foundation Class)](https://github.com/andrewssobral/bgslibrary/wiki/Graphical-User-Interface:-MFC)
* * [Java](https://github.com/andrewssobral/bgslibrary/wiki/Graphical-User-Interface:-Java)
* [Docker images](https://github.com/andrewssobral/bgslibrary/wiki/Docker-images)
* [How to integrate BGSLibrary in your own CPP code](https://github.com/andrewssobral/bgslibrary/wiki/How-to-integrate-BGSLibrary-in-your-own-CPP-code)
* [How to contribute](https://github.com/andrewssobral/bgslibrary/wiki/How-to-contribute)
* [List of collaborators](https://github.com/andrewssobral/bgslibrary/wiki/List-of-collaborators)
* [Release notes](https://github.com/andrewssobral/bgslibrary/wiki/Release-notes)
Citation
--------
If you use this library for your publications, please cite it as:
```
chmod +x *.sh
./run_demo.sh
./run_demo2.sh
@inproceedings{bgslibrary,
author = {Sobral, Andrews},
title = {{BGSLibrary}: An OpenCV C++ Background Subtraction Library},
booktitle = {IX Workshop de Visão Computacional (WVC'2013)},
address = {Rio de Janeiro, Brazil},
year = {2013},
month = {Jun},
url = {https://github.com/andrewssobral/bgslibrary}
}
```
or
A chapter about the BGSLibrary has been published in the handbook on [Background Modeling and Foreground Detection for Video Surveillance](https://sites.google.com/site/backgroundmodeling/).
```
@incollection{bgslibrarychapter,
author = {Sobral, Andrews and Bouwmans, Thierry},
title = {BGS Library: A Library Framework for Algorithm’s Evaluation in Foreground/Background Segmentation},
booktitle = {Background Modeling and Foreground Detection for Video Surveillance},
publisher = {CRC Press, Taylor and Francis Group.}
year = {2014},
}
```
# using a web camera
./build/bgs_demo
# using a video file
./build/bgs_demo ../dataset/video.avi
# using a sequence of images
./build/bgs_demo2 ../dataset/frames
```
Download PDF:
* Sobral, Andrews. BGSLibrary: An OpenCV C++ Background Subtraction Library. IX Workshop de Visão Computacional (WVC'2013), Rio de Janeiro, Brazil, Jun. 2013. ([PDF](http://www.researchgate.net/publication/257424214_BGSLibrary_An_OpenCV_C_Background_Subtraction_Library) in brazilian-portuguese containing an english abstract).
* Sobral, Andrews; Bouwmans, Thierry. "BGS Library: A Library Framework for Algorithm’s Evaluation in Foreground/Background Segmentation". Chapter on the handbook "Background Modeling and Foreground Detection for Video Surveillance", CRC Press, Taylor and Francis Group, 2014. ([PDF](http://www.researchgate.net/publication/257424214_BGSLibrary_An_OpenCV_C_Background_Subtraction_Library) in english).
Some references
---------------
Some algorithms of the BGSLibrary were used successfully in the following papers:
* (2014) Sobral, Andrews; Vacavant, Antoine. A comprehensive review of background subtraction algorithms evaluated with synthetic and real videos. Computer Vision and Image Understanding (CVIU), 2014. ([Online](http://dx.doi.org/10.1016/j.cviu.2013.12.005)) ([PDF](http://www.researchgate.net/publication/259340906_A_comprehensive_review_of_background_subtraction_algorithms_evaluated_with_synthetic_and_real_videos))
* (2013) Sobral, Andrews; Oliveira, Luciano; Schnitman, Leizer; Souza, Felippe. (**Best Paper Award**) Highway Traffic Congestion Classification Using Holistic Properties. In International Conference on Signal Processing, Pattern Recognition and Applications (SPPRA'2013), Innsbruck, Austria, Feb 2013. ([Online](http://dx.doi.org/10.2316/P.2013.798-105)) ([PDF](http://www.researchgate.net/publication/233427564_HIGHWAY_TRAFFIC_CONGESTION_CLASSIFICATION_USING_HOLISTIC_PROPERTIES))
Videos
------
<p align="center">
<a href="https://www.youtube.com/watch?v=_UbERwuQ0OU" target="_blank">
<img src="https://sites.google.com/site/andrewssobral/bgslibrary_qt_gui_video.png?width=600" border="0" />
</a>
</p>
<p align="center">
<a href="https://www.youtube.com/watch?v=Ccqa9KBO9_U" target="_blank">
<img src="https://sites.google.com/site/andrewssobral/bgslibrary_youtube.png?width=600" border="0" />
</a>
</p>
/*
This file is part of BGSLibrary.
BGSLibrary is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
BGSLibrary is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with BGSLibrary. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Tapter.h"
using namespace bgslibrary::algorithms;
Tapter::Tapter() :
sensitivity(75), trainingSensitivity(245), learningRate(62), trainingLearningRate(255), trainingSteps(55)
{
std::cout << "Tapter()" << std::endl;
setup("./config/Tapter.xml");
// frameCounter = 0;
// //inputPath = ".";
// //centerFile = ".";
// outputPath = ".";
// flagWrite = -1;
// writeDbgPic = -1;
}
Tapter::~Tapter()
{
delete m_pBGModel;
std::cout << "~Tapter()" << std::endl;
}
//void Tapter::setFlagWrite(short flag)
//{
// flagWrite = flag;
//}
//void Tapter::setFlagWriteDBGpic(short flag)
//{
// writeDbgPic = flag;
//}
//void Tapter::setPathOut(std::string outPath)
//{
// outputPath = outPath;
//}
//void Tapter::setLearningRate(int rate)
//{
// learningRate = rate;
//}
//void Tapter::setInitialFrameCounter(int counter)
//{
// frameCounter = counter;
//}
void Tapter::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
{
//! continue the normal
init(img_input, img_output, img_bgmodel);
IplImage *frame = new IplImage(img_input);
if (firstTime)
{
int w = cvGetSize(frame).width;
int h = cvGetSize(frame).height;
m_pBGModel = new BGModelSom(w, h);
m_pBGModel->InitModel(frame);
}
m_pBGModel->setBGModelParameter(0, sensitivity);
m_pBGModel->setBGModelParameter(1, trainingSensitivity);
m_pBGModel->setBGModelParameter(2, learningRate);
m_pBGModel->setBGModelParameter(3, trainingLearningRate);
m_pBGModel->setBGModelParameter(5, trainingSteps);
m_pBGModel->UpdateModel(frame);
img_foreground = cv::cvarrToMat(m_pBGModel->GetFG());
img_background = cv::cvarrToMat(m_pBGModel->GetBG());
#ifndef MEX_COMPILE_FLAG
if (showOutput)
{
cv::imshow("SOM Mask", img_foreground);
cv::imshow("SOM Model", img_background);
}
#endif
img_foreground.copyTo(img_output);
img_background.copyTo(img_bgmodel);
delete frame;
firstTime = false;
}
void Tapter::saveConfig()
{
CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
cvWriteInt(fs, "sensitivity", sensitivity);
cvWriteInt(fs, "trainingSensitivity", trainingSensitivity);
cvWriteInt(fs, "learningRate", learningRate);
cvWriteInt(fs, "trainingLearningRate", trainingLearningRate);
cvWriteInt(fs, "trainingSteps", trainingSteps);
cvWriteInt(fs, "showOutput", showOutput);
cvReleaseFileStorage(&fs);
}
void Tapter::loadConfig()
{
CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
sensitivity = cvReadIntByName(fs, nullptr, "sensitivity", 75);
trainingSensitivity = cvReadIntByName(fs, nullptr, "trainingSensitivity", 245);
learningRate = cvReadIntByName(fs, nullptr, "learningRate", 62);
trainingLearningRate = cvReadIntByName(fs, nullptr, "trainingLearningRate", 255);
trainingSteps = cvReadIntByName(fs, nullptr, "trainingSteps", 55);
showOutput = cvReadIntByName(fs, 0, "showOutput", true);
cvReleaseFileStorage(&fs);
}
/*
This file is part of BGSLibrary.
BGSLibrary is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
BGSLibrary is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with BGSLibrary. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
//std lib
#include <sstream>
#include <vector>
//opencv
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
//bgslib
#include "lb/BGModelSom.h"
#include "IBGS.h"
#include "ttoolbox.h"
//#define MC_SHOW_STEP_ANALYSE
using namespace lb_library;
using namespace lb_library::AdaptiveSOM;
using namespace cv;
using namespace std;
namespace bgslibrary
{
namespace algorithms
{
class Tapter : public IBGS
{
private:
BGModel* m_pBGModel;
int sensitivity;
int trainingSensitivity;
int learningRate;
int trainingLearningRate;
int trainingSteps;
// int frameCounter; //
// std::string inputPath;
//// std::string centerFile;
// short flagWrite;
// short writeDbgPic;
// std::string outputPath;
public:
Tapter();
~Tapter();
void setInitialFrameCounter(int counter);
// void setPaths(std::string inPath,std::string outPath);
void setPathOut(std::string outPath);
// //! 1 is on
// //! other no write
// void setFlagWrite(short flag);
// //! set learning rate
// void setLearningRate(int rate);
// //! 1 is on
// //! other no write
// void setFlagWriteDBGpic(short flag);
void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
private:
void saveConfig();
void loadConfig();
};
}
}
#include "ttoolbox.h"
std::string TToolBox::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 TToolBox::getFileName(int i)
{
std::string fileName =std::string ( std::string ("/data/")+ mNzero(i) + std::string (".jpg"));
return fileName;
}
std::vector<std::vector<cv::Point>> TToolBox::applyCannyEdgeAndCalcCountours(cv::Mat imgSource, double threshholdMin, double threshholdMax, int apertureSize)
{
cv::Mat imgCannyEdge;
std::vector<std::vector<cv::Point> > contours;
std::vector<cv::Vec4i> hierarchy;
//! 2 make a copy
cv::Mat imgBinary = imgSource.clone();
//imgMarkBinary = Scalar(255,255,255); //fill white
//! 3 apply binary filter not reduce noise
//method to threshold important changes
int binaryThreshold = 80; //TODO as parameter
imgBinary = imgSource > binaryThreshold;
//! 4 smooth with gaussian filter to suppress no connected lines
//add a gaussian filter //see http://docs.opencv.org/2.4/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.html
cv::Mat imgSmoothed = imgBinary.clone();
int exclusPara3 = 3; //TODO as parameter
cv::GaussianBlur(imgBinary,imgSmoothed,cv::Size(exclusPara3,exclusPara3),0); //0 = BORDER_CONSTANT
//! 5 we make the canny edge detect
// Detect edges using canny
cv::Canny( imgSmoothed, imgCannyEdge, threshholdMin, threshholdMax, apertureSize );
// Find contours, use RETR_EXTERNAL ignore inner child structures, TREE more usefull ?
cv::findContours( imgCannyEdge, contours, hierarchy, cv::RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );
#define MC_SHOW_STEP_ANALYSE
#ifdef MC_SHOW_STEP_ANALYSE
// Draw contours on extra mat
cv::Mat imgContour = cv::Mat::zeros( imgCannyEdge.size(), CV_8UC3 );
imgContour = cv::Scalar(255,255,255); //fille the picture
cv::RNG rng(232323);
for( size_t i = 0; i< contours.size(); i++ )
{
//random color
cv::Scalar color = cv::Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
//contour
cv::drawContours( imgContour, contours, i, color, 1, cv::LINE_AA, hierarchy, 0, cv::Point() );
}
cv::String outpath= "/homes/tb55xemi/work/dev/bgslibrary-bgslib_qtgui_2.0.0/build/test0815/results";
std::ostringstream convert;
convert << outpath << "test_countour_canny_edge.jpg";
cv::imwrite(convert.str().c_str(), imgContour);
#endif
// return minRect;
return contours;
}
cv::Mat TToolBox::cropImageCircle(cv::Mat image, int x, int y, int r)
{
// Your Hough circle
cv::Vec3f circ(x,y,r);
// Draw the mask: white circle on black background
cv::Mat1b mask(image.size(), uchar(0));
cv::circle(mask, cv::Point(circ[0], circ[1]), circ[2], cv::Scalar(255), CV_FILLED);
//NO CROP NEEDED
// Compute the bounding box
//Rect bbox(circ[0] - circ[2], circ[1] - circ[2], 2 * circ[2], 2 * circ[2]);
// Create a black image
cv::Mat res = cv::Mat::zeros( image.size(), CV_8UC3 );
res = cv::Scalar(0,0,0); //fill with black color
// Copy only the image under the white circle to black image
image.copyTo(res, mask);
// Crop according to the roi
//res = res(bbox);
return res;
}
int TToolBox::checkFileCorrupted(std::string filename)
{
int retVal = 1;//is as long Corrupted as we dont find it in another way
char command[] = "identify ";
const char *fileNameArr = filename.c_str();
char command2[] = " > /dev/null 2>&1 ; echo $?";
char *cmd = new char[std::strlen(command)+std::strlen(fileNameArr) + std::strlen(command2) +1];
//we put all peaces together
std::strcpy(cmd,command);
std::strcat(cmd,fileNameArr);
std::strcat(cmd,command2);
//std:: cout <<"cmd is: "<< cmd<< std::endl;
//execute the command
std::string result = TToolBox::execCMD((const char* ) cmd);
//std:: cout <<"results is: "<< result<< std::endl;
if(!result.empty())
{
try {
retVal = std::stoi(result);
}
catch(std::invalid_argument& e)
{
std::cerr <<"wrong argument for stoi"<<std::endl;
// if no conversion could be performed
}
catch (const std::exception& e)
{
std::cerr <<"error during use stoi"<<std::endl;
}
}//end if
return retVal;
}
std::string TToolBox::execCMD(const char* cmd) {
std::array<char, 128> buffer;
std::string result;
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
if (!pipe) throw std::runtime_error("popen() failed!");
while (!feof(pipe.get())) {
if (fgets(buffer.data(), 128, pipe.get()) != nullptr)
result += buffer.data();
//std::cout<<result<<std::endl;
}
//std::cout<<"call: " <<result<<std::endl;
return result;
}
#ifndef TTOOLBOX_H
#define TTOOLBOX_H
//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 <sstream>
#include <cstdio>
#include <memory>
#include <stdexcept>
#include <string>
#include <array>
//open cv
#include "opencv2/core/core.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
class TToolBox
{
public:
//! return the number as string with 10 digits and '0' leading ones
static std::string mNzero(int i);
//! return string plus data path and jpg suffix
static std::string getFileName(int i);
//! returns a image, which is resulting circle
//! return roi of image which is cloned
//! without resize the image
//! will fill rest outer bound black
static cv::Mat cropImageCircle(cv::Mat image, int x, int y, int r);
//! canny edge detect
static std::vector<std::vector<cv::Point>> applyCannyEdgeAndCalcCountours(cv::Mat imgSource, double threshholdMin, double threshholdMax, int apertureSize);
//! will test if file is not corrupted
//! @return 1 if corrupted
//! @return 0 if not
static int checkFileCorrupted(std::string filename);
//! will try to execute the cmd on the bash
static std::string execCMD(const char* cmd);
};
#endif // TTOOLBOX_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment