diff --git a/.gitignore b/.gitignore
index 3f5e0f7bbb092306784a68a8dd9a3fdf95c25e08..f1d9cb4f152103523a763b0ee6d6d67515a8239c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
 etc/
 build_*/
-binaries/
+dataset_*/
+binaries*/
 java_gui/dist/
 java_gui/build/
 java_gui/bgslibrary.exe
@@ -9,4 +10,5 @@ qt_gui/
 fet/etc/
 *.exe
 *.pdb
-*.suo
\ No newline at end of file
+*.suo
+*.dll
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d8e60dae5f33cad38be88f2d074d9d0ddbdc676c..6a01cce7f22aefc347789b441115adb3c734e168 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,24 +2,44 @@ cmake_minimum_required(VERSION 2.8)
 
 project(bgslibrary)
 
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
+# 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")
+endif(UNIX)
+
 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
 #set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules)
 
-set( bgs_out_dir "." )
+# compilation mode setup
+set(CMAKE_BUILD_TYPE Release)
+#set(CMAKE_BUILD_TYPE Debug)
+
+if(WIN32)
+	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 ".")
 # First for the generic no-config case (e.g. with mingw)
-set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${bgs_out_dir} )
-set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${bgs_out_dir} )
-set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${bgs_out_dir} )
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${bgs_out_dir})
+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} )
-endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES )
-
-IF(UNIX)
+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})
+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)
 
@@ -30,6 +50,7 @@ IF(UNIX)
 	#ADD_DEFINITIONS(-Wconversion -Wfloat-equal)
 endif(UNIX)
 
+set(OpenCV_STATIC OFF)
 find_package(OpenCV REQUIRED)
 
 message(STATUS "OpenCV library status:")
@@ -37,24 +58,50 @@ 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}")
-endif()
+# if(${OpenCV_VERSION} VERSION_EQUAL 3 OR ${OpenCV_VERSION} VERSION_GREATER 3)
+# 	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}")
 endif()
 
-file(GLOB sources FrameProcessor.cpp PreProcessor.cpp VideoAnalysis.cpp  VideoCapture.cpp)
-file(GLOB main Main.cpp)
+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)
 
 # list(REMOVE_ITEM sources ${demo} ${demo2})
 
 file(GLOB_RECURSE analysis_src package_analysis/*.cpp)
-file(GLOB_RECURSE bgs_src package_bgs/*.cpp package_bgs/*.c)
-file(GLOB_RECURSE bgs_include package_bgs/*.h)
+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})
+endif()
 
 # GMG is not available in older OpenCV versions
 if(${OpenCV_VERSION} VERSION_LESS 2.4.3)
@@ -62,10 +109,16 @@ if(${OpenCV_VERSION} VERSION_LESS 2.4.3)
 	list(REMOVE_ITEM bgs_src ${gmg})
 endif()
 
-include_directories(${CMAKE_SOURCE_DIR})
-
-add_library(libbgs STATIC ${sources} ${bgs_src} ${analysis_src})
-target_link_libraries(libbgs ${OpenCV_LIBS})
+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")
@@ -83,7 +136,7 @@ target_link_libraries(bgs_demo ${OpenCV_LIBS} libbgs)
 add_executable(bgs_demo2 ${demo2})
 target_link_libraries(bgs_demo2 ${OpenCV_LIBS} libbgs)
 
-INSTALL(TARGETS libbgs
+install(TARGETS libbgs
 	bgslibrary
 	RUNTIME DESTINATION bin COMPONENT app
 	LIBRARY DESTINATION lib COMPONENT runtime
diff --git a/Demo.cpp b/Demo.cpp
index 61561be797917b2b8dffb8f637f679df8c6e1c26..fec54d85fe804e6bece7ec0bd1e6d5c2b7fe7626 100644
--- a/Demo.cpp
+++ b/Demo.cpp
@@ -17,178 +17,98 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 #include <iostream>
 #include <opencv2/opencv.hpp>
 
-
-#include "package_bgs/FrameDifferenceBGS.h"
-#include "package_bgs/StaticFrameDifferenceBGS.h"
-#include "package_bgs/WeightedMovingMeanBGS.h"
-#include "package_bgs/WeightedMovingVarianceBGS.h"
-#include "package_bgs/MixtureOfGaussianV1BGS.h"
-#include "package_bgs/MixtureOfGaussianV2BGS.h"
-#include "package_bgs/AdaptiveBackgroundLearning.h"
-#include "package_bgs/AdaptiveSelectiveBackgroundLearning.h"
-
-#if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >= 4 && CV_SUBMINOR_VERSION >= 3
-#include "package_bgs/GMG.h"
-#endif
-
-#include "package_bgs/dp/DPAdaptiveMedianBGS.h"
-#include "package_bgs/dp/DPGrimsonGMMBGS.h"
-#include "package_bgs/dp/DPZivkovicAGMMBGS.h"
-#include "package_bgs/dp/DPMeanBGS.h"
-#include "package_bgs/dp/DPWrenGABGS.h"
-#include "package_bgs/dp/DPPratiMediodBGS.h"
-#include "package_bgs/dp/DPEigenbackgroundBGS.h"
-#include "package_bgs/dp/DPTextureBGS.h"
-
-#include "package_bgs/tb/T2FGMM_UM.h"
-#include "package_bgs/tb/T2FGMM_UV.h"
-#include "package_bgs/tb/T2FMRF_UM.h"
-#include "package_bgs/tb/T2FMRF_UV.h"
-#include "package_bgs/tb/FuzzySugenoIntegral.h"
-#include "package_bgs/tb/FuzzyChoquetIntegral.h"
-
-#include "package_bgs/lb/LBSimpleGaussian.h"
-#include "package_bgs/lb/LBFuzzyGaussian.h"
-#include "package_bgs/lb/LBMixtureOfGaussians.h"
-#include "package_bgs/lb/LBAdaptiveSOM.h"
-#include "package_bgs/lb/LBFuzzyAdaptiveSOM.h"
-
-#include "package_bgs/ck/LbpMrf.h"
-#include "package_bgs/jmo/MultiLayerBGS.h"
-// The PBAS algorithm was removed from BGSLibrary because it is
-// based on patented algorithm ViBE
-// http://www2.ulg.ac.be/telecom/research/vibe/
-//#include "package_bgs/pt/PixelBasedAdaptiveSegmenter.h"
-#include "package_bgs/av/VuMeter.h"
-#include "package_bgs/ae/KDE.h"
-#include "package_bgs/db/IndependentMultimodalBGS.h"
-#include "package_bgs/sjn/SJN_MultiCueBGS.h"
-#include "package_bgs/bl/SigmaDeltaBGS.h"
-
-#include "package_bgs/pl/SuBSENSE.h"
-#include "package_bgs/pl/LOBSTER.h"
+#include "package_bgs/bgslibrary.h"
 
 int main(int argc, char **argv)
 {
   std::cout << "Using OpenCV " << CV_MAJOR_VERSION << "." << CV_MINOR_VERSION << "." << CV_SUBMINOR_VERSION << std::endl;
 
-  CvCapture *capture = 0;
-  int resize_factor = 100;
+  VideoCapture capture;
 
-  if(argc > 1)
+  if (argc > 1)
   {
     std::cout << "Openning: " << argv[1] << std::endl;
-    capture = cvCaptureFromAVI(argv[1]);
+    capture.open(argv[1]);
   }
   else
-  {
-    capture = cvCaptureFromCAM(0);
-    resize_factor = 50; // set size = 50% of original image
-  }
+    capture.open(0);
 
-  if(!capture)
+  if (!capture.isOpened())
   {
     std::cerr << "Cannot initialize video!" << std::endl;
     return -1;
   }
-  
-  IplImage *frame_aux = cvQueryFrame(capture);
-  IplImage *frame = cvCreateImage(cvSize((int)((frame_aux->width*resize_factor)/100) , (int)((frame_aux->height*resize_factor)/100)), frame_aux->depth, frame_aux->nChannels);
-  cvResize(frame_aux, frame);
 
   /* Background Subtraction Methods */
   IBGS *bgs;
 
-  /*** Default Package ***/
-  bgs = new FrameDifferenceBGS;
-  //bgs = new StaticFrameDifferenceBGS;
-  //bgs = new WeightedMovingMeanBGS;
-  //bgs = new WeightedMovingVarianceBGS;
-  //bgs = new MixtureOfGaussianV1BGS;
-  //bgs = new MixtureOfGaussianV2BGS;
+  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;
-  
-  /*** DP Package (thanks to Donovan Parks) ***/
-  //bgs = new DPAdaptiveMedianBGS;
-  //bgs = new DPGrimsonGMMBGS;
-  //bgs = new DPZivkovicAGMMBGS;
-  //bgs = new DPMeanBGS;
-  //bgs = new DPWrenGABGS;
-  //bgs = new DPPratiMediodBGS;
-  //bgs = new DPEigenbackgroundBGS;
-  //bgs = new DPTextureBGS;
-
-  /*** TB Package (thanks to Thierry Bouwmans, Fida EL BAF and Zhenjie Zhao) ***/
+  //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;
-
-  /*** JMO Package (thanks to Jean-Marc Odobez) ***/
-  //bgs = new MultiLayerBGS;
-
-  /*** PT Package (thanks to Martin Hofmann, Philipp Tiefenbacher and Gerhard Rigoll) ***/
+  //bgs = new MultiLayer;
   //bgs = new PixelBasedAdaptiveSegmenter;
-
-  /*** LB Package (thanks to Laurence Bender) ***/
   //bgs = new LBSimpleGaussian;
   //bgs = new LBFuzzyGaussian;
   //bgs = new LBMixtureOfGaussians;
   //bgs = new LBAdaptiveSOM;
   //bgs = new LBFuzzyAdaptiveSOM;
-
-  /*** LBP-MRF Package (thanks to Csaba Kertész) ***/
-  //bgs = new LbpMrf;
-
-  /*** AV Package (thanks to Lionel Robinault and Antoine Vacavant) ***/
+  //bgs = new LBP_MRF;
   //bgs = new VuMeter;
-
-  /*** EG Package (thanks to Ahmed Elgammal) ***/
   //bgs = new KDE;
-  
-  /*** DB Package (thanks to Domenico Daniele Bloisi) ***/
-  //bgs = new IndependentMultimodalBGS;
-
-  /*** SJN Package (thanks to SeungJong Noh) ***/
-  //bgs = new SJN_MultiCueBGS;
-
-  /*** BL Package (thanks to Benjamin Laugraud) ***/
-  //bgs = new SigmaDeltaBGS;
-
-  /*** PL Package (thanks to Pierre-Luc) ***/
-  //bgs = new SuBSENSEBGS();
-  //bgs = new LOBSTERBGS();
+  //bgs = new IndependentMultimodal;
+  //bgs = new MultiCue;
+  //bgs = new SigmaDelta;
+  //bgs = new SuBSENSE;
+  //bgs = new LOBSTER;
+  //bgs = new PAWCS;
+  //bgs = new TwoPoints;
+  //bgs = new ViBe;
 
   int key = 0;
-  while(key != 'q')
+  cv::Mat img_input;
+  while (key != 'q')
   {
-    frame_aux = cvQueryFrame(capture);
-    if(!frame_aux) break;
+    capture >> img_input;
+    if (img_input.empty()) break;
 
-    cvResize(frame_aux, frame);
-    
-    cv::Mat img_input(frame);
     cv::imshow("input", img_input);
 
     cv::Mat img_mask;
     cv::Mat img_bkgmodel;
     bgs->process(img_input, img_mask, img_bkgmodel); // by default, it shows automatically the foreground mask image
-    
+
     //if(!img_mask.empty())
     //  cv::imshow("Foreground", img_mask);
     //  do something
-    
+
     key = cvWaitKey(33);
   }
 
   delete bgs;
 
+  capture.release();
   cvDestroyAllWindows();
-  cvReleaseCapture(&capture);
 
   return 0;
 }
diff --git a/Demo.py b/Demo.py
new file mode 100644
index 0000000000000000000000000000000000000000..71bc35232e73fe4ff54b70d40d3690b274c31af7
--- /dev/null
+++ b/Demo.py
@@ -0,0 +1,84 @@
+import numpy as np
+import cv2
+import libbgs
+
+## BGS Library algorithms
+bgs = libbgs.FrameDifference()
+#bgs = libbgs.StaticFrameDifference()
+#bgs = libbgs.AdaptiveBackgroundLearning()
+#bgs = libbgs.AdaptiveSelectiveBackgroundLearning()
+#bgs = libbgs.DPAdaptiveMedian()
+#bgs = libbgs.DPEigenbackground()
+#bgs = libbgs.DPGrimsonGMM()
+#bgs = libbgs.DPMean()
+#bgs = libbgs.DPPratiMediod()
+#bgs = libbgs.DPTexture()
+#bgs = libbgs.DPWrenGA()
+#bgs = libbgs.DPZivkovicAGMM()
+#bgs = libbgs.FuzzyChoquetIntegral()
+#bgs = libbgs.FuzzySugenoIntegral()
+#bgs = libbgs.GMG() # if opencv 2.x
+#bgs = libbgs.IndependentMultimodal()
+#bgs = libbgs.KDE()
+#bgs = libbgs.KNN() # if opencv 3.x
+#bgs = libbgs.LBAdaptiveSOM()
+#bgs = libbgs.LBFuzzyAdaptiveSOM()
+#bgs = libbgs.LBFuzzyGaussian()
+#bgs = libbgs.LBMixtureOfGaussians()
+#bgs = libbgs.LBSimpleGaussian()
+#bgs = libbgs.LBP_MRF()
+#bgs = libbgs.LOBSTER()
+#bgs = libbgs.MixtureOfGaussianV1() # if opencv 2.x
+#bgs = libbgs.MixtureOfGaussianV2()
+#bgs = libbgs.MultiCue()
+#bgs = libbgs.MultiLayer()
+#bgs = libbgs.PAWCS()
+#bgs = libbgs.PixelBasedAdaptiveSegmenter()
+#bgs = libbgs.SigmaDelta()
+#bgs = libbgs.SuBSENSE()
+#bgs = libbgs.T2FGMM_UM()
+#bgs = libbgs.T2FGMM_UV()
+#bgs = libbgs.T2FMRF_UM()
+#bgs = libbgs.T2FMRF_UV()
+#bgs = libbgs.VuMeter()
+#bgs = libbgs.WeightedMovingMean()
+#bgs = libbgs.WeightedMovingVariance()
+#bgs = libbgs.TwoPoints()
+#bgs = libbgs.ViBe()
+
+video_file = "dataset/video.avi"
+
+capture = cv2.VideoCapture(video_file)
+while not capture.isOpened():
+	capture = cv2.VideoCapture(video_file)
+	cv2.waitKey(1000)
+	print "Wait for the header"
+
+pos_frame = capture.get(cv2.cv.CV_CAP_PROP_POS_FRAMES)
+while True:
+	flag, frame = capture.read()
+	
+	if flag:
+		cv2.imshow('video', frame)
+		pos_frame = capture.get(cv2.cv.CV_CAP_PROP_POS_FRAMES)
+		#print str(pos_frame)+" frames"
+		
+		img_output = bgs.apply(frame)
+		img_bgmodel = bgs.getBackgroundModel();
+		
+		cv2.imshow('img_output', img_output)
+		cv2.imshow('img_bgmodel', img_bgmodel)
+
+	else:
+		capture.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, pos_frame-1)
+		print "frame is not ready"
+		cv2.waitKey(1000)
+		# break
+	
+	if 0xFF & cv2.waitKey(10) == 27:
+		break
+	
+	if capture.get(cv2.cv.CV_CAP_PROP_POS_FRAMES) == capture.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT):
+		break
+
+cv2.destroyAllWindows()
diff --git a/Demo2.cpp b/Demo2.cpp
index fe95c525feec74bb72e92234a6bd6d2d1fe47c38..22c6ffc36d5100967cfd2873b82f0bdb13b61268 100644
--- a/Demo2.cpp
+++ b/Demo2.cpp
@@ -17,56 +17,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 #include <iostream>
 #include <opencv2/opencv.hpp>
 
-
-#include "package_bgs/FrameDifferenceBGS.h"
-#include "package_bgs/StaticFrameDifferenceBGS.h"
-#include "package_bgs/WeightedMovingMeanBGS.h"
-#include "package_bgs/WeightedMovingVarianceBGS.h"
-#include "package_bgs/MixtureOfGaussianV1BGS.h"
-#include "package_bgs/MixtureOfGaussianV2BGS.h"
-#include "package_bgs/AdaptiveBackgroundLearning.h"
-#include "package_bgs/AdaptiveSelectiveBackgroundLearning.h"
-
-#if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >= 4 && CV_SUBMINOR_VERSION >= 3
-#include "package_bgs/GMG.h"
-#endif
-
-#include "package_bgs/dp/DPAdaptiveMedianBGS.h"
-#include "package_bgs/dp/DPGrimsonGMMBGS.h"
-#include "package_bgs/dp/DPZivkovicAGMMBGS.h"
-#include "package_bgs/dp/DPMeanBGS.h"
-#include "package_bgs/dp/DPWrenGABGS.h"
-#include "package_bgs/dp/DPPratiMediodBGS.h"
-#include "package_bgs/dp/DPEigenbackgroundBGS.h"
-#include "package_bgs/dp/DPTextureBGS.h"
-
-#include "package_bgs/tb/T2FGMM_UM.h"
-#include "package_bgs/tb/T2FGMM_UV.h"
-#include "package_bgs/tb/T2FMRF_UM.h"
-#include "package_bgs/tb/T2FMRF_UV.h"
-#include "package_bgs/tb/FuzzySugenoIntegral.h"
-#include "package_bgs/tb/FuzzyChoquetIntegral.h"
-
-#include "package_bgs/lb/LBSimpleGaussian.h"
-#include "package_bgs/lb/LBFuzzyGaussian.h"
-#include "package_bgs/lb/LBMixtureOfGaussians.h"
-#include "package_bgs/lb/LBAdaptiveSOM.h"
-#include "package_bgs/lb/LBFuzzyAdaptiveSOM.h"
-
-#include "package_bgs/ck/LbpMrf.h"
-#include "package_bgs/jmo/MultiLayerBGS.h"
-// The PBAS algorithm was removed from BGSLibrary because it is
-// based on patented algorithm ViBE
-// http://www2.ulg.ac.be/telecom/research/vibe/
-//#include "package_bgs/pt/PixelBasedAdaptiveSegmenter.h"
-#include "package_bgs/av/VuMeter.h"
-#include "package_bgs/ae/KDE.h"
-#include "package_bgs/db/IndependentMultimodalBGS.h"
-#include "package_bgs/sjn/SJN_MultiCueBGS.h"
-#include "package_bgs/bl/SigmaDeltaBGS.h"
-
-#include "package_bgs/pl/SuBSENSE.h"
-#include "package_bgs/pl/LOBSTER.h"
+#include "package_bgs/bgslibrary.h"
 
 int main(int argc, char **argv)
 {
@@ -75,81 +26,60 @@ int main(int argc, char **argv)
   /* Background Subtraction Methods */
   IBGS *bgs;
 
-  /*** Default Package ***/
-  bgs = new FrameDifferenceBGS;
-  //bgs = new StaticFrameDifferenceBGS;
-  //bgs = new WeightedMovingMeanBGS;
-  //bgs = new WeightedMovingVarianceBGS;
-  //bgs = new MixtureOfGaussianV1BGS;
-  //bgs = new MixtureOfGaussianV2BGS;
+  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;
-  
-  /*** DP Package (thanks to Donovan Parks) ***/
-  //bgs = new DPAdaptiveMedianBGS;
-  //bgs = new DPGrimsonGMMBGS;
-  //bgs = new DPZivkovicAGMMBGS;
-  //bgs = new DPMeanBGS;
-  //bgs = new DPWrenGABGS;
-  //bgs = new DPPratiMediodBGS;
-  //bgs = new DPEigenbackgroundBGS;
-  //bgs = new DPTextureBGS;
-
-  /*** TB Package (thanks to Thierry Bouwmans, Fida EL BAF and Zhenjie Zhao) ***/
+  //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;
-
-  /*** JMO Package (thanks to Jean-Marc Odobez) ***/
-  //bgs = new MultiLayerBGS;
-
-  /*** PT Package (thanks to Martin Hofmann, Philipp Tiefenbacher and Gerhard Rigoll) ***/
+  //bgs = new MultiLayer;
   //bgs = new PixelBasedAdaptiveSegmenter;
-
-  /*** LB Package (thanks to Laurence Bender) ***/
   //bgs = new LBSimpleGaussian;
   //bgs = new LBFuzzyGaussian;
   //bgs = new LBMixtureOfGaussians;
   //bgs = new LBAdaptiveSOM;
   //bgs = new LBFuzzyAdaptiveSOM;
-
-  /*** LBP-MRF Package (thanks to Csaba Kertész) ***/
-  //bgs = new LbpMrf;
-
-  /*** AV Package (thanks to Lionel Robinault and Antoine Vacavant) ***/
+  //bgs = new LBP_MRF;
   //bgs = new VuMeter;
-
-  /*** EG Package (thanks to Ahmed Elgammal) ***/
   //bgs = new KDE;
-  
-  /*** DB Package (thanks to Domenico Daniele Bloisi) ***/
-  //bgs = new IndependentMultimodalBGS;
-
-  /*** SJN Package (thanks to SeungJong Noh) ***/
-  //bgs = new SJN_MultiCueBGS;
-
-  /*** BL Package (thanks to Benjamin Laugraud) ***/
-  //bgs = new SigmaDeltaBGS;
-
-  /*** PL Package (thanks to Pierre-Luc) ***/
-  //bgs = new SuBSENSEBGS();
-  //bgs = new LOBSTERBGS();
+  //bgs = new IndependentMultimodal;
+  //bgs = new MultiCue;
+  //bgs = new SigmaDelta;
+  //bgs = new SuBSENSE;
+  //bgs = new LOBSTER;
+  //bgs = new PAWCS;
+  //bgs = new TwoPoints;
+  //bgs = new ViBe;
 
   int frameNumber = 1;
   int key = 0;
-  while(key != 'q')
+  while (key != 'q')
   {
     std::stringstream ss;
     ss << frameNumber;
-    std::string fileName = "frames/" + ss.str() + ".png";
+    std::string fileName = "dataset/frames/" + ss.str() + ".png";
     std::cout << "reading " << fileName << std::endl;
 
     cv::Mat img_input = cv::imread(fileName, CV_LOAD_IMAGE_COLOR);
-    
+
     if (img_input.empty())
       break;
 
@@ -157,18 +87,19 @@ int main(int argc, char **argv)
 
     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
-    
+    bgs->process(img_input, img_mask, img_bkgmodel);
+    // by default, "bgs->process(.)" automatically shows the foreground mask image
+    // or set "bgs->setShowOutput(false)" to disable
+
     //if(!img_mask.empty())
     //  cv::imshow("Foreground", img_mask);
     //  do something
-    
+
     key = cvWaitKey(33);
     frameNumber++;
   }
   cvWaitKey(0);
   delete bgs;
-
   cvDestroyAllWindows();
 
   return 0;
diff --git a/FrameProcessor.cpp b/FrameProcessor.cpp
index 0cce65261c781861eca6eb926482c55cb5df3a96..50881219f6d4bf5e703840f3912204b006777686 100644
--- a/FrameProcessor.cpp
+++ b/FrameProcessor.cpp
@@ -37,23 +37,25 @@ namespace bgslibrary
     if (enablePreProcessor)
       preProcessor = new PreProcessor;
 
-    if (enableFrameDifferenceBGS)
-      frameDifference = new FrameDifferenceBGS;
+    if (enableFrameDifference)
+      frameDifference = new FrameDifference;
 
-    if (enableStaticFrameDifferenceBGS)
-      staticFrameDifference = new StaticFrameDifferenceBGS;
+    if (enableStaticFrameDifference)
+      staticFrameDifference = new StaticFrameDifference;
 
-    if (enableWeightedMovingMeanBGS)
-      weightedMovingMean = new WeightedMovingMeanBGS;
+    if (enableWeightedMovingMean)
+      weightedMovingMean = new WeightedMovingMean;
 
-    if (enableWeightedMovingVarianceBGS)
-      weightedMovingVariance = new WeightedMovingVarianceBGS;
+    if (enableWeightedMovingVariance)
+      weightedMovingVariance = new WeightedMovingVariance;
 
-    if (enableMixtureOfGaussianV1BGS)
-      mixtureOfGaussianV1BGS = new MixtureOfGaussianV1BGS;
+#if CV_MAJOR_VERSION == 2
+    if (enableMixtureOfGaussianV1)
+      mixtureOfGaussianV1 = new MixtureOfGaussianV1;
+#endif
 
-    if (enableMixtureOfGaussianV2BGS)
-      mixtureOfGaussianV2BGS = new MixtureOfGaussianV2BGS;
+    if (enableMixtureOfGaussianV2)
+      mixtureOfGaussianV2 = new MixtureOfGaussianV2;
 
     if (enableAdaptiveBackgroundLearning)
       adaptiveBackgroundLearning = new AdaptiveBackgroundLearning;
@@ -63,29 +65,29 @@ namespace bgslibrary
       gmg = new GMG;
 #endif
 
-    if (enableDPAdaptiveMedianBGS)
-      adaptiveMedian = new DPAdaptiveMedianBGS;
+    if (enableDPAdaptiveMedian)
+      dpAdaptiveMedian = new DPAdaptiveMedian;
 
-    if (enableDPGrimsonGMMBGS)
-      grimsonGMM = new DPGrimsonGMMBGS;
+    if (enableDPGrimsonGMM)
+      dpGrimsonGMM = new DPGrimsonGMM;
 
-    if (enableDPZivkovicAGMMBGS)
-      zivkovicAGMM = new DPZivkovicAGMMBGS;
+    if (enableDPZivkovicAGMM)
+      dpZivkovicAGMM = new DPZivkovicAGMM;
 
-    if (enableDPMeanBGS)
-      temporalMean = new DPMeanBGS;
+    if (enableDPMean)
+      dpTemporalMean = new DPMean;
 
-    if (enableDPWrenGABGS)
-      wrenGA = new DPWrenGABGS;
+    if (enableDPWrenGA)
+      dpWrenGA = new DPWrenGA;
 
-    if (enableDPPratiMediodBGS)
-      pratiMediod = new DPPratiMediodBGS;
+    if (enableDPPratiMediod)
+      dpPratiMediod = new DPPratiMediod;
 
-    if (enableDPEigenbackgroundBGS)
-      eigenBackground = new DPEigenbackgroundBGS;
+    if (enableDPEigenbackground)
+      dpEigenBackground = new DPEigenbackground;
 
-    if (enableDPTextureBGS)
-      textureBGS = new DPTextureBGS;
+    if (enableDPTexture)
+      dpTexture = new DPTexture;
 
     if (enableT2FGMM_UM)
       type2FuzzyGMM_UM = new T2FGMM_UM;
@@ -121,13 +123,15 @@ namespace bgslibrary
       lbFuzzyAdaptiveSOM = new LBFuzzyAdaptiveSOM;
 
     if (enableLbpMrf)
-      lbpMrf = new LbpMrf;
+      lbpMrf = new LBP_MRF;
 
-    if(enableMultiLayerBGS)
-      multiLayerBGS = new MultiLayerBGS;
+#if CV_MAJOR_VERSION == 2
+    if (enableMultiLayer)
+      multiLayer = new MultiLayer;
+#endif
 
-    //if(enablePBAS)
-    //  pixelBasedAdaptiveSegmenter = new PixelBasedAdaptiveSegmenter;
+    if (enablePBAS)
+      pixelBasedAdaptiveSegmenter = new PixelBasedAdaptiveSegmenter;
 
     if (enableVuMeter)
       vuMeter = new VuMeter;
@@ -136,19 +140,19 @@ namespace bgslibrary
       kde = new KDE;
 
     if (enableIMBS)
-      imbs = new IndependentMultimodalBGS;
+      imbs = new IndependentMultimodal;
 
-    if (enableMultiCueBGS)
-      mcbgs = new SJN_MultiCueBGS;
+    if (enableMultiCue)
+      multiCue = new MultiCue;
 
-    if (enableSigmaDeltaBGS)
-      sdbgs = new SigmaDeltaBGS;
+    if (enableSigmaDelta)
+      sigmaDelta = new SigmaDelta;
 
-    if (enableSuBSENSEBGS)
-      ssbgs = new SuBSENSEBGS;
+    if (enableSuBSENSE)
+      subSENSE = new SuBSENSE;
 
-    if (enableLOBSTERBGS)
-      lobgs = new LOBSTERBGS;
+    if (enableLOBSTER)
+      lobster = new LOBSTER;
 
     if (enableForegroundMaskAnalysis)
       foregroundMaskAnalysis = new ForegroundMaskAnalysis;
@@ -171,169 +175,177 @@ namespace bgslibrary
     frameNumber++;
 
     if (enablePreProcessor)
-      preProcessor->process(img_input, img_prep);
+      preProcessor->process(img_input, img_preProcessor);
 
-    if (enableFrameDifferenceBGS)
-      process("FrameDifferenceBGS", frameDifference, img_prep, img_framediff);
+    if (enableFrameDifference)
+      process("FrameDifference", frameDifference, img_preProcessor, img_frameDifference);
 
-    if (enableStaticFrameDifferenceBGS)
-      process("StaticFrameDifferenceBGS", staticFrameDifference, img_prep, img_staticfdiff);
+    if (enableStaticFrameDifference)
+      process("StaticFrameDifference", staticFrameDifference, img_preProcessor, img_staticFrameDifference);
 
-    if (enableWeightedMovingMeanBGS)
-      process("WeightedMovingMeanBGS", weightedMovingMean, img_prep, img_wmovmean);
+    if (enableWeightedMovingMean)
+      process("WeightedMovingMean", weightedMovingMean, img_preProcessor, img_weightedMovingMean);
 
-    if (enableWeightedMovingVarianceBGS)
-      process("WeightedMovingVarianceBGS", weightedMovingVariance, img_prep, img_movvar);
+    if (enableWeightedMovingVariance)
+      process("WeightedMovingVariance", weightedMovingVariance, img_preProcessor, img_weightedMovingVariance);
 
-    if (enableMixtureOfGaussianV1BGS)
-      process("MixtureOfGaussianV1BGS", mixtureOfGaussianV1BGS, img_prep, img_mog1);
+#if CV_MAJOR_VERSION == 2
+    if (enableMixtureOfGaussianV1)
+      process("MixtureOfGaussianV1", mixtureOfGaussianV1, img_preProcessor, img_mixtureOfGaussianV1);
+#endif
 
-    if (enableMixtureOfGaussianV2BGS)
-      process("MixtureOfGaussianV2BGS", mixtureOfGaussianV2BGS, img_prep, img_mog2);
+    if (enableMixtureOfGaussianV2)
+      process("MixtureOfGaussianV2", mixtureOfGaussianV2, img_preProcessor, img_mixtureOfGaussianV2);
 
     if (enableAdaptiveBackgroundLearning)
-      process("AdaptiveBackgroundLearning", adaptiveBackgroundLearning, img_prep, img_bkgl_fgmask);
+      process("AdaptiveBackgroundLearning", adaptiveBackgroundLearning, img_preProcessor, img_adaptiveBackgroundLearning);
 
 #if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >= 4 && CV_SUBMINOR_VERSION >= 3
     if (enableGMG)
-      process("GMG", gmg, img_prep, img_gmg);
+      process("GMG", gmg, img_preProcessor, img_gmg);
 #endif
 
-    if (enableDPAdaptiveMedianBGS)
-      process("DPAdaptiveMedianBGS", adaptiveMedian, img_prep, img_adpmed);
+    if (enableDPAdaptiveMedian)
+      process("DPAdaptiveMedian", dpAdaptiveMedian, img_preProcessor, img_dpAdaptiveMedian);
 
-    if (enableDPGrimsonGMMBGS)
-      process("DPGrimsonGMMBGS", grimsonGMM, img_prep, img_grigmm);
+    if (enableDPGrimsonGMM)
+      process("DPGrimsonGMM", dpGrimsonGMM, img_preProcessor, img_dpGrimsonGMM);
 
-    if (enableDPZivkovicAGMMBGS)
-      process("DPZivkovicAGMMBGS", zivkovicAGMM, img_prep, img_zivgmm);
+    if (enableDPZivkovicAGMM)
+      process("DPZivkovicAGMM", dpZivkovicAGMM, img_preProcessor, img_dpZivkovicAGMM);
 
-    if (enableDPMeanBGS)
-      process("DPMeanBGS", temporalMean, img_prep, img_tmpmean);
+    if (enableDPMean)
+      process("DPMean", dpTemporalMean, img_preProcessor, img_dpTemporalMean);
 
-    if (enableDPWrenGABGS)
-      process("DPWrenGABGS", wrenGA, img_prep, img_wrenga);
+    if (enableDPWrenGA)
+      process("DPWrenGA", dpWrenGA, img_preProcessor, img_dpWrenGA);
 
-    if (enableDPPratiMediodBGS)
-      process("DPPratiMediodBGS", pratiMediod, img_prep, img_pramed);
+    if (enableDPPratiMediod)
+      process("DPPratiMediod", dpPratiMediod, img_preProcessor, img_dpPratiMediod);
 
-    if (enableDPEigenbackgroundBGS)
-      process("DPEigenbackgroundBGS", eigenBackground, img_prep, img_eigbkg);
+    if (enableDPEigenbackground)
+      process("DPEigenbackground", dpEigenBackground, img_preProcessor, img_dpEigenBackground);
 
-    if (enableDPTextureBGS)
-      process("DPTextureBGS", textureBGS, img_prep, img_texbgs);
+    if (enableDPTexture)
+      process("DPTexture", dpTexture, img_preProcessor, img_dpTexture);
 
     if (enableT2FGMM_UM)
-      process("T2FGMM_UM", type2FuzzyGMM_UM, img_prep, img_t2fgmm_um);
+      process("T2FGMM_UM", type2FuzzyGMM_UM, img_preProcessor, img_type2FuzzyGMM_UM);
 
     if (enableT2FGMM_UV)
-      process("T2FGMM_UV", type2FuzzyGMM_UV, img_prep, img_t2fgmm_uv);
+      process("T2FGMM_UV", type2FuzzyGMM_UV, img_preProcessor, img_type2FuzzyGMM_UV);
 
     if (enableT2FMRF_UM)
-      process("T2FMRF_UM", type2FuzzyMRF_UM, img_prep, img_t2fmrf_um);
+      process("T2FMRF_UM", type2FuzzyMRF_UM, img_preProcessor, img_type2FuzzyMRF_UM);
 
     if (enableT2FMRF_UV)
-      process("T2FMRF_UV", type2FuzzyMRF_UV, img_prep, img_t2fmrf_uv);
+      process("T2FMRF_UV", type2FuzzyMRF_UV, img_preProcessor, img_type2FuzzyMRF_UV);
 
     if (enableFuzzySugenoIntegral)
-      process("FuzzySugenoIntegral", fuzzySugenoIntegral, img_prep, img_fsi);
+      process("FuzzySugenoIntegral", fuzzySugenoIntegral, img_preProcessor, img_fuzzySugenoIntegral);
 
     if (enableFuzzyChoquetIntegral)
-      process("FuzzyChoquetIntegral", fuzzyChoquetIntegral, img_prep, img_fci);
+      process("FuzzyChoquetIntegral", fuzzyChoquetIntegral, img_preProcessor, img_fuzzyChoquetIntegral);
 
     if (enableLBSimpleGaussian)
-      process("LBSimpleGaussian", lbSimpleGaussian, img_prep, img_lb_sg);
+      process("LBSimpleGaussian", lbSimpleGaussian, img_preProcessor, img_lbSimpleGaussian);
 
     if (enableLBFuzzyGaussian)
-      process("LBFuzzyGaussian", lbFuzzyGaussian, img_prep, img_lb_fg);
+      process("LBFuzzyGaussian", lbFuzzyGaussian, img_preProcessor, img_lbFuzzyGaussian);
 
     if (enableLBMixtureOfGaussians)
-      process("LBMixtureOfGaussians", lbMixtureOfGaussians, img_prep, img_lb_mog);
+      process("LBMixtureOfGaussians", lbMixtureOfGaussians, img_preProcessor, img_lbMixtureOfGaussians);
 
     if (enableLBAdaptiveSOM)
-      process("LBAdaptiveSOM", lbAdaptiveSOM, img_prep, img_lb_som);
+      process("LBAdaptiveSOM", lbAdaptiveSOM, img_preProcessor, img_lbAdaptiveSOM);
 
     if (enableLBFuzzyAdaptiveSOM)
-      process("LBFuzzyAdaptiveSOM", lbFuzzyAdaptiveSOM, img_prep, img_lb_fsom);
+      process("LBFuzzyAdaptiveSOM", lbFuzzyAdaptiveSOM, img_preProcessor, img_lbFuzzyAdaptiveSOM);
 
     if (enableLbpMrf)
-      process("LbpMrf", lbpMrf, img_prep, img_lbp_mrf);
+      process("LbpMrf", lbpMrf, img_preProcessor, img_lbpMrf);
 
-    if(enableMultiLayerBGS)
+#if CV_MAJOR_VERSION == 2
+    if (enableMultiLayer)
     {
-      multiLayerBGS->setStatus(MultiLayerBGS::MLBGS_LEARN);
-      //multiLayerBGS->setStatus(MultiLayerBGS::MLBGS_DETECT);
-      process("MultiLayerBGS", multiLayerBGS, img_prep, img_mlbgs);
+      multiLayer->setStatus(MultiLayer::MLBGS_LEARN);
+      //multiLayer->setStatus(MultiLayer::MLBGS_DETECT);
+      process("MultiLayer", multiLayer, img_preProcessor, img_multiLayer);
     }
+#endif
 
-    //if(enablePBAS)
-    //  process("PBAS", pixelBasedAdaptiveSegmenter, img_prep, img_pt_pbas);
+    if (enablePBAS)
+      process("PBAS", pixelBasedAdaptiveSegmenter, img_preProcessor, img_pixelBasedAdaptiveSegmenter);
 
     if (enableVuMeter)
-      process("VuMeter", vuMeter, img_prep, img_vumeter);
+      process("VuMeter", vuMeter, img_preProcessor, img_vumeter);
 
     if (enableKDE)
-      process("KDE", kde, img_prep, img_kde);
+      process("KDE", kde, img_preProcessor, img_kde);
 
     if (enableIMBS)
-      process("IMBS", imbs, img_prep, img_imbs);
+      process("IMBS", imbs, img_preProcessor, img_imbs);
 
-    if (enableMultiCueBGS)
-      process("MultiCueBGS", mcbgs, img_prep, img_mcbgs);
+    if (enableMultiCue)
+      process("MultiCue", multiCue, img_preProcessor, img_multiCue);
 
-    if (enableSigmaDeltaBGS)
-      process("SigmaDeltaBGS", sdbgs, img_prep, img_sdbgs);
+    if (enableSigmaDelta)
+      process("SigmaDelta", sigmaDelta, img_preProcessor, img_sigmaDelta);
 
-    if (enableSuBSENSEBGS)
-      process("SuBSENSEBGS", ssbgs, img_prep, img_ssbgs);
+    if (enableSuBSENSE)
+      process("SuBSENSE", subSENSE, img_preProcessor, img_subSENSE);
 
-    if (enableLOBSTERBGS)
-      process("LOBSTERBGS", lobgs, img_prep, img_lobgs);
+    if (enableLOBSTER)
+      process("LOBSTER", lobster, img_preProcessor, img_lobster);
 
     if (enableForegroundMaskAnalysis)
     {
       foregroundMaskAnalysis->stopAt = frameToStop;
       foregroundMaskAnalysis->img_ref_path = imgref;
 
-      foregroundMaskAnalysis->process(frameNumber, "FrameDifferenceBGS", img_framediff);
-      foregroundMaskAnalysis->process(frameNumber, "StaticFrameDifferenceBGS", img_staticfdiff);
-      foregroundMaskAnalysis->process(frameNumber, "WeightedMovingMeanBGS", img_wmovmean);
-      foregroundMaskAnalysis->process(frameNumber, "WeightedMovingVarianceBGS", img_movvar);
-      foregroundMaskAnalysis->process(frameNumber, "MixtureOfGaussianV1BGS", img_mog1);
-      foregroundMaskAnalysis->process(frameNumber, "MixtureOfGaussianV2BGS", img_mog2);
-      foregroundMaskAnalysis->process(frameNumber, "AdaptiveBackgroundLearning", img_bkgl_fgmask);
+      foregroundMaskAnalysis->process(frameNumber, "FrameDifference", img_frameDifference);
+      foregroundMaskAnalysis->process(frameNumber, "StaticFrameDifference", img_staticFrameDifference);
+      foregroundMaskAnalysis->process(frameNumber, "WeightedMovingMean", img_weightedMovingMean);
+      foregroundMaskAnalysis->process(frameNumber, "WeightedMovingVariance", img_weightedMovingVariance);
+#if CV_MAJOR_VERSION == 2
+      foregroundMaskAnalysis->process(frameNumber, "MixtureOfGaussianV1", img_mixtureOfGaussianV1);
+#endif
+      foregroundMaskAnalysis->process(frameNumber, "MixtureOfGaussianV2", img_mixtureOfGaussianV2);
+      foregroundMaskAnalysis->process(frameNumber, "AdaptiveBackgroundLearning", img_adaptiveBackgroundLearning);
 #if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >= 4 && CV_SUBMINOR_VERSION >= 3
       foregroundMaskAnalysis->process(frameNumber, "GMG", img_gmg);
 #endif
-      foregroundMaskAnalysis->process(frameNumber, "DPAdaptiveMedianBGS", img_adpmed);
-      foregroundMaskAnalysis->process(frameNumber, "DPGrimsonGMMBGS", img_grigmm);
-      foregroundMaskAnalysis->process(frameNumber, "DPZivkovicAGMMBGS", img_zivgmm);
-      foregroundMaskAnalysis->process(frameNumber, "DPMeanBGS", img_tmpmean);
-      foregroundMaskAnalysis->process(frameNumber, "DPWrenGABGS", img_wrenga);
-      foregroundMaskAnalysis->process(frameNumber, "DPPratiMediodBGS", img_pramed);
-      foregroundMaskAnalysis->process(frameNumber, "DPEigenbackgroundBGS", img_eigbkg);
-      foregroundMaskAnalysis->process(frameNumber, "DPTextureBGS", img_texbgs);
-      foregroundMaskAnalysis->process(frameNumber, "T2FGMM_UM", img_t2fgmm_um);
-      foregroundMaskAnalysis->process(frameNumber, "T2FGMM_UV", img_t2fgmm_uv);
-      foregroundMaskAnalysis->process(frameNumber, "T2FMRF_UM", img_t2fmrf_um);
-      foregroundMaskAnalysis->process(frameNumber, "T2FMRF_UV", img_t2fmrf_uv);
-      foregroundMaskAnalysis->process(frameNumber, "FuzzySugenoIntegral", img_fsi);
-      foregroundMaskAnalysis->process(frameNumber, "FuzzyChoquetIntegral", img_fci);
-      foregroundMaskAnalysis->process(frameNumber, "LBSimpleGaussian", img_lb_sg);
-      foregroundMaskAnalysis->process(frameNumber, "LBFuzzyGaussian", img_lb_fg);
-      foregroundMaskAnalysis->process(frameNumber, "LBMixtureOfGaussians", img_lb_mog);
-      foregroundMaskAnalysis->process(frameNumber, "LBAdaptiveSOM", img_lb_som);
-      foregroundMaskAnalysis->process(frameNumber, "LBFuzzyAdaptiveSOM", img_lb_fsom);
-      foregroundMaskAnalysis->process(frameNumber, "LbpMrf", img_lbp_mrf);
-      foregroundMaskAnalysis->process(frameNumber, "MultiLayerBGS", img_mlbgs);
-      //foregroundMaskAnalysis->process(frameNumber, "PBAS", img_pt_pbas);
+      foregroundMaskAnalysis->process(frameNumber, "DPAdaptiveMedian", img_dpAdaptiveMedian);
+      foregroundMaskAnalysis->process(frameNumber, "DPGrimsonGMM", img_dpGrimsonGMM);
+      foregroundMaskAnalysis->process(frameNumber, "DPZivkovicAGMM", img_dpZivkovicAGMM);
+      foregroundMaskAnalysis->process(frameNumber, "DPMean", img_dpTemporalMean);
+      foregroundMaskAnalysis->process(frameNumber, "DPWrenGA", img_dpWrenGA);
+      foregroundMaskAnalysis->process(frameNumber, "DPPratiMediod", img_dpPratiMediod);
+      foregroundMaskAnalysis->process(frameNumber, "DPEigenbackground", img_dpEigenBackground);
+      foregroundMaskAnalysis->process(frameNumber, "DPTexture", img_dpTexture);
+      foregroundMaskAnalysis->process(frameNumber, "T2FGMM_UM", img_type2FuzzyGMM_UM);
+      foregroundMaskAnalysis->process(frameNumber, "T2FGMM_UV", img_type2FuzzyGMM_UV);
+      foregroundMaskAnalysis->process(frameNumber, "T2FMRF_UM", img_type2FuzzyMRF_UM);
+      foregroundMaskAnalysis->process(frameNumber, "T2FMRF_UV", img_type2FuzzyMRF_UV);
+      foregroundMaskAnalysis->process(frameNumber, "FuzzySugenoIntegral", img_fuzzySugenoIntegral);
+      foregroundMaskAnalysis->process(frameNumber, "FuzzyChoquetIntegral", img_fuzzyChoquetIntegral);
+      foregroundMaskAnalysis->process(frameNumber, "LBSimpleGaussian", img_lbSimpleGaussian);
+      foregroundMaskAnalysis->process(frameNumber, "LBFuzzyGaussian", img_lbFuzzyGaussian);
+      foregroundMaskAnalysis->process(frameNumber, "LBMixtureOfGaussians", img_lbMixtureOfGaussians);
+      foregroundMaskAnalysis->process(frameNumber, "LBAdaptiveSOM", img_lbAdaptiveSOM);
+      foregroundMaskAnalysis->process(frameNumber, "LBFuzzyAdaptiveSOM", img_lbFuzzyAdaptiveSOM);
+      foregroundMaskAnalysis->process(frameNumber, "LbpMrf", img_lbpMrf);
+#if CV_MAJOR_VERSION == 2
+      foregroundMaskAnalysis->process(frameNumber, "MultiLayer", img_multiLayer);
+#endif
+      foregroundMaskAnalysis->process(frameNumber, "PBAS", img_pixelBasedAdaptiveSegmenter);
       foregroundMaskAnalysis->process(frameNumber, "VuMeter", img_vumeter);
       foregroundMaskAnalysis->process(frameNumber, "KDE", img_kde);
       foregroundMaskAnalysis->process(frameNumber, "IMBS", img_imbs);
-      foregroundMaskAnalysis->process(frameNumber, "MultiCueBGS", img_mcbgs);
-      foregroundMaskAnalysis->process(frameNumber, "SigmaDeltaBGS", img_sdbgs);
-      foregroundMaskAnalysis->process(frameNumber, "SuBSENSEBGS", img_ssbgs);
-      foregroundMaskAnalysis->process(frameNumber, "LOBSTERBGS", img_lobgs);
+      foregroundMaskAnalysis->process(frameNumber, "MultiCue", img_multiCue);
+      foregroundMaskAnalysis->process(frameNumber, "SigmaDelta", img_sigmaDelta);
+      foregroundMaskAnalysis->process(frameNumber, "SuBSENSE", img_subSENSE);
+      foregroundMaskAnalysis->process(frameNumber, "LOBSTER", img_lobster);
     }
 
     firstTime = false;
@@ -341,8 +353,8 @@ namespace bgslibrary
 
   void FrameProcessor::finish(void)
   {
-    /*if(enableMultiLayerBGS)
-    multiLayerBGS->finish();
+    /*if(enableMultiLayer)
+    multiLayer->finish();
 
     if(enableLBSimpleGaussian)
     lbSimpleGaussian->finish();
@@ -362,17 +374,17 @@ namespace bgslibrary
     if (enableForegroundMaskAnalysis)
       delete foregroundMaskAnalysis;
 
-    if (enableLOBSTERBGS)
-      delete lobgs;
+    if (enableLOBSTER)
+      delete lobster;
 
-    if (enableSuBSENSEBGS)
-      delete ssbgs;
+    if (enableSuBSENSE)
+      delete subSENSE;
 
-    if (enableSigmaDeltaBGS)
-      delete sdbgs;
+    if (enableSigmaDelta)
+      delete sigmaDelta;
 
-    if (enableMultiCueBGS)
-      delete mcbgs;
+    if (enableMultiCue)
+      delete multiCue;
 
     if (enableIMBS)
       delete imbs;
@@ -383,11 +395,13 @@ namespace bgslibrary
     if (enableVuMeter)
       delete vuMeter;
 
-    //if(enablePBAS)
-    //  delete pixelBasedAdaptiveSegmenter;
+    if (enablePBAS)
+      delete pixelBasedAdaptiveSegmenter;
 
-    if (enableMultiLayerBGS)
-      delete multiLayerBGS;
+#if CV_MAJOR_VERSION == 2
+    if (enableMultiLayer)
+      delete multiLayer;
+#endif
 
     if (enableLBFuzzyAdaptiveSOM)
       delete lbFuzzyAdaptiveSOM;
@@ -409,7 +423,7 @@ namespace bgslibrary
       delete lbpMrf;
 #endif
 
-    if(enableFuzzyChoquetIntegral)
+    if (enableFuzzyChoquetIntegral)
       delete fuzzyChoquetIntegral;
 
     if (enableFuzzySugenoIntegral)
@@ -427,29 +441,29 @@ namespace bgslibrary
     if (enableT2FGMM_UM)
       delete type2FuzzyGMM_UM;
 
-    if (enableDPTextureBGS)
-      delete textureBGS;
+    if (enableDPTexture)
+      delete dpTexture;
 
-    if (enableDPEigenbackgroundBGS)
-      delete eigenBackground;
+    if (enableDPEigenbackground)
+      delete dpEigenBackground;
 
-    if (enableDPPratiMediodBGS)
-      delete pratiMediod;
+    if (enableDPPratiMediod)
+      delete dpPratiMediod;
 
-    if (enableDPWrenGABGS)
-      delete wrenGA;
+    if (enableDPWrenGA)
+      delete dpWrenGA;
 
-    if (enableDPMeanBGS)
-      delete temporalMean;
+    if (enableDPMean)
+      delete dpTemporalMean;
 
-    if (enableDPZivkovicAGMMBGS)
-      delete zivkovicAGMM;
+    if (enableDPZivkovicAGMM)
+      delete dpZivkovicAGMM;
 
-    if (enableDPGrimsonGMMBGS)
-      delete grimsonGMM;
+    if (enableDPGrimsonGMM)
+      delete dpGrimsonGMM;
 
-    if (enableDPAdaptiveMedianBGS)
-      delete adaptiveMedian;
+    if (enableDPAdaptiveMedian)
+      delete dpAdaptiveMedian;
 
 #if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >= 4 && CV_SUBMINOR_VERSION >= 3
     if (enableGMG)
@@ -459,22 +473,24 @@ namespace bgslibrary
     if (enableAdaptiveBackgroundLearning)
       delete adaptiveBackgroundLearning;
 
-    if (enableMixtureOfGaussianV2BGS)
-      delete mixtureOfGaussianV2BGS;
+    if (enableMixtureOfGaussianV2)
+      delete mixtureOfGaussianV2;
 
-    if (enableMixtureOfGaussianV1BGS)
-      delete mixtureOfGaussianV1BGS;
+#if CV_MAJOR_VERSION == 2
+    if (enableMixtureOfGaussianV1)
+      delete mixtureOfGaussianV1;
+#endif
 
-    if (enableWeightedMovingVarianceBGS)
+    if (enableWeightedMovingVariance)
       delete weightedMovingVariance;
 
-    if (enableWeightedMovingMeanBGS)
+    if (enableWeightedMovingMean)
       delete weightedMovingMean;
 
-    if (enableStaticFrameDifferenceBGS)
+    if (enableStaticFrameDifference)
       delete staticFrameDifference;
 
-    if (enableFrameDifferenceBGS)
+    if (enableFrameDifference)
       delete frameDifference;
 
     if (enablePreProcessor)
@@ -503,25 +519,27 @@ namespace bgslibrary
 
     cvWriteInt(fs, "enableForegroundMaskAnalysis", enableForegroundMaskAnalysis);
 
-    cvWriteInt(fs, "enableFrameDifferenceBGS", enableFrameDifferenceBGS);
-    cvWriteInt(fs, "enableStaticFrameDifferenceBGS", enableStaticFrameDifferenceBGS);
-    cvWriteInt(fs, "enableWeightedMovingMeanBGS", enableWeightedMovingMeanBGS);
-    cvWriteInt(fs, "enableWeightedMovingVarianceBGS", enableWeightedMovingVarianceBGS);
-    cvWriteInt(fs, "enableMixtureOfGaussianV1BGS", enableMixtureOfGaussianV1BGS);
-    cvWriteInt(fs, "enableMixtureOfGaussianV2BGS", enableMixtureOfGaussianV2BGS);
+    cvWriteInt(fs, "enableFrameDifference", enableFrameDifference);
+    cvWriteInt(fs, "enableStaticFrameDifference", enableStaticFrameDifference);
+    cvWriteInt(fs, "enableWeightedMovingMean", enableWeightedMovingMean);
+    cvWriteInt(fs, "enableWeightedMovingVariance", enableWeightedMovingVariance);
+#if CV_MAJOR_VERSION == 2
+    cvWriteInt(fs, "enableMixtureOfGaussianV1", enableMixtureOfGaussianV1);
+#endif
+    cvWriteInt(fs, "enableMixtureOfGaussianV2", enableMixtureOfGaussianV2);
     cvWriteInt(fs, "enableAdaptiveBackgroundLearning", enableAdaptiveBackgroundLearning);
 #if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >= 4 && CV_SUBMINOR_VERSION >= 3
     cvWriteInt(fs, "enableGMG", enableGMG);
 #endif
 
-    cvWriteInt(fs, "enableDPAdaptiveMedianBGS", enableDPAdaptiveMedianBGS);
-    cvWriteInt(fs, "enableDPGrimsonGMMBGS", enableDPGrimsonGMMBGS);
-    cvWriteInt(fs, "enableDPZivkovicAGMMBGS", enableDPZivkovicAGMMBGS);
-    cvWriteInt(fs, "enableDPMeanBGS", enableDPMeanBGS);
-    cvWriteInt(fs, "enableDPWrenGABGS", enableDPWrenGABGS);
-    cvWriteInt(fs, "enableDPPratiMediodBGS", enableDPPratiMediodBGS);
-    cvWriteInt(fs, "enableDPEigenbackgroundBGS", enableDPEigenbackgroundBGS);
-    cvWriteInt(fs, "enableDPTextureBGS", enableDPTextureBGS);
+    cvWriteInt(fs, "enableDPAdaptiveMedian", enableDPAdaptiveMedian);
+    cvWriteInt(fs, "enableDPGrimsonGMM", enableDPGrimsonGMM);
+    cvWriteInt(fs, "enableDPZivkovicAGMM", enableDPZivkovicAGMM);
+    cvWriteInt(fs, "enableDPMean", enableDPMean);
+    cvWriteInt(fs, "enableDPWrenGA", enableDPWrenGA);
+    cvWriteInt(fs, "enableDPPratiMediod", enableDPPratiMediod);
+    cvWriteInt(fs, "enableDPEigenbackground", enableDPEigenbackground);
+    cvWriteInt(fs, "enableDPTexture", enableDPTexture);
 
     cvWriteInt(fs, "enableT2FGMM_UM", enableT2FGMM_UM);
     cvWriteInt(fs, "enableT2FGMM_UV", enableT2FGMM_UV);
@@ -538,15 +556,17 @@ namespace bgslibrary
 
     cvWriteInt(fs, "enableLbpMrf", enableLbpMrf);
 
-    cvWriteInt(fs, "enableMultiLayerBGS", enableMultiLayerBGS);
-    //cvWriteInt(fs, "enablePBAS", enablePBAS);
+#if CV_MAJOR_VERSION == 2
+    cvWriteInt(fs, "enableMultiLayer", enableMultiLayer);
+#endif
+    cvWriteInt(fs, "enablePBAS", enablePBAS);
     cvWriteInt(fs, "enableVuMeter", enableVuMeter);
     cvWriteInt(fs, "enableKDE", enableKDE);
     cvWriteInt(fs, "enableIMBS", enableIMBS);
-    cvWriteInt(fs, "enableMultiCueBGS", enableMultiCueBGS);
-    cvWriteInt(fs, "enableSigmaDeltaBGS", enableSigmaDeltaBGS);
-    cvWriteInt(fs, "enableSuBSENSEBGS", enableSuBSENSEBGS);
-    cvWriteInt(fs, "enableLOBSTERBGS", enableLOBSTERBGS);
+    cvWriteInt(fs, "enableMultiCue", enableMultiCue);
+    cvWriteInt(fs, "enableSigmaDelta", enableSigmaDelta);
+    cvWriteInt(fs, "enableSuBSENSE", enableSuBSENSE);
+    cvWriteInt(fs, "enableLOBSTER", enableLOBSTER);
 
     cvReleaseFileStorage(&fs);
   }
@@ -561,25 +581,27 @@ namespace bgslibrary
 
     enableForegroundMaskAnalysis = cvReadIntByName(fs, 0, "enableForegroundMaskAnalysis", false);
 
-    enableFrameDifferenceBGS = cvReadIntByName(fs, 0, "enableFrameDifferenceBGS", false);
-    enableStaticFrameDifferenceBGS = cvReadIntByName(fs, 0, "enableStaticFrameDifferenceBGS", false);
-    enableWeightedMovingMeanBGS = cvReadIntByName(fs, 0, "enableWeightedMovingMeanBGS", false);
-    enableWeightedMovingVarianceBGS = cvReadIntByName(fs, 0, "enableWeightedMovingVarianceBGS", false);
-    enableMixtureOfGaussianV1BGS = cvReadIntByName(fs, 0, "enableMixtureOfGaussianV1BGS", false);
-    enableMixtureOfGaussianV2BGS = cvReadIntByName(fs, 0, "enableMixtureOfGaussianV2BGS", false);
+    enableFrameDifference = cvReadIntByName(fs, 0, "enableFrameDifference", false);
+    enableStaticFrameDifference = cvReadIntByName(fs, 0, "enableStaticFrameDifference", false);
+    enableWeightedMovingMean = cvReadIntByName(fs, 0, "enableWeightedMovingMean", false);
+    enableWeightedMovingVariance = cvReadIntByName(fs, 0, "enableWeightedMovingVariance", false);
+#if CV_MAJOR_VERSION == 2
+    enableMixtureOfGaussianV1 = cvReadIntByName(fs, 0, "enableMixtureOfGaussianV1", false);
+#endif
+    enableMixtureOfGaussianV2 = cvReadIntByName(fs, 0, "enableMixtureOfGaussianV2", false);
     enableAdaptiveBackgroundLearning = cvReadIntByName(fs, 0, "enableAdaptiveBackgroundLearning", false);
 #if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >= 4 && CV_SUBMINOR_VERSION >= 3
     enableGMG = cvReadIntByName(fs, 0, "enableGMG", false);
 #endif
 
-    enableDPAdaptiveMedianBGS = cvReadIntByName(fs, 0, "enableDPAdaptiveMedianBGS", false);
-    enableDPGrimsonGMMBGS = cvReadIntByName(fs, 0, "enableDPGrimsonGMMBGS", false);
-    enableDPZivkovicAGMMBGS = cvReadIntByName(fs, 0, "enableDPZivkovicAGMMBGS", false);
-    enableDPMeanBGS = cvReadIntByName(fs, 0, "enableDPMeanBGS", false);
-    enableDPWrenGABGS = cvReadIntByName(fs, 0, "enableDPWrenGABGS", false);
-    enableDPPratiMediodBGS = cvReadIntByName(fs, 0, "enableDPPratiMediodBGS", false);
-    enableDPEigenbackgroundBGS = cvReadIntByName(fs, 0, "enableDPEigenbackgroundBGS", false);
-    enableDPTextureBGS = cvReadIntByName(fs, 0, "enableDPTextureBGS", false);
+    enableDPAdaptiveMedian = cvReadIntByName(fs, 0, "enableDPAdaptiveMedian", false);
+    enableDPGrimsonGMM = cvReadIntByName(fs, 0, "enableDPGrimsonGMM", false);
+    enableDPZivkovicAGMM = cvReadIntByName(fs, 0, "enableDPZivkovicAGMM", false);
+    enableDPMean = cvReadIntByName(fs, 0, "enableDPMean", false);
+    enableDPWrenGA = cvReadIntByName(fs, 0, "enableDPWrenGA", false);
+    enableDPPratiMediod = cvReadIntByName(fs, 0, "enableDPPratiMediod", false);
+    enableDPEigenbackground = cvReadIntByName(fs, 0, "enableDPEigenbackground", false);
+    enableDPTexture = cvReadIntByName(fs, 0, "enableDPTexture", false);
 
     enableT2FGMM_UM = cvReadIntByName(fs, 0, "enableT2FGMM_UM", false);
     enableT2FGMM_UV = cvReadIntByName(fs, 0, "enableT2FGMM_UV", false);
@@ -596,15 +618,17 @@ namespace bgslibrary
 
     enableLbpMrf = cvReadIntByName(fs, 0, "enableLbpMrf", false);
 
-    enableMultiLayerBGS = cvReadIntByName(fs, 0, "enableMultiLayerBGS", false);
-    //enablePBAS = cvReadIntByName(fs, 0, "enablePBAS", false);
+#if CV_MAJOR_VERSION == 2
+    enableMultiLayer = cvReadIntByName(fs, 0, "enableMultiLayer", false);
+#endif
+    enablePBAS = cvReadIntByName(fs, 0, "enablePBAS", false);
     enableVuMeter = cvReadIntByName(fs, 0, "enableVuMeter", false);
     enableKDE = cvReadIntByName(fs, 0, "enableKDE", false);
     enableIMBS = cvReadIntByName(fs, 0, "enableIMBS", false);
-    enableMultiCueBGS = cvReadIntByName(fs, 0, "enableMultiCueBGS", false);
-    enableSigmaDeltaBGS = cvReadIntByName(fs, 0, "enableSigmaDeltaBGS", false);
-    enableSuBSENSEBGS = cvReadIntByName(fs, 0, "enableSuBSENSEBGS", false);
-    enableLOBSTERBGS = cvReadIntByName(fs, 0, "enableLOBSTERBGS", false);
+    enableMultiCue = cvReadIntByName(fs, 0, "enableMultiCue", false);
+    enableSigmaDelta = cvReadIntByName(fs, 0, "enableSigmaDelta", false);
+    enableSuBSENSE = cvReadIntByName(fs, 0, "enableSuBSENSE", false);
+    enableLOBSTER = cvReadIntByName(fs, 0, "enableLOBSTER", false);
 
     cvReleaseFileStorage(&fs);
   }
diff --git a/FrameProcessor.h b/FrameProcessor.h
index 0bb854ee48d5f30285aeb51369ca5646b03eebcd..228fa4c0e8a8b57f0d1a345f0d35700c25a60715 100644
--- a/FrameProcessor.h
+++ b/FrameProcessor.h
@@ -21,56 +21,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 #include "PreProcessor.h"
 
 #include "package_bgs/IBGS.h"
-
-#include "package_bgs/FrameDifferenceBGS.h"
-#include "package_bgs/StaticFrameDifferenceBGS.h"
-#include "package_bgs/WeightedMovingMeanBGS.h"
-#include "package_bgs/WeightedMovingVarianceBGS.h"
-#include "package_bgs/MixtureOfGaussianV1BGS.h"
-#include "package_bgs/MixtureOfGaussianV2BGS.h"
-#include "package_bgs/AdaptiveBackgroundLearning.h"
-#if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >= 4 && CV_SUBMINOR_VERSION >= 3
-#include "package_bgs/GMG.h"
-#endif
-
-#include "package_bgs/dp/DPAdaptiveMedianBGS.h"
-#include "package_bgs/dp/DPGrimsonGMMBGS.h"
-#include "package_bgs/dp/DPZivkovicAGMMBGS.h"
-#include "package_bgs/dp/DPMeanBGS.h"
-#include "package_bgs/dp/DPWrenGABGS.h"
-#include "package_bgs/dp/DPPratiMediodBGS.h"
-#include "package_bgs/dp/DPEigenbackgroundBGS.h"
-#include "package_bgs/dp/DPTextureBGS.h"
-
-#include "package_bgs/tb/T2FGMM_UM.h"
-#include "package_bgs/tb/T2FGMM_UV.h"
-#include "package_bgs/tb/T2FMRF_UM.h"
-#include "package_bgs/tb/T2FMRF_UV.h"
-#include "package_bgs/tb/FuzzySugenoIntegral.h"
-#include "package_bgs/tb/FuzzyChoquetIntegral.h"
-
-#include "package_bgs/lb/LBSimpleGaussian.h"
-#include "package_bgs/lb/LBFuzzyGaussian.h"
-#include "package_bgs/lb/LBMixtureOfGaussians.h"
-#include "package_bgs/lb/LBAdaptiveSOM.h"
-#include "package_bgs/lb/LBFuzzyAdaptiveSOM.h"
-
-#include "package_bgs/ck/LbpMrf.h"
-
-#include "package_bgs/jmo/MultiLayerBGS.h"
-// The PBAS algorithm was removed from BGSLibrary because it is
-// based on patented algorithm ViBE
-// http://www2.ulg.ac.be/telecom/research/vibe/
-//#include "package_bgs/pt/PixelBasedAdaptiveSegmenter.h"
-#include "package_bgs/av/VuMeter.h"
-#include "package_bgs/ae/KDE.h"
-#include "package_bgs/db/IndependentMultimodalBGS.h"
-#include "package_bgs/sjn/SJN_MultiCueBGS.h"
-#include "package_bgs/bl/SigmaDeltaBGS.h"
-
-#include "package_bgs/pl/SuBSENSE.h"
-#include "package_bgs/pl/LOBSTER.h"
-
+#include "package_bgs/bgslibrary.h"
 #include "package_analysis/ForegroundMaskAnalysis.h"
 
 namespace bgslibrary
@@ -84,35 +35,37 @@ namespace bgslibrary
     double duration;
     std::string tictoc;
 
-    cv::Mat img_prep;
+    cv::Mat img_preProcessor;
     PreProcessor* preProcessor;
     bool enablePreProcessor;
 
-    cv::Mat img_framediff;
-    FrameDifferenceBGS* frameDifference;
-    bool enableFrameDifferenceBGS;
+    cv::Mat img_frameDifference;
+    FrameDifference* frameDifference;
+    bool enableFrameDifference;
 
-    cv::Mat img_staticfdiff;
-    StaticFrameDifferenceBGS* staticFrameDifference;
-    bool enableStaticFrameDifferenceBGS;
+    cv::Mat img_staticFrameDifference;
+    StaticFrameDifference* staticFrameDifference;
+    bool enableStaticFrameDifference;
 
-    cv::Mat img_wmovmean;
-    WeightedMovingMeanBGS* weightedMovingMean;
-    bool enableWeightedMovingMeanBGS;
+    cv::Mat img_weightedMovingMean;
+    WeightedMovingMean* weightedMovingMean;
+    bool enableWeightedMovingMean;
 
-    cv::Mat img_movvar;
-    WeightedMovingVarianceBGS* weightedMovingVariance;
-    bool enableWeightedMovingVarianceBGS;
+    cv::Mat img_weightedMovingVariance;
+    WeightedMovingVariance* weightedMovingVariance;
+    bool enableWeightedMovingVariance;
 
-    cv::Mat img_mog1;
-    MixtureOfGaussianV1BGS* mixtureOfGaussianV1BGS;
-    bool enableMixtureOfGaussianV1BGS;
+#if CV_MAJOR_VERSION == 2
+    cv::Mat img_mixtureOfGaussianV1;
+    MixtureOfGaussianV1* mixtureOfGaussianV1;
+    bool enableMixtureOfGaussianV1;
+#endif
 
-    cv::Mat img_mog2;
-    MixtureOfGaussianV2BGS* mixtureOfGaussianV2BGS;
-    bool enableMixtureOfGaussianV2BGS;
+    cv::Mat img_mixtureOfGaussianV2;
+    MixtureOfGaussianV2* mixtureOfGaussianV2;
+    bool enableMixtureOfGaussianV2;
 
-    cv::Mat img_bkgl_fgmask;
+    cv::Mat img_adaptiveBackgroundLearning;
     AdaptiveBackgroundLearning* adaptiveBackgroundLearning;
     bool enableAdaptiveBackgroundLearning;
 
@@ -122,93 +75,95 @@ namespace bgslibrary
     bool enableGMG;
 #endif
 
-    cv::Mat img_adpmed;
-    DPAdaptiveMedianBGS* adaptiveMedian;
-    bool enableDPAdaptiveMedianBGS;
+    cv::Mat img_dpAdaptiveMedian;
+    DPAdaptiveMedian* dpAdaptiveMedian;
+    bool enableDPAdaptiveMedian;
 
-    cv::Mat img_grigmm;
-    DPGrimsonGMMBGS* grimsonGMM;
-    bool enableDPGrimsonGMMBGS;
+    cv::Mat img_dpGrimsonGMM;
+    DPGrimsonGMM* dpGrimsonGMM;
+    bool enableDPGrimsonGMM;
 
-    cv::Mat img_zivgmm;
-    DPZivkovicAGMMBGS* zivkovicAGMM;
-    bool enableDPZivkovicAGMMBGS;
+    cv::Mat img_dpZivkovicAGMM;
+    DPZivkovicAGMM* dpZivkovicAGMM;
+    bool enableDPZivkovicAGMM;
 
-    cv::Mat img_tmpmean;
-    DPMeanBGS* temporalMean;
-    bool enableDPMeanBGS;
+    cv::Mat img_dpTemporalMean;
+    DPMean* dpTemporalMean;
+    bool enableDPMean;
 
-    cv::Mat img_wrenga;
-    DPWrenGABGS* wrenGA;
-    bool enableDPWrenGABGS;
+    cv::Mat img_dpWrenGA;
+    DPWrenGA* dpWrenGA;
+    bool enableDPWrenGA;
 
-    cv::Mat img_pramed;
-    DPPratiMediodBGS* pratiMediod;
-    bool enableDPPratiMediodBGS;
+    cv::Mat img_dpPratiMediod;
+    DPPratiMediod* dpPratiMediod;
+    bool enableDPPratiMediod;
 
-    cv::Mat img_eigbkg;
-    DPEigenbackgroundBGS* eigenBackground;
-    bool enableDPEigenbackgroundBGS;
+    cv::Mat img_dpEigenBackground;
+    DPEigenbackground* dpEigenBackground;
+    bool enableDPEigenbackground;
 
-    cv::Mat img_texbgs;
-    DPTextureBGS* textureBGS;
-    bool enableDPTextureBGS;
+    cv::Mat img_dpTexture;
+    DPTexture* dpTexture;
+    bool enableDPTexture;
 
-    cv::Mat img_t2fgmm_um;
+    cv::Mat img_type2FuzzyGMM_UM;
     T2FGMM_UM* type2FuzzyGMM_UM;
     bool enableT2FGMM_UM;
 
-    cv::Mat img_t2fgmm_uv;
+    cv::Mat img_type2FuzzyGMM_UV;
     T2FGMM_UV* type2FuzzyGMM_UV;
     bool enableT2FGMM_UV;
 
-    cv::Mat img_t2fmrf_um;
+    cv::Mat img_type2FuzzyMRF_UM;
     T2FMRF_UM* type2FuzzyMRF_UM;
     bool enableT2FMRF_UM;
 
-    cv::Mat img_t2fmrf_uv;
+    cv::Mat img_type2FuzzyMRF_UV;
     T2FMRF_UV* type2FuzzyMRF_UV;
     bool enableT2FMRF_UV;
 
-    cv::Mat img_fsi;
+    cv::Mat img_fuzzySugenoIntegral;
     FuzzySugenoIntegral* fuzzySugenoIntegral;
     bool enableFuzzySugenoIntegral;
 
-    cv::Mat img_fci;
+    cv::Mat img_fuzzyChoquetIntegral;
     FuzzyChoquetIntegral* fuzzyChoquetIntegral;
     bool enableFuzzyChoquetIntegral;
 
-    cv::Mat img_lb_sg;
+    cv::Mat img_lbSimpleGaussian;
     LBSimpleGaussian* lbSimpleGaussian;
     bool enableLBSimpleGaussian;
 
-    cv::Mat img_lb_fg;
+    cv::Mat img_lbFuzzyGaussian;
     LBFuzzyGaussian* lbFuzzyGaussian;
     bool enableLBFuzzyGaussian;
 
-    cv::Mat img_lb_mog;
+    cv::Mat img_lbMixtureOfGaussians;
     LBMixtureOfGaussians* lbMixtureOfGaussians;
     bool enableLBMixtureOfGaussians;
 
-    cv::Mat img_lb_som;
+    cv::Mat img_lbAdaptiveSOM;
     LBAdaptiveSOM* lbAdaptiveSOM;
     bool enableLBAdaptiveSOM;
 
-    cv::Mat img_lb_fsom;
+    cv::Mat img_lbFuzzyAdaptiveSOM;
     LBFuzzyAdaptiveSOM* lbFuzzyAdaptiveSOM;
     bool enableLBFuzzyAdaptiveSOM;
 
-    cv::Mat img_lbp_mrf;
-    LbpMrf* lbpMrf;
+    cv::Mat img_lbpMrf;
+    LBP_MRF* lbpMrf;
     bool enableLbpMrf;
 
-    cv::Mat img_mlbgs;
-    MultiLayerBGS* multiLayerBGS;
-    bool enableMultiLayerBGS;
+#if CV_MAJOR_VERSION == 2
+    cv::Mat img_multiLayer;
+    MultiLayer* multiLayer;
+    bool enableMultiLayer;
+#endif
 
-    //cv::Mat img_pt_pbas;
-    //PixelBasedAdaptiveSegmenter* pixelBasedAdaptiveSegmenter;
-    //bool enablePBAS;
+    cv::Mat img_pixelBasedAdaptiveSegmenter;
+    PixelBasedAdaptiveSegmenter* pixelBasedAdaptiveSegmenter;
+    bool enablePBAS;
 
     cv::Mat img_vumeter;
     VuMeter* vuMeter;
@@ -219,24 +174,24 @@ namespace bgslibrary
     bool enableKDE;
 
     cv::Mat img_imbs;
-    IndependentMultimodalBGS* imbs;
+    IndependentMultimodal* imbs;
     bool enableIMBS;
 
-    cv::Mat img_mcbgs;
-    SJN_MultiCueBGS* mcbgs;
-    bool enableMultiCueBGS;
+    cv::Mat img_multiCue;
+    MultiCue* multiCue;
+    bool enableMultiCue;
 
-    cv::Mat img_sdbgs;
-    SigmaDeltaBGS* sdbgs;
-    bool enableSigmaDeltaBGS;
+    cv::Mat img_sigmaDelta;
+    SigmaDelta* sigmaDelta;
+    bool enableSigmaDelta;
 
-    cv::Mat img_ssbgs;
-    SuBSENSEBGS* ssbgs;
-    bool enableSuBSENSEBGS;
+    cv::Mat img_subSENSE;
+    SuBSENSE* subSENSE;
+    bool enableSuBSENSE;
 
-    cv::Mat img_lobgs;
-    LOBSTERBGS* lobgs;
-    bool enableLOBSTERBGS;
+    cv::Mat img_lobster;
+    LOBSTER* lobster;
+    bool enableLOBSTER;
 
     ForegroundMaskAnalysis* foregroundMaskAnalysis;
     bool enableForegroundMaskAnalysis;
diff --git a/Main.cpp b/Main.cpp
index 1d170adf54d9500116d598f2b1e390cb4e21e304..7a406d9a859c56c6603c76f09d48cf08e326fc97 100644
--- a/Main.cpp
+++ b/Main.cpp
@@ -29,7 +29,7 @@ namespace bgslibrary
     static void start(int argc, const char **argv)
     {
       std::cout << "-----------------------------------------" << std::endl;
-      std::cout << "Background Subtraction Library v1.9.2     " << std::endl;
+      std::cout << "Background Subtraction Library v2.0.0     " << std::endl;
       std::cout << "http://code.google.com/p/bgslibrary       " << std::endl;
       std::cout << "by:                                       " << std::endl;
       std::cout << "Andrews Sobral (andrewssobral@gmail.com)  " << std::endl;
diff --git a/PreProcessor.cpp b/PreProcessor.cpp
index 6f4ebbe964c197f35c21654d6eeb15e85337a40a..4c13f7e4c3fcd39959b93cb8b6484f45e55e2733 100644
--- a/PreProcessor.cpp
+++ b/PreProcessor.cpp
@@ -95,7 +95,7 @@ namespace bgslibrary
     cv2DRotationMatrix(center, angle, 1.0, mapMatrix);
     cvWarpAffine(image, rotatedImage, mapMatrix, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll(0));
 
-    cv::Mat img_rot(rotatedImage);
+    cv::Mat img_rot = cv::cvarrToMat(rotatedImage);
     img_rot.copyTo(img_output);
 
     cvReleaseImage(&image);
diff --git a/PreProcessor.h b/PreProcessor.h
index da46cce7e0955e19130499e159707d23f5f721d0..2e6e61c75ddd3d8e21362a83e800fe7ab846db48 100644
--- a/PreProcessor.h
+++ b/PreProcessor.h
@@ -19,7 +19,6 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 #include <iostream>
 #include <opencv2/opencv.hpp>
 
-
 namespace bgslibrary
 {
   class PreProcessor
diff --git a/README.md b/README.md
index a35389ace6bb41579661f3032fc5fd7d05ff0f15..3b8a3cba5c0d19175ddfe3453e7e2a6e27daa0d7 100644
--- a/README.md
+++ b/README.md
@@ -4,13 +4,13 @@ A Background Subtraction Library
 
 [![bgslibrary](http://i.giphy.com/5A94AZahSIVOw.gif)](https://youtu.be/_UbERwuQ0OU)
 
-Last Page Update: **12/03/2017**
+Last Page Update: **18/03/2017**
 
-Latest Library Version: **1.9.2** (see [Release Notes](https://github.com/andrewssobral/bgslibrary/wiki/Release-notes) for more info)
+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 compiles under Windows, Linux, and Mac OS X. Currently the library contains **37** 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. 
+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 BGSLibrary is based on OpenCV 2.X, if you want to use with OpenCV 3.x please check-out our [opencv3](https://github.com/andrewssobral/bgslibrary/tree/opencv3) branch.
+***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)
@@ -77,6 +77,7 @@ Some algorithms of the BGSLibrary were used successfully in the following papers
 
 * (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
 ------
 
diff --git a/VideoAnalysis.cpp b/VideoAnalysis.cpp
index 1e46542c9124cd69d3cb030659f236564e328d54..9c8020a8c2aef4a16c0bdc36c491d7d7030ba09a 100644
--- a/VideoAnalysis.cpp
+++ b/VideoAnalysis.cpp
@@ -18,7 +18,9 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 
 namespace bgslibrary
 {
-  VideoAnalysis::VideoAnalysis() : use_file(false), use_camera(false), cameraIndex(0), use_comp(false), frameToStop(0)
+  VideoAnalysis::VideoAnalysis() :
+    use_file(false), use_camera(false), cameraIndex(0),
+    use_comp(false), frameToStop(0)
   {
     std::cout << "VideoAnalysis()" << std::endl;
   }
@@ -32,8 +34,9 @@ namespace bgslibrary
   {
     bool flag = false;
 
+#if CV_MAJOR_VERSION == 2
     const char* keys =
-      "{hp|help|false|Print help message}"
+      "{hp|help|false|Print this message}"
       "{uf|use_file|false|Use video file}"
       "{fn|filename||Specify video file}"
       "{uc|use_cam|false|Use camera}"
@@ -42,21 +45,63 @@ namespace bgslibrary
       "{st|stopAt|0|Frame number to stop}"
       "{im|imgref||Specify image file}"
       ;
+#elif CV_MAJOR_VERSION == 3
+    const std::string keys =
+      "{h help ?     |     | Print this message   }"
+      "{uf use_file  |false| Use a video file     }"
+      "{fn filename  |     | Specify a video file }"
+      "{uc use_cam   |false| Use a webcamera      }"
+      "{ca camera    | 0   | Specify camera index }"
+      "{co use_comp  |false| Use mask comparator  }"
+      "{st stopAt    | 0   | Frame number to stop }"
+      "{im imgref    |     | Specify a image file }"
+      ;
+#endif
+
     cv::CommandLineParser cmd(argc, argv, keys);
 
+#if CV_MAJOR_VERSION == 2
     if (argc <= 1 || cmd.get<bool>("help") == true)
     {
       std::cout << "Usage: " << argv[0] << " [options]" << std::endl;
-      std::cout << "Avaible options:" << std::endl;
+      std::cout << "Available options:" << std::endl;
       cmd.printParams();
       return false;
     }
+#elif CV_MAJOR_VERSION == 3
+    if (argc <= 1 || cmd.has("help"))
+    {
+      std::cout << "Usage: " << argv[0] << " [options]" << std::endl;
+      std::cout << "Available options:" << std::endl;
+      cmd.printMessage();
+      return false;
+    }
+    if (!cmd.check())
+    {
+      cmd.printErrors();
+      return false;
+    }
+#endif
+
+    use_file = cmd.get<bool>("uf"); //use_file
+    filename = cmd.get<std::string>("fn"); //filename
+    use_camera = cmd.get<bool>("uc"); //use_cam
+    cameraIndex = cmd.get<int>("ca"); //camera
+    use_comp = cmd.get<bool>("co"); //use_comp
+    frameToStop = cmd.get<int>("st"); //stopAt
+    imgref = cmd.get<std::string>("im"); //imgref
+
+    std::cout << "use_file:    " << use_file << std::endl;
+    std::cout << "filename:    " << filename << std::endl;
+    std::cout << "use_camera:  " << use_camera << std::endl;
+    std::cout << "cameraIndex: " << cameraIndex << std::endl;
+    std::cout << "use_comp:    " << use_comp << std::endl;
+    std::cout << "frameToStop: " << frameToStop << std::endl;
+    std::cout << "imgref:      " << imgref << std::endl;
+    //return false;
 
-    use_file = cmd.get<bool>("use_file");
     if (use_file)
     {
-      filename = cmd.get<std::string>("filename");
-
       if (filename.empty())
       {
         std::cout << "Specify filename" << std::endl;
@@ -66,26 +111,15 @@ namespace bgslibrary
       flag = true;
     }
 
-    use_camera = cmd.get<bool>("use_cam");
     if (use_camera)
-    {
-      cameraIndex = cmd.get<int>("camera");
       flag = true;
-    }
 
-    if (flag == true)
+    if (flag && use_comp)
     {
-      use_comp = cmd.get<bool>("use_comp");
-      if (use_comp)
+      if (imgref.empty())
       {
-        frameToStop = cmd.get<int>("stopAt");
-        imgref = cmd.get<std::string>("imgref");
-
-        if (imgref.empty())
-        {
-          std::cout << "Specify image reference" << std::endl;
-          return false;
-        }
+        std::cout << "Specify image reference" << std::endl;
+        return false;
       }
     }
 
diff --git a/VideoCapture.cpp b/VideoCapture.cpp
index 4de5b90f9a1f02eadeba1a7760f40f51c1f996f5..b302a3f5e2921bef2c1424819f244efd5b76ac18 100644
--- a/VideoCapture.cpp
+++ b/VideoCapture.cpp
@@ -15,6 +15,7 @@ You should have received a copy of the GNU General Public License
 along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "VideoCapture.h"
+#include <opencv2/highgui/highgui_c.h>
 
 namespace bgslibrary
 {
@@ -74,8 +75,11 @@ namespace bgslibrary
     }
   }
 
-  VideoCapture::VideoCapture() : key(0), start_time(0), delta_time(0), freq(0), fps(0), frameNumber(0), stopAt(0),
-    useCamera(false), useVideo(false), input_resize_percent(100), showOutput(true), enableFlip(false)
+  VideoCapture::VideoCapture() :
+    key(0), start_time(0), delta_time(0), freq(0),
+    fps(0), frameNumber(0), stopAt(0), useCamera(false),
+    useVideo(false), input_resize_percent(100), showOutput(true),
+    enableFlip(false), cameraIndex(0)
   {
     std::cout << "VideoCapture()" << std::endl;
   }
@@ -101,10 +105,10 @@ namespace bgslibrary
   void VideoCapture::setUpCamera()
   {
     std::cout << "Camera index:" << cameraIndex << std::endl;
-    capture = cvCaptureFromCAM(cameraIndex);
+    capture.open(cameraIndex);
 
-    if (!capture)
-      std::cerr << "Cannot open initialize webcam!\n" << std::endl;
+    if (!capture.isOpened())
+      std::cerr << "Cannot initialize webcam!\n" << std::endl;
   }
 
   void VideoCapture::setVideo(std::string filename)
@@ -117,10 +121,13 @@ namespace bgslibrary
 
   void VideoCapture::setUpVideo()
   {
-    capture = cvCaptureFromFile(videoFileName.c_str());
+    std::cout << "Openning: " << videoFileName << std::endl;
+    capture.open(videoFileName.c_str());
 
-    if (!capture)
+    if (!capture.isOpened())
       std::cerr << "Cannot open video file " << videoFileName << std::endl;
+    else
+      std::cout << "OK" << std::endl;
   }
 
   void VideoCapture::start()
@@ -129,17 +136,21 @@ namespace bgslibrary
 
     if (useCamera) setUpCamera();
     if (useVideo)  setUpVideo();
-    if (!capture)  std::cerr << "Capture error..." << std::endl;
+    //if (!capture)  std::cerr << "Capture error..." << std::endl;
 
-    int input_fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
+    int input_fps = capture.get(CV_CAP_PROP_FPS);
     std::cout << "input->fps:" << input_fps << std::endl;
 
+    /*
     IplImage* frame1 = cvQueryFrame(capture);
-    frame = cvCreateImage(cvSize((int)((frame1->width*input_resize_percent) / 100), (int)((frame1->height*input_resize_percent) / 100)), frame1->depth, frame1->nChannels);
+    frame = cvCreateImage(cvSize(
+      (int)((frame1->width*input_resize_percent) / 100),
+      (int)((frame1->height*input_resize_percent) / 100)), frame1->depth, frame1->nChannels);
     //cvCreateImage(cvSize(frame1->width/input_resize_factor, frame1->height/input_resize_factor), frame1->depth, frame1->nChannels);
     std::cout << "input->resize_percent:" << input_resize_percent << std::endl;
     std::cout << "input->width:" << frame->width << std::endl;
     std::cout << "input->height:" << frame->height << std::endl;
+    */
 
     double loopDelay = 33.333;
     if (input_fps > 0)
@@ -152,13 +163,14 @@ namespace bgslibrary
     {
       frameNumber++;
 
-      frame1 = cvQueryFrame(capture);
-      if (!frame1) break;
+      cv::Mat frame;
+      capture >> frame;
+      if (frame.empty()) break;
 
-      cvResize(frame1, frame);
+      //cvResize(frame1, frame);
 
-      if (enableFlip)
-        cvFlip(frame, frame, 0);
+      //if (enableFlip)
+      //  cvFlip(frame, frame, 0);
 
       if (VC_ROI::use_roi == true && VC_ROI::roi_defined == false && firstTime == true)
       {
@@ -166,7 +178,9 @@ namespace bgslibrary
 
         do
         {
-          cv::Mat img_input(frame);
+          //cv::Mat img_input = cv::cvarrToMat(frame);
+          cv::Mat img_input;
+          frame.copyTo(img_input);
 
           if (showOutput)
           {
@@ -202,11 +216,13 @@ namespace bgslibrary
 
       if (VC_ROI::use_roi == true && VC_ROI::roi_defined == true)
       {
-        CvRect rect = cvRect(VC_ROI::roi_x0, VC_ROI::roi_y0, VC_ROI::roi_x1 - VC_ROI::roi_x0, VC_ROI::roi_y1 - VC_ROI::roi_y0);
-        cvSetImageROI(frame, rect);
+        cv::Rect roi(VC_ROI::roi_x0, VC_ROI::roi_y0, VC_ROI::roi_x1 - VC_ROI::roi_x0, VC_ROI::roi_y1 - VC_ROI::roi_y0);
+        frame = frame(roi);
       }
 
-      cv::Mat img_input(frame);
+      //cv::Mat img_input = cv::cvarrToMat(frame);
+      cv::Mat img_input;
+      frame.copyTo(img_input);
 
       if (showOutput)
         cv::imshow("Input", img_input);
@@ -221,7 +237,7 @@ namespace bgslibrary
       fps = freq / delta_time;
       //std::cout << "FPS: " << fps << std::endl;
 
-      cvResetImageROI(frame);
+      //cvResetImageROI(frame);
 
       key = cvWaitKey(loopDelay);
       //std::cout << "key: " << key << std::endl;
@@ -238,7 +254,7 @@ namespace bgslibrary
       firstTime = false;
     } while (1);
 
-    cvReleaseCapture(&capture);
+    capture.release();
   }
 
   void VideoCapture::saveConfig()
diff --git a/VideoCapture.h b/VideoCapture.h
index a8ba2ff25017203d9b800006515675ec5766ed7a..0e88c87023b8fedbb4f089e0bf19dfc0222c3d28 100644
--- a/VideoCapture.h
+++ b/VideoCapture.h
@@ -18,7 +18,8 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 
 #include <iostream>
 #include <opencv2/opencv.hpp>
-
+#include <opencv2/imgproc/imgproc_c.h>
+#include <opencv2/imgproc/types_c.h>
 
 #include "Config.h"
 #include "IFrameProcessor.h"
@@ -29,7 +30,7 @@ namespace bgslibrary
   {
   private:
     IFrameProcessor* frameProcessor;
-    CvCapture* capture;
+    cv::VideoCapture capture;
     IplImage* frame;
     int key;
     int64 start_time;
diff --git a/config/FrameProcessor.xml b/config/FrameProcessor.xml
index 5155bbf218b7a34466a2ab7b190ed97eac1a5b97..3cf398cc4f421bd0c42bf3a19631c425af5add42 100644
--- a/config/FrameProcessor.xml
+++ b/config/FrameProcessor.xml
@@ -3,22 +3,22 @@
 <tictoc>""</tictoc>
 <enablePreProcessor>1</enablePreProcessor>
 <enableForegroundMaskAnalysis>0</enableForegroundMaskAnalysis>
-<enableFrameDifferenceBGS>1</enableFrameDifferenceBGS>
-<enableStaticFrameDifferenceBGS>0</enableStaticFrameDifferenceBGS>
-<enableWeightedMovingMeanBGS>0</enableWeightedMovingMeanBGS>
-<enableWeightedMovingVarianceBGS>0</enableWeightedMovingVarianceBGS>
-<enableMixtureOfGaussianV1BGS>0</enableMixtureOfGaussianV1BGS>
-<enableMixtureOfGaussianV2BGS>0</enableMixtureOfGaussianV2BGS>
+<enableFrameDifference>1</enableFrameDifference>
+<enableStaticFrameDifference>0</enableStaticFrameDifference>
+<enableWeightedMovingMean>0</enableWeightedMovingMean>
+<enableWeightedMovingVariance>0</enableWeightedMovingVariance>
+<enableMixtureOfGaussianV1>0</enableMixtureOfGaussianV1>
+<enableMixtureOfGaussianV2>0</enableMixtureOfGaussianV2>
 <enableAdaptiveBackgroundLearning>0</enableAdaptiveBackgroundLearning>
 <enableGMG>0</enableGMG>
-<enableDPAdaptiveMedianBGS>0</enableDPAdaptiveMedianBGS>
-<enableDPGrimsonGMMBGS>0</enableDPGrimsonGMMBGS>
-<enableDPZivkovicAGMMBGS>0</enableDPZivkovicAGMMBGS>
-<enableDPMeanBGS>0</enableDPMeanBGS>
-<enableDPWrenGABGS>0</enableDPWrenGABGS>
-<enableDPPratiMediodBGS>0</enableDPPratiMediodBGS>
-<enableDPEigenbackgroundBGS>0</enableDPEigenbackgroundBGS>
-<enableDPTextureBGS>0</enableDPTextureBGS>
+<enableDPAdaptiveMedian>0</enableDPAdaptiveMedian>
+<enableDPGrimsonGMM>0</enableDPGrimsonGMM>
+<enableDPZivkovicAGMM>0</enableDPZivkovicAGMM>
+<enableDPMean>0</enableDPMean>
+<enableDPWrenGA>0</enableDPWrenGA>
+<enableDPPratiMediod>0</enableDPPratiMediod>
+<enableDPEigenbackground>0</enableDPEigenbackground>
+<enableDPTexture>0</enableDPTexture>
 <enableT2FGMM_UM>0</enableT2FGMM_UM>
 <enableT2FGMM_UV>0</enableT2FGMM_UV>
 <enableT2FMRF_UM>0</enableT2FMRF_UM>
@@ -31,12 +31,13 @@
 <enableLBAdaptiveSOM>0</enableLBAdaptiveSOM>
 <enableLBFuzzyAdaptiveSOM>0</enableLBFuzzyAdaptiveSOM>
 <enableLbpMrf>0</enableLbpMrf>
-<enableMultiLayerBGS>0</enableMultiLayerBGS>
+<enableMultiLayer>0</enableMultiLayer>
+<enablePBAS>0</enablePBAS>
 <enableVuMeter>0</enableVuMeter>
 <enableKDE>0</enableKDE>
 <enableIMBS>0</enableIMBS>
-<enableMultiCueBGS>0</enableMultiCueBGS>
-<enableSigmaDeltaBGS>0</enableSigmaDeltaBGS>
-<enableSuBSENSEBGS>0</enableSuBSENSEBGS>
-<enableLOBSTERBGS>0</enableLOBSTERBGS>
+<enableMultiCue>0</enableMultiCue>
+<enableSigmaDelta>0</enableSigmaDelta>
+<enableSuBSENSE>0</enableSuBSENSE>
+<enableLOBSTER>0</enableLOBSTER>
 </opencv_storage>
diff --git a/dataset/demo.avi b/dataset/demo.avi
new file mode 100644
index 0000000000000000000000000000000000000000..df20707af3b0a2cbcaaae127b982e1886b1d2aa7
Binary files /dev/null and b/dataset/demo.avi differ
diff --git a/frames/1.png b/dataset/frames/1.png
similarity index 100%
rename from frames/1.png
rename to dataset/frames/1.png
diff --git a/frames/10.png b/dataset/frames/10.png
similarity index 100%
rename from frames/10.png
rename to dataset/frames/10.png
diff --git a/frames/11.png b/dataset/frames/11.png
similarity index 100%
rename from frames/11.png
rename to dataset/frames/11.png
diff --git a/frames/12.png b/dataset/frames/12.png
similarity index 100%
rename from frames/12.png
rename to dataset/frames/12.png
diff --git a/frames/13.png b/dataset/frames/13.png
similarity index 100%
rename from frames/13.png
rename to dataset/frames/13.png
diff --git a/frames/14.png b/dataset/frames/14.png
similarity index 100%
rename from frames/14.png
rename to dataset/frames/14.png
diff --git a/frames/15.png b/dataset/frames/15.png
similarity index 100%
rename from frames/15.png
rename to dataset/frames/15.png
diff --git a/frames/16.png b/dataset/frames/16.png
similarity index 100%
rename from frames/16.png
rename to dataset/frames/16.png
diff --git a/frames/17.png b/dataset/frames/17.png
similarity index 100%
rename from frames/17.png
rename to dataset/frames/17.png
diff --git a/frames/18.png b/dataset/frames/18.png
similarity index 100%
rename from frames/18.png
rename to dataset/frames/18.png
diff --git a/frames/19.png b/dataset/frames/19.png
similarity index 100%
rename from frames/19.png
rename to dataset/frames/19.png
diff --git a/frames/2.png b/dataset/frames/2.png
similarity index 100%
rename from frames/2.png
rename to dataset/frames/2.png
diff --git a/frames/20.png b/dataset/frames/20.png
similarity index 100%
rename from frames/20.png
rename to dataset/frames/20.png
diff --git a/frames/21.png b/dataset/frames/21.png
similarity index 100%
rename from frames/21.png
rename to dataset/frames/21.png
diff --git a/frames/22.png b/dataset/frames/22.png
similarity index 100%
rename from frames/22.png
rename to dataset/frames/22.png
diff --git a/frames/23.png b/dataset/frames/23.png
similarity index 100%
rename from frames/23.png
rename to dataset/frames/23.png
diff --git a/frames/24.png b/dataset/frames/24.png
similarity index 100%
rename from frames/24.png
rename to dataset/frames/24.png
diff --git a/frames/25.png b/dataset/frames/25.png
similarity index 100%
rename from frames/25.png
rename to dataset/frames/25.png
diff --git a/frames/26.png b/dataset/frames/26.png
similarity index 100%
rename from frames/26.png
rename to dataset/frames/26.png
diff --git a/frames/27.png b/dataset/frames/27.png
similarity index 100%
rename from frames/27.png
rename to dataset/frames/27.png
diff --git a/frames/28.png b/dataset/frames/28.png
similarity index 100%
rename from frames/28.png
rename to dataset/frames/28.png
diff --git a/frames/29.png b/dataset/frames/29.png
similarity index 100%
rename from frames/29.png
rename to dataset/frames/29.png
diff --git a/frames/3.png b/dataset/frames/3.png
similarity index 100%
rename from frames/3.png
rename to dataset/frames/3.png
diff --git a/frames/30.png b/dataset/frames/30.png
similarity index 100%
rename from frames/30.png
rename to dataset/frames/30.png
diff --git a/frames/31.png b/dataset/frames/31.png
similarity index 100%
rename from frames/31.png
rename to dataset/frames/31.png
diff --git a/frames/32.png b/dataset/frames/32.png
similarity index 100%
rename from frames/32.png
rename to dataset/frames/32.png
diff --git a/frames/33.png b/dataset/frames/33.png
similarity index 100%
rename from frames/33.png
rename to dataset/frames/33.png
diff --git a/frames/34.png b/dataset/frames/34.png
similarity index 100%
rename from frames/34.png
rename to dataset/frames/34.png
diff --git a/frames/35.png b/dataset/frames/35.png
similarity index 100%
rename from frames/35.png
rename to dataset/frames/35.png
diff --git a/frames/36.png b/dataset/frames/36.png
similarity index 100%
rename from frames/36.png
rename to dataset/frames/36.png
diff --git a/frames/37.png b/dataset/frames/37.png
similarity index 100%
rename from frames/37.png
rename to dataset/frames/37.png
diff --git a/frames/38.png b/dataset/frames/38.png
similarity index 100%
rename from frames/38.png
rename to dataset/frames/38.png
diff --git a/frames/39.png b/dataset/frames/39.png
similarity index 100%
rename from frames/39.png
rename to dataset/frames/39.png
diff --git a/frames/4.png b/dataset/frames/4.png
similarity index 100%
rename from frames/4.png
rename to dataset/frames/4.png
diff --git a/frames/40.png b/dataset/frames/40.png
similarity index 100%
rename from frames/40.png
rename to dataset/frames/40.png
diff --git a/frames/41.png b/dataset/frames/41.png
similarity index 100%
rename from frames/41.png
rename to dataset/frames/41.png
diff --git a/frames/42.png b/dataset/frames/42.png
similarity index 100%
rename from frames/42.png
rename to dataset/frames/42.png
diff --git a/frames/43.png b/dataset/frames/43.png
similarity index 100%
rename from frames/43.png
rename to dataset/frames/43.png
diff --git a/frames/44.png b/dataset/frames/44.png
similarity index 100%
rename from frames/44.png
rename to dataset/frames/44.png
diff --git a/frames/45.png b/dataset/frames/45.png
similarity index 100%
rename from frames/45.png
rename to dataset/frames/45.png
diff --git a/frames/46.png b/dataset/frames/46.png
similarity index 100%
rename from frames/46.png
rename to dataset/frames/46.png
diff --git a/frames/47.png b/dataset/frames/47.png
similarity index 100%
rename from frames/47.png
rename to dataset/frames/47.png
diff --git a/frames/48.png b/dataset/frames/48.png
similarity index 100%
rename from frames/48.png
rename to dataset/frames/48.png
diff --git a/frames/49.png b/dataset/frames/49.png
similarity index 100%
rename from frames/49.png
rename to dataset/frames/49.png
diff --git a/frames/5.png b/dataset/frames/5.png
similarity index 100%
rename from frames/5.png
rename to dataset/frames/5.png
diff --git a/frames/50.png b/dataset/frames/50.png
similarity index 100%
rename from frames/50.png
rename to dataset/frames/50.png
diff --git a/frames/51.png b/dataset/frames/51.png
similarity index 100%
rename from frames/51.png
rename to dataset/frames/51.png
diff --git a/frames/6.png b/dataset/frames/6.png
similarity index 100%
rename from frames/6.png
rename to dataset/frames/6.png
diff --git a/frames/7.png b/dataset/frames/7.png
similarity index 100%
rename from frames/7.png
rename to dataset/frames/7.png
diff --git a/frames/8.png b/dataset/frames/8.png
similarity index 100%
rename from frames/8.png
rename to dataset/frames/8.png
diff --git a/frames/9.png b/dataset/frames/9.png
similarity index 100%
rename from frames/9.png
rename to dataset/frames/9.png
diff --git a/demos/DemoFrameDifferenceBGS.cpp b/demos/DemoFrameDifferenceBGS.cpp
deleted file mode 100644
index 5a449e21dda93981e91b1a4758bb8247882cb897..0000000000000000000000000000000000000000
--- a/demos/DemoFrameDifferenceBGS.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "package_bgs/FrameDifferenceBGS.h"
-
-int main(int argc, char **argv)
-{
-  CvCapture *capture = 0;
-  
-  capture = cvCaptureFromCAM(0);
-  //capture = cvCaptureFromAVI("video.avi");
-  
-  if(!capture){
-    std::cerr << "Cannot open initialize webcam!" << std::endl;
-    return 1;
-  }
-  
-  IplImage *frame = cvQueryFrame(capture);
-  
-  FrameDifferenceBGS* bgs = new FrameDifferenceBGS;
-
-  int key = 0;
-  while(key != 'q')
-  {
-    frame = cvQueryFrame(capture);
-
-    if(!frame) break;
-
-    cv::Mat img_input(frame,true);
-    cv::resize(img_input,img_input,cv::Size(320,240));
-    cv::imshow("input", img_input);
-    
-    cv::Mat img_mask;
-    bgs->process(img_input, img_mask); // automatically shows the foreground mask image
-    
-    //if(!img_mask.empty())
-    //  do something
-    
-    key = cvWaitKey(1);
-  }
-
-  delete bgs;
-
-  cvDestroyAllWindows();
-  cvReleaseCapture(&capture);
-  
-  return 0;
-}
diff --git a/demos/DemoMultiLayerBGS.cpp b/demos/DemoMultiLayerBGS.cpp
deleted file mode 100644
index 08abe30df39d937e8210c1311fa5a89976d6fe1d..0000000000000000000000000000000000000000
--- a/demos/DemoMultiLayerBGS.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "package_bgs/jmo/MultiLayerBGS.h"
-
-int main(int argc, char **argv)
-{
-  CvCapture *capture = 0;
-  
-  capture = cvCaptureFromCAM(0);
-  //capture = cvCaptureFromAVI("video.avi");
-  
-  if(!capture){
-    std::cerr << "Cannot open initialize webcam!" << std::endl;
-    return 1;
-  }
-  
-  IplImage *frame = cvQueryFrame(capture);
-  
-  MultiLayerBGS* bgs = new MultiLayerBGS;
-
-  int key = 0;
-  while(key != 'q')
-  {
-    frame = cvQueryFrame(capture);
-
-    if(!frame) break;
-
-    cv::Mat img_input(frame,true);
-    cv::resize(img_input,img_input,cv::Size(320,240));
-    cv::imshow("input", img_input);
-    
-    cv::Mat img_mask;
-    bgs->process(img_input, img_mask); // automatically shows the foreground mask image
-    
-    //if(!img_mask.empty())
-    //  do something
-    
-    key = cvWaitKey(1);
-  }
-
-  delete bgs;
-
-  cvDestroyAllWindows();
-  cvReleaseCapture(&capture);
-  
-  return 0;
-}
diff --git a/demos/linux_ubuntu/.gitignore b/demos/linux_ubuntu/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..46d4288c817cdfd5c83571222c2c43e4674d6c32
--- /dev/null
+++ b/demos/linux_ubuntu/.gitignore
@@ -0,0 +1,8 @@
+# Ignore everything in this directory
+*
+# Except these files
+!.gitignore
+!CMakeLists.txt
+!FrameDifferenceTest.cpp
+!README.txt
+!config/
diff --git a/example_linux/CMakeLists.txt b/demos/linux_ubuntu/CMakeLists.txt
similarity index 66%
rename from example_linux/CMakeLists.txt
rename to demos/linux_ubuntu/CMakeLists.txt
index 9317e55f501298c9035145675a6f84a5e22366ff..8cc38e8852cd8facf728c49ca358e6a641feacd2 100644
--- a/example_linux/CMakeLists.txt
+++ b/demos/linux_ubuntu/CMakeLists.txt
@@ -9,15 +9,14 @@ find_package(OpenCV REQUIRED)
 
 file(GLOB source FrameDifferenceTest.cpp)
 
-file(GLOB_RECURSE bgs_src ../package_bgs/*.cpp ../package_bgs/*.c)
-file(GLOB_RECURSE bgs_include ../package_bgs/*.h)
+file(GLOB_RECURSE bgs_src ../../package_bgs/*.cpp ../../package_bgs/*.c ../../package_analysis/*.cpp)
+file(GLOB_RECURSE bgs_inc ../../package_bgs/*.h ../../package_analysis/*.h)
 
 include_directories(${CMAKE_SOURCE_DIR})
 
 add_library(bgs SHARED ${bgs_src})
 target_link_libraries(bgs ${OpenCV_LIBS})
-set_property(TARGET bgs PROPERTY PUBLIC_HEADER ${bgs_include})
+set_property(TARGET bgs PROPERTY PUBLIC_HEADER ${bgs_inc})
 
 add_executable(FrameDifferenceTest ${source})
 target_link_libraries(FrameDifferenceTest ${OpenCV_LIBS} bgs)
-
diff --git a/example_macosx/FrameDifferenceTest.cpp b/demos/linux_ubuntu/FrameDifferenceTest.cpp
similarity index 87%
rename from example_macosx/FrameDifferenceTest.cpp
rename to demos/linux_ubuntu/FrameDifferenceTest.cpp
index 56f1e7cb3cc0c620bb0cdc2c1ca90a2725089a58..7ebe8b1aa19ef3495d0cf57868340577a83f9134 100644
--- a/example_macosx/FrameDifferenceTest.cpp
+++ b/demos/linux_ubuntu/FrameDifferenceTest.cpp
@@ -2,7 +2,9 @@
 #include <cv.h>
 #include <highgui.h>
 
-#include "../package_bgs/FrameDifferenceBGS.h"
+#include "../../package_bgs/FrameDifference.h"
+
+using namespace bgslibrary::algorithms;
 
 int main(int argc, char **argv)
 {
@@ -15,7 +17,7 @@ int main(int argc, char **argv)
   }
 
   IBGS *bgs;
-  bgs = new FrameDifferenceBGS;
+  bgs = new FrameDifference;
 
   IplImage *frame;
   while(1)
diff --git a/example_linux/README.txt b/demos/linux_ubuntu/README.txt
similarity index 100%
rename from example_linux/README.txt
rename to demos/linux_ubuntu/README.txt
diff --git a/demos/linux_ubuntu/config/.gitignore b/demos/linux_ubuntu/config/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..8ee04a01eb210a035d02f190538c5235aebc7277
--- /dev/null
+++ b/demos/linux_ubuntu/config/.gitignore
@@ -0,0 +1,4 @@
+# Ignore everything in this directory
+*
+# Except these files
+!.gitignore
\ No newline at end of file
diff --git a/demos/macosx/.gitignore b/demos/macosx/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..46d4288c817cdfd5c83571222c2c43e4674d6c32
--- /dev/null
+++ b/demos/macosx/.gitignore
@@ -0,0 +1,8 @@
+# Ignore everything in this directory
+*
+# Except these files
+!.gitignore
+!CMakeLists.txt
+!FrameDifferenceTest.cpp
+!README.txt
+!config/
diff --git a/example_macosx/CMakeLists.txt b/demos/macosx/CMakeLists.txt
similarity index 79%
rename from example_macosx/CMakeLists.txt
rename to demos/macosx/CMakeLists.txt
index 107303fdf769fda32d152e24c25343e9b24cd12a..a9775d850e56c7d5aa6669ae652980394f95a968 100644
--- a/example_macosx/CMakeLists.txt
+++ b/demos/macosx/CMakeLists.txt
@@ -20,15 +20,14 @@ find_package(OpenCV REQUIRED)
 
 file(GLOB source FrameDifferenceTest.cpp)
 
-file(GLOB_RECURSE bgs_src ../package_bgs/*.cpp ../package_bgs/*.c)
-file(GLOB_RECURSE bgs_include ../package_bgs/*.h)
+file(GLOB_RECURSE bgs_src ../../package_bgs/*.cpp ../../package_bgs/*.c ../../package_analysis/*.cpp)
+file(GLOB_RECURSE bgs_inc ../../package_bgs/*.h ../../package_analysis/*.h)
 
 include_directories(${CMAKE_SOURCE_DIR})
 
 add_library(bgs SHARED ${bgs_src})
 target_link_libraries(bgs ${OpenCV_LIBS})
-set_property(TARGET bgs PROPERTY PUBLIC_HEADER ${bgs_include})
+set_property(TARGET bgs PROPERTY PUBLIC_HEADER ${bgs_inc})
 
 add_executable(FrameDifferenceTest ${source})
 target_link_libraries(FrameDifferenceTest ${OpenCV_LIBS} bgs)
-
diff --git a/example_linux/FrameDifferenceTest.cpp b/demos/macosx/FrameDifferenceTest.cpp
similarity index 87%
rename from example_linux/FrameDifferenceTest.cpp
rename to demos/macosx/FrameDifferenceTest.cpp
index 56f1e7cb3cc0c620bb0cdc2c1ca90a2725089a58..7ebe8b1aa19ef3495d0cf57868340577a83f9134 100644
--- a/example_linux/FrameDifferenceTest.cpp
+++ b/demos/macosx/FrameDifferenceTest.cpp
@@ -2,7 +2,9 @@
 #include <cv.h>
 #include <highgui.h>
 
-#include "../package_bgs/FrameDifferenceBGS.h"
+#include "../../package_bgs/FrameDifference.h"
+
+using namespace bgslibrary::algorithms;
 
 int main(int argc, char **argv)
 {
@@ -15,7 +17,7 @@ int main(int argc, char **argv)
   }
 
   IBGS *bgs;
-  bgs = new FrameDifferenceBGS;
+  bgs = new FrameDifference;
 
   IplImage *frame;
   while(1)
diff --git a/example_macosx/README.txt b/demos/macosx/README.txt
similarity index 100%
rename from example_macosx/README.txt
rename to demos/macosx/README.txt
diff --git a/demos/macosx/config/.gitignore b/demos/macosx/config/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..8ee04a01eb210a035d02f190538c5235aebc7277
--- /dev/null
+++ b/demos/macosx/config/.gitignore
@@ -0,0 +1,4 @@
+# Ignore everything in this directory
+*
+# Except these files
+!.gitignore
\ No newline at end of file
diff --git a/README_CMAKE_USERS.txt b/docs/README_CMAKE_USERS_OPENCV2.txt
similarity index 70%
rename from README_CMAKE_USERS.txt
rename to docs/README_CMAKE_USERS_OPENCV2.txt
index 974e9416be37091a476b1c2f8421cb0e0e561097..26c69979c2b2f0d4610f1c8f903a7a9122f9f4db 100644
--- a/README_CMAKE_USERS.txt
+++ b/docs/README_CMAKE_USERS_OPENCV2.txt
@@ -15,18 +15,17 @@ Please follow the instructions below:
 1) Go to Windows console.
 
 2) Clone BGSLibrary git repository:
-e.g.: git clone https://github.com/andrewssobral/bgslibrary.git
+git clone https://github.com/andrewssobral/bgslibrary.git
 
 3) Go to bgslibrary/build folder.
-e.g.: C:\bgslibrary\build>_
 
-2) Set your OpenCV PATH:
-e.g.:
-\> setlocal
-\> set OpenCV_DIR=C:\OpenCV2.4.10\build
-\> cmake -DOpenCV_DIR=%OpenCV_DIR% -G "Visual Studio 12" ..
-or:
-\> cmake -DOpenCV_DIR=%OpenCV_DIR% -G "Visual Studio 12 Win64" ..
+4) Set your OpenCV PATH:
+setlocal
+set OpenCV_DIR=C:\OpenCV2.4.10\build
+
+5) Launch CMAKE:
+(For Windows x86 32bits) cmake -DOpenCV_DIR=%OpenCV_DIR% -G "Visual Studio 12" ..
+(For Windows x64 64bits) cmake -DOpenCV_DIR=%OpenCV_DIR% -G "Visual Studio 12 Win64" ..
 
 Now, you will see something like (for win64):
 -------------------------------------------------
@@ -52,27 +51,25 @@ Now, you will see something like (for win64):
 -- Build files have been written to: C:/bgslibrary/build
 -------------------------------------------------
 
-3) Include OpenCV binaries in the system path:
-\> set PATH=%PATH%;%OpenCV_DIR%\x86\vc12\bin
-or:
-\> set PATH=%PATH%;%OpenCV_DIR%\x64\vc12\bin
+6) Include OpenCV binaries in the system path:
+(For Windows x86 32bits) set PATH=%PATH%;%OpenCV_DIR%\x86\vc12\bin
+(For Windows x64 64bits) set PATH=%PATH%;%OpenCV_DIR%\x64\vc12\bin
 
-4) Open 'bgs.sln' in Visual Studio and switch to 'RELEASE' mode 
-4.1) Note if you are using a Visual Studio version superior than 2013, you will need to CANCEL the project wizard update. However, you can go to step (2) and change the Visual Studio version, e.g.: -G "Visual Studio XX", where XX is your Visual Studio version.
+7) Open 'bgs.sln' in Visual Studio and switch to 'RELEASE' mode 
+7.1) Note if you are using a Visual Studio version superior than 2013, you will need to CANCEL the project wizard update. However, you can go to step (5) and change the Visual Studio version, e.g.: -G "Visual Studio XX", where XX is your Visual Studio version.
 
-5) Click on 'ALL_BUILD' project and build!
+8) Click on 'ALL_BUILD' project and build!
 
-6) If everything goes well, you can run bgslibrary in the Windows console as follows:
+9) If everything goes well, you can run bgslibrary in the Windows console as follows:
 
-6.1) Running BGSLibrary with a webcamera:
+9.1) Running BGSLibrary with a webcamera:
 C:\bgslibrary> build\bgslibrary.exe --use_cam --camera=0
 
-6.2) Running demo code:
+9.2) Running demo code:
 C:\bgslibrary> build\bgs_demo.exe dataset/video.avi
 
-6.3) Running demo2 code:
+9.3) Running demo2 code:
 C:\bgslibrary> build\bgs_demo2.exe
 
 Additional information:
 * Note that bgslibrary requires a 'config' folder in the working directory.
-e.g.: C:\bgslibrary\config
diff --git a/docs/README_CMAKE_USERS_OPENCV3.txt b/docs/README_CMAKE_USERS_OPENCV3.txt
new file mode 100644
index 0000000000000000000000000000000000000000..543fd86e39395c308cf8be8cf290fb92329c47bd
--- /dev/null
+++ b/docs/README_CMAKE_USERS_OPENCV3.txt
@@ -0,0 +1,77 @@
+-------------------------------------------------
+-------------- WINDOWS CMAKE USERS --------------
+
+How to build BGSLibrary with OpenCV 3.2.0 and Visual Studio 2015 from CMAKE.
+
+For Linux users, please see the instruction in README_LINUX_USERS.txt file.
+
+Dependencies:
+* GIT (tested with git version 2.7.2.windows.1).
+* CMAKE for Windows (tested with cmake version 3.1.1).
+* Microsoft Visual Studio (tested with VS2015).
+
+Please follow the instructions below:
+
+1) Go to Windows console.
+
+2) Clone BGSLibrary git repository:
+git clone https://github.com/andrewssobral/bgslibrary.git
+
+3) Go to bgslibrary/build folder.
+
+4) Set your OpenCV PATH:
+setlocal
+set OpenCV_DIR=C:\OpenCV3.2.0\build
+
+5) Launch CMAKE:
+cmake -DOpenCV_DIR=%OpenCV_DIR% -G "Visual Studio 14 Win64" ..
+
+Now, you will see something like:
+-------------------------------------------------
+-- The C compiler identification is MSVC 19.0.24215.1
+-- The CXX compiler identification is MSVC 19.0.24215.1
+-- Check for working C compiler using: Visual Studio 14 2015 Win64
+-- Check for working C compiler using: Visual Studio 14 2015 Win64 -- works
+-- Detecting C compiler ABI info
+-- Detecting C compiler ABI info - done
+-- Check for working CXX compiler using: Visual Studio 14 2015 Win64
+-- Check for working CXX compiler using: Visual Studio 14 2015 Win64 -- works
+-- Detecting CXX compiler ABI info
+-- Detecting CXX compiler ABI info - done
+-- Detecting CXX compile features
+-- Detecting CXX compile features - done
+-- OpenCV ARCH: x64
+-- OpenCV RUNTIME: vc14
+-- OpenCV STATIC: ON
+-- Found OpenCV 3.2.0 in C:/OpenCV3.2.0/build/x64/vc14/lib
+-- You might need to add C:\OpenCV3.2.0\build\x64\vc14\bin to your PATH to be able to run your applications.
+-- OpenCV library status:
+--     version: 3.2.0
+--     libraries: opencv_world;opencv_videostab;opencv_videoio;opencv_video;opencv_superres;opencv_stitching;opencv_shape;opencv_photo;opencv_objdetect;opencv_ml;opencv_imgproc;opencv_imgcodecs;opencv_highgui;opencv_flann;opencv_features2d;opencv_core;opencv_calib3d
+--     include path: C:/OpenCV3.2.0/build/include;C:/OpenCV3.2.0/build/include/opencv
+-- Configuring done
+-- Generating done
+-- Build files have been written to: C:/bgslibrary/build
+-------------------------------------------------
+
+6) Include OpenCV binaries in the system path:
+set PATH=%PATH%;%OpenCV_DIR%\x64\vc14\bin
+
+7) Open 'bgs.sln' in Visual Studio and switch to 'RELEASE' mode 
+7.1) Note if you are using a Visual Studio version superior than 2015, you will need to CANCEL the project wizard update. However, you can go to step (2) and change the Visual Studio version, e.g.: -G "Visual Studio XX", where XX is your Visual Studio version.
+
+8) Click on 'ALL_BUILD' project and build!
+
+9) If everything goes well, you can run bgslibrary in the Windows console as follows:
+
+9.1) Running BGSLibrary with a webcamera:
+C:\bgslibrary> build\bgslibrary.exe --use_cam --camera=0
+
+9.2) Running demo code:
+C:\bgslibrary> build\bgs_demo.exe dataset/video.avi
+
+9.3) Running demo2 code:
+C:\bgslibrary> build\bgs_demo2.exe
+
+Additional information:
+* Note that bgslibrary requires a 'config' folder in the working directory.
diff --git a/README_LINUX_USERS.txt b/docs/README_LINUX_USERS.txt
similarity index 85%
rename from README_LINUX_USERS.txt
rename to docs/README_LINUX_USERS.txt
index 5a2611faf296d01262d99bd5150900fc0000f35e..9482f33d3fe8210430eee55ad22080019a526d52 100644
--- a/README_LINUX_USERS.txt
+++ b/docs/README_LINUX_USERS.txt
@@ -4,6 +4,8 @@
 # Requirements:
 # cmake >= 2.8
 # opencv >= 2.3.1
+#
+# Tested with: Ubuntu 14.04 and Ubuntu 16.04
 
 cd build
 cmake ..
@@ -17,7 +19,8 @@ export LD_LIBRARY_PATH
 # Now you can run bgslibrary by: bgs -i video.avi
 ########################
 cd ..
-chmod +x run_video.sh run_camera.sh run_demo.sh
+chmod +x *.sh
 ./run_video.sh
 ./run_camera.sh
 ./run_demo.sh
+./run_demo2.sh
diff --git a/README_VISUAL_STUDIO_USERS.txt b/docs/README_VS2010_OPENCV2.txt
similarity index 81%
rename from README_VISUAL_STUDIO_USERS.txt
rename to docs/README_VS2010_OPENCV2.txt
index ee9fe126b80f698ba647cbb2d2b8e3b787747964..66ee0f43ec69342dc5dd051af18baf390a091850 100644
--- a/README_VISUAL_STUDIO_USERS.txt
+++ b/docs/README_VS2010_OPENCV2.txt
@@ -1,16 +1,13 @@
 ---------------------------------------------------
 BGSLibrary with Visual Studio 2010 and Opencv 2.4.x
 ---------------------------------------------------
-
-1) Clone our VS2010 example project at [vs2010] folder
-https://github.com/andrewssobral/bgslibrary/tree/master/vs2010
-
-Or configure manually by:
+--- Tutorial for Windows x86 32 bits ---
+----------------------------------------
 
 1) Install OpenCV
 1.a) Download OpenCV 2.4.x from http://opencv.org/
-2.b) Install in: C:\OpenCV2.4.x
-2.c) Add OpenCV binaries in your Path
+1.b) Install in: C:\OpenCV2.4.x
+1.c) Add OpenCV binaries in your Path
 C:\OpenCV2.4.x\build\x86\vc10\bin
 
 2) Download BGSLibrary
@@ -22,7 +19,7 @@ C:\OpenCV2.4.x\build\x86\vc10\bin
 3.c) Set project location: C:\bgslibrary
 3.d) Set project name: bgslibrary
 3.e) Set Empty project 
-3.f) Add Demo.cpp in [Source Files]
+3.f) Add Main.cpp in [Source Files]
 3.g) Add content of c:\bgslibrary\package_bgs\*.* in [Header Files]
 3.h) Add content of c:\bgslibrary\package_analysis\*.* in [Header Files]
 3.i) Change to [Release] [Win32] mode
diff --git a/example_linux/config/KEEP_THIS_FOLDER b/example_linux/config/KEEP_THIS_FOLDER
deleted file mode 100644
index 24353bcb3c57d58895a3c2500232445466fabd6b..0000000000000000000000000000000000000000
--- a/example_linux/config/KEEP_THIS_FOLDER
+++ /dev/null
@@ -1 +0,0 @@
-bgslibrary uses this folder to store the configuration files
\ No newline at end of file
diff --git a/example_macosx/config/KEEP_THIS_FOLDER b/example_macosx/config/KEEP_THIS_FOLDER
deleted file mode 100644
index 24353bcb3c57d58895a3c2500232445466fabd6b..0000000000000000000000000000000000000000
--- a/example_macosx/config/KEEP_THIS_FOLDER
+++ /dev/null
@@ -1 +0,0 @@
-bgslibrary uses this folder to store the configuration files
\ No newline at end of file
diff --git a/java_gui/README.txt b/gui_java/README.txt
similarity index 100%
rename from java_gui/README.txt
rename to gui_java/README.txt
diff --git a/java_gui/_COPY_bgslibrary.exe_HERE_ b/gui_java/_COPY_bgslibrary.exe_HERE_
similarity index 100%
rename from java_gui/_COPY_bgslibrary.exe_HERE_
rename to gui_java/_COPY_bgslibrary.exe_HERE_
diff --git a/java_gui/bgslibrary_gui.jar b/gui_java/bgslibrary_gui.jar
similarity index 100%
rename from java_gui/bgslibrary_gui.jar
rename to gui_java/bgslibrary_gui.jar
diff --git a/java_gui/bgslibrary_gui.properties b/gui_java/bgslibrary_gui.properties
similarity index 100%
rename from java_gui/bgslibrary_gui.properties
rename to gui_java/bgslibrary_gui.properties
diff --git a/java_gui/build.xml b/gui_java/build.xml
similarity index 100%
rename from java_gui/build.xml
rename to gui_java/build.xml
diff --git a/java_gui/config/.gitignore b/gui_java/config/.gitignore
similarity index 100%
rename from java_gui/config/.gitignore
rename to gui_java/config/.gitignore
diff --git a/java_gui/config/FrameProcessor.xml b/gui_java/config/FrameProcessor.xml
similarity index 100%
rename from java_gui/config/FrameProcessor.xml
rename to gui_java/config/FrameProcessor.xml
diff --git a/java_gui/config/PreProcessor.xml b/gui_java/config/PreProcessor.xml
similarity index 100%
rename from java_gui/config/PreProcessor.xml
rename to gui_java/config/PreProcessor.xml
diff --git a/java_gui/config/VideoCapture.xml b/gui_java/config/VideoCapture.xml
similarity index 100%
rename from java_gui/config/VideoCapture.xml
rename to gui_java/config/VideoCapture.xml
diff --git a/java_gui/images/bgslibrary_gui_screen01.png b/gui_java/images/bgslibrary_gui_screen01.png
similarity index 100%
rename from java_gui/images/bgslibrary_gui_screen01.png
rename to gui_java/images/bgslibrary_gui_screen01.png
diff --git a/java_gui/images/bgslibrary_gui_screen02.png b/gui_java/images/bgslibrary_gui_screen02.png
similarity index 100%
rename from java_gui/images/bgslibrary_gui_screen02.png
rename to gui_java/images/bgslibrary_gui_screen02.png
diff --git a/java_gui/images/bgslibrary_gui_screen03.png b/gui_java/images/bgslibrary_gui_screen03.png
similarity index 100%
rename from java_gui/images/bgslibrary_gui_screen03.png
rename to gui_java/images/bgslibrary_gui_screen03.png
diff --git a/java_gui/images/bgslibrary_gui_screen04.png b/gui_java/images/bgslibrary_gui_screen04.png
similarity index 100%
rename from java_gui/images/bgslibrary_gui_screen04.png
rename to gui_java/images/bgslibrary_gui_screen04.png
diff --git a/java_gui/images/logo.jpg b/gui_java/images/logo.jpg
similarity index 100%
rename from java_gui/images/logo.jpg
rename to gui_java/images/logo.jpg
diff --git a/java_gui/lib/commons-configuration-1.8.jar b/gui_java/lib/commons-configuration-1.8.jar
similarity index 100%
rename from java_gui/lib/commons-configuration-1.8.jar
rename to gui_java/lib/commons-configuration-1.8.jar
diff --git a/java_gui/lib/commons-io-2.3.jar b/gui_java/lib/commons-io-2.3.jar
similarity index 100%
rename from java_gui/lib/commons-io-2.3.jar
rename to gui_java/lib/commons-io-2.3.jar
diff --git a/java_gui/lib/commons-lang-2.6.jar b/gui_java/lib/commons-lang-2.6.jar
similarity index 100%
rename from java_gui/lib/commons-lang-2.6.jar
rename to gui_java/lib/commons-lang-2.6.jar
diff --git a/java_gui/lib/commons-logging-1.1.1.jar b/gui_java/lib/commons-logging-1.1.1.jar
similarity index 100%
rename from java_gui/lib/commons-logging-1.1.1.jar
rename to gui_java/lib/commons-logging-1.1.1.jar
diff --git a/java_gui/lib/swingx-all-1.6.3.jar b/gui_java/lib/swingx-all-1.6.3.jar
similarity index 100%
rename from java_gui/lib/swingx-all-1.6.3.jar
rename to gui_java/lib/swingx-all-1.6.3.jar
diff --git a/java_gui/lib/swingx-beaninfo-1.6.3.jar b/gui_java/lib/swingx-beaninfo-1.6.3.jar
similarity index 100%
rename from java_gui/lib/swingx-beaninfo-1.6.3.jar
rename to gui_java/lib/swingx-beaninfo-1.6.3.jar
diff --git a/java_gui/manifest.mf b/gui_java/manifest.mf
similarity index 100%
rename from java_gui/manifest.mf
rename to gui_java/manifest.mf
diff --git a/java_gui/nbproject/build-impl.xml b/gui_java/nbproject/build-impl.xml
similarity index 100%
rename from java_gui/nbproject/build-impl.xml
rename to gui_java/nbproject/build-impl.xml
diff --git a/java_gui/nbproject/genfiles.properties b/gui_java/nbproject/genfiles.properties
similarity index 100%
rename from java_gui/nbproject/genfiles.properties
rename to gui_java/nbproject/genfiles.properties
diff --git a/java_gui/nbproject/private/config.properties b/gui_java/nbproject/private/config.properties
similarity index 100%
rename from java_gui/nbproject/private/config.properties
rename to gui_java/nbproject/private/config.properties
diff --git a/java_gui/nbproject/private/private.properties b/gui_java/nbproject/private/private.properties
similarity index 100%
rename from java_gui/nbproject/private/private.properties
rename to gui_java/nbproject/private/private.properties
diff --git a/java_gui/nbproject/private/private.xml b/gui_java/nbproject/private/private.xml
similarity index 100%
rename from java_gui/nbproject/private/private.xml
rename to gui_java/nbproject/private/private.xml
diff --git a/java_gui/nbproject/project.properties b/gui_java/nbproject/project.properties
similarity index 100%
rename from java_gui/nbproject/project.properties
rename to gui_java/nbproject/project.properties
diff --git a/java_gui/nbproject/project.xml b/gui_java/nbproject/project.xml
similarity index 100%
rename from java_gui/nbproject/project.xml
rename to gui_java/nbproject/project.xml
diff --git a/java_gui/run_camera.bat b/gui_java/run_camera.bat
similarity index 100%
rename from java_gui/run_camera.bat
rename to gui_java/run_camera.bat
diff --git a/java_gui/run_java_gui.bat b/gui_java/run_java_gui.bat
similarity index 100%
rename from java_gui/run_java_gui.bat
rename to gui_java/run_java_gui.bat
diff --git a/java_gui/run_java_gui_with_console.bat b/gui_java/run_java_gui_with_console.bat
similarity index 100%
rename from java_gui/run_java_gui_with_console.bat
rename to gui_java/run_java_gui_with_console.bat
diff --git a/java_gui/run_video.bat b/gui_java/run_video.bat
similarity index 100%
rename from java_gui/run_video.bat
rename to gui_java/run_video.bat
diff --git a/java_gui/src/br/com/bgslibrary/Main.java b/gui_java/src/br/com/bgslibrary/Main.java
similarity index 100%
rename from java_gui/src/br/com/bgslibrary/Main.java
rename to gui_java/src/br/com/bgslibrary/Main.java
diff --git a/java_gui/src/br/com/bgslibrary/entity/Command.java b/gui_java/src/br/com/bgslibrary/entity/Command.java
similarity index 100%
rename from java_gui/src/br/com/bgslibrary/entity/Command.java
rename to gui_java/src/br/com/bgslibrary/entity/Command.java
diff --git a/java_gui/src/br/com/bgslibrary/entity/Configuration.java b/gui_java/src/br/com/bgslibrary/entity/Configuration.java
similarity index 100%
rename from java_gui/src/br/com/bgslibrary/entity/Configuration.java
rename to gui_java/src/br/com/bgslibrary/entity/Configuration.java
diff --git a/java_gui/src/br/com/bgslibrary/gui/AboutDialog.form b/gui_java/src/br/com/bgslibrary/gui/AboutDialog.form
similarity index 100%
rename from java_gui/src/br/com/bgslibrary/gui/AboutDialog.form
rename to gui_java/src/br/com/bgslibrary/gui/AboutDialog.form
diff --git a/java_gui/src/br/com/bgslibrary/gui/AboutDialog.java b/gui_java/src/br/com/bgslibrary/gui/AboutDialog.java
similarity index 100%
rename from java_gui/src/br/com/bgslibrary/gui/AboutDialog.java
rename to gui_java/src/br/com/bgslibrary/gui/AboutDialog.java
diff --git a/java_gui/src/br/com/bgslibrary/gui/MainFrame.form b/gui_java/src/br/com/bgslibrary/gui/MainFrame.form
similarity index 100%
rename from java_gui/src/br/com/bgslibrary/gui/MainFrame.form
rename to gui_java/src/br/com/bgslibrary/gui/MainFrame.form
diff --git a/java_gui/src/br/com/bgslibrary/gui/MainFrame.java b/gui_java/src/br/com/bgslibrary/gui/MainFrame.java
similarity index 100%
rename from java_gui/src/br/com/bgslibrary/gui/MainFrame.java
rename to gui_java/src/br/com/bgslibrary/gui/MainFrame.java
diff --git a/java_gui/src/br/com/bgslibrary/resources/logo.jpg b/gui_java/src/br/com/bgslibrary/resources/logo.jpg
similarity index 100%
rename from java_gui/src/br/com/bgslibrary/resources/logo.jpg
rename to gui_java/src/br/com/bgslibrary/resources/logo.jpg
diff --git a/vs2010mfc/.gitignore b/gui_mfc/.gitignore
similarity index 100%
rename from vs2010mfc/.gitignore
rename to gui_mfc/.gitignore
diff --git a/vs2013mfc/ReadMe.txt b/gui_mfc/ReadMe.txt
similarity index 100%
rename from vs2013mfc/ReadMe.txt
rename to gui_mfc/ReadMe.txt
diff --git a/vs2010mfc/config/AdaptiveBackgroundLearning.xml b/gui_mfc/config/AdaptiveBackgroundLearning.xml
similarity index 100%
rename from vs2010mfc/config/AdaptiveBackgroundLearning.xml
rename to gui_mfc/config/AdaptiveBackgroundLearning.xml
diff --git a/vs2010mfc/config/AdaptiveSelectiveBackgroundLearning.xml b/gui_mfc/config/AdaptiveSelectiveBackgroundLearning.xml
similarity index 100%
rename from vs2010mfc/config/AdaptiveSelectiveBackgroundLearning.xml
rename to gui_mfc/config/AdaptiveSelectiveBackgroundLearning.xml
diff --git a/vs2010mfc/config/DPAdaptiveMedianBGS.xml b/gui_mfc/config/DPAdaptiveMedianBGS.xml
similarity index 100%
rename from vs2010mfc/config/DPAdaptiveMedianBGS.xml
rename to gui_mfc/config/DPAdaptiveMedianBGS.xml
diff --git a/vs2010mfc/config/DPEigenbackgroundBGS.xml b/gui_mfc/config/DPEigenbackgroundBGS.xml
similarity index 100%
rename from vs2010mfc/config/DPEigenbackgroundBGS.xml
rename to gui_mfc/config/DPEigenbackgroundBGS.xml
diff --git a/vs2010mfc/config/DPGrimsonGMMBGS.xml b/gui_mfc/config/DPGrimsonGMMBGS.xml
similarity index 100%
rename from vs2010mfc/config/DPGrimsonGMMBGS.xml
rename to gui_mfc/config/DPGrimsonGMMBGS.xml
diff --git a/vs2010mfc/config/DPMeanBGS.xml b/gui_mfc/config/DPMeanBGS.xml
similarity index 100%
rename from vs2010mfc/config/DPMeanBGS.xml
rename to gui_mfc/config/DPMeanBGS.xml
diff --git a/vs2010mfc/config/DPPratiMediodBGS.xml b/gui_mfc/config/DPPratiMediodBGS.xml
similarity index 100%
rename from vs2010mfc/config/DPPratiMediodBGS.xml
rename to gui_mfc/config/DPPratiMediodBGS.xml
diff --git a/vs2010mfc/config/DPTextureBGS.xml b/gui_mfc/config/DPTextureBGS.xml
similarity index 100%
rename from vs2010mfc/config/DPTextureBGS.xml
rename to gui_mfc/config/DPTextureBGS.xml
diff --git a/vs2010mfc/config/DPWrenGABGS.xml b/gui_mfc/config/DPWrenGABGS.xml
similarity index 100%
rename from vs2010mfc/config/DPWrenGABGS.xml
rename to gui_mfc/config/DPWrenGABGS.xml
diff --git a/vs2010mfc/config/DPZivkovicAGMMBGS.xml b/gui_mfc/config/DPZivkovicAGMMBGS.xml
similarity index 100%
rename from vs2010mfc/config/DPZivkovicAGMMBGS.xml
rename to gui_mfc/config/DPZivkovicAGMMBGS.xml
diff --git a/vs2010mfc/config/FrameDifferenceBGS.xml b/gui_mfc/config/FrameDifferenceBGS.xml
similarity index 100%
rename from vs2010mfc/config/FrameDifferenceBGS.xml
rename to gui_mfc/config/FrameDifferenceBGS.xml
diff --git a/vs2010mfc/config/FuzzyChoquetIntegral.xml b/gui_mfc/config/FuzzyChoquetIntegral.xml
similarity index 100%
rename from vs2010mfc/config/FuzzyChoquetIntegral.xml
rename to gui_mfc/config/FuzzyChoquetIntegral.xml
diff --git a/vs2010mfc/config/FuzzySugenoIntegral.xml b/gui_mfc/config/FuzzySugenoIntegral.xml
similarity index 100%
rename from vs2010mfc/config/FuzzySugenoIntegral.xml
rename to gui_mfc/config/FuzzySugenoIntegral.xml
diff --git a/vs2010mfc/config/GMG.xml b/gui_mfc/config/GMG.xml
similarity index 100%
rename from vs2010mfc/config/GMG.xml
rename to gui_mfc/config/GMG.xml
diff --git a/vs2010mfc/config/IndependentMultimodalBGS.xml b/gui_mfc/config/IndependentMultimodalBGS.xml
similarity index 100%
rename from vs2010mfc/config/IndependentMultimodalBGS.xml
rename to gui_mfc/config/IndependentMultimodalBGS.xml
diff --git a/vs2010mfc/config/KDE.xml b/gui_mfc/config/KDE.xml
similarity index 100%
rename from vs2010mfc/config/KDE.xml
rename to gui_mfc/config/KDE.xml
diff --git a/vs2010mfc/config/LBAdaptiveSOM.xml b/gui_mfc/config/LBAdaptiveSOM.xml
similarity index 100%
rename from vs2010mfc/config/LBAdaptiveSOM.xml
rename to gui_mfc/config/LBAdaptiveSOM.xml
diff --git a/vs2010mfc/config/LBFuzzyAdaptiveSOM.xml b/gui_mfc/config/LBFuzzyAdaptiveSOM.xml
similarity index 100%
rename from vs2010mfc/config/LBFuzzyAdaptiveSOM.xml
rename to gui_mfc/config/LBFuzzyAdaptiveSOM.xml
diff --git a/vs2010mfc/config/LBFuzzyGaussian.xml b/gui_mfc/config/LBFuzzyGaussian.xml
similarity index 100%
rename from vs2010mfc/config/LBFuzzyGaussian.xml
rename to gui_mfc/config/LBFuzzyGaussian.xml
diff --git a/vs2010mfc/config/LBMixtureOfGaussians.xml b/gui_mfc/config/LBMixtureOfGaussians.xml
similarity index 100%
rename from vs2010mfc/config/LBMixtureOfGaussians.xml
rename to gui_mfc/config/LBMixtureOfGaussians.xml
diff --git a/vs2010mfc/config/LBSimpleGaussian.xml b/gui_mfc/config/LBSimpleGaussian.xml
similarity index 100%
rename from vs2010mfc/config/LBSimpleGaussian.xml
rename to gui_mfc/config/LBSimpleGaussian.xml
diff --git a/vs2010mfc/config/LOBSTERBGS.xml b/gui_mfc/config/LOBSTERBGS.xml
similarity index 100%
rename from vs2010mfc/config/LOBSTERBGS.xml
rename to gui_mfc/config/LOBSTERBGS.xml
diff --git a/vs2010mfc/config/MixtureOfGaussianV1BGS.xml b/gui_mfc/config/MixtureOfGaussianV1BGS.xml
similarity index 100%
rename from vs2010mfc/config/MixtureOfGaussianV1BGS.xml
rename to gui_mfc/config/MixtureOfGaussianV1BGS.xml
diff --git a/vs2010mfc/config/MixtureOfGaussianV2BGS.xml b/gui_mfc/config/MixtureOfGaussianV2BGS.xml
similarity index 100%
rename from vs2010mfc/config/MixtureOfGaussianV2BGS.xml
rename to gui_mfc/config/MixtureOfGaussianV2BGS.xml
diff --git a/vs2010mfc/config/MultiCueBGS.xml b/gui_mfc/config/MultiCueBGS.xml
similarity index 100%
rename from vs2010mfc/config/MultiCueBGS.xml
rename to gui_mfc/config/MultiCueBGS.xml
diff --git a/vs2010mfc/config/MultiLayerBGS.xml b/gui_mfc/config/MultiLayerBGS.xml
similarity index 100%
rename from vs2010mfc/config/MultiLayerBGS.xml
rename to gui_mfc/config/MultiLayerBGS.xml
diff --git a/vs2010mfc/config/SigmaDeltaBGS.xml b/gui_mfc/config/SigmaDeltaBGS.xml
similarity index 100%
rename from vs2010mfc/config/SigmaDeltaBGS.xml
rename to gui_mfc/config/SigmaDeltaBGS.xml
diff --git a/vs2010mfc/config/StaticFrameDifferenceBGS.xml b/gui_mfc/config/StaticFrameDifferenceBGS.xml
similarity index 100%
rename from vs2010mfc/config/StaticFrameDifferenceBGS.xml
rename to gui_mfc/config/StaticFrameDifferenceBGS.xml
diff --git a/vs2010mfc/config/SuBSENSEBGS.xml b/gui_mfc/config/SuBSENSEBGS.xml
similarity index 100%
rename from vs2010mfc/config/SuBSENSEBGS.xml
rename to gui_mfc/config/SuBSENSEBGS.xml
diff --git a/vs2010mfc/config/T2FGMM_UM.xml b/gui_mfc/config/T2FGMM_UM.xml
similarity index 100%
rename from vs2010mfc/config/T2FGMM_UM.xml
rename to gui_mfc/config/T2FGMM_UM.xml
diff --git a/vs2010mfc/config/T2FGMM_UV.xml b/gui_mfc/config/T2FGMM_UV.xml
similarity index 100%
rename from vs2010mfc/config/T2FGMM_UV.xml
rename to gui_mfc/config/T2FGMM_UV.xml
diff --git a/vs2010mfc/config/T2FMRF_UM.xml b/gui_mfc/config/T2FMRF_UM.xml
similarity index 100%
rename from vs2010mfc/config/T2FMRF_UM.xml
rename to gui_mfc/config/T2FMRF_UM.xml
diff --git a/vs2010mfc/config/T2FMRF_UV.xml b/gui_mfc/config/T2FMRF_UV.xml
similarity index 100%
rename from vs2010mfc/config/T2FMRF_UV.xml
rename to gui_mfc/config/T2FMRF_UV.xml
diff --git a/vs2010mfc/config/VuMeter.xml b/gui_mfc/config/VuMeter.xml
similarity index 100%
rename from vs2010mfc/config/VuMeter.xml
rename to gui_mfc/config/VuMeter.xml
diff --git a/vs2010mfc/config/WeightedMovingMeanBGS.xml b/gui_mfc/config/WeightedMovingMeanBGS.xml
similarity index 100%
rename from vs2010mfc/config/WeightedMovingMeanBGS.xml
rename to gui_mfc/config/WeightedMovingMeanBGS.xml
diff --git a/vs2010mfc/config/WeightedMovingVarianceBGS.xml b/gui_mfc/config/WeightedMovingVarianceBGS.xml
similarity index 100%
rename from vs2010mfc/config/WeightedMovingVarianceBGS.xml
rename to gui_mfc/config/WeightedMovingVarianceBGS.xml
diff --git a/vs2010mfc/dataset/video.avi b/gui_mfc/dataset/video.avi
similarity index 100%
rename from vs2010mfc/dataset/video.avi
rename to gui_mfc/dataset/video.avi
diff --git a/vs2013mfc/outputs/background/.gitignore b/gui_mfc/outputs/background/.gitignore
similarity index 100%
rename from vs2013mfc/outputs/background/.gitignore
rename to gui_mfc/outputs/background/.gitignore
diff --git a/vs2013mfc/outputs/foreground/.gitignore b/gui_mfc/outputs/foreground/.gitignore
similarity index 100%
rename from vs2013mfc/outputs/foreground/.gitignore
rename to gui_mfc/outputs/foreground/.gitignore
diff --git a/vs2013mfc/outputs/input/.gitignore b/gui_mfc/outputs/input/.gitignore
similarity index 100%
rename from vs2013mfc/outputs/input/.gitignore
rename to gui_mfc/outputs/input/.gitignore
diff --git a/vs2010mfc/src/.gitignore b/gui_mfc/src/.gitignore
similarity index 100%
rename from vs2010mfc/src/.gitignore
rename to gui_mfc/src/.gitignore
diff --git a/vs2010mfc/src/App.cpp b/gui_mfc/src/App.cpp
similarity index 100%
rename from vs2010mfc/src/App.cpp
rename to gui_mfc/src/App.cpp
diff --git a/vs2010mfc/src/App.h b/gui_mfc/src/App.h
similarity index 100%
rename from vs2010mfc/src/App.h
rename to gui_mfc/src/App.h
diff --git a/vs2010mfc/src/Dlg.cpp b/gui_mfc/src/Dlg.cpp
similarity index 100%
rename from vs2010mfc/src/Dlg.cpp
rename to gui_mfc/src/Dlg.cpp
diff --git a/vs2010mfc/src/Dlg.h b/gui_mfc/src/Dlg.h
similarity index 100%
rename from vs2010mfc/src/Dlg.h
rename to gui_mfc/src/Dlg.h
diff --git a/vs2013mfc/src/ReadMe.txt b/gui_mfc/src/ReadMe.txt
similarity index 100%
rename from vs2013mfc/src/ReadMe.txt
rename to gui_mfc/src/ReadMe.txt
diff --git a/vs2013mfc/src/bgslibrary_vs2013_mfc.rc b/gui_mfc/src/bgslibrary_vs2013_mfc.rc
similarity index 100%
rename from vs2013mfc/src/bgslibrary_vs2013_mfc.rc
rename to gui_mfc/src/bgslibrary_vs2013_mfc.rc
diff --git a/vs2013mfc/src/bgslibrary_vs2013_mfc.sln b/gui_mfc/src/bgslibrary_vs2013_mfc.sln
similarity index 100%
rename from vs2013mfc/src/bgslibrary_vs2013_mfc.sln
rename to gui_mfc/src/bgslibrary_vs2013_mfc.sln
diff --git a/vs2013mfc/src/bgslibrary_vs2013_mfc.vcxproj b/gui_mfc/src/bgslibrary_vs2013_mfc.vcxproj
similarity index 100%
rename from vs2013mfc/src/bgslibrary_vs2013_mfc.vcxproj
rename to gui_mfc/src/bgslibrary_vs2013_mfc.vcxproj
diff --git a/vs2013mfc/src/bgslibrary_vs2013_mfc.vcxproj.filters b/gui_mfc/src/bgslibrary_vs2013_mfc.vcxproj.filters
similarity index 100%
rename from vs2013mfc/src/bgslibrary_vs2013_mfc.vcxproj.filters
rename to gui_mfc/src/bgslibrary_vs2013_mfc.vcxproj.filters
diff --git a/vs2013mfc/src/bgslibrary_vs2013_mfc.vcxproj.user b/gui_mfc/src/bgslibrary_vs2013_mfc.vcxproj.user
similarity index 100%
rename from vs2013mfc/src/bgslibrary_vs2013_mfc.vcxproj.user
rename to gui_mfc/src/bgslibrary_vs2013_mfc.vcxproj.user
diff --git a/vs2013mfc/src/res/bgslibrary_vs2013_mfc.ico b/gui_mfc/src/res/bgslibrary_vs2013_mfc.ico
similarity index 100%
rename from vs2013mfc/src/res/bgslibrary_vs2013_mfc.ico
rename to gui_mfc/src/res/bgslibrary_vs2013_mfc.ico
diff --git a/vs2013mfc/src/res/bgslibrary_vs2013_mfc.rc2 b/gui_mfc/src/res/bgslibrary_vs2013_mfc.rc2
similarity index 100%
rename from vs2013mfc/src/res/bgslibrary_vs2013_mfc.rc2
rename to gui_mfc/src/res/bgslibrary_vs2013_mfc.rc2
diff --git a/vs2010mfc/src/resource.h b/gui_mfc/src/resource.h
similarity index 100%
rename from vs2010mfc/src/resource.h
rename to gui_mfc/src/resource.h
diff --git a/vs2010mfc/src/stdafx.cpp b/gui_mfc/src/stdafx.cpp
similarity index 100%
rename from vs2010mfc/src/stdafx.cpp
rename to gui_mfc/src/stdafx.cpp
diff --git a/vs2010mfc/src/stdafx.h b/gui_mfc/src/stdafx.h
similarity index 100%
rename from vs2010mfc/src/stdafx.h
rename to gui_mfc/src/stdafx.h
diff --git a/vs2010mfc/src/targetver.h b/gui_mfc/src/targetver.h
similarity index 100%
rename from vs2010mfc/src/targetver.h
rename to gui_mfc/src/targetver.h
diff --git a/gui_qt/.gitignore b/gui_qt/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..9c28032b4c6631a5f27072a12901a0fecd324309
--- /dev/null
+++ b/gui_qt/.gitignore
@@ -0,0 +1,9 @@
+_*/
+debug/
+release/
+build_*/
+dataset*/
+binaries*/
+Makefile*
+*.exe
+*.dll
diff --git a/gui_qt/CMakeLists.txt b/gui_qt/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..83c89202c63b6a0c15300ddaa017ef6e10606410
--- /dev/null
+++ b/gui_qt/CMakeLists.txt
@@ -0,0 +1,52 @@
+cmake_minimum_required(VERSION 2.8.11)
+
+project(bgslibrary_gui)
+
+# Find includes in corresponding build directories
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+# Instruct CMake to run moc automatically when needed.
+set(CMAKE_AUTOMOC ON)
+
+# Handle the Qt uic code generator automatically
+set(CMAKE_AUTOUIC ON)
+
+# Find the Qt5Widgets library
+find_package(Qt5Widgets)
+
+SET(app_RESOURCES application.qrc)
+QT5_ADD_RESOURCES(app_RESOURCES_RCC ${app_RESOURCES})
+
+# Find the OpenCV library
+set(OpenCV_STATIC OFF)
+find_package(OpenCV REQUIRED)
+
+message(STATUS "OpenCV library status:")
+message(STATUS "    version: ${OpenCV_VERSION}")
+message(STATUS "    libraries: ${OpenCV_LIBS}")
+message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")
+
+file(GLOB main bgslibrary_gui.cpp mainwindow.cpp qt_utils.cpp texteditor.cpp)
+
+file(GLOB_RECURSE analysis_src ../package_analysis/*.cpp)
+file(GLOB_RECURSE analysis_inc ../package_analysis/*.h)
+file(GLOB_RECURSE bgs_src ../package_bgs/*.cpp ../package_bgs/*.c)
+file(GLOB_RECURSE bgs_inc ../package_bgs/*.h)
+
+include_directories(${CMAKE_SOURCE_DIR} ${OpenCV_INCLUDE_DIRS})
+
+add_library(libbgs STATIC ${bgs_src} ${analysis_src})
+target_link_libraries(libbgs ${OpenCV_LIBS})
+set_property(TARGET libbgs PROPERTY PUBLIC_HEADER ${bgs_inc} ${analysis_inc})
+
+if(WIN32)
+	# set_property(TARGET libbgs PROPERTY SUFFIX ".lib")
+else()
+	set_property(TARGET libbgs PROPERTY OUTPUT_NAME "bgs")
+endif()
+
+# Tell CMake to create the bgslibrary_gui executable
+add_executable(bgslibrary_gui ${main} ${app_RESOURCES_RCC})
+
+# Use the Widgets module from Qt 5.
+target_link_libraries(bgslibrary_gui Qt5::Widgets ${OpenCV_LIBS} libbgs)
diff --git a/gui_qt/README.txt b/gui_qt/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..41a4cd2b1548b7ee189911927559afa2aa58d922
--- /dev/null
+++ b/gui_qt/README.txt
@@ -0,0 +1,17 @@
+#-------------------------------------------------
+#
+# Project created with Qt 5.6.2
+#
+# Compiling BGSLibrary QT GUI with CMAKE
+#
+#-------------------------------------------------
+# Qt 5.x 64-bit for Desktop (MSVC 2015)
+#-------------------------------------------------
+
+mkdir build
+
+cd build
+
+set OpenCV_DIR=C:\OpenCV3.2.0\build
+
+cmake -DOpenCV_DIR=%OpenCV_DIR% -G "Visual Studio 14 Win64" ..
diff --git a/gui_qt/application.qrc b/gui_qt/application.qrc
new file mode 100644
index 0000000000000000000000000000000000000000..3e8687f0f14bf61aeb8f6f2b57859d0ad47545aa
--- /dev/null
+++ b/gui_qt/application.qrc
@@ -0,0 +1,10 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+    <file>figs/copy.png</file>
+    <file>figs/cut.png</file>
+    <file>figs/new.png</file>
+    <file>figs/open.png</file>
+    <file>figs/paste.png</file>
+    <file>figs/save.png</file>
+</qresource>
+</RCC>
\ No newline at end of file
diff --git a/gui_qt/bgslibrary_gui.cpp b/gui_qt/bgslibrary_gui.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e886262427295abddf30fd063ed4861a4bd9b16b
--- /dev/null
+++ b/gui_qt/bgslibrary_gui.cpp
@@ -0,0 +1,38 @@
+/*
+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 "mainwindow.h"
+
+int main(int argc, char *argv[])
+{
+  std::cout << "--------------------------------------------" << std::endl;
+  std::cout << "Background Subtraction Library v2.0.0       " << std::endl;
+  std::cout << "https://github.com/andrewssobral/bgslibrary " << std::endl;
+  std::cout << "by:                                         " << std::endl;
+  std::cout << "Andrews Sobral (andrewssobral@gmail.com)    " << std::endl;
+  std::cout << "--------------------------------------------" << std::endl;
+  std::cout << "Using OpenCV version " << CV_VERSION << std::endl;
+
+  QApplication a(argc, argv);
+
+  QCoreApplication::setApplicationName("BGSLibrary");
+  QCoreApplication::setApplicationVersion("2.0.0");
+
+  MainWindow w;
+  w.show();
+
+  return a.exec();
+}
diff --git a/gui_qt/bgslibrary_gui.pro b/gui_qt/bgslibrary_gui.pro
new file mode 100644
index 0000000000000000000000000000000000000000..feedbf6a8601455aaad465d68842e76928c92a3a
--- /dev/null
+++ b/gui_qt/bgslibrary_gui.pro
@@ -0,0 +1,248 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator
+#
+#-------------------------------------------------
+
+QT       += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = bgslibrary_gui
+TEMPLATE = app
+
+# For Windows x64 + Visual Studio 2015 + OpenCV 3.1.0
+#INCLUDEPATH += C:/OpenCV3.1.0/build/include
+#LIBS += -LC:/OpenCV3.1.0/build/x64/vc14/lib -lopencv_world310
+
+# For Windows x64 + Visual Studio 2015 + OpenCV 3.2.0
+INCLUDEPATH += C:/OpenCV3.2.0/build/include
+LIBS += -LC:/OpenCV3.2.0/build/x64/vc14/lib -lopencv_world320
+
+# For Linux
+# INCLUDEPATH += /usr/local/include/opencv
+# LIBS += -L/usr/local/lib
+
+RESOURCES = application.qrc
+
+SOURCES += bgslibrary_gui.cpp\
+    mainwindow.cpp \
+    qt_utils.cpp \
+    texteditor.cpp \
+    ../package_analysis/ForegroundMaskAnalysis.cpp \
+    ../package_analysis/PerformanceUtils.cpp \
+    ../package_analysis/PixelUtils.cpp \
+    ../package_bgs/_template_/Amber.cpp \
+    ../package_bgs/_template_/MyBGS.cpp \
+    ../package_bgs/dp/AdaptiveMedianBGS.cpp \
+    ../package_bgs/dp/Eigenbackground.cpp \
+    ../package_bgs/dp/Error.cpp \
+    ../package_bgs/dp/GrimsonGMM.cpp \
+    ../package_bgs/dp/Image.cpp \
+    ../package_bgs/dp/MeanBGS.cpp \
+    ../package_bgs/dp/PratiMediodBGS.cpp \
+    ../package_bgs/dp/TextureBGS.cpp \
+    ../package_bgs/dp/WrenGA.cpp \
+    ../package_bgs/dp/ZivkovicAGMM.cpp \
+    ../package_bgs/IMBS/IMBS.cpp \
+    ../package_bgs/KDE/KernelTable.cpp \
+    ../package_bgs/KDE/NPBGmodel.cpp \
+    ../package_bgs/KDE/NPBGSubtractor.cpp \
+    ../package_bgs/lb/BGModel.cpp \
+    ../package_bgs/lb/BGModelFuzzyGauss.cpp \
+    ../package_bgs/lb/BGModelFuzzySom.cpp \
+    ../package_bgs/lb/BGModelGauss.cpp \
+    ../package_bgs/lb/BGModelMog.cpp \
+    ../package_bgs/lb/BGModelSom.cpp \
+    ../package_bgs/LBP_MRF/graph.cpp \
+    ../package_bgs/LBP_MRF/maxflow.cpp \
+    ../package_bgs/LBP_MRF/MEDefs.cpp \
+    ../package_bgs/LBP_MRF/MEHistogram.cpp \
+    ../package_bgs/LBP_MRF/MEImage.cpp \
+    ../package_bgs/LBP_MRF/MotionDetection.cpp \
+    ../package_bgs/LBSP/BackgroundSubtractorLBSP.cpp \
+    ../package_bgs/LBSP/BackgroundSubtractorLBSP_.cpp \
+    ../package_bgs/LBSP/BackgroundSubtractorLOBSTER.cpp \
+    ../package_bgs/LBSP/BackgroundSubtractorPAWCS.cpp \
+    ../package_bgs/LBSP/BackgroundSubtractorSuBSENSE.cpp \
+    ../package_bgs/LBSP/LBSP.cpp \
+    ../package_bgs/LBSP/LBSP_.cpp \
+    ../package_bgs/MultiLayer/blob.cpp \
+    ../package_bgs/MultiLayer/BlobExtraction.cpp \
+    ../package_bgs/MultiLayer/BlobResult.cpp \
+    ../package_bgs/MultiLayer/CMultiLayerBGS.cpp \
+    ../package_bgs/MultiLayer/LocalBinaryPattern.cpp \
+    ../package_bgs/PBAS/PBAS.cpp \
+    ../package_bgs/SigmaDelta/sdLaMa091.cpp \
+    ../package_bgs/T2F/FuzzyUtils.cpp \
+    ../package_bgs/T2F/MRF.cpp \
+    ../package_bgs/T2F/T2FGMM.cpp \
+    ../package_bgs/T2F/T2FMRF.cpp \
+    ../package_bgs/TwoPoints/two_points.cpp \
+    ../package_bgs/ViBe/vibe-background-sequential.cpp \
+    ../package_bgs/VuMeter/TBackground.cpp \
+    ../package_bgs/VuMeter/TBackgroundVuMeter.cpp \
+    ../package_bgs/AdaptiveBackgroundLearning.cpp \
+    ../package_bgs/AdaptiveSelectiveBackgroundLearning.cpp \
+    ../package_bgs/DPAdaptiveMedian.cpp \
+    ../package_bgs/DPEigenbackground.cpp \
+    ../package_bgs/DPGrimsonGMM.cpp \
+    ../package_bgs/DPMean.cpp \
+    ../package_bgs/DPPratiMediod.cpp \
+    ../package_bgs/DPTexture.cpp \
+    ../package_bgs/DPWrenGA.cpp \
+    ../package_bgs/DPZivkovicAGMM.cpp \
+    ../package_bgs/FrameDifference.cpp \
+    ../package_bgs/FuzzyChoquetIntegral.cpp \
+    ../package_bgs/FuzzySugenoIntegral.cpp \
+    ../package_bgs/GMG.cpp \
+    ../package_bgs/IndependentMultimodal.cpp \
+    ../package_bgs/KDE.cpp \
+    ../package_bgs/KNN.cpp \
+    ../package_bgs/LBAdaptiveSOM.cpp \
+    ../package_bgs/LBFuzzyAdaptiveSOM.cpp \
+    ../package_bgs/LBFuzzyGaussian.cpp \
+    ../package_bgs/LBMixtureOfGaussians.cpp \
+    ../package_bgs/LBP_MRF.cpp \
+    ../package_bgs/LBSimpleGaussian.cpp \
+    ../package_bgs/LOBSTER.cpp \
+    ../package_bgs/MixtureOfGaussianV1.cpp \
+    ../package_bgs/MixtureOfGaussianV2.cpp \
+    ../package_bgs/MultiCue.cpp \
+    ../package_bgs/MultiLayer.cpp \
+    ../package_bgs/PAWCS.cpp \
+    ../package_bgs/PixelBasedAdaptiveSegmenter.cpp \
+    ../package_bgs/SigmaDelta.cpp \
+    ../package_bgs/StaticFrameDifference.cpp \
+    ../package_bgs/SuBSENSE.cpp \
+    ../package_bgs/T2FGMM_UM.cpp \
+    ../package_bgs/T2FGMM_UV.cpp \
+    ../package_bgs/T2FMRF_UM.cpp \
+    ../package_bgs/T2FMRF_UV.cpp \
+    ../package_bgs/TwoPoints.cpp \
+    ../package_bgs/ViBe.cpp \
+    ../package_bgs/VuMeter.cpp \
+    ../package_bgs/WeightedMovingMean.cpp \
+    ../package_bgs/WeightedMovingVariance.cpp \
+    ../package_bgs/_template_/amber/amber.c
+
+HEADERS  += mainwindow.h \
+    qt_utils.h \
+    texteditor.h \
+    ../package_analysis/ForegroundMaskAnalysis.h \
+    ../package_analysis/PerformanceUtils.h \
+    ../package_analysis/PixelUtils.h \
+    ../package_bgs/_template_/amber/amber.h \
+    ../package_bgs/_template_/Amber.h \
+    ../package_bgs/_template_/MyBGS.h \
+    ../package_bgs/dp/AdaptiveMedianBGS.h \
+    ../package_bgs/dp/Bgs.h \
+    ../package_bgs/dp/BgsParams.h \
+    ../package_bgs/dp/Eigenbackground.h \
+    ../package_bgs/dp/Error.h \
+    ../package_bgs/dp/GrimsonGMM.h \
+    ../package_bgs/dp/Image.h \
+    ../package_bgs/dp/MeanBGS.h \
+    ../package_bgs/dp/PratiMediodBGS.h \
+    ../package_bgs/dp/TextureBGS.h \
+    ../package_bgs/dp/WrenGA.h \
+    ../package_bgs/dp/ZivkovicAGMM.h \
+    ../package_bgs/IMBS/IMBS.hpp \
+    ../package_bgs/KDE/KernelTable.h \
+    ../package_bgs/KDE/NPBGmodel.h \
+    ../package_bgs/KDE/NPBGSubtractor.h \
+    ../package_bgs/lb/BGModel.h \
+    ../package_bgs/lb/BGModelFuzzyGauss.h \
+    ../package_bgs/lb/BGModelFuzzySom.h \
+    ../package_bgs/lb/BGModelGauss.h \
+    ../package_bgs/lb/BGModelMog.h \
+    ../package_bgs/lb/BGModelSom.h \
+    ../package_bgs/lb/Types.h \
+    ../package_bgs/LBP_MRF/block.h \
+    ../package_bgs/LBP_MRF/graph.h \
+    ../package_bgs/LBP_MRF/MEDefs.hpp \
+    ../package_bgs/LBP_MRF/MEHistogram.hpp \
+    ../package_bgs/LBP_MRF/MEImage.hpp \
+    ../package_bgs/LBP_MRF/MotionDetection.hpp \
+    ../package_bgs/LBSP/BackgroundSubtractorLBSP.h \
+    ../package_bgs/LBSP/BackgroundSubtractorLBSP_.h \
+    ../package_bgs/LBSP/BackgroundSubtractorLOBSTER.h \
+    ../package_bgs/LBSP/BackgroundSubtractorPAWCS.h \
+    ../package_bgs/LBSP/BackgroundSubtractorSuBSENSE.h \
+    ../package_bgs/LBSP/DistanceUtils.h \
+    ../package_bgs/LBSP/LBSP.h \
+    ../package_bgs/LBSP/LBSP_.h \
+    ../package_bgs/LBSP/RandUtils.h \
+    ../package_bgs/MultiLayer/BackgroundSubtractionAPI.h \
+    ../package_bgs/MultiLayer/BGS.h \
+    ../package_bgs/MultiLayer/blob.h \
+    ../package_bgs/MultiLayer/BlobExtraction.h \
+    ../package_bgs/MultiLayer/BlobLibraryConfiguration.h \
+    ../package_bgs/MultiLayer/BlobResult.h \
+    ../package_bgs/MultiLayer/CMultiLayerBGS.h \
+    ../package_bgs/MultiLayer/LocalBinaryPattern.h \
+    ../package_bgs/MultiLayer/OpenCvDataConversion.h \
+    ../package_bgs/MultiLayer/OpenCvLegacyIncludes.h \
+    ../package_bgs/PBAS/PBAS.h \
+    ../package_bgs/SigmaDelta/sdLaMa091.h \
+    ../package_bgs/T2F/FuzzyUtils.h \
+    ../package_bgs/T2F/MRF.h \
+    ../package_bgs/T2F/T2FGMM.h \
+    ../package_bgs/T2F/T2FMRF.h \
+    ../package_bgs/TwoPoints/two_points.h \
+    ../package_bgs/ViBe/vibe-background-sequential.h \
+    ../package_bgs/VuMeter/TBackground.h \
+    ../package_bgs/VuMeter/TBackgroundVuMeter.h \
+    ../package_bgs/AdaptiveBackgroundLearning.h \
+    ../package_bgs/AdaptiveSelectiveBackgroundLearning.h \
+    ../package_bgs/bgslibrary.h \
+    ../package_bgs/DPAdaptiveMedian.h \
+    ../package_bgs/DPEigenbackground.h \
+    ../package_bgs/DPGrimsonGMM.h \
+    ../package_bgs/DPMean.h \
+    ../package_bgs/DPPratiMediod.h \
+    ../package_bgs/DPTexture.h \
+    ../package_bgs/DPWrenGA.h \
+    ../package_bgs/DPZivkovicAGMM.h \
+    ../package_bgs/FrameDifference.h \
+    ../package_bgs/FuzzyChoquetIntegral.h \
+    ../package_bgs/FuzzySugenoIntegral.h \
+    ../package_bgs/GMG.h \
+    ../package_bgs/IBGS.h \
+    ../package_bgs/IndependentMultimodal.h \
+    ../package_bgs/KDE.h \
+    ../package_bgs/KNN.h \
+    ../package_bgs/LBAdaptiveSOM.h \
+    ../package_bgs/LBFuzzyAdaptiveSOM.h \
+    ../package_bgs/LBFuzzyGaussian.h \
+    ../package_bgs/LBMixtureOfGaussians.h \
+    ../package_bgs/LBP_MRF.h \
+    ../package_bgs/LBSimpleGaussian.h \
+    ../package_bgs/LOBSTER.h \
+    ../package_bgs/MixtureOfGaussianV1.h \
+    ../package_bgs/MixtureOfGaussianV2.h \
+    ../package_bgs/MultiCue.h \
+    ../package_bgs/MultiLayer.h \
+    ../package_bgs/PAWCS.h \
+    ../package_bgs/PixelBasedAdaptiveSegmenter.h \
+    ../package_bgs/SigmaDelta.h \
+    ../package_bgs/StaticFrameDifference.h \
+    ../package_bgs/SuBSENSE.h \
+    ../package_bgs/T2FGMM_UM.h \
+    ../package_bgs/T2FGMM_UV.h \
+    ../package_bgs/T2FMRF_UM.h \
+    ../package_bgs/T2FMRF_UV.h \
+    ../package_bgs/TwoPoints.h \
+    ../package_bgs/ViBe.h \
+    ../package_bgs/VuMeter.h \
+    ../package_bgs/WeightedMovingMean.h \
+    ../package_bgs/WeightedMovingVariance.h
+
+FORMS    += mainwindow.ui
+
+DISTFILES += \
+    ../package_bgs/LBSP/LBSP_16bits_dbcross_1ch.i \
+    ../package_bgs/LBSP/LBSP_16bits_dbcross_3ch1t.i \
+    ../package_bgs/LBSP/LBSP_16bits_dbcross_3ch3t.i \
+    ../package_bgs/LBSP/LBSP_16bits_dbcross_s3ch.i \
+    ../package_bgs/ViBe/LICENSE
diff --git a/gui_qt/build/.gitignore b/gui_qt/build/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4e2a98bb114355ae964e78a929c12d44f75815de
--- /dev/null
+++ b/gui_qt/build/.gitignore
@@ -0,0 +1,4 @@
+# Ignore everything in this directory
+*
+# Except these files
+!.gitignore
diff --git a/gui_qt/figs/copy.png b/gui_qt/figs/copy.png
new file mode 100644
index 0000000000000000000000000000000000000000..2aeb28288f58ddffdd1d75115f170c5bf2773814
Binary files /dev/null and b/gui_qt/figs/copy.png differ
diff --git a/gui_qt/figs/cut.png b/gui_qt/figs/cut.png
new file mode 100644
index 0000000000000000000000000000000000000000..54638e9386dc8af40dcc9a3ee2f57c62e248e406
Binary files /dev/null and b/gui_qt/figs/cut.png differ
diff --git a/gui_qt/figs/new.png b/gui_qt/figs/new.png
new file mode 100644
index 0000000000000000000000000000000000000000..12131b01008a3ec29ec69f8b3f65c4b3c15b60d6
Binary files /dev/null and b/gui_qt/figs/new.png differ
diff --git a/gui_qt/figs/open.png b/gui_qt/figs/open.png
new file mode 100644
index 0000000000000000000000000000000000000000..45fa2883a71fcb891f1ef7c0c217d71eeae284bc
Binary files /dev/null and b/gui_qt/figs/open.png differ
diff --git a/gui_qt/figs/paste.png b/gui_qt/figs/paste.png
new file mode 100644
index 0000000000000000000000000000000000000000..c14425cad1ff1b2c5628be5769c9e9e52b78635f
Binary files /dev/null and b/gui_qt/figs/paste.png differ
diff --git a/gui_qt/figs/save.png b/gui_qt/figs/save.png
new file mode 100644
index 0000000000000000000000000000000000000000..daba865fafd22fa18e7c0488eb699b79d3554170
Binary files /dev/null and b/gui_qt/figs/save.png differ
diff --git a/gui_qt/mainwindow.cpp b/gui_qt/mainwindow.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bb7eac8c0acbab9f27cfa9ffa59bd3649f0a76a8
--- /dev/null
+++ b/gui_qt/mainwindow.cpp
@@ -0,0 +1,571 @@
+/*
+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 "mainwindow.h"
+#include "ui_mainwindow.h"
+
+namespace bgslibrary
+{
+  //template<typename T> IBGS* createInstance() { return new T; }
+  //typedef std::map<std::string, IBGS*(*)()> map_ibgs;
+
+  IBGS* get_alg(std::string alg_name) {
+    map_ibgs map;
+    map["FrameDifference"] = &createInstance<FrameDifference>;
+    map["StaticFrameDifference"] = &createInstance<StaticFrameDifference>;
+    map["WeightedMovingMean"] = &createInstance<WeightedMovingMean>;
+    map["WeightedMovingVariance"] = &createInstance<WeightedMovingVariance>;
+#if CV_MAJOR_VERSION == 2
+    map["MixtureOfGaussianV1"] = &createInstance<MixtureOfGaussianV1>; // only for OpenCV 2.x
+#endif
+    map["MixtureOfGaussianV2"] = &createInstance<MixtureOfGaussianV2>;
+    map["AdaptiveBackgroundLearning"] = &createInstance<AdaptiveBackgroundLearning>;
+    map["AdaptiveSelectiveBackgroundLearning"] = &createInstance<AdaptiveSelectiveBackgroundLearning>;
+#if CV_MAJOR_VERSION == 2 && CV_MINOR_VERSION >= 4 && CV_SUBMINOR_VERSION >= 3
+    map["GMG"] = &createInstance<GMG>; // only for OpenCV >= 2.4.3
+#endif
+#if CV_MAJOR_VERSION == 3
+    map["KNN"] = &createInstance<KNN>; // only on OpenCV 3.x
+#endif
+    map["DPAdaptiveMedian"] = &createInstance<DPAdaptiveMedian>;
+    map["DPGrimsonGMM"] = &createInstance<DPGrimsonGMM>;
+    map["DPZivkovicAGMM"] = &createInstance<DPZivkovicAGMM>;
+    map["DPMean"] = &createInstance<DPMean>;
+    map["DPWrenGA"] = &createInstance<DPWrenGA>;
+    map["DPPratiMediod"] = &createInstance<DPPratiMediod>;
+    map["DPEigenbackground"] = &createInstance<DPEigenbackground>;
+    map["DPTexture"] = &createInstance<DPTexture>;
+    map["T2FGMM_UM"] = &createInstance<T2FGMM_UM>;
+    map["T2FGMM_UV"] = &createInstance<T2FGMM_UV>;
+    map["T2FMRF_UM"] = &createInstance<T2FMRF_UM>;
+    map["T2FMRF_UV"] = &createInstance<T2FMRF_UV>;
+    map["FuzzySugenoIntegral"] = &createInstance<FuzzySugenoIntegral>;
+    map["FuzzyChoquetIntegral"] = &createInstance<FuzzyChoquetIntegral>;
+    map["MultiLayer"] = &createInstance<MultiLayer>;
+    map["PixelBasedAdaptiveSegmenter"] = &createInstance<PixelBasedAdaptiveSegmenter>;
+    map["LBSimpleGaussian"] = &createInstance<LBSimpleGaussian>;
+    map["LBFuzzyGaussian"] = &createInstance<LBFuzzyGaussian>;
+    map["LBMixtureOfGaussians"] = &createInstance<LBMixtureOfGaussians>;
+    map["LBAdaptiveSOM"] = &createInstance<LBAdaptiveSOM>;
+    map["LBFuzzyAdaptiveSOM"] = &createInstance<LBFuzzyAdaptiveSOM>;
+    map["LBP_MRF"] = &createInstance<LBP_MRF>;
+    map["VuMeter"] = &createInstance<VuMeter>;
+    map["KDE"] = &createInstance<KDE>;
+    map["IndependentMultimodal"] = &createInstance<IndependentMultimodal>;
+    map["MultiCue"] = &createInstance<MultiCue>;
+    map["SigmaDelta"] = &createInstance<SigmaDelta>;
+    map["SuBSENSE"] = &createInstance<SuBSENSE>;
+    map["LOBSTER"] = &createInstance<LOBSTER>;
+    map["PAWCS"] = &createInstance<PAWCS>;
+    map["TwoPoints"] = &createInstance<TwoPoints>;
+    map["ViBe"] = &createInstance<ViBe>;
+
+    return map[alg_name]();
+  }
+
+  QStringList get_algs_name()
+  {
+    QStringList stringList;
+    stringList.append("FrameDifference");
+    stringList.append("StaticFrameDifference");
+    stringList.append("WeightedMovingMean");
+    stringList.append("WeightedMovingVariance");
+#if CV_MAJOR_VERSION == 2
+    stringList.append("MixtureOfGaussianV1"); // only for OpenCV 2.x
+#endif
+    stringList.append("MixtureOfGaussianV2");
+    stringList.append("AdaptiveBackgroundLearning");
+    stringList.append("AdaptiveSelectiveBackgroundLearning");
+#if CV_MAJOR_VERSION == 2 && CV_MINOR_VERSION >= 4 && CV_SUBMINOR_VERSION >= 3
+    stringList.append("GMG"); // only for OpenCV >= 2.4.3
+#endif
+#if CV_MAJOR_VERSION == 3
+    stringList.append("KNN"); // only on OpenCV 3.x
+#endif
+    stringList.append("DPAdaptiveMedian");
+    stringList.append("DPGrimsonGMM");
+    stringList.append("DPZivkovicAGMM");
+    stringList.append("DPMean");
+    stringList.append("DPWrenGA");
+    stringList.append("DPPratiMediod");
+    stringList.append("DPEigenbackground");
+    stringList.append("DPTexture");
+    stringList.append("T2FGMM_UM");
+    stringList.append("T2FGMM_UV");
+    stringList.append("T2FMRF_UM");
+    stringList.append("T2FMRF_UV");
+    stringList.append("FuzzySugenoIntegral");
+    stringList.append("FuzzyChoquetIntegral");
+    stringList.append("MultiLayer");
+    stringList.append("PixelBasedAdaptiveSegmenter");
+    stringList.append("LBSimpleGaussian");
+    stringList.append("LBFuzzyGaussian");
+    stringList.append("LBMixtureOfGaussians");
+    stringList.append("LBAdaptiveSOM");
+    stringList.append("LBFuzzyAdaptiveSOM");
+    stringList.append("LBP_MRF");
+    stringList.append("VuMeter");
+    stringList.append("KDE");
+    stringList.append("IndependentMultimodal");
+    stringList.append("MultiCue");
+    stringList.append("SigmaDelta");
+    stringList.append("SuBSENSE");
+    stringList.append("LOBSTER");
+    stringList.append("PAWCS");
+    stringList.append("TwoPoints");
+    stringList.append("ViBe");
+    return stringList;
+  }
+}
+
+MainWindow::MainWindow(QWidget *parent) :
+  QMainWindow(parent),
+  ui(new Ui::MainWindow)
+{
+  ui->setupUi(this);
+  //QDir applicationPath(QCoreApplication::applicationDirPath());
+  fileName = QDir(".").filePath("dataset/video.avi");
+  //fileName = applicationPath.absolutePath() + "dataset";
+  ui->lineEdit_inputdata->setText(fileName);
+  //fileName = ui->lineEdit_inputdata->text();
+  timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(startCapture()));
+  QStringListModel* listModel = new QStringListModel(bgslibrary::get_algs_name(), NULL);
+  listModel->sort(0);
+  ui->listView_algorithms->setModel(listModel);
+  QModelIndex index = listModel->index(0);
+  ui->listView_algorithms->selectionModel()->select(index, QItemSelectionModel::Select);
+}
+
+MainWindow::~MainWindow()
+{
+  delete ui;
+}
+
+void MainWindow::on_actionExit_triggered()
+{
+  this->close();
+}
+
+void MainWindow::on_pushButton_inputdata_clicked()
+{
+  QFileDialog dialog(this);
+
+  if (ui->checkBox_imageseq->isChecked())
+    dialog.setFileMode(QFileDialog::Directory);
+  else
+    dialog.setFileMode(QFileDialog::ExistingFile);
+  //dialog.setFileMode(QFileDialog::AnyFile);
+
+  dialog.exec();
+  QStringList list = dialog.selectedFiles();
+  /*
+    for(int index = 0; index < list.length(); index++)
+       std::cout << list.at(index).toStdString() << std::endl;
+    */
+  if (list.size() > 0)
+  {
+    fileName = list.at(0);
+    ui->lineEdit_inputdata->setText(fileName);
+  }
+}
+
+void MainWindow::on_pushButton_out_in_clicked()
+{
+  QFileDialog dialog(this);
+  dialog.setDirectory(".");
+  dialog.setFileMode(QFileDialog::Directory);
+  dialog.exec();
+  QStringList list = dialog.selectedFiles();
+  if (list.size() > 0)
+  {
+    fileName = list.at(0);
+    ui->lineEdit_out_in->setText(fileName);
+  }
+}
+
+void MainWindow::on_pushButton_out_fg_clicked()
+{
+  QFileDialog dialog(this);
+  dialog.setDirectory(".");
+  dialog.setFileMode(QFileDialog::Directory);
+  dialog.exec();
+  QStringList list = dialog.selectedFiles();
+  if (list.size() > 0)
+  {
+    fileName = list.at(0);
+    ui->lineEdit_out_fg->setText(fileName);
+  }
+}
+
+void MainWindow::on_pushButton_out_bg_clicked()
+{
+  QFileDialog dialog(this);
+  dialog.setDirectory(".");
+  dialog.setFileMode(QFileDialog::Directory);
+  dialog.exec();
+  QStringList list = dialog.selectedFiles();
+  if (list.size() > 0)
+  {
+    fileName = list.at(0);
+    ui->lineEdit_out_bg->setText(fileName);
+  }
+}
+
+void MainWindow::on_pushButton_start_clicked()
+{
+  useCamera = false;
+  useVideo = false;
+  useSequence = false;
+
+  if (ui->checkBox_webcamera->isChecked())
+    useCamera = true;
+  else
+  {
+    if (ui->checkBox_imageseq->isChecked())
+      useSequence = true;
+    else
+      useVideo = true;
+  }
+
+  if (!timer->isActive() && setUpCapture())
+  {
+    createBGS();
+    startTimer();
+  }
+}
+
+void MainWindow::on_pushButton_stop_clicked()
+{
+  stopTimer();
+}
+
+void MainWindow::createBGS()
+{
+  QString algorithm_name = getSelectedAlgorithmName();
+  bgs = bgslibrary::get_alg(algorithm_name.toStdString());
+  bgs->setShowOutput(false);
+}
+
+void MainWindow::destroyBGS()
+{
+  delete bgs;
+}
+
+void MainWindow::startTimer()
+{
+  std::cout << "startTimer()" << std::endl;
+
+  ui->progressBar->setValue(0);
+  setFrameNumber(0);
+  frameNumber_aux = 0;
+  timer->start(33);
+
+  // disable options
+}
+
+void MainWindow::stopTimer()
+{
+  if (!timer->isActive())
+    return;
+
+  std::cout << "stopTimer()" << std::endl;
+
+  timer->stop();
+  //setFrameNumber(0);
+  //ui->progressBar->setValue(0);
+
+  destroyBGS();
+
+  if (useCamera || useVideo)
+    capture.release();
+
+  // enable options
+}
+
+void MainWindow::setFrameNumber(long long _frameNumber)
+{
+  //std::cout << "setFrameNumber()" << std::endl;
+  frameNumber = _frameNumber;
+  QString txt_frameNumber = QString::fromStdString(its(frameNumber));
+  ui->label_framenumber_txt->setText(txt_frameNumber);
+}
+
+bool MainWindow::setUpCapture()
+{
+  capture_length = 0;
+
+  if (useCamera && !setUpCamera()) {
+    std::cout << "Cannot initialize webcamera!" << std::endl;
+    return false;
+  }
+
+  if (useVideo && !setUpVideo()) {
+    std::cout << "Cannot open video file " << fileName.toStdString() << std::endl;
+    return false;
+  }
+
+  if (useSequence && !setUpSequence()) {
+    std::cout << "Cannot process images at " << fileName.toStdString() << std::endl;
+    return false;
+  }
+
+  if (useCamera || useVideo) {
+    int capture_fps = capture.get(CV_CAP_PROP_FPS);
+    std::cout << "capture_fps: " << capture_fps << std::endl;
+  }
+
+  if (useVideo) {
+    capture_length = capture.get(CV_CAP_PROP_FRAME_COUNT);
+    std::cout << "capture_length: " << capture_length << std::endl;
+  }
+
+  std::cout << "OK!" << std::endl;
+  return true;
+}
+
+void MainWindow::startCapture()
+{
+  //std::cout << "startCapture()" << std::endl;
+  setFrameNumber(frameNumber + 1);
+  cv::Mat cv_frame;
+
+  if (useCamera || useVideo)
+    capture >> cv_frame;
+
+  if (useSequence && (frameNumber - 1) < entryList.length())
+  {
+    QString file = entryList.at(frameNumber - 1);
+    QString filePath = QDir(fileName).filePath(file);
+
+    std::cout << "Processing: " << filePath.toStdString() << std::endl;
+    if (fileExists(filePath))
+      cv_frame = cv::imread(filePath.toStdString());
+  }
+
+  if (cv_frame.empty())
+  {
+    stopTimer();
+    return;
+  }
+
+  if (frameNumber == 1)
+  {
+    int frame_width = cv_frame.size().width;
+    int frame_height = cv_frame.size().height;
+    ui->label_frameresw_txt->setText(QString::fromStdString(its(frame_width)));
+    ui->label_frameresh_txt->setText(QString::fromStdString(its(frame_height)));
+  }
+
+  if (useVideo && capture_length > 0)
+  {
+    double perc = (double(frameNumber) / double(capture_length)) * 100.0;
+    //std::cout << "perc: " << perc << std::endl;
+    ui->progressBar->setValue(perc);
+  }
+
+  int startAt = ui->spinBox_startat->value();
+  if (startAt > 0 && frameNumber < startAt)
+  {
+    timer->setInterval(1);
+    return;
+  }
+  else
+    timer->setInterval(33);
+
+  int stopAt = ui->spinBox_stopat->value();
+  if (stopAt > 0 && frameNumber >= stopAt)
+  {
+    stopTimer();
+    return;
+  }
+
+  cv::Mat cv_frame_small;
+  cv::resize(cv_frame, cv_frame_small, cv::Size(250, 250));
+
+  QImage qt_frame = cv2qimage(cv_frame_small);
+  ui->label_img_in->setPixmap(QPixmap::fromImage(qt_frame, Qt::MonoOnly));
+
+  processFrame(cv_frame);
+}
+
+QImage MainWindow::cv2qimage(const cv::Mat &cv_frame)
+{
+  if (cv_frame.channels() == 3)
+    return Mat2QImage(cv_frame);
+  else
+    return GrayMat2QImage(cv_frame);
+}
+
+void MainWindow::processFrame(const cv::Mat &cv_frame)
+{
+  cv::Mat cv_fg;
+  cv::Mat cv_bg;
+  tic();
+  bgs->process(cv_frame, cv_fg, cv_bg);
+  toc();
+  ui->label_fps_txt->setText(QString::fromStdString(its(fps())));
+
+  cv::Mat cv_fg_small;
+  cv::resize(cv_fg, cv_fg_small, cv::Size(250, 250));
+  QImage qt_fg = cv2qimage(cv_fg_small);
+  ui->label_img_fg->setPixmap(QPixmap::fromImage(qt_fg, Qt::MonoOnly));
+
+  cv::Mat cv_bg_small;
+  cv::resize(cv_bg, cv_bg_small, cv::Size(250, 250));
+  QImage qt_bg = cv2qimage(cv_bg_small);
+  ui->label_img_bg->setPixmap(QPixmap::fromImage(qt_bg, Qt::MonoOnly));
+
+  if (ui->checkBox_save_im->isChecked() || ui->checkBox_save_fg->isChecked() || ui->checkBox_save_bg->isChecked())
+  {
+    if (ui->checkBox_kfn->isChecked())
+      frameNumber_aux = frameNumber;
+    else
+      frameNumber_aux = frameNumber_aux + 1;
+  }
+  if (ui->checkBox_save_im->isChecked())
+  {
+    QString out_im_path = ui->lineEdit_out_in->text();
+    QString out_im_file = QDir(out_im_path).filePath(QString::number(frameNumber_aux) + ".png");
+    cv::imwrite(out_im_file.toStdString(), cv_frame);
+  }
+  if (ui->checkBox_save_fg->isChecked())
+  {
+    QString out_im_path = ui->lineEdit_out_fg->text();
+    QString out_im_file = QDir(out_im_path).filePath(QString::number(frameNumber_aux) + ".png");
+    cv::imwrite(out_im_file.toStdString(), cv_fg);
+  }
+  if (ui->checkBox_save_bg->isChecked())
+  {
+    QString out_im_path = ui->lineEdit_out_bg->text();
+    QString out_im_file = QDir(out_im_path).filePath(QString::number(frameNumber) + ".png");
+    cv::imwrite(out_im_file.toStdString(), cv_bg);
+  }
+}
+
+void MainWindow::tic()
+{
+  duration = static_cast<double>(cv::getTickCount());
+}
+
+void MainWindow::toc()
+{
+  duration = (static_cast<double>(cv::getTickCount()) - duration) / cv::getTickFrequency();
+  //std::cout << "time(sec):" << std::fixed << std::setprecision(6) << duration << std::endl;
+  //std::cout << duration << std::endl;
+}
+
+double MainWindow::fps()
+{
+  //double fps  = frameNumber / duration;
+  double fps = 1 / duration;
+  //std::cout << "Estimated frames per second : " << fps << std::endl;
+  return fps;
+}
+
+bool MainWindow::setUpCamera()
+{
+  int cameraIndex = ui->spinBox_webcamera->value();
+  std::cout << "Camera index: " << cameraIndex << std::endl;
+
+  capture.open(cameraIndex);
+  return capture.isOpened();
+}
+
+bool MainWindow::setUpVideo()
+{
+  std::string videoFileName = fileName.toStdString();
+  std::cout << "Openning: " << videoFileName << std::endl;
+  capture.open(videoFileName.c_str());
+  return capture.isOpened();
+}
+
+bool MainWindow::setUpSequence()
+{
+  std::cout << "Directory path: " << fileName.toStdString() << std::endl;
+  if (QDir(fileName).exists())
+  {
+    QDir dir(fileName);
+    QStringList filters;
+    filters << "*.png" << "*.jpg" << "*.bmp" << "*.gif";
+    dir.setNameFilters(filters);
+    //entryList = dir.entryList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden  | QDir::AllDirs | QDir::Files, QDir::DirsFirst);
+    //entryList = dir.entryList(QDir::Filter::Files, QDir::SortFlag::NoSort);
+    dir.setFilter(QDir::Files | QDir::NoSymLinks);
+    dir.setSorting(QDir::NoSort);  // will sort manually with std::sort
+    //dir.setSorting(QDir::LocaleAware);
+    entryList = dir.entryList();
+
+    std::cout << entryList.length() << std::endl;
+    if (entryList.length() == 0)
+    {
+      QMessageBox::warning(this, "Warning", "No image found! (png, jpg, bmp, gif)");
+      return false;
+    }
+
+    QCollator collator;
+    collator.setNumericMode(true);
+    std::sort(
+      entryList.begin(),
+      entryList.end(),
+      [&collator](const QString &file1, const QString &file2)
+    {
+      return collator.compare(file1, file2) < 0;
+    });
+
+    //    for(int i = 0; i < entryList.length(); i++)
+    //    {
+    //      QString file = entryList.at(i);
+    //      std::cout << file.toStdString() << std::endl;
+    //    }
+    return true;
+  }
+  else
+  {
+    QMessageBox::warning(this, "Warning", "Directory path doesn't exist!");
+    return false;
+  }
+}
+
+QString MainWindow::getSelectedAlgorithmName()
+{
+  QModelIndex index = ui->listView_algorithms->currentIndex();
+  QString algorithm_name = index.data(Qt::DisplayRole).toString();
+  return algorithm_name;
+}
+
+void MainWindow::on_listView_algorithms_doubleClicked(const QModelIndex &index)
+{
+  QString algorithm_name = index.data(Qt::DisplayRole).toString();
+  std::cout << "Selected algorithm: " << algorithm_name.toStdString() << std::endl;
+
+  //  CodeEditor editor;
+  //  editor.setWindowTitle(QObject::tr("Code Editor Example"));
+  //  editor.show();
+
+  QString configFileName = QDir(".").filePath("config/" + algorithm_name + ".xml");
+  std::cout << "Looking for: " << configFileName.toStdString() << std::endl;
+
+  if (fileExists(configFileName))
+  {
+    textEditor.loadFile(configFileName);
+    textEditor.show();
+  }
+  else
+  {
+    QMessageBox::warning(this, "Warning", "XML configuration file not found!\nPlease run the algorithm first!");
+    return;
+  }
+}
diff --git a/gui_qt/mainwindow.h b/gui_qt/mainwindow.h
new file mode 100644
index 0000000000000000000000000000000000000000..a834882b7bc73683e53f6d0960f26209f82e9961
--- /dev/null
+++ b/gui_qt/mainwindow.h
@@ -0,0 +1,110 @@
+/*
+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
+
+#include <QApplication>
+#include <QCommandLineParser>
+#include <QCommandLineOption>
+#include <QMainWindow>
+#include <QFileDialog>
+#include <QDebug>
+#include <QFile>
+#include <QMessageBox>
+#include <QImage>
+#include <QTimer>
+#include <QStringList>
+#include <QStringListModel>
+#include <QCollator>
+
+#include <opencv2/opencv.hpp>
+
+#include "qt_utils.h"
+#include "texteditor.h"
+#include "../package_bgs/bgslibrary.h"
+
+namespace bgslibrary
+{
+  template<typename T> IBGS * createInstance() { return new T; }
+  typedef std::map<std::string, IBGS*(*)()> map_ibgs;
+
+  IBGS* get_alg(std::string alg_name);
+  QStringList get_algs_name();
+}
+
+namespace Ui {
+  class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+  Q_OBJECT
+
+public:
+  explicit MainWindow(QWidget *parent = 0);
+  ~MainWindow();
+
+  private slots:
+  void on_actionExit_triggered();
+
+  void on_pushButton_inputdata_clicked();
+
+  void on_pushButton_start_clicked();
+
+  void on_pushButton_stop_clicked();
+
+  void on_pushButton_out_in_clicked();
+
+  void on_pushButton_out_fg_clicked();
+
+  void on_pushButton_out_bg_clicked();
+
+  void on_listView_algorithms_doubleClicked(const QModelIndex &index);
+
+private:
+  Ui::MainWindow *ui;
+  QString fileName;
+  cv::VideoCapture capture;
+  bool useCamera = false;
+  bool useVideo = false;
+  bool useSequence = false;
+  QStringList entryList;
+  long long frameNumber = 0;
+  long long frameNumber_aux = 0;
+  bool setUpCapture();
+  bool setUpCamera();
+  bool setUpVideo();
+  bool setUpSequence();
+  QString getSelectedAlgorithmName();
+  QTimer* timer;
+  void startTimer();
+  void stopTimer();
+  void setFrameNumber(long long frameNumber);
+  QImage cv2qimage(const cv::Mat &cv_frame);
+  void processFrame(const cv::Mat &cv_frame);
+  IBGS *bgs;
+  void createBGS();
+  void destroyBGS();
+  double duration = 0;
+  void tic();
+  void toc();
+  double fps();
+  int capture_length = 0;
+  TextEditor textEditor;
+
+  public slots:
+  void startCapture();
+};
diff --git a/gui_qt/mainwindow.ui b/gui_qt/mainwindow.ui
new file mode 100644
index 0000000000000000000000000000000000000000..75e9e61a8081a9417d138d40149e10b6f2e5ea00
--- /dev/null
+++ b/gui_qt/mainwindow.ui
@@ -0,0 +1,631 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>1070</width>
+    <height>559</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>BGSLibrary QT GUI</string>
+  </property>
+  <widget class="QWidget" name="centralWidget">
+   <widget class="QLabel" name="label_algorithms">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>10</y>
+      <width>251</width>
+      <height>16</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Algorithms</string>
+    </property>
+   </widget>
+   <widget class="QListView" name="listView_algorithms">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>30</y>
+      <width>256</width>
+      <height>361</height>
+     </rect>
+    </property>
+    <property name="editTriggers">
+     <set>QAbstractItemView::NoEditTriggers</set>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_inputdata">
+    <property name="geometry">
+     <rect>
+      <x>280</x>
+      <y>10</y>
+      <width>601</width>
+      <height>16</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Input (specify a video file or a directory path containing the sequence of images)</string>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="lineEdit_inputdata">
+    <property name="geometry">
+     <rect>
+      <x>280</x>
+      <y>30</y>
+      <width>721</width>
+      <height>22</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>./dataset/video.avi</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="pushButton_inputdata">
+    <property name="geometry">
+     <rect>
+      <x>1010</x>
+      <y>30</y>
+      <width>40</width>
+      <height>21</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>...</string>
+    </property>
+   </widget>
+   <widget class="QCheckBox" name="checkBox_webcamera">
+    <property name="geometry">
+     <rect>
+      <x>280</x>
+      <y>60</y>
+      <width>131</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Use web camera</string>
+    </property>
+   </widget>
+   <widget class="QSpinBox" name="spinBox_webcamera">
+    <property name="geometry">
+     <rect>
+      <x>410</x>
+      <y>60</y>
+      <width>42</width>
+      <height>20</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QCheckBox" name="checkBox_imageseq">
+    <property name="geometry">
+     <rect>
+      <x>470</x>
+      <y>60</y>
+      <width>151</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Sequence of images?</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_startat">
+    <property name="geometry">
+     <rect>
+      <x>945</x>
+      <y>60</y>
+      <width>55</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Start at:</string>
+    </property>
+   </widget>
+   <widget class="QSpinBox" name="spinBox_startat">
+    <property name="geometry">
+     <rect>
+      <x>1000</x>
+      <y>60</y>
+      <width>50</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="maximum">
+     <number>9999</number>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_stopat">
+    <property name="geometry">
+     <rect>
+      <x>945</x>
+      <y>85</y>
+      <width>55</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Stop at:</string>
+    </property>
+   </widget>
+   <widget class="QSpinBox" name="spinBox_stopat">
+    <property name="geometry">
+     <rect>
+      <x>1000</x>
+      <y>85</y>
+      <width>50</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="maximum">
+     <number>9999</number>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_input">
+    <property name="geometry">
+     <rect>
+      <x>280</x>
+      <y>120</y>
+      <width>250</width>
+      <height>16</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Input</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_img_in">
+    <property name="geometry">
+     <rect>
+      <x>280</x>
+      <y>140</y>
+      <width>250</width>
+      <height>250</height>
+     </rect>
+    </property>
+    <property name="frameShape">
+     <enum>QFrame::Box</enum>
+    </property>
+    <property name="text">
+     <string>IMG_INPUT</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_img_fg">
+    <property name="geometry">
+     <rect>
+      <x>540</x>
+      <y>140</y>
+      <width>250</width>
+      <height>250</height>
+     </rect>
+    </property>
+    <property name="frameShape">
+     <enum>QFrame::Box</enum>
+    </property>
+    <property name="text">
+     <string>IMG_FOREGROUND</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_img_bg">
+    <property name="geometry">
+     <rect>
+      <x>800</x>
+      <y>140</y>
+      <width>250</width>
+      <height>250</height>
+     </rect>
+    </property>
+    <property name="frameShape">
+     <enum>QFrame::Box</enum>
+    </property>
+    <property name="text">
+     <string>IMG_BACKGROUND</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_foreground">
+    <property name="geometry">
+     <rect>
+      <x>540</x>
+      <y>120</y>
+      <width>250</width>
+      <height>16</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Foreground mask</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_background">
+    <property name="geometry">
+     <rect>
+      <x>800</x>
+      <y>120</y>
+      <width>250</width>
+      <height>16</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Background model</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QCheckBox" name="checkBox_save_im">
+    <property name="geometry">
+     <rect>
+      <x>280</x>
+      <y>400</y>
+      <width>52</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Save</string>
+    </property>
+   </widget>
+   <widget class="QCheckBox" name="checkBox_save_fg">
+    <property name="geometry">
+     <rect>
+      <x>540</x>
+      <y>400</y>
+      <width>52</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Save</string>
+    </property>
+   </widget>
+   <widget class="QCheckBox" name="checkBox_save_bg">
+    <property name="geometry">
+     <rect>
+      <x>800</x>
+      <y>400</y>
+      <width>52</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Save</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="pushButton_stop">
+    <property name="geometry">
+     <rect>
+      <x>960</x>
+      <y>470</y>
+      <width>93</width>
+      <height>23</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Stop</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="pushButton_start">
+    <property name="geometry">
+     <rect>
+      <x>850</x>
+      <y>470</y>
+      <width>93</width>
+      <height>23</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Start</string>
+    </property>
+   </widget>
+   <widget class="QProgressBar" name="progressBar">
+    <property name="geometry">
+     <rect>
+      <x>280</x>
+      <y>470</y>
+      <width>550</width>
+      <height>23</height>
+     </rect>
+    </property>
+    <property name="value">
+     <number>0</number>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_exectime">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>400</y>
+      <width>121</width>
+      <height>16</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Estimated FPS:</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_fps_txt">
+    <property name="geometry">
+     <rect>
+      <x>210</x>
+      <y>400</y>
+      <width>55</width>
+      <height>16</height>
+     </rect>
+    </property>
+    <property name="layoutDirection">
+     <enum>Qt::LeftToRight</enum>
+    </property>
+    <property name="frameShape">
+     <enum>QFrame::Box</enum>
+    </property>
+    <property name="text">
+     <string>0</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_framenumber">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>420</y>
+      <width>121</width>
+      <height>16</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Frame number:</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_framenumber_txt">
+    <property name="geometry">
+     <rect>
+      <x>210</x>
+      <y>420</y>
+      <width>55</width>
+      <height>16</height>
+     </rect>
+    </property>
+    <property name="layoutDirection">
+     <enum>Qt::LeftToRight</enum>
+    </property>
+    <property name="frameShape">
+     <enum>QFrame::Box</enum>
+    </property>
+    <property name="text">
+     <string>0</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_status">
+    <property name="geometry">
+     <rect>
+      <x>209</x>
+      <y>470</y>
+      <width>61</width>
+      <height>23</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Progress:</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_frameres">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>440</y>
+      <width>121</width>
+      <height>16</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Frame resolution:</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_frameresw_txt">
+    <property name="geometry">
+     <rect>
+      <x>140</x>
+      <y>440</y>
+      <width>55</width>
+      <height>16</height>
+     </rect>
+    </property>
+    <property name="layoutDirection">
+     <enum>Qt::LeftToRight</enum>
+    </property>
+    <property name="frameShape">
+     <enum>QFrame::Box</enum>
+    </property>
+    <property name="text">
+     <string>0</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_frameresh_txt">
+    <property name="geometry">
+     <rect>
+      <x>210</x>
+      <y>440</y>
+      <width>55</width>
+      <height>16</height>
+     </rect>
+    </property>
+    <property name="layoutDirection">
+     <enum>Qt::LeftToRight</enum>
+    </property>
+    <property name="frameShape">
+     <enum>QFrame::Box</enum>
+    </property>
+    <property name="text">
+     <string>0</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label_frameres_2">
+    <property name="geometry">
+     <rect>
+      <x>193</x>
+      <y>440</y>
+      <width>21</width>
+      <height>16</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>x</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="lineEdit_out_in">
+    <property name="geometry">
+     <rect>
+      <x>348</x>
+      <y>400</y>
+      <width>140</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>./output/in/</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="pushButton_out_in">
+    <property name="geometry">
+     <rect>
+      <x>490</x>
+      <y>400</y>
+      <width>40</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>...</string>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="lineEdit_out_fg">
+    <property name="geometry">
+     <rect>
+      <x>608</x>
+      <y>400</y>
+      <width>140</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>./output/fg/</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="pushButton_out_fg">
+    <property name="geometry">
+     <rect>
+      <x>750</x>
+      <y>400</y>
+      <width>40</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>...</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="pushButton_out_bg">
+    <property name="geometry">
+     <rect>
+      <x>1010</x>
+      <y>400</y>
+      <width>40</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>...</string>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="lineEdit_out_bg">
+    <property name="geometry">
+     <rect>
+      <x>868</x>
+      <y>400</y>
+      <width>140</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>./output/bg/</string>
+    </property>
+   </widget>
+   <widget class="QCheckBox" name="checkBox_kfn">
+    <property name="geometry">
+     <rect>
+      <x>280</x>
+      <y>420</y>
+      <width>141</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Keep frame number</string>
+    </property>
+    <property name="checked">
+     <bool>true</bool>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QMenuBar" name="menuBar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>1070</width>
+     <height>26</height>
+    </rect>
+   </property>
+   <widget class="QMenu" name="menuBGSLibrary">
+    <property name="title">
+     <string>BGSLibrary</string>
+    </property>
+    <addaction name="actionExit"/>
+   </widget>
+   <addaction name="menuBGSLibrary"/>
+  </widget>
+  <widget class="QStatusBar" name="statusBar"/>
+  <action name="actionExit">
+   <property name="text">
+    <string>Exit</string>
+   </property>
+  </action>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/gui_qt/qt_utils.cpp b/gui_qt/qt_utils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2464d7896aa7bc9d72a47cff3971b925feab6f3b
--- /dev/null
+++ b/gui_qt/qt_utils.cpp
@@ -0,0 +1,74 @@
+/*
+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 "qt_utils.h"
+
+QImage GrayMat2QImage(cv::Mat const& src) {
+  cv::Mat temp;
+  src.copyTo(temp);
+  QImage dest((const uchar *)temp.data, temp.cols, temp.rows, temp.step, QImage::Format_Indexed8);
+  dest.bits();
+  return dest;
+}
+QImage Mat2QImage(cv::Mat const& src) {
+  cv::Mat temp;
+  cvtColor(src, temp, CV_BGR2RGB);
+  QImage dest((const uchar *)temp.data, temp.cols, temp.rows, temp.step, QImage::Format_RGB888);
+  dest.bits();
+  return dest;
+}
+cv::Mat QImage2Mat(QImage const& src) {
+  cv::Mat tmp(src.height(), src.width(), CV_8UC3, (uchar*)src.bits(), src.bytesPerLine());
+  cv::Mat result;
+  cvtColor(tmp, result, CV_RGB2BGR);
+  return result;
+}
+
+QString base64_encode(const QString string) {
+  QByteArray ba;
+  ba.append(string);
+  return ba.toBase64();
+}
+QString base64_decode(const QString string) {
+  QByteArray ba;
+  ba.append(string);
+  return QByteArray::fromBase64(ba);
+}
+QString md5_encode(const QString string) {
+  QByteArray ba;
+  ba.append(string);
+  return QString(QCryptographicHash::hash((ba), QCryptographicHash::Md5).toHex());
+}
+
+int sti(const std::string &s) {
+  int i;
+  std::stringstream ss;
+  ss << s;
+  ss >> i;
+  return i;
+}
+std::string its(int i) {
+  std::stringstream ss;
+  ss << i;
+  return ss.str();
+}
+
+bool fileExists(QString path) {
+  QFileInfo check_file(path);
+  // check if file exists and if yes: Is it really a file and no directory?
+  return check_file.exists() && check_file.isFile();
+}
diff --git a/gui_qt/qt_utils.h b/gui_qt/qt_utils.h
new file mode 100644
index 0000000000000000000000000000000000000000..84128c5676e8b969e76c749d85bf750bbd7a2dbf
--- /dev/null
+++ b/gui_qt/qt_utils.h
@@ -0,0 +1,99 @@
+/*
+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
+
+#include <sstream>
+#include <string>
+#include <QByteArray>
+#include <QImage>
+#include <QCryptographicHash>
+#include <QFileInfo>
+#include <opencv2/opencv.hpp>
+
+QImage GrayMat2QImage(cv::Mat const& src);
+QImage Mat2QImage(cv::Mat const& src);
+cv::Mat QImage2Mat(QImage const& src);
+
+QString base64_encode(const QString string);
+QString base64_decode(const QString string);
+QString md5_encode(const QString);
+
+int sti(const std::string &s);
+std::string its(int i);
+
+bool fileExists(QString path);
+
+/*
+#include <QFileDialog>
+#include <QApplication>
+#include <QWidget>
+#include <QTreeWidget>
+#include <QPushButton>
+#include <QStringList>
+#include <QModelIndex>
+#include <QDir>
+#include <QDebug>
+
+class FileDialog : public QFileDialog
+{
+    Q_OBJECT
+    public:
+        explicit FileDialog(QWidget *parent = Q_NULLPTR)
+            : QFileDialog(parent)
+        {
+            setOption(QFileDialog::DontUseNativeDialog);
+            setFileMode(QFileDialog::Directory);
+            //setFileMode(QFileDialog::ExistingFiles);
+            //setFileMode(QFileDialog::Directory|QFileDialog::ExistingFiles);
+            for (auto *pushButton : findChildren<QPushButton*>()) {
+                qDebug() << pushButton->text();
+                if (pushButton->text() == "&Open" || pushButton->text() == "&Choose") {
+                    openButton = pushButton;
+                    break;
+                }
+            }
+            disconnect(openButton, SIGNAL(clicked(bool)));
+            connect(openButton, &QPushButton::clicked, this, &FileDialog::openClicked);
+            treeView = findChild<QTreeView*>();
+        }
+
+        QStringList selected() const
+        {
+            return selectedFilePaths;
+        }
+
+    public slots:
+        void openClicked()
+        {
+            selectedFilePaths.clear();
+            qDebug() << treeView->selectionModel()->selection();
+            for (const auto& modelIndex : treeView->selectionModel()->selectedIndexes()) {
+                qDebug() << modelIndex.column();
+                if (modelIndex.column() == 0)
+                    selectedFilePaths.append(directory().absolutePath() + modelIndex.data().toString());
+            }
+            emit filesSelected(selectedFilePaths);
+            hide();
+            qDebug() << selectedFilePaths;
+       }
+
+    private:
+        QTreeView *treeView;
+        QPushButton *openButton;
+        QStringList selectedFilePaths;
+};
+*/
diff --git a/gui_qt/texteditor.cpp b/gui_qt/texteditor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..80f45e118ed842cb231898dbc3128c11ec7f4f8f
--- /dev/null
+++ b/gui_qt/texteditor.cpp
@@ -0,0 +1,320 @@
+/*
+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 <QtWidgets>
+
+#include "texteditor.h"
+
+TextEditor::TextEditor()
+  : textEdit(new QPlainTextEdit)
+{
+  setCentralWidget(textEdit);
+
+  createActions();
+  createStatusBar();
+
+  readSettings();
+
+  connect(textEdit->document(), &QTextDocument::contentsChanged,
+    this, &TextEditor::documentWasModified);
+
+#ifndef QT_NO_SESSIONMANAGER
+  QGuiApplication::setFallbackSessionManagementEnabled(false);
+  connect(qApp, &QGuiApplication::commitDataRequest,
+    this, &TextEditor::commitData);
+#endif
+
+  setCurrentFile(QString());
+  setUnifiedTitleAndToolBarOnMac(true);
+}
+
+void TextEditor::closeEvent(QCloseEvent *event)
+{
+  if (maybeSave()) {
+    writeSettings();
+    event->accept();
+  }
+  else {
+    event->ignore();
+  }
+}
+
+void TextEditor::newFile()
+{
+  if (maybeSave()) {
+    textEdit->clear();
+    setCurrentFile(QString());
+  }
+}
+
+void TextEditor::open()
+{
+  if (maybeSave()) {
+    QString fileName = QFileDialog::getOpenFileName(this);
+    if (!fileName.isEmpty())
+      loadFile(fileName);
+  }
+}
+
+bool TextEditor::save()
+{
+  if (curFile.isEmpty()) {
+    return saveAs();
+  }
+  else {
+    return saveFile(curFile);
+  }
+}
+
+bool TextEditor::saveAs()
+{
+  QFileDialog dialog(this);
+  dialog.setWindowModality(Qt::WindowModal);
+  dialog.setAcceptMode(QFileDialog::AcceptSave);
+  if (dialog.exec() != QDialog::Accepted)
+    return false;
+  return saveFile(dialog.selectedFiles().first());
+}
+
+void TextEditor::about()
+{
+  QMessageBox::about(this, tr("About BGSLibrary"),
+    tr("The <b>BGSLibrary</b> provides an easy-to-use framework "
+      "to perform foreground-background separation in videos."));
+}
+
+void TextEditor::documentWasModified()
+{
+  setWindowModified(textEdit->document()->isModified());
+}
+
+void TextEditor::createActions()
+{
+
+  QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
+  QToolBar *fileToolBar = addToolBar(tr("File"));
+  const QIcon newIcon = QIcon::fromTheme("document-new", QIcon(":/figs/new.png"));
+  QAction *newAct = new QAction(newIcon, tr("&New"), this);
+  newAct->setShortcuts(QKeySequence::New);
+  newAct->setStatusTip(tr("Create a new file"));
+  connect(newAct, &QAction::triggered, this, &TextEditor::newFile);
+  fileMenu->addAction(newAct);
+  fileToolBar->addAction(newAct);
+
+  const QIcon openIcon = QIcon::fromTheme("document-open", QIcon(":/figs/open.png"));
+  QAction *openAct = new QAction(openIcon, tr("&Open..."), this);
+  openAct->setShortcuts(QKeySequence::Open);
+  openAct->setStatusTip(tr("Open an existing file"));
+  connect(openAct, &QAction::triggered, this, &TextEditor::open);
+  fileMenu->addAction(openAct);
+  fileToolBar->addAction(openAct);
+
+  const QIcon saveIcon = QIcon::fromTheme("document-save", QIcon(":/figs/save.png"));
+  QAction *saveAct = new QAction(saveIcon, tr("&Save"), this);
+  saveAct->setShortcuts(QKeySequence::Save);
+  saveAct->setStatusTip(tr("Save the document to disk"));
+  connect(saveAct, &QAction::triggered, this, &TextEditor::save);
+  fileMenu->addAction(saveAct);
+  fileToolBar->addAction(saveAct);
+
+  const QIcon saveAsIcon = QIcon::fromTheme("document-save-as");
+  QAction *saveAsAct = fileMenu->addAction(saveAsIcon, tr("Save &As..."), this, &TextEditor::saveAs);
+  saveAsAct->setShortcuts(QKeySequence::SaveAs);
+  saveAsAct->setStatusTip(tr("Save the document under a new name"));
+
+
+  fileMenu->addSeparator();
+
+  const QIcon exitIcon = QIcon::fromTheme("application-exit");
+  QAction *exitAct = fileMenu->addAction(exitIcon, tr("E&xit"), this, &QWidget::close);
+  exitAct->setShortcuts(QKeySequence::Quit);
+  exitAct->setStatusTip(tr("Exit the application"));
+
+  QMenu *editMenu = menuBar()->addMenu(tr("&Edit"));
+  QToolBar *editToolBar = addToolBar(tr("Edit"));
+#ifndef QT_NO_CLIPBOARD
+  const QIcon cutIcon = QIcon::fromTheme("edit-cut", QIcon(":/figs/cut.png"));
+  QAction *cutAct = new QAction(cutIcon, tr("Cu&t"), this);
+  cutAct->setShortcuts(QKeySequence::Cut);
+  cutAct->setStatusTip(tr("Cut the current selection's contents to the "
+    "clipboard"));
+  connect(cutAct, &QAction::triggered, textEdit, &QPlainTextEdit::cut);
+  editMenu->addAction(cutAct);
+  editToolBar->addAction(cutAct);
+
+  const QIcon copyIcon = QIcon::fromTheme("edit-copy", QIcon(":/figs/copy.png"));
+  QAction *copyAct = new QAction(copyIcon, tr("&Copy"), this);
+  copyAct->setShortcuts(QKeySequence::Copy);
+  copyAct->setStatusTip(tr("Copy the current selection's contents to the "
+    "clipboard"));
+  connect(copyAct, &QAction::triggered, textEdit, &QPlainTextEdit::copy);
+  editMenu->addAction(copyAct);
+  editToolBar->addAction(copyAct);
+
+  const QIcon pasteIcon = QIcon::fromTheme("edit-paste", QIcon(":/figs/paste.png"));
+  QAction *pasteAct = new QAction(pasteIcon, tr("&Paste"), this);
+  pasteAct->setShortcuts(QKeySequence::Paste);
+  pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current "
+    "selection"));
+  connect(pasteAct, &QAction::triggered, textEdit, &QPlainTextEdit::paste);
+  editMenu->addAction(pasteAct);
+  editToolBar->addAction(pasteAct);
+
+  menuBar()->addSeparator();
+
+#endif // !QT_NO_CLIPBOARD
+
+  QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
+  QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &TextEditor::about);
+  aboutAct->setStatusTip(tr("Show the application's About box"));
+
+
+  QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
+  aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
+
+#ifndef QT_NO_CLIPBOARD
+  cutAct->setEnabled(false);
+  copyAct->setEnabled(false);
+  connect(textEdit, &QPlainTextEdit::copyAvailable, cutAct, &QAction::setEnabled);
+  connect(textEdit, &QPlainTextEdit::copyAvailable, copyAct, &QAction::setEnabled);
+#endif // !QT_NO_CLIPBOARD
+}
+
+void TextEditor::createStatusBar()
+{
+  statusBar()->showMessage(tr("Ready"));
+}
+
+void TextEditor::readSettings()
+{
+  QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
+  const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray();
+  if (geometry.isEmpty()) {
+    const QRect availableGeometry = QApplication::desktop()->availableGeometry(this);
+    resize(availableGeometry.width() / 3, availableGeometry.height() / 2);
+    move((availableGeometry.width() - width()) / 2,
+      (availableGeometry.height() - height()) / 2);
+  }
+  else {
+    restoreGeometry(geometry);
+  }
+}
+
+void TextEditor::writeSettings()
+{
+  QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
+  settings.setValue("geometry", saveGeometry());
+}
+
+bool TextEditor::maybeSave()
+{
+  if (!textEdit->document()->isModified())
+    return true;
+  const QMessageBox::StandardButton ret
+    = QMessageBox::warning(this, tr("Application"),
+      tr("The document has been modified.\n"
+        "Do you want to save your changes?"),
+      QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
+  switch (ret) {
+  case QMessageBox::Save:
+    return save();
+  case QMessageBox::Cancel:
+    return false;
+  default:
+    break;
+  }
+  return true;
+}
+
+void TextEditor::loadFile(const QString &fileName)
+{
+  QFile file(fileName);
+  if (!file.open(QFile::ReadOnly | QFile::Text)) {
+    QMessageBox::warning(this, tr("Application"),
+      tr("Cannot read file %1:\n%2.")
+      .arg(QDir::toNativeSeparators(fileName), file.errorString()));
+    return;
+  }
+
+  QTextStream in(&file);
+#ifndef QT_NO_CURSOR
+  QApplication::setOverrideCursor(Qt::WaitCursor);
+#endif
+  textEdit->setPlainText(in.readAll());
+#ifndef QT_NO_CURSOR
+  QApplication::restoreOverrideCursor();
+#endif
+
+  setCurrentFile(fileName);
+  statusBar()->showMessage(tr("File loaded"), 2000);
+}
+
+bool TextEditor::saveFile(const QString &fileName)
+{
+  QFile file(fileName);
+  if (!file.open(QFile::WriteOnly | QFile::Text)) {
+    QMessageBox::warning(this, tr("Application"),
+      tr("Cannot write file %1:\n%2.")
+      .arg(QDir::toNativeSeparators(fileName),
+        file.errorString()));
+    return false;
+  }
+
+  QTextStream out(&file);
+#ifndef QT_NO_CURSOR
+  QApplication::setOverrideCursor(Qt::WaitCursor);
+#endif
+  out << textEdit->toPlainText();
+#ifndef QT_NO_CURSOR
+  QApplication::restoreOverrideCursor();
+#endif
+
+  setCurrentFile(fileName);
+  statusBar()->showMessage(tr("File saved"), 2000);
+  return true;
+}
+
+void TextEditor::setCurrentFile(const QString &fileName)
+{
+  curFile = fileName;
+  textEdit->document()->setModified(false);
+  setWindowModified(false);
+
+  QString shownName = curFile;
+  if (curFile.isEmpty())
+    shownName = "untitled.txt";
+  setWindowFilePath(shownName);
+}
+
+QString TextEditor::strippedName(const QString &fullFileName)
+{
+  return QFileInfo(fullFileName).fileName();
+}
+#ifndef QT_NO_SESSIONMANAGER
+void TextEditor::commitData(QSessionManager &manager)
+{
+  if (manager.allowsInteraction()) {
+    if (!maybeSave())
+      manager.cancel();
+  }
+  else {
+    // Non-interactive: save without asking
+    if (textEdit->document()->isModified())
+      save();
+  }
+}
+#endif
diff --git a/gui_qt/texteditor.h b/gui_qt/texteditor.h
new file mode 100644
index 0000000000000000000000000000000000000000..c0d5d8f60d1d8a4ed859207f52349cd597a49c9a
--- /dev/null
+++ b/gui_qt/texteditor.h
@@ -0,0 +1,64 @@
+/*
+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/>.
+*/
+#ifndef TEXTEDITOR_H
+#define TEXTEDITOR_H
+
+#include <QMainWindow>
+
+class QAction;
+class QMenu;
+class QPlainTextEdit;
+class QSessionManager;
+
+class TextEditor : public QMainWindow
+{
+  Q_OBJECT
+
+public:
+  TextEditor();
+
+  void loadFile(const QString &fileName);
+
+protected:
+  void closeEvent(QCloseEvent *event) override;
+
+  private slots:
+  void newFile();
+  void open();
+  bool save();
+  bool saveAs();
+  void about();
+  void documentWasModified();
+#ifndef QT_NO_SESSIONMANAGER
+  void commitData(QSessionManager &);
+#endif
+
+private:
+  void createActions();
+  void createStatusBar();
+  void readSettings();
+  void writeSettings();
+  bool maybeSave();
+  bool saveFile(const QString &fileName);
+  void setCurrentFile(const QString &fileName);
+  QString strippedName(const QString &fullFileName);
+
+  QPlainTextEdit *textEdit;
+  QString curFile;
+};
+
+#endif // TEXTEDITOR_H
diff --git a/gui_qt/ui_mainwindow.h b/gui_qt/ui_mainwindow.h
new file mode 100644
index 0000000000000000000000000000000000000000..eb3f468520af97f6eb605a2cc1e5feedd91e2545
--- /dev/null
+++ b/gui_qt/ui_mainwindow.h
@@ -0,0 +1,306 @@
+/********************************************************************************
+** Form generated from reading UI file 'mainwindow.ui'
+**
+** Created by: Qt User Interface Compiler version 5.6.2
+**
+** WARNING! All changes made in this file will be lost when recompiling UI file!
+********************************************************************************/
+
+#ifndef UI_MAINWINDOW_H
+#define UI_MAINWINDOW_H
+
+#include <QtCore/QVariant>
+#include <QtWidgets/QAction>
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QButtonGroup>
+#include <QtWidgets/QCheckBox>
+#include <QtWidgets/QHeaderView>
+#include <QtWidgets/QLabel>
+#include <QtWidgets/QLineEdit>
+#include <QtWidgets/QListView>
+#include <QtWidgets/QMainWindow>
+#include <QtWidgets/QMenu>
+#include <QtWidgets/QMenuBar>
+#include <QtWidgets/QProgressBar>
+#include <QtWidgets/QPushButton>
+#include <QtWidgets/QSpinBox>
+#include <QtWidgets/QStatusBar>
+#include <QtWidgets/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class Ui_MainWindow
+{
+public:
+    QAction *actionExit;
+    QWidget *centralWidget;
+    QLabel *label_algorithms;
+    QListView *listView_algorithms;
+    QLabel *label_inputdata;
+    QLineEdit *lineEdit_inputdata;
+    QPushButton *pushButton_inputdata;
+    QCheckBox *checkBox_webcamera;
+    QSpinBox *spinBox_webcamera;
+    QCheckBox *checkBox_imageseq;
+    QLabel *label_startat;
+    QSpinBox *spinBox_startat;
+    QLabel *label_stopat;
+    QSpinBox *spinBox_stopat;
+    QLabel *label_input;
+    QLabel *label_img_in;
+    QLabel *label_img_fg;
+    QLabel *label_img_bg;
+    QLabel *label_foreground;
+    QLabel *label_background;
+    QCheckBox *checkBox_save_im;
+    QCheckBox *checkBox_save_fg;
+    QCheckBox *checkBox_save_bg;
+    QPushButton *pushButton_stop;
+    QPushButton *pushButton_start;
+    QProgressBar *progressBar;
+    QLabel *label_exectime;
+    QLabel *label_fps_txt;
+    QLabel *label_framenumber;
+    QLabel *label_framenumber_txt;
+    QLabel *label_status;
+    QLabel *label_frameres;
+    QLabel *label_frameresw_txt;
+    QLabel *label_frameresh_txt;
+    QLabel *label_frameres_2;
+    QLineEdit *lineEdit_out_in;
+    QPushButton *pushButton_out_in;
+    QLineEdit *lineEdit_out_fg;
+    QPushButton *pushButton_out_fg;
+    QPushButton *pushButton_out_bg;
+    QLineEdit *lineEdit_out_bg;
+    QCheckBox *checkBox_kfn;
+    QMenuBar *menuBar;
+    QMenu *menuBGSLibrary;
+    QStatusBar *statusBar;
+
+    void setupUi(QMainWindow *MainWindow)
+    {
+        if (MainWindow->objectName().isEmpty())
+            MainWindow->setObjectName(QStringLiteral("MainWindow"));
+        MainWindow->resize(1070, 559);
+        actionExit = new QAction(MainWindow);
+        actionExit->setObjectName(QStringLiteral("actionExit"));
+        centralWidget = new QWidget(MainWindow);
+        centralWidget->setObjectName(QStringLiteral("centralWidget"));
+        label_algorithms = new QLabel(centralWidget);
+        label_algorithms->setObjectName(QStringLiteral("label_algorithms"));
+        label_algorithms->setGeometry(QRect(10, 10, 251, 16));
+        listView_algorithms = new QListView(centralWidget);
+        listView_algorithms->setObjectName(QStringLiteral("listView_algorithms"));
+        listView_algorithms->setGeometry(QRect(10, 30, 256, 361));
+        listView_algorithms->setEditTriggers(QAbstractItemView::NoEditTriggers);
+        label_inputdata = new QLabel(centralWidget);
+        label_inputdata->setObjectName(QStringLiteral("label_inputdata"));
+        label_inputdata->setGeometry(QRect(280, 10, 601, 16));
+        lineEdit_inputdata = new QLineEdit(centralWidget);
+        lineEdit_inputdata->setObjectName(QStringLiteral("lineEdit_inputdata"));
+        lineEdit_inputdata->setGeometry(QRect(280, 30, 721, 22));
+        pushButton_inputdata = new QPushButton(centralWidget);
+        pushButton_inputdata->setObjectName(QStringLiteral("pushButton_inputdata"));
+        pushButton_inputdata->setGeometry(QRect(1010, 30, 40, 21));
+        checkBox_webcamera = new QCheckBox(centralWidget);
+        checkBox_webcamera->setObjectName(QStringLiteral("checkBox_webcamera"));
+        checkBox_webcamera->setGeometry(QRect(280, 60, 131, 20));
+        spinBox_webcamera = new QSpinBox(centralWidget);
+        spinBox_webcamera->setObjectName(QStringLiteral("spinBox_webcamera"));
+        spinBox_webcamera->setGeometry(QRect(410, 60, 42, 20));
+        checkBox_imageseq = new QCheckBox(centralWidget);
+        checkBox_imageseq->setObjectName(QStringLiteral("checkBox_imageseq"));
+        checkBox_imageseq->setGeometry(QRect(470, 60, 151, 20));
+        label_startat = new QLabel(centralWidget);
+        label_startat->setObjectName(QStringLiteral("label_startat"));
+        label_startat->setGeometry(QRect(945, 60, 55, 20));
+        spinBox_startat = new QSpinBox(centralWidget);
+        spinBox_startat->setObjectName(QStringLiteral("spinBox_startat"));
+        spinBox_startat->setGeometry(QRect(1000, 60, 50, 20));
+        spinBox_startat->setMaximum(9999);
+        label_stopat = new QLabel(centralWidget);
+        label_stopat->setObjectName(QStringLiteral("label_stopat"));
+        label_stopat->setGeometry(QRect(945, 85, 55, 20));
+        spinBox_stopat = new QSpinBox(centralWidget);
+        spinBox_stopat->setObjectName(QStringLiteral("spinBox_stopat"));
+        spinBox_stopat->setGeometry(QRect(1000, 85, 50, 20));
+        spinBox_stopat->setMaximum(9999);
+        label_input = new QLabel(centralWidget);
+        label_input->setObjectName(QStringLiteral("label_input"));
+        label_input->setGeometry(QRect(280, 120, 250, 16));
+        label_input->setAlignment(Qt::AlignCenter);
+        label_img_in = new QLabel(centralWidget);
+        label_img_in->setObjectName(QStringLiteral("label_img_in"));
+        label_img_in->setGeometry(QRect(280, 140, 250, 250));
+        label_img_in->setFrameShape(QFrame::Box);
+        label_img_in->setAlignment(Qt::AlignCenter);
+        label_img_fg = new QLabel(centralWidget);
+        label_img_fg->setObjectName(QStringLiteral("label_img_fg"));
+        label_img_fg->setGeometry(QRect(540, 140, 250, 250));
+        label_img_fg->setFrameShape(QFrame::Box);
+        label_img_fg->setAlignment(Qt::AlignCenter);
+        label_img_bg = new QLabel(centralWidget);
+        label_img_bg->setObjectName(QStringLiteral("label_img_bg"));
+        label_img_bg->setGeometry(QRect(800, 140, 250, 250));
+        label_img_bg->setFrameShape(QFrame::Box);
+        label_img_bg->setAlignment(Qt::AlignCenter);
+        label_foreground = new QLabel(centralWidget);
+        label_foreground->setObjectName(QStringLiteral("label_foreground"));
+        label_foreground->setGeometry(QRect(540, 120, 250, 16));
+        label_foreground->setAlignment(Qt::AlignCenter);
+        label_background = new QLabel(centralWidget);
+        label_background->setObjectName(QStringLiteral("label_background"));
+        label_background->setGeometry(QRect(800, 120, 250, 16));
+        label_background->setAlignment(Qt::AlignCenter);
+        checkBox_save_im = new QCheckBox(centralWidget);
+        checkBox_save_im->setObjectName(QStringLiteral("checkBox_save_im"));
+        checkBox_save_im->setGeometry(QRect(280, 400, 52, 20));
+        checkBox_save_fg = new QCheckBox(centralWidget);
+        checkBox_save_fg->setObjectName(QStringLiteral("checkBox_save_fg"));
+        checkBox_save_fg->setGeometry(QRect(540, 400, 52, 20));
+        checkBox_save_bg = new QCheckBox(centralWidget);
+        checkBox_save_bg->setObjectName(QStringLiteral("checkBox_save_bg"));
+        checkBox_save_bg->setGeometry(QRect(800, 400, 52, 20));
+        pushButton_stop = new QPushButton(centralWidget);
+        pushButton_stop->setObjectName(QStringLiteral("pushButton_stop"));
+        pushButton_stop->setGeometry(QRect(960, 470, 93, 23));
+        pushButton_start = new QPushButton(centralWidget);
+        pushButton_start->setObjectName(QStringLiteral("pushButton_start"));
+        pushButton_start->setGeometry(QRect(850, 470, 93, 23));
+        progressBar = new QProgressBar(centralWidget);
+        progressBar->setObjectName(QStringLiteral("progressBar"));
+        progressBar->setGeometry(QRect(280, 470, 550, 23));
+        progressBar->setValue(0);
+        label_exectime = new QLabel(centralWidget);
+        label_exectime->setObjectName(QStringLiteral("label_exectime"));
+        label_exectime->setGeometry(QRect(10, 400, 121, 16));
+        label_fps_txt = new QLabel(centralWidget);
+        label_fps_txt->setObjectName(QStringLiteral("label_fps_txt"));
+        label_fps_txt->setGeometry(QRect(210, 400, 55, 16));
+        label_fps_txt->setLayoutDirection(Qt::LeftToRight);
+        label_fps_txt->setFrameShape(QFrame::Box);
+        label_fps_txt->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+        label_framenumber = new QLabel(centralWidget);
+        label_framenumber->setObjectName(QStringLiteral("label_framenumber"));
+        label_framenumber->setGeometry(QRect(10, 420, 121, 16));
+        label_framenumber_txt = new QLabel(centralWidget);
+        label_framenumber_txt->setObjectName(QStringLiteral("label_framenumber_txt"));
+        label_framenumber_txt->setGeometry(QRect(210, 420, 55, 16));
+        label_framenumber_txt->setLayoutDirection(Qt::LeftToRight);
+        label_framenumber_txt->setFrameShape(QFrame::Box);
+        label_framenumber_txt->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+        label_status = new QLabel(centralWidget);
+        label_status->setObjectName(QStringLiteral("label_status"));
+        label_status->setGeometry(QRect(209, 470, 61, 23));
+        label_frameres = new QLabel(centralWidget);
+        label_frameres->setObjectName(QStringLiteral("label_frameres"));
+        label_frameres->setGeometry(QRect(10, 440, 121, 16));
+        label_frameresw_txt = new QLabel(centralWidget);
+        label_frameresw_txt->setObjectName(QStringLiteral("label_frameresw_txt"));
+        label_frameresw_txt->setGeometry(QRect(140, 440, 55, 16));
+        label_frameresw_txt->setLayoutDirection(Qt::LeftToRight);
+        label_frameresw_txt->setFrameShape(QFrame::Box);
+        label_frameresw_txt->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+        label_frameresh_txt = new QLabel(centralWidget);
+        label_frameresh_txt->setObjectName(QStringLiteral("label_frameresh_txt"));
+        label_frameresh_txt->setGeometry(QRect(210, 440, 55, 16));
+        label_frameresh_txt->setLayoutDirection(Qt::LeftToRight);
+        label_frameresh_txt->setFrameShape(QFrame::Box);
+        label_frameresh_txt->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
+        label_frameres_2 = new QLabel(centralWidget);
+        label_frameres_2->setObjectName(QStringLiteral("label_frameres_2"));
+        label_frameres_2->setGeometry(QRect(193, 440, 21, 16));
+        label_frameres_2->setAlignment(Qt::AlignCenter);
+        lineEdit_out_in = new QLineEdit(centralWidget);
+        lineEdit_out_in->setObjectName(QStringLiteral("lineEdit_out_in"));
+        lineEdit_out_in->setGeometry(QRect(348, 400, 140, 20));
+        pushButton_out_in = new QPushButton(centralWidget);
+        pushButton_out_in->setObjectName(QStringLiteral("pushButton_out_in"));
+        pushButton_out_in->setGeometry(QRect(490, 400, 40, 20));
+        lineEdit_out_fg = new QLineEdit(centralWidget);
+        lineEdit_out_fg->setObjectName(QStringLiteral("lineEdit_out_fg"));
+        lineEdit_out_fg->setGeometry(QRect(608, 400, 140, 20));
+        pushButton_out_fg = new QPushButton(centralWidget);
+        pushButton_out_fg->setObjectName(QStringLiteral("pushButton_out_fg"));
+        pushButton_out_fg->setGeometry(QRect(750, 400, 40, 20));
+        pushButton_out_bg = new QPushButton(centralWidget);
+        pushButton_out_bg->setObjectName(QStringLiteral("pushButton_out_bg"));
+        pushButton_out_bg->setGeometry(QRect(1010, 400, 40, 20));
+        lineEdit_out_bg = new QLineEdit(centralWidget);
+        lineEdit_out_bg->setObjectName(QStringLiteral("lineEdit_out_bg"));
+        lineEdit_out_bg->setGeometry(QRect(868, 400, 140, 20));
+        checkBox_kfn = new QCheckBox(centralWidget);
+        checkBox_kfn->setObjectName(QStringLiteral("checkBox_kfn"));
+        checkBox_kfn->setGeometry(QRect(280, 420, 141, 20));
+        checkBox_kfn->setChecked(true);
+        MainWindow->setCentralWidget(centralWidget);
+        menuBar = new QMenuBar(MainWindow);
+        menuBar->setObjectName(QStringLiteral("menuBar"));
+        menuBar->setGeometry(QRect(0, 0, 1070, 26));
+        menuBGSLibrary = new QMenu(menuBar);
+        menuBGSLibrary->setObjectName(QStringLiteral("menuBGSLibrary"));
+        MainWindow->setMenuBar(menuBar);
+        statusBar = new QStatusBar(MainWindow);
+        statusBar->setObjectName(QStringLiteral("statusBar"));
+        MainWindow->setStatusBar(statusBar);
+
+        menuBar->addAction(menuBGSLibrary->menuAction());
+        menuBGSLibrary->addAction(actionExit);
+
+        retranslateUi(MainWindow);
+
+        QMetaObject::connectSlotsByName(MainWindow);
+    } // setupUi
+
+    void retranslateUi(QMainWindow *MainWindow)
+    {
+        MainWindow->setWindowTitle(QApplication::translate("MainWindow", "BGSLibrary QT GUI", 0));
+        actionExit->setText(QApplication::translate("MainWindow", "Exit", 0));
+        label_algorithms->setText(QApplication::translate("MainWindow", "Algorithms", 0));
+        label_inputdata->setText(QApplication::translate("MainWindow", "Input (specify a video file or a directory path containing the sequence of images)", 0));
+        lineEdit_inputdata->setText(QApplication::translate("MainWindow", "./dataset/video.avi", 0));
+        pushButton_inputdata->setText(QApplication::translate("MainWindow", "...", 0));
+        checkBox_webcamera->setText(QApplication::translate("MainWindow", "Use web camera", 0));
+        checkBox_imageseq->setText(QApplication::translate("MainWindow", "Sequence of images?", 0));
+        label_startat->setText(QApplication::translate("MainWindow", "Start at:", 0));
+        label_stopat->setText(QApplication::translate("MainWindow", "Stop at:", 0));
+        label_input->setText(QApplication::translate("MainWindow", "Input", 0));
+        label_img_in->setText(QApplication::translate("MainWindow", "IMG_INPUT", 0));
+        label_img_fg->setText(QApplication::translate("MainWindow", "IMG_FOREGROUND", 0));
+        label_img_bg->setText(QApplication::translate("MainWindow", "IMG_BACKGROUND", 0));
+        label_foreground->setText(QApplication::translate("MainWindow", "Foreground mask", 0));
+        label_background->setText(QApplication::translate("MainWindow", "Background model", 0));
+        checkBox_save_im->setText(QApplication::translate("MainWindow", "Save", 0));
+        checkBox_save_fg->setText(QApplication::translate("MainWindow", "Save", 0));
+        checkBox_save_bg->setText(QApplication::translate("MainWindow", "Save", 0));
+        pushButton_stop->setText(QApplication::translate("MainWindow", "Stop", 0));
+        pushButton_start->setText(QApplication::translate("MainWindow", "Start", 0));
+        label_exectime->setText(QApplication::translate("MainWindow", "Estimated FPS:", 0));
+        label_fps_txt->setText(QApplication::translate("MainWindow", "0", 0));
+        label_framenumber->setText(QApplication::translate("MainWindow", "Frame number:", 0));
+        label_framenumber_txt->setText(QApplication::translate("MainWindow", "0", 0));
+        label_status->setText(QApplication::translate("MainWindow", "Progress:", 0));
+        label_frameres->setText(QApplication::translate("MainWindow", "Frame resolution:", 0));
+        label_frameresw_txt->setText(QApplication::translate("MainWindow", "0", 0));
+        label_frameresh_txt->setText(QApplication::translate("MainWindow", "0", 0));
+        label_frameres_2->setText(QApplication::translate("MainWindow", "x", 0));
+        lineEdit_out_in->setText(QApplication::translate("MainWindow", "./output/in/", 0));
+        pushButton_out_in->setText(QApplication::translate("MainWindow", "...", 0));
+        lineEdit_out_fg->setText(QApplication::translate("MainWindow", "./output/fg/", 0));
+        pushButton_out_fg->setText(QApplication::translate("MainWindow", "...", 0));
+        pushButton_out_bg->setText(QApplication::translate("MainWindow", "...", 0));
+        lineEdit_out_bg->setText(QApplication::translate("MainWindow", "./output/bg/", 0));
+        checkBox_kfn->setText(QApplication::translate("MainWindow", "Keep frame number", 0));
+        menuBGSLibrary->setTitle(QApplication::translate("MainWindow", "BGSLibrary", 0));
+    } // retranslateUi
+
+};
+
+namespace Ui {
+    class MainWindow: public Ui_MainWindow {};
+} // namespace Ui
+
+QT_END_NAMESPACE
+
+#endif // UI_MAINWINDOW_H
diff --git a/output/bg/.gitignore b/output/bg/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4e2a98bb114355ae964e78a929c12d44f75815de
--- /dev/null
+++ b/output/bg/.gitignore
@@ -0,0 +1,4 @@
+# Ignore everything in this directory
+*
+# Except these files
+!.gitignore
diff --git a/output/fg/.gitignore b/output/fg/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4e2a98bb114355ae964e78a929c12d44f75815de
--- /dev/null
+++ b/output/fg/.gitignore
@@ -0,0 +1,4 @@
+# Ignore everything in this directory
+*
+# Except these files
+!.gitignore
diff --git a/output/in/.gitignore b/output/in/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4e2a98bb114355ae964e78a929c12d44f75815de
--- /dev/null
+++ b/output/in/.gitignore
@@ -0,0 +1,4 @@
+# Ignore everything in this directory
+*
+# Except these files
+!.gitignore
diff --git a/package_bgs/tb/PerformanceUtils.cpp b/package_analysis/PerformanceUtils.cpp
similarity index 59%
rename from package_bgs/tb/PerformanceUtils.cpp
rename to package_analysis/PerformanceUtils.cpp
index 0d7cf771dee40bc06b5192718710f78587d99441..6ad5e5faa64d7b746eba212fd2df8313dcb64365 100644
--- a/package_bgs/tb/PerformanceUtils.cpp
+++ b/package_analysis/PerformanceUtils.cpp
@@ -15,15 +15,16 @@ You should have received a copy of the GNU General Public License
 along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "PerformanceUtils.h"
-#include <opencv2/legacy/compat.hpp>
+//#include <opencv2/legacy/compat.hpp>
+//#include <opencv2/highgui/highgui_c.h>
 
-PerformanceUtils::PerformanceUtils(void){}
+PerformanceUtils::PerformanceUtils(void) {}
 
-PerformanceUtils::~PerformanceUtils(void){}
+PerformanceUtils::~PerformanceUtils(void) {}
 
 float PerformanceUtils::NrPixels(IplImage *image)
 {
-  return (float) (image->width * image->height);
+  return (float)(image->width * image->height);
 }
 
 float PerformanceUtils::NrAllDetectedPixNotNULL(IplImage *image, IplImage *ground_truth)
@@ -31,19 +32,19 @@ float PerformanceUtils::NrAllDetectedPixNotNULL(IplImage *image, IplImage *groun
   //Nombre de tous les pixels non nuls dans Groundthruth et dans image
   float Union12 = 0.0;
 
-  unsigned char *pixelGT = (unsigned char*) malloc(1*sizeof(unsigned char));
-  unsigned char *pixelI = (unsigned char*) malloc(1*sizeof(unsigned char));
+  unsigned char *pixelGT = (unsigned char*)malloc(1 * sizeof(unsigned char));
+  unsigned char *pixelI = (unsigned char*)malloc(1 * sizeof(unsigned char));
 
   PixelUtils p;
 
-  for(int y = 0; y < image->height; y++) 
+  for (int y = 0; y < image->height; y++)
   {
-    for(int x = 0; x < image->width; x++) 
-    { 
-      p.GetGrayPixel(ground_truth,x,y,pixelGT); 
-      p.GetGrayPixel(image,x,y,pixelI);
+    for (int x = 0; x < image->width; x++)
+    {
+      p.GetGrayPixel(ground_truth, x, y, pixelGT);
+      p.GetGrayPixel(image, x, y, pixelI);
 
-      if((pixelGT[0] != 0) || (pixelI[0] != 0))	
+      if ((pixelGT[0] != 0) || (pixelI[0] != 0))
         Union12++;
     }
   }
@@ -51,44 +52,44 @@ float PerformanceUtils::NrAllDetectedPixNotNULL(IplImage *image, IplImage *groun
   free(pixelGT);
   free(pixelI);
 
-  return Union12;	
+  return Union12;
 }
 
 float PerformanceUtils::NrTruePositives(IplImage *image, IplImage *ground_truth, bool debug)
 {
   float nTP = 0.0;
 
-  unsigned char *pixelGT = (unsigned char*) malloc(1*sizeof(unsigned char));
-  unsigned char *pixelI = (unsigned char*) malloc(1*sizeof(unsigned char));
+  unsigned char *pixelGT = (unsigned char*)malloc(1 * sizeof(unsigned char));
+  unsigned char *pixelI = (unsigned char*)malloc(1 * sizeof(unsigned char));
 
   IplImage *TPimage = 0;
 
-  if(debug)
+  if (debug)
   {
-    TPimage = cvCreateImage(cvSize(image->width,image->height),image->depth,image->nChannels);
-    cvFillImage(TPimage,0.0);
+    TPimage = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels);
+    cvSetZero(TPimage);
   }
 
   PixelUtils p;
 
-  for(int y = 0; y < image->height; y++) 
+  for (int y = 0; y < image->height; y++)
   {
-    for(int x = 0; x < image->width; x++) 
-    { 
-      p.GetGrayPixel(ground_truth,x,y,pixelGT); 
-      p.GetGrayPixel(image,x,y,pixelI);
+    for (int x = 0; x < image->width; x++)
+    {
+      p.GetGrayPixel(ground_truth, x, y, pixelGT);
+      p.GetGrayPixel(image, x, y, pixelI);
 
-      if((pixelGT[0] != 0) && (pixelI[0] != 0))	
+      if ((pixelGT[0] != 0) && (pixelI[0] != 0))
       {
-        if(debug)
-          p.PutGrayPixel(TPimage,x,y,*pixelI);
+        if (debug)
+          p.PutGrayPixel(TPimage, x, y, *pixelI);
 
         nTP++;
       }
     }
   }
 
-  if(debug)
+  if (debug)
   {
     cvNamedWindow("TPImage", 0);
     cvShowImage("TPImage", TPimage);
@@ -101,46 +102,46 @@ float PerformanceUtils::NrTruePositives(IplImage *image, IplImage *ground_truth,
   free(pixelGT);
   free(pixelI);
 
-  return nTP;	
+  return nTP;
 }
 
 float PerformanceUtils::NrTrueNegatives(IplImage* image, IplImage* ground_truth, bool debug)
 {
   float nTN = 0.0;
 
-  unsigned char *pixelGT = (unsigned char *)malloc(1*sizeof(unsigned char));
-  unsigned char *pixelI = (unsigned char *)malloc(1*sizeof(unsigned char));
+  unsigned char *pixelGT = (unsigned char *)malloc(1 * sizeof(unsigned char));
+  unsigned char *pixelI = (unsigned char *)malloc(1 * sizeof(unsigned char));
 
   IplImage *TNimage = 0;
 
-  if(debug)
+  if (debug)
   {
-    TNimage = cvCreateImage(cvSize(image->width,image->height),image->depth,image->nChannels);
-    cvFillImage(TNimage, 0.0);
+    TNimage = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels);
+    cvSetZero(TNimage);
   }
 
   PixelUtils p;
 
-  for(int y = 0; y < image->height; y++) 
+  for (int y = 0; y < image->height; y++)
   {
-    for(int x = 0; x < image->width; x++) 
+    for (int x = 0; x < image->width; x++)
     {
-      p.GetGrayPixel(ground_truth,x,y,pixelGT);                
-      p.GetGrayPixel(image,x,y,pixelI);
+      p.GetGrayPixel(ground_truth, x, y, pixelGT);
+      p.GetGrayPixel(image, x, y, pixelI);
 
-      if((pixelGT[0] == 0) && (pixelI[0] == 0.0))
+      if ((pixelGT[0] == 0) && (pixelI[0] == 0.0))
       {
         *pixelI = 255;
 
-        if(debug)
-          p.PutGrayPixel(TNimage,x,y,*pixelI);
+        if (debug)
+          p.PutGrayPixel(TNimage, x, y, *pixelI);
 
         nTN++;
-      }				
+      }
     }
   }
 
-  if(debug)
+  if (debug)
   {
     cvNamedWindow("TNImage", 0);
     cvShowImage("TNImage", TNimage);
@@ -156,41 +157,41 @@ float PerformanceUtils::NrTrueNegatives(IplImage* image, IplImage* ground_truth,
   return nTN;
 }
 
-float PerformanceUtils::NrFalsePositives(IplImage *image, IplImage *ground_truth,bool debug)
+float PerformanceUtils::NrFalsePositives(IplImage *image, IplImage *ground_truth, bool debug)
 {
   float nFP = 0.0;
 
-  unsigned char *pixelGT = (unsigned char*) malloc(1*sizeof(unsigned char));
-  unsigned char *pixelI = (unsigned char*) malloc(1*sizeof(unsigned char));
+  unsigned char *pixelGT = (unsigned char*)malloc(1 * sizeof(unsigned char));
+  unsigned char *pixelI = (unsigned char*)malloc(1 * sizeof(unsigned char));
 
   IplImage *FPimage = 0;
 
-  if(debug)
+  if (debug)
   {
-    FPimage = cvCreateImage(cvSize(image->width,image->height),image->depth,image->nChannels);
-    cvFillImage(FPimage, 0.0);
+    FPimage = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels);
+    cvSetZero(FPimage);
   }
 
   PixelUtils p;
 
-  for(int y = 0; y < image->height; y++) 
+  for (int y = 0; y < image->height; y++)
   {
-    for(int x = 0; x < image->width; x++) 
+    for (int x = 0; x < image->width; x++)
     {
-      p.GetGrayPixel(ground_truth,x,y,pixelGT);                
-      p.GetGrayPixel(image,x,y,pixelI);
+      p.GetGrayPixel(ground_truth, x, y, pixelGT);
+      p.GetGrayPixel(image, x, y, pixelI);
 
-      if((pixelGT[0] == 0) && (pixelI[0] != 0))
+      if ((pixelGT[0] == 0) && (pixelI[0] != 0))
       {
-        if(debug)
-          p.PutGrayPixel(FPimage,x,y,*pixelI);
+        if (debug)
+          p.PutGrayPixel(FPimage, x, y, *pixelI);
 
         nFP++;
       }
     }
   }
 
-  if(debug)
+  if (debug)
   {
     cvNamedWindow("FPImage", 0);
     cvShowImage("FPImage", FPimage);
@@ -203,44 +204,44 @@ float PerformanceUtils::NrFalsePositives(IplImage *image, IplImage *ground_truth
   free(pixelGT);
   free(pixelI);
 
-  return nFP;	
+  return nFP;
 }
 
 float PerformanceUtils::NrFalseNegatives(IplImage * image, IplImage *ground_truth, bool debug)
 {
   float nFN = 0.0;
 
-  unsigned char *pixelGT = (unsigned char*) malloc(1*sizeof(unsigned char));
-  unsigned char *pixelI = (unsigned char*) malloc(1*sizeof(unsigned char));
+  unsigned char *pixelGT = (unsigned char*)malloc(1 * sizeof(unsigned char));
+  unsigned char *pixelI = (unsigned char*)malloc(1 * sizeof(unsigned char));
 
   IplImage *FNimage = 0;
 
-  if(debug)
+  if (debug)
   {
-    FNimage = cvCreateImage(cvSize(image->width,image->height),image->depth,image->nChannels);
-    cvFillImage(FNimage, 0.0);
+    FNimage = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels);
+    cvSetZero(FNimage);
   }
 
   PixelUtils p;
 
-  for(int y = 0; y < image->height; y++) 
+  for (int y = 0; y < image->height; y++)
   {
-    for(int x = 0; x < image->width; x++) 
+    for (int x = 0; x < image->width; x++)
     {
-      p.GetGrayPixel(ground_truth,x,y,pixelGT);
-      p.GetGrayPixel(image,x,y,pixelI);
+      p.GetGrayPixel(ground_truth, x, y, pixelGT);
+      p.GetGrayPixel(image, x, y, pixelI);
 
-      if((pixelGT[0] != 0) && (pixelI[0] == 0))
+      if ((pixelGT[0] != 0) && (pixelI[0] == 0))
       {
-        if(debug)
-          p.PutGrayPixel(FNimage,x,y,*pixelGT);
+        if (debug)
+          p.PutGrayPixel(FNimage, x, y, *pixelGT);
 
         nFN++;
       }
     }
   }
 
-  if(debug)
+  if (debug)
   {
     cvNamedWindow("FNImage", 0);
     cvShowImage("FNImage", FNimage);
@@ -253,19 +254,19 @@ float PerformanceUtils::NrFalseNegatives(IplImage * image, IplImage *ground_trut
   free(pixelGT);
   free(pixelI);
 
-  return nFN;	
+  return nFN;
 }
 
 float PerformanceUtils::SimilarityMeasure(IplImage *image, IplImage *ground_truth, bool debug)
 {
-  cv::Mat img_input(image,true);
-  cv::Mat img_ref(ground_truth,true);
+  cv::Mat img_input = cv::cvarrToMat(image, true);
+  cv::Mat img_ref = cv::cvarrToMat(ground_truth, true);
 
   int rn = cv::countNonZero(img_ref);
   cv::Mat i;
   cv::Mat u;
 
-  if(rn > 0)
+  if (rn > 0)
   {
     i = img_input & img_ref;
     u = img_input | img_ref;
@@ -278,16 +279,16 @@ float PerformanceUtils::SimilarityMeasure(IplImage *image, IplImage *ground_trut
 
   int in = cv::countNonZero(i);
   int un = cv::countNonZero(u);
-    
+
   double s = (((double)in) / ((double)un));
-  
-  if(debug)
+
+  if (debug)
   {
     cv::imshow("A^B", i);
     cv::imshow("AvB", u);
 
     //std::cout << "Similarity Measure: " << s  << std::endl;
-    
+
     //<< " press ENTER to continue" << std::endl;
     //cv::waitKey(0);
   }
@@ -295,45 +296,45 @@ float PerformanceUtils::SimilarityMeasure(IplImage *image, IplImage *ground_trut
   return s;
 }
 
-void PerformanceUtils::ImageROC(IplImage *image, IplImage* ground_truth, bool saveResults, char* filename)
+void PerformanceUtils::ImageROC(IplImage *image, IplImage* ground_truth, bool saveResults, std::string filename)
 {
-  unsigned char *pixelGT = (unsigned char*) malloc(1*sizeof(unsigned char));
-  unsigned char *pixelI = (unsigned char*) malloc(1*sizeof(unsigned char));
+  unsigned char *pixelGT = (unsigned char*)malloc(1 * sizeof(unsigned char));
+  unsigned char *pixelI = (unsigned char*)malloc(1 * sizeof(unsigned char));
 
-  IplImage *ROCimage = cvCreateImage(cvSize(image->width,image->height),image->depth,image->nChannels);
-  cvFillImage(ROCimage, 0.0);
+  IplImage *ROCimage = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels);
+  cvSetZero(ROCimage);
 
   PixelUtils p;
 
-  for(int y = 0; y < image->height; y++) 
+  for (int y = 0; y < image->height; y++)
   {
-    for(int x = 0; x < image->width; x++) 
+    for (int x = 0; x < image->width; x++)
     {
-      p.GetGrayPixel(ground_truth,x,y,pixelGT);                
-      p.GetGrayPixel(image,x,y,pixelI);
+      p.GetGrayPixel(ground_truth, x, y, pixelGT);
+      p.GetGrayPixel(image, x, y, pixelI);
 
-      if((pixelGT[0] != 0) && (pixelI[0] != 0)) // TP
+      if ((pixelGT[0] != 0) && (pixelI[0] != 0)) // TP
       {
         *pixelI = 30;
-        p.PutGrayPixel(ROCimage,x,y,*pixelI);
+        p.PutGrayPixel(ROCimage, x, y, *pixelI);
       }
 
-      if((pixelGT[0] == 0) && (pixelI[0] == 0.0)) // TN
+      if ((pixelGT[0] == 0) && (pixelI[0] == 0.0)) // TN
       {
         *pixelI = 0;
-        p.PutGrayPixel(ROCimage,x,y,*pixelI);
-      }	
+        p.PutGrayPixel(ROCimage, x, y, *pixelI);
+      }
 
-      if((pixelGT[0] == 0) && (pixelI[0] != 0)) // FP
+      if ((pixelGT[0] == 0) && (pixelI[0] != 0)) // FP
       {
         *pixelI = 255;
-        p.PutGrayPixel(ROCimage,x,y,*pixelI);
+        p.PutGrayPixel(ROCimage, x, y, *pixelI);
       }
 
-      if((pixelGT[0] != 0) && (pixelI[0] == 0)) // FN
+      if ((pixelGT[0] != 0) && (pixelI[0] == 0)) // FN
       {
         *pixelI = 100;
-        p.PutGrayPixel(ROCimage,x,y,*pixelI);
+        p.PutGrayPixel(ROCimage, x, y, *pixelI);
       }
     }
   }
@@ -341,10 +342,10 @@ void PerformanceUtils::ImageROC(IplImage *image, IplImage* ground_truth, bool sa
   cvNamedWindow("ROC image", 0);
   cvShowImage("ROC image", ROCimage);
 
-  if(saveResults)
+  if (saveResults)
   {
-    unsigned char *pixelOI = (unsigned char*) malloc(1*sizeof(unsigned char));
-    unsigned char *pixelROC = (unsigned char*) malloc(1*sizeof(unsigned char));
+    unsigned char *pixelOI = (unsigned char*)malloc(1 * sizeof(unsigned char));
+    unsigned char *pixelROC = (unsigned char*)malloc(1 * sizeof(unsigned char));
 
     float** freq;
     float nTP = 0.0;
@@ -352,45 +353,45 @@ void PerformanceUtils::ImageROC(IplImage *image, IplImage* ground_truth, bool sa
     float nFP = 0.0;
     float nFN = 0.0;
 
-    freq = (float**) malloc(256*(sizeof(float*)));
-    for(int i = 0; i < 256; i++)
-      freq[i] = (float*) malloc(7 * (sizeof(float)));
+    freq = (float**)malloc(256 * (sizeof(float*)));
+    for (int i = 0; i < 256; i++)
+      freq[i] = (float*)malloc(7 * (sizeof(float)));
 
-    for(int i = 0; i < 256; i++)
-      for(int j = 0; j < 6; j++) 
+    for (int i = 0; i < 256; i++)
+      for (int j = 0; j < 6; j++)
         freq[i][j] = 0.0;
 
-    for(int y = 0; y < image->height; y++)
+    for (int y = 0; y < image->height; y++)
     {
-      for(int x = 0; x < image->width; x++) 
+      for (int x = 0; x < image->width; x++)
       {
-        for(int i = 0; i < 256; i++)
+        for (int i = 0; i < 256; i++)
         {
-          p.GetGrayPixel(image,x,y,pixelOI);                
-          p.GetGrayPixel(ROCimage,x,y,pixelROC);
+          p.GetGrayPixel(image, x, y, pixelOI);
+          p.GetGrayPixel(ROCimage, x, y, pixelROC);
 
-          if((pixelOI[0] == i) && (pixelROC[0] == 30.0)) // TP
+          if ((pixelOI[0] == i) && (pixelROC[0] == 30.0)) // TP
           {
             nTP++;
             freq[i][0] = nTP;
             break;
           }
 
-          if((pixelOI[0] == i) && (pixelROC[0] == 0.0)) // TN
+          if ((pixelOI[0] == i) && (pixelROC[0] == 0.0)) // TN
           {
             nTN++;
             freq[i][1] = nTN;
             break;
           }
 
-          if((pixelOI[0] == i) && (pixelROC[0] == 255.0)) // FP
+          if ((pixelOI[0] == i) && (pixelROC[0] == 255.0)) // FP
           {
             nFP++;
             freq[i][2] = nFP;
             break;
           }
 
-          if((pixelOI[0] == i) && (pixelROC[0] == 100)) // FN
+          if ((pixelOI[0] == i) && (pixelROC[0] == 100)) // FN
           {
             nFN++;
             freq[i][3] = nFN;
@@ -409,17 +410,17 @@ void PerformanceUtils::ImageROC(IplImage *image, IplImage* ground_truth, bool sa
 
     std::ofstream f(filename);
 
-    if(!f.is_open())
+    if (!f.is_open())
       std::cout << "Failed to open file " << filename << " for writing!" << std::endl;
     else
     {
       f << "  I     TP     TN     FP     FN    FPR      FNR      DR   \n" << std::endl;
-      
-      for(int i = 0; i < 256; i++)
+
+      for (int i = 0; i < 256; i++)
       {
         //printf("%4d - TP:%5.0f, TN:%5.0f, FP:%5.0f, FN:%5.0f,", i, freq[i][0], freq[i][1], freq[i][2], freq[i][3]);
 
-        if((freq[i][3] + freq[i][0] != 0.0) && (freq[i][2] + freq[i][1] != 0.0))
+        if ((freq[i][3] + freq[i][0] != 0.0) && (freq[i][2] + freq[i][1] != 0.0))
         {
           freq[i][4] = freq[i][3] / (freq[i][3] + freq[i][0]);  // FNR = FN / (TP + FN);
           freq[i][5] = freq[i][2] / (freq[i][2] + freq[i][1]);	// FPR = FP / (FP + TN);
@@ -429,12 +430,12 @@ void PerformanceUtils::ImageROC(IplImage *image, IplImage* ground_truth, bool sa
           ////fprintf(f," %4d     %1.6f     %1.6f\n",i,freq[i][5],freq[i][4]);
           ////fprintf(f,"  %1.6f     %1.6f\n",freq[i][5],freq[i][4]);
           char line[255];
-          sprintf(line,"%3d %6.0f %6.0f %6.0f %6.0f %1.6f %1.6f %1.6f\n", 
+          sprintf(line, "%3d %6.0f %6.0f %6.0f %6.0f %1.6f %1.6f %1.6f\n",
             i, freq[i][0], freq[i][1], freq[i][2], freq[i][3], freq[i][5], freq[i][4], freq[i][6]);
           f << line;
         }
         //else
-          //printf("\n");
+        //printf("\n");
       }
 
       std::cout << "Results saved in " << filename << std::endl;
@@ -454,36 +455,36 @@ void PerformanceUtils::ImageROC(IplImage *image, IplImage* ground_truth, bool sa
   free(pixelI);
 }
 
-void PerformanceUtils::PerformanceEvaluation(IplImage *image, IplImage *ground_truth, bool saveResults, char* filename, bool debug)
+void PerformanceUtils::PerformanceEvaluation(IplImage *image, IplImage *ground_truth, bool saveResults, std::string filename, bool debug)
 {
   float N = 0;
   N = NrPixels(image);
 
   float U = 0;
   U = NrAllDetectedPixNotNULL(image, ground_truth);
-  
+
   float TP = 0;
   TP = NrTruePositives(image, ground_truth, debug);
-  
+
   float TN = 0;
   TN = NrTrueNegatives(image, ground_truth, debug);
-  
+
   float FP = 0;
   FP = NrFalsePositives(image, ground_truth, debug);
-  
+
   float FN = 0;
   FN = NrFalseNegatives(image, ground_truth, debug);
-  
+
   float DetectionRate = TP / (TP + FN);
   float Precision = TP / (TP + FP);
   float Fmeasure = (2 * DetectionRate * Precision) / (DetectionRate + Precision);
 
   float Accuracy = (TN + TP) / N;
   float FalseNegativeRate = FN / (TP + FN);
-  
+
   float FalsePositiveRate = FP / (FP + TN);
   float TruePositiveRate = TP / (TP + FN);
-  
+
   float SM = 0;
   SM = SimilarityMeasure(image, ground_truth, debug);
 
@@ -506,11 +507,11 @@ void PerformanceUtils::PerformanceEvaluation(IplImage *image, IplImage *ground_t
   std::string results = sstm.str();
   std::cout << results;
 
-  if(saveResults)
+  if (saveResults)
   {
     std::ofstream f(filename);
 
-    if(!f.is_open())
+    if (!f.is_open())
       std::cout << "Failed to open file " << filename << " for writing!" << std::endl;
     else
     {
diff --git a/package_bgs/tb/PerformanceUtils.h b/package_analysis/PerformanceUtils.h
similarity index 82%
rename from package_bgs/tb/PerformanceUtils.h
rename to package_analysis/PerformanceUtils.h
index 9257098386e13a2d2a1cb61382affa074ab981a6..4be392f53a1b40fc1096d448809ff7a7919097a8 100644
--- a/package_bgs/tb/PerformanceUtils.h
+++ b/package_analysis/PerformanceUtils.h
@@ -15,23 +15,11 @@ 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
-/*
-Code provided by Thierry BOUWMANS
-
-Maitre de Conf�rences
-Laboratoire MIA
-Universit� de La Rochelle
-17000 La Rochelle
-France
-tbouwman@univ-lr.fr
 
-http://sites.google.com/site/thierrybouwmans/
-*/
 #include <stdio.h>
 #include <fstream>
 #include <opencv2/opencv.hpp>
 
-
 #include "PixelUtils.h"
 
 class PerformanceUtils
@@ -48,7 +36,7 @@ public:
   float NrFalseNegatives(IplImage *image, IplImage *ground_truth, bool debug = false);
   float SimilarityMeasure(IplImage *image, IplImage *ground_truth, bool debug = false);
 
-  void ImageROC(IplImage *image, IplImage* ground_truth, bool saveResults = false, char* filename = "");
-  void PerformanceEvaluation(IplImage *image, IplImage *ground_truth, bool saveResults = false, char* filename = "", bool debug = false);
+  void ImageROC(IplImage *image, IplImage* ground_truth, bool saveResults = false, std::string filename = "");
+  void PerformanceEvaluation(IplImage *image, IplImage *ground_truth, bool saveResults = false, std::string filename = "", bool debug = false);
 };
 
diff --git a/package_analysis/PixelUtils.cpp b/package_analysis/PixelUtils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..adce122f642ec9260254921999f6954bce28dc03
--- /dev/null
+++ b/package_analysis/PixelUtils.cpp
@@ -0,0 +1,351 @@
+/*
+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 "PixelUtils.h"
+
+PixelUtils::PixelUtils(void) {}
+PixelUtils::~PixelUtils(void) {}
+
+void PixelUtils::ColorConversion(IplImage* RGBImage, IplImage* ConvertedImage, int color_space)
+{
+  // Space Color RGB - Nothing to do!
+  if (color_space == 1)
+    cvCopy(RGBImage, ConvertedImage);
+
+  // Space Color Ohta
+  if (color_space == 2)
+    cvttoOTHA(RGBImage, ConvertedImage);
+
+  // Space Color HSV - V Intensity - (H,S) Chromaticity
+  if (color_space == 3)
+    cvCvtColor(RGBImage, ConvertedImage, CV_BGR2HSV);
+
+  // Space Color YCrCb - Y Intensity - (Cr,Cb) Chromaticity
+  if (color_space == 4)
+    cvCvtColor(RGBImage, ConvertedImage, CV_BGR2YCrCb);
+}
+
+void PixelUtils::cvttoOTHA(IplImage* RGBImage, IplImage* OthaImage)
+{
+  float* OhtaPixel = (float*)malloc(3 * (sizeof(float)));
+  float* RGBPixel = (float*)malloc(3 * (sizeof(float)));
+
+  for (int i = 0; i < RGBImage->width; i++)
+  {
+    for (int j = 0; j < RGBImage->height; j++)
+    {
+      GetPixel(RGBImage, i, j, RGBPixel);
+
+      // I1 = (R + G + B) / 3
+      *OhtaPixel = (*(RGBPixel)+(*(RGBPixel + 1)) + (*(RGBPixel + 2))) / 3.0;
+
+      // I2 = (R - B) / 2
+      *(OhtaPixel + 1) = (*RGBPixel - (*(RGBPixel + 2))) / 2.0;
+
+      // I3 = (2G - R - B) / 4
+      *(OhtaPixel + 2) = (2 * (*(RGBPixel + 1)) - (*RGBPixel) - (*(RGBPixel + 2))) / 4.0;
+
+      PutPixel(OthaImage, i, j, OhtaPixel);
+    }
+  }
+
+  free(OhtaPixel);
+  free(RGBPixel);
+}
+
+void PixelUtils::PostProcessing(IplImage *InputImage)
+{
+  IplImage *ResultImage = cvCreateImage(cvSize(InputImage->width, InputImage->height), IPL_DEPTH_32F, 3);
+
+  cvErode(InputImage, ResultImage, NULL, 1);
+  cvDilate(ResultImage, InputImage, NULL, 0);
+
+  cvReleaseImage(&ResultImage);
+}
+
+void PixelUtils::GetPixel(IplImage *image, int m, int n, unsigned char *pixelcourant)
+{
+  for (int k = 0; k < 3; k++)
+    pixelcourant[k] = ((unsigned char*)(image->imageData + image->widthStep*n))[m * 3 + k];
+}
+
+void PixelUtils::GetGrayPixel(IplImage *image, int m, int n, unsigned char *pixelcourant)
+{
+  *pixelcourant = ((unsigned char*)(image->imageData + image->widthStep*n))[m];
+}
+
+void PixelUtils::PutPixel(IplImage *image, int p, int q, unsigned char *pixelcourant)
+{
+  for (int r = 0; r < 3; r++)
+    ((unsigned char*)(image->imageData + image->widthStep*q))[p * 3 + r] = pixelcourant[r];
+}
+
+void PixelUtils::PutGrayPixel(IplImage *image, int p, int q, unsigned char pixelcourant)
+{
+  ((unsigned char*)(image->imageData + image->widthStep*q))[p] = pixelcourant;
+}
+
+void PixelUtils::GetPixel(IplImage *image, int m, int n, float *pixelcourant)
+{
+  for (int k = 0; k < 3; k++)
+    pixelcourant[k] = ((float*)(image->imageData + image->widthStep*n))[m * 3 + k];
+}
+
+void PixelUtils::GetGrayPixel(IplImage *image, int m, int n, float *pixelcourant)
+{
+  *pixelcourant = ((float*)(image->imageData + image->widthStep*n))[m];
+}
+
+void PixelUtils::PutPixel(IplImage *image, int p, int q, float *pixelcourant)
+{
+  for (int r = 0; r < 3; r++)
+    ((float*)(image->imageData + image->widthStep*q))[p * 3 + r] = pixelcourant[r];
+}
+
+void PixelUtils::PutGrayPixel(IplImage *image, int p, int q, float pixelcourant)
+{
+  ((float*)(image->imageData + image->widthStep*q))[p] = pixelcourant;
+}
+
+void PixelUtils::getNeighberhoodGrayPixel(IplImage* InputImage, int x, int y, float* neighberPixel)
+{
+  int i, j, k;
+
+  float* pixelCourant = (float*)malloc(1 * (sizeof(float)));
+
+  //le calcul de voisinage pour les 4 coins;
+  /* 1.*/
+  if (x == 0 && y == 0)
+  {
+    k = 0;
+    for (i = x; i < x + 2; i++)
+      for (j = y; j < y + 2; j++)
+      {
+        GetGrayPixel(InputImage, i, j, pixelCourant);
+        *(neighberPixel + k) = *pixelCourant;
+        k++;
+      }
+  }
+
+  /* 2.*/
+  if (x == 0 && y == InputImage->width)
+  {
+    k = 0;
+    for (i = x; i < x + 2; i++)
+      for (j = y - 1; j < y + 1; j++)
+      {
+        GetGrayPixel(InputImage, i, j, pixelCourant);
+        *(neighberPixel + k) = *pixelCourant;
+        k++;
+      }
+  }
+
+  /* 3.*/
+  if (x == InputImage->height && y == 0)
+  {
+    k = 0;
+    for (i = x - 1; i < x + 1; i++)
+      for (j = y; j < y + 2; j++)
+      {
+        GetGrayPixel(InputImage, i, j, pixelCourant);
+        *(neighberPixel + k) = *pixelCourant;
+        k++;
+      }
+  }
+
+  /* 4.*/
+  if (x == InputImage->height && y == InputImage->width)
+  {
+    k = 0;
+    for (i = x - 1; i < x + 1; i++)
+      for (j = y - 1; j < y + 1; j++)
+      {
+        GetGrayPixel(InputImage, i, j, pixelCourant);
+        *(neighberPixel + k) = *pixelCourant;
+        k++;
+      }
+  }
+
+  // Voisinage de la premiere ligne : L(0)
+  if (x == 0 && (y != 0 && y != InputImage->width))
+  {
+    k = 0;
+    for (i = x + 1; i >= x; i--)
+      for (j = y - 1; j < y + 2; j++)
+      {
+        GetGrayPixel(InputImage, i, j, pixelCourant);
+        *(neighberPixel + k) = *pixelCourant;
+        k++;
+      }
+  }
+
+  // Voisinage de la dernière colonne : C(w)
+  if ((x != 0 && x != InputImage->height) && y == InputImage->width)
+  {
+    k = 0;
+    for (i = x + 1; i > x - 2; i--)
+      for (j = y - 1; j < y + 1; j++)
+      {
+        GetGrayPixel(InputImage, i, j, pixelCourant);
+        *(neighberPixel + k) = *pixelCourant;
+        k++;
+      }
+  }
+
+  // Voisinage de la dernière ligne : L(h)
+  if (x == InputImage->height && (y != 0 && y != InputImage->width))
+  {
+    k = 0;
+    for (i = x; i > x - 2; i--)
+      for (j = y - 1; j < y + 2; j++)
+      {
+        GetGrayPixel(InputImage, i, j, pixelCourant);
+        *(neighberPixel + k) = *pixelCourant;
+        k++;
+      }
+  }
+
+  // Voisinage de la premiere colonne : C(0)
+  if ((x != 0 && x != InputImage->height) && y == 0)
+  {
+    k = 0;
+    for (i = x - 1; i < x + 2; i++)
+      for (j = y; j < y + 2; j++)
+      {
+        GetGrayPixel(InputImage, i, j, pixelCourant);
+        *(neighberPixel + k) = *pixelCourant;
+        k++;
+      }
+  }
+
+  //le calcul du voisinage pour le reste des elementes d'image
+  if ((x != 0 && x != InputImage->height) && (y != 0 && y != InputImage->width))
+  {
+    k = 0;
+    for (i = x + 1; i > x - 2; i--)
+      for (j = y - 1; j < y + 2; j++)
+      {
+        GetGrayPixel(InputImage, i, j, pixelCourant);
+        *(neighberPixel + k) = *pixelCourant;
+        k++;
+      }
+  }
+
+  free(pixelCourant);
+}
+
+void PixelUtils::ForegroundMinimum(IplImage *Foreground, float *Minimum, int n)
+{
+  int i, j, k;
+  float *pixelcourant;
+
+  pixelcourant = (float *)malloc(n * sizeof(float));
+
+  for (k = 0; k < n; k++)
+    *(Minimum + k) = 255;
+
+  for (i = 0; i < Foreground->width; i++)
+    for (j = 0; j < Foreground->height; j++)
+    {
+      if (n == 3)
+      {
+        GetPixel(Foreground, i, j, pixelcourant);
+
+        for (k = 0; k < n; k++)
+          if (*(pixelcourant + k) < *(Minimum + k))
+            *(Minimum + k) = *(pixelcourant + k);
+      }
+
+      if (n == 1)
+      {
+        GetGrayPixel(Foreground, i, j, pixelcourant);
+
+        if (*pixelcourant < *Minimum)
+          *Minimum = *pixelcourant;
+      }
+    }
+
+  free(pixelcourant);
+}
+
+void PixelUtils::ForegroundMaximum(IplImage *Foreground, float *Maximum, int n)
+{
+  int i, j, k;
+  float *pixelcourant;
+
+  pixelcourant = (float *)malloc(n * sizeof(float));
+
+  for (k = 0; k < n; k++)
+    *(Maximum + k) = 0;
+
+  for (i = 0; i < Foreground->width; i++)
+    for (j = 0; j < Foreground->height; j++)
+    {
+      if (n == 3)
+      {
+        GetPixel(Foreground, i, j, pixelcourant);
+
+        for (k = 0; k < n; k++)
+          if (*(pixelcourant + k) > *(Maximum + k))
+            *(Maximum + k) = *(pixelcourant + k);
+      }
+
+      if (n == 1)
+      {
+        GetGrayPixel(Foreground, i, j, pixelcourant);
+
+        if (*pixelcourant > *Maximum)
+          *Maximum = *pixelcourant;
+      }
+    }
+
+  free(pixelcourant);
+}
+
+void PixelUtils::ComplementaryAlphaImageCreation(IplImage *AlphaImage, IplImage *ComplementaryAlphaImage, int n)
+{
+  int i, j, k;
+  float *pixelcourant, *pixelcourant1;
+
+  pixelcourant = (float *)malloc(n * sizeof(float));
+  pixelcourant1 = (float *)malloc(n * sizeof(float));
+
+  for (i = 0; i < AlphaImage->width; i++)
+    for (j = 0; j < AlphaImage->height; j++)
+    {
+      if (n == 1)
+      {
+        GetGrayPixel(AlphaImage, i, j, pixelcourant);
+        *pixelcourant1 = 1 - *(pixelcourant);
+        PutGrayPixel(ComplementaryAlphaImage, i, j, *pixelcourant1);
+      }
+
+      if (n == 3)
+      {
+        GetPixel(AlphaImage, i, j, pixelcourant);
+        for (k = 0; k < 3; k++)
+        {
+          *pixelcourant1 = 1.0 - *(pixelcourant);
+          *(pixelcourant1 + 1) = 1.0 - *(pixelcourant + 1);
+          *(pixelcourant1 + 2) = 1.0 - *(pixelcourant + 2);
+        }
+        PutPixel(ComplementaryAlphaImage, i, j, pixelcourant1);
+      }
+    }
+
+  free(pixelcourant);
+  free(pixelcourant1);
+}
diff --git a/package_bgs/tb/PixelUtils.h b/package_analysis/PixelUtils.h
similarity index 90%
rename from package_bgs/tb/PixelUtils.h
rename to package_analysis/PixelUtils.h
index a2d3a4af3d5838fc0e1b870507ecacbcacf9d955..0e35c4055421c76d5bdb0af91fee4c6008b98253 100644
--- a/package_bgs/tb/PixelUtils.h
+++ b/package_analysis/PixelUtils.h
@@ -15,22 +15,10 @@ 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
-/*
-Code provided by Thierry BOUWMANS
-
-Maitre de Conf�rences
-Laboratoire MIA
-Universit� de La Rochelle
-17000 La Rochelle
-France
-tbouwman@univ-lr.fr
 
-http://sites.google.com/site/thierrybouwmans/
-*/
 #include <stdio.h>
 #include <opencv2/opencv.hpp>
 
-
 class PixelUtils
 {
 public:
@@ -39,9 +27,9 @@ public:
 
   void ColorConversion(IplImage* RGBImage, IplImage* ConvertedImage, int color_space);
   void cvttoOTHA(IplImage* RGBImage, IplImage* OthaImage);
-  
+
   void PostProcessing(IplImage *InputImage);
-  
+
   void GetPixel(IplImage *image, int m, int n, unsigned char *pixelcourant);
   void GetGrayPixel(IplImage *image, int m, int n, unsigned char *pixelcourant);
 
@@ -58,4 +46,4 @@ public:
   void ForegroundMaximum(IplImage *Foreground, float *Maximum, int n);
   void ForegroundMinimum(IplImage *Foreground, float *Minimum, int n);
   void ComplementaryAlphaImageCreation(IplImage *AlphaImage, IplImage *ComplementaryAlphaImage, int n);
-};
\ No newline at end of file
+};
diff --git a/package_bgs/AdaptiveBackgroundLearning.cpp b/package_bgs/AdaptiveBackgroundLearning.cpp
index b111e65be5ca7b12274af2f91dcd1672f1bd3e36..d2cb8a0ac5fee164454b10b18d2886706987c90c 100644
--- a/package_bgs/AdaptiveBackgroundLearning.cpp
+++ b/package_bgs/AdaptiveBackgroundLearning.cpp
@@ -16,10 +16,14 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "AdaptiveBackgroundLearning.h"
 
-AdaptiveBackgroundLearning::AdaptiveBackgroundLearning() : firstTime(true), alpha(0.05), limit(-1), counter(0), minVal(0.0), maxVal(1.0), 
-  enableThreshold(true), threshold(15), showForeground(true), showBackground(true)
+using namespace bgslibrary::algorithms;
+
+AdaptiveBackgroundLearning::AdaptiveBackgroundLearning() :
+  alpha(0.05), limit(-1), counter(0), minVal(0.0), maxVal(1.0),
+  enableThreshold(true), threshold(15)
 {
   std::cout << "AdaptiveBackgroundLearning()" << std::endl;
+  setup("./config/AdaptiveBackgroundLearning.xml");
 }
 
 AdaptiveBackgroundLearning::~AdaptiveBackgroundLearning()
@@ -29,52 +33,48 @@ AdaptiveBackgroundLearning::~AdaptiveBackgroundLearning()
 
 void AdaptiveBackgroundLearning::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if(firstTime)
-    saveConfig();
+  init(img_input, img_output, img_bgmodel);
 
-  if(img_background.empty())
+  if (img_background.empty())
     img_input.copyTo(img_background);
 
   cv::Mat img_input_f(img_input.size(), CV_32F);
-  img_input.convertTo(img_input_f, CV_32F, 1./255.);
+  img_input.convertTo(img_input_f, CV_32F, 1. / 255.);
 
   cv::Mat img_background_f(img_background.size(), CV_32F);
-  img_background.convertTo(img_background_f, CV_32F, 1./255.);
+  img_background.convertTo(img_background_f, CV_32F, 1. / 255.);
 
   cv::Mat img_diff_f(img_input.size(), CV_32F);
   cv::absdiff(img_input_f, img_background_f, img_diff_f);
 
-  if((limit > 0 && limit < counter) || limit == -1)
+  if ((limit > 0 && limit < counter) || limit == -1)
   {
-    img_background_f = alpha*img_input_f + (1-alpha)*img_background_f;
-    
+    img_background_f = alpha*img_input_f + (1 - alpha)*img_background_f;
+
     cv::Mat img_new_background(img_input.size(), CV_8U);
-    img_background_f.convertTo(img_new_background, CV_8U, 255.0/(maxVal - minVal), -minVal);
+    img_background_f.convertTo(img_new_background, CV_8U, 255.0 / (maxVal - minVal), -minVal);
     img_new_background.copyTo(img_background);
 
-    if(limit > 0 && limit < counter)
+    if (limit > 0 && limit < counter)
       counter++;
   }
-  
-  cv::Mat img_foreground(img_input.size(), CV_8U);
-  img_diff_f.convertTo(img_foreground, CV_8U, 255.0/(maxVal - minVal), -minVal);
 
-  if(img_foreground.channels() == 3)
+  //cv::Mat img_foreground(img_input.size(), CV_8U);
+  img_diff_f.convertTo(img_foreground, CV_8UC1, 255.0 / (maxVal - minVal), -minVal);
+
+  if (img_foreground.channels() == 3)
     cv::cvtColor(img_foreground, img_foreground, CV_BGR2GRAY);
 
-  if(enableThreshold)
+  if (enableThreshold)
     cv::threshold(img_foreground, img_foreground, threshold, 255, cv::THRESH_BINARY);
-  
-  if(showForeground)
-    cv::imshow("A-Learning FG", img_foreground);
 
-  if(showBackground)
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+  {
+    cv::imshow("A-Learning FG", img_foreground);
     cv::imshow("A-Learning BG", img_background);
+  }
+#endif
 
   img_foreground.copyTo(img_output);
   img_background.copyTo(img_bgmodel);
@@ -84,28 +84,26 @@ void AdaptiveBackgroundLearning::process(const cv::Mat &img_input, cv::Mat &img_
 
 void AdaptiveBackgroundLearning::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/AdaptiveBackgroundLearning.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), 0, CV_STORAGE_WRITE);
 
   cvWriteReal(fs, "alpha", alpha);
   cvWriteInt(fs, "limit", limit);
   cvWriteInt(fs, "enableThreshold", enableThreshold);
   cvWriteInt(fs, "threshold", threshold);
-  cvWriteInt(fs, "showForeground", showForeground);
-  cvWriteInt(fs, "showBackground", showBackground);
+  cvWriteInt(fs, "showOutput", showOutput);
 
   cvReleaseFileStorage(&fs);
 }
 
 void AdaptiveBackgroundLearning::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/AdaptiveBackgroundLearning.xml", 0, CV_STORAGE_READ);
-  
-  alpha = cvReadRealByName(fs, 0, "alpha", 0.05);
-  limit = cvReadIntByName(fs, 0, "limit", -1);
-  enableThreshold = cvReadIntByName(fs, 0, "enableThreshold", true);
-  threshold = cvReadIntByName(fs, 0, "threshold", 15);
-  showForeground = cvReadIntByName(fs, 0, "showForeground", true);
-  showBackground = cvReadIntByName(fs, 0, "showBackground", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  alpha = cvReadRealByName(fs, nullptr, "alpha", 0.05);
+  limit = cvReadIntByName(fs, nullptr, "limit", -1);
+  enableThreshold = cvReadIntByName(fs, nullptr, "enableThreshold", true);
+  threshold = cvReadIntByName(fs, nullptr, "threshold", 15);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/AdaptiveBackgroundLearning.h b/package_bgs/AdaptiveBackgroundLearning.h
index 4bbac54ae0f4c3e42499a9878afd764e9c34ab48..3cfc686296ecdda4f582cbf5e1795032273d23fc 100644
--- a/package_bgs/AdaptiveBackgroundLearning.h
+++ b/package_bgs/AdaptiveBackgroundLearning.h
@@ -16,35 +16,32 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
 #include "IBGS.h"
 
-class AdaptiveBackgroundLearning : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  cv::Mat img_background;
-  double alpha;
-  long limit;
-  long counter;
-  double minVal;
-  double maxVal;
-  bool enableThreshold;
-  int threshold;
-  bool showForeground;
-  bool showBackground;
-
-public:
-  AdaptiveBackgroundLearning();
-  ~AdaptiveBackgroundLearning();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
-
+  namespace algorithms
+  {
+    class AdaptiveBackgroundLearning : public IBGS
+    {
+    private:
+      double alpha;
+      long limit;
+      long counter;
+      double minVal;
+      double maxVal;
+      bool enableThreshold;
+      int threshold;
+
+    public:
+      AdaptiveBackgroundLearning();
+      ~AdaptiveBackgroundLearning();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/AdaptiveSelectiveBackgroundLearning.cpp b/package_bgs/AdaptiveSelectiveBackgroundLearning.cpp
index cd3e7d3d966ec6b2e2850d21305f15e1341889df..2f6f9fe89ba9adf4b595c05cc05a3b5fb3c51985 100644
--- a/package_bgs/AdaptiveSelectiveBackgroundLearning.cpp
+++ b/package_bgs/AdaptiveSelectiveBackgroundLearning.cpp
@@ -16,11 +16,14 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "AdaptiveSelectiveBackgroundLearning.h"
 
-AdaptiveSelectiveBackgroundLearning::AdaptiveSelectiveBackgroundLearning() : firstTime(true), 
-alphaLearn(0.05), alphaDetection(0.05), learningFrames(-1), counter(0), minVal(0.0), maxVal(1.0),
-threshold(15), showOutput(true)
+using namespace bgslibrary::algorithms;
+
+AdaptiveSelectiveBackgroundLearning::AdaptiveSelectiveBackgroundLearning() :
+  alphaLearn(0.05), alphaDetection(0.05), learningFrames(-1), counter(0), minVal(0.0), maxVal(1.0),
+  threshold(15)
 {
   std::cout << "AdaptiveSelectiveBackgroundLearning()" << std::endl;
+  setup("./config/AdaptiveSelectiveBackgroundLearning.xml");
 }
 
 AdaptiveSelectiveBackgroundLearning::~AdaptiveSelectiveBackgroundLearning()
@@ -30,8 +33,7 @@ AdaptiveSelectiveBackgroundLearning::~AdaptiveSelectiveBackgroundLearning()
 
 void AdaptiveSelectiveBackgroundLearning::process(const cv::Mat &img_input_, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input_.empty())
-    return;
+  init(img_input_, img_output, img_bgmodel);
 
   cv::Mat img_input;
   if (img_input_.channels() == 3)
@@ -39,24 +41,19 @@ void AdaptiveSelectiveBackgroundLearning::process(const cv::Mat &img_input_, cv:
   else
     img_input_.copyTo(img_input);
 
-  loadConfig();
-
-  if(firstTime)
-    saveConfig();
-
-  if(img_background.empty())
+  if (img_background.empty())
     img_input.copyTo(img_background);
 
   cv::Mat img_input_f(img_input.size(), CV_32F);
-  img_input.convertTo(img_input_f, CV_32F, 1./255.);
+  img_input.convertTo(img_input_f, CV_32F, 1. / 255.);
 
   cv::Mat img_background_f(img_background.size(), CV_32F);
-  img_background.convertTo(img_background_f, CV_32F, 1./255.);
+  img_background.convertTo(img_background_f, CV_32F, 1. / 255.);
 
   cv::Mat img_diff_f(img_input.size(), CV_32F);
   cv::absdiff(img_input_f, img_background_f, img_diff_f);
 
-  cv::Mat img_foreground(img_input.size(), CV_8U);
+  //cv::Mat img_foreground(img_input.size(), CV_8U);
   img_diff_f.convertTo(img_foreground, CV_8U, 255.0 / (maxVal - minVal), -minVal);
 
   cv::threshold(img_foreground, img_foreground, threshold, 255, cv::THRESH_BINARY);
@@ -88,15 +85,17 @@ void AdaptiveSelectiveBackgroundLearning::process(const cv::Mat &img_input_, cv:
     }
   }
 
-  cv::Mat img_new_background(img_input.size(), CV_8U);
-  img_background_f.convertTo(img_new_background, CV_8U, 255.0 / (maxVal - minVal), -minVal);
-  img_new_background.copyTo(img_background);
-  
-  if(showOutput)
+  //cv::Mat img_new_background(img_input.size(), CV_8U);
+  img_background_f.convertTo(img_background, CV_8UC1, 255.0 / (maxVal - minVal), -minVal);
+  //img_new_background.copyTo(img_background);
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
   {
     cv::imshow("AS-Learning FG", img_foreground);
     cv::imshow("AS-Learning BG", img_background);
   }
+#endif
 
   img_foreground.copyTo(img_output);
   img_background.copyTo(img_bgmodel);
@@ -106,7 +105,7 @@ void AdaptiveSelectiveBackgroundLearning::process(const cv::Mat &img_input_, cv:
 
 void AdaptiveSelectiveBackgroundLearning::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/AdaptiveSelectiveBackgroundLearning.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteInt(fs, "learningFrames", learningFrames);
   cvWriteReal(fs, "alphaLearn", alphaLearn);
@@ -119,13 +118,13 @@ void AdaptiveSelectiveBackgroundLearning::saveConfig()
 
 void AdaptiveSelectiveBackgroundLearning::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/AdaptiveSelectiveBackgroundLearning.xml", 0, CV_STORAGE_READ);
-  
-  learningFrames = cvReadIntByName(fs, 0, "learningFrames", 90);
-  alphaLearn = cvReadRealByName(fs, 0, "alphaLearn", 0.05);
-  alphaDetection = cvReadRealByName(fs, 0, "alphaDetection", 0.05);
-  threshold = cvReadIntByName(fs, 0, "threshold", 25);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), 0, CV_STORAGE_READ);
+
+  learningFrames = cvReadIntByName(fs, nullptr, "learningFrames", 90);
+  alphaLearn = cvReadRealByName(fs, nullptr, "alphaLearn", 0.05);
+  alphaDetection = cvReadRealByName(fs, nullptr, "alphaDetection", 0.05);
+  threshold = cvReadIntByName(fs, nullptr, "threshold", 25);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/AdaptiveSelectiveBackgroundLearning.h b/package_bgs/AdaptiveSelectiveBackgroundLearning.h
index 227674751ae4eccf452094f680c43adf72dca961..24da44c7e025c848d5761f84eb9a95c6c96e23f5 100644
--- a/package_bgs/AdaptiveSelectiveBackgroundLearning.h
+++ b/package_bgs/AdaptiveSelectiveBackgroundLearning.h
@@ -16,34 +16,32 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
 #include "IBGS.h"
 
-class AdaptiveSelectiveBackgroundLearning : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  cv::Mat img_background;
-  double alphaLearn;
-  double alphaDetection;
-  long learningFrames;
-  long counter;
-  double minVal;
-  double maxVal;
-  int threshold;
-  bool showOutput;
-
-public:
-  AdaptiveSelectiveBackgroundLearning();
-  ~AdaptiveSelectiveBackgroundLearning();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
-
+  namespace algorithms
+  {
+    class AdaptiveSelectiveBackgroundLearning : public IBGS
+    {
+    private:
+      double alphaLearn;
+      double alphaDetection;
+      long learningFrames;
+      long counter;
+      double minVal;
+      double maxVal;
+      int threshold;
+
+    public:
+      AdaptiveSelectiveBackgroundLearning();
+      ~AdaptiveSelectiveBackgroundLearning();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/DPAdaptiveMedian.cpp b/package_bgs/DPAdaptiveMedian.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0885580a9ce809d5d03eb978236722a4ab451bd5
--- /dev/null
+++ b/package_bgs/DPAdaptiveMedian.cpp
@@ -0,0 +1,110 @@
+/*
+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 "DPAdaptiveMedian.h"
+
+using namespace bgslibrary::algorithms;
+
+DPAdaptiveMedian::DPAdaptiveMedian() :
+  frameNumber(0), threshold(40), samplingRate(7), learningFrames(30)
+{
+  std::cout << "DPAdaptiveMedian()" << std::endl;
+  setup("./config/DPAdaptiveMedian.xml");
+}
+
+DPAdaptiveMedian::~DPAdaptiveMedian()
+{
+  std::cout << "~DPAdaptiveMedian()" << std::endl;
+}
+
+void DPAdaptiveMedian::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+{
+  init(img_input, img_output, img_bgmodel);
+
+  frame = new IplImage(img_input);
+
+  if (firstTime)
+    frame_data.ReleaseMemory(false);
+  frame_data = frame;
+
+  if (firstTime)
+  {
+    int width = img_input.size().width;
+    int height = img_input.size().height;
+
+    lowThresholdMask = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
+    lowThresholdMask.Ptr()->origin = IPL_ORIGIN_BL;
+
+    highThresholdMask = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
+    highThresholdMask.Ptr()->origin = IPL_ORIGIN_BL;
+
+    params.SetFrameSize(width, height);
+    params.LowThreshold() = threshold;
+    params.HighThreshold() = 2 * params.LowThreshold();	// Note: high threshold is used by post-processing
+    params.SamplingRate() = samplingRate;
+    params.LearningFrames() = learningFrames;
+
+    bgs.Initalize(params);
+    bgs.InitModel(frame_data);
+  }
+
+  bgs.Subtract(frameNumber, frame_data, lowThresholdMask, highThresholdMask);
+  lowThresholdMask.Clear();
+  bgs.Update(frameNumber, frame_data, lowThresholdMask);
+
+  img_foreground = cv::cvarrToMat(highThresholdMask.Ptr());
+  //bitwise_not(img_foreground, img_foreground);
+  img_background = cv::cvarrToMat(bgs.Background()->Ptr());
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+  {
+    cv::imshow("Adaptive Median FG (McFarlane&Schofield)", img_foreground);
+    cv::imshow("Adaptive Median BG (McFarlane&Schofield)", img_background);
+  }
+#endif
+
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
+
+  delete frame;
+  firstTime = false;
+  frameNumber++;
+}
+
+void DPAdaptiveMedian::saveConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
+
+  cvWriteInt(fs, "threshold", threshold);
+  cvWriteInt(fs, "samplingRate", samplingRate);
+  cvWriteInt(fs, "learningFrames", learningFrames);
+  cvWriteInt(fs, "showOutput", showOutput);
+
+  cvReleaseFileStorage(&fs);
+}
+
+void DPAdaptiveMedian::loadConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  threshold = cvReadIntByName(fs, nullptr, "threshold", 40);
+  samplingRate = cvReadIntByName(fs, nullptr, "samplingRate", 7);
+  learningFrames = cvReadIntByName(fs, nullptr, "learningFrames", 30);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
+
+  cvReleaseFileStorage(&fs);
+}
diff --git a/package_bgs/DPAdaptiveMedian.h b/package_bgs/DPAdaptiveMedian.h
new file mode 100644
index 0000000000000000000000000000000000000000..7d2b7fa88bb173e2dc08413660c74a507bf7e0bd
--- /dev/null
+++ b/package_bgs/DPAdaptiveMedian.h
@@ -0,0 +1,53 @@
+/*
+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
+
+#include "IBGS.h"
+#include "dp/AdaptiveMedianBGS.h"
+
+using namespace Algorithms::BackgroundSubtraction;
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class DPAdaptiveMedian : public IBGS
+    {
+    private:
+      long frameNumber;
+      IplImage* frame;
+      RgbImage frame_data;
+      AdaptiveMedianParams params;
+      AdaptiveMedianBGS bgs;
+      BwImage lowThresholdMask;
+      BwImage highThresholdMask;
+      int threshold;
+      int samplingRate;
+      int learningFrames;
+
+    public:
+      DPAdaptiveMedian();
+      ~DPAdaptiveMedian();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/dp/DPEigenbackgroundBGS.cpp b/package_bgs/DPEigenbackground.cpp
similarity index 53%
rename from package_bgs/dp/DPEigenbackgroundBGS.cpp
rename to package_bgs/DPEigenbackground.cpp
index 630d9cce521211c62f16408e9f3deb5f964a59c6..75763cec252faa1ef6a28fa202d201ed93213c65 100644
--- a/package_bgs/dp/DPEigenbackgroundBGS.cpp
+++ b/package_bgs/DPEigenbackground.cpp
@@ -14,37 +14,35 @@ 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 "DPEigenbackgroundBGS.h"
+#include "DPEigenbackground.h"
 
-DPEigenbackgroundBGS::DPEigenbackgroundBGS() : firstTime(true), frameNumber(0), threshold(225), historySize(20), embeddedDim(10), showOutput(true) 
+using namespace bgslibrary::algorithms;
+
+DPEigenbackground::DPEigenbackground() :
+  frameNumber(0), threshold(225), historySize(20), embeddedDim(10)
 {
-  std::cout << "DPEigenbackgroundBGS()" << std::endl;
+  std::cout << "DPEigenbackground()" << std::endl;
+  setup("./config/DPEigenbackground.xml");
 }
 
-DPEigenbackgroundBGS::~DPEigenbackgroundBGS()
+DPEigenbackground::~DPEigenbackground()
 {
-  std::cout << "~DPEigenbackgroundBGS()" << std::endl;
+  std::cout << "~DPEigenbackground()" << std::endl;
 }
 
-void DPEigenbackgroundBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+void DPEigenbackground::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if(firstTime)
-    saveConfig();
+  init(img_input, img_output, img_bgmodel);
 
   frame = new IplImage(img_input);
-  
-  if(firstTime)
+
+  if (firstTime)
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if(firstTime)
+  if (firstTime)
   {
-    int width	= img_input.size().width;
+    int width = img_input.size().width;
     int height = img_input.size().height;
 
     lowThresholdMask = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
@@ -55,7 +53,7 @@ void DPEigenbackgroundBGS::process(const cv::Mat &img_input, cv::Mat &img_output
 
     params.SetFrameSize(width, height);
     params.LowThreshold() = threshold; //15*15;
-    params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing 
+    params.HighThreshold() = 2 * params.LowThreshold();	// Note: high threshold is used by post-processing
     //params.HistorySize() = 100;
     params.HistorySize() = historySize;
     //params.EmbeddedDim() = 20;
@@ -68,22 +66,27 @@ void DPEigenbackgroundBGS::process(const cv::Mat &img_input, cv::Mat &img_output
   bgs.Subtract(frameNumber, frame_data, lowThresholdMask, highThresholdMask);
   lowThresholdMask.Clear();
   bgs.Update(frameNumber, frame_data, lowThresholdMask);
-  
-  cv::Mat foreground(highThresholdMask.Ptr());
 
-  if(showOutput)
-    cv::imshow("Eigenbackground (Oliver)", foreground);
+  img_foreground = cv::cvarrToMat(highThresholdMask.Ptr());
+  img_background = cv::cvarrToMat(bgs.Background()->Ptr());
+  //img_background = cv::Mat::zeros(img_input.size(), img_input.type());
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+    cv::imshow("Eigenbackground (Oliver)", img_foreground);
+#endif
 
-  foreground.copyTo(img_output);
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
 
   delete frame;
   firstTime = false;
   frameNumber++;
 }
 
-void DPEigenbackgroundBGS::saveConfig()
+void DPEigenbackground::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/DPEigenbackgroundBGS.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteInt(fs, "threshold", threshold);
   cvWriteInt(fs, "historySize", historySize);
@@ -93,14 +96,14 @@ void DPEigenbackgroundBGS::saveConfig()
   cvReleaseFileStorage(&fs);
 }
 
-void DPEigenbackgroundBGS::loadConfig()
+void DPEigenbackground::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/DPEigenbackgroundBGS.xml", 0, CV_STORAGE_READ);
-  
-  threshold = cvReadIntByName(fs, 0, "threshold", 225);
-  historySize = cvReadIntByName(fs, 0, "historySize", 20);
-  embeddedDim = cvReadIntByName(fs, 0, "embeddedDim", 10);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  threshold = cvReadIntByName(fs, nullptr, "threshold", 225);
+  historySize = cvReadIntByName(fs, nullptr, "historySize", 20);
+  embeddedDim = cvReadIntByName(fs, nullptr, "embeddedDim", 10);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/DPEigenbackground.h b/package_bgs/DPEigenbackground.h
new file mode 100644
index 0000000000000000000000000000000000000000..f84fee765028a7d1c12e55e44dd1239843b5f159
--- /dev/null
+++ b/package_bgs/DPEigenbackground.h
@@ -0,0 +1,55 @@
+/*
+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
+
+#include "IBGS.h"
+#include "dp/Eigenbackground.h"
+
+using namespace Algorithms::BackgroundSubtraction;
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class DPEigenbackground : public IBGS
+    {
+    private:
+      long frameNumber;
+      IplImage* frame;
+      RgbImage frame_data;
+
+      EigenbackgroundParams params;
+      Eigenbackground bgs;
+      BwImage lowThresholdMask;
+      BwImage highThresholdMask;
+
+      int threshold;
+      int historySize;
+      int embeddedDim;
+
+    public:
+      DPEigenbackground();
+      ~DPEigenbackground();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/dp/DPGrimsonGMMBGS.cpp b/package_bgs/DPGrimsonGMM.cpp
similarity index 54%
rename from package_bgs/dp/DPGrimsonGMMBGS.cpp
rename to package_bgs/DPGrimsonGMM.cpp
index ae5486024289ce9582028d10b00eded772100c73..c72b4d218303bf796340d5a3b6f5131c4c595860 100644
--- a/package_bgs/dp/DPGrimsonGMMBGS.cpp
+++ b/package_bgs/DPGrimsonGMM.cpp
@@ -14,37 +14,35 @@ 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 "DPGrimsonGMMBGS.h"
+#include "DPGrimsonGMM.h"
 
-DPGrimsonGMMBGS::DPGrimsonGMMBGS() : firstTime(true), frameNumber(0), threshold(9.0), alpha(0.01), gaussians(3), showOutput(true) 
+using namespace bgslibrary::algorithms;
+
+DPGrimsonGMM::DPGrimsonGMM() :
+  frameNumber(0), threshold(9.0), alpha(0.01), gaussians(3)
 {
-  std::cout << "DPGrimsonGMMBGS()" << std::endl;
+  std::cout << "DPGrimsonGMM()" << std::endl;
+  setup("./config/DPGrimsonGMM.xml");
 }
 
-DPGrimsonGMMBGS::~DPGrimsonGMMBGS()
+DPGrimsonGMM::~DPGrimsonGMM()
 {
-  std::cout << "~DPGrimsonGMMBGS()" << std::endl;
+  std::cout << "~DPGrimsonGMM()" << std::endl;
 }
 
-void DPGrimsonGMMBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+void DPGrimsonGMM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if(firstTime)
-    saveConfig();
+  init(img_input, img_output, img_bgmodel);
 
   frame = new IplImage(img_input);
-  
-  if(firstTime)
+
+  if (firstTime)
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if(firstTime)
+  if (firstTime)
   {
-    int width	= img_input.size().width;
+    int width = img_input.size().width;
     int height = img_input.size().height;
 
     lowThresholdMask = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
@@ -55,7 +53,7 @@ void DPGrimsonGMMBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv:
 
     params.SetFrameSize(width, height);
     params.LowThreshold() = threshold; //3.0f*3.0f;
-    params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing 
+    params.HighThreshold() = 2 * params.LowThreshold();	// Note: high threshold is used by post-processing
     //params.Alpha() = 0.001f;
     params.Alpha() = alpha; //0.01f;
     params.MaxModes() = gaussians; //3;
@@ -67,22 +65,27 @@ void DPGrimsonGMMBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv:
   bgs.Subtract(frameNumber, frame_data, lowThresholdMask, highThresholdMask);
   lowThresholdMask.Clear();
   bgs.Update(frameNumber, frame_data, lowThresholdMask);
-  
-  cv::Mat foreground(highThresholdMask.Ptr());
 
-  if(showOutput)
-    cv::imshow("GMM (Grimson)", foreground);
-  
-  foreground.copyTo(img_output);
+  img_foreground = cv::cvarrToMat(highThresholdMask.Ptr());
+  img_background = cv::cvarrToMat(bgs.Background()->Ptr());
+  //img_background = cv::Mat::zeros(img_input.size(), img_input.type());
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+    cv::imshow("GMM (Grimson)", img_foreground);
+#endif
+
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
 
   delete frame;
   firstTime = false;
   frameNumber++;
 }
 
-void DPGrimsonGMMBGS::saveConfig()
+void DPGrimsonGMM::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/DPGrimsonGMMBGS.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteReal(fs, "threshold", threshold);
   cvWriteReal(fs, "alpha", alpha);
@@ -92,14 +95,14 @@ void DPGrimsonGMMBGS::saveConfig()
   cvReleaseFileStorage(&fs);
 }
 
-void DPGrimsonGMMBGS::loadConfig()
+void DPGrimsonGMM::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/DPGrimsonGMMBGS.xml", 0, CV_STORAGE_READ);
-  
-  threshold = cvReadRealByName(fs, 0, "threshold", 9.0);
-  alpha = cvReadRealByName(fs, 0, "alpha", 0.01);
-  gaussians = cvReadIntByName(fs, 0, "gaussians", 3);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  threshold = cvReadRealByName(fs, nullptr, "threshold", 9.0);
+  alpha = cvReadRealByName(fs, nullptr, "alpha", 0.01);
+  gaussians = cvReadIntByName(fs, nullptr, "gaussians", 3);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/dp/DPEigenbackgroundBGS.h b/package_bgs/DPGrimsonGMM.h
similarity index 53%
rename from package_bgs/dp/DPEigenbackgroundBGS.h
rename to package_bgs/DPGrimsonGMM.h
index cd4e54c3eb433640ff58895e1349660ce5ee3089..dcc05eb1b3b79c46f207898b0668508670eb6d3d 100644
--- a/package_bgs/dp/DPEigenbackgroundBGS.h
+++ b/package_bgs/DPGrimsonGMM.h
@@ -16,41 +16,40 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-#include "Eigenbackground.h"
+#include "IBGS.h"
+#include "dp/GrimsonGMM.h"
 
 using namespace Algorithms::BackgroundSubtraction;
 
-class DPEigenbackgroundBGS : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  long frameNumber;
-  IplImage* frame;
-  RgbImage frame_data;
-
-  EigenbackgroundParams params;
-  Eigenbackground bgs;
-  BwImage lowThresholdMask;
-  BwImage highThresholdMask;
-
-  int threshold;
-  int historySize;
-  int embeddedDim;
-  bool showOutput;
-
-public:
-  DPEigenbackgroundBGS();
-  ~DPEigenbackgroundBGS();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
-
+  namespace algorithms
+  {
+    class DPGrimsonGMM : public IBGS
+    {
+    private:
+      long frameNumber;
+      IplImage* frame;
+      RgbImage frame_data;
+
+      GrimsonParams params;
+      GrimsonGMM bgs;
+      BwImage lowThresholdMask;
+      BwImage highThresholdMask;
+
+      double threshold;
+      double alpha;
+      int gaussians;
+
+    public:
+      DPGrimsonGMM();
+      ~DPGrimsonGMM();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/dp/DPMeanBGS.cpp b/package_bgs/DPMean.cpp
similarity index 55%
rename from package_bgs/dp/DPMeanBGS.cpp
rename to package_bgs/DPMean.cpp
index 13260b469c9d8eb50d05d9218513b46983162a37..3af1fb644ead27c5597c3bfdbe047c5f6270537e 100644
--- a/package_bgs/dp/DPMeanBGS.cpp
+++ b/package_bgs/DPMean.cpp
@@ -14,37 +14,35 @@ 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 "DPMeanBGS.h"
+#include "DPMean.h"
 
-DPMeanBGS::DPMeanBGS() : firstTime(true), frameNumber(0), threshold(2700), alpha(1e-6f), learningFrames(30), showOutput(true)
+using namespace bgslibrary::algorithms;
+
+DPMean::DPMean() :
+  frameNumber(0), threshold(2700), alpha(1e-6f), learningFrames(30)
 {
-  std::cout << "DPMeanBGS()" << std::endl;
+  std::cout << "DPMean()" << std::endl;
+  setup("./config/DPMean.xml");
 }
 
-DPMeanBGS::~DPMeanBGS()
+DPMean::~DPMean()
 {
-  std::cout << "~DPMeanBGS()" << std::endl;
+  std::cout << "~DPMean()" << std::endl;
 }
 
-void DPMeanBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+void DPMean::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if(firstTime)
-    saveConfig();
+  init(img_input, img_output, img_bgmodel);
 
   frame = new IplImage(img_input);
-  
-  if(firstTime)
+
+  if (firstTime)
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if(firstTime)
+  if (firstTime)
   {
-    int width	= img_input.size().width;
+    int width = img_input.size().width;
     int height = img_input.size().height;
 
     lowThresholdMask = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
@@ -55,7 +53,7 @@ void DPMeanBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
 
     params.SetFrameSize(width, height);
     params.LowThreshold() = threshold; //3*30*30; // 2700
-    params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing 
+    params.HighThreshold() = 2 * params.LowThreshold();	// Note: high threshold is used by post-processing
     //params.Alpha() = 1e-6f;
     params.Alpha() = alpha;
     params.LearningFrames() = learningFrames;//30;
@@ -67,22 +65,27 @@ void DPMeanBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
   bgs.Subtract(frameNumber, frame_data, lowThresholdMask, highThresholdMask);
   lowThresholdMask.Clear();
   bgs.Update(frameNumber, frame_data, lowThresholdMask);
-  
-  cv::Mat foreground(highThresholdMask.Ptr());
 
-  if(showOutput)
-    cv::imshow("Temporal Mean (Donovan Parks)", foreground);
+  img_foreground = cv::cvarrToMat(highThresholdMask.Ptr());
+  img_background = cv::cvarrToMat(bgs.Background()->Ptr());
+  //img_background = cv::Mat::zeros(img_input.size(), img_input.type());
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+    cv::imshow("Temporal Mean (Donovan Parks)", img_foreground);
+#endif
 
-  foreground.copyTo(img_output);
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
 
   delete frame;
   firstTime = false;
   frameNumber++;
 }
 
-void DPMeanBGS::saveConfig()
+void DPMean::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/DPMeanBGS.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteInt(fs, "threshold", threshold);
   cvWriteReal(fs, "alpha", alpha);
@@ -92,14 +95,14 @@ void DPMeanBGS::saveConfig()
   cvReleaseFileStorage(&fs);
 }
 
-void DPMeanBGS::loadConfig()
+void DPMean::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/DPMeanBGS.xml", 0, CV_STORAGE_READ);
-  
-  threshold = cvReadIntByName(fs, 0, "threshold", 2700);
-  alpha = cvReadRealByName(fs, 0, "alpha", 1e-6f);
-  learningFrames = cvReadIntByName(fs, 0, "learningFrames", 30);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  threshold = cvReadIntByName(fs, nullptr, "threshold", 2700);
+  alpha = cvReadRealByName(fs, nullptr, "alpha", 1e-6f);
+  learningFrames = cvReadIntByName(fs, nullptr, "learningFrames", 30);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/dp/DPZivkovicAGMMBGS.h b/package_bgs/DPMean.h
similarity index 56%
rename from package_bgs/dp/DPZivkovicAGMMBGS.h
rename to package_bgs/DPMean.h
index 775226a3807311224ea66b48c9f33ac05820b4b4..60299680675ba0c711055109e2ed59eebde018c5 100644
--- a/package_bgs/dp/DPZivkovicAGMMBGS.h
+++ b/package_bgs/DPMean.h
@@ -16,41 +16,40 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-#include "ZivkovicAGMM.h"
+#include "IBGS.h"
+#include "dp/MeanBGS.h"
 
 using namespace Algorithms::BackgroundSubtraction;
 
-class DPZivkovicAGMMBGS : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  long frameNumber;
-  IplImage* frame;
-  RgbImage frame_data;
-
-  ZivkovicParams params;
-  ZivkovicAGMM bgs;
-  BwImage lowThresholdMask;
-  BwImage highThresholdMask;
-
-  double threshold;
-  double alpha;
-  int gaussians;
-  bool showOutput;
-
-public:
-  DPZivkovicAGMMBGS();
-  ~DPZivkovicAGMMBGS();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
-
+  namespace algorithms
+  {
+    class DPMean : public IBGS
+    {
+    private:
+      long frameNumber;
+      IplImage* frame;
+      RgbImage frame_data;
+
+      MeanParams params;
+      MeanBGS bgs;
+      BwImage lowThresholdMask;
+      BwImage highThresholdMask;
+
+      int threshold;
+      double alpha;
+      int learningFrames;
+
+    public:
+      DPMean();
+      ~DPMean();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/dp/DPPratiMediodBGS.cpp b/package_bgs/DPPratiMediod.cpp
similarity index 53%
rename from package_bgs/dp/DPPratiMediodBGS.cpp
rename to package_bgs/DPPratiMediod.cpp
index ba1d6be81fa337f44e6f9126646112d358622f02..d1942c53ce2f4fe758ced5f5631239e4f6dff925 100644
--- a/package_bgs/dp/DPPratiMediodBGS.cpp
+++ b/package_bgs/DPPratiMediod.cpp
@@ -14,37 +14,35 @@ 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 "DPPratiMediodBGS.h"
+#include "DPPratiMediod.h"
 
-DPPratiMediodBGS::DPPratiMediodBGS() : firstTime(true), frameNumber(0), threshold(30), samplingRate(5), historySize(16), weight(5), showOutput(true)
+using namespace bgslibrary::algorithms;
+
+DPPratiMediod::DPPratiMediod() :
+  frameNumber(0), threshold(30), samplingRate(5), historySize(16), weight(5)
 {
-  std::cout << "DPPratiMediodBGS()" << std::endl;
+  std::cout << "DPPratiMediod()" << std::endl;
+  setup("./config/DPPratiMediod.xml");
 }
 
-DPPratiMediodBGS::~DPPratiMediodBGS()
+DPPratiMediod::~DPPratiMediod()
 {
-  std::cout << "~DPPratiMediodBGS()" << std::endl;
+  std::cout << "~DPPratiMediod()" << std::endl;
 }
 
-void DPPratiMediodBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+void DPPratiMediod::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if(firstTime)
-    saveConfig();
+  init(img_input, img_output, img_bgmodel);
 
   frame = new IplImage(img_input);
-  
-  if(firstTime)
+
+  if (firstTime)
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if(firstTime)
+  if (firstTime)
   {
-    int width	= img_input.size().width;
+    int width = img_input.size().width;
     int height = img_input.size().height;
 
     lowThresholdMask = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
@@ -55,7 +53,7 @@ void DPPratiMediodBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv
 
     params.SetFrameSize(width, height);
     params.LowThreshold() = threshold;
-    params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing 
+    params.HighThreshold() = 2 * params.LowThreshold();	// Note: high threshold is used by post-processing
     params.SamplingRate() = samplingRate;
     params.HistorySize() = historySize;
     params.Weight() = weight;
@@ -67,26 +65,29 @@ void DPPratiMediodBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv
   bgs.Subtract(frameNumber, frame_data, lowThresholdMask, highThresholdMask);
   lowThresholdMask.Clear();
   bgs.Update(frameNumber, frame_data, lowThresholdMask);
-  
-  cv::Mat foreground(highThresholdMask.Ptr());
-  cv::Mat background(bgs.Background()->Ptr());
 
-  if(showOutput){
-    cv::imshow("Temporal Median FG (Cucchiara&Calderara)", foreground);
-    cv::imshow("Temporal Median BG (Cucchiara&Calderara)", background);
+  img_foreground = cv::cvarrToMat(highThresholdMask.Ptr());
+  img_background = cv::cvarrToMat(bgs.Background()->Ptr());
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+  {
+    cv::imshow("Temporal Median FG (Cucchiara&Calderara)", img_foreground);
+    cv::imshow("Temporal Median BG (Cucchiara&Calderara)", img_background);
   }
+#endif
 
-  foreground.copyTo(img_output);
-  background.copyTo(img_bgmodel);
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
 
   delete frame;
   firstTime = false;
   frameNumber++;
 }
 
-void DPPratiMediodBGS::saveConfig()
+void DPPratiMediod::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/DPPratiMediodBGS.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteInt(fs, "threshold", threshold);
   cvWriteInt(fs, "samplingRate", samplingRate);
@@ -97,15 +98,15 @@ void DPPratiMediodBGS::saveConfig()
   cvReleaseFileStorage(&fs);
 }
 
-void DPPratiMediodBGS::loadConfig()
+void DPPratiMediod::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/DPPratiMediodBGS.xml", 0, CV_STORAGE_READ);
-  
-  threshold = cvReadIntByName(fs, 0, "threshold", 30);
-  samplingRate = cvReadIntByName(fs, 0, "samplingRate", 5);
-  historySize = cvReadIntByName(fs, 0, "historySize", 16);
-  weight = cvReadIntByName(fs, 0, "weight", 5);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  threshold = cvReadIntByName(fs, nullptr, "threshold", 30);
+  samplingRate = cvReadIntByName(fs, nullptr, "samplingRate", 5);
+  historySize = cvReadIntByName(fs, nullptr, "historySize", 16);
+  weight = cvReadIntByName(fs, nullptr, "weight", 5);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
-}
\ No newline at end of file
+}
diff --git a/package_bgs/dp/DPMeanBGS.h b/package_bgs/DPPratiMediod.h
similarity index 52%
rename from package_bgs/dp/DPMeanBGS.h
rename to package_bgs/DPPratiMediod.h
index 88296860f11f1462df6bbfbc8a31b097cc57c24b..d37a77abd018547f519dcd244b96e970a590bdc1 100644
--- a/package_bgs/dp/DPMeanBGS.h
+++ b/package_bgs/DPPratiMediod.h
@@ -16,41 +16,41 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-#include "MeanBGS.h"
+#include "IBGS.h"
+#include "dp/PratiMediodBGS.h"
 
 using namespace Algorithms::BackgroundSubtraction;
 
-class DPMeanBGS : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  long frameNumber;
-  IplImage* frame;
-  RgbImage frame_data;
-
-  MeanParams params;
-  MeanBGS bgs;
-  BwImage lowThresholdMask;
-  BwImage highThresholdMask;
-
-  int threshold;
-  double alpha;
-  int learningFrames;
-  bool showOutput;
-
-public:
-  DPMeanBGS();
-  ~DPMeanBGS();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
-
+  namespace algorithms
+  {
+    class DPPratiMediod : public IBGS
+    {
+    private:
+      long frameNumber;
+      IplImage* frame;
+      RgbImage frame_data;
+
+      PratiParams params;
+      PratiMediodBGS bgs;
+      BwImage lowThresholdMask;
+      BwImage highThresholdMask;
+
+      int threshold;
+      int samplingRate;
+      int historySize;
+      int weight;
+
+    public:
+      DPPratiMediod();
+      ~DPPratiMediod();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/dp/DPTextureBGS.cpp b/package_bgs/DPTexture.cpp
similarity index 65%
rename from package_bgs/dp/DPTextureBGS.cpp
rename to package_bgs/DPTexture.cpp
index 2d34342e1151fb8c174a9291781622a63fc10a0a..3285ccf83ecdcd0698bcfcfb9622188784144050 100644
--- a/package_bgs/dp/DPTextureBGS.cpp
+++ b/package_bgs/DPTexture.cpp
@@ -14,15 +14,18 @@ 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 "DPTextureBGS.h"
+#include "DPTexture.h"
 
-DPTextureBGS::DPTextureBGS() : firstTime(true), showOutput(true)
-  //, enableFiltering(true)
+using namespace bgslibrary::algorithms;
+
+DPTexture::DPTexture()
+// : enableFiltering(true)
 {
-  std::cout << "DPTextureBGS()" << std::endl;
+  std::cout << "DPTexture()" << std::endl;
+  setup("./config/DPTexture.xml");
 }
 
-DPTextureBGS::~DPTextureBGS()
+DPTexture::~DPTexture()
 {
   delete[] bgModel; // ~10Kb (25.708-15.968)
   delete[] modeArray;
@@ -33,34 +36,31 @@ DPTextureBGS::~DPTextureBGS()
   fgMask.ReleaseImage();
   tempMask.ReleaseImage();
   texture.ReleaseImage();
-  std::cout << "~DPTextureBGS()" << std::endl;
+  std::cout << "~DPTexture()" << std::endl;
 }
 
-void DPTextureBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+void DPTexture::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-
-  loadConfig();
+  init(img_input, img_output, img_bgmodel);
 
   frame = new IplImage(img_input);
-  
-  if(firstTime)
+
+  if (firstTime)
   {
-    width	= img_input.size().width;
+    width = img_input.size().width;
     height = img_input.size().height;
     size = width * height;
 
     // input image
     image = cvCreateImage(cvSize(width, height), 8, 3);
-    cvCopy(frame, image.Ptr());	
+    cvCopy(frame, image.Ptr());
 
     // foreground masks
     fgMask = cvCreateImage(cvSize(width, height), 8, 1);
     tempMask = cvCreateImage(cvSize(width, height), 8, 1);
     cvZero(fgMask.Ptr());
     cvZero(tempMask.Ptr());
-    
+
     // create background model
     bgModel = new TextureArray[size];
     texture = cvCreateImage(cvSize(width, height), 8, 3);
@@ -71,16 +71,16 @@ void DPTextureBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Ma
     // initialize background model
     bgs.LBP(image, texture);
     bgs.Histogram(texture, curTextureHist);
-    for(int y = REGION_R+TEXTURE_R; y < height-REGION_R-TEXTURE_R; ++y)
+    for (int y = REGION_R + TEXTURE_R; y < height - REGION_R - TEXTURE_R; ++y)
     {
-      for(int x = REGION_R+TEXTURE_R; x < width-REGION_R-TEXTURE_R; ++x)
+      for (int x = REGION_R + TEXTURE_R; x < width - REGION_R - TEXTURE_R; ++x)
       {
-        int index = x+y*width;
-      
-        for(int m = 0; m < NUM_MODES; ++m)
+        int index = x + y*width;
+
+        for (int m = 0; m < NUM_MODES; ++m)
         {
-          for(int i = 0; i < NUM_BINS; ++i)
-          {			
+          for (int i = 0; i < NUM_BINS; ++i)
+          {
             bgModel[index].mode[m].r[i] = curTextureHist[index].r[i];
             bgModel[index].mode[m].g[i] = curTextureHist[index].g[i];
             bgModel[index].mode[m].b[i] = curTextureHist[index].b[i];
@@ -91,18 +91,16 @@ void DPTextureBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Ma
 
     //dilateElement = cvCreateStructuringElementEx(7, 7, 3, 3,	CV_SHAPE_RECT);
     //erodeElement = cvCreateStructuringElementEx(3, 3, 1, 1,	CV_SHAPE_RECT);
-
-    saveConfig();
     firstTime = false;
   }
-  
-  cvCopy(frame, image.Ptr());	
+
+  cvCopy(frame, image.Ptr());
 
   // perform background subtraction
   bgs.LBP(image, texture);
   bgs.Histogram(texture, curTextureHist);
   bgs.BgsCompare(bgModel, curTextureHist, modeArray, THRESHOLD, fgMask);
-  
+
   //if(enableFiltering)
   //{
   //  // size filtering
@@ -120,22 +118,27 @@ void DPTextureBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Ma
   //  cvErode(fgMask.Ptr(), fgMask.Ptr(), erodeElement, 1);
   //}
 
-  cv::Mat foreground(fgMask.Ptr());
-  if(!foreground.empty())
-    foreground.copyTo(img_output);
-  
-  if(showOutput)
-    cv::imshow("Texture BGS (Donovan Parks)", foreground);
+  img_foreground = cv::cvarrToMat(fgMask.Ptr());
+  //img_background = cv::cvarrToMat(bgs.Background()->Ptr());
+  img_background = cv::Mat::zeros(img_input.size(), img_input.type());
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+    cv::imshow("Texture BGS (Donovan Parks)", img_foreground);
+#endif
 
-  // update background subtraction		
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
+
+  // update background subtraction
   bgs.UpdateModel(fgMask, bgModel, curTextureHist, modeArray);
-  
+
   delete frame;
 }
 
-void DPTextureBGS::saveConfig()
+void DPTexture::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/DPTextureBGS.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   //cvWriteReal(fs, "alpha", alpha);
   //cvWriteInt(fs, "enableFiltering", enableFiltering);
@@ -144,13 +147,13 @@ void DPTextureBGS::saveConfig()
   cvReleaseFileStorage(&fs);
 }
 
-void DPTextureBGS::loadConfig()
+void DPTexture::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/DPTextureBGS.xml", 0, CV_STORAGE_READ);
-  
-  //alpha = cvReadRealByName(fs, 0, "alpha", 1e-6f);
-  //enableFiltering = cvReadIntByName(fs, 0, "enableFiltering", true);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  //alpha = cvReadRealByName(fs, nullptr, "alpha", 1e-6f);
+  //enableFiltering = cvReadIntByName(fs, nullptr, "enableFiltering", true);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/DPTexture.h b/package_bgs/DPTexture.h
new file mode 100644
index 0000000000000000000000000000000000000000..3cfdcea4c0bb499c323f4ef6b0cb0e218eaf3fdf
--- /dev/null
+++ b/package_bgs/DPTexture.h
@@ -0,0 +1,59 @@
+/*
+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
+
+#include "IBGS.h"
+#include "dp/TextureBGS.h"
+//#include "ConnectedComponents.h"
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class DPTexture : public IBGS
+    {
+    private:
+      int width;
+      int height;
+      int size;
+      TextureBGS bgs;
+      IplImage* frame;
+      RgbImage image;
+      BwImage fgMask;
+      BwImage tempMask;
+      TextureArray* bgModel;
+      RgbImage texture;
+      unsigned char* modeArray;
+      TextureHistogram* curTextureHist;
+      //ConnectedComponents cc;
+      //CBlobResult largeBlobs;
+      //IplConvKernel* dilateElement;
+      //IplConvKernel* erodeElement;
+      //bool enableFiltering;
+
+    public:
+      DPTexture();
+      ~DPTexture();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/dp/DPWrenGABGS.cpp b/package_bgs/DPWrenGA.cpp
similarity index 54%
rename from package_bgs/dp/DPWrenGABGS.cpp
rename to package_bgs/DPWrenGA.cpp
index d7241b1db6ce9ef0c219b5fbaa28e7cb2abc2963..7fc331379d1ef27ea223e43dea6384308aafd503 100644
--- a/package_bgs/dp/DPWrenGABGS.cpp
+++ b/package_bgs/DPWrenGA.cpp
@@ -14,37 +14,35 @@ 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 "DPWrenGABGS.h"
+#include "DPWrenGA.h"
 
-DPWrenGABGS::DPWrenGABGS() : firstTime(true), frameNumber(0), threshold(12.25f), alpha(0.005f), learningFrames(30), showOutput(true)
+using namespace bgslibrary::algorithms;
+
+DPWrenGA::DPWrenGA() :
+  frameNumber(0), threshold(12.25f), alpha(0.005f), learningFrames(30)
 {
-  std::cout << "DPWrenGABGS()" << std::endl;
+  std::cout << "DPWrenGA()" << std::endl;
+  setup("./config/DPWrenGA.xml");
 }
 
-DPWrenGABGS::~DPWrenGABGS()
+DPWrenGA::~DPWrenGA()
 {
-  std::cout << "~DPWrenGABGS()" << std::endl;
+  std::cout << "~DPWrenGA()" << std::endl;
 }
 
-void DPWrenGABGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+void DPWrenGA::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if(firstTime)
-    saveConfig();
+  init(img_input, img_output, img_bgmodel);
 
   frame = new IplImage(img_input);
-  
-  if(firstTime)
+
+  if (firstTime)
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if(firstTime)
+  if (firstTime)
   {
-    int width	= img_input.size().width;
+    int width = img_input.size().width;
     int height = img_input.size().height;
 
     lowThresholdMask = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
@@ -55,7 +53,7 @@ void DPWrenGABGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat
 
     params.SetFrameSize(width, height);
     params.LowThreshold() = threshold; //3.5f*3.5f;
-    params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing 
+    params.HighThreshold() = 2 * params.LowThreshold();	// Note: high threshold is used by post-processing
     params.Alpha() = alpha; //0.005f;
     params.LearningFrames() = learningFrames; //30;
 
@@ -66,22 +64,27 @@ void DPWrenGABGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat
   bgs.Subtract(frameNumber, frame_data, lowThresholdMask, highThresholdMask);
   lowThresholdMask.Clear();
   bgs.Update(frameNumber, frame_data, lowThresholdMask);
-  
-  cv::Mat foreground(highThresholdMask.Ptr());
 
-  if(showOutput)
-    cv::imshow("Gaussian Average (Wren)", foreground);
-  
-  foreground.copyTo(img_output);
+  img_foreground = cv::cvarrToMat(highThresholdMask.Ptr());
+  img_background = cv::cvarrToMat(bgs.Background()->Ptr());
+  //img_background = cv::Mat::zeros(img_input.size(), img_input.type());
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+    cv::imshow("Gaussian Average (Wren)", img_foreground);
+#endif
+
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
 
   delete frame;
   firstTime = false;
   frameNumber++;
 }
 
-void DPWrenGABGS::saveConfig()
+void DPWrenGA::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/DPWrenGABGS.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteReal(fs, "threshold", threshold);
   cvWriteReal(fs, "alpha", alpha);
@@ -91,15 +94,14 @@ void DPWrenGABGS::saveConfig()
   cvReleaseFileStorage(&fs);
 }
 
-void DPWrenGABGS::loadConfig()
+void DPWrenGA::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/DPWrenGABGS.xml", 0, CV_STORAGE_READ);
-  
-  threshold = cvReadRealByName(fs, 0, "threshold", 12.25f);
-  alpha = cvReadRealByName(fs, 0, "alpha", 0.005f);
-  learningFrames = cvReadIntByName(fs, 0, "learningFrames", 30);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  threshold = cvReadRealByName(fs, nullptr, "threshold", 12.25f);
+  alpha = cvReadRealByName(fs, nullptr, "alpha", 0.005f);
+  learningFrames = cvReadIntByName(fs, nullptr, "learningFrames", 30);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
-
diff --git a/package_bgs/dp/DPWrenGABGS.h b/package_bgs/DPWrenGA.h
similarity index 54%
rename from package_bgs/dp/DPWrenGABGS.h
rename to package_bgs/DPWrenGA.h
index 30ab614b0789abbbbe432150b26c5991fdb4751c..e4b0b5fffbb22de9dbc1edcbc8d24929576b69fc 100644
--- a/package_bgs/dp/DPWrenGABGS.h
+++ b/package_bgs/DPWrenGA.h
@@ -16,41 +16,40 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-#include "WrenGA.h"
+#include "IBGS.h"
+#include "dp/WrenGA.h"
 
 using namespace Algorithms::BackgroundSubtraction;
 
-class DPWrenGABGS : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  long frameNumber;
-  IplImage* frame;
-  RgbImage frame_data;
-
-  WrenParams params;
-  WrenGA bgs;
-  BwImage lowThresholdMask;
-  BwImage highThresholdMask;
-
-  double threshold;
-  double alpha;
-  int learningFrames;
-  bool showOutput;
-
-public:
-  DPWrenGABGS();
-  ~DPWrenGABGS();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
-
+  namespace algorithms
+  {
+    class DPWrenGA : public IBGS
+    {
+    private:
+      long frameNumber;
+      IplImage* frame;
+      RgbImage frame_data;
+
+      WrenParams params;
+      WrenGA bgs;
+      BwImage lowThresholdMask;
+      BwImage highThresholdMask;
+
+      double threshold;
+      double alpha;
+      int learningFrames;
+
+    public:
+      DPWrenGA();
+      ~DPWrenGA();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/dp/DPZivkovicAGMMBGS.cpp b/package_bgs/DPZivkovicAGMM.cpp
similarity index 53%
rename from package_bgs/dp/DPZivkovicAGMMBGS.cpp
rename to package_bgs/DPZivkovicAGMM.cpp
index e8276f6bd8ceaa328faedc971b842493f7e70edb..a5a973514783fdb7791cfdc571c8f0c9630df322 100644
--- a/package_bgs/dp/DPZivkovicAGMMBGS.cpp
+++ b/package_bgs/DPZivkovicAGMM.cpp
@@ -14,37 +14,35 @@ 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 "DPZivkovicAGMMBGS.h"
+#include "DPZivkovicAGMM.h"
 
-DPZivkovicAGMMBGS::DPZivkovicAGMMBGS() : firstTime(true), frameNumber(0), threshold(25.0f), alpha(0.001f), gaussians(3), showOutput(true) 
+using namespace bgslibrary::algorithms;
+
+DPZivkovicAGMM::DPZivkovicAGMM() :
+  frameNumber(0), threshold(25.0f), alpha(0.001f), gaussians(3)
 {
-  std::cout << "DPZivkovicAGMMBGS()" << std::endl;
+  std::cout << "DPZivkovicAGMM()" << std::endl;
+  setup("./config/DPZivkovicAGMM.xml");
 }
 
-DPZivkovicAGMMBGS::~DPZivkovicAGMMBGS()
+DPZivkovicAGMM::~DPZivkovicAGMM()
 {
-  std::cout << "~DPZivkovicAGMMBGS()" << std::endl;
+  std::cout << "~DPZivkovicAGMM()" << std::endl;
 }
 
-void DPZivkovicAGMMBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+void DPZivkovicAGMM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if(firstTime)
-    saveConfig();
+  init(img_input, img_output, img_bgmodel);
 
   frame = new IplImage(img_input);
-  
-  if(firstTime)
+
+  if (firstTime)
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if(firstTime)
+  if (firstTime)
   {
-    int width	= img_input.size().width;
+    int width = img_input.size().width;
     int height = img_input.size().height;
 
     lowThresholdMask = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
@@ -55,7 +53,7 @@ void DPZivkovicAGMMBGS::process(const cv::Mat &img_input, cv::Mat &img_output, c
 
     params.SetFrameSize(width, height);
     params.LowThreshold() = threshold; //5.0f*5.0f;
-    params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing 
+    params.HighThreshold() = 2 * params.LowThreshold();	// Note: high threshold is used by post-processing
     params.Alpha() = alpha; //0.001f;
     params.MaxModes() = gaussians; //3;
 
@@ -66,22 +64,27 @@ void DPZivkovicAGMMBGS::process(const cv::Mat &img_input, cv::Mat &img_output, c
   bgs.Subtract(frameNumber, frame_data, lowThresholdMask, highThresholdMask);
   lowThresholdMask.Clear();
   bgs.Update(frameNumber, frame_data, lowThresholdMask);
-  
-  cv::Mat foreground(highThresholdMask.Ptr());
 
-  if(showOutput)
-    cv::imshow("Gaussian Mixture Model (Zivkovic)", foreground);
-  
-  foreground.copyTo(img_output);
+  img_foreground = cv::cvarrToMat(highThresholdMask.Ptr());
+  img_background = cv::cvarrToMat(bgs.Background()->Ptr());
+  //img_background = cv::Mat::zeros(img_input.size(), img_input.type());
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+    cv::imshow("Gaussian Mixture Model (Zivkovic)", img_foreground);
+#endif
+
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
 
   delete frame;
   firstTime = false;
   frameNumber++;
 }
 
-void DPZivkovicAGMMBGS::saveConfig()
+void DPZivkovicAGMM::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/DPZivkovicAGMMBGS.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteReal(fs, "threshold", threshold);
   cvWriteReal(fs, "alpha", alpha);
@@ -91,14 +94,14 @@ void DPZivkovicAGMMBGS::saveConfig()
   cvReleaseFileStorage(&fs);
 }
 
-void DPZivkovicAGMMBGS::loadConfig()
+void DPZivkovicAGMM::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/DPZivkovicAGMMBGS.xml", 0, CV_STORAGE_READ);
-  
-  threshold = cvReadRealByName(fs, 0, "threshold", 25.0f);
-  alpha = cvReadRealByName(fs, 0, "alpha", 0.001f);
-  gaussians = cvReadIntByName(fs, 0, "gaussians", 3);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  threshold = cvReadRealByName(fs, nullptr, "threshold", 25.0f);
+  alpha = cvReadRealByName(fs, nullptr, "alpha", 0.001f);
+  gaussians = cvReadIntByName(fs, nullptr, "gaussians", 3);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/dp/DPGrimsonGMMBGS.h b/package_bgs/DPZivkovicAGMM.h
similarity index 53%
rename from package_bgs/dp/DPGrimsonGMMBGS.h
rename to package_bgs/DPZivkovicAGMM.h
index 4f955b970e7557f9406d458ac5db0dc83abccb28..f35504bff012f395bfa86ad5b304442fcb2fc08b 100644
--- a/package_bgs/dp/DPGrimsonGMMBGS.h
+++ b/package_bgs/DPZivkovicAGMM.h
@@ -16,41 +16,40 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-#include "GrimsonGMM.h"
+#include "IBGS.h"
+#include "dp/ZivkovicAGMM.h"
 
 using namespace Algorithms::BackgroundSubtraction;
 
-class DPGrimsonGMMBGS : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  long frameNumber;
-  IplImage* frame;
-  RgbImage frame_data;
-
-  GrimsonParams params;
-  GrimsonGMM bgs;
-  BwImage lowThresholdMask;
-  BwImage highThresholdMask;
-
-  double threshold;
-  double alpha;
-  int gaussians;
-  bool showOutput;
-
-public:
-  DPGrimsonGMMBGS();
-  ~DPGrimsonGMMBGS();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
-
+  namespace algorithms
+  {
+    class DPZivkovicAGMM : public IBGS
+    {
+    private:
+      long frameNumber;
+      IplImage* frame;
+      RgbImage frame_data;
+
+      ZivkovicParams params;
+      ZivkovicAGMM bgs;
+      BwImage lowThresholdMask;
+      BwImage highThresholdMask;
+
+      double threshold;
+      double alpha;
+      int gaussians;
+
+    public:
+      DPZivkovicAGMM();
+      ~DPZivkovicAGMM();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/FrameDifference.cpp b/package_bgs/FrameDifference.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4d5c076ce380ad410f115c678d4b71a0a2ca354a
--- /dev/null
+++ b/package_bgs/FrameDifference.cpp
@@ -0,0 +1,84 @@
+/*
+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 "FrameDifference.h"
+
+using namespace bgslibrary::algorithms;
+
+FrameDifference::FrameDifference() :
+  enableThreshold(true), threshold(15)
+{
+  std::cout << "FrameDifference()" << std::endl;
+  setup("./config/FrameDifference.xml");
+}
+
+FrameDifference::~FrameDifference()
+{
+  std::cout << "~FrameDifference()" << std::endl;
+}
+
+void FrameDifference::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+{
+  init(img_input, img_output, img_bgmodel);
+
+  if (img_background.empty())
+  {
+    img_input.copyTo(img_background);
+    return;
+  }
+
+  cv::absdiff(img_background, img_input, img_foreground);
+
+  if (img_foreground.channels() == 3)
+    cv::cvtColor(img_foreground, img_foreground, CV_BGR2GRAY);
+
+  if (enableThreshold)
+    cv::threshold(img_foreground, img_foreground, threshold, 255, cv::THRESH_BINARY);
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+    cv::imshow("Frame Difference", img_foreground);
+#endif
+
+  img_foreground.copyTo(img_output);
+
+  img_input.copyTo(img_background);
+  img_background.copyTo(img_bgmodel);
+
+  firstTime = false;
+}
+
+void FrameDifference::saveConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
+
+  cvWriteInt(fs, "enableThreshold", enableThreshold);
+  cvWriteInt(fs, "threshold", threshold);
+  cvWriteInt(fs, "showOutput", showOutput);
+
+  cvReleaseFileStorage(&fs);
+}
+
+void FrameDifference::loadConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  enableThreshold = cvReadIntByName(fs, nullptr, "enableThreshold", true);
+  threshold = cvReadIntByName(fs, nullptr, "threshold", 15);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
+
+  cvReleaseFileStorage(&fs);
+}
diff --git a/package_bgs/FrameDifferenceBGS.h b/package_bgs/FrameDifference.h
similarity index 61%
rename from package_bgs/FrameDifferenceBGS.h
rename to package_bgs/FrameDifference.h
index 338979f1966eac943984eb1b326d58a63df0581a..07bed8ed5e36fa42a53e81b95ea9624349f820a6 100644
--- a/package_bgs/FrameDifferenceBGS.h
+++ b/package_bgs/FrameDifference.h
@@ -16,29 +16,28 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
 #include "IBGS.h"
 
-class FrameDifferenceBGS : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  cv::Mat img_input_prev;
-  cv::Mat img_foreground;
-  bool enableThreshold;
-  int threshold;
-  bool showOutput;
-
-public:
-  FrameDifferenceBGS();
-  ~FrameDifferenceBGS();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
\ No newline at end of file
+  namespace algorithms
+  {
+    class FrameDifference : public IBGS
+    {
+    private:
+      bool enableThreshold;
+      int threshold;
+
+    public:
+      FrameDifference();
+      ~FrameDifference();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
+
diff --git a/package_bgs/FrameDifferenceBGS.cpp b/package_bgs/FrameDifferenceBGS.cpp
deleted file mode 100644
index e87165120919861a03b54fd8066b073122bfdf59..0000000000000000000000000000000000000000
--- a/package_bgs/FrameDifferenceBGS.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-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 "FrameDifferenceBGS.h"
-
-FrameDifferenceBGS::FrameDifferenceBGS() : firstTime(true), enableThreshold(true), threshold(15), showOutput(true)
-{
-  std::cout << "FrameDifferenceBGS()" << std::endl;
-}
-
-FrameDifferenceBGS::~FrameDifferenceBGS()
-{
-  std::cout << "~FrameDifferenceBGS()" << std::endl;
-}
-
-void FrameDifferenceBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
-{
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if(firstTime)
-    saveConfig();
-
-  if(img_input_prev.empty())
-  {
-    img_input.copyTo(img_input_prev);
-    return;
-  }
-
-  cv::absdiff(img_input_prev, img_input, img_foreground);
-
-  if(img_foreground.channels() == 3)
-    cv::cvtColor(img_foreground, img_foreground, CV_BGR2GRAY);
-
-  if(enableThreshold)
-    cv::threshold(img_foreground, img_foreground, threshold, 255, cv::THRESH_BINARY);
-
-  if(showOutput)
-    cv::imshow("Frame Difference", img_foreground);
-
-  img_foreground.copyTo(img_output);
-
-  img_input.copyTo(img_input_prev);
-
-  firstTime = false;
-}
-
-void FrameDifferenceBGS::saveConfig()
-{
-  CvFileStorage* fs = cvOpenFileStorage("./config/FrameDifferenceBGS.xml", 0, CV_STORAGE_WRITE);
-
-  cvWriteInt(fs, "enableThreshold", enableThreshold);
-  cvWriteInt(fs, "threshold", threshold);
-  cvWriteInt(fs, "showOutput", showOutput);
-
-  cvReleaseFileStorage(&fs);
-}
-
-void FrameDifferenceBGS::loadConfig()
-{
-  CvFileStorage* fs = cvOpenFileStorage("./config/FrameDifferenceBGS.xml", 0, CV_STORAGE_READ);
-  
-  enableThreshold = cvReadIntByName(fs, 0, "enableThreshold", true);
-  threshold = cvReadIntByName(fs, 0, "threshold", 15);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
-
-  cvReleaseFileStorage(&fs);
-}
\ No newline at end of file
diff --git a/package_bgs/tb/FuzzyChoquetIntegral.cpp b/package_bgs/FuzzyChoquetIntegral.cpp
similarity index 62%
rename from package_bgs/tb/FuzzyChoquetIntegral.cpp
rename to package_bgs/FuzzyChoquetIntegral.cpp
index c97e1743e445220616a82f6de99f2d176770b6ee..3d24126b4a089ddb7b026786146529876637c1e5 100644
--- a/package_bgs/tb/FuzzyChoquetIntegral.cpp
+++ b/package_bgs/FuzzyChoquetIntegral.cpp
@@ -15,12 +15,15 @@ You should have received a copy of the GNU General Public License
 along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "FuzzyChoquetIntegral.h"
-#include <opencv2/legacy/compat.hpp>
 
-FuzzyChoquetIntegral::FuzzyChoquetIntegral() : firstTime(true), frameNumber(0), showOutput(true),
-  framesToLearn(10), alphaLearn(0.1), alphaUpdate(0.01), colorSpace(1), option(2), smooth(true), threshold(0.67)
+using namespace bgslibrary::algorithms;
+
+FuzzyChoquetIntegral::FuzzyChoquetIntegral() :
+  frameNumber(0), framesToLearn(10), alphaLearn(0.1), alphaUpdate(0.01),
+  colorSpace(1), option(2), smooth(true), threshold(0.67)
 {
   std::cout << "FuzzyChoquetIntegral()" << std::endl;
+  setup("./config/FuzzyChoquetIntegral.xml");
 }
 
 FuzzyChoquetIntegral::~FuzzyChoquetIntegral()
@@ -30,48 +33,52 @@ FuzzyChoquetIntegral::~FuzzyChoquetIntegral()
 
 void FuzzyChoquetIntegral::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
+  init(img_input, img_output, img_bgmodel);
 
   cv::Mat img_input_f3(img_input.size(), CV_32F);
-  img_input.convertTo(img_input_f3, CV_32F, 1./255.);
-
-  loadConfig();
+  img_input.convertTo(img_input_f3, CV_32F, 1. / 255.);
 
-  if(firstTime)
+  if (firstTime)
   {
     std::cout << "FuzzyChoquetIntegral parameters:" << std::endl;
-      
+
     std::string colorSpaceName = "";
-    switch(colorSpace)
+    switch (colorSpace)
     {
-      case 1: colorSpaceName = "RGB";  break;
-      case 2: colorSpaceName = "OHTA"; break;
-      case 3: colorSpaceName = "HSV";  break;
-      case 4: colorSpaceName = "YCrCb"; break;
+    case 1: colorSpaceName = "RGB";  break;
+    case 2: colorSpaceName = "OHTA"; break;
+    case 3: colorSpaceName = "HSV";  break;
+    case 4: colorSpaceName = "YCrCb"; break;
     }
     std::cout << "Color space: " << colorSpaceName << std::endl;
 
-    if(option == 1)
+    if (option == 1)
       std::cout << "Fuzzing by 3 color components" << std::endl;
-    if(option == 2)
+    if (option == 2)
       std::cout << "Fuzzing by 2 color components + 1 texture component" << std::endl;
-    
-    saveConfig();
   }
 
-  if(frameNumber <= framesToLearn)
+  if (frameNumber <= framesToLearn)
   {
-    if(frameNumber == 0)
+    if (frameNumber == 0)
       std::cout << "FuzzyChoquetIntegral initializing background model by adaptive learning..." << std::endl;
 
-    if(img_background_f3.empty())
+    if (img_background_f3.empty())
       img_input_f3.copyTo(img_background_f3);
     else
-      img_background_f3 = alphaLearn*img_input_f3 + (1-alphaLearn)*img_background_f3;
+      img_background_f3 = alphaLearn*img_input_f3 + (1 - alphaLearn)*img_background_f3;
+
+    double minVal = 0., maxVal = 1.;
+    img_background_f3.convertTo(img_background, CV_8U, 255.0 / (maxVal - minVal), -minVal);
+    img_background.copyTo(img_bgmodel);
+
+    img_foreground = cv::Mat::zeros(img_input.size(), img_input.type());
+    img_foreground.copyTo(img_output);
 
-    if(showOutput)
-      cv::imshow("CI BG Model", img_background_f3);
+#ifndef MEX_COMPILE_FLAG
+    if (showOutput)
+      cv::imshow("CI BG Model", img_background);
+#endif
   }
   else
   {
@@ -87,72 +94,74 @@ void FuzzyChoquetIntegral::process(const cv::Mat &img_input, cv::Mat &img_output
     IplImage* background_f1 = new IplImage(img_background_f1);
 
     IplImage* lbp_input_f1 = cvCreateImage(cvSize(input_f1->width, input_f1->height), IPL_DEPTH_32F, 1);
-    cvFillImage(lbp_input_f1, 0.0);
+    cvSetZero(lbp_input_f1);
     fu.LBP(input_f1, lbp_input_f1);
 
-    IplImage* lbp_background_f1 = cvCreateImage(cvSize(background_f1->width, background_f1->height), IPL_DEPTH_32F , 1);
-    cvFillImage(lbp_background_f1, 0.0);
+    IplImage* lbp_background_f1 = cvCreateImage(cvSize(background_f1->width, background_f1->height), IPL_DEPTH_32F, 1);
+    cvSetZero(lbp_background_f1);
     fu.LBP(background_f1, lbp_background_f1);
 
     IplImage* sim_texture_f1 = cvCreateImage(cvSize(input_f1->width, input_f1->height), IPL_DEPTH_32F, 1);
     fu.SimilarityDegreesImage(lbp_input_f1, lbp_background_f1, sim_texture_f1, 1, colorSpace);
 
     IplImage* sim_color_f3 = cvCreateImage(cvSize(input_f3->width, input_f3->height), IPL_DEPTH_32F, 3);
-    fu.SimilarityDegreesImage(input_f3, background_f3, sim_color_f3, 3, colorSpace);	
+    fu.SimilarityDegreesImage(input_f3, background_f3, sim_color_f3, 3, colorSpace);
 
-    float* measureG = (float*) malloc(3*(sizeof(float)));
+    float* measureG = (float*)malloc(3 * (sizeof(float)));
     IplImage* integral_choquet_f1 = cvCreateImage(cvSize(input_f1->width, input_f1->height), IPL_DEPTH_32F, 1);
 
     // 3 color components
-    if(option == 1)
+    if (option == 1)
     {
       fu.FuzzyMeasureG(0.4f, 0.3f, 0.3f, measureG);
       fu.getFuzzyIntegralChoquet(sim_texture_f1, sim_color_f3, option, measureG, integral_choquet_f1);
     }
 
     // 2 color components + 1 texture component
-    if(option == 2)
+    if (option == 2)
     {
       fu.FuzzyMeasureG(0.6f, 0.3f, 0.1f, measureG);
       fu.getFuzzyIntegralChoquet(sim_texture_f1, sim_color_f3, option, measureG, integral_choquet_f1);
     }
 
     free(measureG);
-    cv::Mat img_integral_choquet_f1(integral_choquet_f1);
+    cv::Mat img_integral_choquet_f1 = cv::cvarrToMat(integral_choquet_f1);
 
-    if(smooth)
+    if (smooth)
       cv::medianBlur(img_integral_choquet_f1, img_integral_choquet_f1, 3);
 
     cv::Mat img_foreground_f1(img_input.size(), CV_32F);
     cv::threshold(img_integral_choquet_f1, img_foreground_f1, threshold, 255, cv::THRESH_BINARY_INV);
 
-    cv::Mat img_foreground_u1(img_input.size(), CV_8U);
+    //cv::Mat img_foreground_u1(img_input.size(), CV_8U);
     double minVal = 0., maxVal = 1.;
-    img_foreground_f1.convertTo(img_foreground_u1, CV_8U, 255.0/(maxVal - minVal), -minVal);
-    img_foreground_u1.copyTo(img_output);
+    img_foreground_f1.convertTo(img_foreground, CV_8U, 255.0 / (maxVal - minVal), -minVal);
+    img_foreground.copyTo(img_output);
 
-    cv::Mat img_background_u3(img_input.size(), CV_8U);
+    //cv::Mat img_background_u3(img_input.size(), CV_8U);
     //double minVal = 0., maxVal = 1.;
-    img_background_f3.convertTo(img_background_u3, CV_8U, 255.0/(maxVal - minVal), -minVal);
-    img_background_u3.copyTo(img_bgmodel);
+    img_background_f3.convertTo(img_background, CV_8U, 255.0 / (maxVal - minVal), -minVal);
+    img_background.copyTo(img_bgmodel);
 
-    if(showOutput)
+#ifndef MEX_COMPILE_FLAG
+    if (showOutput)
     {
       cvShowImage("CI LBP Input", lbp_input_f1);
       cvShowImage("CI LBP Background", lbp_background_f1);
       cvShowImage("CI Prob FG Mask", integral_choquet_f1);
 
-      cv::imshow("CI BG Model", img_background_f3);
-      cv::imshow("CI FG Mask", img_foreground_u1);
+      cv::imshow("CI BG Model", img_background);
+      cv::imshow("CI FG Mask", img_foreground);
     }
+#endif
 
-    if(frameNumber == (framesToLearn + 1))
+    if (frameNumber == (framesToLearn + 1))
       std::cout << "FuzzyChoquetIntegral updating background model by adaptive-selective learning..." << std::endl;
 
     IplImage* updated_background_f3 = cvCreateImage(cvSize(input_f1->width, input_f1->height), IPL_DEPTH_32F, 3);
-    cvFillImage(updated_background_f3, 0.0);
+    cvSetZero(updated_background_f3);
     fu.AdaptativeSelectiveBackgroundModelUpdate(input_f3, background_f3, updated_background_f3, integral_choquet_f1, threshold, alphaUpdate);
-    cv::Mat img_updated_background_f3(updated_background_f3);
+    cv::Mat img_updated_background_f3 = cv::cvarrToMat(updated_background_f3);
     img_updated_background_f3.copyTo(img_background_f3);
 
     cvReleaseImage(&lbp_input_f1);
@@ -161,7 +170,7 @@ void FuzzyChoquetIntegral::process(const cv::Mat &img_input, cv::Mat &img_output
     cvReleaseImage(&sim_color_f3);
     cvReleaseImage(&integral_choquet_f1);
     cvReleaseImage(&updated_background_f3);
-    
+
     delete background_f1;
     delete background_f3;
     delete input_f1;
@@ -174,8 +183,8 @@ void FuzzyChoquetIntegral::process(const cv::Mat &img_input, cv::Mat &img_output
 
 void FuzzyChoquetIntegral::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/FuzzyChoquetIntegral.xml", 0, CV_STORAGE_WRITE);
-  
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
+
   cvWriteInt(fs, "showOutput", showOutput);
   cvWriteInt(fs, "framesToLearn", framesToLearn);
   cvWriteReal(fs, "alphaLearn", alphaLearn);
@@ -190,16 +199,16 @@ void FuzzyChoquetIntegral::saveConfig()
 
 void FuzzyChoquetIntegral::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/FuzzyChoquetIntegral.xml", 0, CV_STORAGE_READ);
-  
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
-  framesToLearn = cvReadIntByName(fs, 0, "framesToLearn", 10);
-  alphaLearn = cvReadRealByName(fs, 0, "alphaLearn", 0.1);
-  alphaUpdate = cvReadRealByName(fs, 0, "alphaUpdate", 0.01);
-  colorSpace = cvReadIntByName(fs, 0, "colorSpace", 1);
-  option = cvReadIntByName(fs, 0, "option", 2);
-  smooth = cvReadIntByName(fs, 0, "smooth", true);
-  threshold = cvReadRealByName(fs, 0, "threshold", 0.67);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
+  framesToLearn = cvReadIntByName(fs, nullptr, "framesToLearn", 10);
+  alphaLearn = cvReadRealByName(fs, nullptr, "alphaLearn", 0.1);
+  alphaUpdate = cvReadRealByName(fs, nullptr, "alphaUpdate", 0.01);
+  colorSpace = cvReadIntByName(fs, nullptr, "colorSpace", 1);
+  option = cvReadIntByName(fs, nullptr, "option", 2);
+  smooth = cvReadIntByName(fs, nullptr, "smooth", true);
+  threshold = cvReadRealByName(fs, nullptr, "threshold", 0.67);
 
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/FuzzyChoquetIntegral.h b/package_bgs/FuzzyChoquetIntegral.h
new file mode 100644
index 0000000000000000000000000000000000000000..25681b0c49f4e86efbd35440410b06ba90c25e81
--- /dev/null
+++ b/package_bgs/FuzzyChoquetIntegral.h
@@ -0,0 +1,53 @@
+/*
+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
+
+#include "IBGS.h"
+#include "T2F/FuzzyUtils.h"
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class FuzzyChoquetIntegral : public IBGS
+    {
+    private:
+      long frameNumber;
+
+      int framesToLearn;
+      double alphaLearn;
+      double alphaUpdate;
+      int colorSpace;
+      int option;
+      bool smooth;
+      double threshold;
+
+      FuzzyUtils fu;
+      cv::Mat img_background_f3;
+
+    public:
+      FuzzyChoquetIntegral();
+      ~FuzzyChoquetIntegral();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/tb/FuzzySugenoIntegral.cpp b/package_bgs/FuzzySugenoIntegral.cpp
similarity index 62%
rename from package_bgs/tb/FuzzySugenoIntegral.cpp
rename to package_bgs/FuzzySugenoIntegral.cpp
index 859f14e91d9707d26b61c4af8d47c00e2aa55284..e62fa029637af565142fdd70ae857e180f553ae6 100644
--- a/package_bgs/tb/FuzzySugenoIntegral.cpp
+++ b/package_bgs/FuzzySugenoIntegral.cpp
@@ -15,12 +15,15 @@ You should have received a copy of the GNU General Public License
 along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "FuzzySugenoIntegral.h"
-#include <opencv2/legacy/compat.hpp>
 
-FuzzySugenoIntegral::FuzzySugenoIntegral() : firstTime(true), frameNumber(0), showOutput(true),
-  framesToLearn(10), alphaLearn(0.1), alphaUpdate(0.01), colorSpace(1), option(2), smooth(true), threshold(0.67)
+using namespace bgslibrary::algorithms;
+
+FuzzySugenoIntegral::FuzzySugenoIntegral() :
+  frameNumber(0), framesToLearn(10), alphaLearn(0.1), alphaUpdate(0.01),
+  colorSpace(1), option(2), smooth(true), threshold(0.67)
 {
   std::cout << "FuzzySugenoIntegral()" << std::endl;
+  setup("./config/FuzzySugenoIntegral.xml");
 }
 
 FuzzySugenoIntegral::~FuzzySugenoIntegral()
@@ -30,48 +33,52 @@ FuzzySugenoIntegral::~FuzzySugenoIntegral()
 
 void FuzzySugenoIntegral::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
+  init(img_input, img_output, img_bgmodel);
 
   cv::Mat img_input_f3(img_input.size(), CV_32F);
-  img_input.convertTo(img_input_f3, CV_32F, 1./255.);
-
-  loadConfig();
+  img_input.convertTo(img_input_f3, CV_32F, 1. / 255.);
 
-  if(firstTime)
+  if (firstTime)
   {
     std::cout << "FuzzySugenoIntegral parameters:" << std::endl;
-      
+
     std::string colorSpaceName = "";
-    switch(colorSpace)
+    switch (colorSpace)
     {
-      case 1: colorSpaceName = "RGB";  break;
-      case 2: colorSpaceName = "OHTA"; break;
-      case 3: colorSpaceName = "HSV";  break;
-      case 4: colorSpaceName = "YCrCb"; break;
+    case 1: colorSpaceName = "RGB";  break;
+    case 2: colorSpaceName = "OHTA"; break;
+    case 3: colorSpaceName = "HSV";  break;
+    case 4: colorSpaceName = "YCrCb"; break;
     }
     std::cout << "Color space: " << colorSpaceName << std::endl;
 
-    if(option == 1)
+    if (option == 1)
       std::cout << "Fuzzing by 3 color components" << std::endl;
-    if(option == 2)
+    if (option == 2)
       std::cout << "Fuzzing by 2 color components + 1 texture component" << std::endl;
-    
-    saveConfig();
   }
 
-  if(frameNumber <= framesToLearn)
+  if (frameNumber <= framesToLearn)
   {
-    if(frameNumber == 0)
+    if (frameNumber == 0)
       std::cout << "FuzzySugenoIntegral initializing background model by adaptive learning..." << std::endl;
 
-    if(img_background_f3.empty())
+    if (img_background_f3.empty())
       img_input_f3.copyTo(img_background_f3);
     else
-      img_background_f3 = alphaLearn*img_input_f3 + (1-alphaLearn)*img_background_f3;
+      img_background_f3 = alphaLearn*img_input_f3 + (1 - alphaLearn)*img_background_f3;
+
+    double minVal = 0., maxVal = 1.;
+    img_background_f3.convertTo(img_background, CV_8U, 255.0 / (maxVal - minVal), -minVal);
+    img_background.copyTo(img_bgmodel);
+
+    img_foreground = cv::Mat::zeros(img_input.size(), img_input.type());
+    img_foreground.copyTo(img_output);
 
-    if(showOutput)
-      cv::imshow("SI BG Model", img_background_f3);
+#ifndef MEX_COMPILE_FLAG
+    if (showOutput)
+      cv::imshow("SI BG Model", img_background);
+#endif
   }
   else
   {
@@ -87,72 +94,74 @@ void FuzzySugenoIntegral::process(const cv::Mat &img_input, cv::Mat &img_output,
     IplImage* background_f1 = new IplImage(img_background_f1);
 
     IplImage* lbp_input_f1 = cvCreateImage(cvSize(input_f1->width, input_f1->height), IPL_DEPTH_32F, 1);
-    cvFillImage(lbp_input_f1, 0.0);
+    cvSetZero(lbp_input_f1);
     fu.LBP(input_f1, lbp_input_f1);
 
-    IplImage* lbp_background_f1 = cvCreateImage(cvSize(background_f1->width, background_f1->height), IPL_DEPTH_32F , 1);
-    cvFillImage(lbp_background_f1, 0.0);
+    IplImage* lbp_background_f1 = cvCreateImage(cvSize(background_f1->width, background_f1->height), IPL_DEPTH_32F, 1);
+    cvSetZero(lbp_background_f1);
     fu.LBP(background_f1, lbp_background_f1);
 
     IplImage* sim_texture_f1 = cvCreateImage(cvSize(input_f1->width, input_f1->height), IPL_DEPTH_32F, 1);
     fu.SimilarityDegreesImage(lbp_input_f1, lbp_background_f1, sim_texture_f1, 1, colorSpace);
 
     IplImage* sim_color_f3 = cvCreateImage(cvSize(input_f3->width, input_f3->height), IPL_DEPTH_32F, 3);
-    fu.SimilarityDegreesImage(input_f3, background_f3, sim_color_f3, 3, colorSpace);	
+    fu.SimilarityDegreesImage(input_f3, background_f3, sim_color_f3, 3, colorSpace);
 
-    float* measureG = (float*) malloc(3*(sizeof(float)));
+    float* measureG = (float*)malloc(3 * (sizeof(float)));
     IplImage* integral_sugeno_f1 = cvCreateImage(cvSize(input_f1->width, input_f1->height), IPL_DEPTH_32F, 1);
 
     // 3 color components
-    if(option == 1)
+    if (option == 1)
     {
       fu.FuzzyMeasureG(0.4f, 0.3f, 0.3f, measureG);
       fu.getFuzzyIntegralSugeno(sim_texture_f1, sim_color_f3, option, measureG, integral_sugeno_f1);
     }
 
     // 2 color components + 1 texture component
-    if(option == 2)
+    if (option == 2)
     {
       fu.FuzzyMeasureG(0.6f, 0.3f, 0.1f, measureG);
       fu.getFuzzyIntegralSugeno(sim_texture_f1, sim_color_f3, option, measureG, integral_sugeno_f1);
     }
 
     free(measureG);
-    cv::Mat img_integral_sugeno_f1(integral_sugeno_f1);
+    cv::Mat img_integral_sugeno_f1 = cv::cvarrToMat(integral_sugeno_f1);
 
-    if(smooth)
+    if (smooth)
       cv::medianBlur(img_integral_sugeno_f1, img_integral_sugeno_f1, 3);
 
     cv::Mat img_foreground_f1(img_input.size(), CV_32F);
     cv::threshold(img_integral_sugeno_f1, img_foreground_f1, threshold, 255, cv::THRESH_BINARY_INV);
 
-    cv::Mat img_foreground_u1(img_input.size(), CV_8U);
+    //cv::Mat img_foreground_u1(img_input.size(), CV_8U);
     double minVal = 0., maxVal = 1.;
-    img_foreground_f1.convertTo(img_foreground_u1, CV_8U, 255.0/(maxVal - minVal), -minVal);
-    img_foreground_u1.copyTo(img_output);
-    
-    cv::Mat img_background_u3(img_input.size(), CV_8U);
+    img_foreground_f1.convertTo(img_foreground, CV_8U, 255.0 / (maxVal - minVal), -minVal);
+    img_foreground.copyTo(img_output);
+
+    //cv::Mat img_background_u3(img_input.size(), CV_8U);
     //double minVal = 0., maxVal = 1.;
-    img_background_f3.convertTo(img_background_u3, CV_8U, 255.0/(maxVal - minVal), -minVal);
-    img_background_u3.copyTo(img_bgmodel);
+    img_background_f3.convertTo(img_background, CV_8U, 255.0 / (maxVal - minVal), -minVal);
+    img_background.copyTo(img_bgmodel);
 
-    if(showOutput)
+#ifndef MEX_COMPILE_FLAG
+    if (showOutput)
     {
       cvShowImage("SI LBP Input", lbp_input_f1);
       cvShowImage("SI LBP Background", lbp_background_f1);
       cvShowImage("SI Prob FG Mask", integral_sugeno_f1);
 
-      cv::imshow("SI BG Model", img_background_f3);
-      cv::imshow("SI FG Mask", img_foreground_u1);
+      cv::imshow("SI BG Model", img_background);
+      cv::imshow("SI FG Mask", img_foreground);
     }
+#endif
 
-    if(frameNumber == (framesToLearn + 1))
+    if (frameNumber == (framesToLearn + 1))
       std::cout << "FuzzySugenoIntegral updating background model by adaptive-selective learning..." << std::endl;
 
     IplImage* updated_background_f3 = cvCreateImage(cvSize(input_f1->width, input_f1->height), IPL_DEPTH_32F, 3);
-    cvFillImage(updated_background_f3, 0.0);
+    cvSetZero(updated_background_f3);
     fu.AdaptativeSelectiveBackgroundModelUpdate(input_f3, background_f3, updated_background_f3, integral_sugeno_f1, threshold, alphaUpdate);
-    cv::Mat img_updated_background_f3(updated_background_f3);
+    cv::Mat img_updated_background_f3 = cv::cvarrToMat(updated_background_f3);
     img_updated_background_f3.copyTo(img_background_f3);
 
     cvReleaseImage(&lbp_input_f1);
@@ -161,7 +170,7 @@ void FuzzySugenoIntegral::process(const cv::Mat &img_input, cv::Mat &img_output,
     cvReleaseImage(&sim_color_f3);
     cvReleaseImage(&integral_sugeno_f1);
     cvReleaseImage(&updated_background_f3);
-    
+
     delete background_f1;
     delete background_f3;
     delete input_f1;
@@ -174,8 +183,8 @@ void FuzzySugenoIntegral::process(const cv::Mat &img_input, cv::Mat &img_output,
 
 void FuzzySugenoIntegral::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/FuzzySugenoIntegral.xml", 0, CV_STORAGE_WRITE);
-  
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
+
   cvWriteInt(fs, "showOutput", showOutput);
   cvWriteInt(fs, "framesToLearn", framesToLearn);
   cvWriteReal(fs, "alphaLearn", alphaLearn);
@@ -184,22 +193,22 @@ void FuzzySugenoIntegral::saveConfig()
   cvWriteInt(fs, "option", option);
   cvWriteInt(fs, "smooth", smooth);
   cvWriteReal(fs, "threshold", threshold);
-  
+
   cvReleaseFileStorage(&fs);
 }
 
 void FuzzySugenoIntegral::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/FuzzySugenoIntegral.xml", 0, CV_STORAGE_READ);
-  
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
-  framesToLearn = cvReadIntByName(fs, 0, "framesToLearn", 10);
-  alphaLearn = cvReadRealByName(fs, 0, "alphaLearn", 0.1);
-  alphaUpdate = cvReadRealByName(fs, 0, "alphaUpdate", 0.01);
-  colorSpace = cvReadIntByName(fs, 0, "colorSpace", 1);
-  option = cvReadIntByName(fs, 0, "option", 2);
-  smooth = cvReadIntByName(fs, 0, "smooth", true);
-  threshold = cvReadRealByName(fs, 0, "threshold", 0.67);
-  
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
+  framesToLearn = cvReadIntByName(fs, nullptr, "framesToLearn", 10);
+  alphaLearn = cvReadRealByName(fs, nullptr, "alphaLearn", 0.1);
+  alphaUpdate = cvReadRealByName(fs, nullptr, "alphaUpdate", 0.01);
+  colorSpace = cvReadIntByName(fs, nullptr, "colorSpace", 1);
+  option = cvReadIntByName(fs, nullptr, "option", 2);
+  smooth = cvReadIntByName(fs, nullptr, "smooth", true);
+  threshold = cvReadRealByName(fs, nullptr, "threshold", 0.67);
+
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/FuzzySugenoIntegral.h b/package_bgs/FuzzySugenoIntegral.h
new file mode 100644
index 0000000000000000000000000000000000000000..70bde1591ea4338b1955edf81e72d4089e1d7342
--- /dev/null
+++ b/package_bgs/FuzzySugenoIntegral.h
@@ -0,0 +1,53 @@
+/*
+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
+
+#include "IBGS.h"
+#include "T2F/FuzzyUtils.h"
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class FuzzySugenoIntegral : public IBGS
+    {
+    private:
+      long long frameNumber;
+
+      int framesToLearn;
+      double alphaLearn;
+      double alphaUpdate;
+      int colorSpace;
+      int option;
+      bool smooth;
+      double threshold;
+
+      FuzzyUtils fu;
+      cv::Mat img_background_f3;
+
+    public:
+      FuzzySugenoIntegral();
+      ~FuzzySugenoIntegral();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/GMG.cpp b/package_bgs/GMG.cpp
index 675b23cba8f3a9f71a35bc99fa66d95c7094b456..19bd8abbbf858a3c9d893e03f7a34dc7f557ebb0 100644
--- a/package_bgs/GMG.cpp
+++ b/package_bgs/GMG.cpp
@@ -16,9 +16,14 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "GMG.h"
 
-GMG::GMG() : firstTime(true), initializationFrames(20), decisionThreshold(0.7), showOutput(true)
+#if CV_MAJOR_VERSION == 2
+
+using namespace bgslibrary::algorithms;
+
+GMG::GMG() : initializationFrames(20), decisionThreshold(0.7)
 {
   std::cout << "GMG()" << std::endl;
+  setup("./config/GMG.xml");
 
   cv::initModule_video();
   cv::setUseOptimized(true);
@@ -34,41 +39,33 @@ GMG::~GMG()
 
 void GMG::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
+  init(img_input, img_output, img_bgmodel);
 
-  loadConfig();
-
-  if(firstTime)
+  if (firstTime)
   {
     fgbg->set("initializationFrames", initializationFrames);
     fgbg->set("decisionThreshold", decisionThreshold);
-
-    saveConfig();
   }
-  
-  if(fgbg.empty())
+
+  if (fgbg.empty())
   {
     std::cerr << "Failed to create BackgroundSubtractor.GMG Algorithm." << std::endl;
     return;
   }
 
   (*fgbg)(img_input, img_foreground);
-
-  cv::Mat img_background;
   (*fgbg).getBackgroundImage(img_background);
 
   img_input.copyTo(img_segmentation);
   cv::add(img_input, cv::Scalar(100, 100, 0), img_segmentation, img_foreground);
 
-  if(showOutput)
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
   {
-    if (!img_foreground.empty())
-      cv::imshow("GMG FG (Godbehere-Matsukawa-Goldberg)", img_foreground);
-    
-    if (!img_background.empty())
-      cv::imshow("GMG BG (Godbehere-Matsukawa-Goldberg)", img_background);
+    cv::imshow("GMG FG (Godbehere-Matsukawa-Goldberg)", img_foreground);
+    cv::imshow("GMG BG (Godbehere-Matsukawa-Goldberg)", img_background);
   }
+#endif
 
   img_foreground.copyTo(img_output);
   img_background.copyTo(img_bgmodel);
@@ -78,7 +75,7 @@ void GMG::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bg
 
 void GMG::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/GMG.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteInt(fs, "initializationFrames", initializationFrames);
   cvWriteReal(fs, "decisionThreshold", decisionThreshold);
@@ -89,11 +86,13 @@ void GMG::saveConfig()
 
 void GMG::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/GMG.xml", 0, CV_STORAGE_READ);
-  
-  initializationFrames = cvReadIntByName(fs, 0, "initializationFrames", 20);
-  decisionThreshold = cvReadRealByName(fs, 0, "decisionThreshold", 0.7);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
-  
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  initializationFrames = cvReadIntByName(fs, nullptr, "initializationFrames", 20);
+  decisionThreshold = cvReadRealByName(fs, nullptr, "decisionThreshold", 0.7);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
+
   cvReleaseFileStorage(&fs);
 }
+
+#endif
diff --git a/package_bgs/GMG.h b/package_bgs/GMG.h
index 9da28adb7a40d2cb443d34372a6e6220c09f3af3..1b4af30b234f954ee80d5fa8554b0e945ba21976 100644
--- a/package_bgs/GMG.h
+++ b/package_bgs/GMG.h
@@ -16,30 +16,34 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
-#include <opencv2/opencv.hpp>
+#include "opencv2/core/version.hpp"
+#if CV_MAJOR_VERSION == 2
 
 #include "IBGS.h"
 
-class GMG : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  cv::Ptr<cv::BackgroundSubtractorGMG> fgbg;
-  int initializationFrames;
-  double decisionThreshold;
-  cv::Mat img_foreground;
-  cv::Mat img_segmentation;
-  bool showOutput;
-
-public:
-  GMG();
-  ~GMG();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
-
+  namespace algorithms
+  {
+    class GMG : public IBGS
+    {
+    private:
+      cv::Ptr<cv::BackgroundSubtractorGMG> fgbg;
+      int initializationFrames;
+      double decisionThreshold;
+      cv::Mat img_segmentation;
+
+    public:
+      GMG();
+      ~GMG();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
+
+#endif
diff --git a/package_bgs/IBGS.h b/package_bgs/IBGS.h
index 073ce185b59734f2e8cfb25ab26051746386a3f0..718bf51ed20d35865d420c46aaa867cd446dcb2d 100644
--- a/package_bgs/IBGS.h
+++ b/package_bgs/IBGS.h
@@ -16,18 +16,59 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
+#include <iostream>
+#include <fstream>
 #include <opencv2/opencv.hpp>
 
-class IBGS
+namespace bgslibrary
 {
-public:
-  virtual void process(const cv::Mat &img_input, cv::Mat &img_foreground, cv::Mat &img_background) = 0;
-  /*virtual void process(const cv::Mat &img_input, cv::Mat &img_foreground){
-    process(img_input, img_foreground, cv::Mat());
-  }*/
-  virtual ~IBGS(){}
+	namespace algorithms
+	{
+		class IBGS
+		{
+		public:
+			void setShowOutput(const bool _showOutput) {
+				showOutput = _showOutput;
+			}
+			cv::Mat apply(const cv::Mat &img_input) {
+				setShowOutput(false);
+				cv::Mat _img_foreground;
+				cv::Mat _img_background;
+				process(img_input, _img_foreground, _img_background);
+        _img_background.copyTo(img_background);
+				return _img_foreground;
+			}
+			cv::Mat getBackgroundModel() {
+				return img_background;
+			}
+			virtual void process(const cv::Mat &img_input, cv::Mat &img_foreground, cv::Mat &img_background) = 0;
+			virtual ~IBGS() {}
 
-private:
-  virtual void saveConfig() = 0;
-  virtual void loadConfig() = 0;
-};
+		protected:
+			bool firstTime = true;
+			bool showOutput = true;
+			cv::Mat img_background;
+			cv::Mat img_foreground;
+			std::string config_xml;
+			void setup(const std::string _config_xml) {
+				config_xml = _config_xml;
+				if (!config_xml.empty()) {
+					if (!std::ifstream(config_xml))
+						saveConfig();
+					loadConfig();
+				}
+			}
+			void init(const cv::Mat &img_input, cv::Mat &img_outfg, cv::Mat &img_outbg) {
+				assert(img_input.empty() == false);
+				//img_outfg = cv::Mat::zeros(img_input.size(), img_input.type());
+				//img_outbg = cv::Mat::zeros(img_input.size(), img_input.type());
+				img_outfg = cv::Mat::zeros(img_input.size(), CV_8UC1);
+				img_outbg = cv::Mat::zeros(img_input.size(), CV_8UC3);
+			}
+
+		private:
+			virtual void saveConfig() = 0;
+			virtual void loadConfig() = 0;
+		};
+	}
+}
diff --git a/package_bgs/db/imbs.cpp b/package_bgs/IMBS/IMBS.cpp
similarity index 74%
rename from package_bgs/db/imbs.cpp
rename to package_bgs/IMBS/IMBS.cpp
index f5fc0d0235e3ad026c2990b04f9ce6c677ca05fd..b1e177b3e806a7e3a4302e9b370494d5b6d9d40a 100644
--- a/package_bgs/db/imbs.cpp
+++ b/package_bgs/IMBS/IMBS.cpp
@@ -1,5 +1,21 @@
 /*
-*  IMBS Background Subtraction Library 
+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/>.
+*/
+/*
+*  IMBS Background Subtraction Library
 *
 *  This file imbs.hpp contains the C++ OpenCV based implementation for
 *  IMBS algorithm described in
@@ -8,8 +24,8 @@
 *  In Proc. of the Third Int. Conf. on Computational Modeling of Objects
 *  Presented in Images: Fundamentals, Methods and Applications, pp. 39-44, 2012.
 *  Please, cite the above paper if you use IMBS.
-*  
-*  This software is provided without any warranty about its usability. 
+*
+*  This software is provided without any warranty about its usability.
 *  It is for educational purposes and should be regarded as such.
 *
 *  Written by Domenico D. Bloisi
@@ -19,7 +35,7 @@
 *
 */
 
-#include "imbs.hpp"
+#include "IMBS.hpp"
 
 using namespace std;
 using namespace cv;
@@ -29,15 +45,15 @@ BackgroundSubtractorIMBS::BackgroundSubtractorIMBS()
   fps = 0.;
   fgThreshold = 15;
   associationThreshold = 5;
-  samplingPeriod = 250.;//500.ms
+  samplingPeriod = 250;//500.ms
   minBinHeight = 2;
   numSamples = 10; //30
   alpha = 0.65f;
   beta = 1.15f;
-  tau_s = 60.;
-  tau_h = 40.;
+  tau_s = 60;
+  tau_h = 40;
   minArea = 30.;
-  persistencePeriod = samplingPeriod*numSamples/3.;//ms
+  persistencePeriod = samplingPeriod*numSamples / 3.;//ms
 
   initial_tick_count = (double)getTickCount();
 
@@ -63,7 +79,7 @@ BackgroundSubtractorIMBS::BackgroundSubtractorIMBS(
   this->fps = fps;
   this->fgThreshold = fgThreshold;
   this->persistencePeriod = persistencePeriod;
-  if(minBinHeight <= 1){
+  if (minBinHeight <= 1) {
     this->minBinHeight = 1;
   }
   else {
@@ -79,7 +95,7 @@ BackgroundSubtractorIMBS::BackgroundSubtractorIMBS(
   this->tau_h = tau_h;
   this->minArea = minArea;
 
-  if(fps == 0.)
+  if (fps == 0.)
     initial_tick_count = (double)getTickCount();
   else
     initial_tick_count = 0;
@@ -106,7 +122,7 @@ void BackgroundSubtractorIMBS::initialize(Size frameSize, int frameType)
   this->numPixels = frameSize.width*frameSize.height;
 
   persistenceMap = new unsigned int[numPixels];
-  for(unsigned int i = 0; i < numPixels; i++) {
+  for (unsigned int i = 0; i < numPixels; i++) {
     persistenceMap[i] = 0;
   }
 
@@ -134,20 +150,20 @@ void BackgroundSubtractorIMBS::initialize(Size frameSize, int frameType)
 
   //initial message to be shown until the first fg mask is computed
   initialMsgGray = Mat::zeros(frameSize, CV_8UC1);
-  putText(initialMsgGray, "Creating", Point(10,20), FONT_HERSHEY_SIMPLEX, 0.4, CV_RGB(255, 255, 255));
-  putText(initialMsgGray, "initial", Point(10,40), FONT_HERSHEY_SIMPLEX, 0.4, CV_RGB(255, 255, 255));
-  putText(initialMsgGray, "background...", Point(10,60), FONT_HERSHEY_SIMPLEX, 0.4, CV_RGB(255, 255, 255));
+  putText(initialMsgGray, "Creating", Point(10, 20), FONT_HERSHEY_SIMPLEX, 0.4, CV_RGB(255, 255, 255));
+  putText(initialMsgGray, "initial", Point(10, 40), FONT_HERSHEY_SIMPLEX, 0.4, CV_RGB(255, 255, 255));
+  putText(initialMsgGray, "background...", Point(10, 60), FONT_HERSHEY_SIMPLEX, 0.4, CV_RGB(255, 255, 255));
 
   initialMsgRGB = Mat::zeros(frameSize, CV_8UC3);
-  putText(initialMsgRGB, "Creating", Point(10,20), FONT_HERSHEY_SIMPLEX, 0.4, CV_RGB(255, 255, 255));
-  putText(initialMsgRGB, "initial", Point(10,40), FONT_HERSHEY_SIMPLEX, 0.4, CV_RGB(255, 255, 255));
-  putText(initialMsgRGB, "background...", Point(10,60), FONT_HERSHEY_SIMPLEX, 0.4, CV_RGB(255, 255, 255));
+  putText(initialMsgRGB, "Creating", Point(10, 20), FONT_HERSHEY_SIMPLEX, 0.4, CV_RGB(255, 255, 255));
+  putText(initialMsgRGB, "initial", Point(10, 40), FONT_HERSHEY_SIMPLEX, 0.4, CV_RGB(255, 255, 255));
+  putText(initialMsgRGB, "background...", Point(10, 60), FONT_HERSHEY_SIMPLEX, 0.4, CV_RGB(255, 255, 255));
 
-  if(minBinHeight <= 1){
+  if (minBinHeight <= 1) {
     minBinHeight = 1;
   }
 
-  for(unsigned int p = 0; p < numPixels; ++p)
+  for (unsigned int p = 0; p < numPixels; ++p)
   {
     bgBins[p].binValues = new Vec3b[numSamples];
     bgBins[p].binHeights = new uchar[numSamples];
@@ -169,7 +185,7 @@ void BackgroundSubtractorIMBS::apply(InputArray _frame, OutputArray _fgmask, dou
   CV_Assert(frame.channels() == 3);
 
   bool needToInitialize = nframes == 0 || frame.type() != frameType;
-  if( needToInitialize ) {
+  if (needToInitialize) {
     initialize(frame.size(), frame.type());
   }
 
@@ -179,29 +195,29 @@ void BackgroundSubtractorIMBS::apply(InputArray _frame, OutputArray _fgmask, dou
 
   //get current time
   prev_timestamp = timestamp;
-  if(fps == 0.) {
+  if (fps == 0.) {
     timestamp = getTimestamp();//ms
   }
   else {
-    timestamp += 1000./fps;//ms
+    timestamp += 1000. / fps;//ms
   }
 
   //check for global changes
-  if(sudden_change) {
+  if (sudden_change) {
     changeBg();
   }
 
   //wait for the first model to be generated
-  if(bgModel[0].isValid[0]) {
-    getFg();    	
+  if (bgModel[0].isValid[0]) {
+    getFg();
     hsvSuppression();
     filterFg();
-  }	
+  }
   //update the bg model
   updateBg();
 
   //show an initial message if the first bg is not yet ready
-  if(!bgModel[0].isValid[0]) {
+  if (!bgModel[0].isValid[0]) {
     initialMsgGray.copyTo(fgmask);
     initialMsgRGB.copyTo(bgImage);
   }
@@ -209,23 +225,23 @@ void BackgroundSubtractorIMBS::apply(InputArray _frame, OutputArray _fgmask, dou
 }
 
 void BackgroundSubtractorIMBS::updateBg() {
-  if(bg_reset) {
-    if(bg_frame_counter > numSamples - 1) {
+  if (bg_reset) {
+    if (bg_frame_counter > numSamples - 1) {
       bg_frame_counter = numSamples - 1;
     }
   }
 
-  if(prev_bg_frame_time > timestamp) {
+  if (prev_bg_frame_time > timestamp) {
     prev_bg_frame_time = timestamp;
   }
 
-  if(bg_frame_counter == numSamples - 1) {
+  if (bg_frame_counter == numSamples - 1) {
     createBg(bg_frame_counter);
     bg_frame_counter = 0;
   }
   else { //bg_frame_counter < (numSamples - 1)
 
-    if((timestamp - prev_bg_frame_time) >= samplingPeriod)
+    if ((timestamp - prev_bg_frame_time) >= samplingPeriod)
     {
       //get a new sample for creating the bg model
       prev_bg_frame_time = timestamp;
@@ -237,7 +253,7 @@ void BackgroundSubtractorIMBS::updateBg() {
 }
 
 double BackgroundSubtractorIMBS::getTimestamp() {
-  return ((double)getTickCount() - initial_tick_count)*1000./getTickFrequency();
+  return ((double)getTickCount() - initial_tick_count)*1000. / getTickFrequency();
 }
 
 void BackgroundSubtractorIMBS::hsvSuppression() {
@@ -251,35 +267,35 @@ void BackgroundSubtractorIMBS::hsvSuppression() {
   vector<Mat> imHSV;
   cv::split(convertImageRGBtoHSV(frame), imHSV);
 
-  for(unsigned int p = 0; p < numPixels; ++p) {
-    if(fgmask.data[p]) {
+  for (unsigned int p = 0; p < numPixels; ++p) {
+    if (fgmask.data[p]) {
 
       h_i = imHSV[0].data[p];
       s_i = imHSV[1].data[p];
       v_i = imHSV[2].data[p];
 
-      for(unsigned int n = 0; n < maxBgBins; ++n) {
-        if(!bgModel[p].isValid[n]) {
+      for (unsigned int n = 0; n < maxBgBins; ++n) {
+        if (!bgModel[p].isValid[n]) {
           break;
         }
 
-        if(bgModel[p].isFg[n]) {
+        if (bgModel[p].isFg[n]) {
           continue;
         }
 
-        bgrPixel.at<cv::Vec3b>(0,0) = bgModel[p].values[n];
+        bgrPixel.at<cv::Vec3b>(0, 0) = bgModel[p].values[n];
 
         cv::Mat hsvPixel = convertImageRGBtoHSV(bgrPixel);
 
-        h_b = hsvPixel.at<cv::Vec3b>(0,0)[0];
-        s_b = hsvPixel.at<cv::Vec3b>(0,0)[1];
-        v_b = hsvPixel.at<cv::Vec3b>(0,0)[2];
+        h_b = hsvPixel.at<cv::Vec3b>(0, 0)[0];
+        s_b = hsvPixel.at<cv::Vec3b>(0, 0)[1];
+        v_b = hsvPixel.at<cv::Vec3b>(0, 0)[2];
 
         v_ratio = (float)v_i / (float)v_b;
         s_diff = std::abs(s_i - s_b);
-        h_diff = std::min( std::abs(h_i - h_b), 255 - std::abs(h_i - h_b));
+        h_diff = std::min(std::abs(h_i - h_b), 255 - std::abs(h_i - h_b));
 
-        if(	h_diff <= tau_h &&
+        if (h_diff <= tau_h &&
           s_diff <= tau_s &&
           v_ratio >= alpha &&
           v_ratio < beta)
@@ -293,7 +309,7 @@ void BackgroundSubtractorIMBS::hsvSuppression() {
 }
 
 void BackgroundSubtractorIMBS::createBg(unsigned int bg_sample_number) {
-  if(!bgSample.data) {
+  if (!bgSample.data) {
     //cerr << "createBg -- an error occurred: " <<
     //		" unable to retrieve frame no. " << bg_sample_number << endl;
 
@@ -305,18 +321,18 @@ void BackgroundSubtractorIMBS::createBg(unsigned int bg_sample_number) {
   //split bgSample in channels
   cv::split(bgSample, bgSampleBGR);
   //create a statistical model for each pixel (a set of bins of variable size)
-  for(unsigned int p = 0; p < numPixels; ++p) {
+  for (unsigned int p = 0; p < numPixels; ++p) {
     //create an initial bin for each pixel from the first sample (bg_sample_number = 0)
-    if(bg_sample_number == 0) {
-      for(int k = 0; k < 3; ++k) {
+    if (bg_sample_number == 0) {
+      for (int k = 0; k < 3; ++k) {
         bgBins[p].binValues[0][k] = bgSampleBGR[k].data[p];
       }
       bgBins[p].binHeights[0] = 1;
-      for(unsigned int s = 1; s < numSamples; ++s)	{
+      for (unsigned int s = 1; s < numSamples; ++s) {
         bgBins[p].binHeights[s] = 0;
       }
       //if the sample pixel is from foreground keep track of that situation
-      if(fgmask.data[p] == FOREGROUND_LABEL) {
+      if (fgmask.data[p] == FOREGROUND_LABEL) {
         bgBins[p].isFg[0] = true;
       }
       else {
@@ -324,32 +340,32 @@ void BackgroundSubtractorIMBS::createBg(unsigned int bg_sample_number) {
       }
     }//if(bg_sample_number == 0)
     else { //bg_sample_number > 0
-      for(int k = 0; k < 3; ++k) {
+      for (int k = 0; k < 3; ++k) {
         currentPixel[k] = bgSampleBGR[k].data[p];
       }
       int den = 0;
-      for(unsigned int s = 0; s < bg_sample_number; ++s) {
+      for (unsigned int s = 0; s < bg_sample_number; ++s) {
         //try to associate the current pixel values to an existing bin
-        if( std::abs(currentPixel[2] - bgBins[p].binValues[s][2]) <= associationThreshold &&
+        if (std::abs(currentPixel[2] - bgBins[p].binValues[s][2]) <= associationThreshold &&
           std::abs(currentPixel[1] - bgBins[p].binValues[s][1]) <= associationThreshold &&
-          std::abs(currentPixel[0] - bgBins[p].binValues[s][0]) <= associationThreshold )
+          std::abs(currentPixel[0] - bgBins[p].binValues[s][0]) <= associationThreshold)
         {
           den = (bgBins[p].binHeights[s] + 1);
-          for(int k = 0; k < 3; ++k) {
+          for (int k = 0; k < 3; ++k) {
             bgBins[p].binValues[s][k] =
               (bgBins[p].binValues[s][k] * bgBins[p].binHeights[s] + currentPixel[k]) / den;
           }
           bgBins[p].binHeights[s]++; //increment the height of the bin
-          if(fgmask.data[p] == FOREGROUND_LABEL) {
+          if (fgmask.data[p] == FOREGROUND_LABEL) {
             bgBins[p].isFg[s] = true;
           }
           break;
         }
         //if the association is not possible, create a new bin
-        else if(bgBins[p].binHeights[s] == 0)	{
+        else if (bgBins[p].binHeights[s] == 0) {
           bgBins[p].binValues[s] = currentPixel;
           bgBins[p].binHeights[s]++;
-          if(fgmask.data[p] == FOREGROUND_LABEL) {
+          if (fgmask.data[p] == FOREGROUND_LABEL) {
             bgBins[p].isFg[s] = true;
           }
           else {
@@ -362,44 +378,44 @@ void BackgroundSubtractorIMBS::createBg(unsigned int bg_sample_number) {
 
       //if all samples have been processed
       //it is time to compute the fg mask
-      if(bg_sample_number == (numSamples - 1)) {
+      if (bg_sample_number == (numSamples - 1)) {
         unsigned int index = 0;
         int max_height = -1;
-        for(unsigned int s = 0; s < numSamples; ++s){
-          if(bgBins[p].binHeights[s] == 0) {
+        for (unsigned int s = 0; s < numSamples; ++s) {
+          if (bgBins[p].binHeights[s] == 0) {
             bgModel[p].isValid[index] = false;
             break;
           }
-          if(index == maxBgBins) {
+          if (index == maxBgBins) {
             break;
           }
-          else if(bgBins[p].binHeights[s] >= minBinHeight) {
-            if(fgmask.data[p] == PERSISTENCE_LABEL) {
-              for(unsigned int n = 0; n < maxBgBins; n++) {
-                if(!bgModel[p].isValid[n]) {
+          else if (bgBins[p].binHeights[s] >= minBinHeight) {
+            if (fgmask.data[p] == PERSISTENCE_LABEL) {
+              for (unsigned int n = 0; n < maxBgBins; n++) {
+                if (!bgModel[p].isValid[n]) {
                   break;
                 }
                 unsigned int d = std::max((int)std::abs(bgModel[p].values[n][0] - bgBins[p].binValues[s][0]),
-                  std::abs(bgModel[p].values[n][1] - bgBins[p].binValues[s][1]) );
-                d = std::max((int)d, std::abs(bgModel[p].values[n][2] - bgBins[p].binValues[s][2]) );
-                if(d < fgThreshold){
+                  std::abs(bgModel[p].values[n][1] - bgBins[p].binValues[s][1]));
+                d = std::max((int)d, std::abs(bgModel[p].values[n][2] - bgBins[p].binValues[s][2]));
+                if (d < fgThreshold) {
                   bgModel[p].isFg[n] = false;
                   bgBins[p].isFg[s] = false;
                 }
               }
             }
 
-            if(bgBins[p].binHeights[s] > max_height) {
+            if (bgBins[p].binHeights[s] > max_height) {
               max_height = bgBins[p].binHeights[s];
 
-              for(int k = 0; k < 3; ++k) {
+              for (int k = 0; k < 3; ++k) {
                 bgModel[p].values[index][k] = bgModel[p].values[0][k];
               }
               bgModel[p].isValid[index] = true;
               bgModel[p].isFg[index] = bgModel[p].isFg[0];
               bgModel[p].counter[index] = bgModel[p].counter[0];
 
-              for(int k = 0; k < 3; ++k) {
+              for (int k = 0; k < 3; ++k) {
                 bgModel[p].values[0][k] = bgBins[p].binValues[s][k];
               }
               bgModel[p].isValid[0] = true;
@@ -407,7 +423,7 @@ void BackgroundSubtractorIMBS::createBg(unsigned int bg_sample_number) {
               bgModel[p].counter[0] = bgBins[p].binHeights[s];
             }
             else {
-              for(int k = 0; k < 3; ++k) {
+              for (int k = 0; k < 3; ++k) {
                 bgModel[p].values[index][k] = bgBins[p].binValues[s][k];
               }
               bgModel[p].isValid[index] = true;
@@ -421,25 +437,25 @@ void BackgroundSubtractorIMBS::createBg(unsigned int bg_sample_number) {
     }//else --> if(frame_number == 0)
   }//numPixels
 
-  if(bg_sample_number == (numSamples - 1)) {
-    //std::cout << "new bg created" << std::endl;		
+  if (bg_sample_number == (numSamples - 1)) {
+    //std::cout << "new bg created" << std::endl;
     persistenceImage = Scalar(0);
 
     bg_reset = false;
-    if(sudden_change) {
+    if (sudden_change) {
       numSamples *= 3.;
       samplingPeriod *= 2.;
       sudden_change = false;
     }
 
-    for(unsigned int i = 0; i < numPixels; i++) {
+    for (unsigned int i = 0; i < numPixels; i++) {
       persistenceMap[i] = 0;
     }
 
     unsigned int p = 0;
-    for(int i = 0; i < bgImage.rows; ++i) {
-      for(int j = 0; j < bgImage.cols; ++j, ++p) {
-        bgImage.at<cv::Vec3b>(i,j) = bgModel[p].values[0];
+    for (int i = 0; i < bgImage.rows; ++i) {
+      for (int j = 0; j < bgImage.cols; ++j, ++p) {
+        bgImage.at<cv::Vec3b>(i, j) = bgModel[p].values[0];
       }
     }
   }
@@ -452,13 +468,13 @@ void BackgroundSubtractorIMBS::getFg() {
   bool isFg = true;
   bool conditionalUpdated = false;
   unsigned int d = 0;
-  for(unsigned int p = 0; p < numPixels; ++p) {
+  for (unsigned int p = 0; p < numPixels; ++p) {
     isFg = true;
     conditionalUpdated = false;
     d = 0;
-    for(unsigned int n = 0; n < maxBgBins; ++n) {
-      if(!bgModel[p].isValid[n]) {
-        if(n == 0) {
+    for (unsigned int n = 0; n < maxBgBins; ++n) {
+      if (!bgModel[p].isValid[n]) {
+        if (n == 0) {
           isFg = false;
         }
         break;
@@ -466,13 +482,13 @@ void BackgroundSubtractorIMBS::getFg() {
       else { //the model is valid
         d = std::max(
           (int)std::abs(bgModel[p].values[n][0] - frameBGR[0].data[p]),
-          std::abs(bgModel[p].values[n][1] - frameBGR[1].data[p]) );
+          std::abs(bgModel[p].values[n][1] - frameBGR[1].data[p]));
         d = std::max(
-          (int)d, std::abs(bgModel[p].values[n][2] - frameBGR[2].data[p]) );
-        if(d < fgThreshold){
+          (int)d, std::abs(bgModel[p].values[n][2] - frameBGR[2].data[p]));
+        if (d < fgThreshold) {
           //check if it is a potential background pixel
           //from stationary object
-          if(bgModel[p].isFg[n]) {
+          if (bgModel[p].isFg[n]) {
             conditionalUpdated = true;
             break;
           }
@@ -483,13 +499,13 @@ void BackgroundSubtractorIMBS::getFg() {
         }
       }
     }
-    if(isFg) {
-      if(conditionalUpdated) {
+    if (isFg) {
+      if (conditionalUpdated) {
         fgmask.data[p] = PERSISTENCE_LABEL;
         persistenceMap[p] += (timestamp - prev_timestamp);
-        if(persistenceMap[p] > persistencePeriod) {
-          for(unsigned int n = 0; n < maxBgBins; ++n) {
-            if(!bgModel[p].isValid[n]) {
+        if (persistenceMap[p] > persistencePeriod) {
+          for (unsigned int n = 0; n < maxBgBins; ++n) {
+            if (!bgModel[p].isValid[n]) {
               break;
             }
             bgModel[p].isFg[n] = false;
@@ -521,13 +537,13 @@ void BackgroundSubtractorIMBS::areaThresholding()
     if (area < minArea || area >= maxArea)
       continue;
     else {
-      drawContours( tmpBinaryImage, contours, contourIdx, Scalar(255), CV_FILLED );
+      drawContours(tmpBinaryImage, contours, contourIdx, Scalar(255), CV_FILLED);
     }
-  }	
-  for(int i = 0; i < fgfiltered.rows; ++i) {
-    for(int j = 0; j < fgfiltered.cols; ++j) {
-      if(!tmpBinaryImage.at<uchar>(i,j)) {
-        fgfiltered.at<uchar>(i,j) = 0;
+  }
+  for (int i = 0; i < fgfiltered.rows; ++i) {
+    for (int j = 0; j < fgfiltered.cols; ++j) {
+      if (!tmpBinaryImage.at<uchar>(i, j)) {
+        fgfiltered.at<uchar>(i, j) = 0;
       }
     }
   }
@@ -560,9 +576,9 @@ Mat BackgroundSubtractorIMBS::convertImageRGBtoHSV(const Mat& imageRGB)
     for (int x = 0; x < w; ++x) {
       // Get the RGB pixel components. NOTE that OpenCV stores RGB pixels in B,G,R order.
       //uchar *pRGB = (uchar*)(imRGB + y*rowSizeRGB + x*3);
-      int bB = imageRGB.at<Vec3b>(y,x)[0]; //*(uchar*)(pRGB+0);	// Blue component
-      int bG = imageRGB.at<Vec3b>(y,x)[1]; //*(uchar*)(pRGB+1);	// Green component
-      int bR = imageRGB.at<Vec3b>(y,x)[2]; //*(uchar*)(pRGB+2);	// Red component
+      int bB = imageRGB.at<Vec3b>(y, x)[0]; //*(uchar*)(pRGB+0);	// Blue component
+      int bG = imageRGB.at<Vec3b>(y, x)[1]; //*(uchar*)(pRGB+1);	// Green component
+      int bR = imageRGB.at<Vec3b>(y, x)[2]; //*(uchar*)(pRGB+2);	// Red component
 
       // Convert from 8-bit integers to floats.
       fR = bR * BYTE_TO_FLOAT;
@@ -619,10 +635,10 @@ Mat BackgroundSubtractorIMBS::convertImageRGBtoHSV(const Mat& imageRGB)
           fH = (fG - fB) * ANGLE_TO_UNIT;
         }
         else if (iMax == bG) {		// between cyan and yellow.
-          fH = (2.0f/6.0f) + ( fB - fR ) * ANGLE_TO_UNIT;
+          fH = (2.0f / 6.0f) + (fB - fR) * ANGLE_TO_UNIT;
         }
         else {				// between magenta and cyan.
-          fH = (4.0f/6.0f) + ( fR - fG ) * ANGLE_TO_UNIT;
+          fH = (4.0f / 6.0f) + (fR - fG) * ANGLE_TO_UNIT;
         }
         // Wrap outlier Hues around the circle.
         if (fH < 0.0f)
@@ -666,14 +682,14 @@ Mat BackgroundSubtractorIMBS::convertImageRGBtoHSV(const Mat& imageRGB)
 
 void BackgroundSubtractorIMBS::getBackgroundImage(OutputArray backgroundImage) const
 {
-  bgImage.copyTo(backgroundImage);        
+  bgImage.copyTo(backgroundImage);
 }
 
 void BackgroundSubtractorIMBS::filterFg() {
 
   unsigned int cnt = 0;
-  for(unsigned int p = 0; p < numPixels; ++p) {
-    if(fgmask.data[p] == (uchar)255) {
+  for (unsigned int p = 0; p < numPixels; ++p) {
+    if (fgmask.data[p] == (uchar)255) {
       fgfiltered.data[p] = 255;
       cnt++;
     }
@@ -682,23 +698,23 @@ void BackgroundSubtractorIMBS::filterFg() {
     }
   }
 
-  if(cnt > numPixels*0.5) {
+  if (cnt > numPixels*0.5) {
     sudden_change = true;
   }
 
-  if(morphologicalFiltering) {
-    cv::Mat element3(3,3,CV_8U,cv::Scalar(1));
+  if (morphologicalFiltering) {
+    cv::Mat element3(3, 3, CV_8U, cv::Scalar(1));
     cv::morphologyEx(fgfiltered, fgfiltered, cv::MORPH_OPEN, element3);
     cv::morphologyEx(fgfiltered, fgfiltered, cv::MORPH_CLOSE, element3);
   }
 
   areaThresholding();
 
-  for(unsigned int p = 0; p < numPixels; ++p) {
-    if(fgmask.data[p] == PERSISTENCE_LABEL) {
+  for (unsigned int p = 0; p < numPixels; ++p) {
+    if (fgmask.data[p] == PERSISTENCE_LABEL) {
       fgfiltered.data[p] = PERSISTENCE_LABEL;
     }
-    else if(fgmask.data[p] == SHADOW_LABEL) {
+    else if (fgmask.data[p] == SHADOW_LABEL) {
       fgfiltered.data[p] = SHADOW_LABEL;
     }
   }
@@ -715,7 +731,7 @@ void BackgroundSubtractorIMBS::changeBg() {
   //bg_reset = true;
   //cout << "qua" << endl;
 
-  if(!bg_reset) {
+  if (!bg_reset) {
     numSamples /= 3.;
     samplingPeriod /= 2.;
     bg_frame_counter = 0;
@@ -724,19 +740,19 @@ void BackgroundSubtractorIMBS::changeBg() {
 }
 
 void BackgroundSubtractorIMBS::getBgModel(BgModel bgModel_copy[], int size) {
-  if(size != numPixels) {
+  if (size != numPixels) {
     return;
   }
-  for(unsigned int i = 0; i < numPixels; ++i){
+  for (unsigned int i = 0; i < numPixels; ++i) {
     bgModel_copy[i].values = new Vec3b[maxBgBins];
     bgModel_copy[i].isValid = new bool[maxBgBins];
     bgModel_copy[i].isValid[0] = false;
     bgModel_copy[i].isFg = new bool[maxBgBins];
     bgModel_copy[i].counter = new uchar[maxBgBins];
   }
-  for(unsigned int p = 0; p < numPixels; ++p) {
-    for(unsigned int n = 0; n < maxBgBins; ++n) {
-      if(!bgModel[p].isValid[n]) {
+  for (unsigned int p = 0; p < numPixels; ++p) {
+    for (unsigned int n = 0; n < maxBgBins; ++n) {
+      if (!bgModel[p].isValid[n]) {
         break;
       }
       bgModel_copy[p].values[n] = bgModel[p].values[n];
diff --git a/package_bgs/db/imbs.hpp b/package_bgs/IMBS/IMBS.hpp
similarity index 77%
rename from package_bgs/db/imbs.hpp
rename to package_bgs/IMBS/IMBS.hpp
index fd7faf17ce44bb26a5345984b5768df1a6bf8072..383e0ae27bdfc4b3a15dc703331b943f06d4c47f 100644
--- a/package_bgs/db/imbs.hpp
+++ b/package_bgs/IMBS/IMBS.hpp
@@ -1,5 +1,21 @@
 /*
-*  IMBS Background Subtraction Library 
+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/>.
+*/
+/*
+*  IMBS Background Subtraction Library
 *
 *  This file imbs.hpp contains the C++ OpenCV based implementation for
 *  IMBS algorithm described in
@@ -8,8 +24,8 @@
 *  In Proc. of the Third Int. Conf. on Computational Modeling of Objects
 *  Presented in Images: Fundamentals, Methods and Applications, pp. 39-44, 2012.
 *  Please, cite the above paper if you use IMBS.
-*  
-*  This software is provided without any warranty about its usability. 
+*
+*  This software is provided without any warranty about its usability.
 *  It is for educational purposes and should be regarded as such.
 *
 *  Written by Domenico D. Bloisi
@@ -18,9 +34,7 @@
 *  domenico.bloisi@gmail.com
 *
 */
-
-#ifndef __IMBS_HPP__
-#define __IMBS_HPP__
+#pragma once
 
 //OPENCV
 #include <opencv2/core/core.hpp>
@@ -41,23 +55,23 @@ public:
   BackgroundSubtractorIMBS();
   //! the full constructor
   BackgroundSubtractorIMBS(double fps,
-    unsigned int fgThreshold=15,
-    unsigned int associationThreshold=5,
-    double samplingPeriod=500.,
-    unsigned int minBinHeight=2,
-    unsigned int numSamples=30,
-    double alpha=0.65,
-    double beta=1.15,
-    double tau_s=60.,
-    double tau_h=40.,
-    double minArea=30.,
-    double persistencePeriod=10000.,
-    bool morphologicalFiltering=false
-    );
+    unsigned int fgThreshold = 15,
+    unsigned int associationThreshold = 5,
+    double samplingPeriod = 500.,
+    unsigned int minBinHeight = 2,
+    unsigned int numSamples = 30,
+    double alpha = 0.65,
+    double beta = 1.15,
+    double tau_s = 60.,
+    double tau_h = 40.,
+    double minArea = 30.,
+    double persistencePeriod = 10000.,
+    bool morphologicalFiltering = false
+  );
   //! the destructor
   ~BackgroundSubtractorIMBS();
   //! the update operator
-  void apply(InputArray image, OutputArray fgmask, double learningRate=-1.);
+  void apply(InputArray image, OutputArray fgmask, double learningRate = -1.);
 
   //! computes a background image which shows only the highest bin for each pixel
   void getBackgroundImage(OutputArray backgroundImage) const;
@@ -73,7 +87,7 @@ private:
   //method for computing the foreground mask
   void getFg();
   //method for suppressing shadows and highlights
-  void hsvSuppression();    
+  void hsvSuppression();
   //method for refining foreground mask
   void filterFg();
   //method for filtering out blobs smaller than a given area
@@ -82,7 +96,7 @@ private:
   double getTimestamp();
   //method for converting from RGB to HSV
   Mat convertImageRGBtoHSV(const Mat& imageRGB);
-  //method for changing the bg in case of sudden changes 
+  //method for changing the bg in case of sudden changes
   void changeBg();
 
   //current input RGB frame
@@ -112,7 +126,7 @@ private:
   //previous time stamp in milliseconds (ms)
   double prev_timestamp;
   double initial_tick_count;
-  //initial message to be shown until the first bg model is ready 
+  //initial message to be shown until the first bg model is ready
   Mat initialMsgGray;
   Mat initialMsgRGB;
 
@@ -174,5 +188,3 @@ public:
   }
   void getBgModel(BgModel bgModel_copy[], int size);
 };
-
-#endif //__IMBS_HPP__
diff --git a/package_bgs/IndependentMultimodal.cpp b/package_bgs/IndependentMultimodal.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7b4de4cc06f06b84a7d8d72050cbccf497b0ca9a
--- /dev/null
+++ b/package_bgs/IndependentMultimodal.cpp
@@ -0,0 +1,74 @@
+/*
+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 "IndependentMultimodal.h"
+
+using namespace bgslibrary::algorithms;
+
+IndependentMultimodal::IndependentMultimodal() : fps(10)
+{
+  std::cout << "IndependentMultimodal()" << std::endl;
+  pIMBS = new BackgroundSubtractorIMBS(fps);
+  setup("./config/IndependentMultimodal.xml");
+}
+
+IndependentMultimodal::~IndependentMultimodal()
+{
+  std::cout << "~IndependentMultimodal()" << std::endl;
+  delete pIMBS;
+}
+
+void IndependentMultimodal::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+{
+  init(img_input, img_output, img_bgmodel);
+
+  //get the fgmask and update the background model
+  pIMBS->apply(img_input, img_foreground);
+
+  //get background image
+  pIMBS->getBackgroundImage(img_background);
+
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+  {
+    cv::imshow("IMBS FG", img_foreground);
+    cv::imshow("IMBS BG", img_background);
+  }
+#endif
+
+  firstTime = false;
+}
+
+void IndependentMultimodal::saveConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
+
+  cvWriteInt(fs, "showOutput", showOutput);
+
+  cvReleaseFileStorage(&fs);
+}
+
+void IndependentMultimodal::loadConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
+
+  cvReleaseFileStorage(&fs);
+}
diff --git a/package_bgs/StaticFrameDifferenceBGS.h b/package_bgs/IndependentMultimodal.h
similarity index 60%
rename from package_bgs/StaticFrameDifferenceBGS.h
rename to package_bgs/IndependentMultimodal.h
index 55f7bf1e360419c1dd7bfce6f19facae07fd7431..4e2e3a38e4e71bf65e729e91f3c27717e07e48eb 100644
--- a/package_bgs/StaticFrameDifferenceBGS.h
+++ b/package_bgs/IndependentMultimodal.h
@@ -16,30 +16,28 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
 #include "IBGS.h"
+#include "IMBS/IMBS.hpp"
 
-class StaticFrameDifferenceBGS : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  cv::Mat img_background;
-  cv::Mat img_foreground;
-  bool enableThreshold;
-  int threshold;
-  bool showOutput;
-
-public:
-  StaticFrameDifferenceBGS();
-  ~StaticFrameDifferenceBGS();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
-
+  namespace algorithms
+  {
+    class IndependentMultimodal : public IBGS
+    {
+    private:
+      BackgroundSubtractorIMBS* pIMBS;
+      int fps;
+
+    public:
+      IndependentMultimodal();
+      ~IndependentMultimodal();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/ae/KDE.cpp b/package_bgs/KDE.cpp
similarity index 56%
rename from package_bgs/ae/KDE.cpp
rename to package_bgs/KDE.cpp
index 2cbbd8c808066f8a6c30c7dc31f6ed90068caa84..28564a0c4be11c2d76c89082e2198f6ca2bedeca 100644
--- a/package_bgs/ae/KDE.cpp
+++ b/package_bgs/KDE.cpp
@@ -16,11 +16,15 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "KDE.h"
 
-KDE::KDE() : SequenceLength(50), TimeWindowSize(100), SDEstimationFlag(1), lUseColorRatiosFlag(1),
-  th(10e-8), alpha(0.3), framesToLearn(10), frameNumber(0), firstTime(true), showOutput(true)
+using namespace bgslibrary::algorithms;
+
+KDE::KDE() :
+  SequenceLength(50), TimeWindowSize(100), SDEstimationFlag(1), lUseColorRatiosFlag(1),
+  th(10e-8), alpha(0.3), framesToLearn(10), frameNumber(0)
 {
   p = new NPBGSubtractor;
   std::cout << "KDE()" << std::endl;
+  setup("./config/KDE.xml");
 }
 
 KDE::~KDE()
@@ -32,72 +36,73 @@ KDE::~KDE()
 
 void KDE::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-
-  loadConfig();
+  init(img_input, img_output, img_bgmodel);
 
-  if(firstTime)
+  if (firstTime)
   {
     rows = img_input.size().height;
     cols = img_input.size().width;
     color_channels = img_input.channels();
 
     // SequenceLength: number of samples for each pixel.
-    // TimeWindowSize: Time window for sampling. for example in the call above, the bg will sample 50 points out of 100 frames. 
+    // TimeWindowSize: Time window for sampling. for example in the call above, the bg will sample 50 points out of 100 frames.
     // this rate will affect how fast the model adapt.
     // SDEstimationFlag: True means to estimate suitable kernel bandwidth to each pixel, False uses a default value.
     // lUseColorRatiosFlag: True means use normalized RGB for color (recommended.)
-    p->Intialize(rows,cols,color_channels,SequenceLength,TimeWindowSize,SDEstimationFlag,lUseColorRatiosFlag);
+    p->Intialize(rows, cols, color_channels, SequenceLength, TimeWindowSize, SDEstimationFlag, lUseColorRatiosFlag);
     // th: 0-1 is the probability threshold for a pixel to be a foregroud. typically make it small as 10e-8. the smaller the value the less false positive and more false negative.
     // alpha: 0-1, for color. typically set to 0.3. this affect shadow suppression.
-    p->SetThresholds(th,alpha);
+    p->SetThresholds(th, alpha);
 
     FGImage = new unsigned char[rows*cols];
     //FilteredFGImage = new unsigned char[rows*cols];
     FilteredFGImage = 0;
     DisplayBuffers = 0;
 
-    img_foreground = cv::Mat::zeros(rows,cols,CV_8UC1);
+    img_foreground = cv::Mat::zeros(img_input.size(), CV_8UC1);
+    img_background = cv::Mat::zeros(img_input.size(), img_input.type());
 
     frameNumber = 0;
-    saveConfig();
     firstTime = false;
   }
 
   // Stores the first N frames to build the background model
-  if(frameNumber < framesToLearn)
+  if (frameNumber < framesToLearn)
   {
     p->AddFrame(img_input.data);
     frameNumber++;
-    return;
   }
-
-  // Build the background model with first 10 frames
-  if(frameNumber == framesToLearn)
+  else
   {
-    p->Estimation();
-    frameNumber++;
-  }
+    // Build the background model with first 10 frames
+    if (frameNumber == framesToLearn)
+    {
+      p->Estimation();
+      frameNumber++;
+    }
+
+    // Now, we can subtract the background
+    ((NPBGSubtractor*)p)->NBBGSubtraction(img_input.data, FGImage, FilteredFGImage, DisplayBuffers);
 
-  // Now, we can subtract the background
-  ((NPBGSubtractor *)p)->NBBGSubtraction(img_input.data,FGImage,FilteredFGImage,DisplayBuffers);
-  
-  // At each frame also you can call the update function to adapt the bg
-  // here you pass a mask where pixels with true value will be masked out of the update.
-  ((NPBGSubtractor *)p)->Update(FGImage);
+    // At each frame also you can call the update function to adapt the bg
+    // here you pass a mask where pixels with true value will be masked out of the update.
+    ((NPBGSubtractor*)p)->Update(FGImage);
 
-  img_foreground.data = FGImage;
+    img_foreground.data = FGImage;
+  }
 
-  if(showOutput)
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
     cv::imshow("KDE", img_foreground);
+#endif
 
   img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
 }
 
 void KDE::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/KDE.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteInt(fs, "framesToLearn", framesToLearn);
   cvWriteInt(fs, "SequenceLength", SequenceLength);
@@ -113,16 +118,16 @@ void KDE::saveConfig()
 
 void KDE::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/KDE.xml", 0, CV_STORAGE_READ);
-  
-  framesToLearn = cvReadIntByName(fs, 0, "framesToLearn", 10);
-  SequenceLength = cvReadIntByName(fs, 0, "SequenceLength", 50);
-  TimeWindowSize = cvReadIntByName(fs, 0, "TimeWindowSize", 100);
-  SDEstimationFlag = cvReadIntByName(fs, 0, "SDEstimationFlag", 1);
-  lUseColorRatiosFlag = cvReadIntByName(fs, 0, "lUseColorRatiosFlag", 1);
-  th = cvReadRealByName(fs, 0, "th", 10e-8);
-  alpha = cvReadRealByName(fs, 0, "alpha", 0.3);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  framesToLearn = cvReadIntByName(fs, nullptr, "framesToLearn", 10);
+  SequenceLength = cvReadIntByName(fs, nullptr, "SequenceLength", 50);
+  TimeWindowSize = cvReadIntByName(fs, nullptr, "TimeWindowSize", 100);
+  SDEstimationFlag = cvReadIntByName(fs, nullptr, "SDEstimationFlag", 1);
+  lUseColorRatiosFlag = cvReadIntByName(fs, nullptr, "lUseColorRatiosFlag", 1);
+  th = cvReadRealByName(fs, nullptr, "th", 10e-8);
+  alpha = cvReadRealByName(fs, nullptr, "alpha", 0.3);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/KDE.h b/package_bgs/KDE.h
new file mode 100644
index 0000000000000000000000000000000000000000..e77996fd485456e1fce78df60697bf6254cacd3b
--- /dev/null
+++ b/package_bgs/KDE.h
@@ -0,0 +1,57 @@
+/*
+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
+
+#include "IBGS.h"
+#include "KDE/NPBGSubtractor.h"
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class KDE : public IBGS
+    {
+    private:
+      NPBGSubtractor *p;
+      int rows;
+      int cols;
+      int color_channels;
+      int SequenceLength;
+      int TimeWindowSize;
+      int SDEstimationFlag;
+      int lUseColorRatiosFlag;
+      double th;
+      double alpha;
+      int framesToLearn;
+      int frameNumber;
+
+      unsigned char *FGImage;
+      unsigned char *FilteredFGImage;
+      unsigned char **DisplayBuffers;
+
+    public:
+      KDE();
+      ~KDE();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/ae/KernelTable.cpp b/package_bgs/KDE/KernelTable.cpp
similarity index 75%
rename from package_bgs/ae/KernelTable.cpp
rename to package_bgs/KDE/KernelTable.cpp
index 9e20d7cfc0c09382bc360bda5b069aa870c39d98..bd9c3685c0cf1aa6866eebb6cfcd9f0e5fa0df99 100644
--- a/package_bgs/ae/KernelTable.cpp
+++ b/package_bgs/KDE/KernelTable.cpp
@@ -26,21 +26,21 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * copyright notice must be included.  For any other uses of this software,
 * in original or  modified form, including but not limited to distribution
 * in whole or in  part, specific  prior permission  must be  obtained from
-* Author or UMIACS.  These programs shall not  be  used, rewritten, or  
-* adapted as  the basis  of  a commercial  software  or  hardware product 
-* without first obtaining appropriate licenses  from Author. 
+* Author or UMIACS.  These programs shall not  be  used, rewritten, or
+* adapted as  the basis  of  a commercial  software  or  hardware product
+* without first obtaining appropriate licenses  from Author.
 * Other than these cases, no part of this software may be used or
 * distributed without written permission of the author.
 *
-* Neither the author nor UMIACS make any representations about the 
-* suitability of this software for any purpose.  It is provided 
+* Neither the author nor UMIACS make any representations about the
+* suitability of this software for any purpose.  It is provided
 * "as is" without express or implied warranty.
 *
 * Ahmed Elgammal
-* 
+*
 * University of Maryland at College Park
 * UMIACS
-* A.V. Williams Bldg. 
+* A.V. Williams Bldg.
 * CollegePark, MD 20742
 * E-mail:  elgammal@umiacs.umd.edu
 *
@@ -67,8 +67,8 @@ KernelLUTable::KernelLUTable(int KernelHalfWidth, double Segmamin, double Segmam
 {
   std::cout << "KernelLUTable()" << std::endl;
 
-  double C1,C2,v,segma,sum;
-  int bin,b;
+  double C1, C2, v, segma, sum;
+  int bin, b;
 
   minsegma = Segmamin;
   maxsegma = Segmamax;
@@ -78,27 +78,27 @@ KernelLUTable::KernelLUTable(int KernelHalfWidth, double Segmamin, double Segmam
   // Generate the Kernel
 
   // allocate memory for the Kernal Table
-  kerneltable = new double[segmabins*(2*KernelHalfWidth+1)];
+  kerneltable = new double[segmabins*(2 * KernelHalfWidth + 1)];
   kernelsums = new double[segmabins];
 
   double segmastep = (maxsegma - minsegma) / segmabins;
   double y;
 
-  for(segma = minsegma, bin = 0; bin < segmabins; segma += segmastep, bin++) 
+  for (segma = minsegma, bin = 0; bin < segmabins; segma += segmastep, bin++)
   {
-    C1 = 1/(sqrt(2*PI)*segma);
-    C2 = -1/(2*segma*segma);
+    C1 = 1 / (sqrt(2 * PI)*segma);
+    C2 = -1 / (2 * segma*segma);
 
-    b = (2*KernelHalfWidth+1)*bin;
+    b = (2 * KernelHalfWidth + 1)*bin;
     sum = 0;
-    
-    for(int x = 0; x <= KernelHalfWidth; x++)
+
+    for (int x = 0; x <= KernelHalfWidth; x++)
     {
-      y = x/1.0;
+      y = x / 1.0;
       v = C1*exp(C2*y*y);
-      kerneltable[b+KernelHalfWidth+x]=v;
-      kerneltable[b+KernelHalfWidth-x]=v;
-      sum += 2*v;
+      kerneltable[b + KernelHalfWidth + x] = v;
+      kerneltable[b + KernelHalfWidth - x] = v;
+      sum += 2 * v;
     }
 
     sum -= C1;
@@ -106,11 +106,11 @@ KernelLUTable::KernelLUTable(int KernelHalfWidth, double Segmamin, double Segmam
     kernelsums[bin] = sum;
 
     // Normailization
-    for(int x = 0; x <= KernelHalfWidth; x++)
+    for (int x = 0; x <= KernelHalfWidth; x++)
     {
-      v = kerneltable[b+KernelHalfWidth+x] / sum;
-      kerneltable[b+KernelHalfWidth+x]=v;
-      kerneltable[b+KernelHalfWidth-x]=v;
+      v = kerneltable[b + KernelHalfWidth + x] / sum;
+      kerneltable[b + KernelHalfWidth + x] = v;
+      kerneltable[b + KernelHalfWidth - x] = v;
     }
   }
 }
diff --git a/package_bgs/ae/KernelTable.h b/package_bgs/KDE/KernelTable.h
similarity index 86%
rename from package_bgs/ae/KernelTable.h
rename to package_bgs/KDE/KernelTable.h
index bc37cc4f0a8befb16cf987f7c0f7e697400b1dff..63a20dcdcf257f133abd4403e2fb1dc81618facc 100644
--- a/package_bgs/ae/KernelTable.h
+++ b/package_bgs/KDE/KernelTable.h
@@ -26,28 +26,26 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * copyright notice must be included.  For any other uses of this software,
 * in original or  modified form, including but not limited to distribution
 * in whole or in  part, specific  prior permission  must be  obtained from
-* Author or UMIACS.  These programs shall not  be  used, rewritten, or  
-* adapted as  the basis  of  a commercial  software  or  hardware product 
-* without first obtaining appropriate licenses  from Author. 
+* Author or UMIACS.  These programs shall not  be  used, rewritten, or
+* adapted as  the basis  of  a commercial  software  or  hardware product
+* without first obtaining appropriate licenses  from Author.
 * Other than these cases, no part of this software may be used or
 * distributed without written permission of the author.
 *
-* Neither the author nor UMIACS make any representations about the 
-* suitability of this software for any purpose.  It is provided 
+* Neither the author nor UMIACS make any representations about the
+* suitability of this software for any purpose.  It is provided
 * "as is" without express or implied warranty.
 *
 * Ahmed Elgammal
-* 
+*
 * University of Maryland at College Park
 * UMIACS
-* A.V. Williams Bldg. 
+* A.V. Williams Bldg.
 * CollegePark, MD 20742
 * E-mail:  elgammal@umiacs.umd.edu
 *
 **/
-
-#ifndef __KERNEL_TABLE__
-#define __KERNEL_TABLE__
+#pragma once
 
 #include <iostream>
 
@@ -65,7 +63,5 @@ public:
   KernelLUTable();
   ~KernelLUTable();
 
-  KernelLUTable(int KernelHalfWidth,double Segmamin,double Segmamax,int Segmabins);
+  KernelLUTable(int KernelHalfWidth, double Segmamin, double Segmamax, int Segmabins);
 };
-
-#endif
diff --git a/package_bgs/KDE/NPBGSubtractor.cpp b/package_bgs/KDE/NPBGSubtractor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5f004b9f1f2cb77fc80b6f3bade41f026ff17cad
--- /dev/null
+++ b/package_bgs/KDE/NPBGSubtractor.cpp
@@ -0,0 +1,1160 @@
+/*
+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/>.
+*/
+/*
+*
+* Copyright 2001 by Ahmed Elgammal All  rights reserved.
+*
+* Permission to use, copy,  or modify this software and  its documentation
+* for  educational  and  research purposes only and without fee  is hereby
+* granted, provided  that this copyright notice and the original authors's
+* name appear  on all copies and supporting documentation.  If individual
+* files are  separated from  this  distribution directory  structure, this
+* copyright notice must be included.  For any other uses of this software,
+* in original or  modified form, including but not limited to distribution
+* in whole or in  part, specific  prior permission  must be  obtained from
+* Author or UMIACS.  These programs shall not  be  used, rewritten, or
+* adapted as  the basis  of  a commercial  software  or  hardware product
+* without first obtaining appropriate licenses  from Author.
+* Other than these cases, no part of this software may be used or
+* distributed without written permission of the author.
+*
+* Neither the author nor UMIACS make any representations about the
+* suitability of this software for any purpose.  It is provided
+* "as is" without express or implied warranty.
+*
+* Ahmed Elgammal
+*
+* University of Maryland at College Park
+* UMIACS
+* A.V. Williams Bldg.
+* CollegePark, MD 20742
+* E-mail:  elgammal@umiacs.umd.edu
+*
+**/
+
+// NPBGSubtractor.cpp: implementation of the NPBGSubtractor class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "NPBGSubtractor.h"
+#include <assert.h>
+#include <math.h>
+#include <string.h>
+
+//#ifdef _DEBUG
+//#undef THIS_FILE
+//static char THIS_FILE[]=__FILE__;
+//#define new DEBUG_NEW
+//#endif
+
+void BGR2SnGnRn(unsigned char * in_image,
+  unsigned char * out_image,
+  unsigned int rows,
+  unsigned int cols)
+{
+  unsigned int i;
+  unsigned int r2, r3;
+  unsigned int r, g, b;
+  double s;
+
+  for (i = 0; i < rows*cols * 3; i += 3)
+  {
+    b = in_image[i];
+    g = in_image[i + 1];
+    r = in_image[i + 2];
+
+    // calculate color ratios
+    s = (double)255 / (double)(b + g + r + 30);
+
+    r2 = (unsigned int)((g + 10) * s);
+    r3 = (unsigned int)((r + 10) * s);
+
+    out_image[i] = (unsigned char)(((unsigned int)b + g + r) / 3);
+    out_image[i + 1] = (unsigned char)(r2 > 255 ? 255 : r2);
+    out_image[i + 2] = (unsigned char)(r3 > 255 ? 255 : r3);
+  }
+}
+
+void UpdateDiffHist(unsigned char * image1, unsigned char * image2, DynamicMedianHistogram * pHist)
+{
+  unsigned int j;
+  int bin, diff;
+
+  unsigned int  imagesize = pHist->imagesize;
+  unsigned char histbins = pHist->histbins;
+  unsigned char *pAbsDiffHist = pHist->Hist;
+
+  int histbins_1 = histbins - 1;
+
+  for (j = 0; j < imagesize; j++)
+  {
+    diff = (int)image1[j] - (int)image2[j];
+    diff = abs(diff);
+    // update histogram
+    bin = (diff < histbins ? diff : histbins_1);
+    pAbsDiffHist[j*histbins + bin]++;
+  }
+}
+
+void FindHistMedians(DynamicMedianHistogram * pAbsDiffHist)
+{
+  unsigned char * Hist = pAbsDiffHist->Hist;
+  unsigned char * MedianBins = pAbsDiffHist->MedianBins;
+  unsigned char * AccSum = pAbsDiffHist->AccSum;
+  unsigned char histsum = pAbsDiffHist->histsum;
+  unsigned char histbins = pAbsDiffHist->histbins;
+  unsigned int imagesize = pAbsDiffHist->imagesize;
+
+  int sum;
+  int bin;
+  unsigned int histindex;
+  unsigned char medianCount = histsum / 2;
+  unsigned int j;
+
+  // find medians
+  for (j = 0; j < imagesize; j++)
+  {
+    // find the median
+    bin = 0;
+    sum = 0;
+
+    histindex = j*histbins;
+
+    while (sum < medianCount)
+    {
+      sum += Hist[histindex + bin];
+      bin++;
+    }
+
+    bin--;
+
+    MedianBins[j] = bin;
+    AccSum[j] = sum;
+  }
+}
+
+DynamicMedianHistogram BuildAbsDiffHist(unsigned char * pSequence,
+  unsigned int rows,
+  unsigned int cols,
+  unsigned int color_channels,
+  unsigned int SequenceLength,
+  unsigned int histbins)
+{
+
+  unsigned int imagesize = rows*cols*color_channels;
+  unsigned int i;
+
+  DynamicMedianHistogram Hist;
+
+  unsigned char *pAbsDiffHist = new unsigned char[rows*cols*color_channels*histbins];
+  unsigned char *pMedianBins = new unsigned char[rows*cols*color_channels];
+  unsigned char *pMedianFreq = new unsigned char[rows*cols*color_channels];
+  unsigned char *pAccSum = new unsigned char[rows*cols*color_channels];
+
+  memset(pAbsDiffHist, 0, rows*cols*color_channels*histbins);
+
+  Hist.Hist = pAbsDiffHist;
+  Hist.MedianBins = pMedianBins;
+  Hist.MedianFreq = pMedianFreq;
+  Hist.AccSum = pAccSum;
+  Hist.histbins = histbins;
+  Hist.imagesize = rows*cols*color_channels;
+  Hist.histsum = SequenceLength - 1;
+
+  unsigned char *image1, *image2;
+  for (i = 1; i < SequenceLength; i++)
+  {
+    // find diff between frame i,i-1;
+    image1 = pSequence + (i - 1)*imagesize;
+    image2 = pSequence + (i)*imagesize;
+
+    UpdateDiffHist(image1, image2, &Hist);
+  }
+
+  FindHistMedians(&Hist);
+
+  return Hist;
+}
+
+void EstimateSDsFromAbsDiffHist(DynamicMedianHistogram * pAbsDiffHist,
+  unsigned char * pSDs,
+  unsigned int imagesize,
+  double MinSD,
+  double MaxSD,
+  unsigned int kernelbins)
+{
+  double v;
+  double kernelbinfactor = (kernelbins - 1) / (MaxSD - MinSD);
+  int medianCount;
+  int sum;
+  int bin;
+  unsigned int histindex;
+  unsigned int j;
+  unsigned int x1, x2;
+
+  unsigned char *Hist = pAbsDiffHist->Hist;
+  unsigned char *MedianBins = pAbsDiffHist->MedianBins;
+  unsigned char *AccSum = pAbsDiffHist->AccSum;
+  unsigned char histsum = pAbsDiffHist->histsum;
+  unsigned char histbins = pAbsDiffHist->histbins;
+
+  medianCount = (histsum) / 2;
+
+  for (j = 0; j < imagesize; j++)
+  {
+    histindex = j*histbins;
+
+    bin = MedianBins[j];
+    sum = AccSum[j];
+
+    x1 = sum - Hist[histindex + bin];
+    x2 = sum;
+
+    // interpolate to get the median
+    // x1 < 50 % < x2
+
+    v = 1.04 * ((double)bin - (double)(x2 - medianCount) / (double)(x2 - x1));
+    v = (v <= MinSD ? MinSD : v);
+
+    // convert sd to kernel table bin
+
+    bin = (int)(v >= MaxSD ? kernelbins - 1 : floor((v - MinSD)*kernelbinfactor + .5));
+
+    assert(bin >= 0 && bin < kernelbins);
+
+    pSDs[j] = bin;
+  }
+}
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+NPBGSubtractor::NPBGSubtractor() {}
+
+NPBGSubtractor::~NPBGSubtractor()
+{
+  delete AbsDiffHist.Hist;
+  delete AbsDiffHist.MedianBins;
+  delete AbsDiffHist.MedianFreq;
+  delete AbsDiffHist.AccSum;
+  delete KernelTable;
+  delete BGModel->SDbinsImage;
+  delete BGModel;
+  delete Pimage1;
+  delete Pimage2;
+  delete tempFrame;
+  delete imageindex->List;
+  delete imageindex;
+}
+
+int NPBGSubtractor::Intialize(unsigned int prows,
+  unsigned int pcols,
+  unsigned int pcolor_channels,
+  unsigned int SequenceLength,
+  unsigned int pTimeWindowSize,
+  unsigned char pSDEstimationFlag,
+  unsigned char pUseColorRatiosFlag)
+{
+
+  rows = prows;
+  cols = pcols;
+  color_channels = pcolor_channels;
+  imagesize = rows*cols*color_channels;
+  SdEstimateFlag = pSDEstimationFlag;
+  UseColorRatiosFlag = pUseColorRatiosFlag;
+  //SampleSize = SequenceLength;
+
+  AdaptBGFlag = FALSE;
+  //
+  SubsetFlag = TRUE;
+
+  UpdateSDRate = 0;
+
+  BGModel = new NPBGmodel(rows, cols, color_channels, SequenceLength, pTimeWindowSize, 500);
+
+  Pimage1 = new double[rows*cols];
+  Pimage2 = new double[rows*cols];
+
+  tempFrame = new unsigned char[rows*cols * 3];
+
+  imageindex = new ImageIndex;
+  imageindex->List = new unsigned int[rows*cols];
+
+  // error checking
+  if (BGModel == NULL)
+    return 0;
+
+  return 1;
+}
+
+void NPBGSubtractor::AddFrame(unsigned char *ImageBuffer)
+{
+  if (UseColorRatiosFlag && color_channels == 3)
+    BGR2SnGnRn(ImageBuffer, ImageBuffer, rows, cols);
+
+  BGModel->AddFrame(ImageBuffer);
+}
+
+void NPBGSubtractor::Estimation()
+{
+  int SampleSize = BGModel->SampleSize;
+
+  memset(BGModel->TemporalMask, 0, rows*cols*BGModel->TemporalBufferLength);
+
+  //BGModel->AccMask= new unsigned int [rows*cols];
+  memset(BGModel->AccMask, 0, rows*cols * sizeof(unsigned int));
+
+  unsigned char *pSDs = new unsigned char[rows*cols*color_channels];
+
+  //DynamicMedianHistogram AbsDiffHist;
+
+  int Abshistbins = 20;
+
+  TimeIndex = 0;
+
+  // estimate standard deviations
+
+  if (SdEstimateFlag)
+  {
+    AbsDiffHist = BuildAbsDiffHist(BGModel->Sequence, rows, cols, color_channels, SampleSize, Abshistbins);
+    EstimateSDsFromAbsDiffHist(&AbsDiffHist, pSDs, imagesize, SEGMAMIN, SEGMAMAX, SEGMABINS);
+  }
+  else
+  {
+    unsigned int bin;
+    bin = (unsigned int)floor(((DEFAULTSEGMA - SEGMAMIN)*SEGMABINS) / (SEGMAMAX - SEGMAMIN));
+    memset(pSDs, bin, rows*cols*color_channels * sizeof(unsigned char));
+  }
+
+  BGModel->SDbinsImage = pSDs;
+
+  // Generate the Kernel
+  KernelTable = new KernelLUTable(KERNELHALFWIDTH, SEGMAMIN, SEGMAMAX, SEGMABINS);
+}
+
+/*********************************************************************/
+
+void BuildImageIndex(unsigned char * Image,
+  ImageIndex * imageIndex,
+  unsigned int rows,
+  unsigned int cols)
+{
+  unsigned int i, j;
+  unsigned int r, c;
+  unsigned int * image_list;
+
+  j = cols + 1;
+  i = 0;
+  image_list = imageIndex->List;
+
+  for (r = 1; r < rows - 1; r++)
+  {
+    for (c = 1; c < cols - 1; c++)
+    {
+      if (Image[j])
+        image_list[i++] = j;
+
+      j++;
+    }
+    j += 2;
+  }
+
+  imageIndex->cnt = i;
+}
+
+/*********************************************************************/
+
+void HystExpandOperatorIndexed(unsigned char * inImage,
+  ImageIndex * inIndex,
+  double * Pimage,
+  double hyst_th,
+  unsigned char * outImage,
+  ImageIndex * outIndex,
+  unsigned int urows,
+  unsigned int ucols)
+{
+  unsigned int * in_list;
+  unsigned int in_cnt;
+  unsigned int * out_list;
+
+  int rows, cols;
+
+  int Nbr[9];
+  unsigned int i, j;
+  unsigned int k;
+  unsigned int idx;
+
+  rows = (int)urows;
+  cols = (int)ucols;
+
+  in_cnt = inIndex->cnt;
+  in_list = inIndex->List;
+
+  Nbr[0] = -cols - 1;
+  Nbr[1] = -cols;
+  Nbr[2] = -cols + 1;
+  Nbr[3] = -1;
+  Nbr[4] = 0;
+  Nbr[5] = 1;
+  Nbr[6] = cols - 1;
+  Nbr[7] = cols;
+  Nbr[8] = cols + 1;
+
+  memset(outImage, 0, rows*cols);
+
+  out_list = outIndex->List;
+  k = 0;
+
+  for (i = 0; i < in_cnt; i++)
+  {
+    for (j = 0; j < 9; j++)
+    {
+      idx = in_list[i] + Nbr[j];
+
+      if (Pimage[idx] < hyst_th)
+        outImage[idx] = 255;
+    }
+  }
+
+  // build index for out image
+  BuildImageIndex(outImage, outIndex, urows, ucols);
+}
+
+/*********************************************************************/
+
+void HystShrinkOperatorIndexed(unsigned char * inImage,
+  ImageIndex * inIndex,
+  double * Pimage,
+  double hyst_th,
+  unsigned char * outImage,
+  ImageIndex * outIndex,
+  unsigned int urows,
+  unsigned int ucols)
+{
+  unsigned int * in_list;
+  unsigned int in_cnt;
+  unsigned int * out_list;
+
+  int rows, cols;
+
+  int Nbr[9];
+  unsigned int i, j;
+  unsigned int k, idx;
+
+  rows = (int)urows;
+  cols = (int)ucols;
+
+  in_cnt = inIndex->cnt;
+  in_list = inIndex->List;
+
+  Nbr[0] = -cols - 1;
+  Nbr[1] = -cols;
+  Nbr[2] = -cols + 1;
+  Nbr[3] = -1;
+  Nbr[4] = 0;
+  Nbr[5] = 1;
+  Nbr[6] = cols - 1;
+  Nbr[7] = cols;
+  Nbr[8] = cols + 1;
+
+  memset(outImage, 0, rows*cols);
+
+  out_list = outIndex->List;
+  k = 0;
+
+  for (i = 0; i < in_cnt; i++)
+  {
+    idx = in_list[i];
+    j = 0;
+
+    while (j < 9 && inImage[idx + Nbr[j]])
+      j++;
+
+    if (j >= 9 || Pimage[idx] <= hyst_th)
+      outImage[idx] = 255;
+  }
+
+  BuildImageIndex(outImage, outIndex, rows, cols);
+}
+
+/*********************************************************************/
+
+void ExpandOperatorIndexed(unsigned char * inImage,
+  ImageIndex * inIndex,
+  unsigned char * outImage,
+  ImageIndex * outIndex,
+  unsigned int urows,
+  unsigned int ucols)
+{
+  unsigned int * in_list;
+  unsigned int in_cnt;
+  unsigned int * out_list;
+
+  int rows, cols;
+
+  int Nbr[9];
+  unsigned int i, j;
+  unsigned int k;
+  unsigned int idx;
+
+  rows = (int)urows;
+  cols = (int)ucols;
+
+  in_cnt = inIndex->cnt;
+  in_list = inIndex->List;
+
+  Nbr[0] = -cols - 1;
+  Nbr[1] = -cols;
+  Nbr[2] = -cols + 1;
+  Nbr[3] = -1;
+  Nbr[4] = 0;
+  Nbr[5] = 1;
+  Nbr[6] = cols - 1;
+  Nbr[7] = cols;
+  Nbr[8] = cols + 1;
+
+
+  memset(outImage, 0, rows*cols);
+
+
+  out_list = outIndex->List;
+  k = 0;
+  for (i = 0; i < in_cnt; i++)
+    for (j = 0; j < 9; j++) {
+      idx = in_list[i] + Nbr[j];
+      outImage[idx] = 255;
+    }
+
+
+  // build index for out image
+
+  BuildImageIndex(outImage, outIndex, rows, cols);
+
+}
+
+/*********************************************************************/
+
+void ShrinkOperatorIndexed(unsigned char * inImage,
+  ImageIndex * inIndex,
+  unsigned char * outImage,
+  ImageIndex * outIndex,
+  unsigned int urows,
+  unsigned int ucols)
+{
+
+  unsigned int * in_list;
+  unsigned int in_cnt;
+  unsigned int * out_list;
+
+  int rows, cols;
+
+  int Nbr[9];
+  unsigned int i, j;
+  unsigned int k, idx;
+
+  rows = (int)urows;
+  cols = (int)ucols;
+
+  in_cnt = inIndex->cnt;
+  in_list = inIndex->List;
+
+  Nbr[0] = -cols - 1;
+  Nbr[1] = -cols;
+  Nbr[2] = -cols + 1;
+  Nbr[3] = -1;
+  Nbr[4] = 0;
+  Nbr[5] = 1;
+  Nbr[6] = cols - 1;
+  Nbr[7] = cols;
+  Nbr[8] = cols + 1;
+
+
+  memset(outImage, 0, rows*cols);
+
+  out_list = outIndex->List;
+  k = 0;
+  for (i = 0; i < in_cnt; i++) {
+    idx = in_list[i];
+    j = 0;
+
+    while (j < 9 && inImage[idx + Nbr[j]]) {
+      j++;
+    }
+
+    if (j >= 9) {
+      outImage[idx] = 255;
+    }
+  }
+
+  BuildImageIndex(outImage, outIndex, rows, cols);
+}
+
+/*********************************************************************/
+
+void NoiseFilter_o(unsigned char * Image,
+  unsigned char * ResultIm,
+  int rows,
+  int cols,
+  unsigned char th)
+{
+  /* assuming input is 1 for on, 0 for off */
+
+
+  int r, c;
+  unsigned char *p, *n, *nw, *ne, *e, *w, *s, *sw, *se;
+  unsigned int v;
+  unsigned int TH;
+
+  unsigned char * ResultPtr;
+
+  TH = 255 * th;
+
+  memset(ResultIm, 0, rows*cols);
+
+  p = Image + cols + 1;
+  ResultPtr = ResultIm + cols + 1;
+
+  for (r = 1; r < rows - 1; r++)
+  {
+    for (c = 1; c < cols - 1; c++)
+    {
+      if (*p)
+      {
+        n = p - cols;
+        ne = n + 1;
+        nw = n - 1;
+        e = p + 1;
+        w = p - 1;
+        s = p + cols;
+        se = s + 1;
+        sw = s - 1;
+
+        v = (unsigned int)*nw + *n + *ne + *w + *e + *sw + *s + *se;
+
+        if (v >= TH)
+          *ResultPtr = 255;
+        else
+          *ResultPtr = 0;
+      }
+      p++;
+      ResultPtr++;
+    }
+    p += 2;
+    ResultPtr += 2;
+  }
+}
+
+/*********************************************************************/
+
+void NPBGSubtractor::SequenceBGUpdate_Pairs(unsigned char * image,
+  unsigned char * Mask)
+{
+  unsigned int i, ic;
+  unsigned char * pSequence = BGModel->Sequence;
+  unsigned char * PixelQTop = BGModel->PixelQTop;
+  unsigned int Top = BGModel->Top;
+  unsigned int rate;
+
+  int TemporalBufferTop = (int)BGModel->TemporalBufferTop;
+  unsigned char * pTemporalBuffer = BGModel->TemporalBuffer;
+  unsigned char * pTemporalMask = BGModel->TemporalMask;
+  int TemporalBufferLength = BGModel->TemporalBufferLength;
+
+  unsigned int * AccMask = BGModel->AccMask;
+  unsigned int ResetMaskTh = BGModel->ResetMaskTh;
+
+  unsigned char *pAbsDiffHist = AbsDiffHist.Hist;
+  unsigned char histbins = AbsDiffHist.histbins;
+  int histbins_1 = histbins - 1;
+
+  int TimeWindowSize = BGModel->TimeWindowSize;
+  int SampleSize = BGModel->SampleSize;
+
+  int TemporalBufferNext;
+
+  unsigned int imagebuffersize = rows*cols*color_channels;
+  unsigned int imagespatialsize = rows*cols;
+
+  unsigned char mask;
+
+  unsigned int histindex;
+  unsigned char diff;
+  unsigned char bin;
+
+  static int TBCount = 0;
+
+  unsigned char * pTBbase1, *pTBbase2;
+  unsigned char * pModelbase1, *pModelbase2;
+
+  rate = TimeWindowSize / SampleSize;
+  rate = (rate > 2) ? rate : 2;
+
+
+  TemporalBufferNext = (TemporalBufferTop + 1)
+    % TemporalBufferLength;
+
+  // pointers to Masks : Top and Next
+  unsigned char * pTMaskTop = pTemporalMask + TemporalBufferTop*imagespatialsize;
+  unsigned char * pTMaskNext = pTemporalMask + TemporalBufferNext*imagespatialsize;
+
+  // pointers to TB frames: Top and Next
+  unsigned char * pTBTop = pTemporalBuffer + TemporalBufferTop*imagebuffersize;
+  unsigned char * pTBNext = pTemporalBuffer + TemporalBufferNext*imagebuffersize;
+
+  if (((TimeIndex) % rate == 0) && TBCount >= TemporalBufferLength)
+  {
+    for (i = 0, ic = 0; i < imagespatialsize; i++, ic += color_channels)
+    {
+      mask = *(pTMaskTop + i) || *(pTMaskNext + i);
+
+      if (!mask)
+      {
+        // pointer to TB pixels to be added to the model
+        pTBbase1 = pTBTop + ic;
+        pTBbase2 = pTBNext + ic;
+
+        // pointers to Model pixels to be replaced
+        pModelbase1 = pSequence + PixelQTop[i] * imagebuffersize + ic;
+        pModelbase2 = pSequence + ((PixelQTop[i] + 1) % SampleSize)*imagebuffersize + ic;
+
+        // update Deviation Histogram
+        if (SdEstimateFlag)
+        {
+          if (color_channels == 1)
+          {
+            histindex = i*histbins;
+
+            // add new pair from temporal buffer
+            diff = (unsigned char)abs((int)*pTBbase1 - (int)*pTBbase2);
+            bin = (diff < histbins ? diff : histbins_1);
+            pAbsDiffHist[histindex + bin]++;
+
+
+            // remove old pair from the model
+            diff = (unsigned char)abs((int)*pModelbase1 - (int)*pModelbase2);
+            bin = (diff < histbins ? diff : histbins_1);
+            pAbsDiffHist[histindex + bin]--;
+          }
+          else
+          {
+            // color
+
+            // add new pair from temporal buffer
+            histindex = ic*histbins;
+            diff = abs(*pTBbase1 -
+              *pTBbase2);
+            bin = (diff < histbins ? diff : histbins_1);
+            pAbsDiffHist[histindex + bin]++;
+
+            histindex += histbins;
+            diff = abs(*(pTBbase1 + 1) -
+              *(pTBbase2 + 1));
+            bin = (diff < histbins ? diff : histbins_1);
+            pAbsDiffHist[histindex + bin]++;
+
+            histindex += histbins;
+            diff = abs(*(pTBbase1 + 2) -
+              *(pTBbase2 + 2));
+            bin = (diff < histbins ? diff : histbins_1);
+            pAbsDiffHist[histindex + bin]++;
+
+            // remove old pair from the model
+            histindex = ic*histbins;
+
+            diff = abs(*pModelbase1 -
+              *pModelbase2);
+            bin = (diff < histbins ? diff : histbins_1);
+            pAbsDiffHist[histindex + bin]--;
+
+            histindex += histbins;
+            diff = abs(*(pModelbase1 + 1) -
+              *(pModelbase2 + 1));
+            bin = (diff < histbins ? diff : histbins_1);
+            pAbsDiffHist[histindex + bin]--;
+
+            histindex += histbins;
+            diff = abs(*(pModelbase1 + 2) -
+              *(pModelbase2 + 2));
+            bin = (diff < histbins ? diff : histbins_1);
+            pAbsDiffHist[histindex + bin]--;
+          }
+        }
+
+        // add new pair into the model
+        memcpy(pModelbase1, pTBbase1, color_channels * sizeof(unsigned char));
+
+        memcpy(pModelbase2, pTBbase2, color_channels * sizeof(unsigned char));
+
+        PixelQTop[i] = (PixelQTop[i] + 2) % SampleSize;
+      }
+    }
+  } // end if (sampling event)
+
+  // update temporal buffer
+  // add new frame to Temporal buffer.
+  memcpy(pTBTop, image, imagebuffersize);
+
+  // update AccMask
+  // update new Mask with information in AccMask
+
+  for (i = 0; i < rows*cols; i++)
+  {
+    if (Mask[i])
+      AccMask[i]++;
+    else
+      AccMask[i] = 0;
+
+    if (AccMask[i] > ResetMaskTh)
+      Mask[i] = 0;
+  }
+
+  // add new mask
+  memcpy(pTMaskTop, Mask, imagespatialsize);
+
+  // advance Temporal buffer pointer
+  TemporalBufferTop = (TemporalBufferTop + 1) % TemporalBufferLength;
+
+  BGModel->TemporalBufferTop = TemporalBufferTop;
+
+  TBCount++;
+
+  // estimate SDs
+
+  if (SdEstimateFlag && UpdateSDRate && ((TimeIndex) % UpdateSDRate == 0))
+  {
+    double MaxSD = KernelTable->maxsegma;
+    double MinSD = KernelTable->minsegma;
+    int KernelBins = KernelTable->segmabins;
+
+    unsigned char * pSDs = BGModel->SDbinsImage;
+
+    FindHistMedians(&(AbsDiffHist));
+    EstimateSDsFromAbsDiffHist(&(AbsDiffHist), pSDs, imagebuffersize, MinSD, MaxSD, KernelBins);
+  }
+
+  TimeIndex++;
+}
+
+/*********************************************************************/
+
+void DisplayPropabilityImageWithThresholding(double * Pimage,
+  unsigned char * DisplayImage,
+  double Threshold,
+  unsigned int rows,
+  unsigned int cols)
+{
+  double p;
+
+  for (unsigned int i = 0; i < rows*cols; i++)
+  {
+    p = Pimage[i];
+
+    DisplayImage[i] = (p > Threshold) ? 0 : 255;
+  }
+}
+
+/*********************************************************************/
+
+void NPBGSubtractor::NPBGSubtraction_Subset_Kernel(
+  unsigned char * image,
+  unsigned char * FGImage,
+  unsigned char * FilteredFGImage)
+{
+  unsigned int i, j;
+  unsigned char *pSequence = BGModel->Sequence;
+
+  unsigned int SampleSize = BGModel->SampleSize;
+
+  double *kerneltable = KernelTable->kerneltable;
+  int KernelHalfWidth = KernelTable->tablehalfwidth;
+  double *KernelSum = KernelTable->kernelsums;
+  double KernelMaxSigma = KernelTable->maxsegma;
+  double KernelMinSigma = KernelTable->minsegma;
+  int KernelBins = KernelTable->segmabins;
+  unsigned char * SDbins = BGModel->SDbinsImage;
+
+  unsigned char * SaturationImage = FilteredFGImage;
+
+  // default sigmas .. to be removed.
+  double sigma1;
+  double sigma2;
+  double sigma3;
+
+  sigma1 = 2.25;
+  sigma2 = 2.25;
+  sigma3 = 2.25;
+
+  double p;
+  double th;
+
+  double alpha;
+
+  alpha = AlphaValue;
+
+  /* intialize FG image */
+
+  memset(FGImage, 0, rows*cols);
+
+  //Threshold=1;
+  th = Threshold * SampleSize;
+
+  double sum = 0, kernel1, kernel2, kernel3;
+  int k, g;
+
+
+  if (color_channels == 1)
+  {
+    // gray scale
+
+    int kernelbase;
+
+    for (i = 0; i < rows*cols; i++)
+    {
+      kernelbase = SDbins[i] * (2 * KernelHalfWidth + 1);
+      sum = 0;
+      j = 0;
+
+      while (j < SampleSize && sum < th)
+      {
+        g = pSequence[j*imagesize + i];
+        k = g - image[i] + KernelHalfWidth;
+        sum += kerneltable[kernelbase + k];
+        j++;
+      }
+
+      p = sum / j;
+      Pimage1[i] = p;
+    }
+  }
+  else if (UseColorRatiosFlag && SubsetFlag)
+  {
+    // color ratios
+
+    unsigned int ig;
+    int base;
+
+    int kernelbase1;
+    int kernelbase2;
+    int kernelbase3;
+
+    unsigned int kerneltablewidth = 2 * KernelHalfWidth + 1;
+
+    double beta = 3.0;    // minimum bound on the range.
+    double betau = 100.0;
+
+    double beta_over_alpha = beta / alpha;
+    double betau_over_alpha = betau / alpha;
+
+
+    double brightness_lowerbound = 1 - alpha;
+    double brightness_upperbound = 1 + alpha;
+    int x1, x2;
+    unsigned int SubsampleCount;
+
+    for (i = 0, ig = 0; i < imagesize; i += 3, ig++)
+    {
+      kernelbase1 = SDbins[i] * kerneltablewidth;
+      kernelbase2 = SDbins[i + 1] * kerneltablewidth;
+      kernelbase3 = SDbins[i + 2] * kerneltablewidth;
+
+      sum = 0;
+      j = 0;
+      SubsampleCount = 0;
+
+      while (j < SampleSize && sum < th)
+      {
+        base = j*imagesize + i;
+        g = pSequence[base];
+
+        if (g < beta_over_alpha)
+        {
+          x1 = (int)(g - beta);
+          x2 = (int)(g + beta);
+        }
+        else if (g > betau_over_alpha)
+        {
+          x1 = (int)(g - betau);
+          x2 = (int)(g + betau);
+        }
+        else
+        {
+          x1 = (int)(g*brightness_lowerbound + 0.5);
+          x2 = (int)(g*brightness_upperbound + 0.5);
+        }
+
+        if (x1 < image[i] && image[i] < x2)
+        {
+          g = pSequence[base + 1];
+          k = (g - image[i + 1]) + KernelHalfWidth;
+          kernel2 = kerneltable[kernelbase2 + k];
+
+          g = pSequence[base + 2];
+          k = (g - image[i + 2]) + KernelHalfWidth;
+          kernel3 = kerneltable[kernelbase3 + k];
+
+          sum += kernel2*kernel3;
+
+          SubsampleCount++;
+        }
+        j++;
+      }
+
+      p = sum / j;
+      Pimage1[ig] = p;
+    }
+  }
+  else if (UseColorRatiosFlag && !SubsetFlag)
+  {
+    // color ratios
+
+    unsigned int ig;
+    int base;
+    int bin;
+
+    int kernelbase1;
+    int kernelbase2;
+    int kernelbase3;
+
+    unsigned int kerneltablewidth = 2 * KernelHalfWidth + 1;
+
+    int gmin, gmax;
+    double gfactor;
+
+    gmax = 200;
+    gmin = 10;
+
+    gfactor = (KernelMaxSigma - KernelMinSigma) / (double)(gmax - gmin);
+
+    for (i = 0, ig = 0; i < imagesize; i += 3, ig++)
+    {
+
+      bin = (int)floor(((alpha * 16 - KernelMinSigma)*KernelBins) / (KernelMaxSigma - KernelMinSigma));
+
+      kernelbase1 = bin*kerneltablewidth;
+      kernelbase2 = SDbins[i + 1] * kerneltablewidth;
+      kernelbase3 = SDbins[i + 2] * kerneltablewidth;
+
+      sum = 0;
+      j = 0;
+
+      while (j < SampleSize && sum < th)
+      {
+        base = j*imagesize + i;
+        g = pSequence[base];
+
+        if (g < gmin)
+          bin = 0;
+        else if (g > gmax)
+          bin = KernelBins - 1;
+        else
+          bin = (int)((g - gmin) * gfactor + 0.5);
+
+        kernelbase1 = bin*kerneltablewidth;
+
+        k = (g - image[i]) + KernelHalfWidth;
+        kernel1 = kerneltable[kernelbase1 + k];
+
+        g = pSequence[base + 1];
+        k = (g - image[i + 1]) + KernelHalfWidth;
+        kernel2 = kerneltable[kernelbase2 + k];
+
+        g = pSequence[base + 2];
+        k = (g - image[i + 2]) + KernelHalfWidth;
+        kernel3 = kerneltable[kernelbase3 + k];
+
+        sum += kernel1*kernel2*kernel3;
+        j++;
+      }
+
+      p = sum / j;
+      Pimage1[ig] = p;
+    }
+  }
+  else // RGB color
+  {
+    unsigned int ig;
+    int base;
+
+    int kernelbase1;
+    int kernelbase2;
+    int kernelbase3;
+    unsigned int kerneltablewidth = 2 * KernelHalfWidth + 1;
+
+    for (i = 0, ig = 0; i < imagesize; i += 3, ig++)
+    {
+      // used extimated kernel width to access the right kernel
+      kernelbase1 = SDbins[i] * kerneltablewidth;
+      kernelbase2 = SDbins[i + 1] * kerneltablewidth;
+      kernelbase3 = SDbins[i + 2] * kerneltablewidth;
+
+      sum = 0;
+      j = 0;
+      while (j < SampleSize && sum < th)
+      {
+        base = j*imagesize + i;
+        g = pSequence[base];
+        k = (g - image[i]) + KernelHalfWidth;
+        kernel1 = kerneltable[kernelbase1 + k];
+
+        g = pSequence[base + 1];
+        k = (g - image[i + 1]) + KernelHalfWidth;
+        kernel2 = kerneltable[kernelbase2 + k];
+
+        g = pSequence[base + 2];
+        k = (g - image[i + 2]) + KernelHalfWidth;
+        kernel3 = kerneltable[kernelbase3 + k];
+
+        sum += kernel1*kernel2*kernel3;
+        j++;
+      }
+
+      p = sum / j;
+      Pimage1[ig] = p;
+    }
+  }
+
+  DisplayPropabilityImageWithThresholding(Pimage1, FGImage, Threshold, rows, cols);
+}
+
+/*********************************************************************/
+
+void NPBGSubtractor::NBBGSubtraction(unsigned char * Frame,
+  unsigned char * FGImage,
+  unsigned char * FilteredFGImage,
+  unsigned char ** DisplayBuffers)
+{
+  if (UseColorRatiosFlag)
+    BGR2SnGnRn(Frame, tempFrame, rows, cols);
+  else
+    memcpy(tempFrame, Frame, rows*cols*color_channels);
+
+  NPBGSubtraction_Subset_Kernel(tempFrame, FGImage, FilteredFGImage);
+  /*NoiseFilter_o(FGImage,DisplayBuffers[3],rows,cols,4);
+  BuildImageIndex(DisplayBuffers[3],imageindex,rows,cols);
+
+  ExpandOperatorIndexed(DisplayBuffers[3],imageindex,DisplayBuffers[4],imageindex,rows,cols);
+  ShrinkOperatorIndexed(DisplayBuffers[4],imageindex,FilteredFGImage,imageindex,rows,cols);
+
+  memset(DisplayBuffers[3],0,rows*cols);*/
+}
+
+void NPBGSubtractor::Update(unsigned char * FGMask)
+{
+  if (UpdateBGFlag)
+    SequenceBGUpdate_Pairs(tempFrame, FGMask);
+}
diff --git a/package_bgs/ae/NPBGSubtractor.h b/package_bgs/KDE/NPBGSubtractor.h
similarity index 87%
rename from package_bgs/ae/NPBGSubtractor.h
rename to package_bgs/KDE/NPBGSubtractor.h
index e7f379542767bec2b6e47b1b1b74a2574e58ebb9..ce4bffc4812904a81a203c63f64bf1cf6080d14a 100644
--- a/package_bgs/ae/NPBGSubtractor.h
+++ b/package_bgs/KDE/NPBGSubtractor.h
@@ -26,21 +26,21 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * copyright notice must be included.  For any other uses of this software,
 * in original or  modified form, including but not limited to distribution
 * in whole or in  part, specific  prior permission  must be  obtained from
-* Author or UMIACS.  These programs shall not  be  used, rewritten, or  
-* adapted as  the basis  of  a commercial  software  or  hardware product 
-* without first obtaining appropriate licenses  from Author. 
+* Author or UMIACS.  These programs shall not  be  used, rewritten, or
+* adapted as  the basis  of  a commercial  software  or  hardware product
+* without first obtaining appropriate licenses  from Author.
 * Other than these cases, no part of this software may be used or
 * distributed without written permission of the author.
 *
-* Neither the author nor UMIACS make any representations about the 
-* suitability of this software for any purpose.  It is provided 
+* Neither the author nor UMIACS make any representations about the
+* suitability of this software for any purpose.  It is provided
 * "as is" without express or implied warranty.
 *
 * Ahmed Elgammal
-* 
+*
 * University of Maryland at College Park
 * UMIACS
-* A.V. Williams Bldg. 
+* A.V. Williams Bldg.
 * CollegePark, MD 20742
 * E-mail:  elgammal@umiacs.umd.edu
 *
@@ -49,13 +49,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 // NPBGSubtractor.h: interface for the NPBGSubtractor class.
 //
 //////////////////////////////////////////////////////////////////////
-
-#if !defined(AFX_NPBGSUBTRACTOR_H__84B0F51E_6E65_41E4_AC01_723B406363C4__INCLUDED_)
-#define AFX_NPBGSUBTRACTOR_H__84B0F51E_6E65_41E4_AC01_723B406363C4__INCLUDED_
-
-#if _MSC_VER > 1000
 #pragma once
-#endif // _MSC_VER > 1000
 
 #include "NPBGmodel.h"
 #include "KernelTable.h"
@@ -87,7 +81,7 @@ typedef struct
   unsigned int *List;
 } ImageIndex;
 
-class NPBGSubtractor  
+class NPBGSubtractor
 {
 private:
   unsigned int rows;
@@ -146,9 +140,7 @@ public:
     AlphaValue = alpha;
   };
 
-  void SetUpdateFlag(unsigned int bgflag){
+  void SetUpdateFlag(unsigned int bgflag) {
     UpdateBGFlag = bgflag;
   };
 };
-
-#endif // !defined(AFX_NPBGSUBTRACTOR_H__84B0F51E_6E65_41E4_AC01_723B406363C4__INCLUDED_)
diff --git a/package_bgs/ae/NPBGmodel.cpp b/package_bgs/KDE/NPBGmodel.cpp
similarity index 78%
rename from package_bgs/ae/NPBGmodel.cpp
rename to package_bgs/KDE/NPBGmodel.cpp
index 2c8b07400992bf4db7810723b6fef930ed806ee3..a79a7b42f1ae663d3da1afaef56899bd4cd3f218 100644
--- a/package_bgs/ae/NPBGmodel.cpp
+++ b/package_bgs/KDE/NPBGmodel.cpp
@@ -26,21 +26,21 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * copyright notice must be included.  For any other uses of this software,
 * in original or  modified form, including but not limited to distribution
 * in whole or in  part, specific  prior permission  must be  obtained from
-* Author or UMIACS.  These programs shall not  be  used, rewritten, or  
-* adapted as  the basis  of  a commercial  software  or  hardware product 
-* without first obtaining appropriate licenses  from Author. 
+* Author or UMIACS.  These programs shall not  be  used, rewritten, or
+* adapted as  the basis  of  a commercial  software  or  hardware product
+* without first obtaining appropriate licenses  from Author.
 * Other than these cases, no part of this software may be used or
 * distributed without written permission of the author.
 *
-* Neither the author nor UMIACS make any representations about the 
-* suitability of this software for any purpose.  It is provided 
+* Neither the author nor UMIACS make any representations about the
+* suitability of this software for any purpose.  It is provided
 * "as is" without express or implied warranty.
 *
 * Ahmed Elgammal
-* 
+*
 * University of Maryland at College Park
 * UMIACS
-* A.V. Williams Bldg. 
+* A.V. Williams Bldg.
 * CollegePark, MD 20742
 * E-mail:  elgammal@umiacs.umd.edu
 *
@@ -55,7 +55,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 
 #ifdef _DEBUG
 #undef THIS_FILE
-static char THIS_FILE[]=__FILE__;
+static char THIS_FILE[] = __FILE__;
 //#define new DEBUG_NEW
 #endif
 
@@ -80,11 +80,11 @@ NPBGmodel::~NPBGmodel()
 }
 
 NPBGmodel::NPBGmodel(unsigned int Rows,
-                     unsigned int Cols,
-                     unsigned int ColorChannels,
-                     unsigned int Length,
-                     unsigned int pTimeWindowSize,
-                     unsigned int bg_suppression_time)
+  unsigned int Cols,
+  unsigned int ColorChannels,
+  unsigned int Length,
+  unsigned int pTimeWindowSize,
+  unsigned int bg_suppression_time)
 {
   std::cout << "NPBGmodel()" << std::endl;
 
@@ -98,14 +98,14 @@ NPBGmodel::NPBGmodel(unsigned int Rows,
 
   TimeWindowSize = pTimeWindowSize;
 
-  Sequence	= new unsigned char[imagesize*Length];
+  Sequence = new unsigned char[imagesize*Length];
   Top = 0;
-  memset(Sequence,0,imagesize*Length);
+  memset(Sequence, 0, imagesize*Length);
 
   PixelQTop = new unsigned char[rows*cols];
 
   // temporalBuffer
-  TemporalBufferLength = (TimeWindowSize/Length > 2 ? TimeWindowSize/Length:2);
+  TemporalBufferLength = (TimeWindowSize / Length > 2 ? TimeWindowSize / Length : 2);
   TemporalBuffer = new unsigned char[imagesize*TemporalBufferLength];
   TemporalMask = new unsigned char[rows*cols*TemporalBufferLength];
 
@@ -116,12 +116,12 @@ NPBGmodel::NPBGmodel(unsigned int Rows,
   ResetMaskTh = bg_suppression_time;
 }
 
-void NPBGmodel::AddFrame(unsigned char *ImageBuffer)		
+void NPBGmodel::AddFrame(unsigned char *ImageBuffer)
 {
-  memcpy(Sequence+Top*imagesize,ImageBuffer,imagesize);
-  Top = (Top + 1) % SampleSize;		
+  memcpy(Sequence + Top*imagesize, ImageBuffer, imagesize);
+  Top = (Top + 1) % SampleSize;
 
-  memset(PixelQTop, (unsigned char) Top, rows*cols);
+  memset(PixelQTop, (unsigned char)Top, rows*cols);
 
-  memcpy(TemporalBuffer,ImageBuffer,imagesize);
+  memcpy(TemporalBuffer, ImageBuffer, imagesize);
 }
diff --git a/package_bgs/ae/NPBGmodel.h b/package_bgs/KDE/NPBGmodel.h
similarity index 84%
rename from package_bgs/ae/NPBGmodel.h
rename to package_bgs/KDE/NPBGmodel.h
index 9e285108eec393167c327970aa1c783733c71447..ba4a927875ea083f5e99dad42ee7a4bee3f9ea32 100644
--- a/package_bgs/ae/NPBGmodel.h
+++ b/package_bgs/KDE/NPBGmodel.h
@@ -26,21 +26,21 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * copyright notice must be included.  For any other uses of this software,
 * in original or  modified form, including but not limited to distribution
 * in whole or in  part, specific  prior permission  must be  obtained from
-* Author or UMIACS.  These programs shall not  be  used, rewritten, or  
-* adapted as  the basis  of  a commercial  software  or  hardware product 
-* without first obtaining appropriate licenses  from Author. 
+* Author or UMIACS.  These programs shall not  be  used, rewritten, or
+* adapted as  the basis  of  a commercial  software  or  hardware product
+* without first obtaining appropriate licenses  from Author.
 * Other than these cases, no part of this software may be used or
 * distributed without written permission of the author.
 *
-* Neither the author nor UMIACS make any representations about the 
-* suitability of this software for any purpose.  It is provided 
+* Neither the author nor UMIACS make any representations about the
+* suitability of this software for any purpose.  It is provided
 * "as is" without express or implied warranty.
 *
 * Ahmed Elgammal
-* 
+*
 * University of Maryland at College Park
 * UMIACS
-* A.V. Williams Bldg. 
+* A.V. Williams Bldg.
 * CollegePark, MD 20742
 * E-mail:  elgammal@umiacs.umd.edu
 *
@@ -49,24 +49,18 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 // NPBGmodel.h: interface for the NPBGmodel class.
 //
 //////////////////////////////////////////////////////////////////////
-
-#if !defined(AFX_NPBGMODEL_H__CCAF05D4_D06E_44C2_95D8_979E2249953A__INCLUDED_)
-#define AFX_NPBGMODEL_H__CCAF05D4_D06E_44C2_95D8_979E2249953A__INCLUDED_
-
-#if _MSC_VER > 1000
 #pragma once
-#endif // _MSC_VER > 1000
 
 #include <iostream>
 
-class NPBGmodel  
+class NPBGmodel
 {
 private:
   unsigned char *Sequence;
   unsigned int SampleSize;
   unsigned int TimeWindowSize;
 
-  unsigned int rows,cols,color_channels;
+  unsigned int rows, cols, color_channels;
   unsigned int imagesize;
 
   unsigned int Top;
@@ -74,7 +68,7 @@ private:
 
   //unsigned int *PixelUpdateCounter;
 
-  unsigned char *SDbinsImage; 
+  unsigned char *SDbinsImage;
 
   unsigned char *TemporalBuffer;
   unsigned char TemporalBufferLength;
@@ -107,5 +101,3 @@ public:
 
   friend class NPBGSubtractor;
 };
-
-#endif // !defined(AFX_NPBGMODEL_H__CCAF05D4_D06E_44C2_95D8_979E2249953A__INCLUDED_)
diff --git a/package_bgs/KNN.cpp b/package_bgs/KNN.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d2e14127ee2efcde134226b10871716994bc1f5e
--- /dev/null
+++ b/package_bgs/KNN.cpp
@@ -0,0 +1,111 @@
+/*
+ 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 "KNN.h"
+
+#if CV_MAJOR_VERSION == 3
+
+using namespace bgslibrary::algorithms;
+
+KNN::KNN() :
+  history(500), nSamples(7), dist2Threshold(20.0f * 20.0f), knnSamples(0),
+  doShadowDetection(true), shadowValue(127), shadowThreshold(0.5f)
+{
+  std::cout << "KNN()" << std::endl;
+  setup("./config/KNN.xml");
+}
+
+KNN::~KNN()
+{
+  std::cout << "~KNN()" << std::endl;
+}
+
+void KNN::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+{
+  init(img_input, img_output, img_bgmodel);
+
+  //------------------------------------------------------------------
+  // BackgroundSubtractorKNN
+  // http://docs.opencv.org/trunk/modules/video/doc/motion_analysis_and_object_tracking.html#backgroundsubtractorknn
+  //
+  //  The class implements the K nearest neigbours algorithm from:
+  //  "Efficient Adaptive Density Estimation per Image Pixel for the Task of Background Subtraction"
+  //  Z.Zivkovic, F. van der Heijden
+  //  Pattern Recognition Letters, vol. 27, no. 7, pages 773-780, 2006
+  //  http:  //www.zoranz.net/Publications/zivkovicPRL2006.pdf
+  //
+  //  Fast for small foreground object. Results on the benchmark data is at http://www.changedetection.net.
+  //------------------------------------------------------------------
+
+  int prevNSamples = nSamples;
+  if (firstTime)
+    knn = cv::createBackgroundSubtractorKNN(history, dist2Threshold, doShadowDetection);
+
+  knn->setNSamples(nSamples);
+  knn->setkNNSamples(knnSamples);
+  knn->setShadowValue(shadowValue);
+  knn->setShadowThreshold(shadowThreshold);
+
+  knn->apply(img_input, img_foreground, prevNSamples != nSamples ? 0.f : 1.f);
+  knn->getBackgroundImage(img_background);
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+  {
+    cv::imshow("KNN FG", img_foreground);
+    cv::imshow("KNN BG", img_background);
+  }
+#endif
+
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
+
+  firstTime = false;
+}
+
+void KNN::saveConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
+
+  cvWriteInt(fs, "history", history);
+  cvWriteInt(fs, "nSamples", nSamples);
+  cvWriteReal(fs, "dist2Threshold", dist2Threshold);
+  cvWriteInt(fs, "knnSamples", knnSamples);
+  cvWriteInt(fs, "doShadowDetection", doShadowDetection);
+  cvWriteInt(fs, "shadowValue", shadowValue);
+  cvWriteReal(fs, "shadowThreshold", shadowThreshold);
+  cvWriteInt(fs, "showOutput", showOutput);
+
+  cvReleaseFileStorage(&fs);
+}
+
+void KNN::loadConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  history = cvReadIntByName(fs, nullptr, "history", 500);
+  nSamples = cvReadIntByName(fs, nullptr, "nSamples", 7);
+  dist2Threshold = cvReadRealByName(fs, nullptr, "dist2Threshold", 20.0f * 20.0f);
+  knnSamples = cvReadIntByName(fs, nullptr, "knnSamples", 0);
+  doShadowDetection = cvReadIntByName(fs, nullptr, "doShadowDetection", 1);
+  shadowValue = cvReadIntByName(fs, nullptr, "shadowValue", 127);
+  shadowThreshold = cvReadRealByName(fs, nullptr, "shadowThreshold", 0.5f);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
+
+  cvReleaseFileStorage(&fs);
+}
+
+#endif
diff --git a/package_bgs/KNN.h b/package_bgs/KNN.h
new file mode 100644
index 0000000000000000000000000000000000000000..87f20b249444b5ad2da2864e6b30eb0b9b36e78b
--- /dev/null
+++ b/package_bgs/KNN.h
@@ -0,0 +1,57 @@
+/*
+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
+
+#include "opencv2/core/version.hpp"
+#if CV_MAJOR_VERSION == 3
+
+#include <iostream>
+#include <opencv2/opencv.hpp>
+#include <opencv2/video/background_segm.hpp>
+
+#include "IBGS.h"
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class KNN : public IBGS
+    {
+    private:
+      cv::Ptr<cv::BackgroundSubtractorKNN> knn;
+      int history;
+      int nSamples;
+      float dist2Threshold;
+      int knnSamples;
+      bool doShadowDetection;
+      int shadowValue;
+      float shadowThreshold;
+
+    public:
+      KNN();
+      ~KNN();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
+
+#endif
diff --git a/package_bgs/lb/LBAdaptiveSOM.cpp b/package_bgs/LBAdaptiveSOM.cpp
similarity index 61%
rename from package_bgs/lb/LBAdaptiveSOM.cpp
rename to package_bgs/LBAdaptiveSOM.cpp
index ce06433cf8ab1547a053bbf0576f7c2c6026009f..188e11d450ca29709fd5b1fcc567982ecb0f1360 100644
--- a/package_bgs/lb/LBAdaptiveSOM.cpp
+++ b/package_bgs/LBAdaptiveSOM.cpp
@@ -16,10 +16,13 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "LBAdaptiveSOM.h"
 
-LBAdaptiveSOM::LBAdaptiveSOM() : firstTime(true), showOutput(true), 
+using namespace bgslibrary::algorithms;
+
+LBAdaptiveSOM::LBAdaptiveSOM() :
   sensitivity(75), trainingSensitivity(245), learningRate(62), trainingLearningRate(255), trainingSteps(55)
 {
   std::cout << "LBAdaptiveSOM()" << std::endl;
+  setup("./config/LBAdaptiveSOM.xml");
 }
 
 LBAdaptiveSOM::~LBAdaptiveSOM()
@@ -30,64 +33,55 @@ LBAdaptiveSOM::~LBAdaptiveSOM()
 
 void LBAdaptiveSOM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
+  init(img_input, img_output, img_bgmodel);
 
-  loadConfig();
-  
   IplImage *frame = new IplImage(img_input);
-  
-  if(firstTime)
-  {
-    saveConfig();
 
+  if (firstTime)
+  {
     int w = cvGetSize(frame).width;
     int h = cvGetSize(frame).height;
 
-    m_pBGModel = new BGModelSom(w,h);
+    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->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::Mat(m_pBGModel->GetFG());
-  img_background = cv::Mat(m_pBGModel->GetBG());
-    
-  if(showOutput)
+  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 LBAdaptiveSOM::finish(void)
-//{
-//  delete m_pBGModel;
-//}
-
 void LBAdaptiveSOM::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/LBAdaptiveSOM.xml", 0, CV_STORAGE_WRITE);
+  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);
@@ -95,15 +89,14 @@ void LBAdaptiveSOM::saveConfig()
 
 void LBAdaptiveSOM::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/LBAdaptiveSOM.xml", 0, CV_STORAGE_READ);
-  
-  sensitivity          = cvReadIntByName(fs, 0, "sensitivity", 75);
-  trainingSensitivity  = cvReadIntByName(fs, 0, "trainingSensitivity", 245);
-  learningRate         = cvReadIntByName(fs, 0, "learningRate", 62);
-  trainingLearningRate = cvReadIntByName(fs, 0, "trainingLearningRate", 255);
-  trainingSteps        = cvReadIntByName(fs, 0, "trainingSteps", 55);
+  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);
-}
\ No newline at end of file
+}
diff --git a/package_bgs/lb/LBAdaptiveSOM.h b/package_bgs/LBAdaptiveSOM.h
similarity index 55%
rename from package_bgs/lb/LBAdaptiveSOM.h
rename to package_bgs/LBAdaptiveSOM.h
index beaf77b62a44cecc0ce4d43f754843847306efab..7671ae1df9ff0540e2c74e3da8d53c5d58cceccd 100644
--- a/package_bgs/lb/LBAdaptiveSOM.h
+++ b/package_bgs/LBAdaptiveSOM.h
@@ -16,41 +16,35 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "BGModelSom.h"
-
-#include "../IBGS.h"
+#include "lb/BGModelSom.h"
+#include "IBGS.h"
 
 using namespace lb_library;
 using namespace lb_library::AdaptiveSOM;
 
-class LBAdaptiveSOM : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  bool showOutput;
-  
-  BGModel* m_pBGModel;
-  int sensitivity;
-  int trainingSensitivity;
-  int learningRate;
-  int trainingLearningRate;
-  int trainingSteps;
-
-  cv::Mat img_foreground;
-  cv::Mat img_background;
-
-public:
-  LBAdaptiveSOM();
-  ~LBAdaptiveSOM();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-  //void finish(void);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
\ No newline at end of file
+  namespace algorithms
+  {
+    class LBAdaptiveSOM : public IBGS
+    {
+    private:
+      BGModel* m_pBGModel;
+      int sensitivity;
+      int trainingSensitivity;
+      int learningRate;
+      int trainingLearningRate;
+      int trainingSteps;
+
+    public:
+      LBAdaptiveSOM();
+      ~LBAdaptiveSOM();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/lb/LBFuzzyAdaptiveSOM.cpp b/package_bgs/LBFuzzyAdaptiveSOM.cpp
similarity index 59%
rename from package_bgs/lb/LBFuzzyAdaptiveSOM.cpp
rename to package_bgs/LBFuzzyAdaptiveSOM.cpp
index 4ef856028cbd063cda01e3aaacef7c702c9713d4..73df1d7ba56f18bc35f2ca667727495b254f7555 100644
--- a/package_bgs/lb/LBFuzzyAdaptiveSOM.cpp
+++ b/package_bgs/LBFuzzyAdaptiveSOM.cpp
@@ -16,10 +16,13 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "LBFuzzyAdaptiveSOM.h"
 
-LBFuzzyAdaptiveSOM::LBFuzzyAdaptiveSOM() : firstTime(true), showOutput(true), 
+using namespace bgslibrary::algorithms;
+
+LBFuzzyAdaptiveSOM::LBFuzzyAdaptiveSOM() :
   sensitivity(90), trainingSensitivity(240), learningRate(38), trainingLearningRate(255), trainingSteps(81)
 {
   std::cout << "LBFuzzyAdaptiveSOM()" << std::endl;
+  setup("./config/LBFuzzyAdaptiveSOM.xml");
 }
 
 LBFuzzyAdaptiveSOM::~LBFuzzyAdaptiveSOM()
@@ -30,64 +33,55 @@ LBFuzzyAdaptiveSOM::~LBFuzzyAdaptiveSOM()
 
 void LBFuzzyAdaptiveSOM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
+  init(img_input, img_output, img_bgmodel);
 
-  loadConfig();
-  
   IplImage *frame = new IplImage(img_input);
-  
-  if(firstTime)
-  {
-    saveConfig();
 
+  if (firstTime)
+  {
     int w = cvGetSize(frame).width;
     int h = cvGetSize(frame).height;
 
-    m_pBGModel = new BGModelFuzzySom(w,h);
+    m_pBGModel = new BGModelFuzzySom(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->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::Mat(m_pBGModel->GetFG());
-  img_background = cv::Mat(m_pBGModel->GetBG());
-    
-  if(showOutput)
+  img_foreground = cv::cvarrToMat(m_pBGModel->GetFG());
+  img_background = cv::cvarrToMat(m_pBGModel->GetBG());
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
   {
     cv::imshow("FSOM Mask", img_foreground);
     cv::imshow("FSOM Model", img_background);
   }
+#endif
 
   img_foreground.copyTo(img_output);
   img_background.copyTo(img_bgmodel);
-  
+
   delete frame;
-  
+
   firstTime = false;
 }
 
-//void LBFuzzyAdaptiveSOM::finish(void)
-//{
-//  //delete m_pBGModel;
-//}
-
 void LBFuzzyAdaptiveSOM::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/LBFuzzyAdaptiveSOM.xml", 0, CV_STORAGE_WRITE);
+  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);
@@ -95,15 +89,14 @@ void LBFuzzyAdaptiveSOM::saveConfig()
 
 void LBFuzzyAdaptiveSOM::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/LBFuzzyAdaptiveSOM.xml", 0, CV_STORAGE_READ);
-  
-  sensitivity          = cvReadIntByName(fs, 0, "sensitivity", 90);
-  trainingSensitivity  = cvReadIntByName(fs, 0, "trainingSensitivity", 240);
-  learningRate         = cvReadIntByName(fs, 0, "learningRate", 38);
-  trainingLearningRate = cvReadIntByName(fs, 0, "trainingLearningRate", 255);
-  trainingSteps        = cvReadIntByName(fs, 0, "trainingSteps", 81);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
 
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  sensitivity = cvReadIntByName(fs, nullptr, "sensitivity", 90);
+  trainingSensitivity = cvReadIntByName(fs, nullptr, "trainingSensitivity", 240);
+  learningRate = cvReadIntByName(fs, nullptr, "learningRate", 38);
+  trainingLearningRate = cvReadIntByName(fs, nullptr, "trainingLearningRate", 255);
+  trainingSteps = cvReadIntByName(fs, nullptr, "trainingSteps", 81);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
-}
\ No newline at end of file
+}
diff --git a/package_bgs/lb/LBFuzzyAdaptiveSOM.h b/package_bgs/LBFuzzyAdaptiveSOM.h
similarity index 55%
rename from package_bgs/lb/LBFuzzyAdaptiveSOM.h
rename to package_bgs/LBFuzzyAdaptiveSOM.h
index 9c11d7568c46e8463424145cc6aae72c99ed58c0..6a4a85c0007951b3a82b6f11941e669d16430332 100644
--- a/package_bgs/lb/LBFuzzyAdaptiveSOM.h
+++ b/package_bgs/LBFuzzyAdaptiveSOM.h
@@ -16,41 +16,35 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "BGModelFuzzySom.h"
-
-#include "../IBGS.h"
+#include "IBGS.h"
+#include "lb/BGModelFuzzySom.h"
 
 using namespace lb_library;
 using namespace lb_library::FuzzyAdaptiveSOM;
 
-class LBFuzzyAdaptiveSOM : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  bool showOutput;
-  
-  BGModel* m_pBGModel;
-  int sensitivity;
-  int trainingSensitivity;
-  int learningRate;
-  int trainingLearningRate;
-  int trainingSteps;
-
-  cv::Mat img_foreground;
-  cv::Mat img_background;
-
-public:
-  LBFuzzyAdaptiveSOM();
-  ~LBFuzzyAdaptiveSOM();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-  //void finish(void);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
\ No newline at end of file
+  namespace algorithms
+  {
+    class LBFuzzyAdaptiveSOM : public IBGS
+    {
+    private:
+      BGModel* m_pBGModel;
+      int sensitivity;
+      int trainingSensitivity;
+      int learningRate;
+      int trainingLearningRate;
+      int trainingSteps;
+
+    public:
+      LBFuzzyAdaptiveSOM();
+      ~LBFuzzyAdaptiveSOM();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/lb/LBFuzzyGaussian.cpp b/package_bgs/LBFuzzyGaussian.cpp
similarity index 59%
rename from package_bgs/lb/LBFuzzyGaussian.cpp
rename to package_bgs/LBFuzzyGaussian.cpp
index dc257bf40325167efbe49220be9d08f9f745d4f7..b1610260bf407bc19a0750234fed4e1528ea7f06 100644
--- a/package_bgs/lb/LBFuzzyGaussian.cpp
+++ b/package_bgs/LBFuzzyGaussian.cpp
@@ -16,9 +16,13 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "LBFuzzyGaussian.h"
 
-LBFuzzyGaussian::LBFuzzyGaussian() : firstTime(true), showOutput(true), sensitivity(72), bgThreshold(162), learningRate(49), noiseVariance(195)
+using namespace bgslibrary::algorithms;
+
+LBFuzzyGaussian::LBFuzzyGaussian() :
+  sensitivity(72), bgThreshold(162), learningRate(49), noiseVariance(195)
 {
   std::cout << "LBFuzzyGaussian()" << std::endl;
+  setup("./config/LBFuzzyGaussian.xml");
 }
 
 LBFuzzyGaussian::~LBFuzzyGaussian()
@@ -29,62 +33,53 @@ LBFuzzyGaussian::~LBFuzzyGaussian()
 
 void LBFuzzyGaussian::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
+  init(img_input, img_output, img_bgmodel);
 
-  loadConfig();
-  
   IplImage *frame = new IplImage(img_input);
-  
-  if(firstTime)
-  {
-    saveConfig();
 
+  if (firstTime)
+  {
     int w = cvGetSize(frame).width;
     int h = cvGetSize(frame).height;
 
-    m_pBGModel = new BGModelFuzzyGauss(w,h);
+    m_pBGModel = new BGModelFuzzyGauss(w, h);
     m_pBGModel->InitModel(frame);
   }
-  
-  m_pBGModel->setBGModelParameter(0,sensitivity);
-  m_pBGModel->setBGModelParameter(1,bgThreshold);
-  m_pBGModel->setBGModelParameter(2,learningRate);
-  m_pBGModel->setBGModelParameter(3,noiseVariance);
+
+  m_pBGModel->setBGModelParameter(0, sensitivity);
+  m_pBGModel->setBGModelParameter(1, bgThreshold);
+  m_pBGModel->setBGModelParameter(2, learningRate);
+  m_pBGModel->setBGModelParameter(3, noiseVariance);
 
   m_pBGModel->UpdateModel(frame);
 
-  img_foreground = cv::Mat(m_pBGModel->GetFG());
-  img_background = cv::Mat(m_pBGModel->GetBG());
-    
-  if(showOutput)
+  img_foreground = cv::cvarrToMat(m_pBGModel->GetFG());
+  img_background = cv::cvarrToMat(m_pBGModel->GetBG());
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
   {
     cv::imshow("FG Mask", img_foreground);
     cv::imshow("FG Model", img_background);
   }
+#endif
 
   img_foreground.copyTo(img_output);
   img_background.copyTo(img_bgmodel);
-  
+
   delete frame;
-  
+
   firstTime = false;
 }
 
-//void LBFuzzyGaussian::finish(void)
-//{
-//  delete m_pBGModel;
-//}
-
 void LBFuzzyGaussian::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/LBFuzzyGaussian.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteInt(fs, "sensitivity", sensitivity);
   cvWriteInt(fs, "bgThreshold", bgThreshold);
   cvWriteInt(fs, "learningRate", learningRate);
   cvWriteInt(fs, "noiseVariance", noiseVariance);
-  
   cvWriteInt(fs, "showOutput", showOutput);
 
   cvReleaseFileStorage(&fs);
@@ -92,14 +87,13 @@ void LBFuzzyGaussian::saveConfig()
 
 void LBFuzzyGaussian::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/LBFuzzyGaussian.xml", 0, CV_STORAGE_READ);
-  
-  sensitivity = cvReadIntByName(fs, 0, "sensitivity", 72);
-  bgThreshold = cvReadIntByName(fs, 0, "bgThreshold", 162);
-  learningRate = cvReadIntByName(fs, 0, "learningRate", 49);
-  noiseVariance = cvReadIntByName(fs, 0, "noiseVariance", 195);
-  
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  sensitivity = cvReadIntByName(fs, nullptr, "sensitivity", 72);
+  bgThreshold = cvReadIntByName(fs, nullptr, "bgThreshold", 162);
+  learningRate = cvReadIntByName(fs, nullptr, "learningRate", 49);
+  noiseVariance = cvReadIntByName(fs, nullptr, "noiseVariance", 195);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/lb/LBFuzzyGaussian.h b/package_bgs/LBFuzzyGaussian.h
similarity index 56%
rename from package_bgs/lb/LBFuzzyGaussian.h
rename to package_bgs/LBFuzzyGaussian.h
index f76156ef20ed1152e280a8de60f5fca966119ed7..53c26679d55f1d7720b1eabbce8486f609e7c15d 100644
--- a/package_bgs/lb/LBFuzzyGaussian.h
+++ b/package_bgs/LBFuzzyGaussian.h
@@ -16,40 +16,34 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "BGModelFuzzyGauss.h"
-
-#include "../IBGS.h"
+#include "IBGS.h"
+#include "lb/BGModelFuzzyGauss.h"
 
 using namespace lb_library;
 using namespace lb_library::FuzzyGaussian;
 
-class LBFuzzyGaussian : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  bool showOutput;
-  
-  BGModel* m_pBGModel;
-  int sensitivity;
-  int bgThreshold;
-  int learningRate;
-  int noiseVariance;
-
-  cv::Mat img_foreground;
-  cv::Mat img_background;
-
-public:
-  LBFuzzyGaussian();
-  ~LBFuzzyGaussian();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-  //void finish(void);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
\ No newline at end of file
+  namespace algorithms
+  {
+    class LBFuzzyGaussian : public IBGS
+    {
+    private:
+      BGModel* m_pBGModel;
+      int sensitivity;
+      int bgThreshold;
+      int learningRate;
+      int noiseVariance;
+
+    public:
+      LBFuzzyGaussian();
+      ~LBFuzzyGaussian();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/lb/LBMixtureOfGaussians.cpp b/package_bgs/LBMixtureOfGaussians.cpp
similarity index 59%
rename from package_bgs/lb/LBMixtureOfGaussians.cpp
rename to package_bgs/LBMixtureOfGaussians.cpp
index 8d235c506601f7b2a57379810c3fcd9c4ee75779..6cd9c917ca6d9fddbc01e94e7eb71a998418ba5e 100644
--- a/package_bgs/lb/LBMixtureOfGaussians.cpp
+++ b/package_bgs/LBMixtureOfGaussians.cpp
@@ -16,9 +16,13 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "LBMixtureOfGaussians.h"
 
-LBMixtureOfGaussians::LBMixtureOfGaussians() : firstTime(true), showOutput(true), sensitivity(81), bgThreshold(83), learningRate(59), noiseVariance(206)
+using namespace bgslibrary::algorithms;
+
+LBMixtureOfGaussians::LBMixtureOfGaussians() :
+  sensitivity(81), bgThreshold(83), learningRate(59), noiseVariance(206)
 {
   std::cout << "LBMixtureOfGaussians()" << std::endl;
+  setup("./config/LBMixtureOfGaussians.xml");
 }
 
 LBMixtureOfGaussians::~LBMixtureOfGaussians()
@@ -29,62 +33,53 @@ LBMixtureOfGaussians::~LBMixtureOfGaussians()
 
 void LBMixtureOfGaussians::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
+  init(img_input, img_output, img_bgmodel);
 
-  loadConfig();
-  
   IplImage *frame = new IplImage(img_input);
-  
-  if(firstTime)
-  {
-    saveConfig();
 
+  if (firstTime)
+  {
     int w = cvGetSize(frame).width;
     int h = cvGetSize(frame).height;
 
-    m_pBGModel = new BGModelMog(w,h);
+    m_pBGModel = new BGModelMog(w, h);
     m_pBGModel->InitModel(frame);
   }
-  
-  m_pBGModel->setBGModelParameter(0,sensitivity);
-  m_pBGModel->setBGModelParameter(1,bgThreshold);
-  m_pBGModel->setBGModelParameter(2,learningRate);
-  m_pBGModel->setBGModelParameter(3,noiseVariance);
+
+  m_pBGModel->setBGModelParameter(0, sensitivity);
+  m_pBGModel->setBGModelParameter(1, bgThreshold);
+  m_pBGModel->setBGModelParameter(2, learningRate);
+  m_pBGModel->setBGModelParameter(3, noiseVariance);
 
   m_pBGModel->UpdateModel(frame);
 
-  img_foreground = cv::Mat(m_pBGModel->GetFG());
-  img_background = cv::Mat(m_pBGModel->GetBG());
-    
-  if(showOutput)
+  img_foreground = cv::cvarrToMat(m_pBGModel->GetFG());
+  img_background = cv::cvarrToMat(m_pBGModel->GetBG());
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
   {
     cv::imshow("MOG Mask", img_foreground);
     cv::imshow("MOG Model", img_background);
   }
+#endif
 
   img_foreground.copyTo(img_output);
   img_background.copyTo(img_bgmodel);
-  
+
   delete frame;
-  
+
   firstTime = false;
 }
 
-//void LBMixtureOfGaussians::finish(void)
-//{
-//  delete m_pBGModel;
-//}
-
 void LBMixtureOfGaussians::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/LBMixtureOfGaussians.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteInt(fs, "sensitivity", sensitivity);
   cvWriteInt(fs, "bgThreshold", bgThreshold);
   cvWriteInt(fs, "learningRate", learningRate);
   cvWriteInt(fs, "noiseVariance", noiseVariance);
-  
   cvWriteInt(fs, "showOutput", showOutput);
 
   cvReleaseFileStorage(&fs);
@@ -92,14 +87,13 @@ void LBMixtureOfGaussians::saveConfig()
 
 void LBMixtureOfGaussians::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/LBMixtureOfGaussians.xml", 0, CV_STORAGE_READ);
-  
-  sensitivity = cvReadIntByName(fs, 0, "sensitivity", 81);
-  bgThreshold = cvReadIntByName(fs, 0, "bgThreshold", 83);
-  learningRate = cvReadIntByName(fs, 0, "learningRate", 59);
-  noiseVariance = cvReadIntByName(fs, 0, "noiseVariance", 206);
-  
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  sensitivity = cvReadIntByName(fs, nullptr, "sensitivity", 81);
+  bgThreshold = cvReadIntByName(fs, nullptr, "bgThreshold", 83);
+  learningRate = cvReadIntByName(fs, nullptr, "learningRate", 59);
+  noiseVariance = cvReadIntByName(fs, nullptr, "noiseVariance", 206);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
-}
\ No newline at end of file
+}
diff --git a/package_bgs/lb/LBMixtureOfGaussians.h b/package_bgs/LBMixtureOfGaussians.h
similarity index 56%
rename from package_bgs/lb/LBMixtureOfGaussians.h
rename to package_bgs/LBMixtureOfGaussians.h
index 3b1a96d9cc166dbd89804c86a75df68f646e00ff..8d4cb5619d42f85a74491cea340615f869b72d9a 100644
--- a/package_bgs/lb/LBMixtureOfGaussians.h
+++ b/package_bgs/LBMixtureOfGaussians.h
@@ -16,40 +16,35 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "BGModelMog.h"
-
-#include "../IBGS.h"
+#include "IBGS.h"
+#include "lb/BGModelMog.h"
 
 using namespace lb_library;
 using namespace lb_library::MixtureOfGaussians;
 
-class LBMixtureOfGaussians : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  bool showOutput;
-  
-  BGModel* m_pBGModel;
-  int sensitivity;
-  int bgThreshold;
-  int learningRate;
-  int noiseVariance;
-
-  cv::Mat img_foreground;
-  cv::Mat img_background;
-
-public:
-  LBMixtureOfGaussians();
-  ~LBMixtureOfGaussians();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-  //void finish(void);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
\ No newline at end of file
+  namespace algorithms
+  {
+    class LBMixtureOfGaussians : public IBGS
+    {
+    private:
+      BGModel* m_pBGModel;
+      int sensitivity;
+      int bgThreshold;
+      int learningRate;
+      int noiseVariance;
+
+    public:
+      LBMixtureOfGaussians();
+      ~LBMixtureOfGaussians();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
+
diff --git a/package_bgs/ck/LbpMrf.cpp b/package_bgs/LBP_MRF.cpp
similarity index 57%
rename from package_bgs/ck/LbpMrf.cpp
rename to package_bgs/LBP_MRF.cpp
index f3d068c253505783976837916c3e4611bbed63bb..b9e6bbe019511ccff12706fd40f4effbb479c054 100644
--- a/package_bgs/ck/LbpMrf.cpp
+++ b/package_bgs/LBP_MRF.cpp
@@ -18,35 +18,29 @@ Csaba, Kertész: Texture-Based Foreground Detection, International Journal of Si
 Image Processing and Pattern Recognition (IJSIP), Vol. 4, No. 4, 2011.
 
 */
-#include "LbpMrf.h"
+#include "LBP_MRF.h"
 
-#include "MotionDetection.hpp"
+using namespace bgslibrary::algorithms;
 
-LbpMrf::LbpMrf() : firstTime(true), Detector(NULL), showOutput(true)
+LBP_MRF::LBP_MRF() :
+  Detector(nullptr)
 {
-  std::cout << "LbpMrf()" << std::endl;
+  std::cout << "LBP_MRF()" << std::endl;
+  setup("./config/LBP_MRF.xml");
   Detector = new MotionDetection();
   Detector->SetMode(MotionDetection::md_LBPHistograms);
 }
 
-LbpMrf::~LbpMrf()
+LBP_MRF::~LBP_MRF()
 {
-  std::cout << "~LbpMrf()" << std::endl;
+  std::cout << "~LBP_MRF()" << std::endl;
   delete Detector;
-  Detector = NULL;
+  Detector = nullptr;
 }
 
-void LbpMrf::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+void LBP_MRF::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if(firstTime)
-  {
-    saveConfig();
-  }
+  init(img_input, img_output, img_bgmodel);
 
   IplImage TempImage(img_input);
   MEImage InputImage(img_input.cols, img_input.rows, img_input.channels());
@@ -56,32 +50,35 @@ void LbpMrf::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img
 
   Detector->DetectMotions(InputImage);
   Detector->GetMotionsMask(OutputImage);
-  img_output = (IplImage*)OutputImage.GetIplImage();
-  bitwise_not(img_output, img_bgmodel);
+  img_foreground = cv::cvarrToMat((IplImage*)OutputImage.GetIplImage());
+  //bitwise_not(img_foreground, img_background);
+  img_background = cv::Mat::zeros(img_input.size(), img_input.type());
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+    cv::imshow("LBP-MRF FG", img_foreground);
+#endif
 
-  if(showOutput)
-  {
-    cv::imshow("LBP-MRF FG", img_output);
-    cv::imshow("LBP-MRF BG", img_bgmodel);
-  }
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
 
   firstTime = false;
 }
 
-void LbpMrf::saveConfig()
+void LBP_MRF::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/LbpMrf.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteInt(fs, "showOutput", showOutput);
 
   cvReleaseFileStorage(&fs);
 }
 
-void LbpMrf::loadConfig()
+void LBP_MRF::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/LbpMrf.xml", 0, CV_STORAGE_READ);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
 
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/WeightedMovingMeanBGS.h b/package_bgs/LBP_MRF.h
similarity index 58%
rename from package_bgs/WeightedMovingMeanBGS.h
rename to package_bgs/LBP_MRF.h
index 6f72306c10a18debc70d5e87a1cc8f5b20fd08e9..a6e5c05b984d6ee3c8beb6cc97f94804a8de506d 100644
--- a/package_bgs/WeightedMovingMeanBGS.h
+++ b/package_bgs/LBP_MRF.h
@@ -16,32 +16,28 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
 #include "IBGS.h"
+#include "LBP_MRF/MotionDetection.hpp"
 
-class WeightedMovingMeanBGS : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  cv::Mat img_input_prev_1;
-  cv::Mat img_input_prev_2;
-  bool enableWeight;
-  bool enableThreshold;
-  int threshold;
-  bool showOutput;
-  bool showBackground;
-
-public:
-  WeightedMovingMeanBGS();
-  ~WeightedMovingMeanBGS();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
-
+  namespace algorithms
+  {
+    class LBP_MRF : public IBGS
+    {
+    private:
+      MotionDetection* Detector;
+      cv::Mat img_segmentation;
+
+    public:
+      LBP_MRF();
+      ~LBP_MRF();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/LBP_MRF/MEDefs.cpp b/package_bgs/LBP_MRF/MEDefs.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..95b803333991104738bf58a771f7ff4882f9c488
--- /dev/null
+++ b/package_bgs/LBP_MRF/MEDefs.cpp
@@ -0,0 +1,57 @@
+/*
+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/>.
+*/
+/*
+ *  This file is part of the AiBO+ project
+ *
+ *  Copyright (C) 2005-2013 Csaba Kertész (csaba.kertesz@gmail.com)
+ *
+ *  AiBO+ 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 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  AiBO+ 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "MEDefs.hpp"
+
+#include <math.h>
+
+float MERound(float number)
+{
+  double FracPart = 0.0;
+  double IntPart = 0.0;
+  float Ret = 0.0;
+
+  FracPart = modf((double)number, &IntPart);
+  if (number >= 0)
+  {
+    Ret = (float)(FracPart >= 0.5 ? IntPart + 1 : IntPart);
+  }
+  else {
+    Ret = (float)(FracPart <= -0.5 ? IntPart - 1 : IntPart);
+  }
+  return Ret;
+}
diff --git a/package_bgs/ck/MEDefs.hpp b/package_bgs/LBP_MRF/MEDefs.hpp
similarity index 73%
rename from package_bgs/ck/MEDefs.hpp
rename to package_bgs/LBP_MRF/MEDefs.hpp
index d5bc24637555a67639842a9269ea758d605db9dd..a886ee9ff3be75eb4c3841b38609fbd33dc30037 100644
--- a/package_bgs/ck/MEDefs.hpp
+++ b/package_bgs/LBP_MRF/MEDefs.hpp
@@ -1,3 +1,19 @@
+/*
+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/>.
+*/
 /*
  *  This file is part of the AiBO+ project
  *
@@ -18,16 +34,9 @@
  *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
  *
  */
+#pragma once
 
-#ifndef MEDefs_hpp
-#define MEDefs_hpp
-
-/**
- *  @addtogroup mindeye
- *  @{
- */
-
-/// Pi value
+ /// Pi value
 #ifndef ME_PI_VALUE
 #define ME_PI_VALUE 3.14159265
 #endif
@@ -79,5 +88,3 @@ const T& MEBound(const T& min, const T& val, const T& max)
 float MERound(float number);
 
 /** @} */
-
-#endif
diff --git a/package_bgs/ck/MEHistogram.cpp b/package_bgs/LBP_MRF/MEHistogram.cpp
similarity index 54%
rename from package_bgs/ck/MEHistogram.cpp
rename to package_bgs/LBP_MRF/MEHistogram.cpp
index 09a96724763d527a63f3dd6167dcf7d1b7815e3a..17c77fdb9079f40391229f37401e64dd5b0e2b1e 100644
--- a/package_bgs/ck/MEHistogram.cpp
+++ b/package_bgs/LBP_MRF/MEHistogram.cpp
@@ -1,3 +1,19 @@
+/*
+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/>.
+*/
 /*
  *  This file is part of the AiBO+ project
  *
@@ -45,7 +61,7 @@ MEHistogram::~MEHistogram()
 
 void MEHistogram::Clear()
 {
-  memset(&HistogramData, 0, 256*sizeof(int));
+  memset(&HistogramData, 0, 256 * sizeof(int));
 }
 
 
@@ -77,11 +93,11 @@ void MEHistogram::Calculate(MEImage& image, int channel, HistogramType mode)
   unsigned char *ImageData = image.GetImageData();
   int rowStart = 0;
 
-  for (int i = image.GetHeight()-1; i >= 0; i--)
+  for (int i = image.GetHeight() - 1; i >= 0; i--)
   {
-    for (int i1 = (image.GetWidth()-1)*image.GetLayers()+Channel-1; i1 >= Channel-1; i1 -= image.GetLayers())
+    for (int i1 = (image.GetWidth() - 1)*image.GetLayers() + Channel - 1; i1 >= Channel - 1; i1 -= image.GetLayers())
     {
-      HistogramData[ImageData[rowStart+i1]]++;
+      HistogramData[ImageData[rowStart + i1]]++;
     }
     rowStart += image.GetRowWidth();
   }
@@ -99,11 +115,11 @@ void MEHistogram::Calculate(MEImage& image, HistogramType mode)
   int RowStart = 0;
   int RowWidth = image.GetRowWidth();
 
-  for (int i = image.GetHeight()-1; i >= 0; i--)
+  for (int i = image.GetHeight() - 1; i >= 0; i--)
   {
-    for (int i1 = image.GetWidth()*image.GetLayers()-1; i1 >= 0; i1--)
+    for (int i1 = image.GetWidth()*image.GetLayers() - 1; i1 >= 0; i1--)
     {
-      HistogramData[ImageData[RowStart+i1]]++;
+      HistogramData[ImageData[RowStart + i1]]++;
     }
     RowStart += RowWidth;
   }
@@ -126,16 +142,16 @@ void MEHistogram::Calculate(MEImage& image, int channel, int x0, int y0, int x1,
   // Compute the correct region coordinates and check them
   X0 = X0 < 0 ? 0 : X0;
   Y0 = Y0 < 0 ? 0 : Y0;
-  X1 = X1 > image.GetWidth()-1 ? image.GetWidth()-1 : X1;
-  Y1 = Y1 > image.GetHeight()-1 ? image.GetHeight()-1 : Y1;
+  X1 = X1 > image.GetWidth() - 1 ? image.GetWidth() - 1 : X1;
+  Y1 = Y1 > image.GetHeight() - 1 ? image.GetHeight() - 1 : Y1;
   RowStart = Y0*image.GetRowWidth();
 
   for (int i = Y1; i >= Y0; --i)
   {
-    for (int i1 = X1*image.GetLayers()+Channel-1; i1 >= X0*image.GetLayers()+Channel-1;
-         i1 -= image.GetLayers())
+    for (int i1 = X1*image.GetLayers() + Channel - 1; i1 >= X0*image.GetLayers() + Channel - 1;
+      i1 -= image.GetLayers())
     {
-      HistogramData[ImageData[RowStart+i1]]++;
+      HistogramData[ImageData[RowStart + i1]]++;
     }
     RowStart += RowWidth;
   }
@@ -242,70 +258,70 @@ bool MEHistogram::Stretch(StretchType mode)
 
   switch (mode)
   {
-    case s_OwnMode:
-      Percent = 20;
+  case s_OwnMode:
+    Percent = 20;
+    MinIndex = GetLowestLimitIndex(Percent);
+    MaxIndex = GetHighestLimitIndex(Percent);
+
+    while ((abs(MaxIndex - MinIndex) < 52) && (Percent > 1))
+    {
+      Percent = Percent / 2;
       MinIndex = GetLowestLimitIndex(Percent);
       MaxIndex = GetHighestLimitIndex(Percent);
 
-      while ((abs(MaxIndex-MinIndex) < 52) && (Percent > 1))
+      // The calculation gives wrong answer back
+      if (MinIndex == 0 && MaxIndex == 255)
       {
-        Percent = Percent / 2;
-        MinIndex = GetLowestLimitIndex(Percent);
-        MaxIndex = GetHighestLimitIndex(Percent);
-
-        // The calculation gives wrong answer back
-        if (MinIndex == 0 && MaxIndex == 255)
-        {
-          MinIndex = 128;
-          MaxIndex = 128;
-          Ret = false;
-        }
+        MinIndex = 128;
+        MaxIndex = 128;
+        Ret = false;
       }
-      break;
+    }
+    break;
 
-    case s_GimpMode:
-      Count = GetPowerAmount(0, 255);
-      NewCount = 0;
+  case s_GimpMode:
+    Count = GetPowerAmount(0, 255);
+    NewCount = 0;
 
-      for (int i = 0; i < 255; i++)
-      {
-        double Value = 0.0;
-        double NextValue = 0.0;
+    for (int i = 0; i < 255; i++)
+    {
+      double Value = 0.0;
+      double NextValue = 0.0;
 
-        Value = HistogramData[i];
-        NextValue = HistogramData[i+1];
-        NewCount += Value;
-        Percentage = NewCount / Count;
-        NextPercentage = (NewCount+NextValue) / Count;
+      Value = HistogramData[i];
+      NextValue = HistogramData[i + 1];
+      NewCount += Value;
+      Percentage = NewCount / Count;
+      NextPercentage = (NewCount + NextValue) / Count;
 
-        if (fabs(Percentage-0.006) < fabs(NextPercentage-0.006))
-        {
-          MinIndex = i+1;
-          break;
-        }
-      }
-      NewCount = 0.0;
-      for (int i = 255; i > 0; i--)
+      if (fabs(Percentage - 0.006) < fabs(NextPercentage - 0.006))
       {
-        double Value = 0.0;
-        double NextValue = 0.0;
+        MinIndex = i + 1;
+        break;
+      }
+    }
+    NewCount = 0.0;
+    for (int i = 255; i > 0; i--)
+    {
+      double Value = 0.0;
+      double NextValue = 0.0;
 
-        Value = HistogramData[i];
-        NextValue = HistogramData[i-1];
-        NewCount += Value;
-        Percentage = NewCount / Count;
-        NextPercentage = (NewCount+NextValue) / Count;
+      Value = HistogramData[i];
+      NextValue = HistogramData[i - 1];
+      NewCount += Value;
+      Percentage = NewCount / Count;
+      NextPercentage = (NewCount + NextValue) / Count;
 
-        if (fabs(Percentage-0.006) < fabs(NextPercentage-0.006))
-        {
-          MaxIndex = i-1;
-          break;
-        }
+      if (fabs(Percentage - 0.006) < fabs(NextPercentage - 0.006))
+      {
+        MaxIndex = i - 1;
+        break;
       }
-      break;
+    }
+    break;
 
-    default:
-      break;
+  default:
+    break;
   }
 
   if (MaxIndex <= MinIndex)
@@ -314,8 +330,8 @@ bool MEHistogram::Stretch(StretchType mode)
     MaxIndex = 255;
     Ret = false;
   }
-  if (MaxIndex-MinIndex <= 10 ||
-      (MaxIndex-MinIndex <= 20 && (float)GetPowerAmount(MinIndex, MaxIndex) / GetPowerAmount(0, 255) < 0.20))
+  if (MaxIndex - MinIndex <= 10 ||
+    (MaxIndex - MinIndex <= 20 && (float)GetPowerAmount(MinIndex, MaxIndex) / GetPowerAmount(0, 255) < 0.20))
   {
     MinIndex = 0;
     MaxIndex = 255;
@@ -327,7 +343,7 @@ bool MEHistogram::Stretch(StretchType mode)
 
     for (int i = 0; i < 256; ++i)
     {
-      TransformedHistogram[i] = (unsigned char)MEBound(0, 255*(i-MinIndex) / (MaxIndex-MinIndex), 255);
+      TransformedHistogram[i] = (unsigned char)MEBound(0, 255 * (i - MinIndex) / (MaxIndex - MinIndex), 255);
     }
     for (int i = 0; i < 256; ++i)
     {
@@ -371,7 +387,7 @@ void MEHistogramTransform::HistogramStretch(MEImage& image, TransformType time_m
 
       for (int l = 1; l < image.GetLayers(); l++)
       {
-        RedChannel.Calculate(image, l+1, MEHistogram::h_Add);
+        RedChannel.Calculate(image, l + 1, MEHistogram::h_Add);
       }
       RedChannel.Stretch(StretchMode);
       if (time_mode == t_Discrete && !DiscreteStretchingDone)
@@ -383,45 +399,46 @@ void MEHistogramTransform::HistogramStretch(MEImage& image, TransformType time_m
     int RowStart = 0;
     int RowWidth = image.GetRowWidth();
 
-    for (int i = image.GetHeight()-1; i >= 0; i--)
+    for (int i = image.GetHeight() - 1; i >= 0; i--)
     {
-      for (int i1 = image.GetWidth()*image.GetLayers()-1; i1 >= 0; i1--)
+      for (int i1 = image.GetWidth()*image.GetLayers() - 1; i1 >= 0; i1--)
       {
-        ImageData[RowStart+i1] = RedChannel.HistogramData[ImageData[RowStart+i1]];
+        ImageData[RowStart + i1] = RedChannel.HistogramData[ImageData[RowStart + i1]];
       }
       RowStart += RowWidth;
     }
-  } else
-  if (ChannelMode == p_SeparateChannels)
-  {
-    if (time_mode == t_Continuous || (time_mode == t_Discrete && !DiscreteStretchingDone))
+  }
+  else
+    if (ChannelMode == p_SeparateChannels)
     {
-      RedChannel.Calculate(image, 1, MEHistogram::h_Overwrite);
-      GreenChannel.Calculate(image, 2, MEHistogram::h_Overwrite);
-      BlueChannel.Calculate(image, 3, MEHistogram::h_Overwrite);
-      RedChannel.Stretch(StretchMode);
-      GreenChannel.Stretch(StretchMode);
-      BlueChannel.Stretch(StretchMode);
-      if (time_mode == t_Discrete && !DiscreteStretchingDone)
+      if (time_mode == t_Continuous || (time_mode == t_Discrete && !DiscreteStretchingDone))
       {
-        DiscreteStretchingDone = true;
+        RedChannel.Calculate(image, 1, MEHistogram::h_Overwrite);
+        GreenChannel.Calculate(image, 2, MEHistogram::h_Overwrite);
+        BlueChannel.Calculate(image, 3, MEHistogram::h_Overwrite);
+        RedChannel.Stretch(StretchMode);
+        GreenChannel.Stretch(StretchMode);
+        BlueChannel.Stretch(StretchMode);
+        if (time_mode == t_Discrete && !DiscreteStretchingDone)
+        {
+          DiscreteStretchingDone = true;
+        }
       }
-    }
-    unsigned char *ImageData = image.GetImageData();
-    int RowStart = 0;
-    int RowWidth = image.GetRowWidth();
+      unsigned char *ImageData = image.GetImageData();
+      int RowStart = 0;
+      int RowWidth = image.GetRowWidth();
 
-    for (int i = image.GetHeight()-1; i >= 0; i--)
-    {
-      for (int i1 = image.GetWidth()*image.GetLayers()-3; i1 >= 0; i1 -= 3)
+      for (int i = image.GetHeight() - 1; i >= 0; i--)
       {
-        ImageData[RowStart+i1] = RedChannel.HistogramData[ImageData[RowStart+i1]];
-        ImageData[RowStart+i1+1] = GreenChannel.HistogramData[ImageData[RowStart+i1+1]];
-        ImageData[RowStart+i1+2] = BlueChannel.HistogramData[ImageData[RowStart+i1+2]];
+        for (int i1 = image.GetWidth()*image.GetLayers() - 3; i1 >= 0; i1 -= 3)
+        {
+          ImageData[RowStart + i1] = RedChannel.HistogramData[ImageData[RowStart + i1]];
+          ImageData[RowStart + i1 + 1] = GreenChannel.HistogramData[ImageData[RowStart + i1 + 1]];
+          ImageData[RowStart + i1 + 2] = BlueChannel.HistogramData[ImageData[RowStart + i1 + 2]];
+        }
+        RowStart += RowWidth;
       }
-      RowStart += RowWidth;
     }
-  }
 }
 
 
@@ -433,72 +450,72 @@ void MEHistogramTransform::HistogramEqualize(MEImage& image)
 
   switch (image.GetLayers())
   {
-    case 1:
-      // Grayscale image
-      cvDest8bitImg = cvCreateImage(cvSize(image.GetWidth(), image.GetHeight()), 8, 1);
-      cvEqualizeHist((IplImage*)image.GetIplImage(), cvDest8bitImg);
-      image.SetIplImage((void*)cvDest8bitImg);
-      cvReleaseImage(&cvDest8bitImg);
-      break;
-
-    case 3:
-      // RGB image
-      cvDestImg = cvCreateImage(cvSize(image.GetWidth(), image.GetHeight()), 8, 3);
-      IplImage *cvR, *cvG, *cvB;
-
-      cvR = cvCreateImage(cvSize(image.GetWidth(), image.GetHeight()), 8, 1);
-      cvG = cvCreateImage(cvSize(image.GetWidth(), image.GetHeight()), 8, 1);
-      cvB = cvCreateImage(cvSize(image.GetWidth(), image.GetHeight()), 8, 1);
-
-      cvSplit((IplImage*)image.GetIplImage(), cvR, cvG, cvB, NULL);
-      cvEqualizeHist(cvR, cvR);
-      cvEqualizeHist(cvG, cvG);
-      cvEqualizeHist(cvB, cvB);
-      cvMerge(cvR, cvG, cvB, NULL, cvDestImg);
-
-      image.SetIplImage((void*)cvDestImg);
-      cvReleaseImage(&cvR);
-      cvReleaseImage(&cvG);
-      cvReleaseImage(&cvB);
-      cvReleaseImage(&cvDestImg);
-      break;
-
-    default:
-      break;
+  case 1:
+    // Grayscale image
+    cvDest8bitImg = cvCreateImage(cvSize(image.GetWidth(), image.GetHeight()), 8, 1);
+    cvEqualizeHist((IplImage*)image.GetIplImage(), cvDest8bitImg);
+    image.SetIplImage((void*)cvDest8bitImg);
+    cvReleaseImage(&cvDest8bitImg);
+    break;
+
+  case 3:
+    // RGB image
+    cvDestImg = cvCreateImage(cvSize(image.GetWidth(), image.GetHeight()), 8, 3);
+    IplImage *cvR, *cvG, *cvB;
+
+    cvR = cvCreateImage(cvSize(image.GetWidth(), image.GetHeight()), 8, 1);
+    cvG = cvCreateImage(cvSize(image.GetWidth(), image.GetHeight()), 8, 1);
+    cvB = cvCreateImage(cvSize(image.GetWidth(), image.GetHeight()), 8, 1);
+
+    cvSplit((IplImage*)image.GetIplImage(), cvR, cvG, cvB, NULL);
+    cvEqualizeHist(cvR, cvR);
+    cvEqualizeHist(cvG, cvG);
+    cvEqualizeHist(cvB, cvB);
+    cvMerge(cvR, cvG, cvB, NULL, cvDestImg);
+
+    image.SetIplImage((void*)cvDestImg);
+    cvReleaseImage(&cvR);
+    cvReleaseImage(&cvG);
+    cvReleaseImage(&cvB);
+    cvReleaseImage(&cvDestImg);
+    break;
+
+  default:
+    break;
   }
 }
 
 
 void MEHistogramTransform::SetStretchProcessingMode(ProcessingType new_channel_mode,
-                                                    MEHistogram::StretchType new_stretch_mode)
+  MEHistogram::StretchType new_stretch_mode)
 {
   DiscreteStretchingDone = false;
 
-  switch(new_channel_mode)
+  switch (new_channel_mode)
   {
-    case p_SeparateChannels:
-      ChannelMode = new_channel_mode;
-      break;
+  case p_SeparateChannels:
+    ChannelMode = new_channel_mode;
+    break;
 
-    case p_Average:
-      ChannelMode = new_channel_mode;
-      break;
+  case p_Average:
+    ChannelMode = new_channel_mode;
+    break;
 
-    default:
-      break;
+  default:
+    break;
   }
 
-  switch(new_stretch_mode)
+  switch (new_stretch_mode)
   {
-    case MEHistogram::s_OwnMode:
-      StretchMode = new_stretch_mode;
-      break;
+  case MEHistogram::s_OwnMode:
+    StretchMode = new_stretch_mode;
+    break;
 
-    case MEHistogram::s_GimpMode:
-      StretchMode = new_stretch_mode;
-      break;
+  case MEHistogram::s_GimpMode:
+    StretchMode = new_stretch_mode;
+    break;
 
-    default:
-      break;
+  default:
+    break;
   }
 }
diff --git a/package_bgs/ck/MEHistogram.hpp b/package_bgs/LBP_MRF/MEHistogram.hpp
similarity index 93%
rename from package_bgs/ck/MEHistogram.hpp
rename to package_bgs/LBP_MRF/MEHistogram.hpp
index 5b2b47f00d44716df0b1307a3631992e8c7342b0..0b2fb0dbd833f78fc7140e284fcb1ebd90925af5 100644
--- a/package_bgs/ck/MEHistogram.hpp
+++ b/package_bgs/LBP_MRF/MEHistogram.hpp
@@ -1,3 +1,19 @@
+/*
+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/>.
+*/
 /*
  *  This file is part of the AiBO+ project
  *
@@ -18,14 +34,12 @@
  *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
  *
  */
+#pragma once
 
-#ifndef MEHistogram_hpp
-#define MEHistogram_hpp
-
-/**
- *  @addtogroup mindeye
- *  @{
- */
+ /**
+  *  @addtogroup mindeye
+  *  @{
+  */
 
 class MEImage;
 
@@ -344,5 +358,3 @@ private:
 };
 
 /** @} */
-
-#endif
diff --git a/package_bgs/ck/MEImage.cpp b/package_bgs/LBP_MRF/MEImage.cpp
similarity index 50%
rename from package_bgs/ck/MEImage.cpp
rename to package_bgs/LBP_MRF/MEImage.cpp
index 737383447133ee6148d6f384cd7b5ff31ed0cee3..b01d494e1091985dc04d312aa99712d440fea80e 100644
--- a/package_bgs/ck/MEImage.cpp
+++ b/package_bgs/LBP_MRF/MEImage.cpp
@@ -1,3 +1,19 @@
+/*
+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/>.
+*/
 /*
  *  This file is part of the AiBO+ project
  *
@@ -30,17 +46,17 @@
   cvReleaseImage((IplImage**)&image_ptr); \
   image_ptr = NULL;
 
-// RGB to YUV transform
+ // RGB to YUV transform
 const float RGBtoYUVMatrix[3][3] =
-  {{ 0.299, 0.587, 0.114 },
-  { -0.147, -0.289, 0.436 },
-  { 0.615, -0.515, -0.100 }};
+{ { 0.299, 0.587, 0.114 },
+ { -0.147, -0.289, 0.436 },
+ { 0.615, -0.515, -0.100 } };
 
 // RGB to YIQ transform
 const float RGBtoYIQMatrix[3][3] =
-  {{ 0.299, 0.587, 0.114 },
-  { 0.596, -0.274, -0.322 },
-  { 0.212, -0.523, 0.311 }};
+{ { 0.299, 0.587, 0.114 },
+ { 0.596, -0.274, -0.322 },
+ { 0.212, -0.523, 0.311 } };
 
 MEImage::MEImage(int width, int height, int layers) : cvImg(NULL)
 {
@@ -74,15 +90,15 @@ void MEImage::GetLayer(MEImage& new_layer, int layer_number) const
   int LayerNumber = layer_number;
 
   if ((new_layer.GetWidth() != ME_CAST_TO_IPLIMAGE(cvImg)->width) ||
-      (new_layer.GetHeight() != ME_CAST_TO_IPLIMAGE(cvImg)->height) ||
-      (new_layer.GetLayers() != 1))
+    (new_layer.GetHeight() != ME_CAST_TO_IPLIMAGE(cvImg)->height) ||
+    (new_layer.GetLayers() != 1))
   {
     new_layer.Realloc(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height, 1);
   }
   if (ME_CAST_TO_IPLIMAGE(cvImg)->nChannels < LayerNumber)
   {
     printf("The given layer number is too large (%d > %d)\n",
-               LayerNumber, ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+      LayerNumber, ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
 
     LayerNumber = ME_CAST_TO_IPLIMAGE(cvImg)->nChannels;
   }
@@ -103,17 +119,17 @@ void MEImage::SetLayer(MEImage& layer, int layer_number)
   int LayerNumber = layer_number;
 
   if (layer.GetWidth() != ME_CAST_TO_IPLIMAGE(cvImg)->width ||
-      layer.GetHeight() != ME_CAST_TO_IPLIMAGE(cvImg)->height)
+    layer.GetHeight() != ME_CAST_TO_IPLIMAGE(cvImg)->height)
   {
     printf("The dimensions of the layer and "
-               "destination image is different (%dx%d <> %dx%d)\n",
-               layer.GetWidth(), layer.GetHeight(), ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height);
+      "destination image is different (%dx%d <> %dx%d)\n",
+      layer.GetWidth(), layer.GetHeight(), ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height);
     return;
   }
   if (ME_CAST_TO_IPLIMAGE(cvImg)->nChannels < LayerNumber)
   {
     printf("The given layer number is too large (%d > %d)\n",
-               LayerNumber, ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+      LayerNumber, ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
     LayerNumber = ME_CAST_TO_IPLIMAGE(cvImg)->nChannels;
   }
   if (LayerNumber <= 0)
@@ -124,7 +140,7 @@ void MEImage::SetLayer(MEImage& layer, int layer_number)
   if (layer.GetLayers() != 1)
   {
     printf("The layer image has not one color channel (1 != %d)\n",
-               layer.GetLayers());
+      layer.GetLayers());
     return;
   }
   cvSetImageCOI(ME_CAST_TO_IPLIMAGE(cvImg), LayerNumber);
@@ -223,7 +239,7 @@ void MEImage::SetData(unsigned char* image_data, int width, int height, int chan
 {
   _Init(width, height, channels);
 
-  for (int y = height-1; y >= 0; --y)
+  for (int y = height - 1; y >= 0; --y)
   {
     int Start = GetRowWidth()*y;
     int Start2 = width*channels*y;
@@ -235,7 +251,7 @@ void MEImage::SetData(unsigned char* image_data, int width, int height, int chan
 
 float MEImage::GetRatio() const
 {
-  return ME_CAST_TO_IPLIMAGE(cvImg) ? (float)ME_CAST_TO_IPLIMAGE(cvImg)->height/(float)ME_CAST_TO_IPLIMAGE(cvImg)->width : 0.0;
+  return ME_CAST_TO_IPLIMAGE(cvImg) ? (float)ME_CAST_TO_IPLIMAGE(cvImg)->height / (float)ME_CAST_TO_IPLIMAGE(cvImg)->width : 0.0;
 }
 
 
@@ -289,7 +305,7 @@ void MEImage::ResizeScaleY(int new_height)
     printf("Invalid new height: %d < 1\n", new_height);
     return;
   }
-  Resize((int)((float)new_height*1/GetRatio()), new_height);
+  Resize((int)((float)new_height * 1 / GetRatio()), new_height);
 }
 
 
@@ -322,19 +338,19 @@ void MEImage::Crop(int x1, int y1, int x2, int y2)
   NewY2 = (NewY2 < 0) ? 0 : NewY2;
   NewY2 = (NewY2 > ME_CAST_TO_IPLIMAGE(cvImg)->height) ? ME_CAST_TO_IPLIMAGE(cvImg)->height : NewY2;
 
-  if ((NewX2-NewX1) <= 0)
+  if ((NewX2 - NewX1) <= 0)
   {
-    printf("Invalid new width: %d <= 0\n", NewX2-NewX1);
+    printf("Invalid new width: %d <= 0\n", NewX2 - NewX1);
     return;
   }
-  if ((NewY2-NewY1) <= 0)
+  if ((NewY2 - NewY1) <= 0)
   {
-    printf("Invalid new height: %d <= 0\n", NewY2-NewY1);
+    printf("Invalid new height: %d <= 0\n", NewY2 - NewY1);
     return;
   }
-  IplImage* TempImg = cvCreateImage(cvSize(NewX2-NewX1, NewY2-NewY1), 8, ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+  IplImage* TempImg = cvCreateImage(cvSize(NewX2 - NewX1, NewY2 - NewY1), 8, ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
 
-  cvSetImageROI(ME_CAST_TO_IPLIMAGE(cvImg), cvRect(NewX1, NewY1, NewX2-NewX1, NewY2-NewY1));
+  cvSetImageROI(ME_CAST_TO_IPLIMAGE(cvImg), cvRect(NewX1, NewY1, NewX2 - NewX1, NewY2 - NewY1));
   cvCopy(ME_CAST_TO_IPLIMAGE(cvImg), TempImg);
   ME_RELEASE_IPLIMAGE(cvImg);
   cvImg = TempImg;
@@ -367,13 +383,13 @@ void MEImage::CopyImageInside(int x, int y, MEImage& source_image)
     NewY = 0;
   if (NewY > ME_CAST_TO_IPLIMAGE(cvImg)->height)
     NewY = ME_CAST_TO_IPLIMAGE(cvImg)->height;
-  if (NewX+PasteLengthX > ME_CAST_TO_IPLIMAGE(cvImg)->width)
-    PasteLengthX = ME_CAST_TO_IPLIMAGE(cvImg)->width-NewX;
-  if (NewY+PasteLengthY > ME_CAST_TO_IPLIMAGE(cvImg)->height)
-    PasteLengthY = ME_CAST_TO_IPLIMAGE(cvImg)->height-NewY;
+  if (NewX + PasteLengthX > ME_CAST_TO_IPLIMAGE(cvImg)->width)
+    PasteLengthX = ME_CAST_TO_IPLIMAGE(cvImg)->width - NewX;
+  if (NewY + PasteLengthY > ME_CAST_TO_IPLIMAGE(cvImg)->height)
+    PasteLengthY = ME_CAST_TO_IPLIMAGE(cvImg)->height - NewY;
 
   if (PasteLengthX != source_image.GetWidth() ||
-      PasteLengthY != source_image.GetHeight())
+    PasteLengthY != source_image.GetHeight())
   {
     source_image.Resize(PasteLengthX, PasteLengthY);
   }
@@ -386,8 +402,8 @@ void MEImage::CopyImageInside(int x, int y, MEImage& source_image)
 void MEImage::Erode(int iterations)
 {
   IplImage* TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width,
-                                           ME_CAST_TO_IPLIMAGE(cvImg)->height),
-                                    8, ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+    ME_CAST_TO_IPLIMAGE(cvImg)->height),
+    8, ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
 
   cvErode(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, NULL, iterations);
   ME_RELEASE_IPLIMAGE(cvImg);
@@ -398,8 +414,8 @@ void MEImage::Erode(int iterations)
 void MEImage::Dilate(int iterations)
 {
   IplImage* TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width,
-                                           ME_CAST_TO_IPLIMAGE(cvImg)->height),
-                                    8, ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+    ME_CAST_TO_IPLIMAGE(cvImg)->height),
+    8, ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
 
   cvDilate(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, NULL, iterations);
   ME_RELEASE_IPLIMAGE(cvImg);
@@ -416,22 +432,22 @@ void MEImage::Smooth()
 void MEImage::SmoothAdvanced(SmoothType filtermode, int filtersize)
 {
   IplImage* TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
-                                    ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+    ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
 
   switch (filtermode)
   {
-    case s_Blur:
-      cvSmooth(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_BLUR, filtersize, filtersize, 0);
-      break;
-    case s_Median:
-      cvSmooth(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_MEDIAN, filtersize, 0, 0);
-      break;
-    case s_Gaussian:
-      cvSmooth(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_GAUSSIAN, filtersize, filtersize, 0);
-      break;
-    default:
-      cvSmooth(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_MEDIAN, filtersize, 0, 0);
-      break;
+  case s_Blur:
+    cvSmooth(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_BLUR, filtersize, filtersize, 0);
+    break;
+  case s_Median:
+    cvSmooth(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_MEDIAN, filtersize, 0, 0);
+    break;
+  case s_Gaussian:
+    cvSmooth(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_GAUSSIAN, filtersize, filtersize, 0);
+    break;
+  default:
+    cvSmooth(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_MEDIAN, filtersize, 0, 0);
+    break;
   }
   ME_RELEASE_IPLIMAGE(cvImg);
   cvImg = TempImg;
@@ -446,7 +462,7 @@ void MEImage::Canny()
   }
 
   IplImage* TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
-                                    ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+    ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
   cvCanny(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, 800, 1100, 5);
   ME_RELEASE_IPLIMAGE(cvImg);
   cvImg = TempImg;
@@ -460,8 +476,8 @@ void MEImage::Laplace()
     ConvertToGrayscale(g_OpenCV);
   }
   IplImage* TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width,
-                                           ME_CAST_TO_IPLIMAGE(cvImg)->height),
-                                    IPL_DEPTH_16S, 1);
+    ME_CAST_TO_IPLIMAGE(cvImg)->height),
+    IPL_DEPTH_16S, 1);
   cvLaplace(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, 3);
   cvConvertScale(TempImg, ME_CAST_TO_IPLIMAGE(cvImg), 1, 0);
   ME_RELEASE_IPLIMAGE(cvImg);
@@ -482,7 +498,7 @@ void MEImage::Quantize(int levels)
   }
   unsigned char* ImageData = (unsigned char*)ME_CAST_TO_IPLIMAGE(cvImg)->imageData;
 
-  for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep*ME_CAST_TO_IPLIMAGE(cvImg)->height-1; i >= 0; --i)
+  for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep*ME_CAST_TO_IPLIMAGE(cvImg)->height - 1; i >= 0; --i)
   {
     ImageData[i] = ImageData[i] / (256 / levels)*(256 / levels);
   }
@@ -503,7 +519,7 @@ void MEImage::Threshold(int threshold_limit)
   }
   unsigned char* ImageData = (unsigned char*)ME_CAST_TO_IPLIMAGE(cvImg)->imageData;
 
-  for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep*ME_CAST_TO_IPLIMAGE(cvImg)->height-1; i >= 0; --i)
+  for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep*ME_CAST_TO_IPLIMAGE(cvImg)->height - 1; i >= 0; --i)
   {
     if (ImageData[i] < threshold_limit)
     {
@@ -520,9 +536,9 @@ void MEImage::AdaptiveThreshold()
     ConvertToGrayscale(g_OpenCV);
   }
   IplImage* TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
-                                    ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+    ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
   cvAdaptiveThreshold(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, 25,
-                      CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, 7, -7);
+    CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, 7, -7);
   ME_RELEASE_IPLIMAGE(cvImg);
   cvImg = TempImg;
 }
@@ -531,7 +547,7 @@ void MEImage::AdaptiveThreshold()
 void MEImage::ThresholdByMask(MEImage& mask_image)
 {
   if (mask_image.GetWidth() != ME_CAST_TO_IPLIMAGE(cvImg)->width ||
-      mask_image.GetHeight() != ME_CAST_TO_IPLIMAGE(cvImg)->height)
+    mask_image.GetHeight() != ME_CAST_TO_IPLIMAGE(cvImg)->height)
   {
     printf("Image properties are different\n");
     return;
@@ -543,7 +559,7 @@ void MEImage::ThresholdByMask(MEImage& mask_image)
   unsigned char* ImageData = (unsigned char*)ME_CAST_TO_IPLIMAGE(cvImg)->imageData;
   unsigned char* MaskImageData = mask_image.GetImageData();
 
-  for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep*ME_CAST_TO_IPLIMAGE(cvImg)->height-1; i >= 0; --i)
+  for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep*ME_CAST_TO_IPLIMAGE(cvImg)->height - 1; i >= 0; --i)
   {
     if (MaskImageData[i] == 0)
     {
@@ -567,123 +583,123 @@ void MEImage::ColorSpace(ColorSpaceConvertType mode)
   }
   switch (mode)
   {
-    case csc_RGBtoXYZCIED65:
-      TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width,
-                                     ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
-                              ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
-      cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_RGB2XYZ);
-      ME_RELEASE_IPLIMAGE(cvImg);
-      cvImg = TempImg;
-      break;
-
-    case csc_XYZCIED65toRGB:
-      TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width,
-                                     ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
-                              ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
-      cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_XYZ2RGB);
-      ME_RELEASE_IPLIMAGE(cvImg);
-      cvImg = TempImg;
-      break;
-
-    case csc_RGBtoHSV:
-      TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width,
-                                     ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
-                              ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
-      cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_RGB2HSV);
-      ME_RELEASE_IPLIMAGE(cvImg);
-      cvImg = TempImg;
-      break;
-
-    case csc_HSVtoRGB:
-      TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width,
-                                     ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
-                              ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
-      cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_HSV2RGB);
-      ME_RELEASE_IPLIMAGE(cvImg);
-      cvImg = TempImg;
-      break;
-
-    case csc_RGBtoHLS:
-      TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
-                              ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
-      cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_RGB2HLS);
-      ME_RELEASE_IPLIMAGE(cvImg);
-      cvImg = TempImg;
-      break;
-
-    case csc_HLStoRGB:
-      TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
-                              ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
-      cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_HLS2RGB);
-      ME_RELEASE_IPLIMAGE(cvImg);
-      cvImg = TempImg;
-      break;
-
-    case csc_RGBtoCIELab:
-      TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
-                              ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
-      cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_RGB2Lab);
-      ME_RELEASE_IPLIMAGE(cvImg);
-      cvImg = TempImg;
-      break;
-
-    case csc_CIELabtoRGB:
-      TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
-                              ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
-      cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_Lab2RGB);
-      ME_RELEASE_IPLIMAGE(cvImg);
-      cvImg = TempImg;
-      break;
-
-    case csc_RGBtoCIELuv:
-      TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
-                              ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
-      cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_RGB2Luv);
-      ME_RELEASE_IPLIMAGE(cvImg);
-      cvImg = TempImg;
-      break;
-
-    case csc_CIELuvtoRGB:
-      TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
-                              ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
-      cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_Luv2RGB);
-      ME_RELEASE_IPLIMAGE(cvImg);
-      cvImg = TempImg;
-      break;
-
-    case csc_RGBtoYUV:
-      ComputeColorSpace(csc_RGBtoYUV);
-      break;
-
-    case csc_RGBtoYIQ:
-      ComputeColorSpace(csc_RGBtoYIQ);
-      break;
-
-    case csc_RGBtorgI:
-      ImageData = (unsigned char*)ME_CAST_TO_IPLIMAGE(cvImg)->imageData;
-      WidthStep = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep;
-      RowStart = 0;
-      for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height-1; y >= 0; --y)
+  case csc_RGBtoXYZCIED65:
+    TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width,
+      ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
+      ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+    cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_RGB2XYZ);
+    ME_RELEASE_IPLIMAGE(cvImg);
+    cvImg = TempImg;
+    break;
+
+  case csc_XYZCIED65toRGB:
+    TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width,
+      ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
+      ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+    cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_XYZ2RGB);
+    ME_RELEASE_IPLIMAGE(cvImg);
+    cvImg = TempImg;
+    break;
+
+  case csc_RGBtoHSV:
+    TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width,
+      ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
+      ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+    cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_RGB2HSV);
+    ME_RELEASE_IPLIMAGE(cvImg);
+    cvImg = TempImg;
+    break;
+
+  case csc_HSVtoRGB:
+    TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width,
+      ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
+      ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+    cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_HSV2RGB);
+    ME_RELEASE_IPLIMAGE(cvImg);
+    cvImg = TempImg;
+    break;
+
+  case csc_RGBtoHLS:
+    TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
+      ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+    cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_RGB2HLS);
+    ME_RELEASE_IPLIMAGE(cvImg);
+    cvImg = TempImg;
+    break;
+
+  case csc_HLStoRGB:
+    TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
+      ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+    cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_HLS2RGB);
+    ME_RELEASE_IPLIMAGE(cvImg);
+    cvImg = TempImg;
+    break;
+
+  case csc_RGBtoCIELab:
+    TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
+      ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+    cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_RGB2Lab);
+    ME_RELEASE_IPLIMAGE(cvImg);
+    cvImg = TempImg;
+    break;
+
+  case csc_CIELabtoRGB:
+    TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
+      ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+    cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_Lab2RGB);
+    ME_RELEASE_IPLIMAGE(cvImg);
+    cvImg = TempImg;
+    break;
+
+  case csc_RGBtoCIELuv:
+    TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
+      ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+    cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_RGB2Luv);
+    ME_RELEASE_IPLIMAGE(cvImg);
+    cvImg = TempImg;
+    break;
+
+  case csc_CIELuvtoRGB:
+    TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
+      ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+    cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_Luv2RGB);
+    ME_RELEASE_IPLIMAGE(cvImg);
+    cvImg = TempImg;
+    break;
+
+  case csc_RGBtoYUV:
+    ComputeColorSpace(csc_RGBtoYUV);
+    break;
+
+  case csc_RGBtoYIQ:
+    ComputeColorSpace(csc_RGBtoYIQ);
+    break;
+
+  case csc_RGBtorgI:
+    ImageData = (unsigned char*)ME_CAST_TO_IPLIMAGE(cvImg)->imageData;
+    WidthStep = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep;
+    RowStart = 0;
+    for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height - 1; y >= 0; --y)
+    {
+      for (int x = (ME_CAST_TO_IPLIMAGE(cvImg)->width - 1) * 3; x >= 0; x -= 3)
       {
-        for (int x = (ME_CAST_TO_IPLIMAGE(cvImg)->width-1)*3; x >= 0; x -= 3)
-        {
-          int r = 0;
-          int g = 0;
-          int I = 0;
-
-          I = (int)ImageData[RowStart+x]+(int)ImageData[RowStart+x+1]+(int)ImageData[RowStart+x+2];
-          r = (int)((float)ImageData[RowStart+x] / I*255);
-          g = (int)((float)ImageData[RowStart+x+1] / I*255);
-          ImageData[RowStart+x] = (unsigned char)r;
-          ImageData[RowStart+x+1] = (unsigned char)g;
-          ImageData[RowStart+x+2] = (unsigned char)(I / 3);
-        }
-        RowStart += WidthStep;
+        int r = 0;
+        int g = 0;
+        int I = 0;
+
+        I = (int)ImageData[RowStart + x] + (int)ImageData[RowStart + x + 1] + (int)ImageData[RowStart + x + 2];
+        r = (int)((float)ImageData[RowStart + x] / I * 255);
+        g = (int)((float)ImageData[RowStart + x + 1] / I * 255);
+        ImageData[RowStart + x] = (unsigned char)r;
+        ImageData[RowStart + x + 1] = (unsigned char)g;
+        ImageData[RowStart + x + 2] = (unsigned char)(I / 3);
       }
-      break;
+      RowStart += WidthStep;
+    }
+    break;
 
-    default:
-      break;
+  default:
+    break;
   }
 }
 
@@ -701,27 +717,27 @@ void MEImage::ConvertToGrayscale(GrayscaleType grayscale_mode)
 
   switch (grayscale_mode)
   {
-    case g_Average:
-      TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8, 1);
-      ImageData = (unsigned char*)TempImg->imageData;
+  case g_Average:
+    TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8, 1);
+    ImageData = (unsigned char*)TempImg->imageData;
 
-      for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep*ME_CAST_TO_IPLIMAGE(cvImg)->height-3; i >= 0; i -= 3)
-      {
-        ImageData[i / 3] = (ImgData[i]+ImgData[i+1]+ImgData[i+2]) / 3;
-      }
-      ME_RELEASE_IPLIMAGE(cvImg);
-      cvImg = TempImg;
-      break;
+    for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep*ME_CAST_TO_IPLIMAGE(cvImg)->height - 3; i >= 0; i -= 3)
+    {
+      ImageData[i / 3] = (ImgData[i] + ImgData[i + 1] + ImgData[i + 2]) / 3;
+    }
+    ME_RELEASE_IPLIMAGE(cvImg);
+    cvImg = TempImg;
+    break;
 
-    case g_OpenCV:
-      TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8, 1);
-      cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_RGB2GRAY);
-      ME_RELEASE_IPLIMAGE(cvImg);
-      cvImg = TempImg;
-      break;
+  case g_OpenCV:
+    TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8, 1);
+    cvCvtColor(ME_CAST_TO_IPLIMAGE(cvImg), TempImg, CV_RGB2GRAY);
+    ME_RELEASE_IPLIMAGE(cvImg);
+    cvImg = TempImg;
+    break;
 
-    default:
-      break;
+  default:
+    break;
   }
 }
 
@@ -760,60 +776,60 @@ void MEImage::LBP(LBPType mode)
   IplImage* TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8, 1);
   unsigned char* TempImgData = (unsigned char*)TempImg->imageData;
   int WidthStep = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep;
-  int WidthStep_2 = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep*2;
+  int WidthStep_2 = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep * 2;
 
   cvSetZero(TempImg);
   switch (mode)
   {
-    case lbp_Normal:
-      for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep*(ME_CAST_TO_IPLIMAGE(cvImg)->height-2)-1; i >= ME_CAST_TO_IPLIMAGE(cvImg)->widthStep+1; --i)
-      {
-        TempImgData[i] =
-            (ImageData[i] <= ImageData[i-ME_CAST_TO_IPLIMAGE(cvImg)->widthStep-1])+
-            ((ImageData[i] <= ImageData[i-ME_CAST_TO_IPLIMAGE(cvImg)->widthStep])*2)+
-            ((ImageData[i] <= ImageData[i-ME_CAST_TO_IPLIMAGE(cvImg)->widthStep+1])*4)+
-            ((ImageData[i] <= ImageData[i-1])*8)+
-            ((ImageData[i] <= ImageData[i+1])*16)+
-            ((ImageData[i] <= ImageData[i+ME_CAST_TO_IPLIMAGE(cvImg)->widthStep-1])*32)+
-            ((ImageData[i] <= ImageData[i+ME_CAST_TO_IPLIMAGE(cvImg)->widthStep])*64)+
-            ((ImageData[i] <= ImageData[i+ME_CAST_TO_IPLIMAGE(cvImg)->widthStep+1])*128);
-      }
-      break;
+  case lbp_Normal:
+    for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep*(ME_CAST_TO_IPLIMAGE(cvImg)->height - 2) - 1; i >= ME_CAST_TO_IPLIMAGE(cvImg)->widthStep + 1; --i)
+    {
+      TempImgData[i] =
+        (ImageData[i] <= ImageData[i - ME_CAST_TO_IPLIMAGE(cvImg)->widthStep - 1]) +
+        ((ImageData[i] <= ImageData[i - ME_CAST_TO_IPLIMAGE(cvImg)->widthStep]) * 2) +
+        ((ImageData[i] <= ImageData[i - ME_CAST_TO_IPLIMAGE(cvImg)->widthStep + 1]) * 4) +
+        ((ImageData[i] <= ImageData[i - 1]) * 8) +
+        ((ImageData[i] <= ImageData[i + 1]) * 16) +
+        ((ImageData[i] <= ImageData[i + ME_CAST_TO_IPLIMAGE(cvImg)->widthStep - 1]) * 32) +
+        ((ImageData[i] <= ImageData[i + ME_CAST_TO_IPLIMAGE(cvImg)->widthStep]) * 64) +
+        ((ImageData[i] <= ImageData[i + ME_CAST_TO_IPLIMAGE(cvImg)->widthStep + 1]) * 128);
+    }
+    break;
 
-    case lbp_Special:
-      for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep*(ME_CAST_TO_IPLIMAGE(cvImg)->height-3)-2; i >= ME_CAST_TO_IPLIMAGE(cvImg)->widthStep*2+2; --i)
-      {
-        int CenterPixel = (ImageData[i+1]+ImageData[i-1]+
-                           ImageData[i-WidthStep]+ImageData[i+WidthStep]) / 4;
-        TempImgData[i] = ((CenterPixel <= (ImageData[i-(WidthStep_2)-2]+
-                           ImageData[i-(WidthStep_2)-1]+
-                           ImageData[i-WidthStep-2]+
-                           ImageData[i-WidthStep-1]) / 4))+
-                         ((CenterPixel <= (ImageData[i-WidthStep]+
-                                            ImageData[i-(WidthStep_2)]) / 2)*2)+
-                         ((CenterPixel <= ((ImageData[i-(WidthStep_2)+2]+
-                           ImageData[i-(WidthStep_2)+1]+
-                           ImageData[i-WidthStep+2]+
-                           ImageData[i-WidthStep+1]) / 4))*4)+
-                         ((CenterPixel <= (ImageData[i-1]+
-                                            ImageData[i-2]) / 2)*8)+
-                         ((CenterPixel <= (ImageData[i+1]+
-                                            ImageData[i+2]) / 2)*16)+
-                         ((CenterPixel <= ((ImageData[i+(WidthStep_2)-2]+
-                           ImageData[i+(WidthStep_2)-1]+
-                           ImageData[i+WidthStep-2]+
-                           ImageData[i+WidthStep-1]) / 4))*32)+
-                         ((CenterPixel <= (ImageData[i+WidthStep]+
-                                            ImageData[i-WidthStep_2]) / 2)*64)+
-                         ((CenterPixel <= ((ImageData[i+(WidthStep_2)+2]+
-                           ImageData[i+(WidthStep_2)+1]+
-                           ImageData[i+WidthStep+2]+
-                           ImageData[i+WidthStep+1]) / 4))*128);
-      }
-      break;
+  case lbp_Special:
+    for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep*(ME_CAST_TO_IPLIMAGE(cvImg)->height - 3) - 2; i >= ME_CAST_TO_IPLIMAGE(cvImg)->widthStep * 2 + 2; --i)
+    {
+      int CenterPixel = (ImageData[i + 1] + ImageData[i - 1] +
+        ImageData[i - WidthStep] + ImageData[i + WidthStep]) / 4;
+      TempImgData[i] = ((CenterPixel <= (ImageData[i - (WidthStep_2)-2] +
+        ImageData[i - (WidthStep_2)-1] +
+        ImageData[i - WidthStep - 2] +
+        ImageData[i - WidthStep - 1]) / 4)) +
+        ((CenterPixel <= (ImageData[i - WidthStep] +
+          ImageData[i - (WidthStep_2)]) / 2) * 2) +
+          ((CenterPixel <= ((ImageData[i - (WidthStep_2)+2] +
+            ImageData[i - (WidthStep_2)+1] +
+            ImageData[i - WidthStep + 2] +
+            ImageData[i - WidthStep + 1]) / 4)) * 4) +
+            ((CenterPixel <= (ImageData[i - 1] +
+              ImageData[i - 2]) / 2) * 8) +
+              ((CenterPixel <= (ImageData[i + 1] +
+                ImageData[i + 2]) / 2) * 16) +
+                ((CenterPixel <= ((ImageData[i + (WidthStep_2)-2] +
+                  ImageData[i + (WidthStep_2)-1] +
+                  ImageData[i + WidthStep - 2] +
+                  ImageData[i + WidthStep - 1]) / 4)) * 32) +
+                  ((CenterPixel <= (ImageData[i + WidthStep] +
+                    ImageData[i - WidthStep_2]) / 2) * 64) +
+                    ((CenterPixel <= ((ImageData[i + (WidthStep_2)+2] +
+                      ImageData[i + (WidthStep_2)+1] +
+                      ImageData[i + WidthStep + 2] +
+                      ImageData[i + WidthStep + 1]) / 4)) * 128);
+    }
+    break;
 
-    default:
-      break;
+  default:
+    break;
   }
   ME_RELEASE_IPLIMAGE(cvImg);
   cvImg = TempImg;
@@ -824,12 +840,13 @@ void MEImage::Binarize(int threshold)
 {
   unsigned char* ImageData = (unsigned char*)ME_CAST_TO_IPLIMAGE(cvImg)->imageData;
 
-  for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->height*ME_CAST_TO_IPLIMAGE(cvImg)->widthStep-1; i >= 0; --i)
+  for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->height*ME_CAST_TO_IPLIMAGE(cvImg)->widthStep - 1; i >= 0; --i)
   {
     if (ImageData[i] >= threshold)
     {
       ImageData[i] = 255;
-    } else {
+    }
+    else {
       ImageData[i] = 0;
     }
   }
@@ -839,8 +856,8 @@ void MEImage::Binarize(int threshold)
 void MEImage::Subtract(MEImage& source, SubtractModeType mode)
 {
   if (source.GetWidth() != ME_CAST_TO_IPLIMAGE(cvImg)->width ||
-      source.GetHeight() != ME_CAST_TO_IPLIMAGE(cvImg)->height ||
-      source.GetLayers() != ME_CAST_TO_IPLIMAGE(cvImg)->nChannels)
+    source.GetHeight() != ME_CAST_TO_IPLIMAGE(cvImg)->height ||
+    source.GetLayers() != ME_CAST_TO_IPLIMAGE(cvImg)->nChannels)
   {
     printf("Image properties are different.\n");
     return;
@@ -852,42 +869,42 @@ void MEImage::Subtract(MEImage& source, SubtractModeType mode)
 
   switch (mode)
   {
-    case sub_Normal:
-      ImageData = (unsigned char*)ME_CAST_TO_IPLIMAGE(cvImg)->imageData;
-      DstData = source.GetImageData();
-      RowStart = 0;
+  case sub_Normal:
+    ImageData = (unsigned char*)ME_CAST_TO_IPLIMAGE(cvImg)->imageData;
+    DstData = source.GetImageData();
+    RowStart = 0;
 
-      for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height-1; y >= 0; --y)
+    for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height - 1; y >= 0; --y)
+    {
+      for (int x = ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels - 1; x >= 0; --x)
       {
-        for (int x = ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels-1; x >= 0; --x)
-        {
-          ImageData[RowStart+x] =
-            ImageData[RowStart+x]-DstData[RowStart+x] < 0 ? 0 :
-            ImageData[RowStart+x]-DstData[RowStart+x];
-        }
-        RowStart += WidthStep;
+        ImageData[RowStart + x] =
+          ImageData[RowStart + x] - DstData[RowStart + x] < 0 ? 0 :
+          ImageData[RowStart + x] - DstData[RowStart + x];
       }
-      break;
+      RowStart += WidthStep;
+    }
+    break;
 
-    case sub_Absolut:
-      ImageData = (unsigned char*)ME_CAST_TO_IPLIMAGE(cvImg)->imageData;
-      DstData = source.GetImageData();
-      RowStart = 0;
+  case sub_Absolut:
+    ImageData = (unsigned char*)ME_CAST_TO_IPLIMAGE(cvImg)->imageData;
+    DstData = source.GetImageData();
+    RowStart = 0;
 
-      for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height-1; y >= 0; --y)
+    for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height - 1; y >= 0; --y)
+    {
+      for (int x = ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels - 1; x >= 0; --x)
       {
-        for (int x = ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels-1; x >= 0; --x)
-        {
-          ImageData[RowStart+x] = ImageData[RowStart+x]-
-              DstData[RowStart+x] < 0 ? -ImageData[RowStart+x]+
-              DstData[RowStart+x] : ImageData[RowStart+x]-DstData[RowStart+x];
-        }
-        RowStart += WidthStep;
+        ImageData[RowStart + x] = ImageData[RowStart + x] -
+          DstData[RowStart + x] < 0 ? -ImageData[RowStart + x] +
+          DstData[RowStart + x] : ImageData[RowStart + x] - DstData[RowStart + x];
       }
-      break;
+      RowStart += WidthStep;
+    }
+    break;
 
-    default:
-      break;
+  default:
+    break;
   }
 }
 
@@ -895,8 +912,8 @@ void MEImage::Subtract(MEImage& source, SubtractModeType mode)
 void MEImage::Multiple(MEImage& source, MultiplicationType mode)
 {
   if (source.GetWidth() != ME_CAST_TO_IPLIMAGE(cvImg)->width ||
-      source.GetHeight() != ME_CAST_TO_IPLIMAGE(cvImg)->height ||
-      source.GetLayers() != ME_CAST_TO_IPLIMAGE(cvImg)->nChannels)
+    source.GetHeight() != ME_CAST_TO_IPLIMAGE(cvImg)->height ||
+    source.GetLayers() != ME_CAST_TO_IPLIMAGE(cvImg)->nChannels)
   {
     printf("Image properties are different.\n");
     return;
@@ -910,57 +927,59 @@ void MEImage::Multiple(MEImage& source, MultiplicationType mode)
 
   switch (mode)
   {
-    case m_Normal:
-      Result = 0;
-      ImageData = (unsigned char*)ME_CAST_TO_IPLIMAGE(cvImg)->imageData;
-      DstData = source.GetImageData();
+  case m_Normal:
+    Result = 0;
+    ImageData = (unsigned char*)ME_CAST_TO_IPLIMAGE(cvImg)->imageData;
+    DstData = source.GetImageData();
 
-      for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->height*ME_CAST_TO_IPLIMAGE(cvImg)->widthStep-1; i >= 0; --i)
+    for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->height*ME_CAST_TO_IPLIMAGE(cvImg)->widthStep - 1; i >= 0; --i)
+    {
+      if ((ImageData[i] >= 128) && (DstData[i] >= 128))
       {
-        if ((ImageData[i] >= 128) && (DstData[i] >= 128))
-        {
-          Result = (float)ImageData[i]/128*(float)DstData[i]/128;
+        Result = (float)ImageData[i] / 128 * (float)DstData[i] / 128;
 
-          if (Result >= 1)
-          {
-            ImageData[i] = 255;
-          } else {
-            ImageData[i] = 0;
-          }
-        } else {
+        if (Result >= 1)
+        {
+          ImageData[i] = 255;
+        }
+        else {
           ImageData[i] = 0;
         }
       }
-      break;
-
-    case m_Neighbourhood:
-      TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
-                                     ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
-      ImageData2 = (unsigned char*)ME_CAST_TO_IPLIMAGE(cvImg)->imageData;
-      DstData = source.GetImageData();
-      ImageData3 = (unsigned char*)TempImg->imageData;
-
-      for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height-1; y >= 0; --y)
-        for (int x = ME_CAST_TO_IPLIMAGE(cvImg)->width-1; x >= 0; --x)
-          for (int l = ME_CAST_TO_IPLIMAGE(cvImg)->nChannels-1; l >= 0; --l)
-      {
-        if (((DstData[y*ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+
-                      x*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+l] == 255) ||
-            (ImageData2[y*ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+
-                        x*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+l] == 255)) &&
-            (NeighbourhoodCounter(x-2, y-2, n_5x5) > 3) &&
-            (source.NeighbourhoodCounter(x-2, y-2, n_5x5) > 3))
+      else {
+        ImageData[i] = 0;
+      }
+    }
+    break;
+
+  case m_Neighbourhood:
+    TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
+      ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+    ImageData2 = (unsigned char*)ME_CAST_TO_IPLIMAGE(cvImg)->imageData;
+    DstData = source.GetImageData();
+    ImageData3 = (unsigned char*)TempImg->imageData;
+
+    for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height - 1; y >= 0; --y)
+      for (int x = ME_CAST_TO_IPLIMAGE(cvImg)->width - 1; x >= 0; --x)
+        for (int l = ME_CAST_TO_IPLIMAGE(cvImg)->nChannels - 1; l >= 0; --l)
         {
-          ImageData3[y*ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+
-                     x*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+l] = 255;
+          if (((DstData[y*ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels +
+            x*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels + l] == 255) ||
+            (ImageData2[y*ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels +
+              x*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels + l] == 255)) &&
+              (NeighbourhoodCounter(x - 2, y - 2, n_5x5) > 3) &&
+            (source.NeighbourhoodCounter(x - 2, y - 2, n_5x5) > 3))
+          {
+            ImageData3[y*ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels +
+              x*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels + l] = 255;
+          }
         }
-      }
-      ME_RELEASE_IPLIMAGE(cvImg);
-      cvImg = TempImg;
-      break;
+    ME_RELEASE_IPLIMAGE(cvImg);
+    cvImg = TempImg;
+    break;
 
-    default:
-      break;
+  default:
+    break;
   }
 }
 
@@ -968,8 +987,8 @@ void MEImage::Multiple(MEImage& source, MultiplicationType mode)
 void MEImage::Addition(MEImage& source, AdditionType mode)
 {
   if (source.GetWidth() != ME_CAST_TO_IPLIMAGE(cvImg)->width ||
-      source.GetHeight() != ME_CAST_TO_IPLIMAGE(cvImg)->height ||
-      source.GetLayers() != ME_CAST_TO_IPLIMAGE(cvImg)->nChannels)
+    source.GetHeight() != ME_CAST_TO_IPLIMAGE(cvImg)->height ||
+    source.GetLayers() != ME_CAST_TO_IPLIMAGE(cvImg)->nChannels)
   {
     printf("Image properties are different.\n");
     return;
@@ -979,25 +998,25 @@ void MEImage::Addition(MEImage& source, AdditionType mode)
 
   switch (mode)
   {
-    case a_Average:
-      for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->height*ME_CAST_TO_IPLIMAGE(cvImg)->widthStep-1; i >= 0; --i)
-      {
-        ImageData[i] = (ImageData[i]+DstData[i]) / 2;
-      }
-      break;
+  case a_Average:
+    for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->height*ME_CAST_TO_IPLIMAGE(cvImg)->widthStep - 1; i >= 0; --i)
+    {
+      ImageData[i] = (ImageData[i] + DstData[i]) / 2;
+    }
+    break;
 
-    case a_Union:
-      for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->height*ME_CAST_TO_IPLIMAGE(cvImg)->widthStep-1; i >= 0; --i)
+  case a_Union:
+    for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->height*ME_CAST_TO_IPLIMAGE(cvImg)->widthStep - 1; i >= 0; --i)
+    {
+      if (DstData[i] > ImageData[i])
       {
-        if (DstData[i] > ImageData[i])
-        {
-          ImageData[i] = DstData[i];
-        }
+        ImageData[i] = DstData[i];
       }
-      break;
+    }
+    break;
 
-    default:
-      break;
+  default:
+    break;
   }
 }
 
@@ -1005,42 +1024,44 @@ void MEImage::Addition(MEImage& source, AdditionType mode)
 void MEImage::EliminateSinglePixels()
 {
   IplImage* TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
-                                    ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+    ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
   unsigned char* ImageData = (unsigned char*)ME_CAST_TO_IPLIMAGE(cvImg)->imageData;
   unsigned char* DstData = (unsigned char*)TempImg->imageData;
   int sum = 0;
   int xy = 0;
   int ywidth = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep;
 
-  for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height-1; y >= 0; --y)
-    for (int x = ME_CAST_TO_IPLIMAGE(cvImg)->width-1; x >= 0; --x)
-  {
-    xy = y*ywidth+x*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels;
-
-    for (int l = ME_CAST_TO_IPLIMAGE(cvImg)->nChannels-1; l >= 0; --l)
+  for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height - 1; y >= 0; --y)
+    for (int x = ME_CAST_TO_IPLIMAGE(cvImg)->width - 1; x >= 0; --x)
     {
-      if ((ImageData[xy+l] > 0) && (x > 0) && (y > 0) && (x < ME_CAST_TO_IPLIMAGE(cvImg)->width-1) && (y < ME_CAST_TO_IPLIMAGE(cvImg)->height-1))
+      xy = y*ywidth + x*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels;
+
+      for (int l = ME_CAST_TO_IPLIMAGE(cvImg)->nChannels - 1; l >= 0; --l)
       {
-        sum = (ImageData[xy-ywidth-ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+l] > 0)+
-              (ImageData[xy-ywidth+l] > 0)+
-              (ImageData[xy-ywidth+ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+l] > 0)+
-              (ImageData[xy-ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+l] > 0)+
-              (ImageData[xy+ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+l] > 0)+
-              (ImageData[xy+ywidth-ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+l] > 0)+
-              (ImageData[xy+ywidth+l] > 0)+
-              (ImageData[xy+ywidth+ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+l] > 0);
-
-        if (sum > 3)
+        if ((ImageData[xy + l] > 0) && (x > 0) && (y > 0) && (x < ME_CAST_TO_IPLIMAGE(cvImg)->width - 1) && (y < ME_CAST_TO_IPLIMAGE(cvImg)->height - 1))
         {
-          DstData[xy+l] = 255;
-        } else {
-          DstData[xy+l] = 0;
+          sum = (ImageData[xy - ywidth - ME_CAST_TO_IPLIMAGE(cvImg)->nChannels + l] > 0) +
+            (ImageData[xy - ywidth + l] > 0) +
+            (ImageData[xy - ywidth + ME_CAST_TO_IPLIMAGE(cvImg)->nChannels + l] > 0) +
+            (ImageData[xy - ME_CAST_TO_IPLIMAGE(cvImg)->nChannels + l] > 0) +
+            (ImageData[xy + ME_CAST_TO_IPLIMAGE(cvImg)->nChannels + l] > 0) +
+            (ImageData[xy + ywidth - ME_CAST_TO_IPLIMAGE(cvImg)->nChannels + l] > 0) +
+            (ImageData[xy + ywidth + l] > 0) +
+            (ImageData[xy + ywidth + ME_CAST_TO_IPLIMAGE(cvImg)->nChannels + l] > 0);
+
+          if (sum > 3)
+          {
+            DstData[xy + l] = 255;
+          }
+          else {
+            DstData[xy + l] = 0;
+          }
+        }
+        else {
+          DstData[xy + l] = 0;
         }
-      } else {
-        DstData[xy+l] = 0;
       }
     }
-  }
   ME_RELEASE_IPLIMAGE(cvImg);
   cvImg = TempImg;
 }
@@ -1049,8 +1070,8 @@ void MEImage::EliminateSinglePixels()
 float MEImage::DifferenceAreas(MEImage& reference, int difference) const
 {
   if (reference.GetWidth() != GetWidth() ||
-      reference.GetHeight() != GetHeight() ||
-      reference.GetLayers() != GetLayers())
+    reference.GetHeight() != GetHeight() ||
+    reference.GetLayers() != GetLayers())
   {
     printf("Image dimensions or channels are different\n");
     return -1.0;
@@ -1062,16 +1083,16 @@ float MEImage::DifferenceAreas(MEImage& reference, int difference) const
   int WidthStep = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep;
   int RowStart = 0;
 
-  for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height-1; y >= 0; --y)
+  for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height - 1; y >= 0; --y)
   {
-    for (int x = ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels-1; x >= 0; --x)
+    for (int x = ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels - 1; x >= 0; --x)
     {
-      if (abs(OrigImgData[RowStart+x]-RefImgData[RowStart+x]) > difference)
+      if (abs(OrigImgData[RowStart + x] - RefImgData[RowStart + x]) > difference)
         Pixels++;
     }
     RowStart += WidthStep;
   }
-  PixelDiff = (float)Pixels / (ME_CAST_TO_IPLIMAGE(cvImg)->height*ME_CAST_TO_IPLIMAGE(cvImg)->widthStep)*100;
+  PixelDiff = (float)Pixels / (ME_CAST_TO_IPLIMAGE(cvImg)->height*ME_CAST_TO_IPLIMAGE(cvImg)->widthStep) * 100;
   return PixelDiff;
 }
 
@@ -1079,8 +1100,8 @@ float MEImage::DifferenceAreas(MEImage& reference, int difference) const
 int MEImage::AverageDifference(MEImage& reference) const
 {
   if (reference.GetWidth() != GetWidth() ||
-      reference.GetHeight() != GetHeight() ||
-      reference.GetLayers() != GetLayers())
+    reference.GetHeight() != GetHeight() ||
+    reference.GetLayers() != GetLayers())
   {
     printf("Image dimensions or channels are different\n");
     return -1;
@@ -1091,11 +1112,11 @@ int MEImage::AverageDifference(MEImage& reference) const
   int WidthStep = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep;
   int RowStart = 0;
 
-  for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height-1; y >= 0; --y)
+  for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height - 1; y >= 0; --y)
   {
-    for (int x = ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels-1; x >= 0; --x)
+    for (int x = ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels - 1; x >= 0; --x)
     {
-      Difference += abs(OrigImgData[RowStart+x]-RefImgData[RowStart+x]);
+      Difference += abs(OrigImgData[RowStart + x] - RefImgData[RowStart + x]);
     }
     RowStart += WidthStep;
   }
@@ -1107,8 +1128,8 @@ int MEImage::AverageDifference(MEImage& reference) const
 void MEImage::Minimum(MEImage& image)
 {
   if (image.GetWidth() != ME_CAST_TO_IPLIMAGE(cvImg)->width ||
-      image.GetHeight() != ME_CAST_TO_IPLIMAGE(cvImg)->height ||
-      image.GetLayers() != ME_CAST_TO_IPLIMAGE(cvImg)->nChannels)
+    image.GetHeight() != ME_CAST_TO_IPLIMAGE(cvImg)->height ||
+    image.GetLayers() != ME_CAST_TO_IPLIMAGE(cvImg)->nChannels)
   {
     printf("Image properties are different\n");
     return;
@@ -1118,12 +1139,12 @@ void MEImage::Minimum(MEImage& image)
   int WidthStep = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep;
   int RowStart = 0;
 
-  for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height-1; y >= 0; --y)
+  for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height - 1; y >= 0; --y)
   {
-    for (int x = ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels-1; x >= 0; --x)
+    for (int x = ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels - 1; x >= 0; --x)
     {
-      ImageData[RowStart+x] = ImageData[RowStart+x] > SecData[RowStart+x] ?
-                              SecData[RowStart+x] : ImageData[RowStart+x];
+      ImageData[RowStart + x] = ImageData[RowStart + x] > SecData[RowStart + x] ?
+        SecData[RowStart + x] : ImageData[RowStart + x];
     }
     RowStart += WidthStep;
   }
@@ -1137,11 +1158,11 @@ float MEImage::AverageBrightnessLevel() const
   int RowStart = 0;
   int BrightnessLevel = 0;
 
-  for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height-1; y >= 0; --y)
+  for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height - 1; y >= 0; --y)
   {
-    for (int x = ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels-1; x >= 0; --x)
+    for (int x = ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels - 1; x >= 0; --x)
     {
-      BrightnessLevel += (int)ImageData[RowStart+x];
+      BrightnessLevel += (int)ImageData[RowStart + x];
     }
     RowStart += WidthStep;
   }
@@ -1160,8 +1181,8 @@ bool MEImage::Equal(const MEImage& reference, int maxabsdiff) const
   bool Ret = true;
 
   if (reference.GetWidth() != ME_CAST_TO_IPLIMAGE(cvImg)->width ||
-      reference.GetHeight() != ME_CAST_TO_IPLIMAGE(cvImg)->height ||
-      reference.GetLayers() != ME_CAST_TO_IPLIMAGE(cvImg)->nChannels)
+    reference.GetHeight() != ME_CAST_TO_IPLIMAGE(cvImg)->height ||
+    reference.GetLayers() != ME_CAST_TO_IPLIMAGE(cvImg)->nChannels)
   {
     printf("Image properties are different\n");
     return false;
@@ -1171,11 +1192,11 @@ bool MEImage::Equal(const MEImage& reference, int maxabsdiff) const
   int WidthStep = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep;
   int RowStart = 0;
 
-  for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height-1; y >= 0; --y)
+  for (int y = ME_CAST_TO_IPLIMAGE(cvImg)->height - 1; y >= 0; --y)
   {
-    for (int x = ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels-1; x >= 0; --x)
+    for (int x = ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels - 1; x >= 0; --x)
     {
-      if (abs(ImageData[RowStart+x]-RefData[RowStart+x]) >= maxabsdiff)
+      if (abs(ImageData[RowStart + x] - RefData[RowStart + x]) >= maxabsdiff)
       {
         Ret = false;
         return Ret;
@@ -1193,16 +1214,16 @@ unsigned char MEImage::GrayscalePixel(int x, int y) const
   int NewY = y;
 
   NewX = NewX < 0 ? 0 : NewX;
-  NewX = NewX > ME_CAST_TO_IPLIMAGE(cvImg)->width-1 ? ME_CAST_TO_IPLIMAGE(cvImg)->width-1 : NewX;
+  NewX = NewX > ME_CAST_TO_IPLIMAGE(cvImg)->width - 1 ? ME_CAST_TO_IPLIMAGE(cvImg)->width - 1 : NewX;
   NewY = NewY < 0 ? 0 : NewY;
-  NewY = NewY > ME_CAST_TO_IPLIMAGE(cvImg)->height-1 ? ME_CAST_TO_IPLIMAGE(cvImg)->height-1 : NewY;
+  NewY = NewY > ME_CAST_TO_IPLIMAGE(cvImg)->height - 1 ? ME_CAST_TO_IPLIMAGE(cvImg)->height - 1 : NewY;
 
   float Sum = 0;
   unsigned char* ImageData = (unsigned char*)ME_CAST_TO_IPLIMAGE(cvImg)->imageData;
 
   for (int l = 0; l < ME_CAST_TO_IPLIMAGE(cvImg)->nChannels; l++)
   {
-    Sum = Sum + (int)ImageData[NewY*ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+NewX*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+l];
+    Sum = Sum + (int)ImageData[NewY*ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels + NewX*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels + l];
   }
   Sum = Sum / ME_CAST_TO_IPLIMAGE(cvImg)->nChannels;
   return (unsigned char)(Sum);
@@ -1210,7 +1231,7 @@ unsigned char MEImage::GrayscalePixel(int x, int y) const
 
 
 int MEImage::NeighbourhoodCounter(int startx, int starty,
-                                  NeighbourhoodType neighbourhood) const
+  NeighbourhoodType neighbourhood) const
 {
   int IterX = 0;
   int IterY = 0;
@@ -1219,60 +1240,60 @@ int MEImage::NeighbourhoodCounter(int startx, int starty,
   // Determine the iteration numbers
   switch (neighbourhood)
   {
-    case n_2x2:
-      IterX = 2;
-      IterY = 2;
-      break;
+  case n_2x2:
+    IterX = 2;
+    IterY = 2;
+    break;
 
-    case n_3x3:
-      IterX = 3;
-      IterY = 3;
-      break;
+  case n_3x3:
+    IterX = 3;
+    IterY = 3;
+    break;
 
-    case n_3x2:
-      IterX = 2;
-      IterY = 3;
-      break;
+  case n_3x2:
+    IterX = 2;
+    IterY = 3;
+    break;
 
-    case n_5x5:
-      IterX = 5;
-      IterY = 5;
-      break;
+  case n_5x5:
+    IterX = 5;
+    IterY = 5;
+    break;
 
-    case n_7x7:
-      IterX = 7;
-      IterY = 7;
-      break;
+  case n_7x7:
+    IterX = 7;
+    IterY = 7;
+    break;
 
-    default:
-      IterX = 3;
-      IterY = 3;
-      break;
+  default:
+    IterX = 3;
+    IterY = 3;
+    break;
   }
 
-  int NewStartX = startx ;
+  int NewStartX = startx;
   int NewStartY = starty;
 
   NewStartX = startx < 0 ? 0 : startx;
-  NewStartX = startx >= ME_CAST_TO_IPLIMAGE(cvImg)->width-IterX ? ME_CAST_TO_IPLIMAGE(cvImg)->width-IterX-1 : startx;
+  NewStartX = startx >= ME_CAST_TO_IPLIMAGE(cvImg)->width - IterX ? ME_CAST_TO_IPLIMAGE(cvImg)->width - IterX - 1 : startx;
   NewStartY = starty < 0 ? 0 : starty;
-  NewStartY = starty >= ME_CAST_TO_IPLIMAGE(cvImg)->height-IterY ? ME_CAST_TO_IPLIMAGE(cvImg)->height-IterY-1 : starty;
+  NewStartY = starty >= ME_CAST_TO_IPLIMAGE(cvImg)->height - IterY ? ME_CAST_TO_IPLIMAGE(cvImg)->height - IterY - 1 : starty;
 
   int Value = 0;
   unsigned char* ImageData = (unsigned char*)ME_CAST_TO_IPLIMAGE(cvImg)->imageData;
 
-  for (int x = NewStartX; x < NewStartX+IterX; x++)
-    for (int y = NewStartY; y < NewStartY+IterY; y++)
-  {
-    Value = ((int)ImageData[y*ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+x*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels]+
-             (int)ImageData[y*ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+x*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+1]+
-             (int)ImageData[y*ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+x*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels+2]) / 3;
-
-    if (Value == 255)
+  for (int x = NewStartX; x < NewStartX + IterX; x++)
+    for (int y = NewStartY; y < NewStartY + IterY; y++)
     {
-      Counter++;
+      Value = ((int)ImageData[y*ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels + x*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels] +
+        (int)ImageData[y*ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels + x*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels + 1] +
+        (int)ImageData[y*ME_CAST_TO_IPLIMAGE(cvImg)->width*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels + x*ME_CAST_TO_IPLIMAGE(cvImg)->nChannels + 2]) / 3;
+
+      if (Value == 255)
+      {
+        Counter++;
+      }
     }
-  }
   return Counter;
 }
 
@@ -1288,24 +1309,24 @@ void MEImage::GradientVector(bool smooth, int x, int y, int mask_size, int& resu
   }
   if (smooth)
   {
-    SmoothAdvanced(s_Gaussian, mask_size*3-(mask_size*3-1) % 2);
+    SmoothAdvanced(s_Gaussian, mask_size * 3 - (mask_size * 3 - 1) % 2);
   }
 
-  Results[0] = (int)GrayscalePixel(x,y)-(int)GrayscalePixel(x,y-mask_size);
-  Results[1] = (int)GrayscalePixel(x,y)-(int)GrayscalePixel(x+DiagonalMaskSize,y-DiagonalMaskSize);
-  Results[2] = (int)GrayscalePixel(x,y)-(int)GrayscalePixel(x+mask_size,y);
-  Results[3] = (int)GrayscalePixel(x,y)-(int)GrayscalePixel(x+DiagonalMaskSize,y+DiagonalMaskSize);
-  Results[4] = (int)GrayscalePixel(x,y)-(int)GrayscalePixel(x,y+mask_size);
-  Results[5] = (int)GrayscalePixel(x,y)-(int)GrayscalePixel(x-DiagonalMaskSize,y+DiagonalMaskSize);
-  Results[6] = (int)GrayscalePixel(x,y)-(int)GrayscalePixel(x-mask_size,y);
-  Results[7] = (int)GrayscalePixel(x,y)-(int)GrayscalePixel(x+DiagonalMaskSize,y-DiagonalMaskSize);
+  Results[0] = (int)GrayscalePixel(x, y) - (int)GrayscalePixel(x, y - mask_size);
+  Results[1] = (int)GrayscalePixel(x, y) - (int)GrayscalePixel(x + DiagonalMaskSize, y - DiagonalMaskSize);
+  Results[2] = (int)GrayscalePixel(x, y) - (int)GrayscalePixel(x + mask_size, y);
+  Results[3] = (int)GrayscalePixel(x, y) - (int)GrayscalePixel(x + DiagonalMaskSize, y + DiagonalMaskSize);
+  Results[4] = (int)GrayscalePixel(x, y) - (int)GrayscalePixel(x, y + mask_size);
+  Results[5] = (int)GrayscalePixel(x, y) - (int)GrayscalePixel(x - DiagonalMaskSize, y + DiagonalMaskSize);
+  Results[6] = (int)GrayscalePixel(x, y) - (int)GrayscalePixel(x - mask_size, y);
+  Results[7] = (int)GrayscalePixel(x, y) - (int)GrayscalePixel(x + DiagonalMaskSize, y - DiagonalMaskSize);
 
-  result_x = (DiagonalMaskSize*Results[1]+mask_size*Results[2]+
-             DiagonalMaskSize*Results[3]-DiagonalMaskSize*Results[5]-
-             mask_size*Results[6]+DiagonalMaskSize*Results[7]) / 256;
-  result_y = (-mask_size*Results[0]-DiagonalMaskSize*Results[1]+
-             DiagonalMaskSize*Results[3]+mask_size*Results[4]+
-             DiagonalMaskSize*Results[5]-DiagonalMaskSize*Results[7]) / 256;
+  result_x = (DiagonalMaskSize*Results[1] + mask_size*Results[2] +
+    DiagonalMaskSize*Results[3] - DiagonalMaskSize*Results[5] -
+    mask_size*Results[6] + DiagonalMaskSize*Results[7]) / 256;
+  result_y = (-mask_size*Results[0] - DiagonalMaskSize*Results[1] +
+    DiagonalMaskSize*Results[3] + mask_size*Results[4] +
+    DiagonalMaskSize*Results[5] - DiagonalMaskSize*Results[7]) / 256;
 }
 
 
@@ -1327,28 +1348,28 @@ void MEImage::GradientVisualize(int vector_x, int vector_y)
   }
 
   int masksize = (ME_CAST_TO_IPLIMAGE(cvImg)->width < ME_CAST_TO_IPLIMAGE(cvImg)->height) ?
-                 ME_CAST_TO_IPLIMAGE(cvImg)->width / (vector_x+1) :
-                 ME_CAST_TO_IPLIMAGE(cvImg)->height / (vector_y+1);
+    ME_CAST_TO_IPLIMAGE(cvImg)->width / (vector_x + 1) :
+    ME_CAST_TO_IPLIMAGE(cvImg)->height / (vector_y + 1);
 
-  SmoothAdvanced(s_Gaussian, masksize*2-1);
+  SmoothAdvanced(s_Gaussian, masksize * 2 - 1);
   for (int i = 1; i < vector_x; i++)
     for (int i1 = 1; i1 < vector_y; i1++)
-  {
-    int Resultx = 0, Resulty = 0;
-    int x = (int)(((float)ME_CAST_TO_IPLIMAGE(cvImg)->width*i / (vector_x)));
-    int y = (int)(((float)ME_CAST_TO_IPLIMAGE(cvImg)->height*i1 / (vector_y)));
+    {
+      int Resultx = 0, Resulty = 0;
+      int x = (int)(((float)ME_CAST_TO_IPLIMAGE(cvImg)->width*i / (vector_x)));
+      int y = (int)(((float)ME_CAST_TO_IPLIMAGE(cvImg)->height*i1 / (vector_y)));
 
-    GradientVector(false, x, y, (int)(0.707*masksize), Resultx, Resulty);
+      GradientVector(false, x, y, (int)(0.707*masksize), Resultx, Resulty);
 
-    CvPoint Point1;
-    CvPoint Point2;
+      CvPoint Point1;
+      CvPoint Point2;
 
-    Point1.x = x-Resultx / 2;
-    Point1.y = y-Resulty / 2;
-    Point2.x = x+Resultx / 2;
-    Point2.y = y+Resulty / 2;
-    cvLine(ME_CAST_TO_IPLIMAGE(cvImg), Point1, Point2, CV_RGB(255, 255, 255), 1, 8);
-  }
+      Point1.x = x - Resultx / 2;
+      Point1.y = y - Resulty / 2;
+      Point2.x = x + Resultx / 2;
+      Point2.y = y + Resulty / 2;
+      cvLine(ME_CAST_TO_IPLIMAGE(cvImg), Point1, Point2, CV_RGB(255, 255, 255), 1, 8);
+    }
 }
 
 
@@ -1400,16 +1421,16 @@ void MEImage::ComputeColorSpace(ColorSpaceConvertType mode)
     return;
   }
   IplImage* TempImg = cvCreateImage(cvSize(ME_CAST_TO_IPLIMAGE(cvImg)->width, ME_CAST_TO_IPLIMAGE(cvImg)->height), 8,
-                                    ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
+    ME_CAST_TO_IPLIMAGE(cvImg)->nChannels);
 
   for (int i = 0; i < 3; i++)
     for (int i1 = 0; i1 < 3; i1++)
-  {
-    if (mode == csc_RGBtoYUV)
-      TransformMatrix[i][i1] = RGBtoYUVMatrix[i][i1];
-    if (mode == csc_RGBtoYIQ)
-      TransformMatrix[i][i1] = RGBtoYIQMatrix[i][i1];
-  }
+    {
+      if (mode == csc_RGBtoYUV)
+        TransformMatrix[i][i1] = RGBtoYUVMatrix[i][i1];
+      if (mode == csc_RGBtoYIQ)
+        TransformMatrix[i][i1] = RGBtoYIQMatrix[i][i1];
+    }
   float x = 0.0;
   float y = 0.0;
   float z = 0.0;
@@ -1441,25 +1462,25 @@ void MEImage::ComputeColorSpace(ColorSpaceConvertType mode)
   unsigned char* SrcData = (unsigned char*)ME_CAST_TO_IPLIMAGE(cvImg)->imageData;
   unsigned char* DstData = (unsigned char*)TempImg->imageData;
 
-  for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep*ME_CAST_TO_IPLIMAGE(cvImg)->height-1; i >= 0; i-=3)
+  for (int i = ME_CAST_TO_IPLIMAGE(cvImg)->widthStep*ME_CAST_TO_IPLIMAGE(cvImg)->height - 1; i >= 0; i -= 3)
   {
-    x = (float)SrcData[i]*TransformMatrix[0][0]+
-        (float)SrcData[i+1]*TransformMatrix[0][1]+
-        (float)SrcData[i+2]*TransformMatrix[0][2];
-    y = (float)SrcData[i]*TransformMatrix[1][0]+
-        (float)SrcData[i+1]*TransformMatrix[1][1]+
-        (float)SrcData[i+2]*TransformMatrix[1][2];
-    z = (float)SrcData[i]*TransformMatrix[2][0]+
-        (float)SrcData[i+1]*TransformMatrix[2][1]+
-        (float)SrcData[i+2]*TransformMatrix[2][2];
+    x = (float)SrcData[i] * TransformMatrix[0][0] +
+      (float)SrcData[i + 1] * TransformMatrix[0][1] +
+      (float)SrcData[i + 2] * TransformMatrix[0][2];
+    y = (float)SrcData[i] * TransformMatrix[1][0] +
+      (float)SrcData[i + 1] * TransformMatrix[1][1] +
+      (float)SrcData[i + 2] * TransformMatrix[1][2];
+    z = (float)SrcData[i] * TransformMatrix[2][0] +
+      (float)SrcData[i + 1] * TransformMatrix[2][1] +
+      (float)SrcData[i + 2] * TransformMatrix[2][2];
 
-    x = xmax-xmin != 0.0 ? 255.0 : (x-xmin) / (xmax-xmin)*255.0;
-    y = ymax-ymin != 0.0 ? 255.0 : (y-xmin) / (ymax-ymin)*255.0;
-    z = zmax-zmin != 0.0 ? 255.0 : (z-xmin) / (zmax-zmin)*255.0;
+    x = xmax - xmin != 0.0 ? 255.0 : (x - xmin) / (xmax - xmin)*255.0;
+    y = ymax - ymin != 0.0 ? 255.0 : (y - xmin) / (ymax - ymin)*255.0;
+    z = zmax - zmin != 0.0 ? 255.0 : (z - xmin) / (zmax - zmin)*255.0;
 
     DstData[i] = (unsigned char)MEBound(0, (int)x, 255);
-    DstData[i+1] = (unsigned char)MEBound(0, (int)y, 255);
-    DstData[i+2] = (unsigned char)MEBound(0, (int)z, 255);
+    DstData[i + 1] = (unsigned char)MEBound(0, (int)y, 255);
+    DstData[i + 2] = (unsigned char)MEBound(0, (int)z, 255);
   }
   ME_RELEASE_IPLIMAGE(cvImg);
   cvImg = TempImg;
diff --git a/package_bgs/ck/MEImage.hpp b/package_bgs/LBP_MRF/MEImage.hpp
similarity index 97%
rename from package_bgs/ck/MEImage.hpp
rename to package_bgs/LBP_MRF/MEImage.hpp
index 41ada3ba71e086fd1b6ef0d1517f7ff34261f7bb..3a52a779a282ad02332df009a4021091645d22d7 100644
--- a/package_bgs/ck/MEImage.hpp
+++ b/package_bgs/LBP_MRF/MEImage.hpp
@@ -1,3 +1,19 @@
+/*
+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/>.
+*/
 /*
  *  This file is part of the AiBO+ project
  *
@@ -18,19 +34,17 @@
  *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
  *
  */
+#pragma once
 
-#ifndef MEImage_H
-#define MEImage_H
-
-/**
- *  @addtogroup mindeye
- *  @{
- */
+ /**
+  *  @addtogroup mindeye
+  *  @{
+  */
 
-/**
- * MEImage
- * @brief Basic image functions
- */
+  /**
+   * MEImage
+   * @brief Basic image functions
+   */
 class MEImage
 {
 public:
@@ -995,5 +1009,3 @@ private:
 };
 
 /** @} */
-
-#endif
diff --git a/package_bgs/ck/MotionDetection.cpp b/package_bgs/LBP_MRF/MotionDetection.cpp
similarity index 91%
rename from package_bgs/ck/MotionDetection.cpp
rename to package_bgs/LBP_MRF/MotionDetection.cpp
index 5ac096afd18e51ec238fd9deae1ad60bad452ae2..e591faa92cacdf776db0198f309f76a89f955aa9 100644
--- a/package_bgs/ck/MotionDetection.cpp
+++ b/package_bgs/LBP_MRF/MotionDetection.cpp
@@ -1,4 +1,20 @@
 /*
+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/>.
+*/
+/*
 *  This file is part of the AiBO+ project
 *
 *  Copyright (C) 2005-2013 Csaba Kertész (csaba.kertesz@gmail.com)
@@ -52,15 +68,15 @@ struct MEPixelDataType
 };
 
 MotionDetection::MotionDetection(DetectorType mode) :
-MDMode(md_NotDefined), MDDataState(ps_Uninitialized), Frames(0), ReadyMask(false),
-HUColorSpace(MEImage::csc_RGBtoCIELuv), HULBPMode(MEImage::lbp_Special),
-HUHistogramsPerPixel(3), HUHistogramArea(5), HUHistogramBins(8),
-HUImageWidth(-1), HUImageHeight(-1), HULBPPixelData(NULL),
-HUPrThres(0.75), HUBackgrThres(0.95), HUHistLRate(0.01), HUWeightsLRate(0.01),
-HUSamplePixels(-1), HUDesiredSamplePixels(-1), HUMinCutWeight(8.0),
-HUOFDataState(ps_Uninitialized), HUOFPointsNumber(-1),
-HUOFCamMovementX(0), MaxTrackedPoints(0), HUOFFrames(-1),
-HUOFCamMovement(false)
+  MDMode(md_NotDefined), MDDataState(ps_Uninitialized), Frames(0), ReadyMask(false),
+  HUColorSpace(MEImage::csc_RGBtoCIELuv), HULBPMode(MEImage::lbp_Special),
+  HUHistogramsPerPixel(3), HUHistogramArea(5), HUHistogramBins(8),
+  HUImageWidth(-1), HUImageHeight(-1), HULBPPixelData(NULL),
+  HUPrThres(0.75), HUBackgrThres(0.95), HUHistLRate(0.01), HUWeightsLRate(0.01),
+  HUSamplePixels(-1), HUDesiredSamplePixels(-1), HUMinCutWeight(8.0),
+  HUOFDataState(ps_Uninitialized), HUOFPointsNumber(-1),
+  HUOFCamMovementX(0), MaxTrackedPoints(0), HUOFFrames(-1),
+  HUOFCamMovement(false)
 {
   HUOFPyramid = NULL;
   HUOFPrevPyramid = NULL;
@@ -357,13 +373,13 @@ void MotionDetection::InitHUData(int imagewidth, int imageheight)
     for (int i = 0; i < HUImageWidth / 2; ++i)
       for (int i1 = 0; i1 < HUImageHeight; ++i1)
       {
-      HULBPPixelData[i][i1] = new MEPixelDataType;
-      HULBPPixelData[i][i1]->Weights = new float[HUHistogramsPerPixel];
-      HULBPPixelData[i][i1]->BackgroundHistogram = new bool[HUHistogramsPerPixel];
-      HULBPPixelData[i][i1]->Histograms = new float*[HUHistogramsPerPixel];
-      for (int i2 = 0; i2 < HUHistogramsPerPixel; ++i2)
-        HULBPPixelData[i][i1]->Histograms[i2] = new float[HUHistogramBins];
-      HULBPPixelData[i][i1]->PreviousHistogram = new float[HUHistogramBins];
+        HULBPPixelData[i][i1] = new MEPixelDataType;
+        HULBPPixelData[i][i1]->Weights = new float[HUHistogramsPerPixel];
+        HULBPPixelData[i][i1]->BackgroundHistogram = new bool[HUHistogramsPerPixel];
+        HULBPPixelData[i][i1]->Histograms = new float*[HUHistogramsPerPixel];
+        for (int i2 = 0; i2 < HUHistogramsPerPixel; ++i2)
+          HULBPPixelData[i][i1]->Histograms[i2] = new float[HUHistogramBins];
+        HULBPPixelData[i][i1]->PreviousHistogram = new float[HUHistogramBins];
       }
 
     // Allocate auxiliary variables
@@ -399,8 +415,8 @@ void MotionDetection::InitHUOFData(int imagewidth, int imageheight)
     HUOFPointsNumber = imagewidth*imageheight / 1000;
     HUOFPyramid = cvCreateImage(cvSize(imagewidth, imageheight), 8, 1);
     HUOFPrevPyramid = cvCreateImage(cvSize(imagewidth, imageheight), 8, 1);
-    HUOFPoints[0] = (CvPoint2D32f*)cvAlloc(HUOFPointsNumber*sizeof(HUOFPoints[0][0]));
-    HUOFPoints[1] = (CvPoint2D32f*)cvAlloc(HUOFPointsNumber*sizeof(HUOFPoints[1][0]));
+    HUOFPoints[0] = (CvPoint2D32f*)cvAlloc(HUOFPointsNumber * sizeof(HUOFPoints[0][0]));
+    HUOFPoints[1] = (CvPoint2D32f*)cvAlloc(HUOFPointsNumber * sizeof(HUOFPoints[1][0]));
   }
 }
 
@@ -412,13 +428,13 @@ void MotionDetection::ReleaseHUData()
     for (int i = 0; i < HUImageWidth / 2; i++)
       for (int i1 = 0; i1 < HUImageHeight; i1++)
       {
-      delete[] HULBPPixelData[i][i1]->PreviousHistogram;
-      for (int i2 = 0; i2 < HUHistogramsPerPixel; ++i2)
-        delete[] HULBPPixelData[i][i1]->Histograms[i2];
-      delete[] HULBPPixelData[i][i1]->Histograms;
-      delete[] HULBPPixelData[i][i1]->BackgroundHistogram;
-      delete[] HULBPPixelData[i][i1]->Weights;
-      delete HULBPPixelData[i][i1];
+        delete[] HULBPPixelData[i][i1]->PreviousHistogram;
+        for (int i2 = 0; i2 < HUHistogramsPerPixel; ++i2)
+          delete[] HULBPPixelData[i][i1]->Histograms[i2];
+        delete[] HULBPPixelData[i][i1]->Histograms;
+        delete[] HULBPPixelData[i][i1]->BackgroundHistogram;
+        delete[] HULBPPixelData[i][i1]->Weights;
+        delete HULBPPixelData[i][i1];
       }
 
     for (int i = 0; i < HUImageWidth / 2; i++)
@@ -486,15 +502,15 @@ void MotionDetection::ClearHUData()
     for (int i = (HUImageWidth / 2) - 1; i >= 0; --i)
       for (int i1 = HUImageHeight - 1; i1 >= 0; --i1)
       {
-      for (int i2 = HUHistogramsPerPixel - 1; i2 >= 0; --i2)
-      {
-        memset(HULBPPixelData[i][i1]->Histograms[i2], 0,
-          HUHistogramBins*sizeof(float));
-        HULBPPixelData[i][i1]->Weights[i2] = 1.0 / HUHistogramsPerPixel;
-        HULBPPixelData[i][i1]->BackgroundHistogram[i2] = true;
-      }
-      HULBPPixelData[i][i1]->BackgroundRate = 1.0;
-      HULBPPixelData[i][i1]->LifeCycle = 0;
+        for (int i2 = HUHistogramsPerPixel - 1; i2 >= 0; --i2)
+        {
+          memset(HULBPPixelData[i][i1]->Histograms[i2], 0,
+            HUHistogramBins * sizeof(float));
+          HULBPPixelData[i][i1]->Weights[i2] = 1.0 / HUHistogramsPerPixel;
+          HULBPPixelData[i][i1]->BackgroundHistogram[i2] = true;
+        }
+        HULBPPixelData[i][i1]->BackgroundRate = 1.0;
+        HULBPPixelData[i][i1]->LifeCycle = 0;
       }
     MDDataState = ps_Initialized;
   }
@@ -563,13 +579,13 @@ void MotionDetection::DetectMotionsHU(MEImage& image)
   else
     if (Frames > 1)
     {
-    PreviousImage = CurrentImage;
-    CurrentImage = image;
-    // Optical flow correction of the camera movements
-    if (MDMode == md_DLBPHistograms)
-    {
-      OpticalFlowCorrection();
-    }
+      PreviousImage = CurrentImage;
+      CurrentImage = image;
+      // Optical flow correction of the camera movements
+      if (MDMode == md_DLBPHistograms)
+      {
+        OpticalFlowCorrection();
+      }
     }
 
   newimage.ConvertToGrayscale(MEImage::g_OpenCV);
@@ -915,17 +931,17 @@ void MotionDetection::UpdateHUPixelData(MEPixelDataType* PixelData, const float
   for (int i1 = HUHistogramsPerPixel - 1; i1 >= 2; --i1)
     for (int i = i1; i >= 1; --i)
     {
-    if (Weights[i][1] <= Weights[i - 1][1])
-    {
-      float tmp = Weights[i][0];
-      float tmp2 = Weights[i][1];
+      if (Weights[i][1] <= Weights[i - 1][1])
+      {
+        float tmp = Weights[i][0];
+        float tmp2 = Weights[i][1];
 
-      Weights[i][0] = Weights[i - 1][0];
-      Weights[i][1] = Weights[i - 1][1];
+        Weights[i][0] = Weights[i - 1][0];
+        Weights[i][1] = Weights[i - 1][1];
 
-      Weights[i - 1][0] = tmp;
-      Weights[i - 1][1] = tmp2;
-    }
+        Weights[i - 1][0] = tmp;
+        Weights[i - 1][1] = tmp2;
+      }
     }
 
   float Sum = 0;
@@ -1056,7 +1072,7 @@ void MotionDetection::OpticalFlowCorrection()
       if ((Distances[i][2] > Distances[i - 1][2]) ||
         ((Distances[i][2] == Distances[i - 1][2]) &&
         (abs(Distances[i][0]) + abs(Distances[i][1]) <
-        abs(Distances[i - 1][0]) + abs(Distances[i - 1][1]))))
+          abs(Distances[i - 1][0]) + abs(Distances[i - 1][1]))))
       {
         int tmp = Distances[i][0];
         int tmp2 = Distances[i][1];
@@ -1331,10 +1347,10 @@ void MotionDetection::GetMotionsMaskHU(MEImage& mask_image)
         MaskImgData[RowStart + x + (HUHistogramArea / 2)] =
           ((int)(x > 1 && HULBPPixelData[(x / 2) - 1][y]->BackgroundRate == 0.0) +
           (int)(x < mask_image.GetWidth() - HUHistogramArea - 1 &&
-          HULBPPixelData[(x / 2) + 1][y]->BackgroundRate == 0.0) +
-          (int)(y > 0 && HULBPPixelData[x / 2][y - 1]->BackgroundRate == 0.0) +
-          (int)(y < mask_image.GetHeight() - HUHistogramArea &&
-          HULBPPixelData[x / 2][y + 1]->BackgroundRate == 0.0) > 1)
+            HULBPPixelData[(x / 2) + 1][y]->BackgroundRate == 0.0) +
+            (int)(y > 0 && HULBPPixelData[x / 2][y - 1]->BackgroundRate == 0.0) +
+            (int)(y < mask_image.GetHeight() - HUHistogramArea &&
+              HULBPPixelData[x / 2][y + 1]->BackgroundRate == 0.0) > 1)
           ? 255 : 0;
       }
     }
diff --git a/package_bgs/ck/MotionDetection.hpp b/package_bgs/LBP_MRF/MotionDetection.hpp
similarity index 93%
rename from package_bgs/ck/MotionDetection.hpp
rename to package_bgs/LBP_MRF/MotionDetection.hpp
index 6e11521d493b40ef78ce069d0ad854ac627a4748..e58c93c107f448d62b7cf2dd0c57c7e8eb8c0b78 100644
--- a/package_bgs/ck/MotionDetection.hpp
+++ b/package_bgs/LBP_MRF/MotionDetection.hpp
@@ -1,3 +1,19 @@
+/*
+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/>.
+*/
 /*
  *  This file is part of the AiBO+ project
  *
@@ -18,14 +34,12 @@
  *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
  *
  */
+#pragma once
 
-#ifndef MotionDetection_hpp
-#define MotionDetection_hpp
-
-/**
- *  @addtogroup mindeye
- *  @{
- */
+ /**
+  *  @addtogroup mindeye
+  *  @{
+  */
 
 #include "MEDefs.hpp"
 #include "MEImage.hpp"
@@ -181,7 +195,7 @@ public:
    */
 
   void CalculateResults(MEImage& referenceimage, int& tnegatives, int& tpositives,
-                        int& ttnegatives, int& ttpositives);
+    int& ttnegatives, int& ttpositives);
 
 private:
 
@@ -397,5 +411,3 @@ private:
 };
 
 /** @} */
-
-#endif
diff --git a/package_bgs/ck/block.h b/package_bgs/LBP_MRF/block.h
similarity index 51%
rename from package_bgs/ck/block.h
rename to package_bgs/LBP_MRF/block.h
index 98b1201fc0c0f506c924c688b51e43923ea649fe..bd1ab67ee703ea826d3debddd5eb4978bcf4e185 100644
--- a/package_bgs/ck/block.h
+++ b/package_bgs/LBP_MRF/block.h
@@ -1,3 +1,19 @@
+/*
+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/>.
+*/
 /* block.h */
 /*
     Copyright 2001 Vladimir Kolmogorov (vnk@cs.cornell.edu), Yuri Boykov (yuri@csd.uwo.ca).
@@ -16,8 +32,6 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     */
-
-
 /*
   Template classes Block and DBlock
   Implement adding and deleting items of the same type in blocks.
@@ -105,9 +119,7 @@
   simultaneously at earlier moments. All memory is
   deallocated only when the destructor is called.
   */
-
-#ifndef __BLOCK_H__
-#define __BLOCK_H__
+#pragma once
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -118,170 +130,168 @@
 
 namespace ck
 {
-  template <class Type> class Block
-  {
-  public:
-    /* Constructor. Arguments are the block size and
+template <class Type> class Block
+{
+public:
+  /* Constructor. Arguments are the block size and
        (optionally) the pointer to the function which
        will be called if allocation failed; the message
        passed to this function is "Not enough memory!" */
-    Block(int size, void(*err_function)(char *) = NULL) { first = last = NULL; block_size = size; error_function = err_function; }
+  Block(int size, void(*err_function)(char *) = NULL) { first = last = NULL; block_size = size; error_function = err_function; }
 
-    /* Destructor. Deallocates all items added so far */
-    ~Block() { while (first) { block *next = first->next; delete first; first = next; } }
+  /* Destructor. Deallocates all items added so far */
+  ~Block() { while (first) { block *next = first->next; delete first; first = next; } }
 
-    /* Allocates 'num' consecutive items; returns pointer
+  /* Allocates 'num' consecutive items; returns pointer
        to the first item. 'num' cannot be greater than the
        block size since items must fit in one block */
-    Type *New(int num = 1)
-    {
-      Type *t;
+  Type *New(int num = 1)
+  {
+    Type *t;
 
-      if (!last || last->current + num > last->last)
+    if (!last || last->current + num > last->last)
+    {
+      if (last && last->next) last = last->next;
+      else
       {
-        if (last && last->next) last = last->next;
-        else
-        {
-          block *next = (block *) new char[sizeof(block) + (block_size - 1)*sizeof(Type)];
-          if (!next) { fprintf(stderr, "Not enough memory!"); exit(1); }
-          if (last) last->next = next;
-          else first = next;
-          last = next;
-          last->current = &(last->data[0]);
-          last->last = last->current + block_size;
-          last->next = NULL;
-        }
+        block *next = (block *) new char[sizeof(block) + (block_size - 1)*sizeof(Type)];
+        if (!next) { fprintf(stderr, "Not enough memory!"); exit(1); }
+        if (last) last->next = next;
+        else first = next;
+        last = next;
+        last->current = &(last->data[0]);
+        last->last = last->current + block_size;
+        last->next = NULL;
       }
-
-      t = last->current;
-      last->current += num;
-      return t;
     }
 
-    /* Returns the first item (or NULL, if no items were added) */
-    Type *ScanFirst()
-    {
-      scan_current_block = first;
-      if (!scan_current_block) return NULL;
-      scan_current_data = &(scan_current_block->data[0]);
-      return scan_current_data++;
-    }
+    t = last->current;
+    last->current += num;
+    return t;
+  }
+
+  /* Returns the first item (or NULL, if no items were added) */
+  Type *ScanFirst()
+  {
+    scan_current_block = first;
+    if (!scan_current_block) return NULL;
+    scan_current_data = &(scan_current_block->data[0]);
+    return scan_current_data++;
+  }
 
-    /* Returns the next item (or NULL, if all items have been read)
+  /* Returns the next item (or NULL, if all items have been read)
        Can be called only if previous ScanFirst() or ScanNext()
        call returned not NULL. */
-    Type *ScanNext()
+  Type *ScanNext()
+  {
+    if (scan_current_data >= scan_current_block->current)
     {
-      if (scan_current_data >= scan_current_block->current)
-      {
-        scan_current_block = scan_current_block->next;
-        if (!scan_current_block) return NULL;
-        scan_current_data = &(scan_current_block->data[0]);
-      }
-      return scan_current_data++;
+      scan_current_block = scan_current_block->next;
+      if (!scan_current_block) return NULL;
+      scan_current_data = &(scan_current_block->data[0]);
     }
+    return scan_current_data++;
+  }
 
-    /* Marks all elements as empty */
-    void Reset()
+  /* Marks all elements as empty */
+  void Reset()
+  {
+    block *b;
+    if (!first) return;
+    for (b = first;; b = b->next)
     {
-      block *b;
-      if (!first) return;
-      for (b = first;; b = b->next)
-      {
-        b->current = &(b->data[0]);
-        if (b == last) break;
-      }
-      last = first;
+      b->current = &(b->data[0]);
+      if (b == last) break;
     }
+    last = first;
+  }
 
-    /***********************************************************************/
+  /***********************************************************************/
 
-  private:
+private:
 
-    typedef struct block_st
-    {
-      Type					*current, *last;
-      struct block_st			*next;
-      Type					data[1];
-    } block;
+  typedef struct block_st
+  {
+    Type					*current, *last;
+    struct block_st			*next;
+    Type					data[1];
+  } block;
 
-    int		block_size;
-    block	*first;
-    block	*last;
+  int		block_size;
+  block	*first;
+  block	*last;
 
-    block	*scan_current_block;
-    Type	*scan_current_data;
+  block	*scan_current_block;
+  Type	*scan_current_data;
 
-    void(*error_function)(char *);
-  };
+  void(*error_function)(char *);
+};
 
-  /***********************************************************************/
-  /***********************************************************************/
-  /***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
 
-  template <class Type> class DBlock
-  {
-  public:
-    /* Constructor. Arguments are the block size and
+template <class Type> class DBlock
+{
+public:
+  /* Constructor. Arguments are the block size and
        (optionally) the pointer to the function which
        will be called if allocation failed; the message
        passed to this function is "Not enough memory!" */
-    DBlock(int size, void(*err_function)(char *) = NULL) { first = NULL; first_free = NULL; block_size = size; error_function = err_function; }
-
-    /* Destructor. Deallocates all items added so far */
-    ~DBlock() { while (first) { block *next = first->next; delete first; first = next; } }
-
-    /* Allocates one item */
-    Type *New()
-    {
-      block_item *item;
+  DBlock(int size, void(*err_function)(char *) = NULL) { first = NULL; first_free = NULL; block_size = size; error_function = err_function; }
 
-      if (!first_free)
-      {
-        block *next = first;
-        first = (block *) new char[sizeof(block) + (block_size - 1)*sizeof(block_item)];
-        if (!first) { fprintf(stderr, "Not enough memory!"); exit(1); }
-        first_free = &(first->data[0]);
-        for (item = first_free; item < first_free + block_size - 1; item++)
-          item->next_free = item + 1;
-        item->next_free = NULL;
-        first->next = next;
-      }
+  /* Destructor. Deallocates all items added so far */
+  ~DBlock() { while (first) { block *next = first->next; delete first; first = next; } }
 
-      item = first_free;
-      first_free = item->next_free;
-      return (Type *)item;
-    }
+  /* Allocates one item */
+  Type *New()
+  {
+    block_item *item;
 
-    /* Deletes an item allocated previously */
-    void Delete(Type *t)
+    if (!first_free)
     {
-      ((block_item *)t)->next_free = first_free;
-      first_free = (block_item *)t;
+      block *next = first;
+      first = (block *) new char[sizeof(block) + (block_size - 1)*sizeof(block_item)];
+      if (!first) { fprintf(stderr, "Not enough memory!"); exit(1); }
+      first_free = &(first->data[0]);
+      for (item = first_free; item < first_free + block_size - 1; item++)
+        item->next_free = item + 1;
+      item->next_free = NULL;
+      first->next = next;
     }
 
-    /***********************************************************************/
+    item = first_free;
+    first_free = item->next_free;
+    return (Type *)item;
+  }
 
-  private:
+  /* Deletes an item allocated previously */
+  void Delete(Type *t)
+  {
+    ((block_item *)t)->next_free = first_free;
+    first_free = (block_item *)t;
+  }
 
-    typedef union block_item_st
-    {
-      Type			t;
-      block_item_st	*next_free;
-    } block_item;
+  /***********************************************************************/
 
-    typedef struct block_st
-    {
-      struct block_st			*next;
-      block_item				data[1];
-    } block;
+private:
 
-    int			block_size;
-    block		*first;
-    block_item	*first_free;
+  typedef union block_item_st
+  {
+    Type			t;
+    block_item_st	*next_free;
+  } block_item;
 
-    void(*error_function)(char *);
-  };
-}
+  typedef struct block_st
+  {
+    struct block_st			*next;
+    block_item				data[1];
+  } block;
+
+  int			block_size;
+  block		*first;
+  block_item	*first_free;
 
-#endif
+  void(*error_function)(char *);
+};
+}
diff --git a/package_bgs/ck/graph.cpp b/package_bgs/LBP_MRF/graph.cpp
similarity index 78%
rename from package_bgs/ck/graph.cpp
rename to package_bgs/LBP_MRF/graph.cpp
index daed395f15c9cfa57d902177bee676ff99e76d4d..9301250f051381b1489a6365027da61548a5e5e9 100644
--- a/package_bgs/ck/graph.cpp
+++ b/package_bgs/LBP_MRF/graph.cpp
@@ -1,3 +1,19 @@
+/*
+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/>.
+*/
 /* graph.cpp */
 /*
     Copyright 2001 Vladimir Kolmogorov (vnk@cs.cornell.edu), Yuri Boykov (yuri@csd.uwo.ca).
@@ -80,4 +96,4 @@ namespace ck
     flow += (cap_source < cap_sink) ? cap_source : cap_sink;
     ((node*)i)->tr_cap = cap_source - cap_sink;
   }
-}
\ No newline at end of file
+}
diff --git a/package_bgs/ck/graph.h b/package_bgs/LBP_MRF/graph.h
similarity index 60%
rename from package_bgs/ck/graph.h
rename to package_bgs/LBP_MRF/graph.h
index b6799e40eb07fa24b40288af89daa194c37c26f0..e7b83c7e2c956cbc97777160086c502a6cf918dc 100644
--- a/package_bgs/ck/graph.h
+++ b/package_bgs/LBP_MRF/graph.h
@@ -1,3 +1,19 @@
+/*
+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/>.
+*/
 /* graph.h */
 /*
   This software library implements the maxflow algorithm
@@ -16,41 +32,36 @@
   If you use this software for research purposes, you should cite
   the aforementioned paper in any resulting publication.
   */
-
-/*
-  Copyright 2001 Vladimir Kolmogorov (vnk@cs.cornell.edu), Yuri Boykov (yuri@csd.uwo.ca).
-
-  This program 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 2 of the License, or
-  (at your option) any later version.
-
-  This program 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 this program; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-  */
-
-
-/*
-  For description, example usage, discussion of graph representation
-  and memory usage see README.TXT.
-  */
-
-#ifndef __GRAPH_H__
-#define __GRAPH_H__
+  /*
+    Copyright 2001 Vladimir Kolmogorov (vnk@cs.cornell.edu), Yuri Boykov (yuri@csd.uwo.ca).
+
+    This program 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 2 of the License, or
+    (at your option) any later version.
+
+    This program 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 this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+    */
+    /*
+      For description, example usage, discussion of graph representation
+      and memory usage see README.TXT.
+      */
+#pragma once
 
 #include "block.h"
 
-/*
-  Nodes, arcs and pointers to nodes are
-  added in blocks for memory and time efficiency.
-  Below are numbers of items in blocks
-  */
+      /*
+        Nodes, arcs and pointers to nodes are
+        added in blocks for memory and time efficiency.
+        Below are numbers of items in blocks
+        */
 #define NODE_BLOCK_SIZE 512
 #define ARC_BLOCK_SIZE 1024
 #define NODEPTR_BLOCK_SIZE 128
@@ -67,7 +78,7 @@ namespace ck
     } termtype; /* terminals */
 
     /* Type of edge weights.
-       Can be changed to char, int, float, double, ... */
+         Can be changed to char, int, float, double, ... */
     typedef short captype;
     /* Type of total flow */
     typedef int flowtype;
@@ -77,9 +88,9 @@ namespace ck
     /* interface functions */
 
     /* Constructor. Optional argument is the pointer to the
-       function which will be called if an error occurs;
-       an error message is passed to this function. If this
-       argument is omitted, exit(1) will be called. */
+         function which will be called if an error occurs;
+         an error message is passed to this function. If this
+         argument is omitted, exit(1) will be called. */
     Graph(void(*err_function)(char *) = NULL);
 
     /* Destructor */
@@ -89,21 +100,21 @@ namespace ck
     node_id add_node();
 
     /* Adds a bidirectional edge between 'from' and 'to'
-       with the weights 'cap' and 'rev_cap' */
+         with the weights 'cap' and 'rev_cap' */
     void add_edge(node_id from, node_id to, captype cap, captype rev_cap);
 
     /* Sets the weights of the edges 'SOURCE->i' and 'i->SINK'
-       Can be called at most once for each node before any call to 'add_tweights'.
-       Weights can be negative */
+         Can be called at most once for each node before any call to 'add_tweights'.
+         Weights can be negative */
     void set_tweights(node_id i, captype cap_source, captype cap_sink);
 
     /* Adds new edges 'SOURCE->i' and 'i->SINK' with corresponding weights
-       Can be called multiple times for each node.
-       Weights can be negative */
+         Can be called multiple times for each node.
+         Weights can be negative */
     void add_tweights(node_id i, captype cap_source, captype cap_sink);
 
     /* After the maxflow is computed, this function returns to which
-       segment the node 'i' belongs (Graph::SOURCE or Graph::SINK) */
+         segment the node 'i' belongs (Graph::SOURCE or Graph::SINK) */
     termtype what_segment(node_id i);
 
     /* Computes the maxflow. Can be called only once. */
@@ -125,13 +136,13 @@ namespace ck
 
       arc_st			*parent;	/* node's parent */
       node_st			*next;		/* pointer to the next active node
-                       (or to itself if it is the last node in the list) */
+                         (or to itself if it is the last node in the list) */
       int				TS;			/* timestamp showing when DIST was computed */
       int				DIST;		/* distance to the terminal */
       short			is_sink;	/* flag showing whether the node is in the source or in the sink tree */
 
       captype			tr_cap;		/* if tr_cap > 0 then tr_cap is residual capacity of the arc SOURCE->node
-                       otherwise         -tr_cap is residual capacity of the arc node->SINK */
+                         otherwise         -tr_cap is residual capacity of the arc node->SINK */
     } node;
 
     /* arc structure */
@@ -156,8 +167,8 @@ namespace ck
     DBlock<nodeptr>		*nodeptr_block;
 
     void(*error_function)(char *);	/* this function is called if a error occurs,
-                         with a corresponding error message
-                         (or exit(1) is called if it's NULL) */
+                           with a corresponding error message
+                           (or exit(1) is called if it's NULL) */
 
     flowtype			flow;		/* total flow */
 
@@ -179,5 +190,3 @@ namespace ck
     void process_sink_orphan(node *i);
   };
 }
-
-#endif
diff --git a/package_bgs/ck/maxflow.cpp b/package_bgs/LBP_MRF/maxflow.cpp
similarity index 67%
rename from package_bgs/ck/maxflow.cpp
rename to package_bgs/LBP_MRF/maxflow.cpp
index 53d37057057423950921bb6f8184cde88e5b3603..6ddec507db47d3dbe0e7fdf1c69d63e3277d133f 100644
--- a/package_bgs/ck/maxflow.cpp
+++ b/package_bgs/LBP_MRF/maxflow.cpp
@@ -1,3 +1,19 @@
+/*
+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/>.
+*/
 /* maxflow.cpp */
 /*
     Copyright 2001 Vladimir Kolmogorov (vnk@cs.cornell.edu), Yuri Boykov (yuri@csd.uwo.ca).
@@ -16,33 +32,31 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     */
-
-
 #include <stdio.h>
 #include "graph.h"
 
-/*
-  special constants for node->parent
-  */
+    /*
+      special constants for node->parent
+      */
 #define TERMINAL ( (arc *) 1 )		/* to terminal */
 #define ORPHAN   ( (arc *) 2 )		/* orphan */
 
 #define INFINITE_D 1000000000		/* infinite distance to the terminal */
 
-/***********************************************************************/
+      /***********************************************************************/
 
-/*
-  Functions for processing active list.
-  i->next points to the next node in the list
-  (or to i, if i is the last node in the list).
-  If i->next is NULL iff i is not in the list.
-
-  There are two queues. Active nodes are added
-  to the end of the second queue and read from
-  the front of the first queue. If the first queue
-  is empty, it is replaced by the second queue
-  (and the second queue becomes empty).
-  */
+      /*
+        Functions for processing active list.
+        i->next points to the next node in the list
+        (or to i, if i is the last node in the list).
+        If i->next is NULL iff i is not in the list.
+
+        There are two queues. Active nodes are added
+        to the end of the second queue and read from
+        the front of the first queue. If the first queue
+        is empty, it is replaced by the second queue
+        (and the second queue becomes empty).
+        */
 namespace ck
 {
   inline void Graph::set_active(node *i)
@@ -58,10 +72,10 @@ namespace ck
   }
 
   /*
-    Returns the next active node.
-    If it is connected to the sink, it stays in the list,
-    otherwise it is removed from the list
-    */
+      Returns the next active node.
+      If it is connected to the sink, it stays in the list,
+      otherwise it is removed from the list
+      */
   inline Graph::node * Graph::next_active()
   {
     node *i;
@@ -232,45 +246,45 @@ namespace ck
     for (a0 = i->first; a0; a0 = a0->next)
       if (a0->sister->r_cap)
       {
-      j = a0->head;
-      if (!j->is_sink && (a = j->parent))
-      {
-        /* checking the origin of j */
-        d = 0;
-        while (1)
-        {
-          if (j->TS == TIME)
-          {
-            d += j->DIST;
-            break;
-          }
-          a = j->parent;
-          d++;
-          if (a == TERMINAL)
-          {
-            j->TS = TIME;
-            j->DIST = 1;
-            break;
-          }
-          if (a == ORPHAN) { d = INFINITE_D; break; }
-          j = a->head;
-        }
-        if (d < INFINITE_D) /* j originates from the source - done */
+        j = a0->head;
+        if (!j->is_sink && (a = j->parent))
         {
-          if (d < d_min)
+          /* checking the origin of j */
+          d = 0;
+          while (1)
           {
-            a0_min = a0;
-            d_min = d;
+            if (j->TS == TIME)
+            {
+              d += j->DIST;
+              break;
+            }
+            a = j->parent;
+            d++;
+            if (a == TERMINAL)
+            {
+              j->TS = TIME;
+              j->DIST = 1;
+              break;
+            }
+            if (a == ORPHAN) { d = INFINITE_D; break; }
+            j = a->head;
           }
-          /* set marks along the path */
-          for (j = a0->head; j->TS != TIME; j = j->parent->head)
+          if (d < INFINITE_D) /* j originates from the source - done */
           {
-            j->TS = TIME;
-            j->DIST = d--;
+            if (d < d_min)
+            {
+              a0_min = a0;
+              d_min = d;
+            }
+            /* set marks along the path */
+            for (j = a0->head; j->TS != TIME; j = j->parent->head)
+            {
+              j->TS = TIME;
+              j->DIST = d--;
+            }
           }
         }
       }
-      }
 
     if ((i->parent = a0_min))
     {
@@ -316,45 +330,45 @@ namespace ck
     for (a0 = i->first; a0; a0 = a0->next)
       if (a0->r_cap)
       {
-      j = a0->head;
-      if (j->is_sink && (a = j->parent))
-      {
-        /* checking the origin of j */
-        d = 0;
-        while (1)
-        {
-          if (j->TS == TIME)
-          {
-            d += j->DIST;
-            break;
-          }
-          a = j->parent;
-          d++;
-          if (a == TERMINAL)
-          {
-            j->TS = TIME;
-            j->DIST = 1;
-            break;
-          }
-          if (a == ORPHAN) { d = INFINITE_D; break; }
-          j = a->head;
-        }
-        if (d < INFINITE_D) /* j originates from the sink - done */
+        j = a0->head;
+        if (j->is_sink && (a = j->parent))
         {
-          if (d < d_min)
+          /* checking the origin of j */
+          d = 0;
+          while (1)
           {
-            a0_min = a0;
-            d_min = d;
+            if (j->TS == TIME)
+            {
+              d += j->DIST;
+              break;
+            }
+            a = j->parent;
+            d++;
+            if (a == TERMINAL)
+            {
+              j->TS = TIME;
+              j->DIST = 1;
+              break;
+            }
+            if (a == ORPHAN) { d = INFINITE_D; break; }
+            j = a->head;
           }
-          /* set marks along the path */
-          for (j = a0->head; j->TS != TIME; j = j->parent->head)
+          if (d < INFINITE_D) /* j originates from the sink - done */
           {
-            j->TS = TIME;
-            j->DIST = d--;
+            if (d < d_min)
+            {
+              a0_min = a0;
+              d_min = d;
+            }
+            /* set marks along the path */
+            for (j = a0->head; j->TS != TIME; j = j->parent->head)
+            {
+              j->TS = TIME;
+              j->DIST = d--;
+            }
           }
         }
       }
-      }
 
     if ((i->parent = a0_min))
     {
@@ -419,24 +433,24 @@ namespace ck
         for (a = i->first; a; a = a->next)
           if (a->r_cap)
           {
-          j = a->head;
-          if (!j->parent)
-          {
-            j->is_sink = 0;
-            j->parent = a->sister;
-            j->TS = i->TS;
-            j->DIST = i->DIST + 1;
-            set_active(j);
-          }
-          else if (j->is_sink) break;
-          else if (j->TS <= i->TS &&
-            j->DIST > i->DIST)
-          {
-            /* heuristic - trying to make the distance from j to the source shorter */
-            j->parent = a->sister;
-            j->TS = i->TS;
-            j->DIST = i->DIST + 1;
-          }
+            j = a->head;
+            if (!j->parent)
+            {
+              j->is_sink = 0;
+              j->parent = a->sister;
+              j->TS = i->TS;
+              j->DIST = i->DIST + 1;
+              set_active(j);
+            }
+            else if (j->is_sink) break;
+            else if (j->TS <= i->TS &&
+              j->DIST > i->DIST)
+            {
+              /* heuristic - trying to make the distance from j to the source shorter */
+              j->parent = a->sister;
+              j->TS = i->TS;
+              j->DIST = i->DIST + 1;
+            }
           }
       }
       else
@@ -445,24 +459,24 @@ namespace ck
         for (a = i->first; a; a = a->next)
           if (a->sister->r_cap)
           {
-          j = a->head;
-          if (!j->parent)
-          {
-            j->is_sink = 1;
-            j->parent = a->sister;
-            j->TS = i->TS;
-            j->DIST = i->DIST + 1;
-            set_active(j);
-          }
-          else if (!j->is_sink) { a = a->sister; break; }
-          else if (j->TS <= i->TS &&
-            j->DIST > i->DIST)
-          {
-            /* heuristic - trying to make the distance from j to the sink shorter */
-            j->parent = a->sister;
-            j->TS = i->TS;
-            j->DIST = i->DIST + 1;
-          }
+            j = a->head;
+            if (!j->parent)
+            {
+              j->is_sink = 1;
+              j->parent = a->sister;
+              j->TS = i->TS;
+              j->DIST = i->DIST + 1;
+              set_active(j);
+            }
+            else if (!j->is_sink) { a = a->sister; break; }
+            else if (j->TS <= i->TS &&
+              j->DIST > i->DIST)
+            {
+              /* heuristic - trying to make the distance from j to the sink shorter */
+              j->parent = a->sister;
+              j->TS = i->TS;
+              j->DIST = i->DIST + 1;
+            }
           }
       }
 
@@ -513,4 +527,4 @@ namespace ck
     return SINK;
   }
 
-}
\ No newline at end of file
+}
diff --git a/package_bgs/LBSP/BackgroundSubtractorLBSP.cpp b/package_bgs/LBSP/BackgroundSubtractorLBSP.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2865a30709751b16a06e8a4be0d6354d93dd0eb0
--- /dev/null
+++ b/package_bgs/LBSP/BackgroundSubtractorLBSP.cpp
@@ -0,0 +1,85 @@
+/*
+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 "BackgroundSubtractorLBSP.h"
+#include "DistanceUtils.h"
+#include "RandUtils.h"
+#include <iostream>
+#include <opencv2/imgproc/imgproc.hpp>
+#include <opencv2/highgui/highgui.hpp>
+#include <iomanip>
+#include <exception>
+
+#ifndef SIZE_MAX
+# if __WORDSIZE == 64
+#  define SIZE_MAX		(18446744073709551615UL)
+# else
+#  define SIZE_MAX		(4294967295U)
+# endif
+#endif
+
+// local define used to determine the default median blur kernel size
+#define DEFAULT_MEDIAN_BLUR_KERNEL_SIZE (9)
+
+BackgroundSubtractorLBSP::BackgroundSubtractorLBSP(float fRelLBSPThreshold, size_t nLBSPThresholdOffset)
+  : m_nImgChannels(0)
+  , m_nImgType(0)
+  , m_nLBSPThresholdOffset(nLBSPThresholdOffset)
+  , m_fRelLBSPThreshold(fRelLBSPThreshold)
+  , m_nTotPxCount(0)
+  , m_nTotRelevantPxCount(0)
+  , m_nFrameIndex(SIZE_MAX)
+  , m_nFramesSinceLastReset(0)
+  , m_nModelResetCooldown(0)
+  , m_aPxIdxLUT(nullptr)
+  , m_aPxInfoLUT(nullptr)
+  , m_nDefaultMedianBlurKernelSize(DEFAULT_MEDIAN_BLUR_KERNEL_SIZE)
+  , m_bInitialized(false)
+  , m_bAutoModelResetEnabled(true)
+  , m_bUsingMovingCamera(false)
+  , nDebugCoordX(0), nDebugCoordY(0) {
+  CV_Assert(m_fRelLBSPThreshold >= 0);
+}
+
+BackgroundSubtractorLBSP::~BackgroundSubtractorLBSP() {}
+
+void BackgroundSubtractorLBSP::initialize(const cv::Mat& oInitImg) {
+  this->initialize(oInitImg, cv::Mat());
+}
+
+/*cv::AlgorithmInfo* BackgroundSubtractorLBSP::info() const {
+  return nullptr;
+}*/
+
+cv::Mat BackgroundSubtractorLBSP::getROICopy() const {
+  return m_oROI.clone();
+}
+
+void BackgroundSubtractorLBSP::setROI(cv::Mat& oROI) {
+  LBSP::validateROI(oROI);
+  CV_Assert(cv::countNonZero(oROI) > 0);
+  if (m_bInitialized) {
+    cv::Mat oLatestBackgroundImage;
+    getBackgroundImage(oLatestBackgroundImage);
+    initialize(oLatestBackgroundImage, oROI);
+  }
+  else
+    m_oROI = oROI.clone();
+}
+
+void BackgroundSubtractorLBSP::setAutomaticModelReset(bool bVal) {
+  m_bAutoModelResetEnabled = bVal;
+}
diff --git a/package_bgs/LBSP/BackgroundSubtractorLBSP.h b/package_bgs/LBSP/BackgroundSubtractorLBSP.h
new file mode 100644
index 0000000000000000000000000000000000000000..ef0576c9149a4be20ea8cfb2b24f9fd48c65e4ba
--- /dev/null
+++ b/package_bgs/LBSP/BackgroundSubtractorLBSP.h
@@ -0,0 +1,101 @@
+/*
+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
+
+#include <opencv2/features2d/features2d.hpp>
+#include <opencv2/video/background_segm.hpp>
+#include "LBSP.h"
+
+/*!
+  Local Binary Similarity Pattern (LBSP)-based change detection algorithm (abstract version/base class).
+
+  For more details on the different parameters, see P.-L. St-Charles and G.-A. Bilodeau, "Improving Background
+  Subtraction using Local Binary Similarity Patterns", in WACV 2014, or G.-A. Bilodeau et al, "Change Detection
+  in Feature Space Using Local Binary Similarity Patterns", in CRV 2013.
+
+  This algorithm is currently NOT thread-safe.
+ */
+class BackgroundSubtractorLBSP : public cv::BackgroundSubtractor {
+public:
+  //! full constructor
+  BackgroundSubtractorLBSP(float fRelLBSPThreshold, size_t nLBSPThresholdOffset = 0);
+  //! default destructor
+  virtual ~BackgroundSubtractorLBSP();
+  //! (re)initiaization method; needs to be called before starting background subtraction
+  virtual void initialize(const cv::Mat& oInitImg);
+  //! (re)initiaization method; needs to be called before starting background subtraction
+  virtual void initialize(const cv::Mat& oInitImg, const cv::Mat& oROI) = 0;
+  //! primary model update function; the learning param is used to override the internal learning speed (ignored when <= 0)
+  virtual void apply(cv::InputArray image, cv::OutputArray fgmask, double learningRate = 0) = 0;
+  //! unused, always returns nullptr
+  //virtual cv::AlgorithmInfo* info() const;
+  //! returns a copy of the ROI used for descriptor extraction
+  virtual cv::Mat getROICopy() const;
+  //! sets the ROI to be used for descriptor extraction (note: this function will reinit the model and return the usable ROI)
+  virtual void setROI(cv::Mat& oROI);
+  //! turns automatic model reset on or off
+  void setAutomaticModelReset(bool);
+
+protected:
+  struct PxInfoBase {
+    int nImgCoord_Y;
+    int nImgCoord_X;
+    size_t nModelIdx;
+  };
+  //! background model ROI used for LBSP descriptor extraction (specific to the input image size)
+  cv::Mat m_oROI;
+  //! input image size
+  cv::Size m_oImgSize;
+  //! input image channel size
+  size_t m_nImgChannels;
+  //! input image type
+  int m_nImgType;
+  //! LBSP internal threshold offset value, used to reduce texture noise in dark regions
+  const size_t m_nLBSPThresholdOffset;
+  //! LBSP relative internal threshold (kept here since we don't keep an LBSP object)
+  const float m_fRelLBSPThreshold;
+  //! total number of pixels (depends on the input frame size) & total number of relevant pixels
+  size_t m_nTotPxCount, m_nTotRelevantPxCount;
+  //! current frame index, frame count since last model reset & model reset cooldown counters
+  size_t m_nFrameIndex, m_nFramesSinceLastReset, m_nModelResetCooldown;
+  //! pre-allocated internal LBSP threshold values LUT for all possible 8-bit intensities
+  size_t m_anLBSPThreshold_8bitLUT[UCHAR_MAX + 1];
+  //! internal pixel index LUT for all relevant analysis regions (based on the provided ROI)
+  size_t* m_aPxIdxLUT;
+  //! internal pixel info LUT for all possible pixel indexes
+  PxInfoBase* m_aPxInfoLUT;
+  //! default kernel size for median blur post-proc filtering
+  const int m_nDefaultMedianBlurKernelSize;
+  //! specifies whether the algorithm is fully initialized or not
+  bool m_bInitialized;
+  //! specifies whether automatic model resets are enabled or not
+  bool m_bAutoModelResetEnabled;
+  //! specifies whether the camera is considered moving or not
+  bool m_bUsingMovingCamera;
+  //! copy of latest pixel intensities (used when refreshing model)
+  cv::Mat m_oLastColorFrame;
+  //! copy of latest descriptors (used when refreshing model)
+  cv::Mat m_oLastDescFrame;
+  //! the foreground mask generated by the method at [t-1]
+  cv::Mat m_oLastFGMask;
+
+public:
+  // ######## DEBUG PURPOSES ONLY ##########
+  int nDebugCoordX, nDebugCoordY;
+  std::string sDebugName;
+};
+
diff --git a/package_bgs/LBSP/BackgroundSubtractorLBSP_.cpp b/package_bgs/LBSP/BackgroundSubtractorLBSP_.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4e5d4a6fad9bcc75476b3d598e05d44fca07cdd0
--- /dev/null
+++ b/package_bgs/LBSP/BackgroundSubtractorLBSP_.cpp
@@ -0,0 +1,79 @@
+/*
+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 "BackgroundSubtractorLBSP_.h"
+#include "DistanceUtils.h"
+#include "RandUtils.h"
+#include <iostream>
+#include <opencv2/imgproc/imgproc.hpp>
+#include <opencv2/highgui/highgui.hpp>
+#include <iomanip>
+#include <exception>
+
+// local define used to determine the default median blur kernel size
+#define DEFAULT_MEDIAN_BLUR_KERNEL_SIZE (9)
+
+BackgroundSubtractorLBSP_::BackgroundSubtractorLBSP_(float fRelLBSPThreshold, size_t nLBSPThresholdOffset)
+  : m_nImgChannels(0)
+  , m_nImgType(0)
+  , m_nLBSPThresholdOffset(nLBSPThresholdOffset)
+  , m_fRelLBSPThreshold(fRelLBSPThreshold)
+  , m_nTotPxCount(0)
+  , m_nTotRelevantPxCount(0)
+  , m_nFrameIndex(SIZE_MAX)
+  , m_nFramesSinceLastReset(0)
+  , m_nModelResetCooldown(0)
+  , m_aPxIdxLUT(nullptr)
+  , m_aPxInfoLUT(nullptr)
+  , m_nDefaultMedianBlurKernelSize(DEFAULT_MEDIAN_BLUR_KERNEL_SIZE)
+  , m_bInitialized(false)
+  , m_bAutoModelResetEnabled(true)
+  , m_bUsingMovingCamera(false)
+  , m_nDebugCoordX(0)
+  , m_nDebugCoordY(0)
+  , m_pDebugFS(nullptr) {
+  CV_Assert(m_fRelLBSPThreshold >= 0);
+}
+
+BackgroundSubtractorLBSP_::~BackgroundSubtractorLBSP_() {}
+
+void BackgroundSubtractorLBSP_::initialize(const cv::Mat& oInitImg) {
+  this->initialize(oInitImg, cv::Mat());
+}
+/*
+cv::AlgorithmInfo* BackgroundSubtractorLBSP_::info() const {
+    return nullptr;
+}
+*/
+cv::Mat BackgroundSubtractorLBSP_::getROICopy() const {
+  return m_oROI.clone();
+}
+
+void BackgroundSubtractorLBSP_::setROI(cv::Mat& oROI) {
+  LBSP_::validateROI(oROI);
+  CV_Assert(cv::countNonZero(oROI) > 0);
+  if (m_bInitialized) {
+    cv::Mat oLatestBackgroundImage;
+    getBackgroundImage(oLatestBackgroundImage);
+    initialize(oLatestBackgroundImage, oROI);
+  }
+  else
+    m_oROI = oROI.clone();
+}
+
+void BackgroundSubtractorLBSP_::setAutomaticModelReset(bool bVal) {
+  m_bAutoModelResetEnabled = bVal;
+}
diff --git a/package_bgs/LBSP/BackgroundSubtractorLBSP_.h b/package_bgs/LBSP/BackgroundSubtractorLBSP_.h
new file mode 100644
index 0000000000000000000000000000000000000000..861f78a7bd15a9e84a23e4f69f3fc1d9b88c6692
--- /dev/null
+++ b/package_bgs/LBSP/BackgroundSubtractorLBSP_.h
@@ -0,0 +1,107 @@
+/*
+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
+
+#include <opencv2/features2d/features2d.hpp>
+#include <opencv2/video/background_segm.hpp>
+#include "LBSP_.h"
+
+/*!
+    Local Binary Similarity Pattern (LBSP)-based change detection algorithm (abstract version/base class).
+
+    For more details on the different parameters, see P.-L. St-Charles and G.-A. Bilodeau, "Improving Background
+    Subtraction using Local Binary Similarity Patterns", in WACV 2014, or G.-A. Bilodeau et al, "Change Detection
+    in Feature Space Using Local Binary Similarity Patterns", in CRV 2013.
+
+    This algorithm is currently NOT thread-safe.
+ */
+class BackgroundSubtractorLBSP_ : public cv::BackgroundSubtractor {
+public:
+  //! full constructor
+  BackgroundSubtractorLBSP_(float fRelLBSPThreshold, size_t nLBSPThresholdOffset = 0);
+  //! default destructor
+  virtual ~BackgroundSubtractorLBSP_();
+  //! (re)initiaization method; needs to be called before starting background subtraction
+  virtual void initialize(const cv::Mat& oInitImg);
+  //! (re)initiaization method; needs to be called before starting background subtraction
+  virtual void initialize(const cv::Mat& oInitImg, const cv::Mat& oROI) = 0;
+  //! primary model update function; the learning param is used to override the internal learning speed (ignored when <= 0)
+  virtual void apply(cv::InputArray image, cv::OutputArray fgmask, double learningRate = 0) = 0;
+  //! unused, always returns nullptr
+  //virtual cv::AlgorithmInfo* info() const;
+  //! returns a copy of the ROI used for descriptor extraction
+  virtual cv::Mat getROICopy() const;
+  //! sets the ROI to be used for descriptor extraction (note: this function will reinit the model and return the usable ROI)
+  virtual void setROI(cv::Mat& oROI);
+  //! turns automatic model reset on or off
+  void setAutomaticModelReset(bool);
+
+protected:
+  struct PxInfoBase {
+    int nImgCoord_Y;
+    int nImgCoord_X;
+    size_t nModelIdx;
+  };
+  //! background model ROI used for LBSP descriptor extraction (specific to the input image size)
+  cv::Mat m_oROI;
+  //! input image size
+  cv::Size m_oImgSize;
+  //! input image channel size
+  size_t m_nImgChannels;
+  //! input image type
+  int m_nImgType;
+  //! LBSP internal threshold offset value, used to reduce texture noise in dark regions
+  const size_t m_nLBSPThresholdOffset;
+  //! LBSP relative internal threshold (kept here since we don't keep an LBSP object)
+  const float m_fRelLBSPThreshold;
+  //! total number of pixels (depends on the input frame size) & total number of relevant pixels
+  size_t m_nTotPxCount, m_nTotRelevantPxCount;
+  //! current frame index, frame count since last model reset & model reset cooldown counters
+  size_t m_nFrameIndex, m_nFramesSinceLastReset, m_nModelResetCooldown;
+  //! pre-allocated internal LBSP threshold values LUT for all possible 8-bit intensities
+  size_t m_anLBSPThreshold_8bitLUT[UCHAR_MAX + 1];
+  //! internal pixel index LUT for all relevant analysis regions (based on the provided ROI)
+  size_t* m_aPxIdxLUT;
+  //! internal pixel info LUT for all possible pixel indexes
+  PxInfoBase* m_aPxInfoLUT;
+  //! default kernel size for median blur post-proc filtering
+  const int m_nDefaultMedianBlurKernelSize;
+  //! specifies whether the algorithm is fully initialized or not
+  bool m_bInitialized;
+  //! specifies whether automatic model resets are enabled or not
+  bool m_bAutoModelResetEnabled;
+  //! specifies whether the camera is considered moving or not
+  bool m_bUsingMovingCamera;
+  //! copy of latest pixel intensities (used when refreshing model)
+  cv::Mat m_oLastColorFrame;
+  //! copy of latest descriptors (used when refreshing model)
+  cv::Mat m_oLastDescFrame;
+  //! the foreground mask generated by the method at [t-1]
+  cv::Mat m_oLastFGMask;
+
+private:
+  //! copy constructor -- disabled since this class (and its children) use lots of dynamic structs based on raw pointers
+  BackgroundSubtractorLBSP_(const BackgroundSubtractorLBSP_&);
+  //! assignment operator -- disabled since this class (and its children) use lots of dynamic structs based on raw pointers
+  BackgroundSubtractorLBSP_& operator=(const BackgroundSubtractorLBSP_&);
+
+public:
+  // ######## DEBUG PURPOSES ONLY ##########
+  int m_nDebugCoordX, m_nDebugCoordY;
+  std::string m_sDebugName;
+  cv::FileStorage* m_pDebugFS;
+};
diff --git a/package_bgs/LBSP/BackgroundSubtractorLOBSTER.cpp b/package_bgs/LBSP/BackgroundSubtractorLOBSTER.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9648c5c1bf8ebc2dfef307ebc5aafc7d11bd42a1
--- /dev/null
+++ b/package_bgs/LBSP/BackgroundSubtractorLOBSTER.cpp
@@ -0,0 +1,342 @@
+/*
+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 "BackgroundSubtractorLOBSTER.h"
+#include "DistanceUtils.h"
+#include "RandUtils.h"
+#include <iostream>
+#include <opencv2/imgproc/imgproc.hpp>
+#include <opencv2/highgui/highgui.hpp>
+#include <iomanip>
+
+BackgroundSubtractorLOBSTER::BackgroundSubtractorLOBSTER(float fRelLBSPThreshold
+  , size_t nLBSPThresholdOffset
+  , size_t nDescDistThreshold
+  , size_t nColorDistThreshold
+  , size_t nBGSamples
+  , size_t nRequiredBGSamples)
+  : BackgroundSubtractorLBSP(fRelLBSPThreshold, nLBSPThresholdOffset)
+  , m_nColorDistThreshold(nColorDistThreshold)
+  , m_nDescDistThreshold(nDescDistThreshold)
+  , m_nBGSamples(nBGSamples)
+  , m_nRequiredBGSamples(nRequiredBGSamples) {
+  CV_Assert(m_nRequiredBGSamples <= m_nBGSamples);
+  m_bAutoModelResetEnabled = false; // @@@@@@ not supported here for now
+}
+
+BackgroundSubtractorLOBSTER::~BackgroundSubtractorLOBSTER() {
+  if (m_aPxIdxLUT)
+    delete[] m_aPxIdxLUT;
+  if (m_aPxInfoLUT)
+    delete[] m_aPxInfoLUT;
+}
+
+void BackgroundSubtractorLOBSTER::initialize(const cv::Mat& oInitImg, const cv::Mat& oROI) {
+  CV_Assert(!oInitImg.empty() && oInitImg.cols > 0 && oInitImg.rows > 0);
+  CV_Assert(oInitImg.isContinuous());
+  CV_Assert(oInitImg.type() == CV_8UC1 || oInitImg.type() == CV_8UC3);
+  if (oInitImg.type() == CV_8UC3) {
+    std::vector<cv::Mat> voInitImgChannels;
+    cv::split(oInitImg, voInitImgChannels);
+    if (!cv::countNonZero((voInitImgChannels[0] != voInitImgChannels[1]) | (voInitImgChannels[2] != voInitImgChannels[1])))
+      std::cout << std::endl << "\tBackgroundSubtractorLOBSTER : Warning, grayscale images should always be passed in CV_8UC1 format for optimal performance." << std::endl;
+  }
+  cv::Mat oNewBGROI;
+  if (oROI.empty() && (m_oROI.empty() || oROI.size() != oInitImg.size())) {
+    oNewBGROI.create(oInitImg.size(), CV_8UC1);
+    oNewBGROI = cv::Scalar_<uchar>(UCHAR_MAX);
+  }
+  else if (oROI.empty())
+    oNewBGROI = m_oROI;
+  else {
+    CV_Assert(oROI.size() == oInitImg.size() && oROI.type() == CV_8UC1);
+    CV_Assert(cv::countNonZero((oROI < UCHAR_MAX)&(oROI > 0)) == 0);
+    oNewBGROI = oROI.clone();
+  }
+  LBSP::validateROI(oNewBGROI);
+  const size_t nROIPxCount = (size_t)cv::countNonZero(oNewBGROI);
+  CV_Assert(nROIPxCount > 0);
+  m_oROI = oNewBGROI;
+  m_oImgSize = oInitImg.size();
+  m_nImgType = oInitImg.type();
+  m_nImgChannels = oInitImg.channels();
+  m_nTotPxCount = m_oImgSize.area();
+  m_nTotRelevantPxCount = nROIPxCount;
+  m_nFrameIndex = 0;
+  m_nFramesSinceLastReset = 0;
+  m_nModelResetCooldown = 0;
+  m_oLastFGMask.create(m_oImgSize, CV_8UC1);
+  m_oLastFGMask = cv::Scalar_<uchar>(0);
+  m_oLastColorFrame.create(m_oImgSize, CV_8UC((int)m_nImgChannels));
+  m_oLastColorFrame = cv::Scalar_<uchar>::all(0);
+  m_oLastDescFrame.create(m_oImgSize, CV_16UC((int)m_nImgChannels));
+  m_oLastDescFrame = cv::Scalar_<ushort>::all(0);
+  m_voBGColorSamples.resize(m_nBGSamples);
+  m_voBGDescSamples.resize(m_nBGSamples);
+  for (size_t s = 0; s < m_nBGSamples; ++s) {
+    m_voBGColorSamples[s].create(m_oImgSize, CV_8UC((int)m_nImgChannels));
+    m_voBGColorSamples[s] = cv::Scalar_<uchar>::all(0);
+    m_voBGDescSamples[s].create(m_oImgSize, CV_16UC((int)m_nImgChannels));
+    m_voBGDescSamples[s] = cv::Scalar_<ushort>::all(0);
+  }
+  if (m_aPxIdxLUT)
+    delete[] m_aPxIdxLUT;
+  if (m_aPxInfoLUT)
+    delete[] m_aPxInfoLUT;
+  m_aPxIdxLUT = new size_t[m_nTotRelevantPxCount];
+  m_aPxInfoLUT = new PxInfoBase[m_nTotPxCount];
+  if (m_nImgChannels == 1) {
+    CV_Assert(m_oLastColorFrame.step.p[0] == (size_t)m_oImgSize.width && m_oLastColorFrame.step.p[1] == 1);
+    CV_Assert(m_oLastDescFrame.step.p[0] == m_oLastColorFrame.step.p[0] * 2 && m_oLastDescFrame.step.p[1] == m_oLastColorFrame.step.p[1] * 2);
+    for (size_t t = 0; t <= UCHAR_MAX; ++t)
+      m_anLBSPThreshold_8bitLUT[t] = cv::saturate_cast<uchar>((t*m_fRelLBSPThreshold + m_nLBSPThresholdOffset) / 2);
+    for (size_t nPxIter = 0, nModelIter = 0; nPxIter < m_nTotPxCount; ++nPxIter) {
+      if (m_oROI.data[nPxIter]) {
+        m_aPxIdxLUT[nModelIter] = nPxIter;
+        m_aPxInfoLUT[nPxIter].nImgCoord_Y = (int)nPxIter / m_oImgSize.width;
+        m_aPxInfoLUT[nPxIter].nImgCoord_X = (int)nPxIter%m_oImgSize.width;
+        m_aPxInfoLUT[nPxIter].nModelIdx = nModelIter;
+        m_oLastColorFrame.data[nPxIter] = oInitImg.data[nPxIter];
+        const size_t nDescIter = nPxIter * 2;
+        LBSP::computeGrayscaleDescriptor(oInitImg, oInitImg.data[nPxIter], m_aPxInfoLUT[nPxIter].nImgCoord_X, m_aPxInfoLUT[nPxIter].nImgCoord_Y, m_anLBSPThreshold_8bitLUT[oInitImg.data[nPxIter]], *((ushort*)(m_oLastDescFrame.data + nDescIter)));
+        ++nModelIter;
+      }
+    }
+  }
+  else { //m_nImgChannels==3
+    CV_Assert(m_oLastColorFrame.step.p[0] == (size_t)m_oImgSize.width * 3 && m_oLastColorFrame.step.p[1] == 3);
+    CV_Assert(m_oLastDescFrame.step.p[0] == m_oLastColorFrame.step.p[0] * 2 && m_oLastDescFrame.step.p[1] == m_oLastColorFrame.step.p[1] * 2);
+    for (size_t t = 0; t <= UCHAR_MAX; ++t)
+      m_anLBSPThreshold_8bitLUT[t] = cv::saturate_cast<uchar>(t*m_fRelLBSPThreshold + m_nLBSPThresholdOffset);
+    for (size_t nPxIter = 0, nModelIter = 0; nPxIter < m_nTotPxCount; ++nPxIter) {
+      if (m_oROI.data[nPxIter]) {
+        m_aPxIdxLUT[nModelIter] = nPxIter;
+        m_aPxInfoLUT[nPxIter].nImgCoord_Y = (int)nPxIter / m_oImgSize.width;
+        m_aPxInfoLUT[nPxIter].nImgCoord_X = (int)nPxIter%m_oImgSize.width;
+        m_aPxInfoLUT[nPxIter].nModelIdx = nModelIter;
+        const size_t nPxRGBIter = nPxIter * 3;
+        const size_t nDescRGBIter = nPxRGBIter * 2;
+        for (size_t c = 0; c < 3; ++c) {
+          m_oLastColorFrame.data[nPxRGBIter + c] = oInitImg.data[nPxRGBIter + c];
+          LBSP::computeSingleRGBDescriptor(oInitImg, oInitImg.data[nPxRGBIter + c], m_aPxInfoLUT[nPxIter].nImgCoord_X, m_aPxInfoLUT[nPxIter].nImgCoord_Y, c, m_anLBSPThreshold_8bitLUT[oInitImg.data[nPxRGBIter + c]], ((ushort*)(m_oLastDescFrame.data + nDescRGBIter))[c]);
+        }
+        ++nModelIter;
+      }
+    }
+  }
+  m_bInitialized = true;
+  refreshModel(1.0f);
+}
+
+void BackgroundSubtractorLOBSTER::refreshModel(float fSamplesRefreshFrac, bool bForceFGUpdate) {
+  // == refresh
+  CV_Assert(m_bInitialized);
+  CV_Assert(fSamplesRefreshFrac > 0.0f && fSamplesRefreshFrac <= 1.0f);
+  const size_t nModelsToRefresh = fSamplesRefreshFrac < 1.0f ? (size_t)(fSamplesRefreshFrac*m_nBGSamples) : m_nBGSamples;
+  const size_t nRefreshStartPos = fSamplesRefreshFrac < 1.0f ? rand() % m_nBGSamples : 0;
+  if (m_nImgChannels == 1) {
+    for (size_t nModelIter = 0; nModelIter < m_nTotRelevantPxCount; ++nModelIter) {
+      const size_t nPxIter = m_aPxIdxLUT[nModelIter];
+      if (bForceFGUpdate || !m_oLastFGMask.data[nPxIter]) {
+        for (size_t nCurrModelIdx = nRefreshStartPos; nCurrModelIdx < nRefreshStartPos + nModelsToRefresh; ++nCurrModelIdx) {
+          int nSampleImgCoord_Y, nSampleImgCoord_X;
+          getRandSamplePosition(nSampleImgCoord_X, nSampleImgCoord_Y, m_aPxInfoLUT[nPxIter].nImgCoord_X, m_aPxInfoLUT[nPxIter].nImgCoord_Y, LBSP::PATCH_SIZE / 2, m_oImgSize);
+          const size_t nSamplePxIdx = m_oImgSize.width*nSampleImgCoord_Y + nSampleImgCoord_X;
+          if (bForceFGUpdate || !m_oLastFGMask.data[nSamplePxIdx]) {
+            const size_t nCurrRealModelIdx = nCurrModelIdx%m_nBGSamples;
+            m_voBGColorSamples[nCurrRealModelIdx].data[nPxIter] = m_oLastColorFrame.data[nSamplePxIdx];
+            *((ushort*)(m_voBGDescSamples[nCurrRealModelIdx].data + nPxIter * 2)) = *((ushort*)(m_oLastDescFrame.data + nSamplePxIdx * 2));
+          }
+        }
+      }
+    }
+  }
+  else { //m_nImgChannels==3
+    for (size_t nModelIter = 0; nModelIter < m_nTotRelevantPxCount; ++nModelIter) {
+      const size_t nPxIter = m_aPxIdxLUT[nModelIter];
+      if (bForceFGUpdate || !m_oLastFGMask.data[nPxIter]) {
+        for (size_t nCurrModelIdx = nRefreshStartPos; nCurrModelIdx < nRefreshStartPos + nModelsToRefresh; ++nCurrModelIdx) {
+          int nSampleImgCoord_Y, nSampleImgCoord_X;
+          getRandSamplePosition(nSampleImgCoord_X, nSampleImgCoord_Y, m_aPxInfoLUT[nPxIter].nImgCoord_X, m_aPxInfoLUT[nPxIter].nImgCoord_Y, LBSP::PATCH_SIZE / 2, m_oImgSize);
+          const size_t nSamplePxIdx = m_oImgSize.width*nSampleImgCoord_Y + nSampleImgCoord_X;
+          if (bForceFGUpdate || !m_oLastFGMask.data[nSamplePxIdx]) {
+            const size_t nCurrRealModelIdx = nCurrModelIdx%m_nBGSamples;
+            for (size_t c = 0; c < 3; ++c) {
+              m_voBGColorSamples[nCurrRealModelIdx].data[nPxIter * 3 + c] = m_oLastColorFrame.data[nSamplePxIdx * 3 + c];
+              *((ushort*)(m_voBGDescSamples[nCurrRealModelIdx].data + (nPxIter * 3 + c) * 2)) = *((ushort*)(m_oLastDescFrame.data + (nSamplePxIdx * 3 + c) * 2));
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+void BackgroundSubtractorLOBSTER::apply(cv::InputArray _image, cv::OutputArray _fgmask, double learningRate) {
+  CV_Assert(m_bInitialized);
+  CV_Assert(learningRate > 0);
+  cv::Mat oInputImg = _image.getMat();
+  CV_Assert(oInputImg.type() == m_nImgType && oInputImg.size() == m_oImgSize);
+  CV_Assert(oInputImg.isContinuous());
+  _fgmask.create(m_oImgSize, CV_8UC1);
+  cv::Mat oCurrFGMask = _fgmask.getMat();
+  oCurrFGMask = cv::Scalar_<uchar>(0);
+  const size_t nLearningRate = (size_t)ceil(learningRate);
+  if (m_nImgChannels == 1) {
+    for (size_t nModelIter = 0; nModelIter < m_nTotRelevantPxCount; ++nModelIter) {
+      const size_t nPxIter = m_aPxIdxLUT[nModelIter];
+      const size_t nDescIter = nPxIter * 2;
+      const int nCurrImgCoord_X = m_aPxInfoLUT[nPxIter].nImgCoord_X;
+      const int nCurrImgCoord_Y = m_aPxInfoLUT[nPxIter].nImgCoord_Y;
+      const uchar nCurrColor = oInputImg.data[nPxIter];
+      size_t nGoodSamplesCount = 0, nModelIdx = 0;
+      ushort nCurrInputDesc;
+      while (nGoodSamplesCount < m_nRequiredBGSamples && nModelIdx < m_nBGSamples) {
+        const uchar nBGColor = m_voBGColorSamples[nModelIdx].data[nPxIter];
+        {
+          const size_t nColorDist = L1dist(nCurrColor, nBGColor);
+          if (nColorDist > m_nColorDistThreshold / 2)
+            goto failedcheck1ch;
+          LBSP::computeGrayscaleDescriptor(oInputImg, nBGColor, nCurrImgCoord_X, nCurrImgCoord_Y, m_anLBSPThreshold_8bitLUT[nBGColor], nCurrInputDesc);
+          const size_t nDescDist = hdist(nCurrInputDesc, *((ushort*)(m_voBGDescSamples[nModelIdx].data + nDescIter)));
+          if (nDescDist > m_nDescDistThreshold)
+            goto failedcheck1ch;
+          nGoodSamplesCount++;
+        }
+      failedcheck1ch:
+        nModelIdx++;
+      }
+      if (nGoodSamplesCount < m_nRequiredBGSamples)
+        oCurrFGMask.data[nPxIter] = UCHAR_MAX;
+      else {
+        if ((rand() % nLearningRate) == 0) {
+          const size_t nSampleModelIdx = rand() % m_nBGSamples;
+          ushort& nRandInputDesc = *((ushort*)(m_voBGDescSamples[nSampleModelIdx].data + nDescIter));
+          LBSP::computeGrayscaleDescriptor(oInputImg, nCurrColor, nCurrImgCoord_X, nCurrImgCoord_Y, m_anLBSPThreshold_8bitLUT[nCurrColor], nRandInputDesc);
+          m_voBGColorSamples[nSampleModelIdx].data[nPxIter] = nCurrColor;
+        }
+        if ((rand() % nLearningRate) == 0) {
+          int nSampleImgCoord_Y, nSampleImgCoord_X;
+          getRandNeighborPosition_3x3(nSampleImgCoord_X, nSampleImgCoord_Y, nCurrImgCoord_X, nCurrImgCoord_Y, LBSP::PATCH_SIZE / 2, m_oImgSize);
+          const size_t nSampleModelIdx = rand() % m_nBGSamples;
+          ushort& nRandInputDesc = m_voBGDescSamples[nSampleModelIdx].at<ushort>(nSampleImgCoord_Y, nSampleImgCoord_X);
+          LBSP::computeGrayscaleDescriptor(oInputImg, nCurrColor, nCurrImgCoord_X, nCurrImgCoord_Y, m_anLBSPThreshold_8bitLUT[nCurrColor], nRandInputDesc);
+          m_voBGColorSamples[nSampleModelIdx].at<uchar>(nSampleImgCoord_Y, nSampleImgCoord_X) = nCurrColor;
+        }
+      }
+    }
+  }
+  else { //m_nImgChannels==3
+    const size_t nCurrDescDistThreshold = m_nDescDistThreshold * 3;
+    const size_t nCurrColorDistThreshold = m_nColorDistThreshold * 3;
+    const size_t nCurrSCDescDistThreshold = nCurrDescDistThreshold / 2;
+    const size_t nCurrSCColorDistThreshold = nCurrColorDistThreshold / 2;
+    const size_t desc_row_step = m_voBGDescSamples[0].step.p[0];
+    const size_t img_row_step = m_voBGColorSamples[0].step.p[0];
+    for (size_t nModelIter = 0; nModelIter < m_nTotRelevantPxCount; ++nModelIter) {
+      const size_t nPxIter = m_aPxIdxLUT[nModelIter];
+      const int nCurrImgCoord_X = m_aPxInfoLUT[nPxIter].nImgCoord_X;
+      const int nCurrImgCoord_Y = m_aPxInfoLUT[nPxIter].nImgCoord_Y;
+      const size_t nPxIterRGB = nPxIter * 3;
+      const size_t nDescIterRGB = nPxIterRGB * 2;
+      const uchar* const anCurrColor = oInputImg.data + nPxIterRGB;
+      size_t nGoodSamplesCount = 0, nModelIdx = 0;
+      ushort anCurrInputDesc[3];
+      while (nGoodSamplesCount < m_nRequiredBGSamples && nModelIdx < m_nBGSamples) {
+        const ushort* const anBGDesc = (ushort*)(m_voBGDescSamples[nModelIdx].data + nDescIterRGB);
+        const uchar* const anBGColor = m_voBGColorSamples[nModelIdx].data + nPxIterRGB;
+        size_t nTotColorDist = 0;
+        size_t nTotDescDist = 0;
+        for (size_t c = 0; c < 3; ++c) {
+          const size_t nColorDist = L1dist(anCurrColor[c], anBGColor[c]);
+          if (nColorDist > nCurrSCColorDistThreshold)
+            goto failedcheck3ch;
+          LBSP::computeSingleRGBDescriptor(oInputImg, anBGColor[c], nCurrImgCoord_X, nCurrImgCoord_Y, c, m_anLBSPThreshold_8bitLUT[anBGColor[c]], anCurrInputDesc[c]);
+          const size_t nDescDist = hdist(anCurrInputDesc[c], anBGDesc[c]);
+          if (nDescDist > nCurrSCDescDistThreshold)
+            goto failedcheck3ch;
+          nTotColorDist += nColorDist;
+          nTotDescDist += nDescDist;
+        }
+        if (nTotDescDist <= nCurrDescDistThreshold && nTotColorDist <= nCurrColorDistThreshold)
+          nGoodSamplesCount++;
+      failedcheck3ch:
+        nModelIdx++;
+      }
+      if (nGoodSamplesCount < m_nRequiredBGSamples)
+        oCurrFGMask.data[nPxIter] = UCHAR_MAX;
+      else {
+        if ((rand() % nLearningRate) == 0) {
+          const size_t nSampleModelIdx = rand() % m_nBGSamples;
+          ushort* anRandInputDesc = ((ushort*)(m_voBGDescSamples[nSampleModelIdx].data + nDescIterRGB));
+          const size_t anCurrIntraLBSPThresholds[3] = { m_anLBSPThreshold_8bitLUT[anCurrColor[0]],m_anLBSPThreshold_8bitLUT[anCurrColor[1]],m_anLBSPThreshold_8bitLUT[anCurrColor[2]] };
+          LBSP::computeRGBDescriptor(oInputImg, anCurrColor, nCurrImgCoord_X, nCurrImgCoord_Y, anCurrIntraLBSPThresholds, anRandInputDesc);
+          for (size_t c = 0; c < 3; ++c)
+            *(m_voBGColorSamples[nSampleModelIdx].data + nPxIterRGB + c) = anCurrColor[c];
+        }
+        if ((rand() % nLearningRate) == 0) {
+          int nSampleImgCoord_Y, nSampleImgCoord_X;
+          getRandNeighborPosition_3x3(nSampleImgCoord_X, nSampleImgCoord_Y, nCurrImgCoord_X, nCurrImgCoord_Y, LBSP::PATCH_SIZE / 2, m_oImgSize);
+          const size_t nSampleModelIdx = rand() % m_nBGSamples;
+          ushort* anRandInputDesc = ((ushort*)(m_voBGDescSamples[nSampleModelIdx].data + desc_row_step*nSampleImgCoord_Y + 6 * nSampleImgCoord_X));
+          const size_t anCurrIntraLBSPThresholds[3] = { m_anLBSPThreshold_8bitLUT[anCurrColor[0]],m_anLBSPThreshold_8bitLUT[anCurrColor[1]],m_anLBSPThreshold_8bitLUT[anCurrColor[2]] };
+          LBSP::computeRGBDescriptor(oInputImg, anCurrColor, nCurrImgCoord_X, nCurrImgCoord_Y, anCurrIntraLBSPThresholds, anRandInputDesc);
+          for (size_t c = 0; c < 3; ++c)
+            *(m_voBGColorSamples[nSampleModelIdx].data + img_row_step*nSampleImgCoord_Y + 3 * nSampleImgCoord_X + c) = anCurrColor[c];
+        }
+      }
+    }
+  }
+  cv::medianBlur(oCurrFGMask, m_oLastFGMask, m_nDefaultMedianBlurKernelSize);
+  m_oLastFGMask.copyTo(oCurrFGMask);
+}
+
+void BackgroundSubtractorLOBSTER::getBackgroundImage(cv::OutputArray backgroundImage) const {
+  CV_DbgAssert(m_bInitialized);
+  cv::Mat oAvgBGImg = cv::Mat::zeros(m_oImgSize, CV_32FC((int)m_nImgChannels));
+  for (size_t s = 0; s < m_nBGSamples; ++s) {
+    for (int y = 0; y < m_oImgSize.height; ++y) {
+      for (int x = 0; x < m_oImgSize.width; ++x) {
+        const size_t idx_nimg = m_voBGColorSamples[s].step.p[0] * y + m_voBGColorSamples[s].step.p[1] * x;
+        const size_t idx_flt32 = idx_nimg * 4;
+        float* oAvgBgImgPtr = (float*)(oAvgBGImg.data + idx_flt32);
+        const uchar* const oBGImgPtr = m_voBGColorSamples[s].data + idx_nimg;
+        for (size_t c = 0; c < m_nImgChannels; ++c)
+          oAvgBgImgPtr[c] += ((float)oBGImgPtr[c]) / m_nBGSamples;
+      }
+    }
+  }
+  oAvgBGImg.convertTo(backgroundImage, CV_8U);
+}
+
+void BackgroundSubtractorLOBSTER::getBackgroundDescriptorsImage(cv::OutputArray backgroundDescImage) const {
+  CV_Assert(LBSP::DESC_SIZE == 2);
+  CV_Assert(m_bInitialized);
+  cv::Mat oAvgBGDesc = cv::Mat::zeros(m_oImgSize, CV_32FC((int)m_nImgChannels));
+  for (size_t n = 0; n < m_voBGDescSamples.size(); ++n) {
+    for (int y = 0; y < m_oImgSize.height; ++y) {
+      for (int x = 0; x < m_oImgSize.width; ++x) {
+        const size_t idx_ndesc = m_voBGDescSamples[n].step.p[0] * y + m_voBGDescSamples[n].step.p[1] * x;
+        const size_t idx_flt32 = idx_ndesc * 2;
+        float* oAvgBgDescPtr = (float*)(oAvgBGDesc.data + idx_flt32);
+        const ushort* const oBGDescPtr = (ushort*)(m_voBGDescSamples[n].data + idx_ndesc);
+        for (size_t c = 0; c < m_nImgChannels; ++c)
+          oAvgBgDescPtr[c] += ((float)oBGDescPtr[c]) / m_voBGDescSamples.size();
+      }
+    }
+  }
+  oAvgBGDesc.convertTo(backgroundDescImage, CV_16U);
+}
diff --git a/package_bgs/LBSP/BackgroundSubtractorLOBSTER.h b/package_bgs/LBSP/BackgroundSubtractorLOBSTER.h
new file mode 100644
index 0000000000000000000000000000000000000000..d69fd1c3e8d1ff6d9f7a3f7ea807b92dcc94f7e4
--- /dev/null
+++ b/package_bgs/LBSP/BackgroundSubtractorLOBSTER.h
@@ -0,0 +1,83 @@
+/*
+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
+
+#include "BackgroundSubtractorLBSP.h"
+
+//! defines the default value for BackgroundSubtractorLBSP::m_fRelLBSPThreshold
+#define BGSLOBSTER_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD (0.365f)
+//! defines the default value for BackgroundSubtractorLBSP::m_nLBSPThresholdOffset
+#define BGSLOBSTER_DEFAULT_LBSP_OFFSET_SIMILARITY_THRESHOLD (0)
+//! defines the default value for BackgroundSubtractorLOBSTER::m_nDescDistThreshold
+#define BGSLOBSTER_DEFAULT_DESC_DIST_THRESHOLD (4)
+//! defines the default value for BackgroundSubtractorLOBSTER::m_nColorDistThreshold
+#define BGSLOBSTER_DEFAULT_COLOR_DIST_THRESHOLD (30)
+//! defines the default value for BackgroundSubtractorLOBSTER::m_nBGSamples
+#define BGSLOBSTER_DEFAULT_NB_BG_SAMPLES (35)
+//! defines the default value for BackgroundSubtractorLOBSTER::m_nRequiredBGSamples
+#define BGSLOBSTER_DEFAULT_REQUIRED_NB_BG_SAMPLES (2)
+//! defines the default value for the learning rate passed to BackgroundSubtractorLOBSTER::operator()
+#define BGSLOBSTER_DEFAULT_LEARNING_RATE (16)
+
+/*!
+  LOcal Binary Similarity segmenTER (LOBSTER) change detection algorithm.
+
+  Note: both grayscale and RGB/BGR images may be used with this extractor (parameters are adjusted automatically).
+  For optimal grayscale results, use CV_8UC1 frames instead of CV_8UC3.
+
+  For more details on the different parameters or on the algorithm itself, see P.-L. St-Charles and
+  G.-A. Bilodeau, "Improving Background Subtraction using Local Binary Similarity Patterns", in WACV 2014.
+
+  This algorithm is currently NOT thread-safe.
+ */
+class BackgroundSubtractorLOBSTER : public BackgroundSubtractorLBSP {
+public:
+  //! full constructor
+  BackgroundSubtractorLOBSTER(float fRelLBSPThreshold = BGSLOBSTER_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD,
+    size_t nLBSPThresholdOffset = BGSLOBSTER_DEFAULT_LBSP_OFFSET_SIMILARITY_THRESHOLD,
+    size_t nDescDistThreshold = BGSLOBSTER_DEFAULT_DESC_DIST_THRESHOLD,
+    size_t nColorDistThreshold = BGSLOBSTER_DEFAULT_COLOR_DIST_THRESHOLD,
+    size_t nBGSamples = BGSLOBSTER_DEFAULT_NB_BG_SAMPLES,
+    size_t nRequiredBGSamples = BGSLOBSTER_DEFAULT_REQUIRED_NB_BG_SAMPLES);
+  //! default destructor
+  virtual ~BackgroundSubtractorLOBSTER();
+  //! (re)initiaization method; needs to be called before starting background subtraction
+  virtual void initialize(const cv::Mat& oInitImg, const cv::Mat& oROI);
+  //! refreshes all samples based on the last analyzed frame
+  virtual void refreshModel(float fSamplesRefreshFrac, bool bForceFGUpdate = false);
+  //! primary model update function; the learning param is reinterpreted as an integer and should be > 0 (smaller values == faster adaptation)
+  virtual void apply(cv::InputArray image, cv::OutputArray fgmask, double learningRateOverride = BGSLOBSTER_DEFAULT_LEARNING_RATE);
+  //! returns a copy of the latest reconstructed background image
+  void getBackgroundImage(cv::OutputArray backgroundImage) const;
+  //! returns a copy of the latest reconstructed background descriptors image
+  virtual void getBackgroundDescriptorsImage(cv::OutputArray backgroundDescImage) const;
+
+protected:
+  //! absolute color distance threshold
+  const size_t m_nColorDistThreshold;
+  //! absolute descriptor distance threshold
+  const size_t m_nDescDistThreshold;
+  //! number of different samples per pixel/block to be taken from input frames to build the background model
+  const size_t m_nBGSamples;
+  //! number of similar samples needed to consider the current pixel/block as 'background'
+  const size_t m_nRequiredBGSamples;
+  //! background model pixel intensity samples
+  std::vector<cv::Mat> m_voBGColorSamples;
+  //! background model descriptors samples
+  std::vector<cv::Mat> m_voBGDescSamples;
+};
+
diff --git a/package_bgs/LBSP/BackgroundSubtractorPAWCS.cpp b/package_bgs/LBSP/BackgroundSubtractorPAWCS.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6c48df3b91115c25be8aff64e6d30c9f21865208
--- /dev/null
+++ b/package_bgs/LBSP/BackgroundSubtractorPAWCS.cpp
@@ -0,0 +1,1349 @@
+/*
+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 "BackgroundSubtractorPAWCS.h"
+#include "DistanceUtils.h"
+#include "RandUtils.h"
+#include <iostream>
+#include <opencv2/imgproc/imgproc.hpp>
+#include <opencv2/highgui/highgui.hpp>
+#include <iomanip>
+
+/*
+ *
+ * Intrinsic configuration parameters are defined here; tuning these for better
+ * performance should not be required in most cases -- although improvements in
+ * very specific scenarios are always possible.
+ *
+ */
+ //! parameter used for dynamic distance threshold adjustments ('R(x)')
+#define FEEDBACK_R_VAR (0.01f)
+//! parameters used to adjust the variation step size of 'v(x)'
+#define FEEDBACK_V_INCR  (1.000f)
+#define FEEDBACK_V_DECR  (0.100f)
+//! parameters used to scale dynamic learning rate adjustments  ('T(x)')
+#define FEEDBACK_T_DECR  (0.2500f)
+#define FEEDBACK_T_INCR  (0.5000f)
+#define FEEDBACK_T_LOWER (1.0000f)
+#define FEEDBACK_T_UPPER (256.00f)
+//! parameters used to define 'unstable' regions, based on segm noise/bg dynamics and local dist threshold values
+#define UNSTABLE_REG_RATIO_MIN (0.100f)
+#define UNSTABLE_REG_RDIST_MIN (3.000f)
+//! parameters used to scale the relative LBSP intensity threshold used for internal comparisons
+#define LBSPDESC_RATIO_MIN (0.100f)
+#define LBSPDESC_RATIO_MAX (0.500f)
+//! parameters used to trigger auto model resets in our frame-level component
+#define FRAMELEVEL_MIN_L1DIST_THRES (45)
+#define FRAMELEVEL_MIN_CDIST_THRES (FRAMELEVEL_MIN_L1DIST_THRES/10)
+#define FRAMELEVEL_DOWNSAMPLE_RATIO (8)
+//! parameters used to downscale gword maps & scale thresholds to make comparisons easier
+#define GWORD_LOOKUP_MAPS_DOWNSAMPLE_RATIO (2)
+#define GWORD_DEFAULT_NB_INIT_SAMPL_PASSES (2)
+#define GWORD_DESC_THRES_BITS_MATCH_FACTOR (4)
+
+// local define used to specify the default frame size (320x240 = QVGA)
+#define DEFAULT_FRAME_SIZE cv::Size(320,240)
+// local define used to specify the default lword/gword update rate (16 = like vibe)
+#define DEFAULT_RESAMPLING_RATE (16)
+// local define used to specify the bootstrap window size for faster model stabilization
+#define DEFAULT_BOOTSTRAP_WIN_SIZE (500)
+// local define for the amount of weight offset to apply to words, making sure new words aren't always better than old ones
+#define DEFAULT_LWORD_WEIGHT_OFFSET (DEFAULT_BOOTSTRAP_WIN_SIZE*2)
+// local define used to set the default local word occurrence increment
+#define DEFAULT_LWORD_OCC_INCR 1
+// local define for the maximum weight a word can achieve before cutting off occ incr (used to make sure model stays good for long-term uses)
+#define DEFAULT_LWORD_MAX_WEIGHT (1.0f)
+// local define for the initial weight of a new word (used to make sure old words aren't worse off than new seeds)
+#define DEFAULT_LWORD_INIT_WEIGHT (1.0f/m_nLocalWordWeightOffset)
+// local define used to specify the desc dist threshold offset used for unstable regions
+#define UNSTAB_DESC_DIST_OFFSET (m_nDescDistThresholdOffset)
+// local define used to specify the min descriptor bit count for flat regions
+#define FLAT_REGION_BIT_COUNT (s_nDescMaxDataRange_1ch/8)
+
+static const size_t s_nColorMaxDataRange_1ch = UCHAR_MAX;
+static const size_t s_nDescMaxDataRange_1ch = LBSP_::DESC_SIZE * 8;
+static const size_t s_nColorMaxDataRange_3ch = s_nColorMaxDataRange_1ch * 3;
+static const size_t s_nDescMaxDataRange_3ch = s_nDescMaxDataRange_1ch * 3;
+
+BackgroundSubtractorPAWCS::BackgroundSubtractorPAWCS(float fRelLBSPThreshold
+  , size_t nDescDistThresholdOffset
+  , size_t nMinColorDistThreshold
+  , size_t nMaxNbWords
+  , size_t nSamplesForMovingAvgs)
+  : BackgroundSubtractorLBSP_(fRelLBSPThreshold)
+  , m_nMinColorDistThreshold(nMinColorDistThreshold)
+  , m_nDescDistThresholdOffset(nDescDistThresholdOffset)
+  , m_nMaxLocalWords(nMaxNbWords)
+  , m_nCurrLocalWords(0)
+  , m_nMaxGlobalWords(nMaxNbWords / 2)
+  , m_nCurrGlobalWords(0)
+  , m_nSamplesForMovingAvgs(nSamplesForMovingAvgs)
+  , m_fLastNonFlatRegionRatio(0.0f)
+  , m_nMedianBlurKernelSize(m_nDefaultMedianBlurKernelSize)
+  , m_nDownSampledROIPxCount(0)
+  , m_nLocalWordWeightOffset(DEFAULT_LWORD_WEIGHT_OFFSET)
+  , m_apLocalWordDict(nullptr)
+  , m_aLocalWordList_1ch(nullptr)
+  , m_pLocalWordListIter_1ch(nullptr)
+  , m_aLocalWordList_3ch(nullptr)
+  , m_pLocalWordListIter_3ch(nullptr)
+  , m_apGlobalWordDict(nullptr)
+  , m_aGlobalWordList_1ch(nullptr)
+  , m_pGlobalWordListIter_1ch(nullptr)
+  , m_aGlobalWordList_3ch(nullptr)
+  , m_pGlobalWordListIter_3ch(nullptr)
+  , m_aPxInfoLUT_PAWCS(nullptr) {
+  CV_Assert(m_nMaxLocalWords > 0 && m_nMaxGlobalWords > 0);
+}
+
+BackgroundSubtractorPAWCS::~BackgroundSubtractorPAWCS() {
+  CleanupDictionaries();
+}
+
+void BackgroundSubtractorPAWCS::initialize(const cv::Mat& oInitImg, const cv::Mat& oROI) {
+  // == init
+  CV_Assert(!oInitImg.empty() && oInitImg.cols > 0 && oInitImg.rows > 0);
+  CV_Assert(oInitImg.isContinuous());
+  CV_Assert(oInitImg.type() == CV_8UC3 || oInitImg.type() == CV_8UC1);
+  if (oInitImg.type() == CV_8UC3) {
+    std::vector<cv::Mat> voInitImgChannels;
+    cv::split(oInitImg, voInitImgChannels);
+    if (!cv::countNonZero((voInitImgChannels[0] != voInitImgChannels[1]) | (voInitImgChannels[2] != voInitImgChannels[1])))
+      std::cout << std::endl << "\tBackgroundSubtractorPAWCS : Warning, grayscale images should always be passed in CV_8UC1 format for optimal performance." << std::endl;
+  }
+  cv::Mat oNewBGROI;
+  if (oROI.empty() && (m_oROI.empty() || oROI.size() != oInitImg.size())) {
+    oNewBGROI.create(oInitImg.size(), CV_8UC1);
+    oNewBGROI = cv::Scalar_<uchar>(UCHAR_MAX);
+  }
+  else if (oROI.empty())
+    oNewBGROI = m_oROI;
+  else {
+    CV_Assert(oROI.size() == oInitImg.size() && oROI.type() == CV_8UC1);
+    CV_Assert(cv::countNonZero((oROI < UCHAR_MAX)&(oROI > 0)) == 0);
+    oNewBGROI = oROI.clone();
+    cv::Mat oTempROI;
+    cv::dilate(oNewBGROI, oTempROI, cv::Mat(), cv::Point(-1, -1), LBSP_::PATCH_SIZE / 2);
+    cv::bitwise_or(oNewBGROI, oTempROI / 2, oNewBGROI);
+  }
+  const size_t nOrigROIPxCount = (size_t)cv::countNonZero(oNewBGROI);
+  CV_Assert(nOrigROIPxCount > 0);
+  LBSP_::validateROI(oNewBGROI);
+  const size_t nFinalROIPxCount = (size_t)cv::countNonZero(oNewBGROI);
+  CV_Assert(nFinalROIPxCount > 0);
+  CleanupDictionaries();
+  m_oROI = oNewBGROI;
+  m_oImgSize = oInitImg.size();
+  m_nImgType = oInitImg.type();
+  m_nImgChannels = oInitImg.channels();
+  m_nTotPxCount = m_oImgSize.area();
+  m_nTotRelevantPxCount = nFinalROIPxCount;
+  m_nFrameIndex = 0;
+  m_nFramesSinceLastReset = 0;
+  m_nModelResetCooldown = 0;
+  m_bUsingMovingCamera = false;
+  m_oDownSampledFrameSize_MotionAnalysis = cv::Size(m_oImgSize.width / FRAMELEVEL_DOWNSAMPLE_RATIO, m_oImgSize.height / FRAMELEVEL_DOWNSAMPLE_RATIO);
+  m_oDownSampledFrameSize_GlobalWordLookup = cv::Size(m_oImgSize.width / GWORD_LOOKUP_MAPS_DOWNSAMPLE_RATIO, m_oImgSize.height / GWORD_LOOKUP_MAPS_DOWNSAMPLE_RATIO);
+  cv::resize(m_oROI, m_oDownSampledROI_MotionAnalysis, m_oDownSampledFrameSize_MotionAnalysis, 0, 0, cv::INTER_AREA);
+  m_fLastNonFlatRegionRatio = 0.0f;
+  m_nCurrLocalWords = m_nMaxLocalWords;
+  if (nOrigROIPxCount >= m_nTotPxCount / 2 && (int)m_nTotPxCount >= DEFAULT_FRAME_SIZE.area()) {
+    const float fRegionSizeScaleFactor = (float)m_nTotPxCount / DEFAULT_FRAME_SIZE.area();
+    const int nRawMedianBlurKernelSize = std::min((int)floor(0.5f + fRegionSizeScaleFactor) + m_nDefaultMedianBlurKernelSize, m_nDefaultMedianBlurKernelSize + 4);
+    m_nMedianBlurKernelSize = (nRawMedianBlurKernelSize % 2) ? nRawMedianBlurKernelSize : nRawMedianBlurKernelSize - 1;
+    m_nCurrGlobalWords = m_nMaxGlobalWords;
+    m_oDownSampledROI_MotionAnalysis |= UCHAR_MAX / 2;
+  }
+  else {
+    const float fRegionSizeScaleFactor = (float)nOrigROIPxCount / DEFAULT_FRAME_SIZE.area();
+    const int nRawMedianBlurKernelSize = std::min((int)floor(0.5f + m_nDefaultMedianBlurKernelSize*fRegionSizeScaleFactor * 2) + (m_nDefaultMedianBlurKernelSize - 4), m_nDefaultMedianBlurKernelSize);
+    m_nMedianBlurKernelSize = (nRawMedianBlurKernelSize % 2) ? nRawMedianBlurKernelSize : nRawMedianBlurKernelSize - 1;
+    m_nCurrGlobalWords = std::min((size_t)std::pow(m_nMaxGlobalWords*fRegionSizeScaleFactor, 2) + 1, m_nMaxGlobalWords);
+  }
+  if (m_nImgChannels == 1) {
+    m_nCurrLocalWords = std::max(m_nCurrLocalWords / 2, (size_t)1);
+    m_nCurrGlobalWords = std::max(m_nCurrGlobalWords / 2, (size_t)1);
+  }
+  m_nDownSampledROIPxCount = (size_t)cv::countNonZero(m_oDownSampledROI_MotionAnalysis);
+  m_nLocalWordWeightOffset = DEFAULT_LWORD_WEIGHT_OFFSET;
+  m_oIllumUpdtRegionMask.create(m_oImgSize, CV_8UC1);
+  m_oIllumUpdtRegionMask = cv::Scalar_<uchar>(0);
+  m_oUpdateRateFrame.create(m_oImgSize, CV_32FC1);
+  m_oUpdateRateFrame = cv::Scalar(FEEDBACK_T_LOWER);
+  m_oDistThresholdFrame.create(m_oImgSize, CV_32FC1);
+  m_oDistThresholdFrame = cv::Scalar(2.0f);
+  m_oDistThresholdVariationFrame.create(m_oImgSize, CV_32FC1);
+  m_oDistThresholdVariationFrame = cv::Scalar(FEEDBACK_V_INCR * 10);
+  m_oMeanMinDistFrame_LT.create(m_oImgSize, CV_32FC1);
+  m_oMeanMinDistFrame_LT = cv::Scalar(0.0f);
+  m_oMeanMinDistFrame_ST.create(m_oImgSize, CV_32FC1);
+  m_oMeanMinDistFrame_ST = cv::Scalar(0.0f);
+  m_oMeanDownSampledLastDistFrame_LT.create(m_oDownSampledFrameSize_MotionAnalysis, CV_32FC((int)m_nImgChannels));
+  m_oMeanDownSampledLastDistFrame_LT = cv::Scalar(0.0f);
+  m_oMeanDownSampledLastDistFrame_ST.create(m_oDownSampledFrameSize_MotionAnalysis, CV_32FC((int)m_nImgChannels));
+  m_oMeanDownSampledLastDistFrame_ST = cv::Scalar(0.0f);
+  m_oMeanRawSegmResFrame_LT.create(m_oImgSize, CV_32FC1);
+  m_oMeanRawSegmResFrame_LT = cv::Scalar(0.0f);
+  m_oMeanRawSegmResFrame_ST.create(m_oImgSize, CV_32FC1);
+  m_oMeanRawSegmResFrame_ST = cv::Scalar(0.0f);
+  m_oMeanFinalSegmResFrame_LT.create(m_oImgSize, CV_32FC1);
+  m_oMeanFinalSegmResFrame_LT = cv::Scalar(0.0f);
+  m_oMeanFinalSegmResFrame_ST.create(m_oImgSize, CV_32FC1);
+  m_oMeanFinalSegmResFrame_ST = cv::Scalar(0.0f);
+  m_oUnstableRegionMask.create(m_oImgSize, CV_8UC1);
+  m_oUnstableRegionMask = cv::Scalar_<uchar>(0);
+  m_oBlinksFrame.create(m_oImgSize, CV_8UC1);
+  m_oBlinksFrame = cv::Scalar_<uchar>(0);
+  m_oDownSampledFrame_MotionAnalysis.create(m_oDownSampledFrameSize_MotionAnalysis, CV_8UC((int)m_nImgChannels));
+  m_oDownSampledFrame_MotionAnalysis = cv::Scalar_<uchar>::all(0);
+  m_oLastColorFrame.create(m_oImgSize, CV_8UC((int)m_nImgChannels));
+  m_oLastColorFrame = cv::Scalar_<uchar>::all(0);
+  m_oLastDescFrame.create(m_oImgSize, CV_16UC((int)m_nImgChannels));
+  m_oLastDescFrame = cv::Scalar_<ushort>::all(0);
+  m_oLastRawFGMask.create(m_oImgSize, CV_8UC1);
+  m_oLastRawFGMask = cv::Scalar_<uchar>(0);
+  m_oLastFGMask.create(m_oImgSize, CV_8UC1);
+  m_oLastFGMask = cv::Scalar_<uchar>(0);
+  m_oLastFGMask_dilated.create(m_oImgSize, CV_8UC1);
+  m_oLastFGMask_dilated = cv::Scalar_<uchar>(0);
+  m_oLastFGMask_dilated_inverted.create(m_oImgSize, CV_8UC1);
+  m_oLastFGMask_dilated_inverted = cv::Scalar_<uchar>(0);
+  m_oFGMask_FloodedHoles.create(m_oImgSize, CV_8UC1);
+  m_oFGMask_FloodedHoles = cv::Scalar_<uchar>(0);
+  m_oFGMask_PreFlood.create(m_oImgSize, CV_8UC1);
+  m_oFGMask_PreFlood = cv::Scalar_<uchar>(0);
+  m_oCurrRawFGBlinkMask.create(m_oImgSize, CV_8UC1);
+  m_oCurrRawFGBlinkMask = cv::Scalar_<uchar>(0);
+  m_oLastRawFGBlinkMask.create(m_oImgSize, CV_8UC1);
+  m_oLastRawFGBlinkMask = cv::Scalar_<uchar>(0);
+  m_oTempGlobalWordWeightDiffFactor.create(m_oDownSampledFrameSize_GlobalWordLookup, CV_32FC1);
+  m_oTempGlobalWordWeightDiffFactor = cv::Scalar(-0.1f);
+  m_oMorphExStructElement = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
+  m_aPxIdxLUT = new size_t[m_nTotRelevantPxCount];
+  memset(m_aPxIdxLUT, 0, sizeof(size_t)*m_nTotRelevantPxCount);
+  m_aPxInfoLUT_PAWCS = new PxInfo_PAWCS[m_nTotPxCount];
+  memset(m_aPxInfoLUT_PAWCS, 0, sizeof(PxInfo_PAWCS)*m_nTotPxCount);
+  m_aPxInfoLUT = m_aPxInfoLUT_PAWCS;
+  m_apLocalWordDict = new LocalWordBase*[m_nTotRelevantPxCount*m_nCurrLocalWords];
+  memset(m_apLocalWordDict, 0, sizeof(LocalWordBase*)*m_nTotRelevantPxCount*m_nCurrLocalWords);
+  m_apGlobalWordDict = new GlobalWordBase*[m_nCurrGlobalWords];
+  memset(m_apGlobalWordDict, 0, sizeof(GlobalWordBase*)*m_nCurrGlobalWords);
+  if (m_nImgChannels == 1) {
+    CV_DbgAssert(m_oLastColorFrame.step.p[0] == (size_t)m_oImgSize.width && m_oLastColorFrame.step.p[1] == 1);
+    CV_DbgAssert(m_oLastDescFrame.step.p[0] == m_oLastColorFrame.step.p[0] * 2 && m_oLastDescFrame.step.p[1] == m_oLastColorFrame.step.p[1] * 2);
+    m_aLocalWordList_1ch = new LocalWord_1ch[m_nTotRelevantPxCount*m_nCurrLocalWords];
+    memset(m_aLocalWordList_1ch, 0, sizeof(LocalWord_1ch)*m_nTotRelevantPxCount*m_nCurrLocalWords);
+    m_pLocalWordListIter_1ch = m_aLocalWordList_1ch;
+    m_aGlobalWordList_1ch = new GlobalWord_1ch[m_nCurrGlobalWords];
+    m_pGlobalWordListIter_1ch = m_aGlobalWordList_1ch;
+    for (size_t t = 0; t <= UCHAR_MAX; ++t)
+      m_anLBSPThreshold_8bitLUT[t] = cv::saturate_cast<uchar>((m_nLBSPThresholdOffset + t*m_fRelLBSPThreshold) / 3);
+    for (size_t nPxIter = 0, nModelIter = 0; nPxIter < m_nTotPxCount; ++nPxIter) {
+      if (m_oROI.data[nPxIter]) {
+        m_aPxIdxLUT[nModelIter] = nPxIter;
+        m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_Y = (int)nPxIter / m_oImgSize.width;
+        m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_X = (int)nPxIter%m_oImgSize.width;
+        m_aPxInfoLUT_PAWCS[nPxIter].nModelIdx = nModelIter;
+        m_aPxInfoLUT_PAWCS[nPxIter].nGlobalWordMapLookupIdx = (size_t)((m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_Y / GWORD_LOOKUP_MAPS_DOWNSAMPLE_RATIO)*m_oDownSampledFrameSize_GlobalWordLookup.width + (m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_X / GWORD_LOOKUP_MAPS_DOWNSAMPLE_RATIO)) * 4;
+        m_aPxInfoLUT_PAWCS[nPxIter].apGlobalDictSortLUT = new GlobalWordBase*[m_nCurrGlobalWords];
+        for (size_t nGlobalWordIdxIter = 0; nGlobalWordIdxIter < m_nCurrGlobalWords; ++nGlobalWordIdxIter)
+          m_aPxInfoLUT_PAWCS[nPxIter].apGlobalDictSortLUT[nGlobalWordIdxIter] = &(m_aGlobalWordList_1ch[nGlobalWordIdxIter]);
+        m_oLastColorFrame.data[nPxIter] = oInitImg.data[nPxIter];
+        const size_t nDescIter = nPxIter * 2;
+        LBSP_::computeGrayscaleDescriptor(oInitImg, oInitImg.data[nPxIter], m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_X, m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_Y, m_anLBSPThreshold_8bitLUT[oInitImg.data[nPxIter]], *((ushort*)(m_oLastDescFrame.data + nDescIter)));
+        ++nModelIter;
+      }
+    }
+  }
+  else { //m_nImgChannels==3
+    CV_DbgAssert(m_oLastColorFrame.step.p[0] == (size_t)m_oImgSize.width * 3 && m_oLastColorFrame.step.p[1] == 3);
+    CV_DbgAssert(m_oLastDescFrame.step.p[0] == m_oLastColorFrame.step.p[0] * 2 && m_oLastDescFrame.step.p[1] == m_oLastColorFrame.step.p[1] * 2);
+    m_aLocalWordList_3ch = new LocalWord_3ch[m_nTotRelevantPxCount*m_nCurrLocalWords];
+    memset(m_aLocalWordList_3ch, 0, sizeof(LocalWord_3ch)*m_nTotRelevantPxCount*m_nCurrLocalWords);
+    m_pLocalWordListIter_3ch = m_aLocalWordList_3ch;
+    m_aGlobalWordList_3ch = new GlobalWord_3ch[m_nCurrGlobalWords];
+    m_pGlobalWordListIter_3ch = m_aGlobalWordList_3ch;
+    for (size_t t = 0; t <= UCHAR_MAX; ++t)
+      m_anLBSPThreshold_8bitLUT[t] = cv::saturate_cast<uchar>(m_nLBSPThresholdOffset + t*m_fRelLBSPThreshold);
+    for (size_t nPxIter = 0, nModelIter = 0; nPxIter < m_nTotPxCount; ++nPxIter) {
+      if (m_oROI.data[nPxIter]) {
+        m_aPxIdxLUT[nModelIter] = nPxIter;
+        m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_Y = (int)nPxIter / m_oImgSize.width;
+        m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_X = (int)nPxIter%m_oImgSize.width;
+        m_aPxInfoLUT_PAWCS[nPxIter].nModelIdx = nModelIter;
+        m_aPxInfoLUT_PAWCS[nPxIter].nGlobalWordMapLookupIdx = (size_t)((m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_Y / GWORD_LOOKUP_MAPS_DOWNSAMPLE_RATIO)*m_oDownSampledFrameSize_GlobalWordLookup.width + (m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_X / GWORD_LOOKUP_MAPS_DOWNSAMPLE_RATIO)) * 4;
+        m_aPxInfoLUT_PAWCS[nPxIter].apGlobalDictSortLUT = new GlobalWordBase*[m_nCurrGlobalWords];
+        for (size_t nGlobalWordIdxIter = 0; nGlobalWordIdxIter < m_nCurrGlobalWords; ++nGlobalWordIdxIter)
+          m_aPxInfoLUT_PAWCS[nPxIter].apGlobalDictSortLUT[nGlobalWordIdxIter] = &(m_aGlobalWordList_3ch[nGlobalWordIdxIter]);
+        const size_t nPxRGBIter = nPxIter * 3;
+        const size_t nDescRGBIter = nPxRGBIter * 2;
+        for (size_t c = 0; c < 3; ++c) {
+          m_oLastColorFrame.data[nPxRGBIter + c] = oInitImg.data[nPxRGBIter + c];
+          LBSP_::computeSingleRGBDescriptor(oInitImg, oInitImg.data[nPxRGBIter + c], m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_X, m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_Y, c, m_anLBSPThreshold_8bitLUT[oInitImg.data[nPxRGBIter + c]], ((ushort*)(m_oLastDescFrame.data + nDescRGBIter))[c]);
+        }
+        ++nModelIter;
+      }
+    }
+  }
+  m_bInitialized = true;
+  refreshModel(1, 0);
+}
+
+void BackgroundSubtractorPAWCS::refreshModel(size_t nBaseOccCount, float fOccDecrFrac, bool bForceFGUpdate) {
+  // == refresh
+  CV_Assert(m_bInitialized);
+  CV_Assert(fOccDecrFrac >= 0.0f && fOccDecrFrac <= 1.0f);
+  if (m_nImgChannels == 1) {
+    for (size_t nModelIter = 0; nModelIter < m_nTotRelevantPxCount; ++nModelIter) {
+      const size_t nPxIter = m_aPxIdxLUT[nModelIter];
+      if (bForceFGUpdate || !m_oLastFGMask_dilated.data[nPxIter]) {
+        const size_t nLocalDictIdx = nModelIter*m_nCurrLocalWords;
+        const size_t nFloatIter = nPxIter * 4;
+        uchar& bCurrRegionIsUnstable = m_oUnstableRegionMask.data[nPxIter];
+        const float fCurrDistThresholdFactor = *(float*)(m_oDistThresholdFrame.data + nFloatIter);
+        const size_t nCurrColorDistThreshold = (size_t)(sqrt(fCurrDistThresholdFactor)*m_nMinColorDistThreshold) / 2;
+        const size_t nCurrDescDistThreshold = ((size_t)1 << ((size_t)floor(fCurrDistThresholdFactor + 0.5f))) + m_nDescDistThresholdOffset + (bCurrRegionIsUnstable*UNSTAB_DESC_DIST_OFFSET);
+        // == refresh: local decr
+        if (fOccDecrFrac > 0.0f) {
+          for (size_t nLocalWordIdx = 0; nLocalWordIdx < m_nCurrLocalWords; ++nLocalWordIdx) {
+            LocalWord_1ch* pCurrLocalWord = (LocalWord_1ch*)m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx];
+            if (pCurrLocalWord)
+              pCurrLocalWord->nOccurrences -= (size_t)(fOccDecrFrac*pCurrLocalWord->nOccurrences);
+          }
+        }
+        const size_t nCurrWordOccIncr = DEFAULT_LWORD_OCC_INCR;
+        const size_t nTotLocalSamplingIterCount = (s_nSamplesInitPatternWidth*s_nSamplesInitPatternHeight) * 2;
+        for (size_t nLocalSamplingIter = 0; nLocalSamplingIter < nTotLocalSamplingIterCount; ++nLocalSamplingIter) {
+          // == refresh: local resampling
+          int nSampleImgCoord_Y, nSampleImgCoord_X;
+          getRandSamplePosition(nSampleImgCoord_X, nSampleImgCoord_Y, m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_X, m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_Y, LBSP_::PATCH_SIZE / 2, m_oImgSize);
+          const size_t nSamplePxIdx = m_oImgSize.width*nSampleImgCoord_Y + nSampleImgCoord_X;
+          if (bForceFGUpdate || !m_oLastFGMask_dilated.data[nSamplePxIdx]) {
+            const uchar nSampleColor = m_oLastColorFrame.data[nSamplePxIdx];
+            const size_t nSampleDescIdx = nSamplePxIdx * 2;
+            const ushort nSampleIntraDesc = *((ushort*)(m_oLastDescFrame.data + nSampleDescIdx));
+            bool bFoundUninitd = false;
+            size_t nLocalWordIdx;
+            for (nLocalWordIdx = 0; nLocalWordIdx < m_nCurrLocalWords; ++nLocalWordIdx) {
+              LocalWord_1ch* pCurrLocalWord = (LocalWord_1ch*)m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx];
+              if (pCurrLocalWord
+                && L1dist(nSampleColor, pCurrLocalWord->oFeature.anColor[0]) <= nCurrColorDistThreshold
+                && hdist(nSampleIntraDesc, pCurrLocalWord->oFeature.anDesc[0]) <= nCurrDescDistThreshold) {
+                pCurrLocalWord->nOccurrences += nCurrWordOccIncr;
+                pCurrLocalWord->nLastOcc = m_nFrameIndex;
+                break;
+              }
+              else if (!pCurrLocalWord)
+                bFoundUninitd = true;
+            }
+            if (nLocalWordIdx == m_nCurrLocalWords) {
+              nLocalWordIdx = m_nCurrLocalWords - 1;
+              LocalWord_1ch* pCurrLocalWord = bFoundUninitd ? m_pLocalWordListIter_1ch++ : (LocalWord_1ch*)m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx];
+              pCurrLocalWord->oFeature.anColor[0] = nSampleColor;
+              pCurrLocalWord->oFeature.anDesc[0] = nSampleIntraDesc;
+              pCurrLocalWord->nOccurrences = nBaseOccCount;
+              pCurrLocalWord->nFirstOcc = m_nFrameIndex;
+              pCurrLocalWord->nLastOcc = m_nFrameIndex;
+              m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx] = pCurrLocalWord;
+            }
+            while (nLocalWordIdx > 0 && (!m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx - 1] || GetLocalWordWeight(m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx], m_nFrameIndex, m_nLocalWordWeightOffset) > GetLocalWordWeight(m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx - 1], m_nFrameIndex, m_nLocalWordWeightOffset))) {
+              std::swap(m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx], m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx - 1]);
+              --nLocalWordIdx;
+            }
+          }
+        }
+        CV_Assert(m_apLocalWordDict[nLocalDictIdx]);
+        for (size_t nLocalWordIdx = 1; nLocalWordIdx < m_nCurrLocalWords; ++nLocalWordIdx) {
+          // == refresh: local random resampling
+          LocalWord_1ch* pCurrLocalWord = (LocalWord_1ch*)m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx];
+          if (!pCurrLocalWord) {
+            const size_t nRandLocalWordIdx = (rand() % nLocalWordIdx);
+            const LocalWord_1ch* pRefLocalWord = (LocalWord_1ch*)m_apLocalWordDict[nLocalDictIdx + nRandLocalWordIdx];
+            const int nRandColorOffset = (rand() % (nCurrColorDistThreshold + 1)) - (int)nCurrColorDistThreshold / 2;
+            pCurrLocalWord = m_pLocalWordListIter_1ch++;
+            pCurrLocalWord->oFeature.anColor[0] = cv::saturate_cast<uchar>((int)pRefLocalWord->oFeature.anColor[0] + nRandColorOffset);
+            pCurrLocalWord->oFeature.anDesc[0] = pRefLocalWord->oFeature.anDesc[0];
+            pCurrLocalWord->nOccurrences = std::max((size_t)(pRefLocalWord->nOccurrences*((float)(m_nCurrLocalWords - nLocalWordIdx) / m_nCurrLocalWords)), (size_t)1);
+            pCurrLocalWord->nFirstOcc = m_nFrameIndex;
+            pCurrLocalWord->nLastOcc = m_nFrameIndex;
+            m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx] = pCurrLocalWord;
+          }
+        }
+      }
+    }
+    CV_Assert(m_aLocalWordList_1ch == (m_pLocalWordListIter_1ch - m_nTotRelevantPxCount*m_nCurrLocalWords));
+    cv::Mat oGlobalDictPresenceLookupMap(m_oImgSize, CV_8UC1, cv::Scalar_<uchar>(0));
+    size_t nPxIterIncr = std::max(m_nTotPxCount / m_nCurrGlobalWords, (size_t)1);
+    for (size_t nSamplingPasses = 0; nSamplingPasses < GWORD_DEFAULT_NB_INIT_SAMPL_PASSES; ++nSamplingPasses) {
+      for (size_t nModelIter = 0; nModelIter < m_nTotRelevantPxCount; ++nModelIter) {
+        // == refresh: global resampling
+        const size_t nPxIter = m_aPxIdxLUT[nModelIter];
+        if ((nPxIter%nPxIterIncr) == 0) { // <=(m_nCurrGlobalWords) gwords from (m_nCurrGlobalWords) equally spaced pixels
+          if (bForceFGUpdate || !m_oLastFGMask_dilated.data[nPxIter]) {
+            const size_t nLocalDictIdx = nModelIter*m_nCurrLocalWords;
+            const size_t nGlobalWordMapLookupIdx = m_aPxInfoLUT_PAWCS[nPxIter].nGlobalWordMapLookupIdx;
+            const size_t nFloatIter = nPxIter * 4;
+            uchar& bCurrRegionIsUnstable = m_oUnstableRegionMask.data[nPxIter];
+            const float fCurrDistThresholdFactor = *(float*)(m_oDistThresholdFrame.data + nFloatIter);
+            const size_t nCurrColorDistThreshold = (size_t)(sqrt(fCurrDistThresholdFactor)*m_nMinColorDistThreshold) / 2;
+            const size_t nCurrDescDistThreshold = ((size_t)1 << ((size_t)floor(fCurrDistThresholdFactor + 0.5f))) + m_nDescDistThresholdOffset + (bCurrRegionIsUnstable*UNSTAB_DESC_DIST_OFFSET);
+            CV_Assert(m_apLocalWordDict[nLocalDictIdx]);
+            const LocalWord_1ch* pRefBestLocalWord = (LocalWord_1ch*)m_apLocalWordDict[nLocalDictIdx];
+            const float fRefBestLocalWordWeight = GetLocalWordWeight(pRefBestLocalWord, m_nFrameIndex, m_nLocalWordWeightOffset);
+            const uchar nRefBestLocalWordDescBITS = (uchar)popcount(pRefBestLocalWord->oFeature.anDesc[0]);
+            bool bFoundUninitd = false;
+            size_t nGlobalWordIdx;
+            for (nGlobalWordIdx = 0; nGlobalWordIdx < m_nCurrGlobalWords; ++nGlobalWordIdx) {
+              GlobalWord_1ch* pCurrGlobalWord = (GlobalWord_1ch*)m_apGlobalWordDict[nGlobalWordIdx];
+              if (pCurrGlobalWord
+                && L1dist(pCurrGlobalWord->oFeature.anColor[0], pRefBestLocalWord->oFeature.anColor[0]) <= nCurrColorDistThreshold
+                && L1dist(nRefBestLocalWordDescBITS, pCurrGlobalWord->nDescBITS) <= nCurrDescDistThreshold / GWORD_DESC_THRES_BITS_MATCH_FACTOR)
+                break;
+              else if (!pCurrGlobalWord)
+                bFoundUninitd = true;
+            }
+            if (nGlobalWordIdx == m_nCurrGlobalWords) {
+              nGlobalWordIdx = m_nCurrGlobalWords - 1;
+              GlobalWord_1ch* pCurrGlobalWord = bFoundUninitd ? m_pGlobalWordListIter_1ch++ : (GlobalWord_1ch*)m_apGlobalWordDict[nGlobalWordIdx];
+              pCurrGlobalWord->oFeature.anColor[0] = pRefBestLocalWord->oFeature.anColor[0];
+              pCurrGlobalWord->oFeature.anDesc[0] = pRefBestLocalWord->oFeature.anDesc[0];
+              pCurrGlobalWord->nDescBITS = nRefBestLocalWordDescBITS;
+              pCurrGlobalWord->oSpatioOccMap.create(m_oDownSampledFrameSize_GlobalWordLookup, CV_32FC1);
+              pCurrGlobalWord->oSpatioOccMap = cv::Scalar(0.0f);
+              pCurrGlobalWord->fLatestWeight = 0.0f;
+              m_apGlobalWordDict[nGlobalWordIdx] = pCurrGlobalWord;
+            }
+            float& fCurrGlobalWordLocalWeight = *(float*)(m_apGlobalWordDict[nGlobalWordIdx]->oSpatioOccMap.data + nGlobalWordMapLookupIdx);
+            if (fCurrGlobalWordLocalWeight < fRefBestLocalWordWeight) {
+              m_apGlobalWordDict[nGlobalWordIdx]->fLatestWeight += fRefBestLocalWordWeight;
+              fCurrGlobalWordLocalWeight += fRefBestLocalWordWeight;
+            }
+            oGlobalDictPresenceLookupMap.data[nPxIter] = UCHAR_MAX;
+            while (nGlobalWordIdx > 0 && (!m_apGlobalWordDict[nGlobalWordIdx - 1] || m_apGlobalWordDict[nGlobalWordIdx]->fLatestWeight > m_apGlobalWordDict[nGlobalWordIdx - 1]->fLatestWeight)) {
+              std::swap(m_apGlobalWordDict[nGlobalWordIdx], m_apGlobalWordDict[nGlobalWordIdx - 1]);
+              --nGlobalWordIdx;
+            }
+          }
+        }
+      }
+      nPxIterIncr = std::max(nPxIterIncr / 3, (size_t)1);
+    }
+    for (size_t nGlobalWordIdx = 0; nGlobalWordIdx < m_nCurrGlobalWords; ++nGlobalWordIdx) {
+      GlobalWord_1ch* pCurrGlobalWord = (GlobalWord_1ch*)m_apGlobalWordDict[nGlobalWordIdx];
+      if (!pCurrGlobalWord) {
+        pCurrGlobalWord = m_pGlobalWordListIter_1ch++;
+        pCurrGlobalWord->oFeature.anColor[0] = 0;
+        pCurrGlobalWord->oFeature.anDesc[0] = 0;
+        pCurrGlobalWord->nDescBITS = 0;
+        pCurrGlobalWord->oSpatioOccMap.create(m_oDownSampledFrameSize_GlobalWordLookup, CV_32FC1);
+        pCurrGlobalWord->oSpatioOccMap = cv::Scalar(0.0f);
+        pCurrGlobalWord->fLatestWeight = 0.0f;
+        m_apGlobalWordDict[nGlobalWordIdx] = pCurrGlobalWord;
+      }
+    }
+    CV_Assert((size_t)(m_pGlobalWordListIter_1ch - m_aGlobalWordList_1ch) == m_nCurrGlobalWords && m_aGlobalWordList_1ch == (m_pGlobalWordListIter_1ch - m_nCurrGlobalWords));
+  }
+  else { //m_nImgChannels==3
+    for (size_t nModelIter = 0; nModelIter < m_nTotRelevantPxCount; ++nModelIter) {
+      const size_t nPxIter = m_aPxIdxLUT[nModelIter];
+      if (bForceFGUpdate || !m_oLastFGMask_dilated.data[nPxIter]) {
+        const size_t nLocalDictIdx = nModelIter*m_nCurrLocalWords;
+        const size_t nFloatIter = nPxIter * 4;
+        uchar& bCurrRegionIsUnstable = m_oUnstableRegionMask.data[nPxIter];
+        const float fCurrDistThresholdFactor = *(float*)(m_oDistThresholdFrame.data + nFloatIter);
+        const size_t nCurrTotColorDistThreshold = (size_t)(sqrt(fCurrDistThresholdFactor)*m_nMinColorDistThreshold) * 3;
+        const size_t nCurrTotDescDistThreshold = (((size_t)1 << ((size_t)floor(fCurrDistThresholdFactor + 0.5f))) + m_nDescDistThresholdOffset + (bCurrRegionIsUnstable*UNSTAB_DESC_DIST_OFFSET)) * 3;
+        // == refresh: local decr
+        if (fOccDecrFrac > 0.0f) {
+          for (size_t nLocalWordIdx = 0; nLocalWordIdx < m_nCurrLocalWords; ++nLocalWordIdx) {
+            LocalWord_3ch* pCurrLocalWord = (LocalWord_3ch*)m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx];
+            if (pCurrLocalWord)
+              pCurrLocalWord->nOccurrences -= (size_t)(fOccDecrFrac*pCurrLocalWord->nOccurrences);
+          }
+        }
+        const size_t nCurrWordOccIncr = DEFAULT_LWORD_OCC_INCR;
+        const size_t nTotLocalSamplingIterCount = (s_nSamplesInitPatternWidth*s_nSamplesInitPatternHeight) * 2;
+        for (size_t nLocalSamplingIter = 0; nLocalSamplingIter < nTotLocalSamplingIterCount; ++nLocalSamplingIter) {
+          // == refresh: local resampling
+          int nSampleImgCoord_Y, nSampleImgCoord_X;
+          getRandSamplePosition(nSampleImgCoord_X, nSampleImgCoord_Y, m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_X, m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_Y, LBSP_::PATCH_SIZE / 2, m_oImgSize);
+          const size_t nSamplePxIdx = m_oImgSize.width*nSampleImgCoord_Y + nSampleImgCoord_X;
+          if (bForceFGUpdate || !m_oLastFGMask_dilated.data[nSamplePxIdx]) {
+            const size_t nSamplePxRGBIdx = nSamplePxIdx * 3;
+            const size_t nSampleDescRGBIdx = nSamplePxRGBIdx * 2;
+            const uchar* const anSampleColor = m_oLastColorFrame.data + nSamplePxRGBIdx;
+            const ushort* const anSampleIntraDesc = ((ushort*)(m_oLastDescFrame.data + nSampleDescRGBIdx));
+            bool bFoundUninitd = false;
+            size_t nLocalWordIdx;
+            for (nLocalWordIdx = 0; nLocalWordIdx < m_nCurrLocalWords; ++nLocalWordIdx) {
+              LocalWord_3ch* pCurrLocalWord = (LocalWord_3ch*)m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx];
+              if (pCurrLocalWord
+                && cmixdist<3>(anSampleColor, pCurrLocalWord->oFeature.anColor) <= nCurrTotColorDistThreshold
+                && hdist<3>(anSampleIntraDesc, pCurrLocalWord->oFeature.anDesc) <= nCurrTotDescDistThreshold) {
+                pCurrLocalWord->nOccurrences += nCurrWordOccIncr;
+                pCurrLocalWord->nLastOcc = m_nFrameIndex;
+                break;
+              }
+              else if (!pCurrLocalWord)
+                bFoundUninitd = true;
+            }
+            if (nLocalWordIdx == m_nCurrLocalWords) {
+              nLocalWordIdx = m_nCurrLocalWords - 1;
+              LocalWord_3ch* pCurrLocalWord = bFoundUninitd ? m_pLocalWordListIter_3ch++ : (LocalWord_3ch*)m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx];
+              for (size_t c = 0; c < 3; ++c) {
+                pCurrLocalWord->oFeature.anColor[c] = anSampleColor[c];
+                pCurrLocalWord->oFeature.anDesc[c] = anSampleIntraDesc[c];
+              }
+              pCurrLocalWord->nOccurrences = nBaseOccCount;
+              pCurrLocalWord->nFirstOcc = m_nFrameIndex;
+              pCurrLocalWord->nLastOcc = m_nFrameIndex;
+              m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx] = pCurrLocalWord;
+            }
+            while (nLocalWordIdx > 0 && (!m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx - 1] || GetLocalWordWeight(m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx], m_nFrameIndex, m_nLocalWordWeightOffset) > GetLocalWordWeight(m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx - 1], m_nFrameIndex, m_nLocalWordWeightOffset))) {
+              std::swap(m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx], m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx - 1]);
+              --nLocalWordIdx;
+            }
+          }
+        }
+        CV_Assert(m_apLocalWordDict[nLocalDictIdx]);
+        for (size_t nLocalWordIdx = 1; nLocalWordIdx < m_nCurrLocalWords; ++nLocalWordIdx) {
+          // == refresh: local random resampling
+          LocalWord_3ch* pCurrLocalWord = (LocalWord_3ch*)m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx];
+          if (!pCurrLocalWord) {
+            const size_t nRandLocalWordIdx = (rand() % nLocalWordIdx);
+            const LocalWord_3ch* pRefLocalWord = (LocalWord_3ch*)m_apLocalWordDict[nLocalDictIdx + nRandLocalWordIdx];
+            const int nRandColorOffset = (rand() % (nCurrTotColorDistThreshold / 3 + 1)) - (int)(nCurrTotColorDistThreshold / 6);
+            pCurrLocalWord = m_pLocalWordListIter_3ch++;
+            for (size_t c = 0; c < 3; ++c) {
+              pCurrLocalWord->oFeature.anColor[c] = cv::saturate_cast<uchar>((int)pRefLocalWord->oFeature.anColor[c] + nRandColorOffset);
+              pCurrLocalWord->oFeature.anDesc[c] = pRefLocalWord->oFeature.anDesc[c];
+            }
+            pCurrLocalWord->nOccurrences = std::max((size_t)(pRefLocalWord->nOccurrences*((float)(m_nCurrLocalWords - nLocalWordIdx) / m_nCurrLocalWords)), (size_t)1);
+            pCurrLocalWord->nFirstOcc = m_nFrameIndex;
+            pCurrLocalWord->nLastOcc = m_nFrameIndex;
+            m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx] = pCurrLocalWord;
+          }
+        }
+      }
+    }
+    CV_Assert(m_aLocalWordList_3ch == (m_pLocalWordListIter_3ch - m_nTotRelevantPxCount*m_nCurrLocalWords));
+    cv::Mat oGlobalDictPresenceLookupMap(m_oImgSize, CV_8UC1, cv::Scalar_<uchar>(0));
+    size_t nPxIterIncr = std::max(m_nTotPxCount / m_nCurrGlobalWords, (size_t)1);
+    for (size_t nSamplingPasses = 0; nSamplingPasses < GWORD_DEFAULT_NB_INIT_SAMPL_PASSES; ++nSamplingPasses) {
+      for (size_t nModelIter = 0; nModelIter < m_nTotRelevantPxCount; ++nModelIter) {
+        // == refresh: global resampling
+        const size_t nPxIter = m_aPxIdxLUT[nModelIter];
+        if ((nPxIter%nPxIterIncr) == 0) { // <=(m_nCurrGlobalWords) gwords from (m_nCurrGlobalWords) equally spaced pixels
+          if (bForceFGUpdate || !m_oLastFGMask_dilated.data[nPxIter]) {
+            const size_t nLocalDictIdx = nModelIter*m_nCurrLocalWords;
+            const size_t nGlobalWordMapLookupIdx = m_aPxInfoLUT_PAWCS[nPxIter].nGlobalWordMapLookupIdx;
+            const size_t nFloatIter = nPxIter * 4;
+            uchar& bCurrRegionIsUnstable = m_oUnstableRegionMask.data[nPxIter];
+            const float fCurrDistThresholdFactor = *(float*)(m_oDistThresholdFrame.data + nFloatIter);
+            const size_t nCurrTotColorDistThreshold = (size_t)(sqrt(fCurrDistThresholdFactor)*m_nMinColorDistThreshold) * 3;
+            const size_t nCurrTotDescDistThreshold = (((size_t)1 << ((size_t)floor(fCurrDistThresholdFactor + 0.5f))) + m_nDescDistThresholdOffset + (bCurrRegionIsUnstable*UNSTAB_DESC_DIST_OFFSET)) * 3;
+            CV_Assert(m_apLocalWordDict[nLocalDictIdx]);
+            const LocalWord_3ch* pRefBestLocalWord = (LocalWord_3ch*)m_apLocalWordDict[nLocalDictIdx];
+            const float fRefBestLocalWordWeight = GetLocalWordWeight(pRefBestLocalWord, m_nFrameIndex, m_nLocalWordWeightOffset);
+            const uchar nRefBestLocalWordDescBITS = (uchar)popcount<3>(pRefBestLocalWord->oFeature.anDesc);
+            bool bFoundUninitd = false;
+            size_t nGlobalWordIdx;
+            for (nGlobalWordIdx = 0; nGlobalWordIdx < m_nCurrGlobalWords; ++nGlobalWordIdx) {
+              GlobalWord_3ch* pCurrGlobalWord = (GlobalWord_3ch*)m_apGlobalWordDict[nGlobalWordIdx];
+              if (pCurrGlobalWord
+                && L1dist(nRefBestLocalWordDescBITS, pCurrGlobalWord->nDescBITS) <= nCurrTotDescDistThreshold / GWORD_DESC_THRES_BITS_MATCH_FACTOR
+                && cmixdist<3>(pRefBestLocalWord->oFeature.anColor, pCurrGlobalWord->oFeature.anColor) <= nCurrTotColorDistThreshold)
+                break;
+              else if (!pCurrGlobalWord)
+                bFoundUninitd = true;
+            }
+            if (nGlobalWordIdx == m_nCurrGlobalWords) {
+              nGlobalWordIdx = m_nCurrGlobalWords - 1;
+              GlobalWord_3ch* pCurrGlobalWord = bFoundUninitd ? m_pGlobalWordListIter_3ch++ : (GlobalWord_3ch*)m_apGlobalWordDict[nGlobalWordIdx];
+              for (size_t c = 0; c < 3; ++c) {
+                pCurrGlobalWord->oFeature.anColor[c] = pRefBestLocalWord->oFeature.anColor[c];
+                pCurrGlobalWord->oFeature.anDesc[c] = pRefBestLocalWord->oFeature.anDesc[c];
+              }
+              pCurrGlobalWord->nDescBITS = nRefBestLocalWordDescBITS;
+              pCurrGlobalWord->oSpatioOccMap.create(m_oDownSampledFrameSize_GlobalWordLookup, CV_32FC1);
+              pCurrGlobalWord->oSpatioOccMap = cv::Scalar(0.0f);
+              pCurrGlobalWord->fLatestWeight = 0.0f;
+              m_apGlobalWordDict[nGlobalWordIdx] = pCurrGlobalWord;
+            }
+            float& fCurrGlobalWordLocalWeight = *(float*)(m_apGlobalWordDict[nGlobalWordIdx]->oSpatioOccMap.data + nGlobalWordMapLookupIdx);
+            if (fCurrGlobalWordLocalWeight < fRefBestLocalWordWeight) {
+              m_apGlobalWordDict[nGlobalWordIdx]->fLatestWeight += fRefBestLocalWordWeight;
+              fCurrGlobalWordLocalWeight += fRefBestLocalWordWeight;
+            }
+            oGlobalDictPresenceLookupMap.data[nPxIter] = UCHAR_MAX;
+            while (nGlobalWordIdx > 0 && (!m_apGlobalWordDict[nGlobalWordIdx - 1] || m_apGlobalWordDict[nGlobalWordIdx]->fLatestWeight > m_apGlobalWordDict[nGlobalWordIdx - 1]->fLatestWeight)) {
+              std::swap(m_apGlobalWordDict[nGlobalWordIdx], m_apGlobalWordDict[nGlobalWordIdx - 1]);
+              --nGlobalWordIdx;
+            }
+          }
+        }
+      }
+      nPxIterIncr = std::max(nPxIterIncr / 3, (size_t)1);
+    }
+    for (size_t nGlobalWordIdx = 0; nGlobalWordIdx < m_nCurrGlobalWords; ++nGlobalWordIdx) {
+      GlobalWord_3ch* pCurrGlobalWord = (GlobalWord_3ch*)m_apGlobalWordDict[nGlobalWordIdx];
+      if (!pCurrGlobalWord) {
+        pCurrGlobalWord = m_pGlobalWordListIter_3ch++;
+        for (size_t c = 0; c < 3; ++c) {
+          pCurrGlobalWord->oFeature.anColor[c] = 0;
+          pCurrGlobalWord->oFeature.anDesc[c] = 0;
+        }
+        pCurrGlobalWord->nDescBITS = 0;
+        pCurrGlobalWord->oSpatioOccMap.create(m_oDownSampledFrameSize_GlobalWordLookup, CV_32FC1);
+        pCurrGlobalWord->oSpatioOccMap = cv::Scalar(0.0f);
+        pCurrGlobalWord->fLatestWeight = 0.0f;
+        m_apGlobalWordDict[nGlobalWordIdx] = pCurrGlobalWord;
+      }
+    }
+    CV_Assert((size_t)(m_pGlobalWordListIter_3ch - m_aGlobalWordList_3ch) == m_nCurrGlobalWords && m_aGlobalWordList_3ch == (m_pGlobalWordListIter_3ch - m_nCurrGlobalWords));
+  }
+  for (size_t nModelIter = 0; nModelIter < m_nTotRelevantPxCount; ++nModelIter) {
+    // == refresh: per-px global word sort
+    const size_t nPxIter = m_aPxIdxLUT[nModelIter];
+    const size_t nGlobalWordMapLookupIdx = m_aPxInfoLUT_PAWCS[nPxIter].nGlobalWordMapLookupIdx;
+    float fLastGlobalWordLocalWeight = *(float*)(m_aPxInfoLUT_PAWCS[nPxIter].apGlobalDictSortLUT[0]->oSpatioOccMap.data + nGlobalWordMapLookupIdx);
+    for (size_t nGlobalWordLUTIdx = 1; nGlobalWordLUTIdx < m_nCurrGlobalWords; ++nGlobalWordLUTIdx) {
+      const float fCurrGlobalWordLocalWeight = *(float*)(m_aPxInfoLUT_PAWCS[nPxIter].apGlobalDictSortLUT[nGlobalWordLUTIdx]->oSpatioOccMap.data + nGlobalWordMapLookupIdx);
+      if (fCurrGlobalWordLocalWeight > fLastGlobalWordLocalWeight)
+        std::swap(m_aPxInfoLUT_PAWCS[nPxIter].apGlobalDictSortLUT[nGlobalWordLUTIdx], m_aPxInfoLUT_PAWCS[nPxIter].apGlobalDictSortLUT[nGlobalWordLUTIdx - 1]);
+      else
+        fLastGlobalWordLocalWeight = fCurrGlobalWordLocalWeight;
+    }
+  }
+}
+
+void BackgroundSubtractorPAWCS::apply(cv::InputArray _image, cv::OutputArray _fgmask, double learningRateOverride) {
+  // == process
+  CV_Assert(m_bInitialized);
+  cv::Mat oInputImg = _image.getMat();
+  CV_Assert(oInputImg.type() == m_nImgType && oInputImg.size() == m_oImgSize);
+  CV_Assert(oInputImg.isContinuous());
+  _fgmask.create(m_oImgSize, CV_8UC1);
+  cv::Mat oCurrFGMask = _fgmask.getMat();
+  memset(oCurrFGMask.data, 0, oCurrFGMask.cols*oCurrFGMask.rows);
+  const bool bBootstrapping = ++m_nFrameIndex <= DEFAULT_BOOTSTRAP_WIN_SIZE;
+  const size_t nCurrSamplesForMovingAvg_LT = bBootstrapping ? m_nSamplesForMovingAvgs / 2 : m_nSamplesForMovingAvgs;
+  const size_t nCurrSamplesForMovingAvg_ST = nCurrSamplesForMovingAvg_LT / 4;
+  const float fRollAvgFactor_LT = 1.0f / std::min(m_nFrameIndex, nCurrSamplesForMovingAvg_LT);
+  const float fRollAvgFactor_ST = 1.0f / std::min(m_nFrameIndex, nCurrSamplesForMovingAvg_ST);
+  const size_t nCurrGlobalWordUpdateRate = bBootstrapping ? DEFAULT_RESAMPLING_RATE / 2 : DEFAULT_RESAMPLING_RATE;
+  size_t nFlatRegionCount = 0;
+  if (m_nImgChannels == 1) {
+    for (size_t nModelIter = 0; nModelIter < m_nTotRelevantPxCount; ++nModelIter) {
+      const size_t nPxIter = m_aPxIdxLUT[nModelIter];
+      const size_t nDescIter = nPxIter * 2;
+      const size_t nFloatIter = nPxIter * 4;
+      const size_t nLocalDictIdx = nModelIter*m_nCurrLocalWords;
+      const size_t nGlobalWordMapLookupIdx = m_aPxInfoLUT_PAWCS[nPxIter].nGlobalWordMapLookupIdx;
+      const uchar nCurrColor = oInputImg.data[nPxIter];
+      uchar& nLastColor = m_oLastColorFrame.data[nPxIter];
+      ushort& nLastIntraDesc = *((ushort*)(m_oLastDescFrame.data + nDescIter));
+      size_t nMinColorDist = s_nColorMaxDataRange_1ch;
+      size_t nMinDescDist = s_nDescMaxDataRange_1ch;
+      float& fCurrMeanRawSegmRes_LT = *(float*)(m_oMeanRawSegmResFrame_LT.data + nFloatIter);
+      float& fCurrMeanRawSegmRes_ST = *(float*)(m_oMeanRawSegmResFrame_ST.data + nFloatIter);
+      float& fCurrMeanFinalSegmRes_LT = *(float*)(m_oMeanFinalSegmResFrame_LT.data + nFloatIter);
+      float& fCurrMeanFinalSegmRes_ST = *(float*)(m_oMeanFinalSegmResFrame_ST.data + nFloatIter);
+      float& fCurrDistThresholdFactor = *(float*)(m_oDistThresholdFrame.data + nFloatIter);
+      float& fCurrDistThresholdVariationFactor = *(float*)(m_oDistThresholdVariationFrame.data + nFloatIter);
+      float& fCurrLearningRate = *(float*)(m_oUpdateRateFrame.data + nFloatIter);
+      float& fCurrMeanMinDist_LT = *(float*)(m_oMeanMinDistFrame_LT.data + nFloatIter);
+      float& fCurrMeanMinDist_ST = *(float*)(m_oMeanMinDistFrame_ST.data + nFloatIter);
+      const float fBestLocalWordWeight = GetLocalWordWeight(m_apLocalWordDict[nLocalDictIdx], m_nFrameIndex, m_nLocalWordWeightOffset);
+      const float fLocalWordsWeightSumThreshold = fBestLocalWordWeight / (fCurrDistThresholdFactor * 2);
+      uchar& bCurrRegionIsUnstable = m_oUnstableRegionMask.data[nPxIter];
+      uchar& nCurrRegionIllumUpdtVal = m_oIllumUpdtRegionMask.data[nPxIter];
+      uchar& nCurrRegionSegmVal = oCurrFGMask.data[nPxIter];
+      const bool bCurrRegionIsROIBorder = m_oROI.data[nPxIter] < UCHAR_MAX;
+      const int nCurrImgCoord_X = m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_X;
+      const int nCurrImgCoord_Y = m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_Y;
+      ushort nCurrInterDesc, nCurrIntraDesc;
+      LBSP_::computeGrayscaleDescriptor(oInputImg, nCurrColor, nCurrImgCoord_X, nCurrImgCoord_Y, m_anLBSPThreshold_8bitLUT[nCurrColor], nCurrIntraDesc);
+      const uchar nCurrIntraDescBITS = (uchar)popcount(nCurrIntraDesc);
+      const bool bCurrRegionIsFlat = nCurrIntraDescBITS < FLAT_REGION_BIT_COUNT;
+      if (bCurrRegionIsFlat)
+        ++nFlatRegionCount;
+      const size_t nCurrWordOccIncr = (DEFAULT_LWORD_OCC_INCR + m_nModelResetCooldown) << int(bCurrRegionIsFlat || bBootstrapping);
+      const size_t nCurrLocalWordUpdateRate = learningRateOverride > 0 ? (size_t)ceil(learningRateOverride) : bCurrRegionIsFlat ? (size_t)ceil(fCurrLearningRate + FEEDBACK_T_LOWER) / 2 : (size_t)ceil(fCurrLearningRate);
+      const size_t nCurrColorDistThreshold = (size_t)(sqrt(fCurrDistThresholdFactor)*m_nMinColorDistThreshold) / 2;
+      const size_t nCurrDescDistThreshold = ((size_t)1 << ((size_t)floor(fCurrDistThresholdFactor + 0.5f))) + m_nDescDistThresholdOffset + (bCurrRegionIsUnstable*UNSTAB_DESC_DIST_OFFSET);
+      size_t nLocalWordIdx = 0;
+      float fPotentialLocalWordsWeightSum = 0.0f;
+      float fLastLocalWordWeight = FLT_MAX;
+      while (nLocalWordIdx < m_nCurrLocalWords && fPotentialLocalWordsWeightSum < fLocalWordsWeightSumThreshold) {
+        LocalWord_1ch* pCurrLocalWord = (LocalWord_1ch*)m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx];
+        const float fCurrLocalWordWeight = GetLocalWordWeight(pCurrLocalWord, m_nFrameIndex, m_nLocalWordWeightOffset);
+        {
+          const size_t nColorDist = L1dist(nCurrColor, pCurrLocalWord->oFeature.anColor[0]);
+          const size_t nIntraDescDist = hdist(nCurrIntraDesc, pCurrLocalWord->oFeature.anDesc[0]);
+          LBSP_::computeGrayscaleDescriptor(oInputImg, pCurrLocalWord->oFeature.anColor[0], nCurrImgCoord_X, nCurrImgCoord_Y, m_anLBSPThreshold_8bitLUT[pCurrLocalWord->oFeature.anColor[0]], nCurrInterDesc);
+          const size_t nInterDescDist = hdist(nCurrInterDesc, pCurrLocalWord->oFeature.anDesc[0]);
+          const size_t nDescDist = (nIntraDescDist + nInterDescDist) / 2;
+          if ((!bCurrRegionIsUnstable || bCurrRegionIsFlat || bCurrRegionIsROIBorder)
+            && nColorDist <= nCurrColorDistThreshold
+            && nColorDist >= nCurrColorDistThreshold / 2
+            && nIntraDescDist <= nCurrDescDistThreshold / 2
+            && (rand() % (nCurrRegionIllumUpdtVal ? (nCurrLocalWordUpdateRate / 2 + 1) : nCurrLocalWordUpdateRate)) == 0) {
+            // == illum updt
+            pCurrLocalWord->oFeature.anColor[0] = nCurrColor;
+            pCurrLocalWord->oFeature.anDesc[0] = nCurrIntraDesc;
+            m_oIllumUpdtRegionMask.data[nPxIter - 1] = 1 & m_oROI.data[nPxIter - 1];
+            m_oIllumUpdtRegionMask.data[nPxIter + 1] = 1 & m_oROI.data[nPxIter + 1];
+            m_oIllumUpdtRegionMask.data[nPxIter] = 2;
+          }
+          if (nDescDist <= nCurrDescDistThreshold && nColorDist <= nCurrColorDistThreshold) {
+            fPotentialLocalWordsWeightSum += fCurrLocalWordWeight;
+            pCurrLocalWord->nLastOcc = m_nFrameIndex;
+            if ((!m_oLastFGMask.data[nPxIter] || m_bUsingMovingCamera) && fCurrLocalWordWeight < DEFAULT_LWORD_MAX_WEIGHT)
+              pCurrLocalWord->nOccurrences += nCurrWordOccIncr;
+            nMinColorDist = std::min(nMinColorDist, nColorDist);
+            nMinDescDist = std::min(nMinDescDist, nDescDist);
+          }
+        }
+        if (fCurrLocalWordWeight > fLastLocalWordWeight) {
+          std::swap(m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx], m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx - 1]);
+        }
+        else
+          fLastLocalWordWeight = fCurrLocalWordWeight;
+        ++nLocalWordIdx;
+      }
+      while (nLocalWordIdx < m_nCurrLocalWords) {
+        const float fCurrLocalWordWeight = GetLocalWordWeight(m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx], m_nFrameIndex, m_nLocalWordWeightOffset);
+        if (fCurrLocalWordWeight > fLastLocalWordWeight) {
+          std::swap(m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx], m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx - 1]);
+        }
+        else
+          fLastLocalWordWeight = fCurrLocalWordWeight;
+        ++nLocalWordIdx;
+      }
+      if (fPotentialLocalWordsWeightSum >= fLocalWordsWeightSumThreshold || bCurrRegionIsROIBorder) {
+        // == background
+        const float fNormalizedMinDist = std::max((float)nMinColorDist / s_nColorMaxDataRange_1ch, (float)nMinDescDist / s_nDescMaxDataRange_1ch);
+        fCurrMeanMinDist_LT = fCurrMeanMinDist_LT*(1.0f - fRollAvgFactor_LT) + fNormalizedMinDist*fRollAvgFactor_LT;
+        fCurrMeanMinDist_ST = fCurrMeanMinDist_ST*(1.0f - fRollAvgFactor_ST) + fNormalizedMinDist*fRollAvgFactor_ST;
+        fCurrMeanRawSegmRes_LT = fCurrMeanRawSegmRes_LT*(1.0f - fRollAvgFactor_LT);
+        fCurrMeanRawSegmRes_ST = fCurrMeanRawSegmRes_ST*(1.0f - fRollAvgFactor_ST);
+        if ((rand() % nCurrLocalWordUpdateRate) == 0) {
+          size_t nGlobalWordLUTIdx;
+          GlobalWord_1ch* pCurrGlobalWord = nullptr;
+          for (nGlobalWordLUTIdx = 0; nGlobalWordLUTIdx < m_nCurrGlobalWords; ++nGlobalWordLUTIdx) {
+            pCurrGlobalWord = (GlobalWord_1ch*)m_aPxInfoLUT_PAWCS[nPxIter].apGlobalDictSortLUT[nGlobalWordLUTIdx];
+            if (L1dist(pCurrGlobalWord->oFeature.anColor[0], nCurrColor) <= nCurrColorDistThreshold
+              && L1dist(nCurrIntraDescBITS, pCurrGlobalWord->nDescBITS) <= nCurrDescDistThreshold / GWORD_DESC_THRES_BITS_MATCH_FACTOR)
+              break;
+          }
+          if (nGlobalWordLUTIdx != m_nCurrGlobalWords || (rand() % (nCurrLocalWordUpdateRate * 2)) == 0) {
+            if (nGlobalWordLUTIdx == m_nCurrGlobalWords) {
+              pCurrGlobalWord = (GlobalWord_1ch*)m_apGlobalWordDict[m_nCurrGlobalWords - 1];
+              pCurrGlobalWord->oFeature.anColor[0] = nCurrColor;
+              pCurrGlobalWord->oFeature.anDesc[0] = nCurrIntraDesc;
+              pCurrGlobalWord->nDescBITS = nCurrIntraDescBITS;
+              pCurrGlobalWord->oSpatioOccMap = cv::Scalar(0.0f);
+              pCurrGlobalWord->fLatestWeight = 0.0f;
+            }
+            float& fCurrGlobalWordLocalWeight = *(float*)(pCurrGlobalWord->oSpatioOccMap.data + nGlobalWordMapLookupIdx);
+            if (fCurrGlobalWordLocalWeight < fPotentialLocalWordsWeightSum) {
+              pCurrGlobalWord->fLatestWeight += fPotentialLocalWordsWeightSum;
+              fCurrGlobalWordLocalWeight += fPotentialLocalWordsWeightSum;
+            }
+          }
+        }
+      }
+      else {
+        // == foreground
+        const float fNormalizedMinDist = std::max(std::max((float)nMinColorDist / s_nColorMaxDataRange_1ch, (float)nMinDescDist / s_nDescMaxDataRange_1ch), (fLocalWordsWeightSumThreshold - fPotentialLocalWordsWeightSum) / fLocalWordsWeightSumThreshold);
+        fCurrMeanMinDist_LT = fCurrMeanMinDist_LT*(1.0f - fRollAvgFactor_LT) + fNormalizedMinDist*fRollAvgFactor_LT;
+        fCurrMeanMinDist_ST = fCurrMeanMinDist_ST*(1.0f - fRollAvgFactor_ST) + fNormalizedMinDist*fRollAvgFactor_ST;
+        fCurrMeanRawSegmRes_LT = fCurrMeanRawSegmRes_LT*(1.0f - fRollAvgFactor_LT) + fRollAvgFactor_LT;
+        fCurrMeanRawSegmRes_ST = fCurrMeanRawSegmRes_ST*(1.0f - fRollAvgFactor_ST) + fRollAvgFactor_ST;
+        if (bCurrRegionIsFlat || (rand() % nCurrLocalWordUpdateRate) == 0) {
+          size_t nGlobalWordLUTIdx;
+          GlobalWord_1ch* pCurrGlobalWord;
+          for (nGlobalWordLUTIdx = 0; nGlobalWordLUTIdx < m_nCurrGlobalWords; ++nGlobalWordLUTIdx) {
+            pCurrGlobalWord = (GlobalWord_1ch*)m_aPxInfoLUT_PAWCS[nPxIter].apGlobalDictSortLUT[nGlobalWordLUTIdx];
+            if (L1dist(pCurrGlobalWord->oFeature.anColor[0], nCurrColor) <= nCurrColorDistThreshold
+              && L1dist(nCurrIntraDescBITS, pCurrGlobalWord->nDescBITS) <= nCurrDescDistThreshold / GWORD_DESC_THRES_BITS_MATCH_FACTOR)
+              break;
+          }
+          if (nGlobalWordLUTIdx == m_nCurrGlobalWords)
+            nCurrRegionSegmVal = UCHAR_MAX;
+          else {
+            const float fGlobalWordLocalizedWeight = *(float*)(pCurrGlobalWord->oSpatioOccMap.data + nGlobalWordMapLookupIdx);
+            if (fPotentialLocalWordsWeightSum + fGlobalWordLocalizedWeight / (bCurrRegionIsFlat ? 2 : 4) < fLocalWordsWeightSumThreshold)
+              nCurrRegionSegmVal = UCHAR_MAX;
+          }
+        }
+        else
+          nCurrRegionSegmVal = UCHAR_MAX;
+        if (fPotentialLocalWordsWeightSum < DEFAULT_LWORD_INIT_WEIGHT) {
+          const size_t nNewLocalWordIdx = m_nCurrLocalWords - 1;
+          LocalWord_1ch* pNewLocalWord = (LocalWord_1ch*)m_apLocalWordDict[nLocalDictIdx + nNewLocalWordIdx];
+          pNewLocalWord->oFeature.anColor[0] = nCurrColor;
+          pNewLocalWord->oFeature.anDesc[0] = nCurrIntraDesc;
+          pNewLocalWord->nOccurrences = nCurrWordOccIncr;
+          pNewLocalWord->nFirstOcc = m_nFrameIndex;
+          pNewLocalWord->nLastOcc = m_nFrameIndex;
+        }
+      }
+      // == neighb updt
+      if ((!nCurrRegionSegmVal && (rand() % nCurrLocalWordUpdateRate) == 0) || bCurrRegionIsROIBorder || m_bUsingMovingCamera) {
+        //if((!nCurrRegionSegmVal && (rand()%(nCurrRegionIllumUpdtVal?(nCurrLocalWordUpdateRate/2+1):nCurrLocalWordUpdateRate))==0) || bCurrRegionIsROIBorder) {
+        int nSampleImgCoord_Y, nSampleImgCoord_X;
+        if (bCurrRegionIsFlat || bCurrRegionIsROIBorder || m_bUsingMovingCamera)
+          getRandNeighborPosition_5x5(nSampleImgCoord_X, nSampleImgCoord_Y, nCurrImgCoord_X, nCurrImgCoord_Y, LBSP_::PATCH_SIZE / 2, m_oImgSize);
+        else
+          getRandNeighborPosition_3x3(nSampleImgCoord_X, nSampleImgCoord_Y, nCurrImgCoord_X, nCurrImgCoord_Y, LBSP_::PATCH_SIZE / 2, m_oImgSize);
+        const size_t nSamplePxIdx = m_oImgSize.width*nSampleImgCoord_Y + nSampleImgCoord_X;
+        if (m_oROI.data[nSamplePxIdx]) {
+          const size_t nNeighborLocalDictIdx = m_aPxInfoLUT_PAWCS[nSamplePxIdx].nModelIdx*m_nCurrLocalWords;
+          size_t nNeighborLocalWordIdx = 0;
+          float fNeighborPotentialLocalWordsWeightSum = 0.0f;
+          while (nNeighborLocalWordIdx < m_nCurrLocalWords && fNeighborPotentialLocalWordsWeightSum < fLocalWordsWeightSumThreshold) {
+            LocalWord_1ch* pNeighborLocalWord = (LocalWord_1ch*)m_apLocalWordDict[nNeighborLocalDictIdx + nNeighborLocalWordIdx];
+            const size_t nNeighborColorDist = L1dist(nCurrColor, pNeighborLocalWord->oFeature.anColor[0]);
+            const size_t nNeighborIntraDescDist = hdist(nCurrIntraDesc, pNeighborLocalWord->oFeature.anDesc[0]);
+            const bool bNeighborRegionIsFlat = popcount(pNeighborLocalWord->oFeature.anDesc[0]) < FLAT_REGION_BIT_COUNT;
+            const size_t nNeighborWordOccIncr = bNeighborRegionIsFlat ? nCurrWordOccIncr * 2 : nCurrWordOccIncr;
+            if (nNeighborColorDist <= nCurrColorDistThreshold && nNeighborIntraDescDist <= nCurrDescDistThreshold) {
+              const float fNeighborLocalWordWeight = GetLocalWordWeight(pNeighborLocalWord, m_nFrameIndex, m_nLocalWordWeightOffset);
+              fNeighborPotentialLocalWordsWeightSum += fNeighborLocalWordWeight;
+              pNeighborLocalWord->nLastOcc = m_nFrameIndex;
+              if (fNeighborLocalWordWeight < DEFAULT_LWORD_MAX_WEIGHT)
+                pNeighborLocalWord->nOccurrences += nNeighborWordOccIncr;
+            }
+            else if (!oCurrFGMask.data[nSamplePxIdx] && bCurrRegionIsFlat && (bBootstrapping || (rand() % nCurrLocalWordUpdateRate) == 0)) {
+              const size_t nSampleDescIdx = nSamplePxIdx * 2;
+              ushort& nNeighborLastIntraDesc = *((ushort*)(m_oLastDescFrame.data + nSampleDescIdx));
+              const size_t nNeighborLastIntraDescDist = hdist(nCurrIntraDesc, nNeighborLastIntraDesc);
+              if (nNeighborColorDist <= nCurrColorDistThreshold && nNeighborLastIntraDescDist <= nCurrDescDistThreshold / 2) {
+                const float fNeighborLocalWordWeight = GetLocalWordWeight(pNeighborLocalWord, m_nFrameIndex, m_nLocalWordWeightOffset);
+                fNeighborPotentialLocalWordsWeightSum += fNeighborLocalWordWeight;
+                pNeighborLocalWord->nLastOcc = m_nFrameIndex;
+                if (fNeighborLocalWordWeight < DEFAULT_LWORD_MAX_WEIGHT)
+                  pNeighborLocalWord->nOccurrences += nNeighborWordOccIncr;
+                pNeighborLocalWord->oFeature.anDesc[0] = nCurrIntraDesc;
+              }
+            }
+            ++nNeighborLocalWordIdx;
+          }
+          if (fNeighborPotentialLocalWordsWeightSum < DEFAULT_LWORD_INIT_WEIGHT) {
+            nNeighborLocalWordIdx = m_nCurrLocalWords - 1;
+            LocalWord_1ch* pNeighborLocalWord = (LocalWord_1ch*)m_apLocalWordDict[nNeighborLocalDictIdx + nNeighborLocalWordIdx];
+            pNeighborLocalWord->oFeature.anColor[0] = nCurrColor;
+            pNeighborLocalWord->oFeature.anDesc[0] = nCurrIntraDesc;
+            pNeighborLocalWord->nOccurrences = nCurrWordOccIncr;
+            pNeighborLocalWord->nFirstOcc = m_nFrameIndex;
+            pNeighborLocalWord->nLastOcc = m_nFrameIndex;
+          }
+        }
+      }
+      if (nCurrRegionIllumUpdtVal)
+        nCurrRegionIllumUpdtVal -= 1;
+      // == feedback adj
+      bCurrRegionIsUnstable = fCurrDistThresholdFactor > UNSTABLE_REG_RDIST_MIN || (fCurrMeanRawSegmRes_LT - fCurrMeanFinalSegmRes_LT) > UNSTABLE_REG_RATIO_MIN || (fCurrMeanRawSegmRes_ST - fCurrMeanFinalSegmRes_ST) > UNSTABLE_REG_RATIO_MIN;
+      if (m_oLastFGMask.data[nPxIter] || (std::min(fCurrMeanMinDist_LT, fCurrMeanMinDist_ST) < UNSTABLE_REG_RATIO_MIN && nCurrRegionSegmVal))
+        fCurrLearningRate = std::min(fCurrLearningRate + FEEDBACK_T_INCR / (std::max(fCurrMeanMinDist_LT, fCurrMeanMinDist_ST)*fCurrDistThresholdVariationFactor), FEEDBACK_T_UPPER);
+      else
+        fCurrLearningRate = std::max(fCurrLearningRate - FEEDBACK_T_DECR*fCurrDistThresholdVariationFactor / std::max(fCurrMeanMinDist_LT, fCurrMeanMinDist_ST), FEEDBACK_T_LOWER);
+      if (std::max(fCurrMeanMinDist_LT, fCurrMeanMinDist_ST) > UNSTABLE_REG_RATIO_MIN && m_oBlinksFrame.data[nPxIter])
+        (fCurrDistThresholdVariationFactor) += bBootstrapping ? FEEDBACK_V_INCR * 2 : FEEDBACK_V_INCR;
+      else
+        fCurrDistThresholdVariationFactor = std::max(fCurrDistThresholdVariationFactor - FEEDBACK_V_DECR*((bBootstrapping || bCurrRegionIsFlat) ? 2 : m_oLastFGMask.data[nPxIter] ? 0.5f : 1), FEEDBACK_V_DECR);
+      if (fCurrDistThresholdFactor < std::pow(1.0f + std::min(fCurrMeanMinDist_LT, fCurrMeanMinDist_ST) * 2, 2))
+        fCurrDistThresholdFactor += FEEDBACK_R_VAR*(fCurrDistThresholdVariationFactor - FEEDBACK_V_DECR);
+      else
+        fCurrDistThresholdFactor = std::max(fCurrDistThresholdFactor - FEEDBACK_R_VAR / fCurrDistThresholdVariationFactor, 1.0f);
+      nLastIntraDesc = nCurrIntraDesc;
+      nLastColor = nCurrColor;
+    }
+  }
+  else { //m_nImgChannels==3
+    for (size_t nModelIter = 0; nModelIter < m_nTotRelevantPxCount; ++nModelIter) {
+      const size_t nPxIter = m_aPxIdxLUT[nModelIter];
+      const size_t nPxRGBIter = nPxIter * 3;
+      const size_t nDescRGBIter = nPxRGBIter * 2;
+      const size_t nFloatIter = nPxIter * 4;
+      const size_t nLocalDictIdx = nModelIter*m_nCurrLocalWords;
+      const size_t nGlobalWordMapLookupIdx = m_aPxInfoLUT_PAWCS[nPxIter].nGlobalWordMapLookupIdx;
+      const uchar* const anCurrColor = oInputImg.data + nPxRGBIter;
+      uchar* anLastColor = m_oLastColorFrame.data + nPxRGBIter;
+      ushort* anLastIntraDesc = ((ushort*)(m_oLastDescFrame.data + nDescRGBIter));
+      size_t nMinTotColorDist = s_nColorMaxDataRange_3ch;
+      size_t nMinTotDescDist = s_nDescMaxDataRange_3ch;
+      float& fCurrMeanRawSegmRes_LT = *(float*)(m_oMeanRawSegmResFrame_LT.data + nFloatIter);
+      float& fCurrMeanRawSegmRes_ST = *(float*)(m_oMeanRawSegmResFrame_ST.data + nFloatIter);
+      float& fCurrMeanFinalSegmRes_LT = *(float*)(m_oMeanFinalSegmResFrame_LT.data + nFloatIter);
+      float& fCurrMeanFinalSegmRes_ST = *(float*)(m_oMeanFinalSegmResFrame_ST.data + nFloatIter);
+      float& fCurrDistThresholdFactor = *(float*)(m_oDistThresholdFrame.data + nFloatIter);
+      float& fCurrDistThresholdVariationFactor = *(float*)(m_oDistThresholdVariationFrame.data + nFloatIter);
+      float& fCurrLearningRate = *(float*)(m_oUpdateRateFrame.data + nFloatIter);
+      float& fCurrMeanMinDist_LT = *(float*)(m_oMeanMinDistFrame_LT.data + nFloatIter);
+      float& fCurrMeanMinDist_ST = *(float*)(m_oMeanMinDistFrame_ST.data + nFloatIter);
+      const float fBestLocalWordWeight = GetLocalWordWeight(m_apLocalWordDict[nLocalDictIdx], m_nFrameIndex, m_nLocalWordWeightOffset);
+      const float fLocalWordsWeightSumThreshold = fBestLocalWordWeight / (fCurrDistThresholdFactor * 2);
+      uchar& bCurrRegionIsUnstable = m_oUnstableRegionMask.data[nPxIter];
+      uchar& nCurrRegionIllumUpdtVal = m_oIllumUpdtRegionMask.data[nPxIter];
+      uchar& nCurrRegionSegmVal = oCurrFGMask.data[nPxIter];
+      const bool bCurrRegionIsROIBorder = m_oROI.data[nPxIter] < UCHAR_MAX;
+      const int nCurrImgCoord_X = m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_X;
+      const int nCurrImgCoord_Y = m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_Y;
+      ushort anCurrInterDesc[3], anCurrIntraDesc[3];
+      const size_t anCurrIntraLBSPThresholds[3] = { m_anLBSPThreshold_8bitLUT[anCurrColor[0]],m_anLBSPThreshold_8bitLUT[anCurrColor[1]],m_anLBSPThreshold_8bitLUT[anCurrColor[2]] };
+      LBSP_::computeRGBDescriptor(oInputImg, anCurrColor, nCurrImgCoord_X, nCurrImgCoord_Y, anCurrIntraLBSPThresholds, anCurrIntraDesc);
+      const uchar nCurrIntraDescBITS = (uchar)popcount<3>(anCurrIntraDesc);
+      const bool bCurrRegionIsFlat = nCurrIntraDescBITS < FLAT_REGION_BIT_COUNT * 2;
+      if (bCurrRegionIsFlat)
+        ++nFlatRegionCount;
+      const size_t nCurrWordOccIncr = (DEFAULT_LWORD_OCC_INCR + m_nModelResetCooldown) << int(bCurrRegionIsFlat || bBootstrapping);
+      const size_t nCurrLocalWordUpdateRate = learningRateOverride > 0 ? (size_t)ceil(learningRateOverride) : bCurrRegionIsFlat ? (size_t)ceil(fCurrLearningRate + FEEDBACK_T_LOWER) / 2 : (size_t)ceil(fCurrLearningRate);
+      const size_t nCurrTotColorDistThreshold = (size_t)(sqrt(fCurrDistThresholdFactor)*m_nMinColorDistThreshold) * 3;
+      const size_t nCurrTotDescDistThreshold = (((size_t)1 << ((size_t)floor(fCurrDistThresholdFactor + 0.5f))) + m_nDescDistThresholdOffset + (bCurrRegionIsUnstable*UNSTAB_DESC_DIST_OFFSET)) * 3;
+      size_t nLocalWordIdx = 0;
+      float fPotentialLocalWordsWeightSum = 0.0f;
+      float fLastLocalWordWeight = FLT_MAX;
+      while (nLocalWordIdx < m_nCurrLocalWords && fPotentialLocalWordsWeightSum < fLocalWordsWeightSumThreshold) {
+        LocalWord_3ch* pCurrLocalWord = (LocalWord_3ch*)m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx];
+        const float fCurrLocalWordWeight = GetLocalWordWeight(pCurrLocalWord, m_nFrameIndex, m_nLocalWordWeightOffset);
+        {
+          const size_t nTotColorL1Dist = L1dist<3>(anCurrColor, pCurrLocalWord->oFeature.anColor);
+          const size_t nColorDistortion = cdist<3>(anCurrColor, pCurrLocalWord->oFeature.anColor);
+          const size_t nTotColorMixDist = cmixdist(nTotColorL1Dist, nColorDistortion);
+          const size_t nTotIntraDescDist = hdist<3>(anCurrIntraDesc, pCurrLocalWord->oFeature.anDesc);
+          const size_t anCurrInterLBSPThresholds[3] = { m_anLBSPThreshold_8bitLUT[pCurrLocalWord->oFeature.anColor[0]],m_anLBSPThreshold_8bitLUT[pCurrLocalWord->oFeature.anColor[1]],m_anLBSPThreshold_8bitLUT[pCurrLocalWord->oFeature.anColor[2]] };
+          LBSP_::computeRGBDescriptor(oInputImg, pCurrLocalWord->oFeature.anColor, nCurrImgCoord_X, nCurrImgCoord_Y, anCurrInterLBSPThresholds, anCurrInterDesc);
+          const size_t nTotInterDescDist = hdist<3>(anCurrInterDesc, pCurrLocalWord->oFeature.anDesc);
+          const size_t nTotDescDist = (nTotIntraDescDist + nTotInterDescDist) / 2;
+          if ((!bCurrRegionIsUnstable || bCurrRegionIsFlat || bCurrRegionIsROIBorder)
+            && nTotColorMixDist <= nCurrTotColorDistThreshold
+            && nTotColorL1Dist >= nCurrTotColorDistThreshold / 2
+            && nTotIntraDescDist <= nCurrTotDescDistThreshold / 2
+            && (rand() % (nCurrRegionIllumUpdtVal ? (nCurrLocalWordUpdateRate / 2 + 1) : nCurrLocalWordUpdateRate)) == 0) {
+            // == illum updt
+            for (size_t c = 0; c < 3; ++c) {
+              pCurrLocalWord->oFeature.anColor[c] = anCurrColor[c];
+              pCurrLocalWord->oFeature.anDesc[c] = anCurrIntraDesc[c];
+            }
+            m_oIllumUpdtRegionMask.data[nPxIter - 1] = 1 & m_oROI.data[nPxIter - 1];
+            m_oIllumUpdtRegionMask.data[nPxIter + 1] = 1 & m_oROI.data[nPxIter + 1];
+            m_oIllumUpdtRegionMask.data[nPxIter] = 2;
+          }
+          if (nTotDescDist <= nCurrTotDescDistThreshold && nTotColorMixDist <= nCurrTotColorDistThreshold) {
+            fPotentialLocalWordsWeightSum += fCurrLocalWordWeight;
+            pCurrLocalWord->nLastOcc = m_nFrameIndex;
+            if ((!m_oLastFGMask.data[nPxIter] || m_bUsingMovingCamera) && fCurrLocalWordWeight < DEFAULT_LWORD_MAX_WEIGHT)
+              pCurrLocalWord->nOccurrences += nCurrWordOccIncr;
+            nMinTotColorDist = std::min(nMinTotColorDist, nTotColorMixDist);
+            nMinTotDescDist = std::min(nMinTotDescDist, nTotDescDist);
+          }
+        }
+        if (fCurrLocalWordWeight > fLastLocalWordWeight) {
+          std::swap(m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx], m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx - 1]);
+        }
+        else
+          fLastLocalWordWeight = fCurrLocalWordWeight;
+        ++nLocalWordIdx;
+      }
+      while (nLocalWordIdx < m_nCurrLocalWords) {
+        const float fCurrLocalWordWeight = GetLocalWordWeight(m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx], m_nFrameIndex, m_nLocalWordWeightOffset);
+        if (fCurrLocalWordWeight > fLastLocalWordWeight) {
+          std::swap(m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx], m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx - 1]);
+        }
+        else
+          fLastLocalWordWeight = fCurrLocalWordWeight;
+        ++nLocalWordIdx;
+      }
+      if (fPotentialLocalWordsWeightSum >= fLocalWordsWeightSumThreshold || bCurrRegionIsROIBorder) {
+        // == background
+        const float fNormalizedMinDist = std::max((float)nMinTotColorDist / s_nColorMaxDataRange_3ch, (float)nMinTotDescDist / s_nDescMaxDataRange_3ch);
+        fCurrMeanMinDist_LT = fCurrMeanMinDist_LT*(1.0f - fRollAvgFactor_LT) + fNormalizedMinDist*fRollAvgFactor_LT;
+        fCurrMeanMinDist_ST = fCurrMeanMinDist_ST*(1.0f - fRollAvgFactor_ST) + fNormalizedMinDist*fRollAvgFactor_ST;
+        fCurrMeanRawSegmRes_LT = fCurrMeanRawSegmRes_LT*(1.0f - fRollAvgFactor_LT);
+        fCurrMeanRawSegmRes_ST = fCurrMeanRawSegmRes_ST*(1.0f - fRollAvgFactor_ST);
+        if ((rand() % nCurrLocalWordUpdateRate) == 0) {
+          size_t nGlobalWordLUTIdx;
+          GlobalWord_3ch* pCurrGlobalWord = nullptr;
+          for (nGlobalWordLUTIdx = 0; nGlobalWordLUTIdx < m_nCurrGlobalWords; ++nGlobalWordLUTIdx) {
+            pCurrGlobalWord = (GlobalWord_3ch*)m_aPxInfoLUT_PAWCS[nPxIter].apGlobalDictSortLUT[nGlobalWordLUTIdx];
+            if (L1dist(nCurrIntraDescBITS, pCurrGlobalWord->nDescBITS) <= nCurrTotDescDistThreshold / GWORD_DESC_THRES_BITS_MATCH_FACTOR
+              && cmixdist<3>(anCurrColor, pCurrGlobalWord->oFeature.anColor) <= nCurrTotColorDistThreshold)
+              break;
+          }
+          if (nGlobalWordLUTIdx != m_nCurrGlobalWords || (rand() % (nCurrLocalWordUpdateRate * 2)) == 0) {
+            if (nGlobalWordLUTIdx == m_nCurrGlobalWords) {
+              pCurrGlobalWord = (GlobalWord_3ch*)m_apGlobalWordDict[m_nCurrGlobalWords - 1];
+              for (size_t c = 0; c < 3; ++c) {
+                pCurrGlobalWord->oFeature.anColor[c] = anCurrColor[c];
+                pCurrGlobalWord->oFeature.anDesc[c] = anCurrIntraDesc[c];
+              }
+              pCurrGlobalWord->nDescBITS = nCurrIntraDescBITS;
+              pCurrGlobalWord->oSpatioOccMap = cv::Scalar(0.0f);
+              pCurrGlobalWord->fLatestWeight = 0.0f;
+            }
+            float& fCurrGlobalWordLocalWeight = *(float*)(pCurrGlobalWord->oSpatioOccMap.data + nGlobalWordMapLookupIdx);
+            if (fCurrGlobalWordLocalWeight < fPotentialLocalWordsWeightSum) {
+              pCurrGlobalWord->fLatestWeight += fPotentialLocalWordsWeightSum;
+              fCurrGlobalWordLocalWeight += fPotentialLocalWordsWeightSum;
+            }
+          }
+        }
+      }
+      else {
+        // == foreground
+        const float fNormalizedMinDist = std::max(std::max((float)nMinTotColorDist / s_nColorMaxDataRange_3ch, (float)nMinTotDescDist / s_nDescMaxDataRange_3ch), (fLocalWordsWeightSumThreshold - fPotentialLocalWordsWeightSum) / fLocalWordsWeightSumThreshold);
+        fCurrMeanMinDist_LT = fCurrMeanMinDist_LT*(1.0f - fRollAvgFactor_LT) + fNormalizedMinDist*fRollAvgFactor_LT;
+        fCurrMeanMinDist_ST = fCurrMeanMinDist_ST*(1.0f - fRollAvgFactor_ST) + fNormalizedMinDist*fRollAvgFactor_ST;
+        fCurrMeanRawSegmRes_LT = fCurrMeanRawSegmRes_LT*(1.0f - fRollAvgFactor_LT) + fRollAvgFactor_LT;
+        fCurrMeanRawSegmRes_ST = fCurrMeanRawSegmRes_ST*(1.0f - fRollAvgFactor_ST) + fRollAvgFactor_ST;
+        if (bCurrRegionIsFlat || (rand() % nCurrLocalWordUpdateRate) == 0) {
+          size_t nGlobalWordLUTIdx;
+          GlobalWord_3ch* pCurrGlobalWord;
+          for (nGlobalWordLUTIdx = 0; nGlobalWordLUTIdx < m_nCurrGlobalWords; ++nGlobalWordLUTIdx) {
+            pCurrGlobalWord = (GlobalWord_3ch*)m_aPxInfoLUT_PAWCS[nPxIter].apGlobalDictSortLUT[nGlobalWordLUTIdx];
+            if (L1dist(nCurrIntraDescBITS, pCurrGlobalWord->nDescBITS) <= nCurrTotDescDistThreshold / GWORD_DESC_THRES_BITS_MATCH_FACTOR
+              && cmixdist<3>(anCurrColor, pCurrGlobalWord->oFeature.anColor) <= nCurrTotColorDistThreshold)
+              break;
+          }
+          if (nGlobalWordLUTIdx == m_nCurrGlobalWords)
+            nCurrRegionSegmVal = UCHAR_MAX;
+          else {
+            const float fGlobalWordLocalizedWeight = *(float*)(pCurrGlobalWord->oSpatioOccMap.data + nGlobalWordMapLookupIdx);
+            if (fPotentialLocalWordsWeightSum + fGlobalWordLocalizedWeight / (bCurrRegionIsFlat ? 2 : 4) < fLocalWordsWeightSumThreshold)
+              nCurrRegionSegmVal = UCHAR_MAX;
+          }
+        }
+        else
+          nCurrRegionSegmVal = UCHAR_MAX;
+        if (fPotentialLocalWordsWeightSum < DEFAULT_LWORD_INIT_WEIGHT) {
+          const size_t nNewLocalWordIdx = m_nCurrLocalWords - 1;
+          LocalWord_3ch* pNewLocalWord = (LocalWord_3ch*)m_apLocalWordDict[nLocalDictIdx + nNewLocalWordIdx];
+          for (size_t c = 0; c < 3; ++c) {
+            pNewLocalWord->oFeature.anColor[c] = anCurrColor[c];
+            pNewLocalWord->oFeature.anDesc[c] = anCurrIntraDesc[c];
+          }
+          pNewLocalWord->nOccurrences = nCurrWordOccIncr;
+          pNewLocalWord->nFirstOcc = m_nFrameIndex;
+          pNewLocalWord->nLastOcc = m_nFrameIndex;
+        }
+      }
+      // == neighb updt
+      if ((!nCurrRegionSegmVal && (rand() % nCurrLocalWordUpdateRate) == 0) || bCurrRegionIsROIBorder || m_bUsingMovingCamera) {
+        //if((!nCurrRegionSegmVal && (rand()%(nCurrRegionIllumUpdtVal?(nCurrLocalWordUpdateRate/2+1):nCurrLocalWordUpdateRate))==0) || bCurrRegionIsROIBorder) {
+        int nSampleImgCoord_Y, nSampleImgCoord_X;
+        if (bCurrRegionIsFlat || bCurrRegionIsROIBorder || m_bUsingMovingCamera)
+          getRandNeighborPosition_5x5(nSampleImgCoord_X, nSampleImgCoord_Y, nCurrImgCoord_X, nCurrImgCoord_Y, LBSP_::PATCH_SIZE / 2, m_oImgSize);
+        else
+          getRandNeighborPosition_3x3(nSampleImgCoord_X, nSampleImgCoord_Y, nCurrImgCoord_X, nCurrImgCoord_Y, LBSP_::PATCH_SIZE / 2, m_oImgSize);
+        const size_t nSamplePxIdx = m_oImgSize.width*nSampleImgCoord_Y + nSampleImgCoord_X;
+        if (m_oROI.data[nSamplePxIdx]) {
+          const size_t nNeighborLocalDictIdx = m_aPxInfoLUT_PAWCS[nSamplePxIdx].nModelIdx*m_nCurrLocalWords;
+          size_t nNeighborLocalWordIdx = 0;
+          float fNeighborPotentialLocalWordsWeightSum = 0.0f;
+          while (nNeighborLocalWordIdx < m_nCurrLocalWords && fNeighborPotentialLocalWordsWeightSum < fLocalWordsWeightSumThreshold) {
+            LocalWord_3ch* pNeighborLocalWord = (LocalWord_3ch*)m_apLocalWordDict[nNeighborLocalDictIdx + nNeighborLocalWordIdx];
+            const size_t nNeighborTotColorL1Dist = L1dist<3>(anCurrColor, pNeighborLocalWord->oFeature.anColor);
+            const size_t nNeighborColorDistortion = cdist<3>(anCurrColor, pNeighborLocalWord->oFeature.anColor);
+            const size_t nNeighborTotColorMixDist = cmixdist(nNeighborTotColorL1Dist, nNeighborColorDistortion);
+            const size_t nNeighborTotIntraDescDist = hdist<3>(anCurrIntraDesc, pNeighborLocalWord->oFeature.anDesc);
+            const bool bNeighborRegionIsFlat = popcount<3>(pNeighborLocalWord->oFeature.anDesc) < FLAT_REGION_BIT_COUNT * 2;
+            const size_t nNeighborWordOccIncr = bNeighborRegionIsFlat ? nCurrWordOccIncr * 2 : nCurrWordOccIncr;
+            if (nNeighborTotColorMixDist <= nCurrTotColorDistThreshold && nNeighborTotIntraDescDist <= nCurrTotDescDistThreshold) {
+              const float fNeighborLocalWordWeight = GetLocalWordWeight(pNeighborLocalWord, m_nFrameIndex, m_nLocalWordWeightOffset);
+              fNeighborPotentialLocalWordsWeightSum += fNeighborLocalWordWeight;
+              pNeighborLocalWord->nLastOcc = m_nFrameIndex;
+              if (fNeighborLocalWordWeight < DEFAULT_LWORD_MAX_WEIGHT)
+                pNeighborLocalWord->nOccurrences += nNeighborWordOccIncr;
+            }
+            else if (!oCurrFGMask.data[nSamplePxIdx] && bCurrRegionIsFlat && (bBootstrapping || (rand() % nCurrLocalWordUpdateRate) == 0)) {
+              const size_t nSamplePxRGBIdx = nSamplePxIdx * 3;
+              const size_t nSampleDescRGBIdx = nSamplePxRGBIdx * 2;
+              ushort* anNeighborLastIntraDesc = ((ushort*)(m_oLastDescFrame.data + nSampleDescRGBIdx));
+              const size_t nNeighborTotLastIntraDescDist = hdist<3>(anCurrIntraDesc, anNeighborLastIntraDesc);
+              if (nNeighborTotColorMixDist <= nCurrTotColorDistThreshold && nNeighborTotLastIntraDescDist <= nCurrTotDescDistThreshold / 2) {
+                const float fNeighborLocalWordWeight = GetLocalWordWeight(pNeighborLocalWord, m_nFrameIndex, m_nLocalWordWeightOffset);
+                fNeighborPotentialLocalWordsWeightSum += fNeighborLocalWordWeight;
+                pNeighborLocalWord->nLastOcc = m_nFrameIndex;
+                if (fNeighborLocalWordWeight < DEFAULT_LWORD_MAX_WEIGHT)
+                  pNeighborLocalWord->nOccurrences += nNeighborWordOccIncr;
+                for (size_t c = 0; c < 3; ++c)
+                  pNeighborLocalWord->oFeature.anDesc[c] = anCurrIntraDesc[c];
+              }
+              else {
+                const bool bNeighborLastRegionIsFlat = popcount<3>(anNeighborLastIntraDesc) < FLAT_REGION_BIT_COUNT * 2;
+                if (bNeighborLastRegionIsFlat && bCurrRegionIsFlat &&
+                  nNeighborTotLastIntraDescDist + nNeighborTotIntraDescDist <= nCurrTotDescDistThreshold &&
+                  nNeighborColorDistortion <= nCurrTotColorDistThreshold / 4) {
+                  const float fNeighborLocalWordWeight = GetLocalWordWeight(pNeighborLocalWord, m_nFrameIndex, m_nLocalWordWeightOffset);
+                  fNeighborPotentialLocalWordsWeightSum += fNeighborLocalWordWeight;
+                  pNeighborLocalWord->nLastOcc = m_nFrameIndex;
+                  if (fNeighborLocalWordWeight < DEFAULT_LWORD_MAX_WEIGHT)
+                    pNeighborLocalWord->nOccurrences += nNeighborWordOccIncr;
+                  for (size_t c = 0; c < 3; ++c)
+                    pNeighborLocalWord->oFeature.anColor[c] = anCurrColor[c];
+                }
+              }
+            }
+            ++nNeighborLocalWordIdx;
+          }
+          if (fNeighborPotentialLocalWordsWeightSum < DEFAULT_LWORD_INIT_WEIGHT) {
+            nNeighborLocalWordIdx = m_nCurrLocalWords - 1;
+            LocalWord_3ch* pNeighborLocalWord = (LocalWord_3ch*)m_apLocalWordDict[nNeighborLocalDictIdx + nNeighborLocalWordIdx];
+            for (size_t c = 0; c < 3; ++c) {
+              pNeighborLocalWord->oFeature.anColor[c] = anCurrColor[c];
+              pNeighborLocalWord->oFeature.anDesc[c] = anCurrIntraDesc[c];
+            }
+            pNeighborLocalWord->nOccurrences = nCurrWordOccIncr;
+            pNeighborLocalWord->nFirstOcc = m_nFrameIndex;
+            pNeighborLocalWord->nLastOcc = m_nFrameIndex;
+          }
+        }
+      }
+      if (nCurrRegionIllumUpdtVal)
+        nCurrRegionIllumUpdtVal -= 1;
+      // == feedback adj
+      bCurrRegionIsUnstable = fCurrDistThresholdFactor > UNSTABLE_REG_RDIST_MIN || (fCurrMeanRawSegmRes_LT - fCurrMeanFinalSegmRes_LT) > UNSTABLE_REG_RATIO_MIN || (fCurrMeanRawSegmRes_ST - fCurrMeanFinalSegmRes_ST) > UNSTABLE_REG_RATIO_MIN;
+      if (m_oLastFGMask.data[nPxIter] || (std::min(fCurrMeanMinDist_LT, fCurrMeanMinDist_ST) < UNSTABLE_REG_RATIO_MIN && nCurrRegionSegmVal))
+        fCurrLearningRate = std::min(fCurrLearningRate + FEEDBACK_T_INCR / (std::max(fCurrMeanMinDist_LT, fCurrMeanMinDist_ST)*fCurrDistThresholdVariationFactor), FEEDBACK_T_UPPER);
+      else
+        fCurrLearningRate = std::max(fCurrLearningRate - FEEDBACK_T_DECR*fCurrDistThresholdVariationFactor / std::max(fCurrMeanMinDist_LT, fCurrMeanMinDist_ST), FEEDBACK_T_LOWER);
+      if (std::max(fCurrMeanMinDist_LT, fCurrMeanMinDist_ST) > UNSTABLE_REG_RATIO_MIN && m_oBlinksFrame.data[nPxIter])
+        (fCurrDistThresholdVariationFactor) += bBootstrapping ? FEEDBACK_V_INCR * 2 : FEEDBACK_V_INCR;
+      else
+        fCurrDistThresholdVariationFactor = std::max(fCurrDistThresholdVariationFactor - FEEDBACK_V_DECR*((bBootstrapping || bCurrRegionIsFlat) ? 2 : m_oLastFGMask.data[nPxIter] ? 0.5f : 1), FEEDBACK_V_DECR);
+      if (fCurrDistThresholdFactor < std::pow(1.0f + std::min(fCurrMeanMinDist_LT, fCurrMeanMinDist_ST) * 2, 2))
+        fCurrDistThresholdFactor += FEEDBACK_R_VAR*(fCurrDistThresholdVariationFactor - FEEDBACK_V_DECR);
+      else
+        fCurrDistThresholdFactor = std::max(fCurrDistThresholdFactor - FEEDBACK_R_VAR / fCurrDistThresholdVariationFactor, 1.0f);
+      for (size_t c = 0; c < 3; ++c) {
+        anLastIntraDesc[c] = anCurrIntraDesc[c];
+        anLastColor[c] = anCurrColor[c];
+      }
+    }
+  }
+  const bool bRecalcGlobalWords = !(m_nFrameIndex % (nCurrGlobalWordUpdateRate << 5));
+  const bool bUpdateGlobalWords = !(m_nFrameIndex % (nCurrGlobalWordUpdateRate));
+  cv::Mat oLastFGMask_dilated_inverted_downscaled;
+  if (bUpdateGlobalWords)
+    cv::resize(m_oLastFGMask_dilated_inverted, oLastFGMask_dilated_inverted_downscaled, m_oDownSampledFrameSize_GlobalWordLookup, 0, 0, cv::INTER_NEAREST);
+  for (size_t nGlobalWordIdx = 0; nGlobalWordIdx < m_nCurrGlobalWords; ++nGlobalWordIdx) {
+    if (bRecalcGlobalWords && m_apGlobalWordDict[nGlobalWordIdx]->fLatestWeight > 0.0f) {
+      m_apGlobalWordDict[nGlobalWordIdx]->fLatestWeight = GetGlobalWordWeight(m_apGlobalWordDict[nGlobalWordIdx]);
+      if (m_apGlobalWordDict[nGlobalWordIdx]->fLatestWeight < 1.0f) {
+        m_apGlobalWordDict[nGlobalWordIdx]->fLatestWeight = 0.0f;
+        m_apGlobalWordDict[nGlobalWordIdx]->oSpatioOccMap = cv::Scalar(0.0f);
+      }
+    }
+    if (bUpdateGlobalWords && m_apGlobalWordDict[nGlobalWordIdx]->fLatestWeight > 0.0f) {
+      cv::accumulateProduct(m_apGlobalWordDict[nGlobalWordIdx]->oSpatioOccMap, m_oTempGlobalWordWeightDiffFactor, m_apGlobalWordDict[nGlobalWordIdx]->oSpatioOccMap, oLastFGMask_dilated_inverted_downscaled);
+      m_apGlobalWordDict[nGlobalWordIdx]->fLatestWeight *= 0.9f;
+      cv::blur(m_apGlobalWordDict[nGlobalWordIdx]->oSpatioOccMap, m_apGlobalWordDict[nGlobalWordIdx]->oSpatioOccMap, cv::Size(3, 3), cv::Point(-1, -1), cv::BORDER_REPLICATE);
+    }
+    if (nGlobalWordIdx > 0 && m_apGlobalWordDict[nGlobalWordIdx]->fLatestWeight > m_apGlobalWordDict[nGlobalWordIdx - 1]->fLatestWeight)
+      std::swap(m_apGlobalWordDict[nGlobalWordIdx], m_apGlobalWordDict[nGlobalWordIdx - 1]);
+  }
+  if (bUpdateGlobalWords) {
+    for (size_t nModelIter = 0; nModelIter < m_nTotRelevantPxCount; ++nModelIter) {
+      const size_t nPxIter = m_aPxIdxLUT[nModelIter];
+      const size_t nGlobalWordMapLookupIdx = m_aPxInfoLUT_PAWCS[nPxIter].nGlobalWordMapLookupIdx;
+      float fLastGlobalWordLocalWeight = *(float*)(m_aPxInfoLUT_PAWCS[nPxIter].apGlobalDictSortLUT[0]->oSpatioOccMap.data + nGlobalWordMapLookupIdx);
+      for (size_t nGlobalWordLUTIdx = 1; nGlobalWordLUTIdx < m_nCurrGlobalWords; ++nGlobalWordLUTIdx) {
+        const float fCurrGlobalWordLocalWeight = *(float*)(m_aPxInfoLUT_PAWCS[nPxIter].apGlobalDictSortLUT[nGlobalWordLUTIdx]->oSpatioOccMap.data + nGlobalWordMapLookupIdx);
+        if (fCurrGlobalWordLocalWeight > fLastGlobalWordLocalWeight)
+          std::swap(m_aPxInfoLUT_PAWCS[nPxIter].apGlobalDictSortLUT[nGlobalWordLUTIdx], m_aPxInfoLUT_PAWCS[nPxIter].apGlobalDictSortLUT[nGlobalWordLUTIdx - 1]);
+        else
+          fLastGlobalWordLocalWeight = fCurrGlobalWordLocalWeight;
+      }
+    }
+  }
+  cv::bitwise_xor(oCurrFGMask, m_oLastRawFGMask, m_oCurrRawFGBlinkMask);
+  cv::bitwise_or(m_oCurrRawFGBlinkMask, m_oLastRawFGBlinkMask, m_oBlinksFrame);
+  m_oCurrRawFGBlinkMask.copyTo(m_oLastRawFGBlinkMask);
+  oCurrFGMask.copyTo(m_oLastRawFGMask);
+  cv::morphologyEx(oCurrFGMask, m_oFGMask_PreFlood, cv::MORPH_CLOSE, m_oMorphExStructElement);
+  m_oFGMask_PreFlood.copyTo(m_oFGMask_FloodedHoles);
+  cv::floodFill(m_oFGMask_FloodedHoles, cv::Point(0, 0), UCHAR_MAX);
+  cv::bitwise_not(m_oFGMask_FloodedHoles, m_oFGMask_FloodedHoles);
+  cv::erode(m_oFGMask_PreFlood, m_oFGMask_PreFlood, cv::Mat(), cv::Point(-1, -1), 3);
+  cv::bitwise_or(oCurrFGMask, m_oFGMask_FloodedHoles, oCurrFGMask);
+  cv::bitwise_or(oCurrFGMask, m_oFGMask_PreFlood, oCurrFGMask);
+  cv::medianBlur(oCurrFGMask, m_oLastFGMask, m_nMedianBlurKernelSize);
+  cv::dilate(m_oLastFGMask, m_oLastFGMask_dilated, cv::Mat(), cv::Point(-1, -1), 3);
+  cv::bitwise_and(m_oBlinksFrame, m_oLastFGMask_dilated_inverted, m_oBlinksFrame);
+  cv::bitwise_not(m_oLastFGMask_dilated, m_oLastFGMask_dilated_inverted);
+  cv::bitwise_and(m_oBlinksFrame, m_oLastFGMask_dilated_inverted, m_oBlinksFrame);
+  m_oLastFGMask.copyTo(oCurrFGMask);
+  cv::addWeighted(m_oMeanFinalSegmResFrame_LT, (1.0f - fRollAvgFactor_LT), m_oLastFGMask, (1.0 / UCHAR_MAX)*fRollAvgFactor_LT, 0, m_oMeanFinalSegmResFrame_LT, CV_32F);
+  cv::addWeighted(m_oMeanFinalSegmResFrame_ST, (1.0f - fRollAvgFactor_ST), m_oLastFGMask, (1.0 / UCHAR_MAX)*fRollAvgFactor_ST, 0, m_oMeanFinalSegmResFrame_ST, CV_32F);
+  const float fCurrNonFlatRegionRatio = (float)(m_nTotRelevantPxCount - nFlatRegionCount) / m_nTotRelevantPxCount;
+  if (fCurrNonFlatRegionRatio < LBSPDESC_RATIO_MIN && m_fLastNonFlatRegionRatio < LBSPDESC_RATIO_MIN) {
+    for (size_t t = 0; t <= UCHAR_MAX; ++t)
+      if (m_anLBSPThreshold_8bitLUT[t] > cv::saturate_cast<uchar>((m_nLBSPThresholdOffset + t*m_fRelLBSPThreshold) / 4))
+        --m_anLBSPThreshold_8bitLUT[t];
+  }
+  else if (fCurrNonFlatRegionRatio > LBSPDESC_RATIO_MAX && m_fLastNonFlatRegionRatio > LBSPDESC_RATIO_MAX) {
+    for (size_t t = 0; t <= UCHAR_MAX; ++t)
+      if (m_anLBSPThreshold_8bitLUT[t] < cv::saturate_cast<uchar>(m_nLBSPThresholdOffset + UCHAR_MAX*m_fRelLBSPThreshold))
+        ++m_anLBSPThreshold_8bitLUT[t];
+  }
+  m_fLastNonFlatRegionRatio = fCurrNonFlatRegionRatio;
+  cv::resize(oInputImg, m_oDownSampledFrame_MotionAnalysis, m_oDownSampledFrameSize_MotionAnalysis, 0, 0, cv::INTER_AREA);
+  cv::accumulateWeighted(m_oDownSampledFrame_MotionAnalysis, m_oMeanDownSampledLastDistFrame_LT, fRollAvgFactor_LT);
+  cv::accumulateWeighted(m_oDownSampledFrame_MotionAnalysis, m_oMeanDownSampledLastDistFrame_ST, fRollAvgFactor_ST);
+  const float fCurrMeanL1DistRatio = L1dist((float*)m_oMeanDownSampledLastDistFrame_LT.data, (float*)m_oMeanDownSampledLastDistFrame_ST.data, m_oMeanDownSampledLastDistFrame_LT.total(), m_nImgChannels, m_oDownSampledROI_MotionAnalysis.data) / m_nDownSampledROIPxCount;
+  if (!m_bAutoModelResetEnabled && fCurrMeanL1DistRatio >= FRAMELEVEL_MIN_L1DIST_THRES * 2)
+    m_bAutoModelResetEnabled = true;
+  if (m_bAutoModelResetEnabled || m_bUsingMovingCamera) {
+    if ((m_nFrameIndex%DEFAULT_BOOTSTRAP_WIN_SIZE) == 0) {
+      cv::Mat oCurrBackgroundImg, oDownSampledBackgroundImg;
+      getBackgroundImage(oCurrBackgroundImg);
+      cv::resize(oCurrBackgroundImg, oDownSampledBackgroundImg, m_oDownSampledFrameSize_MotionAnalysis, 0, 0, cv::INTER_AREA);
+      cv::Mat oDownSampledBackgroundImg_32F; oDownSampledBackgroundImg.convertTo(oDownSampledBackgroundImg_32F, CV_32F);
+      const float fCurrModelL1DistRatio = L1dist((float*)m_oMeanDownSampledLastDistFrame_LT.data, (float*)oDownSampledBackgroundImg_32F.data, m_oMeanDownSampledLastDistFrame_LT.total(), m_nImgChannels, cv::Mat(m_oDownSampledROI_MotionAnalysis == UCHAR_MAX).data) / m_nDownSampledROIPxCount;
+      const float fCurrModelCDistRatio = cdist((float*)m_oMeanDownSampledLastDistFrame_LT.data, (float*)oDownSampledBackgroundImg_32F.data, m_oMeanDownSampledLastDistFrame_LT.total(), m_nImgChannels, cv::Mat(m_oDownSampledROI_MotionAnalysis == UCHAR_MAX).data) / m_nDownSampledROIPxCount;
+      if (m_bUsingMovingCamera && fCurrModelL1DistRatio < FRAMELEVEL_MIN_L1DIST_THRES / 4 && fCurrModelCDistRatio < FRAMELEVEL_MIN_CDIST_THRES / 4) {
+        m_nLocalWordWeightOffset = DEFAULT_LWORD_WEIGHT_OFFSET;
+        m_bUsingMovingCamera = false;
+        refreshModel(1, 1, true);
+      }
+      else if (bBootstrapping && !m_bUsingMovingCamera && (fCurrModelL1DistRatio >= FRAMELEVEL_MIN_L1DIST_THRES || fCurrModelCDistRatio >= FRAMELEVEL_MIN_CDIST_THRES)) {
+        m_nLocalWordWeightOffset = 5;
+        m_bUsingMovingCamera = true;
+        refreshModel(1, 1, true);
+      }
+    }
+    if (m_nFramesSinceLastReset > DEFAULT_BOOTSTRAP_WIN_SIZE * 2)
+      m_bAutoModelResetEnabled = false;
+    else if (fCurrMeanL1DistRatio >= FRAMELEVEL_MIN_L1DIST_THRES && m_nModelResetCooldown == 0) {
+      m_nFramesSinceLastReset = 0;
+      refreshModel(m_nLocalWordWeightOffset / 8, 0, true);
+      m_nModelResetCooldown = nCurrSamplesForMovingAvg_ST;
+      m_oUpdateRateFrame = cv::Scalar(1.0f);
+    }
+    else if (!bBootstrapping)
+      ++m_nFramesSinceLastReset;
+  }
+  if (m_nModelResetCooldown > 0)
+    --m_nModelResetCooldown;
+}
+
+void BackgroundSubtractorPAWCS::getBackgroundImage(cv::OutputArray backgroundImage) const { // @@@ add option to reconstruct from gwords?
+  CV_Assert(m_bInitialized);
+  cv::Mat oAvgBGImg = cv::Mat::zeros(m_oImgSize, CV_32FC((int)m_nImgChannels));
+  for (size_t nModelIter = 0; nModelIter < m_nTotRelevantPxCount; ++nModelIter) {
+    const size_t nPxIter = m_aPxIdxLUT[nModelIter];
+    const size_t nLocalDictIdx = nModelIter*m_nCurrLocalWords;
+    const int nCurrImgCoord_X = m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_X;
+    const int nCurrImgCoord_Y = m_aPxInfoLUT_PAWCS[nPxIter].nImgCoord_Y;
+    if (m_nImgChannels == 1) {
+      float fTotWeight = 0.0f;
+      float fTotColor = 0.0f;
+      for (size_t nLocalWordIdx = 0; nLocalWordIdx < m_nCurrLocalWords; ++nLocalWordIdx) {
+        LocalWord_1ch* pCurrLocalWord = (LocalWord_1ch*)m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx];
+        float fCurrWeight = GetLocalWordWeight(pCurrLocalWord, m_nFrameIndex, m_nLocalWordWeightOffset);
+        fTotColor += (float)pCurrLocalWord->oFeature.anColor[0] * fCurrWeight;
+        fTotWeight += fCurrWeight;
+      }
+      oAvgBGImg.at<float>(nCurrImgCoord_Y, nCurrImgCoord_X) = fTotColor / fTotWeight;
+    }
+    else { //m_nImgChannels==3
+      float fTotWeight = 0.0f;
+      float fTotColor[3] = { 0.0f,0.0f,0.0f };
+      for (size_t nLocalWordIdx = 0; nLocalWordIdx < m_nCurrLocalWords; ++nLocalWordIdx) {
+        LocalWord_3ch* pCurrLocalWord = (LocalWord_3ch*)m_apLocalWordDict[nLocalDictIdx + nLocalWordIdx];
+        float fCurrWeight = GetLocalWordWeight(pCurrLocalWord, m_nFrameIndex, m_nLocalWordWeightOffset);
+        for (size_t c = 0; c < 3; ++c)
+          fTotColor[c] += (float)pCurrLocalWord->oFeature.anColor[c] * fCurrWeight;
+        fTotWeight += fCurrWeight;
+      }
+      oAvgBGImg.at<cv::Vec3f>(nCurrImgCoord_Y, nCurrImgCoord_X) = cv::Vec3f(fTotColor[0] / fTotWeight, fTotColor[1] / fTotWeight, fTotColor[2] / fTotWeight);
+    }
+  }
+  oAvgBGImg.convertTo(backgroundImage, CV_8U);
+}
+
+void BackgroundSubtractorPAWCS::getBackgroundDescriptorsImage(cv::OutputArray backgroundDescImage) const {
+  CV_Assert(LBSP_::DESC_SIZE == 2);
+  CV_Assert(m_bInitialized);
+  cv::Mat oAvgBGDesc = cv::Mat::zeros(m_oImgSize, CV_32FC((int)m_nImgChannels));
+  // @@@@@@ TO BE REWRITTEN FOR WORD-BASED RECONSTRUCTION
+  /*for(size_t n=0; n<m_voBGDescSamples.size(); ++n) {
+        for(int y=0; y<m_oImgSize.height; ++y) {
+            for(int x=0; x<m_oImgSize.width; ++x) {
+                const size_t nDescIter = m_voBGDescSamples[n].step.p[0]*y + m_voBGDescSamples[n].step.p[1]*x;
+                const size_t nFloatIter = nDescIter*2;
+                float* oAvgBgDescPtr = (float*)(oAvgBGDesc.data+nFloatIter);
+                const ushort* const oBGDescPtr = (ushort*)(m_voBGDescSamples[n].data+nDescIter);
+                for(size_t c=0; c<m_nImgChannels; ++c)
+                    oAvgBgDescPtr[c] += ((float)oBGDescPtr[c])/m_voBGDescSamples.size();
+            }
+        }
+    }*/
+  oAvgBGDesc.convertTo(backgroundDescImage, CV_16U);
+}
+
+void BackgroundSubtractorPAWCS::CleanupDictionaries() {
+  if (m_aLocalWordList_1ch) {
+    delete[] m_aLocalWordList_1ch;
+    m_aLocalWordList_1ch = nullptr;
+    m_pLocalWordListIter_1ch = nullptr;
+  }
+  else if (m_aLocalWordList_3ch) {
+    delete[] m_aLocalWordList_3ch;
+    m_aLocalWordList_3ch = nullptr;
+    m_pLocalWordListIter_3ch = nullptr;
+  }
+  if (m_apLocalWordDict) {
+    delete[] m_apLocalWordDict;
+    m_apLocalWordDict = nullptr;
+  }
+  if (m_aGlobalWordList_1ch) {
+    delete[] m_aGlobalWordList_1ch;
+    m_aGlobalWordList_1ch = nullptr;
+    m_pGlobalWordListIter_1ch = nullptr;
+  }
+  else if (m_aGlobalWordList_3ch) {
+    delete[] m_aGlobalWordList_3ch;
+    m_aGlobalWordList_3ch = nullptr;
+    m_pGlobalWordListIter_3ch = nullptr;
+  }
+  if (m_apGlobalWordDict) {
+    delete[] m_apGlobalWordDict;
+    m_apGlobalWordDict = nullptr;
+  }
+  if (m_aPxInfoLUT_PAWCS) {
+    for (size_t nPxIter = 0; nPxIter < m_nTotPxCount; ++nPxIter)
+      delete[] m_aPxInfoLUT_PAWCS[nPxIter].apGlobalDictSortLUT;
+    delete[] m_aPxInfoLUT_PAWCS;
+    m_aPxInfoLUT = nullptr;
+    m_aPxInfoLUT_PAWCS = nullptr;
+  }
+  if (m_aPxIdxLUT) {
+    delete[] m_aPxIdxLUT;
+    m_aPxIdxLUT = nullptr;
+  }
+}
+
+float BackgroundSubtractorPAWCS::GetLocalWordWeight(const LocalWordBase* w, size_t nCurrFrame, size_t nOffset) {
+  return (float)(w->nOccurrences) / ((w->nLastOcc - w->nFirstOcc) + (nCurrFrame - w->nLastOcc) * 2 + nOffset);
+}
+
+float BackgroundSubtractorPAWCS::GetGlobalWordWeight(const GlobalWordBase* w) {
+  return (float)cv::sum(w->oSpatioOccMap).val[0];
+}
diff --git a/package_bgs/LBSP/BackgroundSubtractorPAWCS.h b/package_bgs/LBSP/BackgroundSubtractorPAWCS.h
new file mode 100644
index 0000000000000000000000000000000000000000..cafa48c55a0993ca6ec76024e17ad57f8bfdca78
--- /dev/null
+++ b/package_bgs/LBSP/BackgroundSubtractorPAWCS.h
@@ -0,0 +1,169 @@
+/*
+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
+
+#include "BackgroundSubtractorLBSP_.h"
+
+//! defines the default value for BackgroundSubtractorLBSP_::m_fRelLBSPThreshold
+#define BGSPAWCS_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD (0.333f)
+//! defines the default value for BackgroundSubtractorPAWCS::m_nDescDistThresholdOffset
+#define BGSPAWCS_DEFAULT_DESC_DIST_THRESHOLD_OFFSET (2)
+//! defines the default value for BackgroundSubtractorPAWCS::m_nMinColorDistThreshold
+#define BGSPAWCS_DEFAULT_MIN_COLOR_DIST_THRESHOLD (20)
+//! defines the default value for BackgroundSubtractorPAWCS::m_nMaxLocalWords and m_nMaxGlobalWords
+#define BGSPAWCS_DEFAULT_MAX_NB_WORDS (50)
+//! defines the default value for BackgroundSubtractorPAWCS::m_nSamplesForMovingAvgs
+#define BGSPAWCS_DEFAULT_N_SAMPLES_FOR_MV_AVGS (100)
+
+/*!
+    Pixel-based Adaptive Word Consensus Segmenter (PAWCS) change detection algorithm.
+
+    Note: both grayscale and RGB/BGR images may be used with this extractor (parameters are adjusted automatically).
+    For optimal grayscale results, use CV_8UC1 frames instead of CV_8UC3.
+
+    For more details on the different parameters or on the algorithm itself, see P.-L. St-Charles et al.,
+    "A Self-Adjusting Approach to Change Detection Based on Background Word Consensus", in WACV 2015.
+
+    This algorithm is currently NOT thread-safe.
+ */
+class BackgroundSubtractorPAWCS : public BackgroundSubtractorLBSP_ {
+public:
+  //! full constructor
+  BackgroundSubtractorPAWCS(float fRelLBSPThreshold = BGSPAWCS_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD,
+    size_t nDescDistThresholdOffset = BGSPAWCS_DEFAULT_DESC_DIST_THRESHOLD_OFFSET,
+    size_t nMinColorDistThreshold = BGSPAWCS_DEFAULT_MIN_COLOR_DIST_THRESHOLD,
+    size_t nMaxNbWords = BGSPAWCS_DEFAULT_MAX_NB_WORDS,
+    size_t nSamplesForMovingAvgs = BGSPAWCS_DEFAULT_N_SAMPLES_FOR_MV_AVGS);
+  //! default destructor
+  virtual ~BackgroundSubtractorPAWCS();
+  //! (re)initiaization method; needs to be called before starting background subtraction
+  virtual void initialize(const cv::Mat& oInitImg, const cv::Mat& oROI);
+  //! refreshes all local (+ global) dictionaries based on the last analyzed frame
+  virtual void refreshModel(size_t nBaseOccCount, float fOccDecrFrac, bool bForceFGUpdate = false);
+  //! primary model update function; the learning param is used to override the internal learning speed (ignored when <= 0)
+  virtual void apply(cv::InputArray image, cv::OutputArray fgmask, double learningRateOverride = 0);
+  //! returns a copy of the latest reconstructed background image
+  virtual void getBackgroundImage(cv::OutputArray backgroundImage) const;
+  //! returns a copy of the latest reconstructed background descriptors image
+  virtual void getBackgroundDescriptorsImage(cv::OutputArray backgroundDescImage) const;
+
+protected:
+  template<size_t nChannels>
+  struct ColorLBSPFeature {
+    uchar anColor[nChannels];
+    ushort anDesc[nChannels];
+  };
+  struct LocalWordBase {
+    size_t nFirstOcc;
+    size_t nLastOcc;
+    size_t nOccurrences;
+  };
+  template<typename T>
+  struct LocalWord : LocalWordBase {
+    T oFeature;
+  };
+  struct GlobalWordBase {
+    float fLatestWeight;
+    cv::Mat oSpatioOccMap;
+    uchar nDescBITS;
+  };
+  template<typename T>
+  struct GlobalWord : GlobalWordBase {
+    T oFeature;
+  };
+  typedef LocalWord<ColorLBSPFeature<1>> LocalWord_1ch;
+  typedef LocalWord<ColorLBSPFeature<3>> LocalWord_3ch;
+  typedef GlobalWord<ColorLBSPFeature<1>> GlobalWord_1ch;
+  typedef GlobalWord<ColorLBSPFeature<3>> GlobalWord_3ch;
+  struct PxInfo_PAWCS : PxInfoBase {
+    size_t nGlobalWordMapLookupIdx;
+    GlobalWordBase** apGlobalDictSortLUT;
+  };
+  //! absolute minimal color distance threshold ('R' or 'radius' in the original ViBe paper, used as the default/initial 'R(x)' value here)
+  const size_t m_nMinColorDistThreshold;
+  //! absolute descriptor distance threshold offset
+  const size_t m_nDescDistThresholdOffset;
+  //! max/curr number of local words used to build background submodels (for a single pixel, similar to 'N' in ViBe/PBAS, may vary based on img/channel size)
+  size_t m_nMaxLocalWords, m_nCurrLocalWords;
+  //! max/curr number of global words used to build the global background model (may vary based on img/channel size)
+  size_t m_nMaxGlobalWords, m_nCurrGlobalWords;
+  //! number of samples to use to compute the learning rate of moving averages
+  const size_t m_nSamplesForMovingAvgs;
+  //! last calculated non-flat region ratio
+  float m_fLastNonFlatRegionRatio;
+  //! current kernel size for median blur post-proc filtering
+  int m_nMedianBlurKernelSize;
+  //! specifies the downsampled frame size used for cam motion analysis & gword lookup maps
+  cv::Size m_oDownSampledFrameSize_MotionAnalysis, m_oDownSampledFrameSize_GlobalWordLookup;
+  //! downsampled version of the ROI used for cam motion analysis
+  cv::Mat m_oDownSampledROI_MotionAnalysis;
+  //! total pixel count for the downsampled ROIs
+  size_t m_nDownSampledROIPxCount;
+  //! current local word weight offset
+  size_t m_nLocalWordWeightOffset;
+
+  //! word lists & dictionaries
+  LocalWordBase** m_apLocalWordDict;
+  LocalWord_1ch* m_aLocalWordList_1ch, *m_pLocalWordListIter_1ch;
+  LocalWord_3ch* m_aLocalWordList_3ch, *m_pLocalWordListIter_3ch;
+  GlobalWordBase** m_apGlobalWordDict;
+  GlobalWord_1ch* m_aGlobalWordList_1ch, *m_pGlobalWordListIter_1ch;
+  GlobalWord_3ch* m_aGlobalWordList_3ch, *m_pGlobalWordListIter_3ch;
+  PxInfo_PAWCS* m_aPxInfoLUT_PAWCS;
+
+  //! a lookup map used to keep track of regions where illumination recently changed
+  cv::Mat m_oIllumUpdtRegionMask;
+  //! per-pixel update rates ('T(x)' in PBAS, which contains pixel-level 'sigmas', as referred to in ViBe)
+  cv::Mat m_oUpdateRateFrame;
+  //! per-pixel distance thresholds (equivalent to 'R(x)' in PBAS, but used as a relative value to determine both intensity and descriptor variation thresholds)
+  cv::Mat m_oDistThresholdFrame;
+  //! per-pixel distance threshold variation modulators ('v(x)', relative value used to modulate 'R(x)' and 'T(x)' variations)
+  cv::Mat m_oDistThresholdVariationFrame;
+  //! per-pixel mean minimal distances from the model ('D_min(x)' in PBAS, used to control variation magnitude and direction of 'T(x)' and 'R(x)')
+  cv::Mat m_oMeanMinDistFrame_LT, m_oMeanMinDistFrame_ST;
+  //! per-pixel mean downsampled distances between consecutive frames (used to analyze camera movement and force global model resets automatically)
+  cv::Mat m_oMeanDownSampledLastDistFrame_LT, m_oMeanDownSampledLastDistFrame_ST;
+  //! per-pixel mean raw segmentation results (used to detect unstable segmentation regions)
+  cv::Mat m_oMeanRawSegmResFrame_LT, m_oMeanRawSegmResFrame_ST;
+  //! per-pixel mean raw segmentation results (used to detect unstable segmentation regions)
+  cv::Mat m_oMeanFinalSegmResFrame_LT, m_oMeanFinalSegmResFrame_ST;
+  //! a lookup map used to keep track of unstable regions (based on segm. noise & local dist. thresholds)
+  cv::Mat m_oUnstableRegionMask;
+  //! per-pixel blink detection map ('Z(x)')
+  cv::Mat m_oBlinksFrame;
+  //! pre-allocated matrix used to downsample the input frame when needed
+  cv::Mat m_oDownSampledFrame_MotionAnalysis;
+  //! the foreground mask generated by the method at [t-1] (without post-proc, used for blinking px detection)
+  cv::Mat m_oLastRawFGMask;
+
+  //! pre-allocated CV_8UC1 matrices used to speed up morph ops
+  cv::Mat m_oFGMask_PreFlood;
+  cv::Mat m_oFGMask_FloodedHoles;
+  cv::Mat m_oLastFGMask_dilated;
+  cv::Mat m_oLastFGMask_dilated_inverted;
+  cv::Mat m_oCurrRawFGBlinkMask;
+  cv::Mat m_oLastRawFGBlinkMask;
+  cv::Mat m_oTempGlobalWordWeightDiffFactor;
+  cv::Mat m_oMorphExStructElement;
+
+  //! internal cleanup function for the dictionary structures
+  void CleanupDictionaries();
+  //! internal weight lookup function for local words
+  static float GetLocalWordWeight(const LocalWordBase* w, size_t nCurrFrame, size_t nOffset);
+  //! internal weight lookup function for global words
+  static float GetGlobalWordWeight(const GlobalWordBase* w);
+};
diff --git a/package_bgs/LBSP/BackgroundSubtractorSuBSENSE.cpp b/package_bgs/LBSP/BackgroundSubtractorSuBSENSE.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3dcc1b86e231fe83fded922cab432aed5fc53862
--- /dev/null
+++ b/package_bgs/LBSP/BackgroundSubtractorSuBSENSE.cpp
@@ -0,0 +1,753 @@
+/*
+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 "BackgroundSubtractorSuBSENSE.h"
+#include "DistanceUtils.h"
+#include "RandUtils.h"
+#include <iostream>
+#include <opencv2/imgproc/imgproc.hpp>
+#include <opencv2/highgui/highgui.hpp>
+#include <iomanip>
+
+/*
+ *
+ * Intrinsic parameters for our method are defined here; tuning these for better
+ * performance should not be required in most cases -- although improvements in
+ * very specific scenarios are always possible.
+ *
+ */
+ //! defines the threshold value(s) used to detect long-term ghosting and trigger the fast edge-based absorption heuristic
+#define GHOSTDET_D_MAX (0.010f) // defines 'negligible' change here
+#define GHOSTDET_S_MIN (0.995f) // defines the required minimum local foreground saturation value
+//! parameter used to scale dynamic distance threshold adjustments ('R(x)')
+#define FEEDBACK_R_VAR (0.01f)
+//! parameters used to adjust the variation step size of 'v(x)'
+#define FEEDBACK_V_INCR  (1.000f)
+#define FEEDBACK_V_DECR  (0.100f)
+//! parameters used to scale dynamic learning rate adjustments  ('T(x)')
+#define FEEDBACK_T_DECR  (0.2500f)
+#define FEEDBACK_T_INCR  (0.5000f)
+#define FEEDBACK_T_LOWER (2.0000f)
+#define FEEDBACK_T_UPPER (256.00f)
+//! parameters used to define 'unstable' regions, based on segm noise/bg dynamics and local dist threshold values
+#define UNSTABLE_REG_RATIO_MIN (0.100f)
+#define UNSTABLE_REG_RDIST_MIN (3.000f)
+//! parameters used to scale the relative LBSP intensity threshold used for internal comparisons
+#define LBSPDESC_NONZERO_RATIO_MIN (0.100f)
+#define LBSPDESC_NONZERO_RATIO_MAX (0.500f)
+//! parameters used to define model reset/learning rate boosts in our frame-level component
+#define FRAMELEVEL_MIN_COLOR_DIFF_THRESHOLD  (m_nMinColorDistThreshold/2)
+#define FRAMELEVEL_ANALYSIS_DOWNSAMPLE_RATIO (8)
+
+// local define used to display debug information
+#define DISPLAY_SUBSENSE_DEBUG_INFO 0
+// local define used to specify the default frame size (320x240 = QVGA)
+#define DEFAULT_FRAME_SIZE cv::Size(320,240)
+// local define used to specify the color dist threshold offset used for unstable regions
+#define STAB_COLOR_DIST_OFFSET (m_nMinColorDistThreshold/5)
+// local define used to specify the desc dist threshold offset used for unstable regions
+#define UNSTAB_DESC_DIST_OFFSET (m_nDescDistThresholdOffset)
+
+static const size_t s_nColorMaxDataRange_1ch = UCHAR_MAX;
+static const size_t s_nDescMaxDataRange_1ch = LBSP::DESC_SIZE * 8;
+static const size_t s_nColorMaxDataRange_3ch = s_nColorMaxDataRange_1ch * 3;
+static const size_t s_nDescMaxDataRange_3ch = s_nDescMaxDataRange_1ch * 3;
+
+BackgroundSubtractorSuBSENSE::BackgroundSubtractorSuBSENSE(float fRelLBSPThreshold
+  , size_t nDescDistThresholdOffset
+  , size_t nMinColorDistThreshold
+  , size_t nBGSamples
+  , size_t nRequiredBGSamples
+  , size_t nSamplesForMovingAvgs)
+  : BackgroundSubtractorLBSP(fRelLBSPThreshold)
+  , m_nMinColorDistThreshold(nMinColorDistThreshold)
+  , m_nDescDistThresholdOffset(nDescDistThresholdOffset)
+  , m_nBGSamples(nBGSamples)
+  , m_nRequiredBGSamples(nRequiredBGSamples)
+  , m_nSamplesForMovingAvgs(nSamplesForMovingAvgs)
+  , m_fLastNonZeroDescRatio(0.0f)
+  , m_bLearningRateScalingEnabled(true)
+  , m_fCurrLearningRateLowerCap(FEEDBACK_T_LOWER)
+  , m_fCurrLearningRateUpperCap(FEEDBACK_T_UPPER)
+  , m_nMedianBlurKernelSize(m_nDefaultMedianBlurKernelSize)
+  , m_bUse3x3Spread(true) {
+  CV_Assert(m_nBGSamples > 0 && m_nRequiredBGSamples <= m_nBGSamples);
+  CV_Assert(m_nMinColorDistThreshold >= STAB_COLOR_DIST_OFFSET);
+}
+
+BackgroundSubtractorSuBSENSE::~BackgroundSubtractorSuBSENSE() {
+  if (m_aPxIdxLUT)
+    delete[] m_aPxIdxLUT;
+  if (m_aPxInfoLUT)
+    delete[] m_aPxInfoLUT;
+}
+
+void BackgroundSubtractorSuBSENSE::initialize(const cv::Mat& oInitImg, const cv::Mat& oROI) {
+  // == init
+  CV_Assert(!oInitImg.empty() && oInitImg.cols > 0 && oInitImg.rows > 0);
+  CV_Assert(oInitImg.isContinuous());
+  CV_Assert(oInitImg.type() == CV_8UC3 || oInitImg.type() == CV_8UC1);
+  if (oInitImg.type() == CV_8UC3) {
+    std::vector<cv::Mat> voInitImgChannels;
+    cv::split(oInitImg, voInitImgChannels);
+    if (!cv::countNonZero((voInitImgChannels[0] != voInitImgChannels[1]) | (voInitImgChannels[2] != voInitImgChannels[1])))
+      std::cout << std::endl << "\tBackgroundSubtractorSuBSENSE : Warning, grayscale images should always be passed in CV_8UC1 format for optimal performance." << std::endl;
+  }
+  cv::Mat oNewBGROI;
+  if (oROI.empty() && (m_oROI.empty() || oROI.size() != oInitImg.size())) {
+    oNewBGROI.create(oInitImg.size(), CV_8UC1);
+    oNewBGROI = cv::Scalar_<uchar>(UCHAR_MAX);
+  }
+  else if (oROI.empty())
+    oNewBGROI = m_oROI;
+  else {
+    CV_Assert(oROI.size() == oInitImg.size() && oROI.type() == CV_8UC1);
+    CV_Assert(cv::countNonZero((oROI < UCHAR_MAX)&(oROI > 0)) == 0);
+    oNewBGROI = oROI.clone();
+    cv::Mat oTempROI;
+    cv::dilate(oNewBGROI, oTempROI, cv::Mat(), cv::Point(-1, -1), LBSP::PATCH_SIZE / 2);
+    cv::bitwise_or(oNewBGROI, oTempROI / 2, oNewBGROI);
+  }
+  const size_t nOrigROIPxCount = (size_t)cv::countNonZero(oNewBGROI);
+  CV_Assert(nOrigROIPxCount > 0);
+  LBSP::validateROI(oNewBGROI);
+  const size_t nFinalROIPxCount = (size_t)cv::countNonZero(oNewBGROI);
+  CV_Assert(nFinalROIPxCount > 0);
+  m_oROI = oNewBGROI;
+  m_oImgSize = oInitImg.size();
+  m_nImgType = oInitImg.type();
+  m_nImgChannels = oInitImg.channels();
+  m_nTotPxCount = m_oImgSize.area();
+  m_nTotRelevantPxCount = nFinalROIPxCount;
+  m_nFrameIndex = 0;
+  m_nFramesSinceLastReset = 0;
+  m_nModelResetCooldown = 0;
+  m_fLastNonZeroDescRatio = 0.0f;
+  const int nTotImgPixels = m_oImgSize.height*m_oImgSize.width;
+  if (nOrigROIPxCount >= m_nTotPxCount / 2 && (int)m_nTotPxCount >= DEFAULT_FRAME_SIZE.area()) {
+    m_bLearningRateScalingEnabled = true;
+    m_bAutoModelResetEnabled = true;
+    m_bUse3x3Spread = !(nTotImgPixels > DEFAULT_FRAME_SIZE.area() * 2);
+    const int nRawMedianBlurKernelSize = std::min((int)floor((float)nTotImgPixels / DEFAULT_FRAME_SIZE.area() + 0.5f) + m_nDefaultMedianBlurKernelSize, 14);
+    m_nMedianBlurKernelSize = (nRawMedianBlurKernelSize % 2) ? nRawMedianBlurKernelSize : nRawMedianBlurKernelSize - 1;
+    m_fCurrLearningRateLowerCap = FEEDBACK_T_LOWER;
+    m_fCurrLearningRateUpperCap = FEEDBACK_T_UPPER;
+  }
+  else {
+    m_bLearningRateScalingEnabled = false;
+    m_bAutoModelResetEnabled = false;
+    m_bUse3x3Spread = true;
+    m_nMedianBlurKernelSize = m_nDefaultMedianBlurKernelSize;
+    m_fCurrLearningRateLowerCap = FEEDBACK_T_LOWER * 2;
+    m_fCurrLearningRateUpperCap = FEEDBACK_T_UPPER * 2;
+  }
+  m_oUpdateRateFrame.create(m_oImgSize, CV_32FC1);
+  m_oUpdateRateFrame = cv::Scalar(m_fCurrLearningRateLowerCap);
+  m_oDistThresholdFrame.create(m_oImgSize, CV_32FC1);
+  m_oDistThresholdFrame = cv::Scalar(1.0f);
+  m_oVariationModulatorFrame.create(m_oImgSize, CV_32FC1);
+  m_oVariationModulatorFrame = cv::Scalar(10.0f); // should always be >= FEEDBACK_V_DECR
+  m_oMeanLastDistFrame.create(m_oImgSize, CV_32FC1);
+  m_oMeanLastDistFrame = cv::Scalar(0.0f);
+  m_oMeanMinDistFrame_LT.create(m_oImgSize, CV_32FC1);
+  m_oMeanMinDistFrame_LT = cv::Scalar(0.0f);
+  m_oMeanMinDistFrame_ST.create(m_oImgSize, CV_32FC1);
+  m_oMeanMinDistFrame_ST = cv::Scalar(0.0f);
+  m_oDownSampledFrameSize = cv::Size(m_oImgSize.width / FRAMELEVEL_ANALYSIS_DOWNSAMPLE_RATIO, m_oImgSize.height / FRAMELEVEL_ANALYSIS_DOWNSAMPLE_RATIO);
+  m_oMeanDownSampledLastDistFrame_LT.create(m_oDownSampledFrameSize, CV_32FC((int)m_nImgChannels));
+  m_oMeanDownSampledLastDistFrame_LT = cv::Scalar(0.0f);
+  m_oMeanDownSampledLastDistFrame_ST.create(m_oDownSampledFrameSize, CV_32FC((int)m_nImgChannels));
+  m_oMeanDownSampledLastDistFrame_ST = cv::Scalar(0.0f);
+  m_oMeanRawSegmResFrame_LT.create(m_oImgSize, CV_32FC1);
+  m_oMeanRawSegmResFrame_LT = cv::Scalar(0.0f);
+  m_oMeanRawSegmResFrame_ST.create(m_oImgSize, CV_32FC1);
+  m_oMeanRawSegmResFrame_ST = cv::Scalar(0.0f);
+  m_oMeanFinalSegmResFrame_LT.create(m_oImgSize, CV_32FC1);
+  m_oMeanFinalSegmResFrame_LT = cv::Scalar(0.0f);
+  m_oMeanFinalSegmResFrame_ST.create(m_oImgSize, CV_32FC1);
+  m_oMeanFinalSegmResFrame_ST = cv::Scalar(0.0f);
+  m_oUnstableRegionMask.create(m_oImgSize, CV_8UC1);
+  m_oUnstableRegionMask = cv::Scalar_<uchar>(0);
+  m_oBlinksFrame.create(m_oImgSize, CV_8UC1);
+  m_oBlinksFrame = cv::Scalar_<uchar>(0);
+  m_oDownSampledFrame_MotionAnalysis.create(m_oDownSampledFrameSize, CV_8UC((int)m_nImgChannels));
+  m_oDownSampledFrame_MotionAnalysis = cv::Scalar_<uchar>::all(0);
+  m_oLastColorFrame.create(m_oImgSize, CV_8UC((int)m_nImgChannels));
+  m_oLastColorFrame = cv::Scalar_<uchar>::all(0);
+  m_oLastDescFrame.create(m_oImgSize, CV_16UC((int)m_nImgChannels));
+  m_oLastDescFrame = cv::Scalar_<ushort>::all(0);
+  m_oLastRawFGMask.create(m_oImgSize, CV_8UC1);
+  m_oLastRawFGMask = cv::Scalar_<uchar>(0);
+  m_oLastFGMask.create(m_oImgSize, CV_8UC1);
+  m_oLastFGMask = cv::Scalar_<uchar>(0);
+  m_oLastFGMask_dilated.create(m_oImgSize, CV_8UC1);
+  m_oLastFGMask_dilated = cv::Scalar_<uchar>(0);
+  m_oLastFGMask_dilated_inverted.create(m_oImgSize, CV_8UC1);
+  m_oLastFGMask_dilated_inverted = cv::Scalar_<uchar>(0);
+  m_oFGMask_FloodedHoles.create(m_oImgSize, CV_8UC1);
+  m_oFGMask_FloodedHoles = cv::Scalar_<uchar>(0);
+  m_oFGMask_PreFlood.create(m_oImgSize, CV_8UC1);
+  m_oFGMask_PreFlood = cv::Scalar_<uchar>(0);
+  m_oCurrRawFGBlinkMask.create(m_oImgSize, CV_8UC1);
+  m_oCurrRawFGBlinkMask = cv::Scalar_<uchar>(0);
+  m_oLastRawFGBlinkMask.create(m_oImgSize, CV_8UC1);
+  m_oLastRawFGBlinkMask = cv::Scalar_<uchar>(0);
+  m_voBGColorSamples.resize(m_nBGSamples);
+  m_voBGDescSamples.resize(m_nBGSamples);
+  for (size_t s = 0; s < m_nBGSamples; ++s) {
+    m_voBGColorSamples[s].create(m_oImgSize, CV_8UC((int)m_nImgChannels));
+    m_voBGColorSamples[s] = cv::Scalar_<uchar>::all(0);
+    m_voBGDescSamples[s].create(m_oImgSize, CV_16UC((int)m_nImgChannels));
+    m_voBGDescSamples[s] = cv::Scalar_<ushort>::all(0);
+  }
+  if (m_aPxIdxLUT)
+    delete[] m_aPxIdxLUT;
+  if (m_aPxInfoLUT)
+    delete[] m_aPxInfoLUT;
+  m_aPxIdxLUT = new size_t[m_nTotRelevantPxCount];
+  m_aPxInfoLUT = new PxInfoBase[m_nTotPxCount];
+  if (m_nImgChannels == 1) {
+    CV_Assert(m_oLastColorFrame.step.p[0] == (size_t)m_oImgSize.width && m_oLastColorFrame.step.p[1] == 1);
+    CV_Assert(m_oLastDescFrame.step.p[0] == m_oLastColorFrame.step.p[0] * 2 && m_oLastDescFrame.step.p[1] == m_oLastColorFrame.step.p[1] * 2);
+    for (size_t t = 0; t <= UCHAR_MAX; ++t)
+      m_anLBSPThreshold_8bitLUT[t] = cv::saturate_cast<uchar>((m_nLBSPThresholdOffset + t*m_fRelLBSPThreshold) / 3);
+    for (size_t nPxIter = 0, nModelIter = 0; nPxIter < m_nTotPxCount; ++nPxIter) {
+      if (m_oROI.data[nPxIter]) {
+        m_aPxIdxLUT[nModelIter] = nPxIter;
+        m_aPxInfoLUT[nPxIter].nImgCoord_Y = (int)nPxIter / m_oImgSize.width;
+        m_aPxInfoLUT[nPxIter].nImgCoord_X = (int)nPxIter%m_oImgSize.width;
+        m_aPxInfoLUT[nPxIter].nModelIdx = nModelIter;
+        m_oLastColorFrame.data[nPxIter] = oInitImg.data[nPxIter];
+        const size_t nDescIter = nPxIter * 2;
+        LBSP::computeGrayscaleDescriptor(oInitImg, oInitImg.data[nPxIter], m_aPxInfoLUT[nPxIter].nImgCoord_X, m_aPxInfoLUT[nPxIter].nImgCoord_Y, m_anLBSPThreshold_8bitLUT[oInitImg.data[nPxIter]], *((ushort*)(m_oLastDescFrame.data + nDescIter)));
+        ++nModelIter;
+      }
+    }
+  }
+  else { //m_nImgChannels==3
+    CV_Assert(m_oLastColorFrame.step.p[0] == (size_t)m_oImgSize.width * 3 && m_oLastColorFrame.step.p[1] == 3);
+    CV_Assert(m_oLastDescFrame.step.p[0] == m_oLastColorFrame.step.p[0] * 2 && m_oLastDescFrame.step.p[1] == m_oLastColorFrame.step.p[1] * 2);
+    for (size_t t = 0; t <= UCHAR_MAX; ++t)
+      m_anLBSPThreshold_8bitLUT[t] = cv::saturate_cast<uchar>(m_nLBSPThresholdOffset + t*m_fRelLBSPThreshold);
+    for (size_t nPxIter = 0, nModelIter = 0; nPxIter < m_nTotPxCount; ++nPxIter) {
+      if (m_oROI.data[nPxIter]) {
+        m_aPxIdxLUT[nModelIter] = nPxIter;
+        m_aPxInfoLUT[nPxIter].nImgCoord_Y = (int)nPxIter / m_oImgSize.width;
+        m_aPxInfoLUT[nPxIter].nImgCoord_X = (int)nPxIter%m_oImgSize.width;
+        m_aPxInfoLUT[nPxIter].nModelIdx = nModelIter;
+        const size_t nPxRGBIter = nPxIter * 3;
+        const size_t nDescRGBIter = nPxRGBIter * 2;
+        for (size_t c = 0; c < 3; ++c) {
+          m_oLastColorFrame.data[nPxRGBIter + c] = oInitImg.data[nPxRGBIter + c];
+          LBSP::computeSingleRGBDescriptor(oInitImg, oInitImg.data[nPxRGBIter + c], m_aPxInfoLUT[nPxIter].nImgCoord_X, m_aPxInfoLUT[nPxIter].nImgCoord_Y, c, m_anLBSPThreshold_8bitLUT[oInitImg.data[nPxRGBIter + c]], ((ushort*)(m_oLastDescFrame.data + nDescRGBIter))[c]);
+        }
+        ++nModelIter;
+      }
+    }
+  }
+  m_bInitialized = true;
+  refreshModel(1.0f);
+}
+
+void BackgroundSubtractorSuBSENSE::refreshModel(float fSamplesRefreshFrac, bool bForceFGUpdate) {
+  // == refresh
+  CV_Assert(m_bInitialized);
+  CV_Assert(fSamplesRefreshFrac > 0.0f && fSamplesRefreshFrac <= 1.0f);
+  const size_t nModelsToRefresh = fSamplesRefreshFrac < 1.0f ? (size_t)(fSamplesRefreshFrac*m_nBGSamples) : m_nBGSamples;
+  const size_t nRefreshStartPos = fSamplesRefreshFrac < 1.0f ? rand() % m_nBGSamples : 0;
+  if (m_nImgChannels == 1) {
+    for (size_t nModelIter = 0; nModelIter < m_nTotRelevantPxCount; ++nModelIter) {
+      const size_t nPxIter = m_aPxIdxLUT[nModelIter];
+      if (bForceFGUpdate || !m_oLastFGMask.data[nPxIter]) {
+        for (size_t nCurrModelIdx = nRefreshStartPos; nCurrModelIdx < nRefreshStartPos + nModelsToRefresh; ++nCurrModelIdx) {
+          int nSampleImgCoord_Y, nSampleImgCoord_X;
+          getRandSamplePosition(nSampleImgCoord_X, nSampleImgCoord_Y, m_aPxInfoLUT[nPxIter].nImgCoord_X, m_aPxInfoLUT[nPxIter].nImgCoord_Y, LBSP::PATCH_SIZE / 2, m_oImgSize);
+          const size_t nSamplePxIdx = m_oImgSize.width*nSampleImgCoord_Y + nSampleImgCoord_X;
+          if (bForceFGUpdate || !m_oLastFGMask.data[nSamplePxIdx]) {
+            const size_t nCurrRealModelIdx = nCurrModelIdx%m_nBGSamples;
+            m_voBGColorSamples[nCurrRealModelIdx].data[nPxIter] = m_oLastColorFrame.data[nSamplePxIdx];
+            *((ushort*)(m_voBGDescSamples[nCurrRealModelIdx].data + nPxIter * 2)) = *((ushort*)(m_oLastDescFrame.data + nSamplePxIdx * 2));
+          }
+        }
+      }
+    }
+  }
+  else { //m_nImgChannels==3
+    for (size_t nModelIter = 0; nModelIter < m_nTotRelevantPxCount; ++nModelIter) {
+      const size_t nPxIter = m_aPxIdxLUT[nModelIter];
+      if (bForceFGUpdate || !m_oLastFGMask.data[nPxIter]) {
+        for (size_t nCurrModelIdx = nRefreshStartPos; nCurrModelIdx < nRefreshStartPos + nModelsToRefresh; ++nCurrModelIdx) {
+          int nSampleImgCoord_Y, nSampleImgCoord_X;
+          getRandSamplePosition(nSampleImgCoord_X, nSampleImgCoord_Y, m_aPxInfoLUT[nPxIter].nImgCoord_X, m_aPxInfoLUT[nPxIter].nImgCoord_Y, LBSP::PATCH_SIZE / 2, m_oImgSize);
+          const size_t nSamplePxIdx = m_oImgSize.width*nSampleImgCoord_Y + nSampleImgCoord_X;
+          if (bForceFGUpdate || !m_oLastFGMask.data[nSamplePxIdx]) {
+            const size_t nCurrRealModelIdx = nCurrModelIdx%m_nBGSamples;
+            for (size_t c = 0; c < 3; ++c) {
+              m_voBGColorSamples[nCurrRealModelIdx].data[nPxIter * 3 + c] = m_oLastColorFrame.data[nSamplePxIdx * 3 + c];
+              *((ushort*)(m_voBGDescSamples[nCurrRealModelIdx].data + (nPxIter * 3 + c) * 2)) = *((ushort*)(m_oLastDescFrame.data + (nSamplePxIdx * 3 + c) * 2));
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+void BackgroundSubtractorSuBSENSE::apply(cv::InputArray _image, cv::OutputArray _fgmask, double learningRateOverride) {
+  // == process
+  CV_Assert(m_bInitialized);
+  cv::Mat oInputImg = _image.getMat();
+  CV_Assert(oInputImg.type() == m_nImgType && oInputImg.size() == m_oImgSize);
+  CV_Assert(oInputImg.isContinuous());
+  _fgmask.create(m_oImgSize, CV_8UC1);
+  cv::Mat oCurrFGMask = _fgmask.getMat();
+  memset(oCurrFGMask.data, 0, oCurrFGMask.cols*oCurrFGMask.rows);
+  size_t nNonZeroDescCount = 0;
+  const float fRollAvgFactor_LT = 1.0f / std::min(++m_nFrameIndex, m_nSamplesForMovingAvgs);
+  const float fRollAvgFactor_ST = 1.0f / std::min(m_nFrameIndex, m_nSamplesForMovingAvgs / 4);
+  if (m_nImgChannels == 1) {
+    for (size_t nModelIter = 0; nModelIter < m_nTotRelevantPxCount; ++nModelIter) {
+      const size_t nPxIter = m_aPxIdxLUT[nModelIter];
+      const size_t nDescIter = nPxIter * 2;
+      const size_t nFloatIter = nPxIter * 4;
+      const int nCurrImgCoord_X = m_aPxInfoLUT[nPxIter].nImgCoord_X;
+      const int nCurrImgCoord_Y = m_aPxInfoLUT[nPxIter].nImgCoord_Y;
+      const uchar nCurrColor = oInputImg.data[nPxIter];
+      size_t nMinDescDist = s_nDescMaxDataRange_1ch;
+      size_t nMinSumDist = s_nColorMaxDataRange_1ch;
+      float* pfCurrDistThresholdFactor = (float*)(m_oDistThresholdFrame.data + nFloatIter);
+      float* pfCurrVariationFactor = (float*)(m_oVariationModulatorFrame.data + nFloatIter);
+      float* pfCurrLearningRate = ((float*)(m_oUpdateRateFrame.data + nFloatIter));
+      float* pfCurrMeanLastDist = ((float*)(m_oMeanLastDistFrame.data + nFloatIter));
+      float* pfCurrMeanMinDist_LT = ((float*)(m_oMeanMinDistFrame_LT.data + nFloatIter));
+      float* pfCurrMeanMinDist_ST = ((float*)(m_oMeanMinDistFrame_ST.data + nFloatIter));
+      float* pfCurrMeanRawSegmRes_LT = ((float*)(m_oMeanRawSegmResFrame_LT.data + nFloatIter));
+      float* pfCurrMeanRawSegmRes_ST = ((float*)(m_oMeanRawSegmResFrame_ST.data + nFloatIter));
+      float* pfCurrMeanFinalSegmRes_LT = ((float*)(m_oMeanFinalSegmResFrame_LT.data + nFloatIter));
+      float* pfCurrMeanFinalSegmRes_ST = ((float*)(m_oMeanFinalSegmResFrame_ST.data + nFloatIter));
+      ushort& nLastIntraDesc = *((ushort*)(m_oLastDescFrame.data + nDescIter));
+      uchar& nLastColor = m_oLastColorFrame.data[nPxIter];
+      const size_t nCurrColorDistThreshold = (size_t)(((*pfCurrDistThresholdFactor)*m_nMinColorDistThreshold) - ((!m_oUnstableRegionMask.data[nPxIter])*STAB_COLOR_DIST_OFFSET)) / 2;
+      const size_t nCurrDescDistThreshold = ((size_t)1 << ((size_t)floor(*pfCurrDistThresholdFactor + 0.5f))) + m_nDescDistThresholdOffset + (m_oUnstableRegionMask.data[nPxIter] * UNSTAB_DESC_DIST_OFFSET);
+      ushort nCurrInterDesc, nCurrIntraDesc;
+      LBSP::computeGrayscaleDescriptor(oInputImg, nCurrColor, nCurrImgCoord_X, nCurrImgCoord_Y, m_anLBSPThreshold_8bitLUT[nCurrColor], nCurrIntraDesc);
+      m_oUnstableRegionMask.data[nPxIter] = ((*pfCurrDistThresholdFactor) > UNSTABLE_REG_RDIST_MIN || (*pfCurrMeanRawSegmRes_LT - *pfCurrMeanFinalSegmRes_LT) > UNSTABLE_REG_RATIO_MIN || (*pfCurrMeanRawSegmRes_ST - *pfCurrMeanFinalSegmRes_ST) > UNSTABLE_REG_RATIO_MIN) ? 1 : 0;
+      size_t nGoodSamplesCount = 0, nSampleIdx = 0;
+      while (nGoodSamplesCount < m_nRequiredBGSamples && nSampleIdx < m_nBGSamples) {
+        const uchar& nBGColor = m_voBGColorSamples[nSampleIdx].data[nPxIter];
+        {
+          const size_t nColorDist = L1dist(nCurrColor, nBGColor);
+          if (nColorDist > nCurrColorDistThreshold)
+            goto failedcheck1ch;
+          const ushort& nBGIntraDesc = *((ushort*)(m_voBGDescSamples[nSampleIdx].data + nDescIter));
+          const size_t nIntraDescDist = hdist(nCurrIntraDesc, nBGIntraDesc);
+          LBSP::computeGrayscaleDescriptor(oInputImg, nBGColor, nCurrImgCoord_X, nCurrImgCoord_Y, m_anLBSPThreshold_8bitLUT[nBGColor], nCurrInterDesc);
+          const size_t nInterDescDist = hdist(nCurrInterDesc, nBGIntraDesc);
+          const size_t nDescDist = (nIntraDescDist + nInterDescDist) / 2;
+          if (nDescDist > nCurrDescDistThreshold)
+            goto failedcheck1ch;
+          const size_t nSumDist = std::min((nDescDist / 4)*(s_nColorMaxDataRange_1ch / s_nDescMaxDataRange_1ch) + nColorDist, s_nColorMaxDataRange_1ch);
+          if (nSumDist > nCurrColorDistThreshold)
+            goto failedcheck1ch;
+          if (nMinDescDist > nDescDist)
+            nMinDescDist = nDescDist;
+          if (nMinSumDist > nSumDist)
+            nMinSumDist = nSumDist;
+          nGoodSamplesCount++;
+        }
+      failedcheck1ch:
+        nSampleIdx++;
+      }
+      const float fNormalizedLastDist = ((float)L1dist(nLastColor, nCurrColor) / s_nColorMaxDataRange_1ch + (float)hdist(nLastIntraDesc, nCurrIntraDesc) / s_nDescMaxDataRange_1ch) / 2;
+      *pfCurrMeanLastDist = (*pfCurrMeanLastDist)*(1.0f - fRollAvgFactor_ST) + fNormalizedLastDist*fRollAvgFactor_ST;
+      if (nGoodSamplesCount < m_nRequiredBGSamples) {
+        // == foreground
+        const float fNormalizedMinDist = std::min(1.0f, ((float)nMinSumDist / s_nColorMaxDataRange_1ch + (float)nMinDescDist / s_nDescMaxDataRange_1ch) / 2 + (float)(m_nRequiredBGSamples - nGoodSamplesCount) / m_nRequiredBGSamples);
+        *pfCurrMeanMinDist_LT = (*pfCurrMeanMinDist_LT)*(1.0f - fRollAvgFactor_LT) + fNormalizedMinDist*fRollAvgFactor_LT;
+        *pfCurrMeanMinDist_ST = (*pfCurrMeanMinDist_ST)*(1.0f - fRollAvgFactor_ST) + fNormalizedMinDist*fRollAvgFactor_ST;
+        *pfCurrMeanRawSegmRes_LT = (*pfCurrMeanRawSegmRes_LT)*(1.0f - fRollAvgFactor_LT) + fRollAvgFactor_LT;
+        *pfCurrMeanRawSegmRes_ST = (*pfCurrMeanRawSegmRes_ST)*(1.0f - fRollAvgFactor_ST) + fRollAvgFactor_ST;
+        oCurrFGMask.data[nPxIter] = UCHAR_MAX;
+        if (m_nModelResetCooldown && (rand() % (size_t)FEEDBACK_T_LOWER) == 0) {
+          const size_t s_rand = rand() % m_nBGSamples;
+          *((ushort*)(m_voBGDescSamples[s_rand].data + nDescIter)) = nCurrIntraDesc;
+          m_voBGColorSamples[s_rand].data[nPxIter] = nCurrColor;
+        }
+      }
+      else {
+        // == background
+        const float fNormalizedMinDist = ((float)nMinSumDist / s_nColorMaxDataRange_1ch + (float)nMinDescDist / s_nDescMaxDataRange_1ch) / 2;
+        *pfCurrMeanMinDist_LT = (*pfCurrMeanMinDist_LT)*(1.0f - fRollAvgFactor_LT) + fNormalizedMinDist*fRollAvgFactor_LT;
+        *pfCurrMeanMinDist_ST = (*pfCurrMeanMinDist_ST)*(1.0f - fRollAvgFactor_ST) + fNormalizedMinDist*fRollAvgFactor_ST;
+        *pfCurrMeanRawSegmRes_LT = (*pfCurrMeanRawSegmRes_LT)*(1.0f - fRollAvgFactor_LT);
+        *pfCurrMeanRawSegmRes_ST = (*pfCurrMeanRawSegmRes_ST)*(1.0f - fRollAvgFactor_ST);
+        const size_t nLearningRate = learningRateOverride > 0 ? (size_t)ceil(learningRateOverride) : (size_t)ceil(*pfCurrLearningRate);
+        if ((rand() % nLearningRate) == 0) {
+          const size_t s_rand = rand() % m_nBGSamples;
+          *((ushort*)(m_voBGDescSamples[s_rand].data + nDescIter)) = nCurrIntraDesc;
+          m_voBGColorSamples[s_rand].data[nPxIter] = nCurrColor;
+        }
+        int nSampleImgCoord_Y, nSampleImgCoord_X;
+        const bool bCurrUsing3x3Spread = m_bUse3x3Spread && !m_oUnstableRegionMask.data[nPxIter];
+        if (bCurrUsing3x3Spread)
+          getRandNeighborPosition_3x3(nSampleImgCoord_X, nSampleImgCoord_Y, nCurrImgCoord_X, nCurrImgCoord_Y, LBSP::PATCH_SIZE / 2, m_oImgSize);
+        else
+          getRandNeighborPosition_5x5(nSampleImgCoord_X, nSampleImgCoord_Y, nCurrImgCoord_X, nCurrImgCoord_Y, LBSP::PATCH_SIZE / 2, m_oImgSize);
+        const size_t n_rand = rand();
+        const size_t idx_rand_uchar = m_oImgSize.width*nSampleImgCoord_Y + nSampleImgCoord_X;
+        const size_t idx_rand_flt32 = idx_rand_uchar * 4;
+        const float fRandMeanLastDist = *((float*)(m_oMeanLastDistFrame.data + idx_rand_flt32));
+        const float fRandMeanRawSegmRes = *((float*)(m_oMeanRawSegmResFrame_ST.data + idx_rand_flt32));
+        if ((n_rand % (bCurrUsing3x3Spread ? nLearningRate : (nLearningRate / 2 + 1))) == 0
+          || (fRandMeanRawSegmRes > GHOSTDET_S_MIN && fRandMeanLastDist < GHOSTDET_D_MAX && (n_rand % ((size_t)m_fCurrLearningRateLowerCap)) == 0)) {
+          const size_t idx_rand_ushrt = idx_rand_uchar * 2;
+          const size_t s_rand = rand() % m_nBGSamples;
+          *((ushort*)(m_voBGDescSamples[s_rand].data + idx_rand_ushrt)) = nCurrIntraDesc;
+          m_voBGColorSamples[s_rand].data[idx_rand_uchar] = nCurrColor;
+        }
+      }
+      if (m_oLastFGMask.data[nPxIter] || (std::min(*pfCurrMeanMinDist_LT, *pfCurrMeanMinDist_ST) < UNSTABLE_REG_RATIO_MIN && oCurrFGMask.data[nPxIter])) {
+        if ((*pfCurrLearningRate) < m_fCurrLearningRateUpperCap)
+          *pfCurrLearningRate += FEEDBACK_T_INCR / (std::max(*pfCurrMeanMinDist_LT, *pfCurrMeanMinDist_ST)*(*pfCurrVariationFactor));
+      }
+      else if ((*pfCurrLearningRate) > m_fCurrLearningRateLowerCap)
+        *pfCurrLearningRate -= FEEDBACK_T_DECR*(*pfCurrVariationFactor) / std::max(*pfCurrMeanMinDist_LT, *pfCurrMeanMinDist_ST);
+      if ((*pfCurrLearningRate) < m_fCurrLearningRateLowerCap)
+        *pfCurrLearningRate = m_fCurrLearningRateLowerCap;
+      else if ((*pfCurrLearningRate) > m_fCurrLearningRateUpperCap)
+        *pfCurrLearningRate = m_fCurrLearningRateUpperCap;
+      if (std::max(*pfCurrMeanMinDist_LT, *pfCurrMeanMinDist_ST) > UNSTABLE_REG_RATIO_MIN && m_oBlinksFrame.data[nPxIter])
+        (*pfCurrVariationFactor) += FEEDBACK_V_INCR;
+      else if ((*pfCurrVariationFactor) > FEEDBACK_V_DECR) {
+        (*pfCurrVariationFactor) -= m_oLastFGMask.data[nPxIter] ? FEEDBACK_V_DECR / 4 : m_oUnstableRegionMask.data[nPxIter] ? FEEDBACK_V_DECR / 2 : FEEDBACK_V_DECR;
+        if ((*pfCurrVariationFactor) < FEEDBACK_V_DECR)
+          (*pfCurrVariationFactor) = FEEDBACK_V_DECR;
+      }
+      if ((*pfCurrDistThresholdFactor) < std::pow(1.0f + std::min(*pfCurrMeanMinDist_LT, *pfCurrMeanMinDist_ST) * 2, 2))
+        (*pfCurrDistThresholdFactor) += FEEDBACK_R_VAR*(*pfCurrVariationFactor - FEEDBACK_V_DECR);
+      else {
+        (*pfCurrDistThresholdFactor) -= FEEDBACK_R_VAR / (*pfCurrVariationFactor);
+        if ((*pfCurrDistThresholdFactor) < 1.0f)
+          (*pfCurrDistThresholdFactor) = 1.0f;
+      }
+      if (popcount(nCurrIntraDesc) >= 2)
+        ++nNonZeroDescCount;
+      nLastIntraDesc = nCurrIntraDesc;
+      nLastColor = nCurrColor;
+    }
+  }
+  else { //m_nImgChannels==3
+    for (size_t nModelIter = 0; nModelIter < m_nTotRelevantPxCount; ++nModelIter) {
+      const size_t nPxIter = m_aPxIdxLUT[nModelIter];
+      const int nCurrImgCoord_X = m_aPxInfoLUT[nPxIter].nImgCoord_X;
+      const int nCurrImgCoord_Y = m_aPxInfoLUT[nPxIter].nImgCoord_Y;
+      const size_t nPxIterRGB = nPxIter * 3;
+      const size_t nDescIterRGB = nPxIterRGB * 2;
+      const size_t nFloatIter = nPxIter * 4;
+      const uchar* const anCurrColor = oInputImg.data + nPxIterRGB;
+      size_t nMinTotDescDist = s_nDescMaxDataRange_3ch;
+      size_t nMinTotSumDist = s_nColorMaxDataRange_3ch;
+      float* pfCurrDistThresholdFactor = (float*)(m_oDistThresholdFrame.data + nFloatIter);
+      float* pfCurrVariationFactor = (float*)(m_oVariationModulatorFrame.data + nFloatIter);
+      float* pfCurrLearningRate = ((float*)(m_oUpdateRateFrame.data + nFloatIter));
+      float* pfCurrMeanLastDist = ((float*)(m_oMeanLastDistFrame.data + nFloatIter));
+      float* pfCurrMeanMinDist_LT = ((float*)(m_oMeanMinDistFrame_LT.data + nFloatIter));
+      float* pfCurrMeanMinDist_ST = ((float*)(m_oMeanMinDistFrame_ST.data + nFloatIter));
+      float* pfCurrMeanRawSegmRes_LT = ((float*)(m_oMeanRawSegmResFrame_LT.data + nFloatIter));
+      float* pfCurrMeanRawSegmRes_ST = ((float*)(m_oMeanRawSegmResFrame_ST.data + nFloatIter));
+      float* pfCurrMeanFinalSegmRes_LT = ((float*)(m_oMeanFinalSegmResFrame_LT.data + nFloatIter));
+      float* pfCurrMeanFinalSegmRes_ST = ((float*)(m_oMeanFinalSegmResFrame_ST.data + nFloatIter));
+      ushort* anLastIntraDesc = ((ushort*)(m_oLastDescFrame.data + nDescIterRGB));
+      uchar* anLastColor = m_oLastColorFrame.data + nPxIterRGB;
+      const size_t nCurrColorDistThreshold = (size_t)(((*pfCurrDistThresholdFactor)*m_nMinColorDistThreshold) - ((!m_oUnstableRegionMask.data[nPxIter])*STAB_COLOR_DIST_OFFSET));
+      const size_t nCurrDescDistThreshold = ((size_t)1 << ((size_t)floor(*pfCurrDistThresholdFactor + 0.5f))) + m_nDescDistThresholdOffset + (m_oUnstableRegionMask.data[nPxIter] * UNSTAB_DESC_DIST_OFFSET);
+      const size_t nCurrTotColorDistThreshold = nCurrColorDistThreshold * 3;
+      const size_t nCurrTotDescDistThreshold = nCurrDescDistThreshold * 3;
+      const size_t nCurrSCColorDistThreshold = nCurrTotColorDistThreshold / 2;
+      ushort anCurrInterDesc[3], anCurrIntraDesc[3];
+      const size_t anCurrIntraLBSPThresholds[3] = { m_anLBSPThreshold_8bitLUT[anCurrColor[0]],m_anLBSPThreshold_8bitLUT[anCurrColor[1]],m_anLBSPThreshold_8bitLUT[anCurrColor[2]] };
+      LBSP::computeRGBDescriptor(oInputImg, anCurrColor, nCurrImgCoord_X, nCurrImgCoord_Y, anCurrIntraLBSPThresholds, anCurrIntraDesc);
+      m_oUnstableRegionMask.data[nPxIter] = ((*pfCurrDistThresholdFactor) > UNSTABLE_REG_RDIST_MIN || (*pfCurrMeanRawSegmRes_LT - *pfCurrMeanFinalSegmRes_LT) > UNSTABLE_REG_RATIO_MIN || (*pfCurrMeanRawSegmRes_ST - *pfCurrMeanFinalSegmRes_ST) > UNSTABLE_REG_RATIO_MIN) ? 1 : 0;
+      size_t nGoodSamplesCount = 0, nSampleIdx = 0;
+      while (nGoodSamplesCount < m_nRequiredBGSamples && nSampleIdx < m_nBGSamples) {
+        const ushort* const anBGIntraDesc = (ushort*)(m_voBGDescSamples[nSampleIdx].data + nDescIterRGB);
+        const uchar* const anBGColor = m_voBGColorSamples[nSampleIdx].data + nPxIterRGB;
+        size_t nTotDescDist = 0;
+        size_t nTotSumDist = 0;
+        for (size_t c = 0; c < 3; ++c) {
+          const size_t nColorDist = L1dist(anCurrColor[c], anBGColor[c]);
+          if (nColorDist > nCurrSCColorDistThreshold)
+            goto failedcheck3ch;
+          const size_t nIntraDescDist = hdist(anCurrIntraDesc[c], anBGIntraDesc[c]);
+          LBSP::computeSingleRGBDescriptor(oInputImg, anBGColor[c], nCurrImgCoord_X, nCurrImgCoord_Y, c, m_anLBSPThreshold_8bitLUT[anBGColor[c]], anCurrInterDesc[c]);
+          const size_t nInterDescDist = hdist(anCurrInterDesc[c], anBGIntraDesc[c]);
+          const size_t nDescDist = (nIntraDescDist + nInterDescDist) / 2;
+          const size_t nSumDist = std::min((nDescDist / 2)*(s_nColorMaxDataRange_1ch / s_nDescMaxDataRange_1ch) + nColorDist, s_nColorMaxDataRange_1ch);
+          if (nSumDist > nCurrSCColorDistThreshold)
+            goto failedcheck3ch;
+          nTotDescDist += nDescDist;
+          nTotSumDist += nSumDist;
+        }
+        if (nTotDescDist > nCurrTotDescDistThreshold || nTotSumDist > nCurrTotColorDistThreshold)
+          goto failedcheck3ch;
+        if (nMinTotDescDist > nTotDescDist)
+          nMinTotDescDist = nTotDescDist;
+        if (nMinTotSumDist > nTotSumDist)
+          nMinTotSumDist = nTotSumDist;
+        nGoodSamplesCount++;
+      failedcheck3ch:
+        nSampleIdx++;
+      }
+      const float fNormalizedLastDist = ((float)L1dist<3>(anLastColor, anCurrColor) / s_nColorMaxDataRange_3ch + (float)hdist<3>(anLastIntraDesc, anCurrIntraDesc) / s_nDescMaxDataRange_3ch) / 2;
+      *pfCurrMeanLastDist = (*pfCurrMeanLastDist)*(1.0f - fRollAvgFactor_ST) + fNormalizedLastDist*fRollAvgFactor_ST;
+      if (nGoodSamplesCount < m_nRequiredBGSamples) {
+        // == foreground
+        const float fNormalizedMinDist = std::min(1.0f, ((float)nMinTotSumDist / s_nColorMaxDataRange_3ch + (float)nMinTotDescDist / s_nDescMaxDataRange_3ch) / 2 + (float)(m_nRequiredBGSamples - nGoodSamplesCount) / m_nRequiredBGSamples);
+        *pfCurrMeanMinDist_LT = (*pfCurrMeanMinDist_LT)*(1.0f - fRollAvgFactor_LT) + fNormalizedMinDist*fRollAvgFactor_LT;
+        *pfCurrMeanMinDist_ST = (*pfCurrMeanMinDist_ST)*(1.0f - fRollAvgFactor_ST) + fNormalizedMinDist*fRollAvgFactor_ST;
+        *pfCurrMeanRawSegmRes_LT = (*pfCurrMeanRawSegmRes_LT)*(1.0f - fRollAvgFactor_LT) + fRollAvgFactor_LT;
+        *pfCurrMeanRawSegmRes_ST = (*pfCurrMeanRawSegmRes_ST)*(1.0f - fRollAvgFactor_ST) + fRollAvgFactor_ST;
+        oCurrFGMask.data[nPxIter] = UCHAR_MAX;
+        if (m_nModelResetCooldown && (rand() % (size_t)FEEDBACK_T_LOWER) == 0) {
+          const size_t s_rand = rand() % m_nBGSamples;
+          for (size_t c = 0; c < 3; ++c) {
+            *((ushort*)(m_voBGDescSamples[s_rand].data + nDescIterRGB + 2 * c)) = anCurrIntraDesc[c];
+            *(m_voBGColorSamples[s_rand].data + nPxIterRGB + c) = anCurrColor[c];
+          }
+        }
+      }
+      else {
+        // == background
+        const float fNormalizedMinDist = ((float)nMinTotSumDist / s_nColorMaxDataRange_3ch + (float)nMinTotDescDist / s_nDescMaxDataRange_3ch) / 2;
+        *pfCurrMeanMinDist_LT = (*pfCurrMeanMinDist_LT)*(1.0f - fRollAvgFactor_LT) + fNormalizedMinDist*fRollAvgFactor_LT;
+        *pfCurrMeanMinDist_ST = (*pfCurrMeanMinDist_ST)*(1.0f - fRollAvgFactor_ST) + fNormalizedMinDist*fRollAvgFactor_ST;
+        *pfCurrMeanRawSegmRes_LT = (*pfCurrMeanRawSegmRes_LT)*(1.0f - fRollAvgFactor_LT);
+        *pfCurrMeanRawSegmRes_ST = (*pfCurrMeanRawSegmRes_ST)*(1.0f - fRollAvgFactor_ST);
+        const size_t nLearningRate = learningRateOverride > 0 ? (size_t)ceil(learningRateOverride) : (size_t)ceil(*pfCurrLearningRate);
+        if ((rand() % nLearningRate) == 0) {
+          const size_t s_rand = rand() % m_nBGSamples;
+          for (size_t c = 0; c < 3; ++c) {
+            *((ushort*)(m_voBGDescSamples[s_rand].data + nDescIterRGB + 2 * c)) = anCurrIntraDesc[c];
+            *(m_voBGColorSamples[s_rand].data + nPxIterRGB + c) = anCurrColor[c];
+          }
+        }
+        int nSampleImgCoord_Y, nSampleImgCoord_X;
+        const bool bCurrUsing3x3Spread = m_bUse3x3Spread && !m_oUnstableRegionMask.data[nPxIter];
+        if (bCurrUsing3x3Spread)
+          getRandNeighborPosition_3x3(nSampleImgCoord_X, nSampleImgCoord_Y, nCurrImgCoord_X, nCurrImgCoord_Y, LBSP::PATCH_SIZE / 2, m_oImgSize);
+        else
+          getRandNeighborPosition_5x5(nSampleImgCoord_X, nSampleImgCoord_Y, nCurrImgCoord_X, nCurrImgCoord_Y, LBSP::PATCH_SIZE / 2, m_oImgSize);
+        const size_t n_rand = rand();
+        const size_t idx_rand_uchar = m_oImgSize.width*nSampleImgCoord_Y + nSampleImgCoord_X;
+        const size_t idx_rand_flt32 = idx_rand_uchar * 4;
+        const float fRandMeanLastDist = *((float*)(m_oMeanLastDistFrame.data + idx_rand_flt32));
+        const float fRandMeanRawSegmRes = *((float*)(m_oMeanRawSegmResFrame_ST.data + idx_rand_flt32));
+        if ((n_rand % (bCurrUsing3x3Spread ? nLearningRate : (nLearningRate / 2 + 1))) == 0
+          || (fRandMeanRawSegmRes > GHOSTDET_S_MIN && fRandMeanLastDist < GHOSTDET_D_MAX && (n_rand % ((size_t)m_fCurrLearningRateLowerCap)) == 0)) {
+          const size_t idx_rand_uchar_rgb = idx_rand_uchar * 3;
+          const size_t idx_rand_ushrt_rgb = idx_rand_uchar_rgb * 2;
+          const size_t s_rand = rand() % m_nBGSamples;
+          for (size_t c = 0; c < 3; ++c) {
+            *((ushort*)(m_voBGDescSamples[s_rand].data + idx_rand_ushrt_rgb + 2 * c)) = anCurrIntraDesc[c];
+            *(m_voBGColorSamples[s_rand].data + idx_rand_uchar_rgb + c) = anCurrColor[c];
+          }
+        }
+      }
+      if (m_oLastFGMask.data[nPxIter] || (std::min(*pfCurrMeanMinDist_LT, *pfCurrMeanMinDist_ST) < UNSTABLE_REG_RATIO_MIN && oCurrFGMask.data[nPxIter])) {
+        if ((*pfCurrLearningRate) < m_fCurrLearningRateUpperCap)
+          *pfCurrLearningRate += FEEDBACK_T_INCR / (std::max(*pfCurrMeanMinDist_LT, *pfCurrMeanMinDist_ST)*(*pfCurrVariationFactor));
+      }
+      else if ((*pfCurrLearningRate) > m_fCurrLearningRateLowerCap)
+        *pfCurrLearningRate -= FEEDBACK_T_DECR*(*pfCurrVariationFactor) / std::max(*pfCurrMeanMinDist_LT, *pfCurrMeanMinDist_ST);
+      if ((*pfCurrLearningRate) < m_fCurrLearningRateLowerCap)
+        *pfCurrLearningRate = m_fCurrLearningRateLowerCap;
+      else if ((*pfCurrLearningRate) > m_fCurrLearningRateUpperCap)
+        *pfCurrLearningRate = m_fCurrLearningRateUpperCap;
+      if (std::max(*pfCurrMeanMinDist_LT, *pfCurrMeanMinDist_ST) > UNSTABLE_REG_RATIO_MIN && m_oBlinksFrame.data[nPxIter])
+        (*pfCurrVariationFactor) += FEEDBACK_V_INCR;
+      else if ((*pfCurrVariationFactor) > FEEDBACK_V_DECR) {
+        (*pfCurrVariationFactor) -= m_oLastFGMask.data[nPxIter] ? FEEDBACK_V_DECR / 4 : m_oUnstableRegionMask.data[nPxIter] ? FEEDBACK_V_DECR / 2 : FEEDBACK_V_DECR;
+        if ((*pfCurrVariationFactor) < FEEDBACK_V_DECR)
+          (*pfCurrVariationFactor) = FEEDBACK_V_DECR;
+      }
+      if ((*pfCurrDistThresholdFactor) < std::pow(1.0f + std::min(*pfCurrMeanMinDist_LT, *pfCurrMeanMinDist_ST) * 2, 2))
+        (*pfCurrDistThresholdFactor) += FEEDBACK_R_VAR*(*pfCurrVariationFactor - FEEDBACK_V_DECR);
+      else {
+        (*pfCurrDistThresholdFactor) -= FEEDBACK_R_VAR / (*pfCurrVariationFactor);
+        if ((*pfCurrDistThresholdFactor) < 1.0f)
+          (*pfCurrDistThresholdFactor) = 1.0f;
+      }
+      if (popcount<3>(anCurrIntraDesc) >= 4)
+        ++nNonZeroDescCount;
+      for (size_t c = 0; c < 3; ++c) {
+        anLastIntraDesc[c] = anCurrIntraDesc[c];
+        anLastColor[c] = anCurrColor[c];
+      }
+    }
+  }
+#if DISPLAY_SUBSENSE_DEBUG_INFO
+  std::cout << std::endl;
+  cv::Point dbgpt(nDebugCoordX, nDebugCoordY);
+  cv::Mat oMeanMinDistFrameNormalized; m_oMeanMinDistFrame_ST.copyTo(oMeanMinDistFrameNormalized);
+  cv::circle(oMeanMinDistFrameNormalized, dbgpt, 5, cv::Scalar(1.0f));
+  cv::resize(oMeanMinDistFrameNormalized, oMeanMinDistFrameNormalized, DEFAULT_FRAME_SIZE);
+  cv::imshow("d_min(x)", oMeanMinDistFrameNormalized);
+  std::cout << std::fixed << std::setprecision(5) << "  d_min(" << dbgpt << ") = " << m_oMeanMinDistFrame_ST.at<float>(dbgpt) << std::endl;
+  cv::Mat oMeanLastDistFrameNormalized; m_oMeanLastDistFrame.copyTo(oMeanLastDistFrameNormalized);
+  cv::circle(oMeanLastDistFrameNormalized, dbgpt, 5, cv::Scalar(1.0f));
+  cv::resize(oMeanLastDistFrameNormalized, oMeanLastDistFrameNormalized, DEFAULT_FRAME_SIZE);
+  cv::imshow("d_last(x)", oMeanLastDistFrameNormalized);
+  std::cout << std::fixed << std::setprecision(5) << " d_last(" << dbgpt << ") = " << m_oMeanLastDistFrame.at<float>(dbgpt) << std::endl;
+  cv::Mat oMeanRawSegmResFrameNormalized; m_oMeanRawSegmResFrame_ST.copyTo(oMeanRawSegmResFrameNormalized);
+  cv::circle(oMeanRawSegmResFrameNormalized, dbgpt, 5, cv::Scalar(1.0f));
+  cv::resize(oMeanRawSegmResFrameNormalized, oMeanRawSegmResFrameNormalized, DEFAULT_FRAME_SIZE);
+  cv::imshow("s_avg(x)", oMeanRawSegmResFrameNormalized);
+  std::cout << std::fixed << std::setprecision(5) << "  s_avg(" << dbgpt << ") = " << m_oMeanRawSegmResFrame_ST.at<float>(dbgpt) << std::endl;
+  cv::Mat oMeanFinalSegmResFrameNormalized; m_oMeanFinalSegmResFrame_ST.copyTo(oMeanFinalSegmResFrameNormalized);
+  cv::circle(oMeanFinalSegmResFrameNormalized, dbgpt, 5, cv::Scalar(1.0f));
+  cv::resize(oMeanFinalSegmResFrameNormalized, oMeanFinalSegmResFrameNormalized, DEFAULT_FRAME_SIZE);
+  cv::imshow("z_avg(x)", oMeanFinalSegmResFrameNormalized);
+  std::cout << std::fixed << std::setprecision(5) << "  z_avg(" << dbgpt << ") = " << m_oMeanFinalSegmResFrame_ST.at<float>(dbgpt) << std::endl;
+  cv::Mat oDistThresholdFrameNormalized; m_oDistThresholdFrame.convertTo(oDistThresholdFrameNormalized, CV_32FC1, 0.25f, -0.25f);
+  cv::circle(oDistThresholdFrameNormalized, dbgpt, 5, cv::Scalar(1.0f));
+  cv::resize(oDistThresholdFrameNormalized, oDistThresholdFrameNormalized, DEFAULT_FRAME_SIZE);
+  cv::imshow("r(x)", oDistThresholdFrameNormalized);
+  std::cout << std::fixed << std::setprecision(5) << "      r(" << dbgpt << ") = " << m_oDistThresholdFrame.at<float>(dbgpt) << std::endl;
+  cv::Mat oVariationModulatorFrameNormalized; cv::normalize(m_oVariationModulatorFrame, oVariationModulatorFrameNormalized, 0, 255, cv::NORM_MINMAX, CV_8UC1);
+  cv::circle(oVariationModulatorFrameNormalized, dbgpt, 5, cv::Scalar(255));
+  cv::resize(oVariationModulatorFrameNormalized, oVariationModulatorFrameNormalized, DEFAULT_FRAME_SIZE);
+  cv::imshow("v(x)", oVariationModulatorFrameNormalized);
+  std::cout << std::fixed << std::setprecision(5) << "      v(" << dbgpt << ") = " << m_oVariationModulatorFrame.at<float>(dbgpt) << std::endl;
+  cv::Mat oUpdateRateFrameNormalized; m_oUpdateRateFrame.convertTo(oUpdateRateFrameNormalized, CV_32FC1, 1.0f / FEEDBACK_T_UPPER, -FEEDBACK_T_LOWER / FEEDBACK_T_UPPER);
+  cv::circle(oUpdateRateFrameNormalized, dbgpt, 5, cv::Scalar(1.0f));
+  cv::resize(oUpdateRateFrameNormalized, oUpdateRateFrameNormalized, DEFAULT_FRAME_SIZE);
+  cv::imshow("t(x)", oUpdateRateFrameNormalized);
+  std::cout << std::fixed << std::setprecision(5) << "      t(" << dbgpt << ") = " << m_oUpdateRateFrame.at<float>(dbgpt) << std::endl;
+#endif //DISPLAY_SUBSENSE_DEBUG_INFO
+  cv::bitwise_xor(oCurrFGMask, m_oLastRawFGMask, m_oCurrRawFGBlinkMask);
+  cv::bitwise_or(m_oCurrRawFGBlinkMask, m_oLastRawFGBlinkMask, m_oBlinksFrame);
+  m_oCurrRawFGBlinkMask.copyTo(m_oLastRawFGBlinkMask);
+  oCurrFGMask.copyTo(m_oLastRawFGMask);
+  cv::morphologyEx(oCurrFGMask, m_oFGMask_PreFlood, cv::MORPH_CLOSE, cv::Mat());
+  m_oFGMask_PreFlood.copyTo(m_oFGMask_FloodedHoles);
+  cv::floodFill(m_oFGMask_FloodedHoles, cv::Point(0, 0), UCHAR_MAX);
+  cv::bitwise_not(m_oFGMask_FloodedHoles, m_oFGMask_FloodedHoles);
+  cv::erode(m_oFGMask_PreFlood, m_oFGMask_PreFlood, cv::Mat(), cv::Point(-1, -1), 3);
+  cv::bitwise_or(oCurrFGMask, m_oFGMask_FloodedHoles, oCurrFGMask);
+  cv::bitwise_or(oCurrFGMask, m_oFGMask_PreFlood, oCurrFGMask);
+  cv::medianBlur(oCurrFGMask, m_oLastFGMask, m_nMedianBlurKernelSize);
+  cv::dilate(m_oLastFGMask, m_oLastFGMask_dilated, cv::Mat(), cv::Point(-1, -1), 3);
+  cv::bitwise_and(m_oBlinksFrame, m_oLastFGMask_dilated_inverted, m_oBlinksFrame);
+  cv::bitwise_not(m_oLastFGMask_dilated, m_oLastFGMask_dilated_inverted);
+  cv::bitwise_and(m_oBlinksFrame, m_oLastFGMask_dilated_inverted, m_oBlinksFrame);
+  m_oLastFGMask.copyTo(oCurrFGMask);
+  cv::addWeighted(m_oMeanFinalSegmResFrame_LT, (1.0f - fRollAvgFactor_LT), m_oLastFGMask, (1.0 / UCHAR_MAX)*fRollAvgFactor_LT, 0, m_oMeanFinalSegmResFrame_LT, CV_32F);
+  cv::addWeighted(m_oMeanFinalSegmResFrame_ST, (1.0f - fRollAvgFactor_ST), m_oLastFGMask, (1.0 / UCHAR_MAX)*fRollAvgFactor_ST, 0, m_oMeanFinalSegmResFrame_ST, CV_32F);
+  const float fCurrNonZeroDescRatio = (float)nNonZeroDescCount / m_nTotRelevantPxCount;
+  if (fCurrNonZeroDescRatio < LBSPDESC_NONZERO_RATIO_MIN && m_fLastNonZeroDescRatio < LBSPDESC_NONZERO_RATIO_MIN) {
+    for (size_t t = 0; t <= UCHAR_MAX; ++t)
+      if (m_anLBSPThreshold_8bitLUT[t] > cv::saturate_cast<uchar>(m_nLBSPThresholdOffset + ceil(t*m_fRelLBSPThreshold / 4)))
+        --m_anLBSPThreshold_8bitLUT[t];
+  }
+  else if (fCurrNonZeroDescRatio > LBSPDESC_NONZERO_RATIO_MAX && m_fLastNonZeroDescRatio > LBSPDESC_NONZERO_RATIO_MAX) {
+    for (size_t t = 0; t <= UCHAR_MAX; ++t)
+      if (m_anLBSPThreshold_8bitLUT[t] < cv::saturate_cast<uchar>(m_nLBSPThresholdOffset + UCHAR_MAX*m_fRelLBSPThreshold))
+        ++m_anLBSPThreshold_8bitLUT[t];
+  }
+  m_fLastNonZeroDescRatio = fCurrNonZeroDescRatio;
+  if (m_bLearningRateScalingEnabled) {
+    cv::resize(oInputImg, m_oDownSampledFrame_MotionAnalysis, m_oDownSampledFrameSize, 0, 0, cv::INTER_AREA);
+    cv::accumulateWeighted(m_oDownSampledFrame_MotionAnalysis, m_oMeanDownSampledLastDistFrame_LT, fRollAvgFactor_LT);
+    cv::accumulateWeighted(m_oDownSampledFrame_MotionAnalysis, m_oMeanDownSampledLastDistFrame_ST, fRollAvgFactor_ST);
+    size_t nTotColorDiff = 0;
+    for (int i = 0; i < m_oMeanDownSampledLastDistFrame_ST.rows; ++i) {
+      const size_t idx1 = m_oMeanDownSampledLastDistFrame_ST.step.p[0] * i;
+      for (int j = 0; j < m_oMeanDownSampledLastDistFrame_ST.cols; ++j) {
+        const size_t idx2 = idx1 + m_oMeanDownSampledLastDistFrame_ST.step.p[1] * j;
+        nTotColorDiff += (m_nImgChannels == 1) ?
+          (size_t)fabs((*(float*)(m_oMeanDownSampledLastDistFrame_ST.data + idx2)) - (*(float*)(m_oMeanDownSampledLastDistFrame_LT.data + idx2))) / 2
+          :  //(m_nImgChannels==3)
+          std::max((size_t)fabs((*(float*)(m_oMeanDownSampledLastDistFrame_ST.data + idx2)) - (*(float*)(m_oMeanDownSampledLastDistFrame_LT.data + idx2))),
+            std::max((size_t)fabs((*(float*)(m_oMeanDownSampledLastDistFrame_ST.data + idx2 + 4)) - (*(float*)(m_oMeanDownSampledLastDistFrame_LT.data + idx2 + 4))),
+            (size_t)fabs((*(float*)(m_oMeanDownSampledLastDistFrame_ST.data + idx2 + 8)) - (*(float*)(m_oMeanDownSampledLastDistFrame_LT.data + idx2 + 8)))));
+      }
+    }
+    const float fCurrColorDiffRatio = (float)nTotColorDiff / (m_oMeanDownSampledLastDistFrame_ST.rows*m_oMeanDownSampledLastDistFrame_ST.cols);
+    if (m_bAutoModelResetEnabled) {
+      if (m_nFramesSinceLastReset > 1000)
+        m_bAutoModelResetEnabled = false;
+      else if (fCurrColorDiffRatio >= FRAMELEVEL_MIN_COLOR_DIFF_THRESHOLD && m_nModelResetCooldown == 0) {
+        m_nFramesSinceLastReset = 0;
+        refreshModel(0.1f); // reset 10% of the bg model
+        m_nModelResetCooldown = m_nSamplesForMovingAvgs / 4;
+        m_oUpdateRateFrame = cv::Scalar(1.0f);
+      }
+      else
+        ++m_nFramesSinceLastReset;
+    }
+    else if (fCurrColorDiffRatio >= FRAMELEVEL_MIN_COLOR_DIFF_THRESHOLD * 2) {
+      m_nFramesSinceLastReset = 0;
+      m_bAutoModelResetEnabled = true;
+    }
+    if (fCurrColorDiffRatio >= FRAMELEVEL_MIN_COLOR_DIFF_THRESHOLD / 2) {
+      m_fCurrLearningRateLowerCap = (float)std::max((int)FEEDBACK_T_LOWER >> (int)(fCurrColorDiffRatio / 2), 1);
+      m_fCurrLearningRateUpperCap = (float)std::max((int)FEEDBACK_T_UPPER >> (int)(fCurrColorDiffRatio / 2), 1);
+    }
+    else {
+      m_fCurrLearningRateLowerCap = FEEDBACK_T_LOWER;
+      m_fCurrLearningRateUpperCap = FEEDBACK_T_UPPER;
+    }
+    if (m_nModelResetCooldown > 0)
+      --m_nModelResetCooldown;
+  }
+}
+
+void BackgroundSubtractorSuBSENSE::getBackgroundImage(cv::OutputArray backgroundImage) const {
+  CV_Assert(m_bInitialized);
+  cv::Mat oAvgBGImg = cv::Mat::zeros(m_oImgSize, CV_32FC((int)m_nImgChannels));
+  for (size_t s = 0; s < m_nBGSamples; ++s) {
+    for (int y = 0; y < m_oImgSize.height; ++y) {
+      for (int x = 0; x < m_oImgSize.width; ++x) {
+        const size_t idx_nimg = m_voBGColorSamples[s].step.p[0] * y + m_voBGColorSamples[s].step.p[1] * x;
+        const size_t nFloatIter = idx_nimg * 4;
+        float* oAvgBgImgPtr = (float*)(oAvgBGImg.data + nFloatIter);
+        const uchar* const oBGImgPtr = m_voBGColorSamples[s].data + idx_nimg;
+        for (size_t c = 0; c < m_nImgChannels; ++c)
+          oAvgBgImgPtr[c] += ((float)oBGImgPtr[c]) / m_nBGSamples;
+      }
+    }
+  }
+  oAvgBGImg.convertTo(backgroundImage, CV_8U);
+}
+
+void BackgroundSubtractorSuBSENSE::getBackgroundDescriptorsImage(cv::OutputArray backgroundDescImage) const {
+  CV_Assert(LBSP::DESC_SIZE == 2);
+  CV_Assert(m_bInitialized);
+  cv::Mat oAvgBGDesc = cv::Mat::zeros(m_oImgSize, CV_32FC((int)m_nImgChannels));
+  for (size_t n = 0; n < m_voBGDescSamples.size(); ++n) {
+    for (int y = 0; y < m_oImgSize.height; ++y) {
+      for (int x = 0; x < m_oImgSize.width; ++x) {
+        const size_t idx_ndesc = m_voBGDescSamples[n].step.p[0] * y + m_voBGDescSamples[n].step.p[1] * x;
+        const size_t nFloatIter = idx_ndesc * 2;
+        float* oAvgBgDescPtr = (float*)(oAvgBGDesc.data + nFloatIter);
+        const ushort* const oBGDescPtr = (ushort*)(m_voBGDescSamples[n].data + idx_ndesc);
+        for (size_t c = 0; c < m_nImgChannels; ++c)
+          oAvgBgDescPtr[c] += ((float)oBGDescPtr[c]) / m_voBGDescSamples.size();
+      }
+    }
+  }
+  oAvgBGDesc.convertTo(backgroundDescImage, CV_16U);
+}
diff --git a/package_bgs/LBSP/BackgroundSubtractorSuBSENSE.h b/package_bgs/LBSP/BackgroundSubtractorSuBSENSE.h
new file mode 100644
index 0000000000000000000000000000000000000000..9950ea429270007c4e6ee6c45b2d472668b7d2b0
--- /dev/null
+++ b/package_bgs/LBSP/BackgroundSubtractorSuBSENSE.h
@@ -0,0 +1,129 @@
+/*
+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
+
+#include "BackgroundSubtractorLBSP.h"
+
+//! defines the default value for BackgroundSubtractorLBSP::m_fRelLBSPThreshold
+#define BGSSUBSENSE_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD (0.333f)
+//! defines the default value for BackgroundSubtractorSuBSENSE::m_nDescDistThresholdOffset
+#define BGSSUBSENSE_DEFAULT_DESC_DIST_THRESHOLD_OFFSET (3)
+//! defines the default value for BackgroundSubtractorSuBSENSE::m_nMinColorDistThreshold
+#define BGSSUBSENSE_DEFAULT_MIN_COLOR_DIST_THRESHOLD (30)
+//! defines the default value for BackgroundSubtractorSuBSENSE::m_nBGSamples
+#define BGSSUBSENSE_DEFAULT_NB_BG_SAMPLES (50)
+//! defines the default value for BackgroundSubtractorSuBSENSE::m_nRequiredBGSamples
+#define BGSSUBSENSE_DEFAULT_REQUIRED_NB_BG_SAMPLES (2)
+//! defines the default value for BackgroundSubtractorSuBSENSE::m_nSamplesForMovingAvgs
+#define BGSSUBSENSE_DEFAULT_N_SAMPLES_FOR_MV_AVGS (100)
+
+/*!
+  Self-Balanced Sensitivity segmenTER (SuBSENSE) change detection algorithm.
+
+  Note: both grayscale and RGB/BGR images may be used with this extractor (parameters are adjusted automatically).
+  For optimal grayscale results, use CV_8UC1 frames instead of CV_8UC3.
+
+  For more details on the different parameters or on the algorithm itself, see P.-L. St-Charles et al.,
+  "Flexible Background Subtraction With Self-Balanced Local Sensitivity", in CVPRW 2014.
+
+  This algorithm is currently NOT thread-safe.
+ */
+class BackgroundSubtractorSuBSENSE : public BackgroundSubtractorLBSP {
+public:
+  //! full constructor
+  BackgroundSubtractorSuBSENSE(float fRelLBSPThreshold = BGSSUBSENSE_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD,
+    size_t nDescDistThresholdOffset = BGSSUBSENSE_DEFAULT_DESC_DIST_THRESHOLD_OFFSET,
+    size_t nMinColorDistThreshold = BGSSUBSENSE_DEFAULT_MIN_COLOR_DIST_THRESHOLD,
+    size_t nBGSamples = BGSSUBSENSE_DEFAULT_NB_BG_SAMPLES,
+    size_t nRequiredBGSamples = BGSSUBSENSE_DEFAULT_REQUIRED_NB_BG_SAMPLES,
+    size_t nSamplesForMovingAvgs = BGSSUBSENSE_DEFAULT_N_SAMPLES_FOR_MV_AVGS);
+  //! default destructor
+  virtual ~BackgroundSubtractorSuBSENSE();
+  //! (re)initiaization method; needs to be called before starting background subtraction
+  virtual void initialize(const cv::Mat& oInitImg, const cv::Mat& oROI);
+  //! refreshes all samples based on the last analyzed frame
+  virtual void refreshModel(float fSamplesRefreshFrac, bool bForceFGUpdate = false);
+  //! primary model update function; the learning param is used to override the internal learning thresholds (ignored when <= 0)
+  virtual void apply(cv::InputArray image, cv::OutputArray fgmask, double learningRateOverride = 0);
+  //! returns a copy of the latest reconstructed background image
+  void getBackgroundImage(cv::OutputArray backgroundImage) const;
+  //! returns a copy of the latest reconstructed background descriptors image
+  void getBackgroundDescriptorsImage(cv::OutputArray backgroundDescImage) const;
+
+protected:
+  //! absolute minimal color distance threshold ('R' or 'radius' in the original ViBe paper, used as the default/initial 'R(x)' value here)
+  const size_t m_nMinColorDistThreshold;
+  //! absolute descriptor distance threshold offset
+  const size_t m_nDescDistThresholdOffset;
+  //! number of different samples per pixel/block to be taken from input frames to build the background model (same as 'N' in ViBe/PBAS)
+  const size_t m_nBGSamples;
+  //! number of similar samples needed to consider the current pixel/block as 'background' (same as '#_min' in ViBe/PBAS)
+  const size_t m_nRequiredBGSamples;
+  //! number of samples to use to compute the learning rate of moving averages
+  const size_t m_nSamplesForMovingAvgs;
+  //! last calculated non-zero desc ratio
+  float m_fLastNonZeroDescRatio;
+  //! specifies whether Tmin/Tmax scaling is enabled or not
+  bool m_bLearningRateScalingEnabled;
+  //! current learning rate caps
+  float m_fCurrLearningRateLowerCap, m_fCurrLearningRateUpperCap;
+  //! current kernel size for median blur post-proc filtering
+  int m_nMedianBlurKernelSize;
+  //! specifies the px update spread range
+  bool m_bUse3x3Spread;
+  //! specifies the downsampled frame size used for cam motion analysis
+  cv::Size m_oDownSampledFrameSize;
+
+  //! background model pixel color intensity samples (equivalent to 'B(x)' in PBAS)
+  std::vector<cv::Mat> m_voBGColorSamples;
+  //! background model descriptors samples
+  std::vector<cv::Mat> m_voBGDescSamples;
+
+  //! per-pixel update rates ('T(x)' in PBAS, which contains pixel-level 'sigmas', as referred to in ViBe)
+  cv::Mat m_oUpdateRateFrame;
+  //! per-pixel distance thresholds (equivalent to 'R(x)' in PBAS, but used as a relative value to determine both intensity and descriptor variation thresholds)
+  cv::Mat m_oDistThresholdFrame;
+  //! per-pixel distance variation modulators ('v(x)', relative value used to modulate 'R(x)' and 'T(x)' variations)
+  cv::Mat m_oVariationModulatorFrame;
+  //! per-pixel mean distances between consecutive frames ('D_last(x)', used to detect ghosts and high variation regions in the sequence)
+  cv::Mat m_oMeanLastDistFrame;
+  //! per-pixel mean minimal distances from the model ('D_min(x)' in PBAS, used to control variation magnitude and direction of 'T(x)' and 'R(x)')
+  cv::Mat m_oMeanMinDistFrame_LT, m_oMeanMinDistFrame_ST;
+  //! per-pixel mean downsampled distances between consecutive frames (used to analyze camera movement and control max learning rates globally)
+  cv::Mat m_oMeanDownSampledLastDistFrame_LT, m_oMeanDownSampledLastDistFrame_ST;
+  //! per-pixel mean raw segmentation results (used to detect unstable segmentation regions)
+  cv::Mat m_oMeanRawSegmResFrame_LT, m_oMeanRawSegmResFrame_ST;
+  //! per-pixel mean raw segmentation results (used to detect unstable segmentation regions)
+  cv::Mat m_oMeanFinalSegmResFrame_LT, m_oMeanFinalSegmResFrame_ST;
+  //! a lookup map used to keep track of unstable regions (based on segm. noise & local dist. thresholds)
+  cv::Mat m_oUnstableRegionMask;
+  //! per-pixel blink detection map ('Z(x)')
+  cv::Mat m_oBlinksFrame;
+  //! pre-allocated matrix used to downsample the input frame when needed
+  cv::Mat m_oDownSampledFrame_MotionAnalysis;
+  //! the foreground mask generated by the method at [t-1] (without post-proc, used for blinking px detection)
+  cv::Mat m_oLastRawFGMask;
+
+  //! pre-allocated CV_8UC1 matrices used to speed up morph ops
+  cv::Mat m_oFGMask_PreFlood;
+  cv::Mat m_oFGMask_FloodedHoles;
+  cv::Mat m_oLastFGMask_dilated;
+  cv::Mat m_oLastFGMask_dilated_inverted;
+  cv::Mat m_oCurrRawFGBlinkMask;
+  cv::Mat m_oLastRawFGBlinkMask;
+};
+
diff --git a/package_bgs/LBSP/DistanceUtils.h b/package_bgs/LBSP/DistanceUtils.h
new file mode 100644
index 0000000000000000000000000000000000000000..9eabca4a79db6f5f83a2d54c9558370cde799115
--- /dev/null
+++ b/package_bgs/LBSP/DistanceUtils.h
@@ -0,0 +1,332 @@
+/*
+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
+
+#include <opencv2/core/types_c.h>
+
+//! computes the L1 distance between two integer values
+template<typename T> static inline typename std::enable_if<std::is_integral<T>::value,size_t>::type L1dist(T a, T b) {
+  return (size_t)abs((int)a-b);
+}
+
+//! computes the L1 distance between two float values
+template<typename T> static inline typename std::enable_if<std::is_floating_point<T>::value,float>::type L1dist(T a, T b) {
+  return fabs((float)a-(float)b);
+}
+
+//! computes the L1 distance between two generic arrays
+template<size_t nChannels, typename T> static inline auto L1dist(const T* a, const T* b) -> decltype(L1dist(*a,*b)) {
+  decltype(L1dist(*a,*b)) oResult = 0;
+  for(size_t c=0; c<nChannels; ++c)
+    oResult += L1dist(a[c],b[c]);
+  return oResult;
+}
+
+//! computes the L1 distance between two generic arrays
+template<size_t nChannels, typename T> static inline auto L1dist(const T* a, const T* b, size_t nElements, const uchar* m=NULL) -> decltype(L1dist<nChannels>(a,b)) {
+  decltype(L1dist<nChannels>(a,b)) oResult = 0;
+  size_t nTotElements = nElements*nChannels;
+  if(m) {
+    for(size_t n=0,i=0; n<nTotElements; n+=nChannels,++i)
+      if(m[i])
+        oResult += L1dist<nChannels>(a+n,b+n);
+  }
+  else {
+    for(size_t n=0; n<nTotElements; n+=nChannels)
+      oResult += L1dist<nChannels>(a+n,b+n);
+  }
+  return oResult;
+}
+
+//! computes the L1 distance between two generic arrays
+template<typename T> static inline auto L1dist(const T* a, const T* b, size_t nElements, size_t nChannels, const uchar* m=NULL) -> decltype(L1dist<3>(a,b,nElements,m)) {
+  CV_Assert(nChannels>0 && nChannels<=4);
+  switch(nChannels) {
+  case 1: return L1dist<1>(a,b,nElements,m);
+  case 2: return L1dist<2>(a,b,nElements,m);
+  case 3: return L1dist<3>(a,b,nElements,m);
+  case 4: return L1dist<4>(a,b,nElements,m);
+  default: return 0;
+  }
+}
+
+//! computes the L1 distance between two opencv vectors
+template<size_t nChannels, typename T> static inline auto L1dist_(const cv::Vec<T,nChannels>& a, const cv::Vec<T,nChannels>& b) -> decltype(L1dist<nChannels,T>((T*)(0),(T*)(0))) {
+  T a_array[nChannels], b_array[nChannels];
+  for(size_t c=0; c<nChannels; ++c) {
+    a_array[c] = a[(int)c];
+    b_array[c] = b[(int)c];
+  }
+  return L1dist<nChannels>(a_array,b_array);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+//! computes the squared L2 distance between two generic variables
+template<typename T> static inline auto L2sqrdist(T a, T b) -> decltype(L1dist(a,b)) {
+  auto oResult = L1dist(a,b);
+  return oResult*oResult;
+}
+
+//! computes the squared L2 distance between two generic arrays
+template<size_t nChannels, typename T> static inline auto L2sqrdist(const T* a, const T* b) -> decltype(L2sqrdist(*a,*b)) {
+  decltype(L2sqrdist(*a,*b)) oResult = 0;
+  for(size_t c=0; c<nChannels; ++c)
+    oResult += L2sqrdist(a[c],b[c]);
+  return oResult;
+}
+
+//! computes the squared L2 distance between two generic arrays
+template<size_t nChannels, typename T> static inline auto L2sqrdist(const T* a, const T* b, size_t nElements, const uchar* m=NULL) -> decltype(L2sqrdist<nChannels>(a,b)) {
+  decltype(L2sqrdist<nChannels>(a,b)) oResult = 0;
+  size_t nTotElements = nElements*nChannels;
+  if(m) {
+    for(size_t n=0,i=0; n<nTotElements; n+=nChannels,++i)
+      if(m[i])
+        oResult += L2sqrdist<nChannels>(a+n,b+n);
+  }
+  else {
+    for(size_t n=0; n<nTotElements; n+=nChannels)
+      oResult += L2sqrdist<nChannels>(a+n,b+n);
+  }
+  return oResult;
+}
+
+//! computes the squared L2 distance between two generic arrays
+template<typename T> static inline auto L2sqrdist(const T* a, const T* b, size_t nElements, size_t nChannels, const uchar* m=NULL) -> decltype(L2sqrdist<3>(a,b,nElements,m)) {
+  CV_Assert(nChannels>0 && nChannels<=4);
+  switch(nChannels) {
+  case 1: return L2sqrdist<1>(a,b,nElements,m);
+  case 2: return L2sqrdist<2>(a,b,nElements,m);
+  case 3: return L2sqrdist<3>(a,b,nElements,m);
+  case 4: return L2sqrdist<4>(a,b,nElements,m);
+  default: return 0;
+  }
+}
+
+//! computes the squared L2 distance between two opencv vectors
+template<size_t nChannels, typename T> static inline auto L2sqrdist_(const cv::Vec<T,nChannels>& a, const cv::Vec<T,nChannels>& b) -> decltype(L2sqrdist<nChannels,T>((T*)(0),(T*)(0))) {
+  T a_array[nChannels], b_array[nChannels];
+  for(size_t c=0; c<nChannels; ++c) {
+    a_array[c] = a[(int)c];
+    b_array[c] = b[(int)c];
+  }
+  return L2sqrdist<nChannels>(a_array,b_array);
+}
+
+//! computes the L2 distance between two generic arrays
+template<size_t nChannels, typename T> static inline float L2dist(const T* a, const T* b) {
+  decltype(L2sqrdist(*a,*b)) oResult = 0;
+  for(size_t c=0; c<nChannels; ++c)
+    oResult += L2sqrdist(a[c],b[c]);
+  return sqrt((float)oResult);
+}
+
+//! computes the L2 distance between two generic arrays
+template<size_t nChannels, typename T> static inline float L2dist(const T* a, const T* b, size_t nElements, const uchar* m=NULL) {
+  decltype(L2sqrdist<nChannels>(a,b)) oResult = 0;
+  size_t nTotElements = nElements*nChannels;
+  if(m) {
+    for(size_t n=0,i=0; n<nTotElements; n+=nChannels,++i)
+      if(m[i])
+        oResult += L2sqrdist<nChannels>(a+n,b+n);
+  }
+  else {
+    for(size_t n=0; n<nTotElements; n+=nChannels)
+      oResult += L2sqrdist<nChannels>(a+n,b+n);
+  }
+  return sqrt((float)oResult);
+}
+
+//! computes the squared L2 distance between two generic arrays
+template<typename T> static inline float L2dist(const T* a, const T* b, size_t nElements, size_t nChannels, const uchar* m=NULL) {
+  CV_Assert(nChannels>0 && nChannels<=4);
+  switch(nChannels) {
+  case 1: return L2dist<1>(a,b,nElements,m);
+  case 2: return L2dist<2>(a,b,nElements,m);
+  case 3: return L2dist<3>(a,b,nElements,m);
+  case 4: return L2dist<4>(a,b,nElements,m);
+  default: return 0;
+  }
+}
+
+//! computes the L2 distance between two opencv vectors
+template<size_t nChannels, typename T> static inline float L2dist_(const cv::Vec<T,nChannels>& a, const cv::Vec<T,nChannels>& b) {
+  T a_array[nChannels], b_array[nChannels];
+  for(size_t c=0; c<nChannels; ++c) {
+    a_array[c] = a[(int)c];
+    b_array[c] = b[(int)c];
+  }
+  return L2dist<nChannels>(a_array,b_array);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+//! computes the color distortion between two integer arrays
+template<size_t nChannels, typename T> static inline typename std::enable_if<std::is_integral<T>::value,size_t>::type cdist(const T* curr, const T* bg) {
+  static_assert(nChannels>1,"cdist: requires more than one channel");
+  size_t curr_sqr = 0;
+  bool bSkip = true;
+  for(size_t c=0; c<nChannels; ++c) {
+    curr_sqr += curr[c]*curr[c];
+    bSkip = bSkip&(bg[c]<=0);
+  }
+  if(bSkip)
+    return (size_t)sqrt((float)curr_sqr);
+  size_t bg_sqr = 0;
+  size_t mix = 0;
+  for(size_t c=0; c<nChannels; ++c) {
+    bg_sqr += bg[c]*bg[c];
+    mix += curr[c]*bg[c];
+  }
+  return (size_t)sqrt(curr_sqr-((float)(mix*mix)/bg_sqr));
+}
+
+//! computes the color distortion between two float arrays
+template<size_t nChannels, typename T> static inline typename std::enable_if<std::is_floating_point<T>::value,float>::type cdist(const T* curr, const T* bg) {
+  static_assert(nChannels>1,"cdist: requires more than one channel");
+  float curr_sqr = 0;
+  bool bSkip = true;
+  for(size_t c=0; c<nChannels; ++c) {
+    curr_sqr += (float)curr[c]*curr[c];
+    bSkip = bSkip&(bg[c]<=0);
+  }
+  if(bSkip)
+    return sqrt(curr_sqr);
+  float bg_sqr = 0;
+  float mix = 0;
+  for(size_t c=0; c<nChannels; ++c) {
+    bg_sqr += (float)bg[c]*bg[c];
+    mix += (float)curr[c]*bg[c];
+  }
+  return sqrt(curr_sqr-((mix*mix)/bg_sqr));
+}
+
+//! computes the color distortion between two generic arrays
+template<size_t nChannels, typename T> static inline auto cdist(const T* a, const T* b, size_t nElements, const uchar* m=NULL) -> decltype(cdist<nChannels>(a,b)) {
+  decltype(cdist<nChannels>(a,b)) oResult = 0;
+  size_t nTotElements = nElements*nChannels;
+  if(m) {
+    for(size_t n=0,i=0; n<nTotElements; n+=nChannels,++i)
+      if(m[i])
+        oResult += cdist<nChannels>(a+n,b+n);
+  }
+  else {
+    for(size_t n=0; n<nTotElements; n+=nChannels)
+      oResult += cdist<nChannels>(a+n,b+n);
+  }
+  return oResult;
+}
+
+//! computes the color distortion between two generic arrays
+template<typename T> static inline auto cdist(const T* a, const T* b, size_t nElements, size_t nChannels, const uchar* m=NULL) -> decltype(cdist<3>(a,b,nElements,m)) {
+  CV_Assert(nChannels>1 && nChannels<=4);
+  switch(nChannels) {
+  case 2: return cdist<2>(a,b,nElements,m);
+  case 3: return cdist<3>(a,b,nElements,m);
+  case 4: return cdist<4>(a,b,nElements,m);
+  default: return 0;
+  }
+}
+
+//! computes the color distortion between two opencv vectors
+template<size_t nChannels, typename T> static inline auto cdist_(const cv::Vec<T,nChannels>& a, const cv::Vec<T,nChannels>& b) -> decltype(cdist<nChannels,T>((T*)(0),(T*)(0))) {
+  T a_array[nChannels], b_array[nChannels];
+  for(size_t c=0; c<nChannels; ++c) {
+    a_array[c] = a[(int)c];
+    b_array[c] = b[(int)c];
+  }
+  return cdist<nChannels>(a_array,b_array);
+}
+
+//! computes a color distortion-distance mix using two generic distances
+template<typename T> static inline T cmixdist(T oL1Distance, T oCDistortion) {
+  return (oL1Distance/2+oCDistortion*4);
+}
+
+//! computes a color distoirtion-distance mix using two generic arrays
+template<size_t nChannels, typename T> static inline typename std::enable_if<std::is_integral<T>::value,size_t>::type cmixdist(const T* curr, const T* bg) {
+  return cmixdist(L1dist<nChannels>(curr,bg),cdist<nChannels>(curr,bg));
+}
+
+template<size_t nChannels, typename T> static inline typename std::enable_if<std::is_floating_point<T>::value,float>::type cmixdist(const T* curr, const T* bg) {
+  return cmixdist(L1dist<nChannels>(curr,bg),cdist<nChannels>(curr,bg));
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+//! popcount LUT for 8-bit vectors
+static const uchar popcount_LUT8[256] = {
+  0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+  1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+  1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+  2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+  1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+  2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+  2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+  3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+  1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+  2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+  2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+  3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+  2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+  3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+  3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+  4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
+};
+
+//! computes the population count of an N-byte vector using an 8-bit popcount LUT
+template<typename T> static inline size_t popcount(T x) {
+  size_t nBytes = sizeof(T);
+  size_t nResult = 0;
+  for(size_t l=0; l<nBytes; ++l)
+    nResult += popcount_LUT8[(uchar)(x>>l*8)];
+  return nResult;
+}
+
+//! computes the hamming distance between two N-byte vectors using an 8-bit popcount LUT
+template<typename T> static inline size_t hdist(T a, T b) {
+  return popcount(a^b);
+}
+
+//! computes the gradient magnitude distance between two N-byte vectors using an 8-bit popcount LUT
+template<typename T> static inline size_t gdist(T a, T b) {
+  return L1dist(popcount(a),popcount(b));
+}
+
+//! computes the population count of a (nChannels*N)-byte vector using an 8-bit popcount LUT
+template<size_t nChannels, typename T> static inline size_t popcount(const T* x) {
+  size_t nBytes = sizeof(T);
+  size_t nResult = 0;
+  for(size_t c=0; c<nChannels; ++c)
+    for(size_t l=0; l<nBytes; ++l)
+      nResult += popcount_LUT8[(uchar)(*(x+c)>>l*8)];
+  return nResult;
+}
+
+//! computes the hamming distance between two (nChannels*N)-byte vectors using an 8-bit popcount LUT
+template<size_t nChannels, typename T> static inline size_t hdist(const T* a, const T* b) {
+  T xor_array[nChannels];
+  for(size_t c=0; c<nChannels; ++c)
+    xor_array[c] = a[c]^b[c];
+  return popcount<nChannels>(xor_array);
+}
+
+//! computes the gradient magnitude distance between two (nChannels*N)-byte vectors using an 8-bit popcount LUT
+template<size_t nChannels, typename T> static inline size_t gdist(const T* a, const T* b) {
+  return L1dist(popcount<nChannels>(a),popcount<nChannels>(b));
+}
diff --git a/package_bgs/LBSP/LBSP.cpp b/package_bgs/LBSP/LBSP.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4ec17b973dfeaf4d4de076927831838399f4900c
--- /dev/null
+++ b/package_bgs/LBSP/LBSP.cpp
@@ -0,0 +1,334 @@
+/*
+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 "LBSP.h"
+
+LBSP::LBSP(size_t nThreshold)
+  : m_bOnlyUsingAbsThreshold(true)
+  , m_fRelThreshold(0) // unused
+  , m_nThreshold(nThreshold)
+  , m_oRefImage() {}
+
+LBSP::LBSP(float fRelThreshold, size_t nThresholdOffset)
+  : m_bOnlyUsingAbsThreshold(false)
+  , m_fRelThreshold(fRelThreshold)
+  , m_nThreshold(nThresholdOffset)
+  , m_oRefImage() {
+  CV_Assert(m_fRelThreshold >= 0);
+}
+
+LBSP::~LBSP() {}
+
+void LBSP::read(const cv::FileNode& /*fn*/) {
+  // ... = fn["..."];
+}
+
+void LBSP::write(cv::FileStorage& /*fs*/) const {
+  //fs << "..." << ...;
+}
+
+void LBSP::setReference(const cv::Mat& img) {
+  CV_DbgAssert(img.empty() || img.type() == CV_8UC1 || img.type() == CV_8UC3);
+  m_oRefImage = img;
+}
+
+int LBSP::descriptorSize() const {
+  return DESC_SIZE;
+}
+
+int LBSP::descriptorType() const {
+  return CV_16U;
+}
+
+bool LBSP::isUsingRelThreshold() const {
+  return !m_bOnlyUsingAbsThreshold;
+}
+
+float LBSP::getRelThreshold() const {
+  return m_fRelThreshold;
+}
+
+size_t LBSP::getAbsThreshold() const {
+  return m_nThreshold;
+}
+
+static inline void lbsp_computeImpl(const cv::Mat& oInputImg,
+  const cv::Mat& oRefImg,
+  const std::vector<cv::KeyPoint>& voKeyPoints,
+  cv::Mat& oDesc,
+  size_t _t) {
+  CV_DbgAssert(oRefImg.empty() || (oRefImg.size == oInputImg.size && oRefImg.type() == oInputImg.type()));
+  CV_DbgAssert(oInputImg.type() == CV_8UC1 || oInputImg.type() == CV_8UC3);
+  CV_DbgAssert(LBSP::DESC_SIZE == 2); // @@@ also relies on a constant desc size
+  const size_t nChannels = (size_t)oInputImg.channels();
+  const size_t _step_row = oInputImg.step.p[0];
+  const uchar* _data = oInputImg.data;
+  const uchar* _refdata = oRefImg.empty() ? oInputImg.data : oRefImg.data;
+  const size_t nKeyPoints = voKeyPoints.size();
+  if (nChannels == 1) {
+    oDesc.create((int)nKeyPoints, 1, CV_16UC1);
+    for (size_t k = 0; k < nKeyPoints; ++k) {
+      const int _x = (int)voKeyPoints[k].pt.x;
+      const int _y = (int)voKeyPoints[k].pt.y;
+      const uchar _ref = _refdata[_step_row*(_y)+_x];
+      ushort& _res = oDesc.at<ushort>((int)k);
+#include "LBSP_16bits_dbcross_1ch.i"
+    }
+  }
+  else { //nChannels==3
+    oDesc.create((int)nKeyPoints, 1, CV_16UC3);
+    for (size_t k = 0; k < nKeyPoints; ++k) {
+      const int _x = (int)voKeyPoints[k].pt.x;
+      const int _y = (int)voKeyPoints[k].pt.y;
+      const uchar* _ref = _refdata + _step_row*(_y)+3 * (_x);
+      ushort* _res = ((ushort*)(oDesc.data + oDesc.step.p[0] * k));
+#include "LBSP_16bits_dbcross_3ch1t.i"
+    }
+  }
+}
+
+static inline void lbsp_computeImpl(const cv::Mat& oInputImg,
+  const cv::Mat& oRefImg,
+  const std::vector<cv::KeyPoint>& voKeyPoints,
+  cv::Mat& oDesc,
+  float fThreshold,
+  size_t nThresholdOffset) {
+  CV_DbgAssert(oRefImg.empty() || (oRefImg.size == oInputImg.size && oRefImg.type() == oInputImg.type()));
+  CV_DbgAssert(oInputImg.type() == CV_8UC1 || oInputImg.type() == CV_8UC3);
+  CV_DbgAssert(LBSP::DESC_SIZE == 2); // @@@ also relies on a constant desc size
+  CV_DbgAssert(fThreshold >= 0);
+  const size_t nChannels = (size_t)oInputImg.channels();
+  const size_t _step_row = oInputImg.step.p[0];
+  const uchar* _data = oInputImg.data;
+  const uchar* _refdata = oRefImg.empty() ? oInputImg.data : oRefImg.data;
+  const size_t nKeyPoints = voKeyPoints.size();
+  if (nChannels == 1) {
+    oDesc.create((int)nKeyPoints, 1, CV_16UC1);
+    for (size_t k = 0; k < nKeyPoints; ++k) {
+      const int _x = (int)voKeyPoints[k].pt.x;
+      const int _y = (int)voKeyPoints[k].pt.y;
+      const uchar _ref = _refdata[_step_row*(_y)+_x];
+      ushort& _res = oDesc.at<ushort>((int)k);
+      const size_t _t = (size_t)(_ref*fThreshold) + nThresholdOffset;
+#include "LBSP_16bits_dbcross_1ch.i"
+    }
+  }
+  else { //nChannels==3
+    oDesc.create((int)nKeyPoints, 1, CV_16UC3);
+    for (size_t k = 0; k < nKeyPoints; ++k) {
+      const int _x = (int)voKeyPoints[k].pt.x;
+      const int _y = (int)voKeyPoints[k].pt.y;
+      const uchar* _ref = _refdata + _step_row*(_y)+3 * (_x);
+      ushort* _res = ((ushort*)(oDesc.data + oDesc.step.p[0] * k));
+      const size_t _t[3] = { (size_t)(_ref[0] * fThreshold) + nThresholdOffset,(size_t)(_ref[1] * fThreshold) + nThresholdOffset,(size_t)(_ref[2] * fThreshold) + nThresholdOffset };
+#include "LBSP_16bits_dbcross_3ch3t.i"
+    }
+  }
+}
+
+static inline void lbsp_computeImpl2(const cv::Mat& oInputImg,
+  const cv::Mat& oRefImg,
+  const std::vector<cv::KeyPoint>& voKeyPoints,
+  cv::Mat& oDesc,
+  size_t _t) {
+  CV_DbgAssert(oRefImg.empty() || (oRefImg.size == oInputImg.size && oRefImg.type() == oInputImg.type()));
+  CV_DbgAssert(oInputImg.type() == CV_8UC1 || oInputImg.type() == CV_8UC3);
+  CV_DbgAssert(LBSP::DESC_SIZE == 2); // @@@ also relies on a constant desc size
+  const size_t nChannels = (size_t)oInputImg.channels();
+  const size_t _step_row = oInputImg.step.p[0];
+  const uchar* _data = oInputImg.data;
+  const uchar* _refdata = oRefImg.empty() ? oInputImg.data : oRefImg.data;
+  const size_t nKeyPoints = voKeyPoints.size();
+  if (nChannels == 1) {
+    oDesc.create(oInputImg.size(), CV_16UC1);
+    for (size_t k = 0; k < nKeyPoints; ++k) {
+      const int _x = (int)voKeyPoints[k].pt.x;
+      const int _y = (int)voKeyPoints[k].pt.y;
+      const uchar _ref = _refdata[_step_row*(_y)+_x];
+      ushort& _res = oDesc.at<ushort>(_y, _x);
+#include "LBSP_16bits_dbcross_1ch.i"
+    }
+  }
+  else { //nChannels==3
+    oDesc.create(oInputImg.size(), CV_16UC3);
+    for (size_t k = 0; k < nKeyPoints; ++k) {
+      const int _x = (int)voKeyPoints[k].pt.x;
+      const int _y = (int)voKeyPoints[k].pt.y;
+      const uchar* _ref = _refdata + _step_row*(_y)+3 * (_x);
+      ushort* _res = ((ushort*)(oDesc.data + oDesc.step.p[0] * _y + oDesc.step.p[1] * _x));
+#include "LBSP_16bits_dbcross_3ch1t.i"
+    }
+  }
+}
+
+static inline void lbsp_computeImpl2(const cv::Mat& oInputImg,
+  const cv::Mat& oRefImg,
+  const std::vector<cv::KeyPoint>& voKeyPoints,
+  cv::Mat& oDesc,
+  float fThreshold,
+  size_t nThresholdOffset) {
+  CV_DbgAssert(oRefImg.empty() || (oRefImg.size == oInputImg.size && oRefImg.type() == oInputImg.type()));
+  CV_DbgAssert(oInputImg.type() == CV_8UC1 || oInputImg.type() == CV_8UC3);
+  CV_DbgAssert(LBSP::DESC_SIZE == 2); // @@@ also relies on a constant desc size
+  CV_DbgAssert(fThreshold >= 0);
+  const size_t nChannels = (size_t)oInputImg.channels();
+  const size_t _step_row = oInputImg.step.p[0];
+  const uchar* _data = oInputImg.data;
+  const uchar* _refdata = oRefImg.empty() ? oInputImg.data : oRefImg.data;
+  const size_t nKeyPoints = voKeyPoints.size();
+  if (nChannels == 1) {
+    oDesc.create(oInputImg.size(), CV_16UC1);
+    for (size_t k = 0; k < nKeyPoints; ++k) {
+      const int _x = (int)voKeyPoints[k].pt.x;
+      const int _y = (int)voKeyPoints[k].pt.y;
+      const uchar _ref = _refdata[_step_row*(_y)+_x];
+      ushort& _res = oDesc.at<ushort>(_y, _x);
+      const size_t _t = (size_t)(_ref*fThreshold) + nThresholdOffset;
+#include "LBSP_16bits_dbcross_1ch.i"
+    }
+  }
+  else { //nChannels==3
+    oDesc.create(oInputImg.size(), CV_16UC3);
+    for (size_t k = 0; k < nKeyPoints; ++k) {
+      const int _x = (int)voKeyPoints[k].pt.x;
+      const int _y = (int)voKeyPoints[k].pt.y;
+      const uchar* _ref = _refdata + _step_row*(_y)+3 * (_x);
+      ushort* _res = ((ushort*)(oDesc.data + oDesc.step.p[0] * _y + oDesc.step.p[1] * _x));
+      const size_t _t[3] = { (size_t)(_ref[0] * fThreshold) + nThresholdOffset,(size_t)(_ref[1] * fThreshold) + nThresholdOffset,(size_t)(_ref[2] * fThreshold) + nThresholdOffset };
+#include "LBSP_16bits_dbcross_3ch3t.i"
+    }
+  }
+}
+
+void LBSP::compute2(const cv::Mat& oImage, std::vector<cv::KeyPoint>& voKeypoints, cv::Mat& oDescriptors) const {
+  CV_Assert(!oImage.empty());
+  cv::KeyPointsFilter::runByImageBorder(voKeypoints, oImage.size(), PATCH_SIZE / 2);
+  cv::KeyPointsFilter::runByKeypointSize(voKeypoints, std::numeric_limits<float>::epsilon());
+  if (voKeypoints.empty()) {
+    oDescriptors.release();
+    return;
+  }
+  if (m_bOnlyUsingAbsThreshold)
+    lbsp_computeImpl2(oImage, m_oRefImage, voKeypoints, oDescriptors, m_nThreshold);
+  else
+    lbsp_computeImpl2(oImage, m_oRefImage, voKeypoints, oDescriptors, m_fRelThreshold, m_nThreshold);
+}
+
+void LBSP::compute2(const std::vector<cv::Mat>& voImageCollection, std::vector<std::vector<cv::KeyPoint> >& vvoPointCollection, std::vector<cv::Mat>& voDescCollection) const {
+  CV_Assert(voImageCollection.size() == vvoPointCollection.size());
+  voDescCollection.resize(voImageCollection.size());
+  for (size_t i = 0; i < voImageCollection.size(); i++)
+    compute2(voImageCollection[i], vvoPointCollection[i], voDescCollection[i]);
+}
+
+void LBSP::computeImpl(const cv::Mat& oImage, std::vector<cv::KeyPoint>& voKeypoints, cv::Mat& oDescriptors) const {
+  CV_Assert(!oImage.empty());
+  cv::KeyPointsFilter::runByImageBorder(voKeypoints, oImage.size(), PATCH_SIZE / 2);
+  cv::KeyPointsFilter::runByKeypointSize(voKeypoints, std::numeric_limits<float>::epsilon());
+  if (voKeypoints.empty()) {
+    oDescriptors.release();
+    return;
+  }
+  if (m_bOnlyUsingAbsThreshold)
+    lbsp_computeImpl(oImage, m_oRefImage, voKeypoints, oDescriptors, m_nThreshold);
+  else
+    lbsp_computeImpl(oImage, m_oRefImage, voKeypoints, oDescriptors, m_fRelThreshold, m_nThreshold);
+}
+
+void LBSP::reshapeDesc(cv::Size oSize, const std::vector<cv::KeyPoint>& voKeypoints, const cv::Mat& oDescriptors, cv::Mat& oOutput) {
+  CV_DbgAssert(!voKeypoints.empty());
+  CV_DbgAssert(!oDescriptors.empty() && oDescriptors.cols == 1);
+  CV_DbgAssert(oSize.width > 0 && oSize.height > 0);
+  CV_DbgAssert(DESC_SIZE == 2); // @@@ also relies on a constant desc size
+  CV_DbgAssert(oDescriptors.type() == CV_16UC1 || oDescriptors.type() == CV_16UC3);
+  const size_t nChannels = (size_t)oDescriptors.channels();
+  const size_t nKeyPoints = voKeypoints.size();
+  if (nChannels == 1) {
+    oOutput.create(oSize, CV_16UC1);
+    oOutput = cv::Scalar_<ushort>(0);
+    for (size_t k = 0; k < nKeyPoints; ++k)
+      oOutput.at<ushort>(voKeypoints[k].pt) = oDescriptors.at<ushort>((int)k);
+  }
+  else { //nChannels==3
+    oOutput.create(oSize, CV_16UC3);
+    oOutput = cv::Scalar_<ushort>(0, 0, 0);
+    for (size_t k = 0; k < nKeyPoints; ++k) {
+      ushort* output_ptr = (ushort*)(oOutput.data + oOutput.step.p[0] * (int)voKeypoints[k].pt.y);
+      const ushort* const desc_ptr = (ushort*)(oDescriptors.data + oDescriptors.step.p[0] * k);
+      const size_t idx = 3 * (int)voKeypoints[k].pt.x;
+      for (size_t n = 0; n < 3; ++n)
+        output_ptr[idx + n] = desc_ptr[n];
+    }
+  }
+}
+
+void LBSP::calcDescImgDiff(const cv::Mat& oDesc1, const cv::Mat& oDesc2, cv::Mat& oOutput, bool bForceMergeChannels) {
+  CV_DbgAssert(oDesc1.size() == oDesc2.size() && oDesc1.type() == oDesc2.type());
+  CV_DbgAssert(DESC_SIZE == 2); // @@@ also relies on a constant desc size
+  CV_DbgAssert(oDesc1.type() == CV_16UC1 || oDesc1.type() == CV_16UC3);
+  CV_DbgAssert(CV_MAT_DEPTH(oDesc1.type()) == CV_16U);
+  CV_DbgAssert(DESC_SIZE * 8 <= UCHAR_MAX);
+  CV_DbgAssert(oDesc1.step.p[0] == oDesc2.step.p[0] && oDesc1.step.p[1] == oDesc2.step.p[1]);
+  const float fScaleFactor = (float)UCHAR_MAX / (DESC_SIZE * 8);
+  const size_t nChannels = CV_MAT_CN(oDesc1.type());
+  const size_t _step_row = oDesc1.step.p[0];
+  if (nChannels == 1) {
+    oOutput.create(oDesc1.size(), CV_8UC1);
+    oOutput = cv::Scalar(0);
+    for (int i = 0; i < oDesc1.rows; ++i) {
+      const size_t idx = _step_row*i;
+      const ushort* const desc1_ptr = (ushort*)(oDesc1.data + idx);
+      const ushort* const desc2_ptr = (ushort*)(oDesc2.data + idx);
+      for (int j = 0; j < oDesc1.cols; ++j)
+        oOutput.at<uchar>(i, j) = (uchar)(fScaleFactor*hdist(desc1_ptr[j], desc2_ptr[j]));
+    }
+  }
+  else { //nChannels==3
+    if (bForceMergeChannels)
+      oOutput.create(oDesc1.size(), CV_8UC1);
+    else
+      oOutput.create(oDesc1.size(), CV_8UC3);
+    oOutput = cv::Scalar::all(0);
+    for (int i = 0; i < oDesc1.rows; ++i) {
+      const size_t idx = _step_row*i;
+      const ushort* const desc1_ptr = (ushort*)(oDesc1.data + idx);
+      const ushort* const desc2_ptr = (ushort*)(oDesc2.data + idx);
+      uchar* output_ptr = oOutput.data + oOutput.step.p[0] * i;
+      for (int j = 0; j < oDesc1.cols; ++j) {
+        for (size_t n = 0; n < 3; ++n) {
+          const size_t idx2 = 3 * j + n;
+          if (bForceMergeChannels)
+            output_ptr[j] += (uchar)((fScaleFactor*hdist(desc1_ptr[idx2], desc2_ptr[idx2])) / 3);
+          else
+            output_ptr[idx2] = (uchar)(fScaleFactor*hdist(desc1_ptr[idx2], desc2_ptr[idx2]));
+        }
+      }
+    }
+  }
+}
+
+void LBSP::validateKeyPoints(std::vector<cv::KeyPoint>& voKeypoints, cv::Size oImgSize) {
+  cv::KeyPointsFilter::runByImageBorder(voKeypoints, oImgSize, PATCH_SIZE / 2);
+}
+
+void LBSP::validateROI(cv::Mat& oROI) {
+  CV_Assert(!oROI.empty() && oROI.type() == CV_8UC1);
+  cv::Mat oROI_new(oROI.size(), CV_8UC1, cv::Scalar_<uchar>(0));
+  const size_t nBorderSize = PATCH_SIZE / 2;
+  const cv::Rect nROI_inner(nBorderSize, nBorderSize, oROI.cols - nBorderSize * 2, oROI.rows - nBorderSize * 2);
+  cv::Mat(oROI, nROI_inner).copyTo(cv::Mat(oROI_new, nROI_inner));
+  oROI = oROI_new;
+}
diff --git a/package_bgs/LBSP/LBSP.h b/package_bgs/LBSP/LBSP.h
new file mode 100644
index 0000000000000000000000000000000000000000..c908eaa068641ece3b1ec0f487e2f6b01fae5899
--- /dev/null
+++ b/package_bgs/LBSP/LBSP.h
@@ -0,0 +1,134 @@
+/*
+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
+
+#include <opencv2/core/core.hpp>
+#include <opencv2/imgproc/imgproc.hpp>
+#include <opencv2/features2d/features2d.hpp>
+#include "DistanceUtils.h"
+
+/*!
+  Local Binary Similarity Pattern (LBSP) feature extractor
+
+  Note 1: both grayscale and RGB/BGR images may be used with this extractor.
+  Note 2: using LBSP::compute2(...) is logically equivalent to using LBSP::compute(...) followed by LBSP::reshapeDesc(...).
+
+  For more details on the different parameters, see G.-A. Bilodeau et al, "Change Detection in Feature Space Using Local
+  Binary Similarity Patterns", in CRV 2013.
+
+  This algorithm is currently NOT thread-safe.
+ */
+class LBSP : public cv::DescriptorExtractor {
+public:
+  //! constructor 1, threshold = absolute intensity 'similarity' threshold used when computing comparisons
+  LBSP(size_t nThreshold);
+  //! constructor 2, threshold = relative intensity 'similarity' threshold used when computing comparisons
+  LBSP(float fRelThreshold, size_t nThresholdOffset = 0);
+  //! default destructor
+  virtual ~LBSP();
+  //! loads extractor params from the specified file node @@@@ not impl
+  virtual void read(const cv::FileNode&);
+  //! writes extractor params to the specified file storage @@@@ not impl
+  virtual void write(cv::FileStorage&) const;
+  //! sets the 'reference' image to be used for inter-frame comparisons (note: if no image is set or if the image is empty, the algorithm will default back to intra-frame comparisons)
+  virtual void setReference(const cv::Mat&);
+  //! returns the current descriptor size, in bytes
+  virtual int descriptorSize() const;
+  //! returns the current descriptor data type
+  virtual int descriptorType() const;
+  //! returns whether this extractor is using a relative threshold or not
+  virtual bool isUsingRelThreshold() const;
+  //! returns the current relative threshold used for comparisons (-1 = invalid/not used)
+  virtual float getRelThreshold() const;
+  //! returns the current absolute threshold used for comparisons (-1 = invalid/not used)
+  virtual size_t getAbsThreshold() const;
+
+  //! similar to DescriptorExtractor::compute(const cv::Mat& image, ...), but in this case, the descriptors matrix has the same shape as the input matrix (possibly slower, but the result can be displayed)
+  void compute2(const cv::Mat& oImage, std::vector<cv::KeyPoint>& voKeypoints, cv::Mat& oDescriptors) const;
+  //! batch version of LBSP::compute2(const cv::Mat& image, ...), also similar to DescriptorExtractor::compute(const std::vector<cv::Mat>& imageCollection, ...)
+  void compute2(const std::vector<cv::Mat>& voImageCollection, std::vector<std::vector<cv::KeyPoint> >& vvoPointCollection, std::vector<cv::Mat>& voDescCollection) const;
+
+  //! utility function, shortcut/lightweight/direct single-point LBSP computation function for extra flexibility (1-channel version)
+  inline static void computeGrayscaleDescriptor(const cv::Mat& oInputImg, const uchar _ref, const int _x, const int _y, const size_t _t, ushort& _res) {
+    CV_DbgAssert(!oInputImg.empty());
+    CV_DbgAssert(oInputImg.type() == CV_8UC1);
+    CV_DbgAssert(LBSP::DESC_SIZE == 2); // @@@ also relies on a constant desc size
+    CV_DbgAssert(_x >= (int)LBSP::PATCH_SIZE / 2 && _y >= (int)LBSP::PATCH_SIZE / 2);
+    CV_DbgAssert(_x < oInputImg.cols - (int)LBSP::PATCH_SIZE / 2 && _y < oInputImg.rows - (int)LBSP::PATCH_SIZE / 2);
+    const size_t _step_row = oInputImg.step.p[0];
+    const uchar* const _data = oInputImg.data;
+#include "LBSP_16bits_dbcross_1ch.i"
+  }
+
+  //! utility function, shortcut/lightweight/direct single-point LBSP computation function for extra flexibility (3-channels version)
+  inline static void computeRGBDescriptor(const cv::Mat& oInputImg, const uchar* const _ref, const int _x, const int _y, const size_t* const _t, ushort* _res) {
+    CV_DbgAssert(!oInputImg.empty());
+    CV_DbgAssert(oInputImg.type() == CV_8UC3);
+    CV_DbgAssert(LBSP::DESC_SIZE == 2); // @@@ also relies on a constant desc size
+    CV_DbgAssert(_x >= (int)LBSP::PATCH_SIZE / 2 && _y >= (int)LBSP::PATCH_SIZE / 2);
+    CV_DbgAssert(_x < oInputImg.cols - (int)LBSP::PATCH_SIZE / 2 && _y < oInputImg.rows - (int)LBSP::PATCH_SIZE / 2);
+    const size_t _step_row = oInputImg.step.p[0];
+    const uchar* const _data = oInputImg.data;
+#include "LBSP_16bits_dbcross_3ch3t.i"
+  }
+
+  //! utility function, shortcut/lightweight/direct single-point LBSP computation function for extra flexibility (3-channels version)
+  inline static void computeRGBDescriptor(const cv::Mat& oInputImg, const uchar* const _ref, const int _x, const int _y, const size_t _t, ushort* _res) {
+    CV_DbgAssert(!oInputImg.empty());
+    CV_DbgAssert(oInputImg.type() == CV_8UC3);
+    CV_DbgAssert(LBSP::DESC_SIZE == 2); // @@@ also relies on a constant desc size
+    CV_DbgAssert(_x >= (int)LBSP::PATCH_SIZE / 2 && _y >= (int)LBSP::PATCH_SIZE / 2);
+    CV_DbgAssert(_x < oInputImg.cols - (int)LBSP::PATCH_SIZE / 2 && _y < oInputImg.rows - (int)LBSP::PATCH_SIZE / 2);
+    const size_t _step_row = oInputImg.step.p[0];
+    const uchar* const _data = oInputImg.data;
+#include "LBSP_16bits_dbcross_3ch1t.i"
+  }
+
+  //! utility function, shortcut/lightweight/direct single-point LBSP computation function for extra flexibility (1-channel-RGB version)
+  inline static void computeSingleRGBDescriptor(const cv::Mat& oInputImg, const uchar _ref, const int _x, const int _y, const size_t _c, const size_t _t, ushort& _res) {
+    CV_DbgAssert(!oInputImg.empty());
+    CV_DbgAssert(oInputImg.type() == CV_8UC3 && _c < 3);
+    CV_DbgAssert(LBSP::DESC_SIZE == 2); // @@@ also relies on a constant desc size
+    CV_DbgAssert(_x >= (int)LBSP::PATCH_SIZE / 2 && _y >= (int)LBSP::PATCH_SIZE / 2);
+    CV_DbgAssert(_x < oInputImg.cols - (int)LBSP::PATCH_SIZE / 2 && _y < oInputImg.rows - (int)LBSP::PATCH_SIZE / 2);
+    const size_t _step_row = oInputImg.step.p[0];
+    const uchar* const _data = oInputImg.data;
+#include "LBSP_16bits_dbcross_s3ch.i"
+  }
+
+  //! utility function, used to reshape a descriptors matrix to its input image size via their keypoint locations
+  static void reshapeDesc(cv::Size oSize, const std::vector<cv::KeyPoint>& voKeypoints, const cv::Mat& oDescriptors, cv::Mat& oOutput);
+  //! utility function, used to illustrate the difference between two descriptor images
+  static void calcDescImgDiff(const cv::Mat& oDesc1, const cv::Mat& oDesc2, cv::Mat& oOutput, bool bForceMergeChannels = false);
+  //! utility function, used to filter out bad keypoints that would trigger out of bounds error because they're too close to the image border
+  static void validateKeyPoints(std::vector<cv::KeyPoint>& voKeypoints, cv::Size oImgSize);
+  //! utility function, used to filter out bad pixels in a ROI that would trigger out of bounds error because they're too close to the image border
+  static void validateROI(cv::Mat& oROI);
+  //! utility, specifies the pixel size of the pattern used (width and height)
+  static const size_t PATCH_SIZE = 5;
+  //! utility, specifies the number of bytes per descriptor (should be the same as calling 'descriptorSize()')
+  static const size_t DESC_SIZE = 2;
+
+protected:
+  //! classic 'compute' implementation, based on the regular DescriptorExtractor::computeImpl arguments & expected output
+  virtual void computeImpl(const cv::Mat& oImage, std::vector<cv::KeyPoint>& voKeypoints, cv::Mat& oDescriptors) const;
+
+  const bool m_bOnlyUsingAbsThreshold;
+  const float m_fRelThreshold;
+  const size_t m_nThreshold;
+  cv::Mat m_oRefImage;
+};
diff --git a/package_bgs/LBSP/LBSP_.cpp b/package_bgs/LBSP/LBSP_.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ff5c8e8abed8fd8e1a96a4ef1bfea3b91fe74119
--- /dev/null
+++ b/package_bgs/LBSP/LBSP_.cpp
@@ -0,0 +1,334 @@
+/*
+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 "LBSP_.h"
+
+LBSP_::LBSP_(size_t nThreshold)
+  : m_bOnlyUsingAbsThreshold(true)
+  , m_fRelThreshold(0) // unused
+  , m_nThreshold(nThreshold)
+  , m_oRefImage() {}
+
+LBSP_::LBSP_(float fRelThreshold, size_t nThresholdOffset)
+  : m_bOnlyUsingAbsThreshold(false)
+  , m_fRelThreshold(fRelThreshold)
+  , m_nThreshold(nThresholdOffset)
+  , m_oRefImage() {
+  CV_Assert(m_fRelThreshold >= 0);
+}
+
+LBSP_::~LBSP_() {}
+
+void LBSP_::read(const cv::FileNode& /*fn*/) {
+  // ... = fn["..."];
+}
+
+void LBSP_::write(cv::FileStorage& /*fs*/) const {
+  //fs << "..." << ...;
+}
+
+void LBSP_::setReference(const cv::Mat& img) {
+  CV_DbgAssert(img.empty() || img.type() == CV_8UC1 || img.type() == CV_8UC3);
+  m_oRefImage = img;
+}
+
+int LBSP_::descriptorSize() const {
+  return DESC_SIZE;
+}
+
+int LBSP_::descriptorType() const {
+  return CV_16U;
+}
+
+bool LBSP_::isUsingRelThreshold() const {
+  return !m_bOnlyUsingAbsThreshold;
+}
+
+float LBSP_::getRelThreshold() const {
+  return m_fRelThreshold;
+}
+
+size_t LBSP_::getAbsThreshold() const {
+  return m_nThreshold;
+}
+
+static inline void LBSP__computeImpl(const cv::Mat& oInputImg,
+  const cv::Mat& oRefImg,
+  const std::vector<cv::KeyPoint>& voKeyPoints,
+  cv::Mat& oDesc,
+  size_t _t) {
+  CV_DbgAssert(oRefImg.empty() || (oRefImg.size == oInputImg.size && oRefImg.type() == oInputImg.type()));
+  CV_DbgAssert(oInputImg.type() == CV_8UC1 || oInputImg.type() == CV_8UC3);
+  CV_DbgAssert(LBSP_::DESC_SIZE == 2); // @@@ also relies on a constant desc size
+  const size_t nChannels = (size_t)oInputImg.channels();
+  const size_t _step_row = oInputImg.step.p[0];
+  const uchar* _data = oInputImg.data;
+  const uchar* _refdata = oRefImg.empty() ? oInputImg.data : oRefImg.data;
+  const size_t nKeyPoints = voKeyPoints.size();
+  if (nChannels == 1) {
+    oDesc.create((int)nKeyPoints, 1, CV_16UC1);
+    for (size_t k = 0; k < nKeyPoints; ++k) {
+      const int _x = (int)voKeyPoints[k].pt.x;
+      const int _y = (int)voKeyPoints[k].pt.y;
+      const uchar _ref = _refdata[_step_row*(_y)+_x];
+      ushort& _res = oDesc.at<ushort>((int)k);
+#include "LBSP_16bits_dbcross_1ch.i"
+    }
+  }
+  else { //nChannels==3
+    oDesc.create((int)nKeyPoints, 1, CV_16UC3);
+    for (size_t k = 0; k < nKeyPoints; ++k) {
+      const int _x = (int)voKeyPoints[k].pt.x;
+      const int _y = (int)voKeyPoints[k].pt.y;
+      const uchar* _ref = _refdata + _step_row*(_y)+3 * (_x);
+      ushort* _res = ((ushort*)(oDesc.data + oDesc.step.p[0] * k));
+#include "LBSP_16bits_dbcross_3ch1t.i"
+    }
+  }
+}
+
+static inline void LBSP__computeImpl(const cv::Mat& oInputImg,
+  const cv::Mat& oRefImg,
+  const std::vector<cv::KeyPoint>& voKeyPoints,
+  cv::Mat& oDesc,
+  float fThreshold,
+  size_t nThresholdOffset) {
+  CV_DbgAssert(oRefImg.empty() || (oRefImg.size == oInputImg.size && oRefImg.type() == oInputImg.type()));
+  CV_DbgAssert(oInputImg.type() == CV_8UC1 || oInputImg.type() == CV_8UC3);
+  CV_DbgAssert(LBSP_::DESC_SIZE == 2); // @@@ also relies on a constant desc size
+  CV_DbgAssert(fThreshold >= 0);
+  const size_t nChannels = (size_t)oInputImg.channels();
+  const size_t _step_row = oInputImg.step.p[0];
+  const uchar* _data = oInputImg.data;
+  const uchar* _refdata = oRefImg.empty() ? oInputImg.data : oRefImg.data;
+  const size_t nKeyPoints = voKeyPoints.size();
+  if (nChannels == 1) {
+    oDesc.create((int)nKeyPoints, 1, CV_16UC1);
+    for (size_t k = 0; k < nKeyPoints; ++k) {
+      const int _x = (int)voKeyPoints[k].pt.x;
+      const int _y = (int)voKeyPoints[k].pt.y;
+      const uchar _ref = _refdata[_step_row*(_y)+_x];
+      ushort& _res = oDesc.at<ushort>((int)k);
+      const size_t _t = (size_t)(_ref*fThreshold) + nThresholdOffset;
+#include "LBSP_16bits_dbcross_1ch.i"
+    }
+  }
+  else { //nChannels==3
+    oDesc.create((int)nKeyPoints, 1, CV_16UC3);
+    for (size_t k = 0; k < nKeyPoints; ++k) {
+      const int _x = (int)voKeyPoints[k].pt.x;
+      const int _y = (int)voKeyPoints[k].pt.y;
+      const uchar* _ref = _refdata + _step_row*(_y)+3 * (_x);
+      ushort* _res = ((ushort*)(oDesc.data + oDesc.step.p[0] * k));
+      const size_t _t[3] = { (size_t)(_ref[0] * fThreshold) + nThresholdOffset,(size_t)(_ref[1] * fThreshold) + nThresholdOffset,(size_t)(_ref[2] * fThreshold) + nThresholdOffset };
+#include "LBSP_16bits_dbcross_3ch3t.i"
+    }
+  }
+}
+
+static inline void LBSP__computeImpl2(const cv::Mat& oInputImg,
+  const cv::Mat& oRefImg,
+  const std::vector<cv::KeyPoint>& voKeyPoints,
+  cv::Mat& oDesc,
+  size_t _t) {
+  CV_DbgAssert(oRefImg.empty() || (oRefImg.size == oInputImg.size && oRefImg.type() == oInputImg.type()));
+  CV_DbgAssert(oInputImg.type() == CV_8UC1 || oInputImg.type() == CV_8UC3);
+  CV_DbgAssert(LBSP_::DESC_SIZE == 2); // @@@ also relies on a constant desc size
+  const size_t nChannels = (size_t)oInputImg.channels();
+  const size_t _step_row = oInputImg.step.p[0];
+  const uchar* _data = oInputImg.data;
+  const uchar* _refdata = oRefImg.empty() ? oInputImg.data : oRefImg.data;
+  const size_t nKeyPoints = voKeyPoints.size();
+  if (nChannels == 1) {
+    oDesc.create(oInputImg.size(), CV_16UC1);
+    for (size_t k = 0; k < nKeyPoints; ++k) {
+      const int _x = (int)voKeyPoints[k].pt.x;
+      const int _y = (int)voKeyPoints[k].pt.y;
+      const uchar _ref = _refdata[_step_row*(_y)+_x];
+      ushort& _res = oDesc.at<ushort>(_y, _x);
+#include "LBSP_16bits_dbcross_1ch.i"
+    }
+  }
+  else { //nChannels==3
+    oDesc.create(oInputImg.size(), CV_16UC3);
+    for (size_t k = 0; k < nKeyPoints; ++k) {
+      const int _x = (int)voKeyPoints[k].pt.x;
+      const int _y = (int)voKeyPoints[k].pt.y;
+      const uchar* _ref = _refdata + _step_row*(_y)+3 * (_x);
+      ushort* _res = ((ushort*)(oDesc.data + oDesc.step.p[0] * _y + oDesc.step.p[1] * _x));
+#include "LBSP_16bits_dbcross_3ch1t.i"
+    }
+  }
+}
+
+static inline void LBSP__computeImpl2(const cv::Mat& oInputImg,
+  const cv::Mat& oRefImg,
+  const std::vector<cv::KeyPoint>& voKeyPoints,
+  cv::Mat& oDesc,
+  float fThreshold,
+  size_t nThresholdOffset) {
+  CV_DbgAssert(oRefImg.empty() || (oRefImg.size == oInputImg.size && oRefImg.type() == oInputImg.type()));
+  CV_DbgAssert(oInputImg.type() == CV_8UC1 || oInputImg.type() == CV_8UC3);
+  CV_DbgAssert(LBSP_::DESC_SIZE == 2); // @@@ also relies on a constant desc size
+  CV_DbgAssert(fThreshold >= 0);
+  const size_t nChannels = (size_t)oInputImg.channels();
+  const size_t _step_row = oInputImg.step.p[0];
+  const uchar* _data = oInputImg.data;
+  const uchar* _refdata = oRefImg.empty() ? oInputImg.data : oRefImg.data;
+  const size_t nKeyPoints = voKeyPoints.size();
+  if (nChannels == 1) {
+    oDesc.create(oInputImg.size(), CV_16UC1);
+    for (size_t k = 0; k < nKeyPoints; ++k) {
+      const int _x = (int)voKeyPoints[k].pt.x;
+      const int _y = (int)voKeyPoints[k].pt.y;
+      const uchar _ref = _refdata[_step_row*(_y)+_x];
+      ushort& _res = oDesc.at<ushort>(_y, _x);
+      const size_t _t = (size_t)(_ref*fThreshold) + nThresholdOffset;
+#include "LBSP_16bits_dbcross_1ch.i"
+    }
+  }
+  else { //nChannels==3
+    oDesc.create(oInputImg.size(), CV_16UC3);
+    for (size_t k = 0; k < nKeyPoints; ++k) {
+      const int _x = (int)voKeyPoints[k].pt.x;
+      const int _y = (int)voKeyPoints[k].pt.y;
+      const uchar* _ref = _refdata + _step_row*(_y)+3 * (_x);
+      ushort* _res = ((ushort*)(oDesc.data + oDesc.step.p[0] * _y + oDesc.step.p[1] * _x));
+      const size_t _t[3] = { (size_t)(_ref[0] * fThreshold) + nThresholdOffset,(size_t)(_ref[1] * fThreshold) + nThresholdOffset,(size_t)(_ref[2] * fThreshold) + nThresholdOffset };
+#include "LBSP_16bits_dbcross_3ch3t.i"
+    }
+  }
+}
+
+void LBSP_::compute2(const cv::Mat& oImage, std::vector<cv::KeyPoint>& voKeypoints, cv::Mat& oDescriptors) const {
+  CV_Assert(!oImage.empty());
+  cv::KeyPointsFilter::runByImageBorder(voKeypoints, oImage.size(), PATCH_SIZE / 2);
+  cv::KeyPointsFilter::runByKeypointSize(voKeypoints, std::numeric_limits<float>::epsilon());
+  if (voKeypoints.empty()) {
+    oDescriptors.release();
+    return;
+  }
+  if (m_bOnlyUsingAbsThreshold)
+    LBSP__computeImpl2(oImage, m_oRefImage, voKeypoints, oDescriptors, m_nThreshold);
+  else
+    LBSP__computeImpl2(oImage, m_oRefImage, voKeypoints, oDescriptors, m_fRelThreshold, m_nThreshold);
+}
+
+void LBSP_::compute2(const std::vector<cv::Mat>& voImageCollection, std::vector<std::vector<cv::KeyPoint> >& vvoPointCollection, std::vector<cv::Mat>& voDescCollection) const {
+  CV_Assert(voImageCollection.size() == vvoPointCollection.size());
+  voDescCollection.resize(voImageCollection.size());
+  for (size_t i = 0; i < voImageCollection.size(); i++)
+    compute2(voImageCollection[i], vvoPointCollection[i], voDescCollection[i]);
+}
+
+void LBSP_::computeImpl(const cv::Mat& oImage, std::vector<cv::KeyPoint>& voKeypoints, cv::Mat& oDescriptors) const {
+  CV_Assert(!oImage.empty());
+  cv::KeyPointsFilter::runByImageBorder(voKeypoints, oImage.size(), PATCH_SIZE / 2);
+  cv::KeyPointsFilter::runByKeypointSize(voKeypoints, std::numeric_limits<float>::epsilon());
+  if (voKeypoints.empty()) {
+    oDescriptors.release();
+    return;
+  }
+  if (m_bOnlyUsingAbsThreshold)
+    LBSP__computeImpl(oImage, m_oRefImage, voKeypoints, oDescriptors, m_nThreshold);
+  else
+    LBSP__computeImpl(oImage, m_oRefImage, voKeypoints, oDescriptors, m_fRelThreshold, m_nThreshold);
+}
+
+void LBSP_::reshapeDesc(cv::Size oSize, const std::vector<cv::KeyPoint>& voKeypoints, const cv::Mat& oDescriptors, cv::Mat& oOutput) {
+  CV_DbgAssert(!voKeypoints.empty());
+  CV_DbgAssert(!oDescriptors.empty() && oDescriptors.cols == 1);
+  CV_DbgAssert(oSize.width > 0 && oSize.height > 0);
+  CV_DbgAssert(DESC_SIZE == 2); // @@@ also relies on a constant desc size
+  CV_DbgAssert(oDescriptors.type() == CV_16UC1 || oDescriptors.type() == CV_16UC3);
+  const size_t nChannels = (size_t)oDescriptors.channels();
+  const size_t nKeyPoints = voKeypoints.size();
+  if (nChannels == 1) {
+    oOutput.create(oSize, CV_16UC1);
+    oOutput = cv::Scalar_<ushort>(0);
+    for (size_t k = 0; k < nKeyPoints; ++k)
+      oOutput.at<ushort>(voKeypoints[k].pt) = oDescriptors.at<ushort>((int)k);
+  }
+  else { //nChannels==3
+    oOutput.create(oSize, CV_16UC3);
+    oOutput = cv::Scalar_<ushort>(0, 0, 0);
+    for (size_t k = 0; k < nKeyPoints; ++k) {
+      ushort* output_ptr = (ushort*)(oOutput.data + oOutput.step.p[0] * (int)voKeypoints[k].pt.y);
+      const ushort* const desc_ptr = (ushort*)(oDescriptors.data + oDescriptors.step.p[0] * k);
+      const size_t idx = 3 * (int)voKeypoints[k].pt.x;
+      for (size_t n = 0; n < 3; ++n)
+        output_ptr[idx + n] = desc_ptr[n];
+    }
+  }
+}
+
+void LBSP_::calcDescImgDiff(const cv::Mat& oDesc1, const cv::Mat& oDesc2, cv::Mat& oOutput, bool bForceMergeChannels) {
+  CV_DbgAssert(oDesc1.size() == oDesc2.size() && oDesc1.type() == oDesc2.type());
+  CV_DbgAssert(DESC_SIZE == 2); // @@@ also relies on a constant desc size
+  CV_DbgAssert(oDesc1.type() == CV_16UC1 || oDesc1.type() == CV_16UC3);
+  CV_DbgAssert(CV_MAT_DEPTH(oDesc1.type()) == CV_16U);
+  CV_DbgAssert(DESC_SIZE * 8 <= UCHAR_MAX);
+  CV_DbgAssert(oDesc1.step.p[0] == oDesc2.step.p[0] && oDesc1.step.p[1] == oDesc2.step.p[1]);
+  const float fScaleFactor = (float)UCHAR_MAX / (DESC_SIZE * 8);
+  const size_t nChannels = CV_MAT_CN(oDesc1.type());
+  const size_t _step_row = oDesc1.step.p[0];
+  if (nChannels == 1) {
+    oOutput.create(oDesc1.size(), CV_8UC1);
+    oOutput = cv::Scalar(0);
+    for (int i = 0; i < oDesc1.rows; ++i) {
+      const size_t idx = _step_row*i;
+      const ushort* const desc1_ptr = (ushort*)(oDesc1.data + idx);
+      const ushort* const desc2_ptr = (ushort*)(oDesc2.data + idx);
+      for (int j = 0; j < oDesc1.cols; ++j)
+        oOutput.at<uchar>(i, j) = (uchar)(fScaleFactor*hdist(desc1_ptr[j], desc2_ptr[j]));
+    }
+  }
+  else { //nChannels==3
+    if (bForceMergeChannels)
+      oOutput.create(oDesc1.size(), CV_8UC1);
+    else
+      oOutput.create(oDesc1.size(), CV_8UC3);
+    oOutput = cv::Scalar::all(0);
+    for (int i = 0; i < oDesc1.rows; ++i) {
+      const size_t idx = _step_row*i;
+      const ushort* const desc1_ptr = (ushort*)(oDesc1.data + idx);
+      const ushort* const desc2_ptr = (ushort*)(oDesc2.data + idx);
+      uchar* output_ptr = oOutput.data + oOutput.step.p[0] * i;
+      for (int j = 0; j < oDesc1.cols; ++j) {
+        for (size_t n = 0; n < 3; ++n) {
+          const size_t idx2 = 3 * j + n;
+          if (bForceMergeChannels)
+            output_ptr[j] += (uchar)((fScaleFactor*hdist(desc1_ptr[idx2], desc2_ptr[idx2])) / 3);
+          else
+            output_ptr[idx2] = (uchar)(fScaleFactor*hdist(desc1_ptr[idx2], desc2_ptr[idx2]));
+        }
+      }
+    }
+  }
+}
+
+void LBSP_::validateKeyPoints(std::vector<cv::KeyPoint>& voKeypoints, cv::Size oImgSize) {
+  cv::KeyPointsFilter::runByImageBorder(voKeypoints, oImgSize, PATCH_SIZE / 2);
+}
+
+void LBSP_::validateROI(cv::Mat& oROI) {
+  CV_Assert(!oROI.empty() && oROI.type() == CV_8UC1);
+  cv::Mat oROI_new(oROI.size(), CV_8UC1, cv::Scalar_<uchar>(0));
+  const size_t nBorderSize = PATCH_SIZE / 2;
+  const cv::Rect nROI_inner(nBorderSize, nBorderSize, oROI.cols - nBorderSize * 2, oROI.rows - nBorderSize * 2);
+  cv::Mat(oROI, nROI_inner).copyTo(cv::Mat(oROI_new, nROI_inner));
+  oROI = oROI_new;
+}
diff --git a/package_bgs/LBSP/LBSP_.h b/package_bgs/LBSP/LBSP_.h
new file mode 100644
index 0000000000000000000000000000000000000000..819174a948ea1556f898f7804cacff30ac25d1b2
--- /dev/null
+++ b/package_bgs/LBSP/LBSP_.h
@@ -0,0 +1,134 @@
+/*
+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
+
+#include <opencv2/core/core.hpp>
+#include <opencv2/imgproc/imgproc.hpp>
+#include <opencv2/features2d/features2d.hpp>
+#include "DistanceUtils.h"
+
+/*!
+    Local Binary Similarity Pattern (LBSP) feature extractor
+
+    Note 1: both grayscale and RGB/BGR images may be used with this extractor.
+    Note 2: using LBSP_::compute2(...) is logically equivalent to using LBSP_::compute(...) followed by LBSP_::reshapeDesc(...).
+
+    For more details on the different parameters, see G.-A. Bilodeau et al, "Change Detection in Feature Space Using Local
+    Binary Similarity Patterns", in CRV 2013.
+
+    This algorithm is currently NOT thread-safe.
+ */
+class LBSP_ : public cv::Feature2D {
+public:
+  //! constructor 1, threshold = absolute intensity 'similarity' threshold used when computing comparisons
+  LBSP_(size_t nThreshold);
+  //! constructor 2, threshold = relative intensity 'similarity' threshold used when computing comparisons
+  LBSP_(float fRelThreshold, size_t nThresholdOffset = 0);
+  //! default destructor
+  virtual ~LBSP_();
+  //! loads extractor params from the specified file node @@@@ not impl
+  virtual void read(const cv::FileNode&);
+  //! writes extractor params to the specified file storage @@@@ not impl
+  virtual void write(cv::FileStorage&) const;
+  //! sets the 'reference' image to be used for inter-frame comparisons (note: if no image is set or if the image is empty, the algorithm will default back to intra-frame comparisons)
+  virtual void setReference(const cv::Mat&);
+  //! returns the current descriptor size, in bytes
+  virtual int descriptorSize() const;
+  //! returns the current descriptor data type
+  virtual int descriptorType() const;
+  //! returns whether this extractor is using a relative threshold or not
+  virtual bool isUsingRelThreshold() const;
+  //! returns the current relative threshold used for comparisons (-1 = invalid/not used)
+  virtual float getRelThreshold() const;
+  //! returns the current absolute threshold used for comparisons (-1 = invalid/not used)
+  virtual size_t getAbsThreshold() const;
+
+  //! similar to DescriptorExtractor::compute(const cv::Mat& image, ...), but in this case, the descriptors matrix has the same shape as the input matrix (possibly slower, but the result can be displayed)
+  void compute2(const cv::Mat& oImage, std::vector<cv::KeyPoint>& voKeypoints, cv::Mat& oDescriptors) const;
+  //! batch version of LBSP_::compute2(const cv::Mat& image, ...), also similar to DescriptorExtractor::compute(const std::vector<cv::Mat>& imageCollection, ...)
+  void compute2(const std::vector<cv::Mat>& voImageCollection, std::vector<std::vector<cv::KeyPoint> >& vvoPointCollection, std::vector<cv::Mat>& voDescCollection) const;
+
+  //! utility function, shortcut/lightweight/direct single-point LBSP computation function for extra flexibility (1-channel version)
+  inline static void computeGrayscaleDescriptor(const cv::Mat& oInputImg, const uchar _ref, const int _x, const int _y, const size_t _t, ushort& _res) {
+    CV_DbgAssert(!oInputImg.empty());
+    CV_DbgAssert(oInputImg.type() == CV_8UC1);
+    CV_DbgAssert(LBSP_::DESC_SIZE == 2); // @@@ also relies on a constant desc size
+    CV_DbgAssert(_x >= (int)LBSP_::PATCH_SIZE / 2 && _y >= (int)LBSP_::PATCH_SIZE / 2);
+    CV_DbgAssert(_x < oInputImg.cols - (int)LBSP_::PATCH_SIZE / 2 && _y < oInputImg.rows - (int)LBSP_::PATCH_SIZE / 2);
+    const size_t _step_row = oInputImg.step.p[0];
+    const uchar* const _data = oInputImg.data;
+#include "LBSP_16bits_dbcross_1ch.i"
+  }
+
+  //! utility function, shortcut/lightweight/direct single-point LBSP computation function for extra flexibility (3-channels version)
+  inline static void computeRGBDescriptor(const cv::Mat& oInputImg, const uchar* const _ref, const int _x, const int _y, const size_t* const _t, ushort* _res) {
+    CV_DbgAssert(!oInputImg.empty());
+    CV_DbgAssert(oInputImg.type() == CV_8UC3);
+    CV_DbgAssert(LBSP_::DESC_SIZE == 2); // @@@ also relies on a constant desc size
+    CV_DbgAssert(_x >= (int)LBSP_::PATCH_SIZE / 2 && _y >= (int)LBSP_::PATCH_SIZE / 2);
+    CV_DbgAssert(_x < oInputImg.cols - (int)LBSP_::PATCH_SIZE / 2 && _y < oInputImg.rows - (int)LBSP_::PATCH_SIZE / 2);
+    const size_t _step_row = oInputImg.step.p[0];
+    const uchar* const _data = oInputImg.data;
+#include "LBSP_16bits_dbcross_3ch3t.i"
+  }
+
+  //! utility function, shortcut/lightweight/direct single-point LBSP computation function for extra flexibility (3-channels version)
+  inline static void computeRGBDescriptor(const cv::Mat& oInputImg, const uchar* const _ref, const int _x, const int _y, const size_t _t, ushort* _res) {
+    CV_DbgAssert(!oInputImg.empty());
+    CV_DbgAssert(oInputImg.type() == CV_8UC3);
+    CV_DbgAssert(LBSP_::DESC_SIZE == 2); // @@@ also relies on a constant desc size
+    CV_DbgAssert(_x >= (int)LBSP_::PATCH_SIZE / 2 && _y >= (int)LBSP_::PATCH_SIZE / 2);
+    CV_DbgAssert(_x < oInputImg.cols - (int)LBSP_::PATCH_SIZE / 2 && _y < oInputImg.rows - (int)LBSP_::PATCH_SIZE / 2);
+    const size_t _step_row = oInputImg.step.p[0];
+    const uchar* const _data = oInputImg.data;
+#include "LBSP_16bits_dbcross_3ch1t.i"
+  }
+
+  //! utility function, shortcut/lightweight/direct single-point LBSP computation function for extra flexibility (1-channel-RGB version)
+  inline static void computeSingleRGBDescriptor(const cv::Mat& oInputImg, const uchar _ref, const int _x, const int _y, const size_t _c, const size_t _t, ushort& _res) {
+    CV_DbgAssert(!oInputImg.empty());
+    CV_DbgAssert(oInputImg.type() == CV_8UC3 && _c < 3);
+    CV_DbgAssert(LBSP_::DESC_SIZE == 2); // @@@ also relies on a constant desc size
+    CV_DbgAssert(_x >= (int)LBSP_::PATCH_SIZE / 2 && _y >= (int)LBSP_::PATCH_SIZE / 2);
+    CV_DbgAssert(_x < oInputImg.cols - (int)LBSP_::PATCH_SIZE / 2 && _y < oInputImg.rows - (int)LBSP_::PATCH_SIZE / 2);
+    const size_t _step_row = oInputImg.step.p[0];
+    const uchar* const _data = oInputImg.data;
+#include "LBSP_16bits_dbcross_s3ch.i"
+  }
+
+  //! utility function, used to reshape a descriptors matrix to its input image size via their keypoint locations
+  static void reshapeDesc(cv::Size oSize, const std::vector<cv::KeyPoint>& voKeypoints, const cv::Mat& oDescriptors, cv::Mat& oOutput);
+  //! utility function, used to illustrate the difference between two descriptor images
+  static void calcDescImgDiff(const cv::Mat& oDesc1, const cv::Mat& oDesc2, cv::Mat& oOutput, bool bForceMergeChannels = false);
+  //! utility function, used to filter out bad keypoints that would trigger out of bounds error because they're too close to the image border
+  static void validateKeyPoints(std::vector<cv::KeyPoint>& voKeypoints, cv::Size oImgSize);
+  //! utility function, used to filter out bad pixels in a ROI that would trigger out of bounds error because they're too close to the image border
+  static void validateROI(cv::Mat& oROI);
+  //! utility, specifies the pixel size of the pattern used (width and height)
+  static const size_t PATCH_SIZE = 5;
+  //! utility, specifies the number of bytes per descriptor (should be the same as calling 'descriptorSize()')
+  static const size_t DESC_SIZE = 2;
+
+protected:
+  //! classic 'compute' implementation, based on the regular DescriptorExtractor::computeImpl arguments & expected output
+  virtual void computeImpl(const cv::Mat& oImage, std::vector<cv::KeyPoint>& voKeypoints, cv::Mat& oDescriptors) const;
+
+  const bool m_bOnlyUsingAbsThreshold;
+  const float m_fRelThreshold;
+  const size_t m_nThreshold;
+  cv::Mat m_oRefImage;
+};
diff --git a/package_bgs/pl/LBSP_16bits_dbcross_1ch.i b/package_bgs/LBSP/LBSP_16bits_dbcross_1ch.i
similarity index 100%
rename from package_bgs/pl/LBSP_16bits_dbcross_1ch.i
rename to package_bgs/LBSP/LBSP_16bits_dbcross_1ch.i
diff --git a/package_bgs/pl/LBSP_16bits_dbcross_3ch1t.i b/package_bgs/LBSP/LBSP_16bits_dbcross_3ch1t.i
similarity index 100%
rename from package_bgs/pl/LBSP_16bits_dbcross_3ch1t.i
rename to package_bgs/LBSP/LBSP_16bits_dbcross_3ch1t.i
diff --git a/package_bgs/pl/LBSP_16bits_dbcross_3ch3t.i b/package_bgs/LBSP/LBSP_16bits_dbcross_3ch3t.i
similarity index 100%
rename from package_bgs/pl/LBSP_16bits_dbcross_3ch3t.i
rename to package_bgs/LBSP/LBSP_16bits_dbcross_3ch3t.i
diff --git a/package_bgs/pl/LBSP_16bits_dbcross_s3ch.i b/package_bgs/LBSP/LBSP_16bits_dbcross_s3ch.i
similarity index 100%
rename from package_bgs/pl/LBSP_16bits_dbcross_s3ch.i
rename to package_bgs/LBSP/LBSP_16bits_dbcross_s3ch.i
diff --git a/package_bgs/LBSP/RandUtils.h b/package_bgs/LBSP/RandUtils.h
new file mode 100644
index 0000000000000000000000000000000000000000..f676ca08da83ee0478c762180664d1b9a9dc34e4
--- /dev/null
+++ b/package_bgs/LBSP/RandUtils.h
@@ -0,0 +1,112 @@
+/*
+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
+
+/*// gaussian 3x3 pattern, based on 'floor(fspecial('gaussian', 3, 1)*256)'
+static const int s_nSamplesInitPatternWidth = 3;
+static const int s_nSamplesInitPatternHeight = 3;
+static const int s_nSamplesInitPatternTot = 256;
+static const int s_anSamplesInitPattern[s_nSamplesInitPatternHeight][s_nSamplesInitPatternWidth] = {
+    {19,    32,    19,},
+    {32,    52,    32,},
+    {19,    32,    19,},
+};*/
+
+// gaussian 7x7 pattern, based on 'floor(fspecial('gaussian',7,2)*512)'
+static const int s_nSamplesInitPatternWidth = 7;
+static const int s_nSamplesInitPatternHeight = 7;
+static const int s_nSamplesInitPatternTot = 512;
+static const int s_anSamplesInitPattern[s_nSamplesInitPatternHeight][s_nSamplesInitPatternWidth] = {
+  {2,     4,     6,     7,     6,     4,     2,},
+  {4,     8,    12,    14,    12,     8,     4,},
+  {6,    12,    21,    25,    21,    12,     6,},
+  {7,    14,    25,    28,    25,    14,     7,},
+  {6,    12,    21,    25,    21,    12,     6,},
+  {4,     8,    12,    14,    12,     8,     4,},
+  {2,     4,     6,     7,     6,     4,     2,},
+};
+
+//! returns a random init/sampling position for the specified pixel position; also guards against out-of-bounds values via image/border size check.
+static inline void getRandSamplePosition(int& x_sample, int& y_sample, const int x_orig, const int y_orig, const int border, const cv::Size& imgsize) {
+  int r = 1+rand()%s_nSamplesInitPatternTot;
+  for(x_sample=0; x_sample<s_nSamplesInitPatternWidth; ++x_sample) {
+    for(y_sample=0; y_sample<s_nSamplesInitPatternHeight; ++y_sample) {
+      r -= s_anSamplesInitPattern[y_sample][x_sample];
+      if(r<=0)
+        goto stop;
+    }
+  }
+stop:
+  x_sample += x_orig-s_nSamplesInitPatternWidth/2;
+  y_sample += y_orig-s_nSamplesInitPatternHeight/2;
+  if(x_sample<border)
+    x_sample = border;
+  else if(x_sample>=imgsize.width-border)
+    x_sample = imgsize.width-border-1;
+  if(y_sample<border)
+    y_sample = border;
+  else if(y_sample>=imgsize.height-border)
+    y_sample = imgsize.height-border-1;
+}
+
+// simple 8-connected (3x3) neighbors pattern
+static const int s_anNeighborPatternSize_3x3 = 8;
+static const int s_anNeighborPattern_3x3[8][2] = {
+  {-1, 1},  { 0, 1},  { 1, 1},
+  {-1, 0},            { 1, 0},
+  {-1,-1},  { 0,-1},  { 1,-1},
+};
+
+//! returns a random neighbor position for the specified pixel position; also guards against out-of-bounds values via image/border size check.
+static inline void getRandNeighborPosition_3x3(int& x_neighbor, int& y_neighbor, const int x_orig, const int y_orig, const int border, const cv::Size& imgsize) {
+  int r = rand()%s_anNeighborPatternSize_3x3;
+  x_neighbor = x_orig+s_anNeighborPattern_3x3[r][0];
+  y_neighbor = y_orig+s_anNeighborPattern_3x3[r][1];
+  if(x_neighbor<border)
+    x_neighbor = border;
+  else if(x_neighbor>=imgsize.width-border)
+    x_neighbor = imgsize.width-border-1;
+  if(y_neighbor<border)
+    y_neighbor = border;
+  else if(y_neighbor>=imgsize.height-border)
+    y_neighbor = imgsize.height-border-1;
+}
+
+// 5x5 neighbors pattern
+static const int s_anNeighborPatternSize_5x5 = 24;
+static const int s_anNeighborPattern_5x5[24][2] = {
+  {-2, 2},  {-1, 2},  { 0, 2},  { 1, 2},  { 2, 2},
+  {-2, 1},  {-1, 1},  { 0, 1},  { 1, 1},  { 2, 1},
+  {-2, 0},  {-1, 0},            { 1, 0},  { 2, 0},
+  {-2,-1},  {-1,-1},  { 0,-1},  { 1,-1},  { 2,-1},
+  {-2,-2},  {-1,-2},  { 0,-2},  { 1,-2},  { 2,-2},
+};
+
+//! returns a random neighbor position for the specified pixel position; also guards against out-of-bounds values via image/border size check.
+static inline void getRandNeighborPosition_5x5(int& x_neighbor, int& y_neighbor, const int x_orig, const int y_orig, const int border, const cv::Size& imgsize) {
+  int r = rand()%s_anNeighborPatternSize_5x5;
+  x_neighbor = x_orig+s_anNeighborPattern_5x5[r][0];
+  y_neighbor = y_orig+s_anNeighborPattern_5x5[r][1];
+  if(x_neighbor<border)
+    x_neighbor = border;
+  else if(x_neighbor>=imgsize.width-border)
+    x_neighbor = imgsize.width-border-1;
+  if(y_neighbor<border)
+    y_neighbor = border;
+  else if(y_neighbor>=imgsize.height-border)
+    y_neighbor = imgsize.height-border-1;
+}
diff --git a/package_bgs/lb/LBSimpleGaussian.cpp b/package_bgs/LBSimpleGaussian.cpp
similarity index 61%
rename from package_bgs/lb/LBSimpleGaussian.cpp
rename to package_bgs/LBSimpleGaussian.cpp
index f0ce6fc69c6e572e1ebba8883af7706a117f91ad..9ce071c029e94969da5b07347bf4696a98dec84e 100644
--- a/package_bgs/lb/LBSimpleGaussian.cpp
+++ b/package_bgs/LBSimpleGaussian.cpp
@@ -16,9 +16,13 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "LBSimpleGaussian.h"
 
-LBSimpleGaussian::LBSimpleGaussian() : firstTime(true), showOutput(true), sensitivity(66), noiseVariance(162), learningRate(18)
+using namespace bgslibrary::algorithms;
+
+LBSimpleGaussian::LBSimpleGaussian() :
+  sensitivity(66), noiseVariance(162), learningRate(18)
 {
   std::cout << "LBSimpleGaussian()" << std::endl;
+  setup("./config/LBSimpleGaussian.xml");
 }
 
 LBSimpleGaussian::~LBSimpleGaussian()
@@ -29,55 +33,47 @@ LBSimpleGaussian::~LBSimpleGaussian()
 
 void LBSimpleGaussian::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
+  init(img_input, img_output, img_bgmodel);
 
-  loadConfig();
-  
   IplImage *frame = new IplImage(img_input);
-  
-  if(firstTime)
-  {
-    saveConfig();
 
+  if (firstTime)
+  {
     int w = cvGetSize(frame).width;
     int h = cvGetSize(frame).height;
 
-    m_pBGModel = new BGModelGauss(w,h);
+    m_pBGModel = new BGModelGauss(w, h);
     m_pBGModel->InitModel(frame);
   }
-  
-  m_pBGModel->setBGModelParameter(0,sensitivity);
-  m_pBGModel->setBGModelParameter(1,noiseVariance);
-  m_pBGModel->setBGModelParameter(2,learningRate);
+
+  m_pBGModel->setBGModelParameter(0, sensitivity);
+  m_pBGModel->setBGModelParameter(1, noiseVariance);
+  m_pBGModel->setBGModelParameter(2, learningRate);
 
   m_pBGModel->UpdateModel(frame);
 
-  img_foreground = cv::Mat(m_pBGModel->GetFG());
-  img_background = cv::Mat(m_pBGModel->GetBG());
-    
-  if(showOutput)
+  img_foreground = cv::cvarrToMat(m_pBGModel->GetFG());
+  img_background = cv::cvarrToMat(m_pBGModel->GetBG());
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
   {
     cv::imshow("SG Mask", img_foreground);
     cv::imshow("SG Model", img_background);
   }
+#endif
 
   img_foreground.copyTo(img_output);
   img_background.copyTo(img_bgmodel);
-  
+
   delete frame;
-  
+
   firstTime = false;
 }
 
-//void LBSimpleGaussian::finish(void)
-//{
-//  delete m_pBGModel;
-//}
-
 void LBSimpleGaussian::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/LBSimpleGaussian.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteInt(fs, "sensitivity", sensitivity);
   cvWriteInt(fs, "noiseVariance", noiseVariance);
@@ -89,12 +85,12 @@ void LBSimpleGaussian::saveConfig()
 
 void LBSimpleGaussian::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/LBSimpleGaussian.xml", 0, CV_STORAGE_READ);
-  
-  sensitivity = cvReadIntByName(fs, 0, "sensitivity", 66);
-  noiseVariance = cvReadIntByName(fs, 0, "noiseVariance", 162);
-  learningRate = cvReadIntByName(fs, 0, "learningRate", 18);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  sensitivity = cvReadIntByName(fs, nullptr, "sensitivity", 66);
+  noiseVariance = cvReadIntByName(fs, nullptr, "noiseVariance", 162);
+  learningRate = cvReadIntByName(fs, nullptr, "learningRate", 18);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
-}
\ No newline at end of file
+}
diff --git a/package_bgs/lb/LBSimpleGaussian.h b/package_bgs/LBSimpleGaussian.h
similarity index 57%
rename from package_bgs/lb/LBSimpleGaussian.h
rename to package_bgs/LBSimpleGaussian.h
index bfefd3e12cf9bd03b9b14585d512f6b3d1c54adc..5c829234f86933736682ca4d41e9fa4f12bf550c 100644
--- a/package_bgs/lb/LBSimpleGaussian.h
+++ b/package_bgs/LBSimpleGaussian.h
@@ -16,39 +16,33 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "BGModelGauss.h"
-
-#include "../IBGS.h"
+#include "IBGS.h"
+#include "lb/BGModelGauss.h"
 
 using namespace lb_library;
 using namespace lb_library::SimpleGaussian;
 
-class LBSimpleGaussian : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  bool showOutput;
-  
-  BGModel* m_pBGModel;
-  int sensitivity;
-  int noiseVariance;
-  int learningRate;
-
-  cv::Mat img_foreground;
-  cv::Mat img_background;
-
-public:
-  LBSimpleGaussian();
-  ~LBSimpleGaussian();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-  //void finish(void);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
\ No newline at end of file
+  namespace algorithms
+  {
+    class LBSimpleGaussian : public IBGS
+    {
+    private:
+      BGModel* m_pBGModel;
+      int sensitivity;
+      int noiseVariance;
+      int learningRate;
+
+    public:
+      LBSimpleGaussian();
+      ~LBSimpleGaussian();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/LOBSTER.cpp b/package_bgs/LOBSTER.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dc48a63ba3a578e1ac0b8ebd9f123189827e2959
--- /dev/null
+++ b/package_bgs/LOBSTER.cpp
@@ -0,0 +1,98 @@
+/*
+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 "LOBSTER.h"
+
+using namespace bgslibrary::algorithms;
+
+LOBSTER::LOBSTER() :
+  pLOBSTER(nullptr),
+  fRelLBSPThreshold(BGSLOBSTER_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD),
+  nLBSPThresholdOffset(BGSLOBSTER_DEFAULT_LBSP_OFFSET_SIMILARITY_THRESHOLD),
+  nDescDistThreshold(BGSLOBSTER_DEFAULT_DESC_DIST_THRESHOLD),
+  nColorDistThreshold(BGSLOBSTER_DEFAULT_COLOR_DIST_THRESHOLD),
+  nBGSamples(BGSLOBSTER_DEFAULT_NB_BG_SAMPLES),
+  nRequiredBGSamples(BGSLOBSTER_DEFAULT_REQUIRED_NB_BG_SAMPLES)
+{
+  std::cout << "LOBSTER()" << std::endl;
+  setup("./config/LOBSTER.xml");
+}
+
+LOBSTER::~LOBSTER()
+{
+  if (pLOBSTER)
+    delete pLOBSTER;
+  std::cout << "~LOBSTER()" << std::endl;
+}
+
+void LOBSTER::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+{
+  init(img_input, img_output, img_bgmodel);
+
+  if (firstTime)
+  {
+    pLOBSTER = new BackgroundSubtractorLOBSTER(
+      fRelLBSPThreshold, nLBSPThresholdOffset, nDescDistThreshold,
+      nColorDistThreshold, nBGSamples, nRequiredBGSamples);
+
+    pLOBSTER->initialize(img_input, cv::Mat(img_input.size(), CV_8UC1, cv::Scalar_<uchar>(255)));
+    firstTime = false;
+  }
+
+  pLOBSTER->apply(img_input, img_foreground);
+  pLOBSTER->getBackgroundImage(img_background);
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+  {
+    imshow("LOBSTER FG", img_foreground);
+    imshow("LOBSTER BG", img_background);
+  }
+#endif
+
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
+}
+
+void LOBSTER::saveConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
+
+  cvWriteReal(fs, "fRelLBSPThreshold", fRelLBSPThreshold);
+  cvWriteInt(fs, "nLBSPThresholdOffset", nLBSPThresholdOffset);
+  cvWriteInt(fs, "nDescDistThreshold", nDescDistThreshold);
+  cvWriteInt(fs, "nColorDistThreshold", nColorDistThreshold);
+  cvWriteInt(fs, "nBGSamples", nBGSamples);
+  cvWriteInt(fs, "nRequiredBGSamples", nRequiredBGSamples);
+  cvWriteInt(fs, "showOutput", showOutput);
+
+  cvReleaseFileStorage(&fs);
+}
+
+void LOBSTER::loadConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  fRelLBSPThreshold = cvReadRealByName(fs, nullptr, "fRelLBSPThreshold", BGSLOBSTER_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD);
+  nLBSPThresholdOffset = cvReadIntByName(fs, nullptr, "nLBSPThresholdOffset", BGSLOBSTER_DEFAULT_LBSP_OFFSET_SIMILARITY_THRESHOLD);
+  nDescDistThreshold = cvReadIntByName(fs, nullptr, "nDescDistThreshold", BGSLOBSTER_DEFAULT_DESC_DIST_THRESHOLD);
+  nColorDistThreshold = cvReadIntByName(fs, nullptr, "nColorDistThreshold", BGSLOBSTER_DEFAULT_COLOR_DIST_THRESHOLD);
+  nBGSamples = cvReadIntByName(fs, nullptr, "nBGSamples", BGSLOBSTER_DEFAULT_NB_BG_SAMPLES);
+  nRequiredBGSamples = cvReadIntByName(fs, nullptr, "nRequiredBGSamples", BGSLOBSTER_DEFAULT_REQUIRED_NB_BG_SAMPLES);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
+
+  cvReleaseFileStorage(&fs);
+}
diff --git a/package_bgs/LOBSTER.h b/package_bgs/LOBSTER.h
new file mode 100644
index 0000000000000000000000000000000000000000..41ba8828664215cf1b9201a1c9f64b748e43ff34
--- /dev/null
+++ b/package_bgs/LOBSTER.h
@@ -0,0 +1,49 @@
+/*
+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
+
+#include "IBGS.h"
+#include "LBSP/BackgroundSubtractorLOBSTER.h"
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class LOBSTER : public IBGS
+    {
+    private:
+      BackgroundSubtractorLOBSTER* pLOBSTER;
+
+      float fRelLBSPThreshold;
+      size_t nLBSPThresholdOffset;
+      size_t nDescDistThreshold;
+      size_t nColorDistThreshold;
+      size_t nBGSamples;
+      size_t nRequiredBGSamples;
+
+    public:
+      LOBSTER();
+      ~LOBSTER();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/MixtureOfGaussianV1BGS.cpp b/package_bgs/MixtureOfGaussianV1.cpp
similarity index 53%
rename from package_bgs/MixtureOfGaussianV1BGS.cpp
rename to package_bgs/MixtureOfGaussianV1.cpp
index 51d41eb57348d76695a5c6c4392dc0e5e385a371..e56609a64c69539e2e6638db5fc159b055d8ac9f 100644
--- a/package_bgs/MixtureOfGaussianV1BGS.cpp
+++ b/package_bgs/MixtureOfGaussianV1.cpp
@@ -14,27 +14,27 @@ 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 "MixtureOfGaussianV1BGS.h"
+#include "MixtureOfGaussianV1.h"
 
-MixtureOfGaussianV1BGS::MixtureOfGaussianV1BGS() : firstTime(true), alpha(0.05), enableThreshold(true), threshold(15), showOutput(true)
+#if CV_MAJOR_VERSION == 2
+
+using namespace bgslibrary::algorithms;
+
+MixtureOfGaussianV1::MixtureOfGaussianV1() :
+  alpha(0.05), enableThreshold(true), threshold(15)
 {
-  std::cout << "MixtureOfGaussianV1BGS()" << std::endl;
+  std::cout << "MixtureOfGaussianV1()" << std::endl;
+  setup("./config/MixtureOfGaussianV1.xml");
 }
 
-MixtureOfGaussianV1BGS::~MixtureOfGaussianV1BGS()
+MixtureOfGaussianV1::~MixtureOfGaussianV1()
 {
-  std::cout << "~MixtureOfGaussianV1BGS()" << std::endl;
+  std::cout << "~MixtureOfGaussianV1()" << std::endl;
 }
 
-void MixtureOfGaussianV1BGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+void MixtureOfGaussianV1::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if(firstTime)
-    saveConfig();
+  init(img_input, img_output, img_bgmodel);
 
   //------------------------------------------------------------------
   // BackgroundSubtractorMOG
@@ -43,26 +43,30 @@ void MixtureOfGaussianV1BGS::process(const cv::Mat &img_input, cv::Mat &img_outp
   // Gaussian Mixture-based Backbround/Foreground Segmentation Algorithm.
   //
   // The class implements the algorithm described in:
-  //   P. KadewTraKuPong and R. Bowden, 
-  //   An improved adaptive background mixture model for real-time tracking with shadow detection, 
+  //   P. KadewTraKuPong and R. Bowden,
+  //   An improved adaptive background mixture model for real-time tracking with shadow detection,
   //   Proc. 2nd European Workshp on Advanced Video-Based Surveillance Systems, 2001
   //------------------------------------------------------------------
 
   mog(img_input, img_foreground, alpha);
-  cv::Mat img_background;
   mog.getBackgroundImage(img_background);
 
-  if(enableThreshold)
+  if (enableThreshold)
     cv::threshold(img_foreground, img_foreground, threshold, 255, cv::THRESH_BINARY);
 
-  if(showOutput)
+  if (img_foreground.empty())
+    img_foreground = cv::Mat::zeros(img_input.size(), img_input.type());
+
+  if (img_background.empty())
+    img_background = cv::Mat::zeros(img_input.size(), img_input.type());
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
   {
-    if (!img_foreground.empty())
-      cv::imshow("GMM FG (KadewTraKuPong&Bowden)", img_foreground);
-    
-    if (!img_background.empty())
-      cv::imshow("GMM BG (KadewTraKuPong&Bowden)", img_background);
+    cv::imshow("GMM FG (KadewTraKuPong&Bowden)", img_foreground);
+    cv::imshow("GMM BG (KadewTraKuPong&Bowden)", img_background);
   }
+#endif
 
   img_foreground.copyTo(img_output);
   img_background.copyTo(img_bgmodel);
@@ -70,9 +74,9 @@ void MixtureOfGaussianV1BGS::process(const cv::Mat &img_input, cv::Mat &img_outp
   firstTime = false;
 }
 
-void MixtureOfGaussianV1BGS::saveConfig()
+void MixtureOfGaussianV1::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/MixtureOfGaussianV1BGS.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteReal(fs, "alpha", alpha);
   cvWriteInt(fs, "enableThreshold", enableThreshold);
@@ -82,14 +86,15 @@ void MixtureOfGaussianV1BGS::saveConfig()
   cvReleaseFileStorage(&fs);
 }
 
-void MixtureOfGaussianV1BGS::loadConfig()
+void MixtureOfGaussianV1::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/MixtureOfGaussianV1BGS.xml", 0, CV_STORAGE_READ);
-  
-  alpha = cvReadRealByName(fs, 0, "alpha", 0.05);
-  enableThreshold = cvReadIntByName(fs, 0, "enableThreshold", true);
-  threshold = cvReadIntByName(fs, 0, "threshold", 15);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  alpha = cvReadRealByName(fs, nullptr, "alpha", 0.05);
+  enableThreshold = cvReadIntByName(fs, nullptr, "enableThreshold", true);
+  threshold = cvReadIntByName(fs, nullptr, "threshold", 15);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
+#endif
diff --git a/package_bgs/MixtureOfGaussianV1BGS.h b/package_bgs/MixtureOfGaussianV1.h
similarity index 59%
rename from package_bgs/MixtureOfGaussianV1BGS.h
rename to package_bgs/MixtureOfGaussianV1.h
index f735a1357e321de6ba5acbb0b9b76c4fb1534d1a..e18dbdbeae973b8d8e6c4b73504a5bea94050c5e 100644
--- a/package_bgs/MixtureOfGaussianV1BGS.h
+++ b/package_bgs/MixtureOfGaussianV1.h
@@ -16,32 +16,38 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
+#include "opencv2/core/version.hpp"
+#if CV_MAJOR_VERSION == 2
+
 #include <iostream>
 #include <opencv2/opencv.hpp>
-
 #include <opencv2/video/background_segm.hpp>
 
 #include "IBGS.h"
 
-class MixtureOfGaussianV1BGS : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  cv::BackgroundSubtractorMOG mog;
-  cv::Mat img_foreground;
-  double alpha;
-  bool enableThreshold;
-  int threshold;
-  bool showOutput;
-
-public:
-  MixtureOfGaussianV1BGS();
-  ~MixtureOfGaussianV1BGS();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
-
+  namespace algorithms
+  {
+    class MixtureOfGaussianV1 : public IBGS
+    {
+    private:
+      cv::BackgroundSubtractorMOG mog;
+      double alpha;
+      bool enableThreshold;
+      int threshold;
+
+    public:
+      MixtureOfGaussianV1();
+      ~MixtureOfGaussianV1();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
+
+#endif
diff --git a/package_bgs/MixtureOfGaussianV2BGS.cpp b/package_bgs/MixtureOfGaussianV2.cpp
similarity index 60%
rename from package_bgs/MixtureOfGaussianV2BGS.cpp
rename to package_bgs/MixtureOfGaussianV2.cpp
index 5ce33a3ef1b36a5948c20288530be22332106f0c..085b1a9503f9297a9d553b4991ff29443aead97f 100644
--- a/package_bgs/MixtureOfGaussianV2BGS.cpp
+++ b/package_bgs/MixtureOfGaussianV2.cpp
@@ -14,27 +14,31 @@ 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 "MixtureOfGaussianV2BGS.h"
+#include "MixtureOfGaussianV2.h"
 
-MixtureOfGaussianV2BGS::MixtureOfGaussianV2BGS() : firstTime(true), alpha(0.05), enableThreshold(true), threshold(15), showOutput(true)
+using namespace bgslibrary::algorithms;
+
+MixtureOfGaussianV2::MixtureOfGaussianV2() :
+  alpha(0.05), enableThreshold(true), threshold(15)
 {
-  std::cout << "MixtureOfGaussianV2BGS()" << std::endl;
+  std::cout << "MixtureOfGaussianV2()" << std::endl;
+  setup("./config/MixtureOfGaussianV2.xml");
 }
 
-MixtureOfGaussianV2BGS::~MixtureOfGaussianV2BGS()
+MixtureOfGaussianV2::~MixtureOfGaussianV2()
 {
-  std::cout << "~MixtureOfGaussianV2BGS()" << std::endl;
+  std::cout << "~MixtureOfGaussianV2()" << std::endl;
 }
 
-void MixtureOfGaussianV2BGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+void MixtureOfGaussianV2::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-
-  loadConfig();
+  init(img_input, img_output, img_bgmodel);
 
-  if(firstTime)
-    saveConfig();
+  if (firstTime) {
+#if CV_MAJOR_VERSION == 3
+    mog = cv::createBackgroundSubtractorMOG2();
+#endif
+  }
 
   //------------------------------------------------------------------
   // BackgroundSubtractorMOG2
@@ -43,29 +47,34 @@ void MixtureOfGaussianV2BGS::process(const cv::Mat &img_input, cv::Mat &img_outp
   // Gaussian Mixture-based Backbround/Foreground Segmentation Algorithm.
   //
   // The class implements the Gaussian mixture model background subtraction described in:
-  //  (1) Z.Zivkovic, Improved adaptive Gausian mixture model for background subtraction, International Conference Pattern Recognition, UK, August, 2004, 
+  //  (1) Z.Zivkovic, Improved adaptive Gausian mixture model for background subtraction, International Conference Pattern Recognition, UK, August, 2004,
   //  The code is very fast and performs also shadow detection. Number of Gausssian components is adapted per pixel.
   //
-  //  (2) Z.Zivkovic, F. van der Heijden, Efficient Adaptive Density Estimation per Image Pixel for the Task of Background Subtraction, 
-  //  Pattern Recognition Letters, vol. 27, no. 7, pages 773-780, 2006. 
-  //  The algorithm similar to the standard Stauffer&Grimson algorithm with additional selection of the number of the Gaussian components based on: 
-  //    Z.Zivkovic, F.van der Heijden, Recursive unsupervised learning of finite mixture models, IEEE Trans. on Pattern Analysis and Machine Intelligence, 
+  //  (2) Z.Zivkovic, F. van der Heijden, Efficient Adaptive Density Estimation per Image Pixel for the Task of Background Subtraction,
+  //  Pattern Recognition Letters, vol. 27, no. 7, pages 773-780, 2006.
+  //  The algorithm similar to the standard Stauffer&Grimson algorithm with additional selection of the number of the Gaussian components based on:
+  //    Z.Zivkovic, F.van der Heijden, Recursive unsupervised learning of finite mixture models, IEEE Trans. on Pattern Analysis and Machine Intelligence,
   //    vol.26, no.5, pages 651-656, 2004.
   //------------------------------------------------------------------
 
+#if CV_MAJOR_VERSION == 2
   mog(img_input, img_foreground, alpha);
-  
-  cv::Mat img_background;
   mog.getBackgroundImage(img_background);
+#elif CV_MAJOR_VERSION == 3
+  mog->apply(img_input, img_foreground, alpha);
+  mog->getBackgroundImage(img_background);
+#endif
 
-  if(enableThreshold)
+  if (enableThreshold)
     cv::threshold(img_foreground, img_foreground, threshold, 255, cv::THRESH_BINARY);
 
-  if(showOutput)
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
   {
-    cv::imshow("GMM (Zivkovic&Heijden)", img_foreground);
-    cv::imshow("GMM BKG (Zivkovic&Heijden)", img_background);
+    cv::imshow("GMM FG (Zivkovic&Heijden)", img_foreground);
+    cv::imshow("GMM BG (Zivkovic&Heijden)", img_background);
   }
+#endif
 
   img_foreground.copyTo(img_output);
   img_background.copyTo(img_bgmodel);
@@ -73,9 +82,9 @@ void MixtureOfGaussianV2BGS::process(const cv::Mat &img_input, cv::Mat &img_outp
   firstTime = false;
 }
 
-void MixtureOfGaussianV2BGS::saveConfig()
+void MixtureOfGaussianV2::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/MixtureOfGaussianV2BGS.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteReal(fs, "alpha", alpha);
   cvWriteInt(fs, "enableThreshold", enableThreshold);
@@ -85,14 +94,14 @@ void MixtureOfGaussianV2BGS::saveConfig()
   cvReleaseFileStorage(&fs);
 }
 
-void MixtureOfGaussianV2BGS::loadConfig()
+void MixtureOfGaussianV2::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/MixtureOfGaussianV2BGS.xml", 0, CV_STORAGE_READ);
-  
-  alpha = cvReadRealByName(fs, 0, "alpha", 0.05);
-  enableThreshold = cvReadIntByName(fs, 0, "enableThreshold", true);
-  threshold = cvReadIntByName(fs, 0, "threshold", 15);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  alpha = cvReadRealByName(fs, nullptr, "alpha", 0.05);
+  enableThreshold = cvReadIntByName(fs, nullptr, "enableThreshold", true);
+  threshold = cvReadIntByName(fs, nullptr, "threshold", 15);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/MixtureOfGaussianV2BGS.h b/package_bgs/MixtureOfGaussianV2.h
similarity index 57%
rename from package_bgs/MixtureOfGaussianV2BGS.h
rename to package_bgs/MixtureOfGaussianV2.h
index a14ff0b788fb4e161e9d4acd7a2855a71f68a2c6..edc8add6c693988fd2bc9c06815b0b6e4d01c9ca 100644
--- a/package_bgs/MixtureOfGaussianV2BGS.h
+++ b/package_bgs/MixtureOfGaussianV2.h
@@ -18,30 +18,35 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 
 #include <iostream>
 #include <opencv2/opencv.hpp>
-
 #include <opencv2/video/background_segm.hpp>
 
 #include "IBGS.h"
 
-class MixtureOfGaussianV2BGS : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  cv::BackgroundSubtractorMOG2 mog;
-  cv::Mat img_foreground;
-  double alpha;
-  bool enableThreshold;
-  int threshold;
-  bool showOutput;
-
-public:
-  MixtureOfGaussianV2BGS();
-  ~MixtureOfGaussianV2BGS();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
-
+  namespace algorithms
+  {
+    class MixtureOfGaussianV2 : public IBGS
+    {
+    private:
+#if CV_MAJOR_VERSION == 2
+      cv::BackgroundSubtractorMOG2 mog;
+#elif CV_MAJOR_VERSION == 3
+      cv::Ptr<cv::BackgroundSubtractorMOG2> mog;
+#endif
+      double alpha;
+      bool enableThreshold;
+      int threshold;
+
+    public:
+      MixtureOfGaussianV2();
+      ~MixtureOfGaussianV2();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/sjn/SJN_MultiCueBGS.cpp b/package_bgs/MultiCue.cpp
similarity index 83%
rename from package_bgs/sjn/SJN_MultiCueBGS.cpp
rename to package_bgs/MultiCue.cpp
index 83db6ec62153ca3a40136dc9df2a3ffbb762dd94..7717842975210f5ff32eeb876f615737d4c024bd 100644
--- a/package_bgs/sjn/SJN_MultiCueBGS.cpp
+++ b/package_bgs/MultiCue.cpp
@@ -21,12 +21,16 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 //  - Code by: SeungJon Noh																											  //
 //------------------------------------------------------------------------------------------------------------------------------------//
 //#include "StdAfx.h"
-#include "SJN_MultiCueBGS.h"
-SJN_MultiCueBGS::SJN_MultiCueBGS() : firstTime(true), showOutput(true)
+#include "MultiCue.h"
+
+using namespace bgslibrary::algorithms::libMultiCue;
+using namespace bgslibrary::algorithms;
+
+MultiCue::MultiCue()
 {
   //----------------------------------
   //	User adjustable parameters
-  //----------------------------------			
+  //----------------------------------
   g_iTrainingPeriod = 20;											//the training period								(The parameter t in the paper)
   g_iT_ModelThreshold = 1;										//the threshold for texture-model based BGS.		(The parameter tau_T in the paper)
   g_iC_ModelThreshold = 10;										//the threshold for appearance based verification.  (The parameter tau_A in the paper)
@@ -37,15 +41,15 @@ SJN_MultiCueBGS::SJN_MultiCueBGS() : firstTime(true), showOutput(true)
   g_nColorTrainVolRange = 20;										//the codebook size factor for color models.		(The parameter eta_1 in the paper)
 
   g_bAbsorptionEnable = TRUE;										//If TRUE, cache-book is also modeled for ghost region removal.
-  g_iAbsortionPeriod = 200;										//the period to absorb static ghost regions 
+  g_iAbsortionPeriod = 200;										//the period to absorb static ghost regions
 
   g_iRWidth = 160, g_iRHeight = 120;								//Frames are precessed after reduced in this size .
 
   //------------------------------------
   //	For codebook maintenance
   //------------------------------------
-  g_iBackClearPeriod = 300;										//the period to clear background models	
-  g_iCacheClearPeriod = 30;										//the period to clear cache-book models	
+  g_iBackClearPeriod = 300;										//the period to clear background models
+  g_iCacheClearPeriod = 30;										//the period to clear cache-book models
 
   //------------------------------------
   //	Initialization of other parameters
@@ -57,38 +61,37 @@ SJN_MultiCueBGS::SJN_MultiCueBGS() : firstTime(true), showOutput(true)
   g_bForegroundMapEnable = FALSE;									//TRUE only when BGS is successful
   g_bModelMemAllocated = FALSE;									//To handle memory..
   g_bNonModelMemAllocated = FALSE;								//To handle memory..
+
+  std::cout << "MultiCue()" << std::endl;
+  setup("./config/MultiCue.xml");
 }
 
-SJN_MultiCueBGS::~SJN_MultiCueBGS(void){
+MultiCue::~MultiCue(void)
+{
   Destroy();
+  std::cout << "~MultiCue()" << std::endl;
 }
 
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //											the main function to background modeling and subtraction									   //																   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel){
-
-  if (img_input.empty())
-    return;
-
-  loadConfig();
-
-  if (firstTime)
-    saveConfig();
+void MultiCue::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+{
+  init(img_input, img_output, img_bgmodel);
 
   //--STep1: Background Modeling--//
   //IplImage* frame = &IplImage(img_input);
   IplImage* frame = new IplImage(img_input);
   IplImage* result_image = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 3);
   cvSetZero(result_image);
-
-  if (g_iFrameCount <= g_iTrainingPeriod){
+  if (g_iFrameCount <= g_iTrainingPeriod)
+  {
     BackgroundModeling_Par(frame);
     g_iFrameCount++;
   }
-
   //--Step2: Background Subtraction--//
-  else{
+  else
+  {
     g_bForegroundMapEnable = FALSE;
 
     ForegroundExtraction(frame);
@@ -99,33 +102,35 @@ void SJN_MultiCueBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv:
   }
   delete frame;
 
-  cv::Mat temp(result_image, TRUE);
-  temp.copyTo(img_output);
-
+  img_background = cv::Mat::zeros(img_input.size(), img_input.type());
+  img_foreground = cv::cvarrToMat(result_image, TRUE);
   cvReleaseImage(&result_image);
 
+#ifndef MEX_COMPILE_FLAG
   if (showOutput)
-  {
-    cv::imshow("MultiCueBGS FG", img_output);
-  }
+    cv::imshow("MultiCue FG", img_foreground);
+#endif
+
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
 
   firstTime = false;
 }
 
-void SJN_MultiCueBGS::saveConfig()
+void MultiCue::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/MultiCueBGS.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteInt(fs, "showOutput", showOutput);
 
   cvReleaseFileStorage(&fs);
 }
 
-void SJN_MultiCueBGS::loadConfig()
+void MultiCue::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/MultiCueBGS.xml", 0, CV_STORAGE_READ);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
 
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
@@ -133,7 +138,7 @@ void SJN_MultiCueBGS::loadConfig()
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //													the system initialization function													   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::Initialize(IplImage* frame)
+void MultiCue::Initialize(IplImage* frame)
 {
   int i, j;
 
@@ -148,15 +153,15 @@ void SJN_MultiCueBGS::Initialize(IplImage* frame)
   g_ResizedFrame = cvCreateImage(cvSize(g_iRWidth, g_iRHeight), IPL_DEPTH_8U, 3);
 
   g_aGaussFilteredFrame = (uchar***)malloc(sizeof(uchar**)*g_iRHeight);
-  for (i = 0; i < g_iRHeight; i++){
+  for (i = 0; i < g_iRHeight; i++) {
     g_aGaussFilteredFrame[i] = (uchar**)malloc(sizeof(uchar*)*g_iRWidth);
-    for (j = 0; j < g_iRWidth; j++) g_aGaussFilteredFrame[i][j] = (uchar*)malloc(sizeof(uchar)* 3);
+    for (j = 0; j < g_iRWidth; j++) g_aGaussFilteredFrame[i][j] = (uchar*)malloc(sizeof(uchar) * 3);
   }
 
   g_aXYZFrame = (uchar***)malloc(sizeof(uchar**)*g_iRHeight);
-  for (i = 0; i < g_iRHeight; i++){
+  for (i = 0; i < g_iRHeight; i++) {
     g_aXYZFrame[i] = (uchar**)malloc(sizeof(uchar*)*g_iRWidth);
-    for (j = 0; j < g_iRWidth; j++) g_aXYZFrame[i][j] = (uchar*)malloc(sizeof(uchar)* 3);
+    for (j = 0; j < g_iRWidth; j++) g_aXYZFrame[i][j] = (uchar*)malloc(sizeof(uchar) * 3);
   }
 
   g_aLandmarkArray = (uchar**)malloc(sizeof(uchar*)*g_iRHeight);
@@ -203,30 +208,30 @@ void SJN_MultiCueBGS::Initialize(IplImage* frame)
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //												the function to release allocated memories											       //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::Destroy()
+void MultiCue::Destroy()
 {
   if (g_bModelMemAllocated == FALSE && g_bNonModelMemAllocated == FALSE) return;
 
   short nNeighborNum = g_nNeighborNum;
 
-  if (g_bModelMemAllocated == TRUE){
+  if (g_bModelMemAllocated == TRUE) {
     T_ReleaseTextureModelRelatedMemory();
     C_ReleaseColorModelRelatedMemory();
 
     g_bModelMemAllocated = FALSE;
   }
 
-  if (g_bNonModelMemAllocated == TRUE){
+  if (g_bNonModelMemAllocated == TRUE) {
 
     cvReleaseImage(&g_ResizedFrame);
 
-    for (int i = 0; i < g_iRHeight; i++){
+    for (int i = 0; i < g_iRHeight; i++) {
       for (int j = 0; j < g_iRWidth; j++) free(g_aGaussFilteredFrame[i][j]);
       free(g_aGaussFilteredFrame[i]);
     }
     free(g_aGaussFilteredFrame);
 
-    for (int i = 0; i < g_iRHeight; i++){
+    for (int i = 0; i < g_iRHeight; i++) {
       for (int j = 0; j < g_iRWidth; j++) free(g_aXYZFrame[i][j]);
       free(g_aXYZFrame[i]);
     }
@@ -256,7 +261,7 @@ void SJN_MultiCueBGS::Destroy()
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //														the preprocessing function		    											   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::PreProcessing(IplImage* frame){
+void MultiCue::PreProcessing(IplImage* frame) {
 
   //image resize
   ReduceImageSize(frame, g_ResizedFrame);
@@ -271,7 +276,7 @@ void SJN_MultiCueBGS::PreProcessing(IplImage* frame){
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //														the background modeling function												   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::BackgroundModeling_Par(IplImage* frame){
+void MultiCue::BackgroundModeling_Par(IplImage* frame) {
 
   //initialization
   if (g_iFrameCount == 0) Initialize(frame);
@@ -285,8 +290,8 @@ void SJN_MultiCueBGS::BackgroundModeling_Par(IplImage* frame){
   float fLearningRate = g_fLearningRate * 4;
 
   //Step2: background modeling
-  for (int i = iH_Start; i < iH_end; i++){
-    for (int j = iW_Start; j < iW_end; j++){
+  for (int i = iH_Start; i < iH_end; i++) {
+    for (int j = iW_Start; j < iW_end; j++) {
       point center;
       center.m_nX = j;
       center.m_nY = i;
@@ -297,9 +302,9 @@ void SJN_MultiCueBGS::BackgroundModeling_Par(IplImage* frame){
   }
 
   //Step3: Clear non-essential codewords
-  if (g_iFrameCount == g_iTrainingPeriod){
-    for (int i = 0; i < g_iRHeight; i++){
-      for (int j = 0; j < g_iRWidth; j++){
+  if (g_iFrameCount == g_iTrainingPeriod) {
+    for (int i = 0; i < g_iRHeight; i++) {
+      for (int j = 0; j < g_iRWidth; j++) {
         T_ClearNonEssentialEntries(g_iTrainingPeriod, g_TextureModel[i][j]);
 
         C_ClearNonEssentialEntries(g_iTrainingPeriod, g_ColorModel[i][j]);
@@ -312,7 +317,7 @@ void SJN_MultiCueBGS::BackgroundModeling_Par(IplImage* frame){
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //														the background subtraction function							                       //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::ForegroundExtraction(IplImage* frame){
+void MultiCue::ForegroundExtraction(IplImage* frame) {
 
   //Step1:pre-processing
   PreProcessing(frame);
@@ -332,9 +337,9 @@ void SJN_MultiCueBGS::ForegroundExtraction(IplImage* frame){
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //														the post-processing function													   //												
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::PostProcessing(IplImage* frame){
+void MultiCue::PostProcessing(IplImage* frame) {
 
-  //Step1: morphological operation	
+  //Step1: morphological operation
   MorphologicalOpearions(g_aLandmarkArray, g_aResizedForeMap, 0.5, 5, g_iRWidth, g_iRHeight);
   g_bForegroundMapEnable = TRUE;
 
@@ -361,20 +366,20 @@ void SJN_MultiCueBGS::PostProcessing(IplImage* frame){
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //														the background-model update function			                                   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::UpdateModel_Par(){
+void MultiCue::UpdateModel_Par() {
   short nNeighborNum = g_nNeighborNum;
 
   //Step1: update map construction
-  for (int i = 0; i < g_iRHeight; i++){
-    for (int j = 0; j < g_iRWidth; j++){
+  for (int i = 0; i < g_iRHeight; i++) {
+    for (int j = 0; j < g_iRWidth; j++) {
       g_aUpdateMap[i][j] = TRUE;
     }
   }
 
-  for (int k = 0; k < g_BoundBoxInfo->m_iBoundBoxNum; k++){
-    if (g_BoundBoxInfo->m_ValidBox[k] == TRUE){
-      for (int i = g_BoundBoxInfo->m_aRUpper[k]; i <= g_BoundBoxInfo->m_aRBottom[k]; i++){
-        for (int j = g_BoundBoxInfo->m_aRLeft[k]; j <= g_BoundBoxInfo->m_aRRight[k]; j++){
+  for (int k = 0; k < g_BoundBoxInfo->m_iBoundBoxNum; k++) {
+    if (g_BoundBoxInfo->m_ValidBox[k] == TRUE) {
+      for (int i = g_BoundBoxInfo->m_aRUpper[k]; i <= g_BoundBoxInfo->m_aRBottom[k]; i++) {
+        for (int j = g_BoundBoxInfo->m_aRLeft[k]; j <= g_BoundBoxInfo->m_aRRight[k]; j++) {
           g_aUpdateMap[i][j] = FALSE;
         }
       }
@@ -387,16 +392,16 @@ void SJN_MultiCueBGS::UpdateModel_Par(){
 
   float fLearningRate = (float)g_fLearningRate;
 
-  for (int i = iH_Start; i < iH_End; i++){
-    for (int j = iW_Start; j < iW_End; j++){
+  for (int i = iH_Start; i < iH_End; i++) {
+    for (int j = iW_Start; j < iW_End; j++) {
 
       point center;
 
       center.m_nX = j;
       center.m_nY = i;
 
-      if (g_aUpdateMap[i][j] == TRUE){
-        //model update		
+      if (g_aUpdateMap[i][j] == TRUE) {
+        //model update
         T_ModelConstruction(g_nTextureTrainVolRange, fLearningRate, g_aXYZFrame, center, g_aNeighborDirection[i][j], g_TextureModel[i][j]);
         C_CodebookConstruction(g_aXYZFrame[i][j], j, i, g_nColorTrainVolRange, fLearningRate, g_ColorModel[i][j]);
 
@@ -406,7 +411,7 @@ void SJN_MultiCueBGS::UpdateModel_Par(){
 
       }
       else {
-        if (g_bAbsorptionEnable == TRUE){
+        if (g_bAbsorptionEnable == TRUE) {
           //model update
           T_ModelConstruction(g_nTextureTrainVolRange, fLearningRate, g_aXYZFrame, center, g_aNeighborDirection[i][j], g_TCacheBook[i][j]);
           C_CodebookConstruction(g_aXYZFrame[i][j], j, i, g_nColorTrainVolRange, fLearningRate, g_CCacheBook[i][j]);
@@ -419,7 +424,7 @@ void SJN_MultiCueBGS::UpdateModel_Par(){
       }
 
       //clearing non-essential codewords for cache-books
-      if (g_bAbsorptionEnable == TRUE){
+      if (g_bAbsorptionEnable == TRUE) {
         T_ClearNonEssentialEntriesForCachebook(g_aLandmarkArray[i][j], g_aTReferredIndex[i][j], 10, g_TCacheBook[i][j]);
         C_ClearNonEssentialEntriesForCachebook(g_aLandmarkArray[i][j], g_aCReferredIndex[i][j], 10, g_CCacheBook[i][j]);
       }
@@ -431,16 +436,16 @@ void SJN_MultiCueBGS::UpdateModel_Par(){
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //														the color based verification function											   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::CreateLandmarkArray_Par(float fConfThre, short nTrainVolRange, float**aConfMap, int iNehborNum, uchar*** aXYZ,
-  point*** aNeiDir, TextureModel**** TModel, ColorModel*** CModel, uchar**aLandmarkArr){
+void MultiCue::CreateLandmarkArray_Par(float fConfThre, short nTrainVolRange, float**aConfMap, int iNehborNum, uchar*** aXYZ,
+  point*** aNeiDir, TextureModel**** TModel, ColorModel*** CModel, uchar**aLandmarkArr) {
 
   int iBound_w = g_iRWidth - g_nRadius;
   int iBound_h = g_iRHeight - g_nRadius;
 
-  for (int i = 0; i < g_iRHeight; i++){
-    for (int j = 0; j < g_iRWidth; j++){
+  for (int i = 0; i < g_iRHeight; i++) {
+    for (int j = 0; j < g_iRWidth; j++) {
 
-      if (i < g_nRadius || i >= iBound_h || j<g_nRadius || j >= iBound_w) {
+      if (i < g_nRadius || i >= iBound_h || j < g_nRadius || j >= iBound_w) {
         aLandmarkArr[i][j] = 0;
         continue;
       }
@@ -448,14 +453,14 @@ void SJN_MultiCueBGS::CreateLandmarkArray_Par(float fConfThre, short nTrainVolRa
       double tmp = aConfMap[i][j];
 
       if (tmp > fConfThre) aLandmarkArr[i][j] = 255;
-      else{
+      else {
         aLandmarkArr[i][j] = 0;
         //Calculating texture amount in the background
         double dBackAmt, dCnt;
         dBackAmt = dCnt = 0;
 
-        for (int m = 0; m < iNehborNum; m++){
-          for (int n = 0; n < TModel[i][j][m]->m_iNumEntries; n++){
+        for (int m = 0; m < iNehborNum; m++) {
+          for (int n = 0; n < TModel[i][j][m]->m_iNumEntries; n++) {
             dBackAmt += TModel[i][j][m]->m_Codewords[n]->m_fMean;
             dCnt++;
           }
@@ -464,7 +469,7 @@ void SJN_MultiCueBGS::CreateLandmarkArray_Par(float fConfThre, short nTrainVolRa
 
         //Calculating texture amount in the input image
         double dTemp, dInputAmt = 0;
-        for (int m = 0; m < iNehborNum; m++){
+        for (int m = 0; m < iNehborNum; m++) {
           dTemp = aXYZ[i][j][2] - aXYZ[aNeiDir[i][j][m].m_nY][aNeiDir[i][j][m].m_nX][2];
 
           if (dTemp >= 0) dInputAmt += dTemp;
@@ -473,13 +478,13 @@ void SJN_MultiCueBGS::CreateLandmarkArray_Par(float fConfThre, short nTrainVolRa
         }
 
         //If there are only few textures in both background and input image
-        if (dBackAmt < 50 && dInputAmt < 50){
+        if (dBackAmt < 50 && dInputAmt < 50) {
           //Conduct color codebook matching
           BOOL bMatched = FALSE;
-          for (int m = 0; m < CModel[i][j]->m_iNumEntries; m++){
+          for (int m = 0; m < CModel[i][j]->m_iNumEntries; m++) {
 
             int iMatchedCount = 0;
-            for (int n = 0; n < 3; n++){
+            for (int n = 0; n < 3; n++) {
               double dLowThre = CModel[i][j]->m_Codewords[m]->m_dMean[n] - nTrainVolRange - 10;
               double dHighThre = CModel[i][j]->m_Codewords[m]->m_dMean[n] + nTrainVolRange + 10;
 
@@ -505,13 +510,13 @@ void SJN_MultiCueBGS::CreateLandmarkArray_Par(float fConfThre, short nTrainVolRa
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //													the Gaussian filtering function								                           //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::GaussianFiltering(IplImage* frame, uchar*** aFilteredFrame){
+void MultiCue::GaussianFiltering(IplImage* frame, uchar*** aFilteredFrame) {
 
   double dSigma = 0.7;
 
-  if (dSigma == 0){
-    for (int i = 0; i < g_iRHeight; i++){
-      for (int j = 0; j < g_iRWidth; j++){
+  if (dSigma == 0) {
+    for (int i = 0; i < g_iRHeight; i++) {
+      for (int j = 0; j < g_iRWidth; j++) {
         aFilteredFrame[i][j][0] = frame->imageData[i*frame->widthStep + j * 3];
         aFilteredFrame[i][j][1] = frame->imageData[i*frame->widthStep + j * 3 + 1];
         aFilteredFrame[i][j][2] = frame->imageData[i*frame->widthStep + j * 3 + 2];
@@ -520,16 +525,16 @@ void SJN_MultiCueBGS::GaussianFiltering(IplImage* frame, uchar*** aFilteredFrame
   }
   else
   {
-    cv::Mat temp_img(frame, TRUE);
+    cv::Mat temp_img = cv::cvarrToMat(frame, TRUE);
     cv::GaussianBlur(temp_img, temp_img, cv::Size(7, 7), dSigma);
 
     //Store results into aFilteredFrame[][][]
     //IplImage* img = &IplImage(temp_img);
     IplImage* img = new IplImage(temp_img);
-    int iWidthStep = img->widthStep;
+    //int iWidthStep = img->widthStep;
 
-    for (int i = 0; i < g_iRHeight; i++){
-      for (int j = 0; j < g_iRWidth; j++){
+    for (int i = 0; i < g_iRHeight; i++) {
+      for (int j = 0; j < g_iRWidth; j++) {
         aFilteredFrame[i][j][0] = img->imageData[i*img->widthStep + j * 3];
         aFilteredFrame[i][j][1] = img->imageData[i*img->widthStep + j * 3 + 1];
         aFilteredFrame[i][j][2] = img->imageData[i*img->widthStep + j * 3 + 2];
@@ -542,7 +547,7 @@ void SJN_MultiCueBGS::GaussianFiltering(IplImage* frame, uchar*** aFilteredFrame
 //------------------------------------------------------------------------------------------------------------------------------------//
 //														the image resize function									                 //
 //------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::ReduceImageSize(IplImage* SrcImage, IplImage* DstImage){
+void MultiCue::ReduceImageSize(IplImage* SrcImage, IplImage* DstImage) {
 
   int iChannel = 3;
 
@@ -550,8 +555,8 @@ void SJN_MultiCueBGS::ReduceImageSize(IplImage* SrcImage, IplImage* DstImage){
   double dResizeFactor_h = (double)g_iHeight / (double)g_iRHeight;
 
 
-  for (int i = 0; i < g_iRHeight; i++){
-    for (int j = 0; j < g_iRWidth; j++){
+  for (int i = 0; i < g_iRHeight; i++) {
+    for (int j = 0; j < g_iRWidth; j++) {
       int iSrcY = (int)(i*dResizeFactor_h);
       int iSrcX = (int)(j*dResizeFactor_w);
 
@@ -565,18 +570,18 @@ void SJN_MultiCueBGS::ReduceImageSize(IplImage* SrcImage, IplImage* DstImage){
 //------------------------------------------------------------------------------------------------------------------------------------//
 //											    the color space conversion function                                                   //
 //------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::BGR2HSVxyz_Par(uchar*** aBGR, uchar*** aXYZ){
+void MultiCue::BGR2HSVxyz_Par(uchar*** aBGR, uchar*** aXYZ) {
 
   double dH_ratio = (2 * PI) / 360;
 
-  for (int i = 0; i < g_iRHeight; i++){
+  for (int i = 0; i < g_iRHeight; i++) {
 
     double dR, dG, dB;
     double dMax, dMin;
 
     double dH, dS, dV;
 
-    for (int j = 0; j < g_iRWidth; j++){
+    for (int j = 0; j < g_iRWidth; j++) {
 
       dB = (double)(aBGR[i][j][0]) / 255;
       dG = (double)(aBGR[i][j][1]) / 255;
@@ -593,13 +598,13 @@ void SJN_MultiCueBGS::BGR2HSVxyz_Par(uchar*** aBGR, uchar*** aXYZ){
 
       //Get S, H
       if (dV == 0) dS = dH = 0;
-      else{
+      else {
 
         //S value
         dS = (dMax - dMin) / dMax;
 
         if (dS == 0) dH = 0;
-        else{
+        else {
           //H value
           if (dMax == dR) {
             dH = 60 * (dG - dB) / dS;
@@ -622,7 +627,7 @@ void SJN_MultiCueBGS::BGR2HSVxyz_Par(uchar*** aBGR, uchar*** aXYZ){
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //												the function to get enlarged confidence map												   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::GetEnlargedMap(float** aOriginMap, float** aEnlargedMap){
+void MultiCue::GetEnlargedMap(float** aOriginMap, float** aEnlargedMap) {
   int i, j;
 
   short nSrcX;
@@ -639,8 +644,8 @@ void SJN_MultiCueBGS::GetEnlargedMap(float** aOriginMap, float** aEnlargedMap){
   double dScaleFactor_w = ((double)g_iWidth) / ((double)g_iRWidth);
   double dScaleFactor_h = ((double)g_iHeight) / ((double)g_iRHeight);
 
-  for (i = 0; i < g_iHeight; i++){
-    for (j = 0; j < g_iWidth; j++){
+  for (i = 0; i < g_iHeight; i++) {
+    for (j = 0; j < g_iWidth; j++) {
       //backward mapping
       nSrcY = (int)(i / dScaleFactor_h);
       nSrcX = (int)(j / dScaleFactor_w);
@@ -668,7 +673,7 @@ void SJN_MultiCueBGS::GetEnlargedMap(float** aOriginMap, float** aEnlargedMap){
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //										   				 the morphological operation function				    				   		   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::MorphologicalOpearions(uchar** aInput, uchar** aOutput, double dThresholdRatio, int iMaskSize, int iWidth, int iHeight){
+void MultiCue::MorphologicalOpearions(uchar** aInput, uchar** aOutput, double dThresholdRatio, int iMaskSize, int iWidth, int iHeight) {
 
   int iOffset = (int)(iMaskSize / 2);
 
@@ -676,28 +681,28 @@ void SJN_MultiCueBGS::MorphologicalOpearions(uchar** aInput, uchar** aOutput, do
   int iBound_h = iHeight - iOffset;
 
   uchar** aTemp = (uchar**)malloc(sizeof(uchar*)*iHeight);
-  for (int i = 0; i < iHeight; i++){
+  for (int i = 0; i < iHeight; i++) {
     aTemp[i] = (uchar*)malloc(sizeof(uchar)*iWidth);
   }
 
-  for (int i = 0; i < iHeight; i++){
-    for (int j = 0; j < iWidth; j++){
+  for (int i = 0; i < iHeight; i++) {
+    for (int j = 0; j < iWidth; j++) {
       aTemp[i][j] = aInput[i][j];
     }
   }
 
   int iThreshold = (int)(iMaskSize*iMaskSize*dThresholdRatio);
-  for (int i = 0; i < iHeight; i++){
-    for (int j = 0; j < iWidth; j++){
+  for (int i = 0; i < iHeight; i++) {
+    for (int j = 0; j < iWidth; j++) {
 
-      if (i < iOffset || i >= iBound_h || j < iOffset || j >= iBound_w){
+      if (i < iOffset || i >= iBound_h || j < iOffset || j >= iBound_w) {
         aOutput[i][j] = 0;
         continue;
       }
 
       int iCnt = 0;
-      for (int m = -iOffset; m <= iOffset; m++){
-        for (int n = -iOffset; n <= iOffset; n++){
+      for (int m = -iOffset; m <= iOffset; m++) {
+        for (int n = -iOffset; n <= iOffset; n++) {
           if (aTemp[i + m][j + n] == 255) iCnt++;
         }
       }
@@ -708,7 +713,7 @@ void SJN_MultiCueBGS::MorphologicalOpearions(uchar** aInput, uchar** aOutput, do
   }
 
 
-  for (int i = 0; i < iHeight; i++){
+  for (int i = 0; i < iHeight; i++) {
     free(aTemp[i]);
   }
   free(aTemp);
@@ -717,7 +722,7 @@ void SJN_MultiCueBGS::MorphologicalOpearions(uchar** aInput, uchar** aOutput, do
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //													2-raster scan pass based labeling function											   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::Labeling(uchar** aBinaryArray, int* pLabelCount, int** aLabelTable){
+void MultiCue::Labeling(uchar** aBinaryArray, int* pLabelCount, int** aLabelTable) {
   int x, y, i;		// pass 1,2
   int cnt = 0;		// pass 1
   int label = 0;	// pass 2
@@ -730,45 +735,45 @@ void SJN_MultiCueBGS::Labeling(uchar** aBinaryArray, int* pLabelCount, int** aLa
   int* aTable1 = (int*)malloc(iSize / 2 * sizeof(int));
   int* aTable2 = (int*)malloc(iSize / 2 * sizeof(int));
 
-  memset(aPass1, 0, (iSize)* sizeof(int));
-  for (y = 1; y < (g_iRHeight); y++){
-    for (x = 1; x < (g_iRWidth); x++){
+  memset(aPass1, 0, (iSize) * sizeof(int));
+  for (y = 1; y < (g_iRHeight); y++) {
+    for (x = 1; x < (g_iRWidth); x++) {
       aLabelTable[y][x] = 0;
     }
   }
 
-  for (i = 0; i < iTableSize; i++){
+  for (i = 0; i < iTableSize; i++) {
     aTable1[i] = i;
   }
   memset(aTable2, 0, iTableSize * sizeof(int));
 
   // pass 1
-  for (y = 1; y < (g_iRHeight); y++){
-    for (x = 1; x < (g_iRWidth); x++){
+  for (y = 1; y < (g_iRHeight); y++) {
+    for (x = 1; x < (g_iRWidth); x++) {
 
-      if (aBinaryArray[y][x] == 255){ // fore ground??
+      if (aBinaryArray[y][x] == 255) { // fore ground??
         int up, le;
 
         up = aPass1[(y - 1)*(g_iRWidth)+(x)]; // up  index
         le = aPass1[(y)*(g_iRWidth)+(x - 1)]; // left index
 
         // case
-        if (up == 0 && le == 0){
+        if (up == 0 && le == 0) {
           ++cnt;
           aPass1[y * g_iRWidth + x] = cnt;
 
         }
-        else if (up != 0 && le != 0){
-          if (up > le){
+        else if (up != 0 && le != 0) {
+          if (up > le) {
             aPass1[y *g_iRWidth + x] = le;
             aTable1[up] = aTable1[le]; // update table1 table1
           }
-          else{
+          else {
             aPass1[y * g_iRWidth + x] = up;
             aTable1[le] = aTable1[up]; // update table1 table1
           }
         }
-        else{
+        else {
           aPass1[y * g_iRWidth + x] = up + le;
         }
 
@@ -778,13 +783,13 @@ void SJN_MultiCueBGS::Labeling(uchar** aBinaryArray, int* pLabelCount, int** aLa
   }
 
   // pass 2
-  for (y = 1; y < (g_iRHeight); y++){
-    for (x = 1; x < (g_iRWidth); x++){
+  for (y = 1; y < (g_iRHeight); y++) {
+    for (x = 1; x < (g_iRWidth); x++) {
 
-      if (aPass1[y * g_iRWidth + x]){
+      if (aPass1[y * g_iRWidth + x]) {
         int v = aTable1[aPass1[y * g_iRWidth + x]];
 
-        if (aTable2[v] == 0){
+        if (aTable2[v] == 0) {
           ++label;
           aTable2[v] = label;
         }
@@ -804,12 +809,12 @@ void SJN_MultiCueBGS::Labeling(uchar** aBinaryArray, int* pLabelCount, int** aLa
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //									the function to set bounding boxes for each candidate foreground regions					    	   //																									   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::SetBoundingBox(int iLabelCount, int** aLabelTable){
+void MultiCue::SetBoundingBox(int iLabelCount, int** aLabelTable) {
   int iBoundBoxIndex;
 
   g_BoundBoxInfo->m_iBoundBoxNum = iLabelCount;
 
-  for (int i = 0; i < g_BoundBoxInfo->m_iBoundBoxNum; i++){
+  for (int i = 0; i < g_BoundBoxInfo->m_iBoundBoxNum; i++) {
     g_BoundBoxInfo->m_aRLeft[i] = 9999;		//left
     g_BoundBoxInfo->m_aRUpper[i] = 9999;	//top
     g_BoundBoxInfo->m_aRRight[i] = 0;		//right
@@ -817,8 +822,8 @@ void SJN_MultiCueBGS::SetBoundingBox(int iLabelCount, int** aLabelTable){
   }
 
   //Step1: Set tight bounding boxes
-  for (int i = 1; i<g_iRHeight; i++){
-    for (int j = 1; j<g_iRWidth; j++){
+  for (int i = 1; i < g_iRHeight; i++) {
+    for (int j = 1; j < g_iRWidth; j++) {
 
       if ((aLabelTable[i][j] == 0)) continue;
 
@@ -835,7 +840,7 @@ void SJN_MultiCueBGS::SetBoundingBox(int iLabelCount, int** aLabelTable){
   //Step2: Add margins.
   int iBoundary_w = (int)(g_iRWidth / 80), iBoundary_h = (int)(g_iRHeight / 60);
 
-  for (int i = 0; i < g_BoundBoxInfo->m_iBoundBoxNum; i++){
+  for (int i = 0; i < g_BoundBoxInfo->m_iBoundBoxNum; i++) {
 
     g_BoundBoxInfo->m_aRLeft[i] -= iBoundary_w;
     if (g_BoundBoxInfo->m_aRLeft[i] < g_nRadius) g_BoundBoxInfo->m_aRLeft[i] = g_nRadius;									//left
@@ -853,7 +858,7 @@ void SJN_MultiCueBGS::SetBoundingBox(int iLabelCount, int** aLabelTable){
   double dH_ratio = (double)g_iHeight / (double)g_iRHeight;
   double dW_ratio = (double)g_iWidth / (double)g_iRWidth;
 
-  for (int i = 0; i < g_BoundBoxInfo->m_iBoundBoxNum; i++){
+  for (int i = 0; i < g_BoundBoxInfo->m_iBoundBoxNum; i++) {
     g_BoundBoxInfo->m_aLeft[i] = (int)(g_BoundBoxInfo->m_aRLeft[i] * dW_ratio);
     g_BoundBoxInfo->m_aUpper[i] = (int)(g_BoundBoxInfo->m_aRUpper[i] * dH_ratio);
     g_BoundBoxInfo->m_aRight[i] = (int)(g_BoundBoxInfo->m_aRRight[i] * dW_ratio);
@@ -865,7 +870,7 @@ void SJN_MultiCueBGS::SetBoundingBox(int iLabelCount, int** aLabelTable){
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //														the box verification function													   //																							   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::BoundBoxVerification(IplImage* frame, uchar** aResForeMap, BoundingBoxInfo* BoundBoxInfo){
+void MultiCue::BoundBoxVerification(IplImage* frame, uchar** aResForeMap, BoundingBoxInfo* BoundBoxInfo) {
 
   //Step1: Verification by the bounding box size
   EvaluateBoxSize(BoundBoxInfo);
@@ -875,7 +880,7 @@ void SJN_MultiCueBGS::BoundBoxVerification(IplImage* frame, uchar** aResForeMap,
 
   //Step3: Counting the # of valid box
   g_iForegroundNum = 0;
-  for (int i = 0; i < BoundBoxInfo->m_iBoundBoxNum; i++){
+  for (int i = 0; i < BoundBoxInfo->m_iBoundBoxNum; i++) {
     if (BoundBoxInfo->m_ValidBox[i] == TRUE) g_iForegroundNum++;
   }
 }
@@ -883,7 +888,7 @@ void SJN_MultiCueBGS::BoundBoxVerification(IplImage* frame, uchar** aResForeMap,
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //																the size based verification												   //																							   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::EvaluateBoxSize(BoundingBoxInfo* BoundBoxInfo){
+void MultiCue::EvaluateBoxSize(BoundingBoxInfo* BoundBoxInfo) {
 
   //Set thresholds
   int iLowThreshold_w, iHighThreshold_w;
@@ -897,7 +902,7 @@ void SJN_MultiCueBGS::EvaluateBoxSize(BoundingBoxInfo* BoundBoxInfo){
   int iBoxWidth, iBoxHeight;
 
   //Perform verification.
-  for (int i = 0; i < BoundBoxInfo->m_iBoundBoxNum; i++){
+  for (int i = 0; i < BoundBoxInfo->m_iBoundBoxNum; i++) {
 
     iBoxWidth = BoundBoxInfo->m_aRRight[i] - BoundBoxInfo->m_aRLeft[i];
     iBoxHeight = BoundBoxInfo->m_aRBottom[i] - BoundBoxInfo->m_aRUpper[i];
@@ -912,7 +917,7 @@ void SJN_MultiCueBGS::EvaluateBoxSize(BoundingBoxInfo* BoundBoxInfo){
 //------------------------------------------------------------------------------------------------------------------------------------//
 //														overlapped region removal													  //
 //------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::EvaluateOverlapRegionSize(BoundingBoxInfo* SrcBoxInfo){
+void MultiCue::EvaluateOverlapRegionSize(BoundingBoxInfo* SrcBoxInfo) {
 
   BOOL *aValidBoxFlag = new BOOL[SrcBoxInfo->m_iBoundBoxNum];
   for (int i = 0; i < SrcBoxInfo->m_iBoundBoxNum; i++) aValidBoxFlag[i] = TRUE;
@@ -924,7 +929,7 @@ void SJN_MultiCueBGS::EvaluateOverlapRegionSize(BoundingBoxInfo* SrcBoxInfo){
   int iThreshold, iCount, iSmall_Idx, iLarge_Idx;
   double dThreRatio = 0.7;
 
-  for (int i = 0; i < SrcBoxInfo->m_iBoundBoxNum; i++){
+  for (int i = 0; i < SrcBoxInfo->m_iBoundBoxNum; i++) {
 
     if (SrcBoxInfo->m_ValidBox[i] == FALSE) {
       aValidBoxFlag[i] = FALSE;
@@ -933,7 +938,7 @@ void SJN_MultiCueBGS::EvaluateOverlapRegionSize(BoundingBoxInfo* SrcBoxInfo){
 
     size1 = (aRight[i] - aLeft[i]) * (aBottom[i] - aTop[i]);
 
-    for (int j = i; j < SrcBoxInfo->m_iBoundBoxNum; j++){
+    for (int j = i; j < SrcBoxInfo->m_iBoundBoxNum; j++) {
       if ((i == j) || (SrcBoxInfo->m_ValidBox[j] == FALSE)) continue;
 
       //Setting threshold for checking overlapped region size
@@ -950,8 +955,8 @@ void SJN_MultiCueBGS::EvaluateOverlapRegionSize(BoundingBoxInfo* SrcBoxInfo){
 
       //Calculating overlapped region size
       iCount = 0;
-      for (int m = aLeft[iSmall_Idx]; m < aRight[iSmall_Idx]; m++){
-        for (int n = aTop[iSmall_Idx]; n<aBottom[iSmall_Idx]; n++){
+      for (int m = aLeft[iSmall_Idx]; m < aRight[iSmall_Idx]; m++) {
+        for (int n = aTop[iSmall_Idx]; n < aBottom[iSmall_Idx]; n++) {
           if (aLeft[iLarge_Idx] <= m && m <= aRight[iLarge_Idx] && aTop[iLarge_Idx] <= n && n <= aBottom[iLarge_Idx]) iCount++;
         }
       }
@@ -968,20 +973,20 @@ void SJN_MultiCueBGS::EvaluateOverlapRegionSize(BoundingBoxInfo* SrcBoxInfo){
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //														appearance based verification													   //																							   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::EvaluateGhostRegion(IplImage* frame, uchar** aResForeMap, BoundingBoxInfo* BoundBoxInfo){
+void MultiCue::EvaluateGhostRegion(IplImage* frame, uchar** aResForeMap, BoundingBoxInfo* BoundBoxInfo) {
 
   double dThreshold = 10;
 
   BOOL** aUpdateMap = (BOOL**)malloc(sizeof(BOOL*)*g_iRHeight);
-  for (int i = 0; i < g_iRHeight; i++){
+  for (int i = 0; i < g_iRHeight; i++) {
     aUpdateMap[i] = (BOOL*)malloc(sizeof(BOOL)*g_iRWidth);
     for (int j = 0; j < g_iRWidth; j++) aUpdateMap[i][j] = FALSE;
   }
 
   //Step1: Conduct fore-region evaluation to identify ghost regions
 
-  for (int i = 0; i < BoundBoxInfo->m_iBoundBoxNum; i++){
-    if (BoundBoxInfo->m_ValidBox[i] == TRUE){
+  for (int i = 0; i < BoundBoxInfo->m_iBoundBoxNum; i++) {
+    if (BoundBoxInfo->m_ValidBox[i] == TRUE) {
       int iWin_w = BoundBoxInfo->m_aRRight[i] - BoundBoxInfo->m_aRLeft[i];
       int iWin_h = BoundBoxInfo->m_aRBottom[i] - BoundBoxInfo->m_aRUpper[i];
 
@@ -999,8 +1004,8 @@ void SJN_MultiCueBGS::EvaluateGhostRegion(IplImage* frame, uchar** aResForeMap,
 
       //Generating edge image from aResForeMap
       IplImage* edge_fore = cvCreateImage(cvSize(iWin_w, iWin_h), IPL_DEPTH_8U, 1);
-      for (int m = BoundBoxInfo->m_aRUpper[i]; m < BoundBoxInfo->m_aRBottom[i]; m++){
-        for (int n = BoundBoxInfo->m_aRLeft[i]; n<BoundBoxInfo->m_aRRight[i]; n++){
+      for (int m = BoundBoxInfo->m_aRUpper[i]; m < BoundBoxInfo->m_aRBottom[i]; m++) {
+        for (int n = BoundBoxInfo->m_aRLeft[i]; n < BoundBoxInfo->m_aRRight[i]; n++) {
           edge_fore->imageData[(m - BoundBoxInfo->m_aRUpper[i])*edge_fore->widthStep + (n - BoundBoxInfo->m_aRLeft[i])] = (char)aResForeMap[m][n];
         }
       }
@@ -1011,8 +1016,8 @@ void SJN_MultiCueBGS::EvaluateGhostRegion(IplImage* frame, uchar** aResForeMap,
       //Recording evaluation result
       if (distance > dThreshold) {
 
-        for (int m = BoundBoxInfo->m_aRUpper[i]; m < BoundBoxInfo->m_aRBottom[i]; m++){
-          for (int n = BoundBoxInfo->m_aRLeft[i]; n < BoundBoxInfo->m_aRRight[i]; n++){
+        for (int m = BoundBoxInfo->m_aRUpper[i]; m < BoundBoxInfo->m_aRBottom[i]; m++) {
+          for (int n = BoundBoxInfo->m_aRLeft[i]; n < BoundBoxInfo->m_aRRight[i]; n++) {
             aUpdateMap[m][n] = TRUE;
           }
         }
@@ -1029,9 +1034,9 @@ void SJN_MultiCueBGS::EvaluateGhostRegion(IplImage* frame, uchar** aResForeMap,
   //Step2: Adding information fo ghost region pixels to background model
   float fLearningRate = g_fLearningRate;
 
-  for (int i = 0; i < g_iRHeight; i++){
-    for (int j = 0; j < g_iRWidth; j++){
-      if (aUpdateMap[i][j] == TRUE){
+  for (int i = 0; i < g_iRHeight; i++) {
+    for (int j = 0; j < g_iRWidth; j++) {
+      if (aUpdateMap[i][j] == TRUE) {
         point center;
         center.m_nX = j; center.m_nY = i;
 
@@ -1053,16 +1058,16 @@ void SJN_MultiCueBGS::EvaluateGhostRegion(IplImage* frame, uchar** aResForeMap,
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //								the function to calculate partial undirected Hausdorff distance(forward distance)						   //																							   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-double SJN_MultiCueBGS::CalculateHausdorffDist(IplImage* input_image, IplImage* model_image){
+double MultiCue::CalculateHausdorffDist(IplImage* input_image, IplImage* model_image) {
 
   //Step1: Generating imag vectors
   //For reduce errors, points at the image boundary are excluded
-  vector<point> vInput, vModel;
+  std::vector<point> vInput, vModel;
   point temp;
 
-  //input image --> input vector 
-  for (int i = 0; i < input_image->height; i++){
-    for (int j = 0; j < input_image->width; j++){
+  //input image --> input vector
+  for (int i = 0; i < input_image->height; i++) {
+    for (int j = 0; j < input_image->width; j++) {
 
       if ((uchar)input_image->imageData[i*input_image->widthStep + j] == 0) continue;
 
@@ -1071,8 +1076,8 @@ double SJN_MultiCueBGS::CalculateHausdorffDist(IplImage* input_image, IplImage*
     }
   }
   //model image --> model vector
-  for (int i = 0; i < model_image->height; i++){
-    for (int j = 0; j < model_image->width; j++){
+  for (int i = 0; i < model_image->height; i++) {
+    for (int j = 0; j < model_image->width; j++) {
       if ((uchar)model_image->imageData[i*model_image->widthStep + j] == 0) continue;
 
       temp.m_nX = j; temp.m_nY = i;
@@ -1086,12 +1091,12 @@ double SJN_MultiCueBGS::CalculateHausdorffDist(IplImage* input_image, IplImage*
 
   //Step2: Calculating forward distance h(Model,Image)
   double dDist, temp1, temp2, dMinDist;
-  vector<double> vTempDist;
+  std::vector<double> vTempDist;
 
-  for (auto iter_m = vModel.begin(); iter_m < vModel.end(); iter_m++){
+  for (auto iter_m = vModel.begin(); iter_m < vModel.end(); iter_m++) {
 
     dMinDist = 9999999;
-    for (auto iter_i = vInput.begin(); iter_i < vInput.end(); iter_i++){
+    for (auto iter_i = vInput.begin(); iter_i < vInput.end(); iter_i++) {
       temp1 = (*iter_m).m_nX - (*iter_i).m_nX;
       temp2 = (*iter_m).m_nY - (*iter_i).m_nY;
       dDist = temp1*temp1 + temp2*temp2;
@@ -1114,15 +1119,15 @@ double SJN_MultiCueBGS::CalculateHausdorffDist(IplImage* input_image, IplImage*
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //											function to remove non-valid bounding boxes fore fore-candidates							   //												
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::RemovingInvalidForeRegions(uchar** aResForeMap, BoundingBoxInfo* BoundBoxInfo){
+void MultiCue::RemovingInvalidForeRegions(uchar** aResForeMap, BoundingBoxInfo* BoundBoxInfo) {
 
   int iBoxNum = BoundBoxInfo->m_iBoundBoxNum;
 
-  for (int k = 0; k < iBoxNum; k++){
+  for (int k = 0; k < iBoxNum; k++) {
 
-    if (BoundBoxInfo->m_ValidBox[k] == FALSE){
-      for (int i = BoundBoxInfo->m_aRUpper[k]; i < BoundBoxInfo->m_aRBottom[k]; i++){
-        for (int j = BoundBoxInfo->m_aRLeft[k]; j < BoundBoxInfo->m_aRRight[k]; j++){
+    if (BoundBoxInfo->m_ValidBox[k] == FALSE) {
+      for (int i = BoundBoxInfo->m_aRUpper[k]; i < BoundBoxInfo->m_aRBottom[k]; i++) {
+        for (int j = BoundBoxInfo->m_aRLeft[k]; j < BoundBoxInfo->m_aRRight[k]; j++) {
           if (aResForeMap[i][j] == 255) aResForeMap[i][j] = 0;
         }
       }
@@ -1134,15 +1139,15 @@ void SJN_MultiCueBGS::RemovingInvalidForeRegions(uchar** aResForeMap, BoundingBo
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //													the function returning a foreground binary-map										   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::GetForegroundMap(IplImage* return_image, IplImage* input_frame){
+void MultiCue::GetForegroundMap(IplImage* return_image, IplImage* input_frame) {
 
   if (g_bForegroundMapEnable == FALSE) return;
 
   IplImage* temp_image = cvCreateImage(cvSize(g_iRWidth, g_iRHeight), IPL_DEPTH_8U, 3);
 
-  if (input_frame == NULL){
-    for (int i = 0; i < g_iRHeight; i++){
-      for (int j = 0; j < g_iRWidth; j++){
+  if (input_frame == NULL) {
+    for (int i = 0; i < g_iRHeight; i++) {
+      for (int j = 0; j < g_iRWidth; j++) {
         temp_image->imageData[i*temp_image->widthStep + j * 3] = (char)g_aResizedForeMap[i][j];
         temp_image->imageData[i*temp_image->widthStep + j * 3 + 1] = (char)g_aResizedForeMap[i][j];
         temp_image->imageData[i*temp_image->widthStep + j * 3 + 2] = (char)g_aResizedForeMap[i][j];
@@ -1150,7 +1155,7 @@ void SJN_MultiCueBGS::GetForegroundMap(IplImage* return_image, IplImage* input_f
     }
   }
 
-  else{
+  else {
 
     cvResize(input_frame, temp_image);
     CvScalar MixColor;
@@ -1158,8 +1163,8 @@ void SJN_MultiCueBGS::GetForegroundMap(IplImage* return_image, IplImage* input_f
     MixColor.val[1] = 0;	//G
     MixColor.val[2] = 255;   //R
 
-    for (int i = 0; i < g_iRHeight; i++){
-      for (int j = 0; j < g_iRWidth; j++){
+    for (int i = 0; i < g_iRHeight; i++) {
+      for (int j = 0; j < g_iRWidth; j++) {
 
         if (g_aResizedForeMap[i][j] == 255) {
 
@@ -1187,15 +1192,15 @@ void SJN_MultiCueBGS::GetForegroundMap(IplImage* return_image, IplImage* input_f
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //												the	initialization function for the texture-models									       //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::T_AllocateTextureModelRelatedMemory(){
+void MultiCue::T_AllocateTextureModelRelatedMemory() {
   int i, j, k;
 
   //neighborhood system related
   int iMaxNeighborArraySize = 8;
   g_aNeighborDirection = (point***)malloc(sizeof(point**)*g_iRHeight);
-  for (i = 0; i < g_iRHeight; i++){
+  for (i = 0; i < g_iRHeight; i++) {
     g_aNeighborDirection[i] = (point**)malloc(sizeof(point*)*g_iRWidth);
-    for (j = 0; j < g_iRWidth; j++){
+    for (j = 0; j < g_iRWidth; j++) {
       g_aNeighborDirection[i][j] = (point*)malloc(sizeof(point)*iMaxNeighborArraySize);
     }
   }
@@ -1204,11 +1209,11 @@ void SJN_MultiCueBGS::T_AllocateTextureModelRelatedMemory(){
   //texture-model related
   int iElementArraySize = 6;
   g_TextureModel = (TextureModel****)malloc(sizeof(TextureModel***)*g_iRHeight);
-  for (i = 0; i < g_iRHeight; i++){
+  for (i = 0; i < g_iRHeight; i++) {
     g_TextureModel[i] = (TextureModel***)malloc(sizeof(TextureModel**)*g_iRWidth);
-    for (j = 0; j < g_iRWidth; j++){
+    for (j = 0; j < g_iRWidth; j++) {
       g_TextureModel[i][j] = (TextureModel**)malloc(sizeof(TextureModel*)*g_nNeighborNum);
-      for (k = 0; k < g_nNeighborNum; k++){
+      for (k = 0; k < g_nNeighborNum; k++) {
         g_TextureModel[i][j][k] = (TextureModel*)malloc(sizeof(TextureModel));
         g_TextureModel[i][j][k]->m_Codewords = (TextureCodeword**)malloc(sizeof(TextureCodeword*)*iElementArraySize);
         g_TextureModel[i][j][k]->m_iElementArraySize = iElementArraySize;
@@ -1223,16 +1228,16 @@ void SJN_MultiCueBGS::T_AllocateTextureModelRelatedMemory(){
   for (i = 0; i < g_iRHeight; i++) g_aTextureConfMap[i] = (float*)malloc(sizeof(float)*g_iRWidth);
 
   //cache-book related
-  if (g_bAbsorptionEnable == TRUE){
+  if (g_bAbsorptionEnable == TRUE) {
     iElementArraySize = iElementArraySize / 2;
     if (iElementArraySize < 3)iElementArraySize = 3;
 
     g_TCacheBook = (TextureModel****)malloc(sizeof(TextureModel***)*g_iRHeight);
-    for (i = 0; i < g_iRHeight; i++){
+    for (i = 0; i < g_iRHeight; i++) {
       g_TCacheBook[i] = (TextureModel***)malloc(sizeof(TextureModel**)*g_iRWidth);
-      for (j = 0; j < g_iRWidth; j++){
+      for (j = 0; j < g_iRWidth; j++) {
         g_TCacheBook[i][j] = (TextureModel**)malloc(sizeof(TextureModel*)*g_nNeighborNum);
-        for (k = 0; k < g_nNeighborNum; k++){
+        for (k = 0; k < g_nNeighborNum; k++) {
           g_TCacheBook[i][j][k] = (TextureModel*)malloc(sizeof(TextureModel));
           g_TCacheBook[i][j][k]->m_Codewords = (TextureCodeword**)malloc(sizeof(TextureCodeword*)*iElementArraySize);
           g_TCacheBook[i][j][k]->m_iElementArraySize = iElementArraySize;
@@ -1245,13 +1250,13 @@ void SJN_MultiCueBGS::T_AllocateTextureModelRelatedMemory(){
 
     g_aTReferredIndex = (short***)malloc(sizeof(short**)*g_iRHeight);
     g_aTContinuousCnt = (short***)malloc(sizeof(short**)*g_iRHeight);
-    for (i = 0; i < g_iRHeight; i++){
+    for (i = 0; i < g_iRHeight; i++) {
       g_aTReferredIndex[i] = (short**)malloc(sizeof(short*)*g_iRWidth);
       g_aTContinuousCnt[i] = (short**)malloc(sizeof(short*)*g_iRWidth);
       for (j = 0; j < g_iRWidth; j++) {
         g_aTReferredIndex[i][j] = (short*)malloc(sizeof(short)*g_nNeighborNum);
         g_aTContinuousCnt[i][j] = (short*)malloc(sizeof(short)*g_nNeighborNum);
-        for (k = 0; k < g_nNeighborNum; k++){
+        for (k = 0; k < g_nNeighborNum; k++) {
           g_aTReferredIndex[i][j][k] = -1;
           g_aTContinuousCnt[i][j][k] = 0;
         }
@@ -1262,13 +1267,13 @@ void SJN_MultiCueBGS::T_AllocateTextureModelRelatedMemory(){
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //															the memory release function											           //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::T_ReleaseTextureModelRelatedMemory(){
+void MultiCue::T_ReleaseTextureModelRelatedMemory() {
   int i, j, k, m;
   short nNeighborNum = g_nNeighborNum;
 
-  for (i = 0; i < g_iRHeight; i++){
-    for (j = 0; j < g_iRWidth; j++){
-      for (k = 0; k < nNeighborNum; k++){
+  for (i = 0; i < g_iRHeight; i++) {
+    for (j = 0; j < g_iRWidth; j++) {
+      for (k = 0; k < nNeighborNum; k++) {
         for (m = 0; m < g_TextureModel[i][j][k]->m_iNumEntries; m++) free(g_TextureModel[i][j][k]->m_Codewords[m]);
         free(g_TextureModel[i][j][k]->m_Codewords);
         free(g_TextureModel[i][j][k]);
@@ -1278,7 +1283,7 @@ void SJN_MultiCueBGS::T_ReleaseTextureModelRelatedMemory(){
   }
   free(g_TextureModel);
 
-  for (i = 0; i < g_iRHeight; i++){
+  for (i = 0; i < g_iRHeight; i++) {
     for (j = 0; j < g_iRWidth; j++) free(g_aNeighborDirection[i][j]);
     free(g_aNeighborDirection[i]);
   }
@@ -1287,10 +1292,10 @@ void SJN_MultiCueBGS::T_ReleaseTextureModelRelatedMemory(){
   for (i = 0; i < g_iRHeight; i++) free(g_aTextureConfMap[i]);
   free(g_aTextureConfMap);
 
-  if (g_bAbsorptionEnable == TRUE){
-    for (i = 0; i < g_iRHeight; i++){
-      for (j = 0; j < g_iRWidth; j++){
-        for (k = 0; k < nNeighborNum; k++){
+  if (g_bAbsorptionEnable == TRUE) {
+    for (i = 0; i < g_iRHeight; i++) {
+      for (j = 0; j < g_iRWidth; j++) {
+        for (k = 0; k < nNeighborNum; k++) {
           for (m = 0; m < g_TCacheBook[i][j][k]->m_iNumEntries; m++) free(g_TCacheBook[i][j][k]->m_Codewords[m]);
           free(g_TCacheBook[i][j][k]->m_Codewords);
           free(g_TCacheBook[i][j][k]);
@@ -1300,8 +1305,8 @@ void SJN_MultiCueBGS::T_ReleaseTextureModelRelatedMemory(){
     }
     free(g_TCacheBook);
 
-    for (i = 0; i < g_iRHeight; i++){
-      for (j = 0; j < g_iRWidth; j++){
+    for (i = 0; i < g_iRHeight; i++) {
+      for (j = 0; j < g_iRWidth; j++) {
         free(g_aTReferredIndex[i][j]);
         free(g_aTContinuousCnt[i][j]);
       }
@@ -1317,7 +1322,7 @@ void SJN_MultiCueBGS::T_ReleaseTextureModelRelatedMemory(){
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //														the codebook construction function				                                   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::T_ModelConstruction(short nTrainVolRange, float fLearningRate, uchar*** aXYZ, point center, point* aNei, TextureModel** aModel){
+void MultiCue::T_ModelConstruction(short nTrainVolRange, float fLearningRate, uchar*** aXYZ, point center, point* aNei, TextureModel** aModel) {
 
   int i, j;
   int iMatchedIndex;
@@ -1329,15 +1334,15 @@ void SJN_MultiCueBGS::T_ModelConstruction(short nTrainVolRange, float fLearningR
 
   float fNegLearningRate = 1 - fLearningRate;
 
-  //for all neighboring pairs 
-  for (i = 0; i < nNeighborNum; i++){
+  //for all neighboring pairs
+  for (i = 0; i < nNeighborNum; i++) {
 
     fDifference = (float)(aXYZ[center.m_nY][center.m_nX][2] - aXYZ[aNei[i].m_nY][aNei[i].m_nX][2]);
 
     //Step1: matching
     iMatchedIndex = -1;
-    for (j = 0; j < aModel[i]->m_iNumEntries; j++){
-      if (aModel[i]->m_Codewords[j]->m_fLowThre <= fDifference && fDifference <= aModel[i]->m_Codewords[j]->m_fHighThre){
+    for (j = 0; j < aModel[i]->m_iNumEntries; j++) {
+      if (aModel[i]->m_Codewords[j]->m_fLowThre <= fDifference && fDifference <= aModel[i]->m_Codewords[j]->m_fHighThre) {
         iMatchedIndex = j;
         break;
       }
@@ -1345,12 +1350,12 @@ void SJN_MultiCueBGS::T_ModelConstruction(short nTrainVolRange, float fLearningR
 
     aModel[i]->m_iTotal++;
     //Step2: adding a new element
-    if (iMatchedIndex == -1){
+    if (iMatchedIndex == -1) {
       //element array
-      if (aModel[i]->m_iElementArraySize == aModel[i]->m_iNumEntries){
+      if (aModel[i]->m_iElementArraySize == aModel[i]->m_iNumEntries) {
         aModel[i]->m_iElementArraySize += 5;
         TextureCodeword **temp = (TextureCodeword**)malloc(sizeof(TextureCodeword*)*aModel[i]->m_iElementArraySize);
-        for (j = 0; j < aModel[i]->m_iNumEntries; j++){
+        for (j = 0; j < aModel[i]->m_iNumEntries; j++) {
           temp[j] = aModel[i]->m_Codewords[j];
           aModel[i]->m_Codewords[j] = NULL;
         }
@@ -1370,7 +1375,7 @@ void SJN_MultiCueBGS::T_ModelConstruction(short nTrainVolRange, float fLearningR
     }
 
     //Step3: update
-    else{
+    else {
       fDiffMean = aModel[i]->m_Codewords[iMatchedIndex]->m_fMean;
       aModel[i]->m_Codewords[iMatchedIndex]->m_fMean = fLearningRate*fDifference + fNegLearningRate*fDiffMean;
 
@@ -1381,10 +1386,10 @@ void SJN_MultiCueBGS::T_ModelConstruction(short nTrainVolRange, float fLearningR
     }
 
     //cache-book handling
-    if (aModel[i]->m_bID == 1){
+    if (aModel[i]->m_bID == 1) {
       //1. m_iMNRL update
       int negTime;
-      for (j = 0; j < aModel[i]->m_iNumEntries; j++){
+      for (j = 0; j < aModel[i]->m_iNumEntries; j++) {
         //m_iMNRL update
         negTime = aModel[i]->m_iTotal - aModel[i]->m_Codewords[j]->m_iT_last_time + aModel[i]->m_Codewords[j]->m_iT_first_time - 1;
         if (aModel[i]->m_Codewords[j]->m_iMNRL < negTime) aModel[i]->m_Codewords[j]->m_iMNRL = negTime;
@@ -1395,18 +1400,18 @@ void SJN_MultiCueBGS::T_ModelConstruction(short nTrainVolRange, float fLearningR
       if (g_bAbsorptionEnable == TRUE) g_aTReferredIndex[center.m_nY][center.m_nX][i] = -1;
     }
 
-    else{
+    else {
       //1. m_iMNRL update
       if (iMatchedIndex == -1) aModel[i]->m_Codewords[aModel[i]->m_iNumEntries - 1]->m_iMNRL = 0;
 
       //2. g_aTReferredIndex[center.m_nY][center.m_nX][i] update
-      if (iMatchedIndex == -1){
+      if (iMatchedIndex == -1) {
         g_aTReferredIndex[center.m_nY][center.m_nX][i] = aModel[i]->m_iNumEntries - 1;
         g_aTContinuousCnt[center.m_nY][center.m_nX][i] = 1;
       }
-      else{
+      else {
         if (iMatchedIndex == g_aTReferredIndex[center.m_nY][center.m_nX][i]) g_aTContinuousCnt[center.m_nY][center.m_nX][i]++;
-        else{
+        else {
           g_aTReferredIndex[center.m_nY][center.m_nX][i] = iMatchedIndex;
           g_aTContinuousCnt[center.m_nY][center.m_nX][i] = 1;
         }
@@ -1420,7 +1425,7 @@ void SJN_MultiCueBGS::T_ModelConstruction(short nTrainVolRange, float fLearningR
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //												Clear non-essential codewords of the given codebook						                   //																									   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::T_ClearNonEssentialEntries(short nClearNum, TextureModel** aModel){
+void MultiCue::T_ClearNonEssentialEntries(short nClearNum, TextureModel** aModel) {
   int i, n;
   int iStaleThresh = (int)(nClearNum*0.5);
   int iKeepCnt;
@@ -1430,7 +1435,7 @@ void SJN_MultiCueBGS::T_ClearNonEssentialEntries(short nClearNum, TextureModel**
 
   TextureModel* c;
 
-  for (n = 0; n < nNeighborNum; n++){
+  for (n = 0; n < nNeighborNum; n++) {
     c = aModel[n];
 
     if (c->m_iTotal < nClearNum) continue; //(being operated only when c[w][h]->m_iTotal == nClearNum)
@@ -1441,7 +1446,7 @@ void SJN_MultiCueBGS::T_ClearNonEssentialEntries(short nClearNum, TextureModel**
     iKeepCnt = 0;
 
     //Step2: Find non-essential code-words
-    for (i = 0; i<c->m_iNumEntries; i++){
+    for (i = 0; i < c->m_iNumEntries; i++) {
       if (c->m_Codewords[i]->m_iMNRL > iStaleThresh) {
         aKeep[i] = 0; //removal candidate
       }
@@ -1452,20 +1457,20 @@ void SJN_MultiCueBGS::T_ClearNonEssentialEntries(short nClearNum, TextureModel**
     }
 
     //Step3: Perform removal
-    if (iKeepCnt == 0 || iKeepCnt == c->m_iNumEntries){
-      for (i = 0; i < c->m_iNumEntries; i++){
+    if (iKeepCnt == 0 || iKeepCnt == c->m_iNumEntries) {
+      for (i = 0; i < c->m_iNumEntries; i++) {
         c->m_Codewords[i]->m_iT_first_time = 1;
         c->m_Codewords[i]->m_iT_last_time = 1;
         c->m_Codewords[i]->m_iMNRL = 0;
       }
     }
 
-    else{
+    else {
       iKeepCnt = 0;
       TextureCodeword** temp = (TextureCodeword**)malloc(sizeof(TextureCodeword*)*c->m_iNumEntries);
 
-      for (i = 0; i < c->m_iNumEntries; i++){
-        if (aKeep[i] == 1){
+      for (i = 0; i < c->m_iNumEntries; i++) {
+        if (aKeep[i] == 1) {
           temp[iKeepCnt] = c->m_Codewords[i];
           temp[iKeepCnt]->m_iT_first_time = 1;
           temp[iKeepCnt]->m_iT_last_time = 1;
@@ -1491,21 +1496,21 @@ void SJN_MultiCueBGS::T_ClearNonEssentialEntries(short nClearNum, TextureModel**
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //								Clear non-essential codewords of the given codebook (only for the cache-book)			                   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::T_ClearNonEssentialEntriesForCachebook(uchar bLandmark, short* nReferredIdxArr, short nClearNum, TextureModel** pCachebook){
+void MultiCue::T_ClearNonEssentialEntriesForCachebook(uchar bLandmark, short* nReferredIdxArr, short nClearNum, TextureModel** pCachebook) {
   int i, n;
   short nNeighborNum = g_nNeighborNum;
 
   TextureModel* c;
   short nReferredIdx;
 
-  for (n = 0; n < nNeighborNum; n++){
+  for (n = 0; n < nNeighborNum; n++) {
 
     c = pCachebook[n];
     nReferredIdx = nReferredIdxArr[n];
 
     //pCachebook->m_iTotal < nClearNum? --> MNRL update
     if (c->m_iTotal < nClearNum) {
-      for (i = 0; i < c->m_iNumEntries; i++){
+      for (i = 0; i < c->m_iNumEntries; i++) {
         if (bLandmark == 255 && i == nReferredIdx) c->m_Codewords[i]->m_iMNRL = 0;
         else c->m_Codewords[i]->m_iMNRL++;
       }
@@ -1514,7 +1519,7 @@ void SJN_MultiCueBGS::T_ClearNonEssentialEntriesForCachebook(uchar bLandmark, sh
     }
 
     //Perform clearing
-    else{
+    else {
       int iStaleThreshold = 5;
 
       int* aKeep;
@@ -1523,8 +1528,8 @@ void SJN_MultiCueBGS::T_ClearNonEssentialEntriesForCachebook(uchar bLandmark, sh
       aKeep = (int*)malloc(sizeof(int)*c->m_iNumEntries);
       nKeepCnt = 0;
 
-      for (i = 0; i < c->m_iNumEntries; i++){
-        if (c->m_Codewords[i]->m_iMNRL < iStaleThreshold){
+      for (i = 0; i < c->m_iNumEntries; i++) {
+        if (c->m_Codewords[i]->m_iMNRL < iStaleThreshold) {
           aKeep[i] = 1;
           nKeepCnt++;
         }
@@ -1537,8 +1542,8 @@ void SJN_MultiCueBGS::T_ClearNonEssentialEntriesForCachebook(uchar bLandmark, sh
       TextureCodeword** temp = (TextureCodeword**)malloc(sizeof(TextureCodeword*)*c->m_iElementArraySize);
       nKeepCnt = 0;
 
-      for (i = 0; i < c->m_iNumEntries; i++){
-        if (aKeep[i] == 1){
+      for (i = 0; i < c->m_iNumEntries; i++) {
+        if (aKeep[i] == 1) {
           temp[nKeepCnt] = c->m_Codewords[i];
           temp[nKeepCnt]->m_iMNRL = 0;
           nKeepCnt++;
@@ -1564,7 +1569,7 @@ void SJN_MultiCueBGS::T_ClearNonEssentialEntriesForCachebook(uchar bLandmark, sh
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //											the function to generate texture confidence maps				                               //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::T_GetConfidenceMap_Par(uchar*** aXYZ, float** aTextureMap, point*** aNeiDirArr, TextureModel**** aModel){
+void MultiCue::T_GetConfidenceMap_Par(uchar*** aXYZ, float** aTextureMap, point*** aNeiDirArr, TextureModel**** aModel) {
 
   int iBound_w = g_iRWidth - g_nRadius;
   int iBound_h = g_iRHeight - g_nRadius;
@@ -1572,10 +1577,10 @@ void SJN_MultiCueBGS::T_GetConfidenceMap_Par(uchar*** aXYZ, float** aTextureMap,
   short nNeighborNum = g_nNeighborNum;
   float fPadding = 5;
 
-  for (int h = 0; h < g_iRHeight; h++){
-    for (int w = 0; w < g_iRWidth; w++){
+  for (int h = 0; h < g_iRHeight; h++) {
+    for (int w = 0; w < g_iRWidth; w++) {
 
-      if (h < g_nRadius || h >= iBound_h || w < g_nRadius || w >= iBound_w){
+      if (h < g_nRadius || h >= iBound_h || w < g_nRadius || w >= iBound_w) {
         aTextureMap[h][w] = 0;
         continue;
       }
@@ -1585,7 +1590,7 @@ void SJN_MultiCueBGS::T_GetConfidenceMap_Par(uchar*** aXYZ, float** aTextureMap,
       float fDifference;
       point nei;
 
-      for (int i = 0; i < nNeighborNum; i++){
+      for (int i = 0; i < nNeighborNum; i++) {
 
         nei.m_nX = aNeiDirArr[h][w][i].m_nX;
         nei.m_nY = aNeiDirArr[h][w][i].m_nY;
@@ -1594,8 +1599,8 @@ void SJN_MultiCueBGS::T_GetConfidenceMap_Par(uchar*** aXYZ, float** aTextureMap,
         if (fDifference < 0) fDiffSum -= fDifference;
         else fDiffSum += fDifference;
 
-        for (int j = 0; j < aModel[h][w][i]->m_iNumEntries; j++){
-          if (aModel[h][w][i]->m_Codewords[j]->m_fLowThre - fPadding <= fDifference && fDifference <= aModel[h][w][i]->m_Codewords[j]->m_fHighThre + fPadding){
+        for (int j = 0; j < aModel[h][w][i]->m_iNumEntries; j++) {
+          if (aModel[h][w][i]->m_Codewords[j]->m_fLowThre - fPadding <= fDifference && fDifference <= aModel[h][w][i]->m_Codewords[j]->m_fHighThre + fPadding) {
             nMatchedCount++;
             break;
           }
@@ -1609,21 +1614,21 @@ void SJN_MultiCueBGS::T_GetConfidenceMap_Par(uchar*** aXYZ, float** aTextureMap,
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //											Absorbing Ghost Non-background Region Update					                               //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::T_Absorption(int iAbsorbCnt, point pos, short*** aContinuCnt, short*** aRefferedIndex, TextureModel** pModel, TextureModel** pCache){
+void MultiCue::T_Absorption(int iAbsorbCnt, point pos, short*** aContinuCnt, short*** aRefferedIndex, TextureModel** pModel, TextureModel** pCache) {
   int i, j, k;
   int iLeavingIndex;
 
-  short g_nRadius = 2;
+  //short g_nRadius = 2;
   short nNeighborNum = g_nNeighborNum;
 
-  for (i = 0; i < nNeighborNum; i++){
+  for (i = 0; i < nNeighborNum; i++) {
     //set iLeavingIndex
     if (aContinuCnt[pos.m_nY][pos.m_nX][i] < iAbsorbCnt) continue;
 
     iLeavingIndex = aRefferedIndex[pos.m_nY][pos.m_nX][i];
 
     //array expansion
-    if (pModel[i]->m_iElementArraySize == pModel[i]->m_iNumEntries){
+    if (pModel[i]->m_iElementArraySize == pModel[i]->m_iNumEntries) {
       pModel[i]->m_iElementArraySize = pModel[i]->m_iElementArraySize + 5;
       TextureCodeword** temp = (TextureCodeword**)malloc(sizeof(TextureCodeword*)*pModel[i]->m_iElementArraySize);
       for (j = 0; j < pModel[i]->m_iNumEntries; j++) temp[j] = pModel[i]->m_Codewords[j];
@@ -1643,9 +1648,9 @@ void SJN_MultiCueBGS::T_Absorption(int iAbsorbCnt, point pos, short*** aContinuC
 
     k = 0;
     TextureCodeword **temp_Cache = (TextureCodeword**)malloc(sizeof(TextureCodeword*)*pCache[i]->m_iElementArraySize);
-    for (j = 0; j < pCache[i]->m_iNumEntries; j++){
+    for (j = 0; j < pCache[i]->m_iNumEntries; j++) {
       if (j == iLeavingIndex) continue;
-      else{
+      else {
         temp_Cache[k] = pCache[i]->m_Codewords[j];
         k++;
       }
@@ -1659,7 +1664,7 @@ void SJN_MultiCueBGS::T_Absorption(int iAbsorbCnt, point pos, short*** aContinuC
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //													the function to set neighborhood system												   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::T_SetNeighborDirection(point*** aNeighborPos){
+void MultiCue::T_SetNeighborDirection(point*** aNeighborPos) {
   int i, j, k;
   point* aSearchDirection = (point*)malloc(sizeof(point)*g_nNeighborNum);
 
@@ -1683,9 +1688,9 @@ void SJN_MultiCueBGS::T_SetNeighborDirection(point*** aNeighborPos){
 
   point temp_pos;
 
-  for (i = 0; i < g_iRHeight; i++){
-    for (j = 0; j < g_iRWidth; j++){
-      for (k = 0; k < g_nNeighborNum; k++){
+  for (i = 0; i < g_iRHeight; i++) {
+    for (j = 0; j < g_iRWidth; j++) {
+      for (k = 0; k < g_nNeighborNum; k++) {
         temp_pos.m_nX = j + aSearchDirection[k].m_nX;
         temp_pos.m_nY = i + aSearchDirection[k].m_nY;
 
@@ -1707,16 +1712,16 @@ void SJN_MultiCueBGS::T_SetNeighborDirection(point*** aNeighborPos){
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //													the color-model initialization function												   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::C_AllocateColorModelRelatedMemory(){
+void MultiCue::C_AllocateColorModelRelatedMemory() {
   int i, j;
 
   int iElementArraySize = 10;
 
   //codebook initialization
   g_ColorModel = (ColorModel***)malloc(sizeof(ColorModel**)*g_iRHeight);
-  for (i = 0; i < g_iRHeight; i++){
+  for (i = 0; i < g_iRHeight; i++) {
     g_ColorModel[i] = (ColorModel**)malloc(sizeof(ColorModel*)*g_iRWidth);
-    for (j = 0; j < g_iRWidth; j++){
+    for (j = 0; j < g_iRWidth; j++) {
       //initialization of each CodeBookArray.
       g_ColorModel[i][j] = (ColorModel*)malloc(sizeof(ColorModel));
       g_ColorModel[i][j]->m_Codewords = (ColorCodeword**)malloc(sizeof(ColorCodeword*)*iElementArraySize);
@@ -1728,13 +1733,13 @@ void SJN_MultiCueBGS::C_AllocateColorModelRelatedMemory(){
   }
 
   //cache-book initialization
-  if (g_bAbsorptionEnable == TRUE){
+  if (g_bAbsorptionEnable == TRUE) {
     iElementArraySize = 3;
 
     g_CCacheBook = (ColorModel***)malloc(sizeof(ColorModel**)*g_iRHeight);
-    for (i = 0; i < g_iRHeight; i++){
+    for (i = 0; i < g_iRHeight; i++) {
       g_CCacheBook[i] = (ColorModel**)malloc(sizeof(ColorModel*)*g_iRWidth);
-      for (j = 0; j < g_iRWidth; j++){
+      for (j = 0; j < g_iRWidth; j++) {
         //initialization of each CodeBookArray.
         g_CCacheBook[i][j] = (ColorModel*)malloc(sizeof(ColorModel));
         g_CCacheBook[i][j]->m_Codewords = (ColorCodeword**)malloc(sizeof(ColorCodeword*)*iElementArraySize);
@@ -1747,10 +1752,10 @@ void SJN_MultiCueBGS::C_AllocateColorModelRelatedMemory(){
 
     g_aCReferredIndex = (short**)malloc(sizeof(short*)*g_iRHeight);
     g_aCContinuousCnt = (short**)malloc(sizeof(short*)*g_iRHeight);
-    for (i = 0; i < g_iRHeight; i++){
+    for (i = 0; i < g_iRHeight; i++) {
       g_aCReferredIndex[i] = (short*)malloc(sizeof(short)*g_iRWidth);
       g_aCContinuousCnt[i] = (short*)malloc(sizeof(short)*g_iRWidth);
-      for (j = 0; j < g_iRWidth; j++){
+      for (j = 0; j < g_iRWidth; j++) {
         g_aCReferredIndex[i][j] = -1;
         g_aCContinuousCnt[i][j] = 0;
       }
@@ -1761,12 +1766,12 @@ void SJN_MultiCueBGS::C_AllocateColorModelRelatedMemory(){
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //															the memory release function											           //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::C_ReleaseColorModelRelatedMemory(){
+void MultiCue::C_ReleaseColorModelRelatedMemory() {
   int i, j, k;
 
-  for (i = 0; i < g_iRHeight; i++){
-    for (j = 0; j < g_iRWidth; j++){
-      for (k = 0; k < g_ColorModel[i][j]->m_iNumEntries; k++){
+  for (i = 0; i < g_iRHeight; i++) {
+    for (j = 0; j < g_iRWidth; j++) {
+      for (k = 0; k < g_ColorModel[i][j]->m_iNumEntries; k++) {
         free(g_ColorModel[i][j]->m_Codewords[k]);
       }
       free(g_ColorModel[i][j]->m_Codewords);
@@ -1776,10 +1781,10 @@ void SJN_MultiCueBGS::C_ReleaseColorModelRelatedMemory(){
   }
   free(g_ColorModel);
 
-  if (g_bAbsorptionEnable == TRUE){
-    for (i = 0; i < g_iRHeight; i++){
-      for (j = 0; j < g_iRWidth; j++){
-        for (k = 0; k < g_CCacheBook[i][j]->m_iNumEntries; k++){
+  if (g_bAbsorptionEnable == TRUE) {
+    for (i = 0; i < g_iRHeight; i++) {
+      for (j = 0; j < g_iRWidth; j++) {
+        for (k = 0; k < g_CCacheBook[i][j]->m_iNumEntries; k++) {
           free(g_CCacheBook[i][j]->m_Codewords[k]);
         }
         free(g_CCacheBook[i][j]->m_Codewords);
@@ -1789,7 +1794,7 @@ void SJN_MultiCueBGS::C_ReleaseColorModelRelatedMemory(){
     }
     free(g_CCacheBook);
 
-    for (i = 0; i < g_iRHeight; i++){
+    for (i = 0; i < g_iRHeight; i++) {
       free(g_aCReferredIndex[i]);
       free(g_aCContinuousCnt[i]);
     }
@@ -1801,7 +1806,7 @@ void SJN_MultiCueBGS::C_ReleaseColorModelRelatedMemory(){
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //														the codebook construction function								                   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::C_CodebookConstruction(uchar* aP, int iPosX, int iPosY, short nTrainVolRange, float fLearningRate, ColorModel* pC){
+void MultiCue::C_CodebookConstruction(uchar* aP, int iPosX, int iPosY, short nTrainVolRange, float fLearningRate, ColorModel* pC) {
 
   //Step1: matching
   short nMatchedIndex;
@@ -1810,14 +1815,14 @@ void SJN_MultiCueBGS::C_CodebookConstruction(uchar* aP, int iPosX, int iPosY, sh
 
   nMatchedIndex = -1;
 
-  for (int i = 0; i < pC->m_iNumEntries; i++){
+  for (int i = 0; i < pC->m_iNumEntries; i++) {
 
     //Checking X
-    if (pC->m_Codewords[i]->m_dMean[0] - nTrainVolRange <= aP[0] && aP[0] <= pC->m_Codewords[i]->m_dMean[0] + nTrainVolRange){
+    if (pC->m_Codewords[i]->m_dMean[0] - nTrainVolRange <= aP[0] && aP[0] <= pC->m_Codewords[i]->m_dMean[0] + nTrainVolRange) {
       //Checking Y
-      if (pC->m_Codewords[i]->m_dMean[1] - nTrainVolRange <= aP[1] && aP[1] <= pC->m_Codewords[i]->m_dMean[1] + nTrainVolRange){
+      if (pC->m_Codewords[i]->m_dMean[1] - nTrainVolRange <= aP[1] && aP[1] <= pC->m_Codewords[i]->m_dMean[1] + nTrainVolRange) {
         //Checking Z
-        if (pC->m_Codewords[i]->m_dMean[2] - nTrainVolRange <= aP[2] && aP[2] <= pC->m_Codewords[i]->m_dMean[2] + nTrainVolRange){
+        if (pC->m_Codewords[i]->m_dMean[2] - nTrainVolRange <= aP[2] && aP[2] <= pC->m_Codewords[i]->m_dMean[2] + nTrainVolRange) {
           nMatchedIndex = i;
           break;
         }
@@ -1828,11 +1833,11 @@ void SJN_MultiCueBGS::C_CodebookConstruction(uchar* aP, int iPosX, int iPosY, sh
   pC->m_iTotal = pC->m_iTotal + 1;
 
   //Step2 : adding a new element
-  if (nMatchedIndex == -1){
-    if (pC->m_iElementArraySize == pC->m_iNumEntries){
+  if (nMatchedIndex == -1) {
+    if (pC->m_iElementArraySize == pC->m_iNumEntries) {
       pC->m_iElementArraySize = pC->m_iElementArraySize + 5;
       ColorCodeword **temp = (ColorCodeword**)malloc(sizeof(ColorCodeword*)*pC->m_iElementArraySize);
-      for (int j = 0; j < pC->m_iNumEntries; j++){
+      for (int j = 0; j < pC->m_iNumEntries; j++) {
         temp[j] = pC->m_Codewords[j];
         pC->m_Codewords[j] = NULL;
       }
@@ -1853,7 +1858,7 @@ void SJN_MultiCueBGS::C_CodebookConstruction(uchar* aP, int iPosX, int iPosY, sh
   }
 
   //Step3 : update
-  else{
+  else {
     //m_dMean update
     pC->m_Codewords[nMatchedIndex]->m_dMean[0] = (fLearningRate*aP[0]) + fNegLearningRate*pC->m_Codewords[nMatchedIndex]->m_dMean[0];//X
     pC->m_Codewords[nMatchedIndex]->m_dMean[1] = (fLearningRate*aP[1]) + fNegLearningRate*pC->m_Codewords[nMatchedIndex]->m_dMean[1];//Y
@@ -1863,10 +1868,10 @@ void SJN_MultiCueBGS::C_CodebookConstruction(uchar* aP, int iPosX, int iPosY, sh
   }
 
   //cache-book handling
-  if (pC->m_bID == 1){
+  if (pC->m_bID == 1) {
     //1. m_iMNRL update
     int iNegTime;
-    for (int i = 0; i < pC->m_iNumEntries; i++){
+    for (int i = 0; i < pC->m_iNumEntries; i++) {
       //m_iMNRL update
       iNegTime = pC->m_iTotal - pC->m_Codewords[i]->m_iT_last_time + pC->m_Codewords[i]->m_iT_first_time - 1;
       if (pC->m_Codewords[i]->m_iMNRL < iNegTime) pC->m_Codewords[i]->m_iMNRL = iNegTime;
@@ -1876,18 +1881,18 @@ void SJN_MultiCueBGS::C_CodebookConstruction(uchar* aP, int iPosX, int iPosY, sh
     if (g_bAbsorptionEnable == TRUE) g_aCReferredIndex[iPosY][iPosX] = -1;
   }
 
-  else{
+  else {
     //1. m_iMNRL update:
     if (nMatchedIndex == -1) pC->m_Codewords[pC->m_iNumEntries - 1]->m_iMNRL = 0;
 
     //2. g_aCReferredIndex[iPosY][iPosX] update
-    if (nMatchedIndex == -1){
+    if (nMatchedIndex == -1) {
       g_aCReferredIndex[iPosY][iPosX] = pC->m_iNumEntries - 1;
       g_aCContinuousCnt[iPosY][iPosX] = 1;
     }
-    else{
+    else {
       if (nMatchedIndex == g_aCReferredIndex[iPosY][iPosX]) g_aCContinuousCnt[iPosY][iPosX]++;
-      else{
+      else {
         g_aCReferredIndex[iPosY][iPosX] = nMatchedIndex;
         g_aCContinuousCnt[iPosY][iPosX] = 1;
       }
@@ -1898,7 +1903,7 @@ void SJN_MultiCueBGS::C_CodebookConstruction(uchar* aP, int iPosX, int iPosY, sh
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //												Clear non-essential codewords of the given codebook							               //																													   //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::C_ClearNonEssentialEntries(short nClearNum, ColorModel* pModel){
+void MultiCue::C_ClearNonEssentialEntries(short nClearNum, ColorModel* pModel) {
   int i;
   short nStaleThresh = (int)(nClearNum*0.5);
   short nKeepCnt;
@@ -1914,7 +1919,7 @@ void SJN_MultiCueBGS::C_ClearNonEssentialEntries(short nClearNum, ColorModel* pM
   nKeepCnt = 0;
 
   //Step2: Find non-essential codewords
-  for (i = 0; i<pC->m_iNumEntries; i++){
+  for (i = 0; i < pC->m_iNumEntries; i++) {
     if (pC->m_Codewords[i]->m_iMNRL > nStaleThresh) {
       aKeep[i] = 0; //removal
     }
@@ -1925,19 +1930,19 @@ void SJN_MultiCueBGS::C_ClearNonEssentialEntries(short nClearNum, ColorModel* pM
   }
 
   //Step3: Perform removal
-  if (nKeepCnt == 0 || nKeepCnt == pC->m_iNumEntries){
-    for (i = 0; i < pC->m_iNumEntries; i++){
+  if (nKeepCnt == 0 || nKeepCnt == pC->m_iNumEntries) {
+    for (i = 0; i < pC->m_iNumEntries; i++) {
       pC->m_Codewords[i]->m_iT_first_time = 1;
       pC->m_Codewords[i]->m_iT_last_time = 1;
       pC->m_Codewords[i]->m_iMNRL = 0;
     }
   }
-  else{
+  else {
     nKeepCnt = 0;
     ColorCodeword** temp = (ColorCodeword**)malloc(sizeof(ColorCodeword*)*pC->m_iNumEntries);
 
-    for (i = 0; i < pC->m_iNumEntries; i++){
-      if (aKeep[i] == 1){
+    for (i = 0; i < pC->m_iNumEntries; i++) {
+      if (aKeep[i] == 1) {
         temp[nKeepCnt] = pC->m_Codewords[i];
         temp[nKeepCnt]->m_iT_first_time = 1;
         temp[nKeepCnt]->m_iT_last_time = 1;
@@ -1962,11 +1967,11 @@ void SJN_MultiCueBGS::C_ClearNonEssentialEntries(short nClearNum, ColorModel* pM
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //										Clear non-essential codewords of the given codebook (for cache-book)				               //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::C_ClearNonEssentialEntriesForCachebook(uchar bLandmark, short nReferredIdx, short nClearNum, ColorModel* pCachebook){
+void MultiCue::C_ClearNonEssentialEntriesForCachebook(uchar bLandmark, short nReferredIdx, short nClearNum, ColorModel* pCachebook) {
   int i;
 
   if (pCachebook->m_iTotal < nClearNum) {
-    for (i = 0; i < pCachebook->m_iNumEntries; i++){
+    for (i = 0; i < pCachebook->m_iNumEntries; i++) {
       if (bLandmark == 255 && i == nReferredIdx) pCachebook->m_Codewords[i]->m_iMNRL = 0;
       else pCachebook->m_Codewords[i]->m_iMNRL++;
     }
@@ -1974,7 +1979,7 @@ void SJN_MultiCueBGS::C_ClearNonEssentialEntriesForCachebook(uchar bLandmark, sh
     pCachebook->m_iTotal++;
   }
 
-  else{
+  else {
     int iStaleThreshold = 5;
 
     int* aKeep;
@@ -1983,8 +1988,8 @@ void SJN_MultiCueBGS::C_ClearNonEssentialEntriesForCachebook(uchar bLandmark, sh
     aKeep = (int*)malloc(sizeof(int)*pCachebook->m_iNumEntries);
     nKeepCnt = 0;
 
-    for (i = 0; i < pCachebook->m_iNumEntries; i++){
-      if (pCachebook->m_Codewords[i]->m_iMNRL < iStaleThreshold){
+    for (i = 0; i < pCachebook->m_iNumEntries; i++) {
+      if (pCachebook->m_Codewords[i]->m_iMNRL < iStaleThreshold) {
         aKeep[i] = 1;
         nKeepCnt++;
       }
@@ -1997,8 +2002,8 @@ void SJN_MultiCueBGS::C_ClearNonEssentialEntriesForCachebook(uchar bLandmark, sh
     ColorCodeword** temp = (ColorCodeword**)malloc(sizeof(ColorCodeword*)*pCachebook->m_iElementArraySize);
     nKeepCnt = 0;
 
-    for (i = 0; i < pCachebook->m_iNumEntries; i++){
-      if (aKeep[i] == 1){
+    for (i = 0; i < pCachebook->m_iNumEntries; i++) {
+      if (aKeep[i] == 1) {
         temp[nKeepCnt] = pCachebook->m_Codewords[i];
         temp[nKeepCnt]->m_iMNRL = 0;
         nKeepCnt++;
@@ -2022,7 +2027,7 @@ void SJN_MultiCueBGS::C_ClearNonEssentialEntriesForCachebook(uchar bLandmark, sh
 //-----------------------------------------------------------------------------------------------------------------------------------------//
 //														the ghost-region absorption function										       //
 //-----------------------------------------------------------------------------------------------------------------------------------------//
-void SJN_MultiCueBGS::C_Absorption(int iAbsorbCnt, point pos, short** aContinuCnt, short** aRefferedIndex, ColorModel* pModel, ColorModel* pCache){
+void MultiCue::C_Absorption(int iAbsorbCnt, point pos, short** aContinuCnt, short** aRefferedIndex, ColorModel* pModel, ColorModel* pCache) {
 
   //set iLeavingIndex
   if (aContinuCnt[pos.m_nY][pos.m_nX] < iAbsorbCnt) return;
@@ -2030,7 +2035,7 @@ void SJN_MultiCueBGS::C_Absorption(int iAbsorbCnt, point pos, short** aContinuCn
   int iLeavingIndex = aRefferedIndex[pos.m_nY][pos.m_nX];
 
   //array expansion
-  if (pModel->m_iElementArraySize == pModel->m_iNumEntries){
+  if (pModel->m_iElementArraySize == pModel->m_iNumEntries) {
     pModel->m_iElementArraySize = pModel->m_iElementArraySize + 5;
     ColorCodeword** temp = (ColorCodeword**)malloc(sizeof(ColorCodeword*)*pModel->m_iElementArraySize);
     for (int i = 0; i < pModel->m_iNumEntries; i++) temp[i] = pModel->m_Codewords[i];
@@ -2051,9 +2056,9 @@ void SJN_MultiCueBGS::C_Absorption(int iAbsorbCnt, point pos, short** aContinuCn
 
   int k = 0;
   ColorCodeword **pTempCache = (ColorCodeword**)malloc(sizeof(ColorCodeword*)*pCache->m_iElementArraySize);
-  for (int i = 0; i < pCache->m_iNumEntries; i++){
+  for (int i = 0; i < pCache->m_iNumEntries; i++) {
     if (i == iLeavingIndex) continue;
-    else{
+    else {
       pTempCache[k] = pCache->m_Codewords[i];
       k++;
     }
diff --git a/package_bgs/MultiCue.h b/package_bgs/MultiCue.h
new file mode 100644
index 0000000000000000000000000000000000000000..44524e0ab11c7b192cb4a26e0f5875f58749fa9a
--- /dev/null
+++ b/package_bgs/MultiCue.h
@@ -0,0 +1,254 @@
+/*
+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
+
+#define MIN3(x,y,z)  ((y) <= (z) ? ((x) <= (y) ? (x) : (y)) : ((x) <= (z) ? (x) : (z)))
+#define MAX3(x,y,z)  ((y) >= (z) ? ((x) >= (y) ? (x) : (y)) : ((x) >= (z) ? (x) : (z)))
+
+#ifndef PI
+#define PI 3.14159
+#endif
+
+typedef int BOOL;
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#if !defined(__APPLE__)
+#include <malloc.h>
+#endif
+#include "math.h"
+
+#include <vector>
+#include <algorithm>
+#include <opencv2/opencv.hpp>
+
+#include "IBGS.h"
+
+//------------------------------------Structure Lists-------------------------------------//
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    namespace libMultiCue
+    {
+      struct point {
+        short m_nX;
+        short m_nY;
+      };
+
+      struct neighbor_pos {
+        short m_nX;
+        short m_nY;
+      };
+      //1) Bounding Box Structure
+      struct BoundingBoxInfo {
+        int m_iBoundBoxNum;										//# of bounding boxes for all foreground and false-positive blobs
+        int m_iArraySize;										//the size of the below arrays to store bounding box information
+
+        short *m_aLeft, *m_aRight, *m_aUpper, *m_aBottom;		//arrays to store bounding box information for (the original frame size)
+        short *m_aRLeft, *m_aRRight, *m_aRUpper, *m_aRBottom;	//arrays to store bounding box information for (the reduced frame size)
+        BOOL* m_ValidBox;										//If this value is true, the corresponding bounding box is for a foreground blob.
+                                            //Else, it is for a false-positive blob
+      };
+
+      //2) Texture Model Structure
+      struct TextureCodeword {
+        int m_iMNRL;											//the maximum negative run-length
+        int m_iT_first_time;									//the first access time
+        int m_iT_last_time;										//the last access time
+
+        float m_fLowThre;										//a low threshold for the matching
+        float m_fHighThre;										//a high threshold for the matching
+        float m_fMean;											//mean of the codeword
+      };
+
+      struct TextureModel {
+        TextureCodeword** m_Codewords;							//the texture-codeword Array
+
+        int m_iTotal;											//# of learned samples after the last clear process
+        int m_iElementArraySize;								//the array size of m_Codewords
+        int m_iNumEntries;										//# of codewords
+
+        BOOL m_bID;												//id=1 --> background model, id=0 --> cachebook
+      };
+
+      //3) Color Model Structure
+      struct ColorCodeword {
+        int m_iMNRL;											//the maximum negative run-length
+        int m_iT_first_time;									//the first access time
+        int m_iT_last_time;										//the last access time
+
+        double m_dMean[3];										//mean vector of the codeword
+
+      };
+
+      struct ColorModel {
+        ColorCodeword** m_Codewords;							//the color-codeword Array
+
+        int m_iTotal;											//# of learned samples after the last clear process
+        int m_iElementArraySize;								//the array size of m_Codewords
+        int m_iNumEntries;										//# of codewords
+
+        BOOL m_bID;												//id=1 --> background model, id=0 --> cachebookk
+      };
+    }
+  }
+}
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    using namespace bgslibrary::algorithms::libMultiCue;
+
+    class MultiCue : public IBGS
+    {
+    private:
+      void saveConfig();
+      void loadConfig();
+
+    public:
+      MultiCue();
+      ~MultiCue();
+
+    public:
+      //----------------------------------------------------
+      //		APIs and User-Adjustable Parameters
+      //----------------------------------------------------
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);			//the main function to background modeling and subtraction
+
+      void GetForegroundMap(IplImage* return_image, IplImage* input_frame = NULL);					//the function returning a foreground binary-map
+      void Destroy();																				//the function to release allocated memories
+
+      int g_iTrainingPeriod;										//the training period								(The parameter t in the paper)
+      int g_iT_ModelThreshold;									//the threshold for texture-model based BGS.		(The parameter tau_T in the paper)
+      int g_iC_ModelThreshold;									//the threshold for appearance based verification.  (The parameter tau_A in the paper)
+
+      float g_fLearningRate;										//the learning rate for background models.			(The parameter alpha in the paper)
+
+      short g_nTextureTrainVolRange;								//the codebook size factor for texture models.		(The parameter k in the paper)
+      short g_nColorTrainVolRange;								//the codebook size factor for color models.		(The parameter eta_1 in the paper)
+
+    public:
+      //----------------------------------------------------
+      //	Implemented Function Lists
+      //----------------------------------------------------
+
+      //--1) General Functions
+      void Initialize(IplImage* frame);
+
+      void PreProcessing(IplImage* frame);
+      void ReduceImageSize(IplImage* SrcImage, IplImage* DstImage);
+      void GaussianFiltering(IplImage* frame, uchar*** aFilteredFrame);
+      void BGR2HSVxyz_Par(uchar*** aBGR, uchar*** aXYZ);
+
+      void BackgroundModeling_Par(IplImage* frame);
+      void ForegroundExtraction(IplImage* frame);
+      void CreateLandmarkArray_Par(float fConfThre, short nTrainVolRange, float**aConfMap, int iNehborNum, uchar*** aXYZ,
+        point*** aNeiDir, TextureModel**** TModel, ColorModel*** CModel, uchar**aLandmarkArr);
+
+      void PostProcessing(IplImage* frame);
+      void MorphologicalOpearions(uchar** aInput, uchar** aOutput, double dThresholdRatio, int iMaskSize, int iWidth, int iHeight);
+      void Labeling(uchar** aBinaryArray, int* pLabelCount, int** aLabelTable);
+      void SetBoundingBox(int iLabelCount, int** aLabelTable);
+      void BoundBoxVerification(IplImage* frame, uchar** aResForeMap, BoundingBoxInfo* BoundBoxInfo);
+      void EvaluateBoxSize(BoundingBoxInfo* BoundBoxInfo);
+      void EvaluateOverlapRegionSize(BoundingBoxInfo* SrcBoxInfo);
+      void EvaluateGhostRegion(IplImage* frame, uchar** aResForeMap, BoundingBoxInfo* BoundBoxInfo);
+      double CalculateHausdorffDist(IplImage* input_image, IplImage* model_image);
+      void RemovingInvalidForeRegions(uchar** aResForeMap, BoundingBoxInfo* BoundBoxInfo);
+
+      void UpdateModel_Par();
+      void GetEnlargedMap(float** aOriginMap, float** aEnlargedMap);
+
+      //--2) Texture Model Related Functions
+      void T_AllocateTextureModelRelatedMemory();
+      void T_ReleaseTextureModelRelatedMemory();
+      void T_SetNeighborDirection(point*** aNeighborPos);
+      void T_ModelConstruction(short nTrainVolRange, float fLearningRate, uchar*** aXYZ, point center, point* aNei, TextureModel** aModel);
+      void T_ClearNonEssentialEntries(short nClearNum, TextureModel** aModel);
+      void T_ClearNonEssentialEntriesForCachebook(uchar bLandmark, short* nReferredIdxArr, short nClearNum, TextureModel** pCachebook);
+      void T_GetConfidenceMap_Par(uchar*** aXYZ, float** aTextureMap, point*** aNeiDirArr, TextureModel**** aModel);
+      void T_Absorption(int iAbsorbCnt, point pos, short*** aContinuCnt, short*** aRefferedIndex, TextureModel** pModel, TextureModel** pCache);
+
+      //--3) Color Model Related Functions
+      void C_AllocateColorModelRelatedMemory();
+      void C_ReleaseColorModelRelatedMemory();
+      void C_CodebookConstruction(uchar* aP, int iPosX, int iPosY, short nTrainVolRange, float fLearningRate, ColorModel* pC);
+      void C_ClearNonEssentialEntries(short nClearNum, ColorModel* pModel);
+      void C_ClearNonEssentialEntriesForCachebook(uchar bLandmark, short nReferredIdx, short nClearNum, ColorModel* pCachebook);
+      void C_Absorption(int iAbsorbCnt, point pos, short** aContinuCnt, short** aRefferedIndex, ColorModel* pModel, ColorModel* pCache);
+    public:
+      //----------------------------------------------------
+      //	Implemented Variable Lists
+      //----------------------------------------------------
+
+      //--1) General Variables
+      int g_iFrameCount;							//the counter of processed frames
+
+      int g_iBackClearPeriod;						//the period to clear background models
+      int g_iCacheClearPeriod;					//the period to clear cache-book models
+
+      int g_iAbsortionPeriod;						//the period to absorb static ghost regions
+      BOOL g_bAbsorptionEnable;					//If True, procedures for ghost region absorption are activated.
+
+      BOOL g_bModelMemAllocated;					//To handle memory..
+      BOOL g_bNonModelMemAllocated;				//To handle memory..
+
+      float g_fConfidenceThre;					//the final decision threshold
+
+      int g_iWidth, g_iHeight;					//width and height of input frames
+      int g_iRWidth, g_iRHeight;					//width and height of reduced frames (For efficiency, the reduced size of frames are processed)
+      int g_iForegroundNum;						//# of detected foreground regions
+      BOOL g_bForegroundMapEnable;				//TRUE only when BGS is successful
+
+      IplImage* g_ResizedFrame;					//reduced size of frame (For efficiency, the reduced size of frames are processed)
+      uchar*** g_aGaussFilteredFrame;
+      uchar*** g_aXYZFrame;
+      uchar** g_aLandmarkArray;					//the landmark map
+      uchar** g_aResizedForeMap;					//the resized foreground map
+      uchar** g_aForegroundMap;					//the final foreground map
+      BOOL** g_aUpdateMap;						//the location map of update candidate pixels
+
+      BoundingBoxInfo* g_BoundBoxInfo;			//the array of bounding boxes of each foreground blob
+
+                                            //--2) Texture Model Related
+      TextureModel**** g_TextureModel;			//the texture background model
+      TextureModel**** g_TCacheBook;				//the texture cache-book
+      short*** g_aTReferredIndex;					//To handle cache-book
+      short*** g_aTContinuousCnt;					//To handle cache-book
+      point*** g_aNeighborDirection;
+      float**g_aTextureConfMap;					//the texture confidence map
+
+      short g_nNeighborNum;						//# of neighborhoods
+      short g_nRadius;
+      short g_nBoundarySize;
+
+      //--3) Texture Model Related
+      ColorModel*** g_ColorModel;					//the color background model
+      ColorModel*** g_CCacheBook;					//the color cache-book
+      short** g_aCReferredIndex;					//To handle cache-book
+      short** g_aCContinuousCnt;					//To handle cache-book
+    };
+  }
+}
diff --git a/package_bgs/jmo/MultiLayerBGS.cpp b/package_bgs/MultiLayer.cpp
similarity index 65%
rename from package_bgs/jmo/MultiLayerBGS.cpp
rename to package_bgs/MultiLayer.cpp
index 03e223f1f49e44816af126238d5a50f3217883f4..180d88d74a7fdded44fd4700038d3dbbe0ac9ade 100644
--- a/package_bgs/jmo/MultiLayerBGS.cpp
+++ b/package_bgs/MultiLayer.cpp
@@ -14,36 +14,40 @@ 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 "MultiLayerBGS.h"
+#include "MultiLayer.h"
 
-MultiLayerBGS::MultiLayerBGS() : firstTime(true), frameNumber(0), showOutput(true), 
-saveModel(false), disableDetectMode(true), disableLearning(false), detectAfter(0), bg_model_preload(""), loadDefaultParams(true)
+using namespace bgslibrary::algorithms;
+
+MultiLayer::MultiLayer() :
+  frameNumber(0), saveModel(false), disableDetectMode(true), disableLearning(false),
+  detectAfter(0), bg_model_preload(""), loadDefaultParams(true)
 {
-  std::cout << "MultiLayerBGS()" << std::endl;
+  std::cout << "MultiLayer()" << std::endl;
+  setup("./config/MultiLayer.xml");
 }
 
-MultiLayerBGS::~MultiLayerBGS()
+MultiLayer::~MultiLayer()
 {
   finish();
-  std::cout << "~MultiLayerBGS()" << std::endl;
+  std::cout << "~MultiLayer()" << std::endl;
 }
 
-void MultiLayerBGS::setStatus(Status _status)
+void MultiLayer::setStatus(Status _status)
 {
   status = _status;
 }
 
-void MultiLayerBGS::finish(void)
+void MultiLayer::finish()
 {
   if (bg_model_preload.empty())
   {
-    bg_model_preload = "./models/MultiLayerBGSModel.yml";
+    bg_model_preload = "./MultiLayerModel.yml";
     saveConfig();
   }
 
   if (status == MLBGS_LEARN && saveModel == true)
   {
-    std::cout << "MultiLayerBGS saving background model: " << bg_model_preload << std::endl;
+    std::cout << "MultiLayer saving background model: " << bg_model_preload << std::endl;
     BGS->Save(bg_model_preload.c_str());
   }
 
@@ -57,13 +61,9 @@ void MultiLayerBGS::finish(void)
   delete BGS;
 }
 
-void MultiLayerBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+void MultiLayer::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if (img_input.empty())
-    return;
-
-  loadConfig();
-
+  init(img_input, img_output, img_bgmodel);
   CvSize img_size = cvSize(cvCeil((double)img_input.size().width), cvCeil((double)img_input.size().height));
 
   if (firstTime)
@@ -72,10 +72,10 @@ void MultiLayerBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::M
       status = MLBGS_LEARN;
 
     if (status == MLBGS_LEARN)
-      std::cout << "MultiLayerBGS in LEARN mode" << std::endl;
+      std::cout << "MultiLayer in LEARN mode" << std::endl;
 
     if (status == MLBGS_DETECT)
-      std::cout << "MultiLayerBGS in DETECT mode" << std::endl;
+      std::cout << "MultiLayer in DETECT mode" << std::endl;
 
     org_img = new IplImage(img_input);
 
@@ -93,7 +93,7 @@ void MultiLayerBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::M
 
     if (bg_model_preload.empty() == false)
     {
-      std::cout << "MultiLayerBGS loading background model: " << bg_model_preload << std::endl;
+      std::cout << "MultiLayer loading background model: " << bg_model_preload << std::endl;
       BGS->Load(bg_model_preload.c_str());
     }
 
@@ -102,14 +102,14 @@ void MultiLayerBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::M
       BGS->m_disableLearning = disableLearning;
 
       if (disableLearning)
-        std::cout << "MultiLayerBGS disabled learning in DETECT mode" << std::endl;
+        std::cout << "MultiLayer disabled learning in DETECT mode" << std::endl;
       else
-        std::cout << "MultiLayerBGS enabled learning in DETECT mode" << std::endl;
+        std::cout << "MultiLayer enabled learning in DETECT mode" << std::endl;
     }
 
     if (loadDefaultParams)
     {
-      std::cout << "MultiLayerBGS loading default params" << std::endl;
+      std::cout << "MultiLayer loading default params" << std::endl;
 
       max_mode_num = 5;
       weight_updating_constant = 5.0;
@@ -127,7 +127,7 @@ void MultiLayerBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::M
       bilater_filter_sigma_r = 0.1f;
     }
     else
-      std::cout << "MultiLayerBGS loading config params" << std::endl;
+      std::cout << "MultiLayer loading config params" << std::endl;
 
     BGS->m_nMaxLBPModeNum = max_mode_num;
     BGS->m_fWeightUpdatingConstant = weight_updating_constant;
@@ -186,9 +186,6 @@ void MultiLayerBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::M
     }
 
     BGS->SetParameters(max_mode_num, mode_learn_rate_per_second, weight_learn_rate_per_second, init_mode_weight);
-
-    saveConfig();
-
     delete org_img;
   }
 
@@ -199,7 +196,7 @@ void MultiLayerBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::M
 
   if (detectAfter > 0 && detectAfter == frameNumber)
   {
-    std::cout << "MultiLayerBGS in DETECT mode" << std::endl;
+    std::cout << "MultiLayer in DETECT mode" << std::endl;
 
     status = MLBGS_DETECT;
 
@@ -212,9 +209,9 @@ void MultiLayerBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::M
     BGS->m_disableLearning = disableLearning;
 
     if (disableLearning)
-      std::cout << "MultiLayerBGS disabled learning in DETECT mode" << std::endl;
+      std::cout << "MultiLayer disabled learning in DETECT mode" << std::endl;
     else
-      std::cout << "MultiLayerBGS enabled learning in DETECT mode" << std::endl;
+      std::cout << "MultiLayer enabled learning in DETECT mode" << std::endl;
   }
 
   IplImage* img = new IplImage(img_input);
@@ -228,15 +225,17 @@ void MultiLayerBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::M
   BGS->GetForegroundMaskImage(fg_mask_img);
   BGS->MergeImages(4, img, bg_img, fg_prob_img3, fg_img, merged_img);
 
-  img_merged = cv::Mat(merged_img);
-  img_foreground = cv::Mat(fg_mask_img);
-  img_background = cv::Mat(bg_img);
+  img_merged = cv::cvarrToMat(merged_img);
+  img_foreground = cv::cvarrToMat(fg_mask_img);
+  img_background = cv::cvarrToMat(bg_img);
 
+#ifndef MEX_COMPILE_FLAG
   if (showOutput)
   {
     cv::imshow("MLBGS Layers", img_merged);
     cv::imshow("MLBGS FG Mask", img_foreground);
   }
+#endif
 
   img_foreground.copyTo(img_output);
   img_background.copyTo(img_bgmodel);
@@ -248,9 +247,9 @@ void MultiLayerBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::M
   frameNumber++;
 }
 
-void MultiLayerBGS::saveConfig()
+void MultiLayer::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/MultiLayerBGS.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteString(fs, "preloadModel", bg_model_preload.c_str());
   cvWriteInt(fs, "saveModel", saveModel);
@@ -289,43 +288,43 @@ void MultiLayerBGS::saveConfig()
   cvReleaseFileStorage(&fs);
 }
 
-void MultiLayerBGS::loadConfig()
+void MultiLayer::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/MultiLayerBGS.xml", 0, CV_STORAGE_READ);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
 
-  bg_model_preload = cvReadStringByName(fs, 0, "preloadModel", "");
-  saveModel = cvReadIntByName(fs, 0, "saveModel", false);
-  detectAfter = cvReadIntByName(fs, 0, "detectAfter", 0);
-  disableDetectMode = cvReadIntByName(fs, 0, "disableDetectMode", true);
-  disableLearning = cvReadIntByName(fs, 0, "disableLearningInDetecMode", false);
-  loadDefaultParams = cvReadIntByName(fs, 0, "loadDefaultParams", true);
+  bg_model_preload = cvReadStringByName(fs, nullptr, "preloadModel", "");
+  saveModel = cvReadIntByName(fs, nullptr, "saveModel", false);
+  detectAfter = cvReadIntByName(fs, nullptr, "detectAfter", 0);
+  disableDetectMode = cvReadIntByName(fs, nullptr, "disableDetectMode", true);
+  disableLearning = cvReadIntByName(fs, nullptr, "disableLearningInDetecMode", false);
+  loadDefaultParams = cvReadIntByName(fs, nullptr, "loadDefaultParams", true);
 
-  max_mode_num = cvReadIntByName(fs, 0, "max_mode_num", 5);
+  max_mode_num = cvReadIntByName(fs, nullptr, "max_mode_num", 5);
   weight_updating_constant = cvReadRealByName(fs, 0, "weight_updating_constant", 5.0);
-  texture_weight = cvReadRealByName(fs, 0, "texture_weight", 0.5);
-  bg_mode_percent = cvReadRealByName(fs, 0, "bg_mode_percent", 0.6);
-  pattern_neig_half_size = cvReadIntByName(fs, 0, "pattern_neig_half_size", 4);
-  pattern_neig_gaus_sigma = cvReadRealByName(fs, 0, "pattern_neig_gaus_sigma", 3.0);
-  bg_prob_threshold = cvReadRealByName(fs, 0, "bg_prob_threshold", 0.2);
-  bg_prob_updating_threshold = cvReadRealByName(fs, 0, "bg_prob_updating_threshold", 0.2);
-  robust_LBP_constant = cvReadIntByName(fs, 0, "robust_LBP_constant", 3);
-  min_noised_angle = cvReadRealByName(fs, 0, "min_noised_angle", 0.01768);
-  shadow_rate = cvReadRealByName(fs, 0, "shadow_rate", 0.6);
-  highlight_rate = cvReadRealByName(fs, 0, "highlight_rate", 1.2);
-  bilater_filter_sigma_s = cvReadRealByName(fs, 0, "bilater_filter_sigma_s", 3.0);
-  bilater_filter_sigma_r = cvReadRealByName(fs, 0, "bilater_filter_sigma_r", 0.1);
-
-  frame_duration = cvReadRealByName(fs, 0, "frame_duration", 0.1);
-
-  learn_mode_learn_rate_per_second = cvReadRealByName(fs, 0, "learn_mode_learn_rate_per_second", 0.5);
-  learn_weight_learn_rate_per_second = cvReadRealByName(fs, 0, "learn_weight_learn_rate_per_second", 0.5);
-  learn_init_mode_weight = cvReadRealByName(fs, 0, "learn_init_mode_weight", 0.05);
-
-  detect_mode_learn_rate_per_second = cvReadRealByName(fs, 0, "detect_mode_learn_rate_per_second", 0.01);
-  detect_weight_learn_rate_per_second = cvReadRealByName(fs, 0, "detect_weight_learn_rate_per_second", 0.01);
-  detect_init_mode_weight = cvReadRealByName(fs, 0, "detect_init_mode_weight", 0.001);
-
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  texture_weight = cvReadRealByName(fs, nullptr, "texture_weight", 0.5);
+  bg_mode_percent = cvReadRealByName(fs, nullptr, "bg_mode_percent", 0.6);
+  pattern_neig_half_size = cvReadIntByName(fs, nullptr, "pattern_neig_half_size", 4);
+  pattern_neig_gaus_sigma = cvReadRealByName(fs, nullptr, "pattern_neig_gaus_sigma", 3.0);
+  bg_prob_threshold = cvReadRealByName(fs, nullptr, "bg_prob_threshold", 0.2);
+  bg_prob_updating_threshold = cvReadRealByName(fs, nullptr, "bg_prob_updating_threshold", 0.2);
+  robust_LBP_constant = cvReadIntByName(fs, nullptr, "robust_LBP_constant", 3);
+  min_noised_angle = cvReadRealByName(fs, nullptr, "min_noised_angle", 0.01768);
+  shadow_rate = cvReadRealByName(fs, nullptr, "shadow_rate", 0.6);
+  highlight_rate = cvReadRealByName(fs, nullptr, "highlight_rate", 1.2);
+  bilater_filter_sigma_s = cvReadRealByName(fs, nullptr, "bilater_filter_sigma_s", 3.0);
+  bilater_filter_sigma_r = cvReadRealByName(fs, nullptr, "bilater_filter_sigma_r", 0.1);
+
+  frame_duration = cvReadRealByName(fs, nullptr, "frame_duration", 0.1);
+
+  learn_mode_learn_rate_per_second = cvReadRealByName(fs, nullptr, "learn_mode_learn_rate_per_second", 0.5);
+  learn_weight_learn_rate_per_second = cvReadRealByName(fs, nullptr, "learn_weight_learn_rate_per_second", 0.5);
+  learn_init_mode_weight = cvReadRealByName(fs, nullptr, "learn_init_mode_weight", 0.05);
+
+  detect_mode_learn_rate_per_second = cvReadRealByName(fs, nullptr, "detect_mode_learn_rate_per_second", 0.01);
+  detect_weight_learn_rate_per_second = cvReadRealByName(fs, nullptr, "detect_weight_learn_rate_per_second", 0.01);
+  detect_init_mode_weight = cvReadRealByName(fs, nullptr, "detect_init_mode_weight", 0.001);
+
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/MultiLayer.h b/package_bgs/MultiLayer.h
new file mode 100644
index 0000000000000000000000000000000000000000..af7e128c9c8230653486bc5d1673405034e0eab8
--- /dev/null
+++ b/package_bgs/MultiLayer.h
@@ -0,0 +1,99 @@
+/*
+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
+
+#include "IBGS.h"
+#include "MultiLayer/CMultiLayerBGS.h"
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class MultiLayer : public IBGS
+    {
+    public:
+      enum Status
+      {
+        MLBGS_NONE = -1,
+        MLBGS_LEARN = 0,
+        MLBGS_DETECT = 1
+      };
+
+    private:
+      long long frameNumber;
+      cv::Mat img_merged;
+      bool saveModel;
+      bool disableDetectMode;
+      bool disableLearning;
+      int detectAfter;
+      CMultiLayerBGS* BGS;
+      Status status;
+      IplImage* img;
+      IplImage* org_img;
+      IplImage* fg_img;
+      IplImage* bg_img;
+      IplImage* fg_prob_img;
+      IplImage* fg_mask_img;
+      IplImage* fg_prob_img3;
+      IplImage* merged_img;
+      std::string bg_model_preload;
+
+      bool loadDefaultParams;
+
+      int max_mode_num;
+      float weight_updating_constant;
+      float texture_weight;
+      float bg_mode_percent;
+      int pattern_neig_half_size;
+      float pattern_neig_gaus_sigma;
+      float bg_prob_threshold;
+      float bg_prob_updating_threshold;
+      int robust_LBP_constant;
+      float min_noised_angle;
+      float shadow_rate;
+      float highlight_rate;
+      float bilater_filter_sigma_s;
+      float bilater_filter_sigma_r;
+
+      float frame_duration;
+
+      float mode_learn_rate_per_second;
+      float weight_learn_rate_per_second;
+      float init_mode_weight;
+
+      float learn_mode_learn_rate_per_second;
+      float learn_weight_learn_rate_per_second;
+      float learn_init_mode_weight;
+
+      float detect_mode_learn_rate_per_second;
+      float detect_weight_learn_rate_per_second;
+      float detect_init_mode_weight;
+
+    public:
+      MultiLayer();
+      ~MultiLayer();
+
+      void setStatus(Status status);
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void finish();
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/jmo/BGS.h b/package_bgs/MultiLayer/BGS.h
similarity index 98%
rename from package_bgs/jmo/BGS.h
rename to package_bgs/MultiLayer/BGS.h
index c506df2ba9a6e4fa68f821fd92be2a2cbc771ed5..ad2129bccbfdfbce8164925eddfee7aef07853fb 100644
--- a/package_bgs/jmo/BGS.h
+++ b/package_bgs/MultiLayer/BGS.h
@@ -40,10 +40,9 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
-#if !defined(_BGS_H_)
-#define _BGS_H_
+#pragma once
 
-#include <opencv2/opencv.hpp>
+#include "OpenCvLegacyIncludes.h"
 
 
 // TODO check these defines are not used (or not redundant with real params)
@@ -211,6 +210,3 @@ class IMAGE_BG_MODEL
     delete[] pixel_PATTERNs;
   }
 };
-
-
-#endif // !defined(_BGS_H_)
diff --git a/package_bgs/jmo/BackgroundSubtractionAPI.h b/package_bgs/MultiLayer/BackgroundSubtractionAPI.h
similarity index 89%
rename from package_bgs/jmo/BackgroundSubtractionAPI.h
rename to package_bgs/MultiLayer/BackgroundSubtractionAPI.h
index bb396119623dc9a794821b395e46af5c4adcd366..409fa4049d2cda20f7c92506e90e16bc60e5cfed 100644
--- a/package_bgs/jmo/BackgroundSubtractionAPI.h
+++ b/package_bgs/MultiLayer/BackgroundSubtractionAPI.h
@@ -60,12 +60,9 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 //          char image for the output
 //
 //////////////////////////////////////////////////////////////////////
+#pragma once
 
-
-#if !defined(_BACKGROUND_SUBTRACTION_API_H_)
-#define _BACKGROUND_SUBTRACTION_API_H_
-
-#include <opencv2/opencv.hpp>
+#include "OpenCvLegacyIncludes.h"
 
 class CBackgroundSubtractionAPI
 {
@@ -79,14 +76,14 @@ public:
   void   Init(int width, int height);
 
   //-------------------------------------------------------------
-  // PROVIDE A MASK TO DEFINE THE SET OF POINTS WHERE BACKGROUND 
+  // PROVIDE A MASK TO DEFINE THE SET OF POINTS WHERE BACKGROUND
   // SUBTRACTION DOES NOT NEED TO BE PERFORMED
-  // 
-  //  mode is useful to specify if the points to remove from 
+  //
+  //  mode is useful to specify if the points to remove from
   //  processing are in addition to the ones potentially
   //  removed according to the configuration file,
-  //  or if they are the only ones to be removed 
-  // 
+  //  or if they are the only ones to be removed
+  //
   // mode=0 : provided points need to be removed
   //          in addition to those already removed
   // mode=1 : the provided points are the only one to remove
@@ -96,12 +93,12 @@ public:
   void   SetValidPointMask(IplImage* maskImage, int mode);
 
   //-------------------------------------------------------------
-  // 
+  //
   //   set the frame rate, to adjust the update parameters
   //   to the actual frame rate.
   //   Can be called only once at initialisation,
   //   but in online cases, can be used to indicate
-  //   the time interval during the last processed frame 
+  //   the time interval during the last processed frame
   //
   //   frameDuration is in millisecond
   void   SetFrameRate(float    frameDuration);
@@ -113,31 +110,31 @@ public:
   //   Here assumes that the input image will contain RGB images.
   //   The memory of this image is handled by the caller.
   //
-  //    The return value indicate whether the actual Background 
+  //    The return value indicate whether the actual Background
   //    Subtraction algorithm handles RGB images (1) or not (0).
-  //   
+  //
   int  SetRGBInputImage(IplImage  *  inputImage);
 
   //-------------------------------------------------------------
   //   PROVIDE A POINTER TO THE RESULT IMAGE
   //   INDICATE WHERE THE BACKGROUND RESULT NEED TO BE STORED
-  //  
+  //
   //   The return value is 1 if correct image format is provided,
   //   otherwise the return value is 0.
   //   e.g. fg_mask_img = cvCreateImage(imgSize, IPL_DEPTH_8U, 1);
   int  SetForegroundMaskImage(IplImage *fg_mask_img);
 
-  //   The return value is 1 if the function is implemented 
+  //   The return value is 1 if the function is implemented
   //   with correct format, otherwise the return value is 0
   //   e.g. fg_prob_img = cvCreateImage(imgSize, IPL_DEPTH_32F, 1);
   int  SetForegroundProbImage(IplImage *fg_prob_img);
 
   //-------------------------------------------------------------
-  // This function should be called each time a new image is 
+  // This function should be called each time a new image is
   // available in the input image.
-  // 
+  //
   // The return value is 1 if everything goes well,
-  // otherwise the return value is 0.  
+  // otherwise the return value is 0.
   //
   int   Process();
 
@@ -150,9 +147,7 @@ public:
 
   //-------------------------------------------------------------
   // this function should load the parameters necessary
-  // for the processing of the background subtraction or 
+  // for the processing of the background subtraction or
   // load background model information
   void   Load(char  *bg_model_fn);
 };
-
-#endif // !defined(_BACKGROUND_SUBTRACTION_API_H_)
diff --git a/package_bgs/jmo/BlobExtraction.cpp b/package_bgs/MultiLayer/BlobExtraction.cpp
similarity index 91%
rename from package_bgs/jmo/BlobExtraction.cpp
rename to package_bgs/MultiLayer/BlobExtraction.cpp
index 81857eb671e7432dd16e7fc048f52cb648ca5e55..7aecd65b2577f162333674f84c5263f7a0c32128 100644
--- a/package_bgs/jmo/BlobExtraction.cpp
+++ b/package_bgs/MultiLayer/BlobExtraction.cpp
@@ -55,47 +55,47 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 //! Indica si la connectivitat es a 8 (si es desactiva es a 4)
 #define B_CONNECTIVITAT_8
 
-//! si la imatge �s c�clica verticalment (els blobs que toquen
+//! si la imatge és cíclica verticalment (els blobs que toquen
 //! les vores superior i inferior no es consideren externs)
 #define IMATGE_CICLICA_VERTICAL		1
-//! si la imatge �s c�clica horitzontalment (els blobs que toquen
+//! si la imatge és cíclica horitzontalment (els blobs que toquen
 //! les vores dreta i esquerra no es consideren externs)
 #define IMATGE_CICLICA_HORITZONTAL	0
 
 #define PERIMETRE_DIAGONAL (1.41421356237310 - 2)
 #define SQRT2	1.41421356237310
-// color dels p�xels de la m�scara per ser exteriors
+// color dels píxels de la màscara per ser exteriors
 #define PIXEL_EXTERIOR 0
 
 
 #include "BlobResult.h"
 #include "BlobExtraction.h"
-#include <opencv2/legacy/compat.hpp>
+#include "OpenCvLegacyIncludes.h"
 
 namespace Blob
 {
 
   /**
-  - FUNCI�: BlobAnalysis
-  - FUNCIONALITAT: Extreu els blobs d'una imatge d'un sol canal
-  - PAR�METRES:
-  - inputImage: Imatge d'entrada. Ha de ser d'un sol canal
-  - threshold: Nivell de gris per considerar un pixel blanc o negre
-  - maskImage: Imatge de m�scara fora de la cual no es calculen els blobs. A m�s,
-  els blobs que toquen els pixels de la m�scara a 0, s�n considerats
-  externs
-  - borderColor: Color del marc de la imatge (0=black or 1=white)
-  - findmoments: calcula els moments dels blobs o no
-  - RegionData: on es desar� el resultat
-  - RESULTAT:
-  - retorna true si tot ha anat b�, false si no. Deixa el resultat a blobs.
-  - RESTRICCIONS:
-  - La imatge d'entrada ha de ser d'un sol canal
-  - AUTOR: dgrossman@cdr.stanford.edu
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  - fpinyol@cvc.uab.es, rborras@cvc.uab.es: adaptaci� a les OpenCV
-  */
+    - FUNCIÓ: BlobAnalysis
+    - FUNCIONALITAT: Extreu els blobs d'una imatge d'un sol canal
+    - PARÀMETRES:
+    - inputImage: Imatge d'entrada. Ha de ser d'un sol canal
+    - threshold: Nivell de gris per considerar un pixel blanc o negre
+    - maskImage: Imatge de màscara fora de la cual no es calculen els blobs. A més,
+    els blobs que toquen els pixels de la màscara a 0, són considerats
+    externs
+    - borderColor: Color del marc de la imatge (0=black or 1=white)
+    - findmoments: calcula els moments dels blobs o no
+    - RegionData: on es desarà el resultat
+    - RESULTAT:
+    - retorna true si tot ha anat bé, false si no. Deixa el resultat a blobs.
+    - RESTRICCIONS:
+    - La imatge d'entrada ha de ser d'un sol canal
+    - AUTOR: dgrossman@cdr.stanford.edu
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    - fpinyol@cvc.uab.es, rborras@cvc.uab.es: adaptació a les OpenCV
+    */
   bool BlobAnalysis(IplImage* inputImage,
     uchar threshold,
     IplImage* maskImage,
@@ -151,13 +151,13 @@ namespace Blob
       if (!CV_IS_IMAGE(inputImage) || !CV_IS_IMAGE(maskImage))
         return false;
 
-      // comprova que la m�scara tingui les mateixes dimensions que la imatge
+      // comprova que la màscara tingui les mateixes dimensions que la imatge
       if (inputImage->width != maskImage->width || inputImage->height != maskImage->height)
       {
         return false;
       }
 
-      // comprova que la m�scara sigui una imatge d'un sol canal (grayscale)
+      // comprova que la màscara sigui una imatge d'un sol canal (grayscale)
       if (maskImage->nChannels != 1)
       {
         return false;
@@ -167,16 +167,16 @@ namespace Blob
 
     // Initialize Transition array
     Transition = new int[(Rows + 2)*(Cols + 2)];
-    memset(Transition, 0, (Rows + 2) * (Cols + 2)*sizeof(int));
+    memset(Transition, 0, (Rows + 2) * (Cols + 2) * sizeof(int));
     Transition[0] = Transition[(Rows + 1) * (Cols + 2)] = Cols + 2;
 
     // Start at the beginning of the image (startCol, startRow)
     pImage = inputImage->imageData + startCol - 1 + startRow * inputImage->widthStep;
 
     /*
-    Paral�lelitzaci� del c�lcul de la matriu de transicions
-    Fem que cada iteraci� del for el faci un thread o l'altre ( tenim 2 possibles threads )
-    */
+      Paral·lelització del càlcul de la matriu de transicions
+      Fem que cada iteració del for el faci un thread o l'altre ( tenim 2 possibles threads )
+      */
     if (maskImage == NULL)
     {
       imatgePerimetreExtern = NULL;
@@ -184,7 +184,7 @@ namespace Blob
       //Fill Transition array
       for (iRow = 1; iRow < Rows + 1; iRow++)		// Choose a row of Bordered image
       {
-        TransitionOffset = iRow*(Cols + 2); //per a que sigui paral�litzable
+        TransitionOffset = iRow*(Cols + 2); //per a que sigui paral·litzable
         iTran = 0;					// Index into Transition array
         Tran = 0;					// No transitions at row start
         LastCell = borderColor;
@@ -218,12 +218,12 @@ namespace Blob
     }
     else
     {
-      //maskImage not NULL: Cal rec�rrer la m�scara tamb� per calcular la matriu de transicions
+      //maskImage not NULL: Cal recòrrer la màscara també per calcular la matriu de transicions
 
       char perimeter;
       char *pPerimetre;
 
-      // creem la imatge que contindr� el perimetre extern de cada pixel
+      // creem la imatge que contindrà el perimetre extern de cada pixel
       imatgePerimetreExtern = cvCreateImage(cvSize(maskImage->width, maskImage->height), IPL_DEPTH_8U, 1);
       cvSetZero(imatgePerimetreExtern);
 
@@ -255,9 +255,9 @@ namespace Blob
           }
 
           /*////////////////////////////////////////////////////////////////////////
-          Calcul de la imatge amb els pixels externs
-          ////////////////////////////////////////////////////////////////////////*/
-          // pels pixels externs no cal calcular res pq no hi accedir-hem
+            Calcul de la imatge amb els pixels externs
+            ////////////////////////////////////////////////////////////////////////*/
+            // pels pixels externs no cal calcular res pq no hi accedir-hem
           if ((iCol > 0) && (iCol < Cols))
           {
             if (*pMask == PIXEL_EXTERIOR)
@@ -277,7 +277,7 @@ namespace Blob
               // pixels a l'est i oest de l'actual
               if (iRow < imatgePerimetreExtern->height)
               {
-                if ((iCol>0) && (*(pMask - 1) == PIXEL_EXTERIOR)) perimeter++;
+                if ((iCol > 0) && (*(pMask - 1) == PIXEL_EXTERIOR)) perimeter++;
 
                 if ((iCol < imatgePerimetreExtern->width - 1) && (*(pMask + 1) == PIXEL_EXTERIOR)) perimeter++;
               }
@@ -323,7 +323,7 @@ namespace Blob
     // Last |xxx    |xxxxoo |xxxxxxx|xxxxxxx|ooxxxxx|ooxxx  |ooxxxxx|    xxx|
     // This |    yyy|    yyy|  yyyy |  yyyyy|yyyyyyy|yyyyyyy|yyyy   |yyyy   |
     // Here o is optional
-    // 
+    //
     // Here are the primitive tests to distinguish these 6 cases:
     //   A) Last end < This start - 1 OR NOT		Note: -1
     //   B) This end < Last start OR NOT
@@ -409,7 +409,7 @@ namespace Blob
     uchar imagevalue;
     bool CandidatExterior = false;
 
-    // apuntadors als blobs de la regi� actual i last
+    // apuntadors als blobs de la regió actual i last
     CBlob *regionDataThisRegion, *regionDataLastRegion;
 
     LastRegion = new int[Cols + 2];
@@ -431,7 +431,7 @@ namespace Blob
     ThisIndexCount = 1;
     ThisRegion[0] = 0;	// Border region
 
-    // beginning of the image 
+    // beginning of the image
     // en cada linia, pimage apunta al primer pixel de la fila
     pImage = inputImage->imageData - 1 + startCol + startRow * inputImage->widthStep;
     //the mask should be the same size as image Roi, so don't take into account the offset
@@ -457,9 +457,9 @@ namespace Blob
       {
         int Index = ThisOffset + j;
         int TranVal = Transition[Index];
-        if (TranVal > 0) ThisIndexCount = j + 1;	// stop at highest 
+        if (TranVal > 0) ThisIndexCount = j + 1;	// stop at highest
 
-        if (ThisRegion[j] == -1)  { EndLast = 1; }
+        if (ThisRegion[j] == -1) { EndLast = 1; }
         if (TranVal < 0) { EndThis = 1; }
 
         if (EndLast > 0 && EndThis > 0) { break; }
@@ -505,7 +505,7 @@ namespace Blob
 #endif
 #if !IMATGE_CICLICA_HORITZONTAL
           ThisStart <= 1 || ThisEnd >= Cols ||
-#endif				
+#endif
           GetExternPerimeter(ThisStart, ThisEnd, ThisRow, inputImage->width, inputImage->height, imatgePerimetreExtern)
           )
         {
@@ -601,7 +601,7 @@ namespace Blob
           //afegim la cantonada a ThisRegion
           if (ThisRegionNum != -1)
           {
-            // afegim dos vertexs si s�n diferents, nom�s
+            // afegim dos vertexs si són diferents, només
             if (ThisStart - 1 != ThisEnd)
             {
               actualedge.x = ThisStart - 1;
@@ -615,7 +615,7 @@ namespace Blob
           //afegim la cantonada a ThisRegion
           if (LastRegionNum != -1 && LastRegionNum != ThisRegionNum)
           {
-            // afegim dos vertexs si s�n diferents, nom�s
+            // afegim dos vertexs si són diferents, només
             if (ThisStart - 1 != ThisEnd)
             {
               actualedge.x = ThisStart - 1;
@@ -662,8 +662,8 @@ namespace Blob
             SubsumedRegion = NewSubsume(SubsumedRegion, HighRegionNum);
             if (CandidatExterior)
               ThisExternPerimeter = GetExternPerimeter(ThisStart, ThisEnd, ThisRow,
-              inputImage->width, inputImage->height,
-              imatgePerimetreExtern);
+                inputImage->width, inputImage->height,
+                imatgePerimetreExtern);
 
           }
 
@@ -728,8 +728,8 @@ namespace Blob
             SubsumedRegion = NewSubsume(SubsumedRegion, HighRegionNum);
             if (CandidatExterior)
               ThisExternPerimeter = GetExternPerimeter(ThisStart, ThisEnd, ThisRow,
-              inputImage->width, inputImage->height,
-              imatgePerimetreExtern);
+                inputImage->width, inputImage->height,
+                imatgePerimetreExtern);
 
           }
 
@@ -789,8 +789,8 @@ namespace Blob
             SubsumedRegion = NewSubsume(SubsumedRegion, HighRegionNum);
             if (CandidatExterior)
               ThisExternPerimeter = GetExternPerimeter(ThisStart, ThisEnd, ThisRow,
-              inputImage->width, inputImage->height,
-              imatgePerimetreExtern);
+                inputImage->width, inputImage->height,
+                imatgePerimetreExtern);
 
           }
           else if (TestMatch && !TestKnown)	// Same color and unknown
@@ -986,8 +986,8 @@ namespace Blob
             SubsumedRegion = NewSubsume(SubsumedRegion, HighRegionNum);
             if (CandidatExterior)
               ThisExternPerimeter = GetExternPerimeter(ThisStart, ThisEnd, ThisRow,
-              inputImage->width, inputImage->height,
-              imatgePerimetreExtern);
+                inputImage->width, inputImage->height,
+                imatgePerimetreExtern);
 
           }
           else if (TestMatch && !TestKnown)
@@ -1077,7 +1077,7 @@ namespace Blob
           //|yyyy   |
 
 #ifdef B_CONNECTIVITAT_8					
-          // fusionem blobs
+        // fusionem blobs
           if (TestMatch)
           {
             if (ThisRegionNum > LastRegionNum)
@@ -1159,7 +1159,7 @@ namespace Blob
 
           }
 
-          // compute the mean gray level and its std deviation 
+          // compute the mean gray level and its std deviation
           if (ThisRow <= Rows)
           {
             pImageAux = pImage + ThisStart;
@@ -1170,9 +1170,9 @@ namespace Blob
               {
                 if (maskImage != NULL)
                 {
-                  // nom�s es t� en compte el valor del p�xel de la
-                  // imatge que queda dins de la m�scara
-                  // (de pas, comptem el nombre de p�xels de la m�scara)
+                  // només es té en compte el valor del píxel de la
+                  // imatge que queda dins de la màscara
+                  // (de pas, comptem el nombre de píxels de la màscara)
                   if (((unsigned char)*pMaskAux) != PIXEL_EXTERIOR)
                   {
                     imagevalue = (unsigned char)(*pImageAux);
@@ -1200,7 +1200,7 @@ namespace Blob
           // compute the min and max values of X and Y
           if (ThisStart - 1 < (int)ThisMinX) ThisMinX = (float)(ThisStart - 1);
           if (ThisMinX < (float) 0.0) ThisMinX = (float) 0.0;
-          if (ThisEnd >(int) ThisMaxX) ThisMaxX = (float)ThisEnd;
+          if (ThisEnd > (int) ThisMaxX) ThisMaxX = (float)ThisEnd;
 
           if (ThisRow - 1 < ThisMinY) ThisMinY = ThisRow - 1;
           if (ThisMinY < (float) 0.0) ThisMinY = (float) 0.0;
@@ -1242,10 +1242,10 @@ namespace Blob
       }	// end Main loop
 
       if (ErrorFlag != 0) {
-          delete[] Transition;
-          delete[] ThisRegion;
-          delete[] LastRegion;
-          return false;
+        delete[] Transition;
+        delete[] ThisRegion;
+        delete[] LastRegion;
+        return false;
       }
       // ens situem al primer pixel de la seguent fila
       pImage = inputImage->imageData - 1 + startCol + (ThisRow + startRow) * inputImage->widthStep;
@@ -1254,19 +1254,19 @@ namespace Blob
         pMask = maskImage->imageData - 1 + ThisRow * maskImage->widthStep;
     }	// end Loop over all rows
 
-    // eliminem l'�rea del marc
-    // i tamb� els p�xels de la m�scara
+    // eliminem l'àrea del marc
+    // i també els píxels de la màscara
     // ATENCIO: PERFER: el fet de restar el nombre_pixels_mascara del
-    // blob 0 nom�s ser� cert si la m�scara t� contacte amb el marc.
-    // Si no, s'haur� de trobar quin �s el blob que cont� m�s p�xels del
+    // blob 0 només serà cert si la màscara té contacte amb el marc.
+    // Si no, s'haurà de trobar quin és el blob que conté més píxels del
     // compte.
     RegionData[0]->area -= (Rows + 1 + Cols + 1) * 2 + nombre_pixels_mascara;
 
-    // eliminem el per�metre de m�s:
-    // - sense marc: 2m+2n (per�metre extern)
+    // eliminem el perímetre de més:
+    // - sense marc: 2m+2n (perímetre extern)
     // - amb marc:   2(m+2)+2(n+2) = 2m+2n + 8
-    // (segurament no �s del tot acurat)
-    // (i amb les m�scares encara menys...)
+    // (segurament no és del tot acurat)
+    // (i amb les màscares encara menys...)
     RegionData[0]->perimeter -= 8.0;
 
     // Condense the list
@@ -1306,7 +1306,7 @@ namespace Blob
     if (findmoments)
     {
       iti = RegionData.begin();
-      // Normalize summation fields into moments 
+      // Normalize summation fields into moments
       for (ThisRegionNum = 0; ThisRegionNum <= HighRegionNum; ThisRegionNum++, iti++)
       {
         blobActual = *iti;
@@ -1340,10 +1340,10 @@ namespace Blob
         blobActual->stddev =
           sqrt(
           (
-          blobActual->stddev * blobActual->area -
-          blobActual->mean * blobActual->mean
-          ) /
-          (blobActual->area*(blobActual->area - 1))
+            blobActual->stddev * blobActual->area -
+            blobActual->mean * blobActual->mean
+            ) /
+            (blobActual->area*(blobActual->area - 1))
           );
       }
       else
@@ -1385,16 +1385,16 @@ namespace Blob
     }
     else
     {
-      subsumed = (int*)realloc(subsumed, (index_subsume + 1)*sizeof(int));
+      subsumed = (int*)realloc(subsumed, (index_subsume + 1) * sizeof(int));
     }
     subsumed[index_subsume] = 0;
     return subsumed;
   }
 
   /**
-  Fusiona dos blobs i afegeix el blob les caracter�stiques del blob RegionData[HiNum]
-  al blob RegionData[LoNum]. Al final allibera el blob de RegionData[HiNum]
-  */
+    Fusiona dos blobs i afegeix el blob les característiques del blob RegionData[HiNum]
+    al blob RegionData[LoNum]. Al final allibera el blob de RegionData[HiNum]
+    */
   void Subsume(blob_vector &RegionData,
     int HighRegionNum,
     int* SubsumedRegion,
@@ -1440,28 +1440,28 @@ namespace Blob
     // marquem el blob com a lliure
     blobHi->etiqueta = -1;
 
-    // Atenci�!!!! abans d'eliminar els edges 
+    // Atenció!!!! abans d'eliminar els edges
     // s'han de traspassar del blob HiNum al blob LoNum
     blobHi->CopyEdges(*blobLo);
     blobHi->ClearEdges();
   }
 
   /**
-  - FUNCI�: GetExternPerimeter
-  - FUNCIONALITAT: Retorna el perimetre extern d'una run lenght
-  - PAR�METRES:
-  - start: columna d'inici del run
-  - end: columna final del run
-  - row: fila del run
-  - maskImage: m�scara pels pixels externs
-  - RESULTAT:
-  - quantitat de perimetre extern d'un run, suposant que �s un blob
-  d'una �nica fila d'al�ada
-  - RESTRICCIONS:
-  - AUTOR:
-  - DATA DE CREACI�: 2006/02/27
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
+    - FUNCIÓ: GetExternPerimeter
+    - FUNCIONALITAT: Retorna el perimetre extern d'una run lenght
+    - PARÀMETRES:
+    - start: columna d'inici del run
+    - end: columna final del run
+    - row: fila del run
+    - maskImage: màscara pels pixels externs
+    - RESULTAT:
+    - quantitat de perimetre extern d'un run, suposant que és un blob
+    d'una única fila d'alçada
+    - RESTRICCIONS:
+    - AUTOR:
+    - DATA DE CREACIÓ: 2006/02/27
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
   double GetExternPerimeter(int start, int end, int row, int width, int height, IplImage *imatgePerimetreExtern)
   {
     double perimeter = 0.0f;
@@ -1474,7 +1474,7 @@ namespace Blob
     if (row >= height - 1) perimeter += start - end;
 
 
-    // comprovem els pixels que toquen a la m�scara (si s'escau)
+    // comprovem els pixels que toquen a la màscara (si s'escau)
     if (imatgePerimetreExtern != NULL)
     {
       if (row <= 0 || row >= height) return perimeter;
diff --git a/package_bgs/jmo/BlobExtraction.h b/package_bgs/MultiLayer/BlobExtraction.h
similarity index 96%
rename from package_bgs/jmo/BlobExtraction.h
rename to package_bgs/MultiLayer/BlobExtraction.h
index 9f47b02ad12efeba33657764544211706233c144..d8bd1af5dc762d0434311e0f6bac9c373b7af64f 100644
--- a/package_bgs/jmo/BlobExtraction.h
+++ b/package_bgs/MultiLayer/BlobExtraction.h
@@ -49,10 +49,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 //* Email: dgrossman@cdr.stanford.edu                       *//
 //* Acknowledgement: the algorithm has been around > 20 yrs *//
 //***********************************************************//
-
-
-#if !defined(_CLASSE_BLOBEXTRACTION_INCLUDED)
-#define _CLASSE_BLOBEXTRACTION_INCLUDED
+#pragma once
 
 namespace Blob
 {
@@ -71,6 +68,3 @@ namespace Blob
   //! Retorna el perimetre extern d'una run lenght
   double GetExternPerimeter(int start, int end, int row, int width, int height, IplImage *maskImage);
 }
-
-#endif //_CLASSE_BLOBEXTRACTION_INCLUDED
-
diff --git a/package_bgs/jmo/BlobLibraryConfiguration.h b/package_bgs/MultiLayer/BlobLibraryConfiguration.h
similarity index 95%
rename from package_bgs/jmo/BlobLibraryConfiguration.h
rename to package_bgs/MultiLayer/BlobLibraryConfiguration.h
index b864fc76dae998fc301eacf20b59b907220b43f3..0ba18fc3ac1d846e054a17ab9087915e9a50d2b8 100644
--- a/package_bgs/jmo/BlobLibraryConfiguration.h
+++ b/package_bgs/MultiLayer/BlobLibraryConfiguration.h
@@ -43,15 +43,16 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 /************************************************************************
 BlobLibraryConfiguration.h
 
-FUNCIONALITAT: Configuraci� del comportament global de la llibreria
+FUNCIONALITAT: Configuració del comportament global de la llibreria
 AUTOR: Inspecta S.L.
-MODIFICACIONS (Modificaci�, Autor, Data):
+MODIFICACIONS (Modificació, Autor, Data):
 
 FUNCTIONALITY: Global configuration of the library
 AUTHOR: Inspecta S.L.
 MODIFICATIONS (Modification, Author, Date):
 
 **************************************************************************/
+#pragma once
 
 //! Indica si es volen fer servir les MatrixCV o no
 //! Use/Not use the MatrixCV class
diff --git a/package_bgs/MultiLayer/BlobResult.cpp b/package_bgs/MultiLayer/BlobResult.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1ec60e35e0ddc24dbef325abb7f9b9fffa5e7633
--- /dev/null
+++ b/package_bgs/MultiLayer/BlobResult.cpp
@@ -0,0 +1,847 @@
+/*
+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/>.
+*/
+/* --- --- ---
+* Copyright (C) 2008--2010 Idiap Research Institute (.....@idiap.ch)
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+* 3. The name of the author may not be used to endorse or promote products
+*    derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/************************************************************************
+BlobResult.cpp
+
+FUNCIONALITAT: Implementació de la classe CBlobResult
+AUTOR: Inspecta S.L.
+MODIFICACIONS (Modificació, Autor, Data):
+
+**************************************************************************/
+
+#include <limits.h>
+#include <stdio.h>
+#include <functional>
+#include <algorithm>
+#include "BlobResult.h"
+#include "BlobExtraction.h"
+
+/**************************************************************************
+Constructors / Destructors
+**************************************************************************/
+
+namespace Blob
+{
+
+  /**
+    - FUNCIÓ: CBlobResult
+    - FUNCIONALITAT: Constructor estandard.
+    - PARÀMETRES:
+    - RESULTAT:
+    - Crea un CBlobResult sense cap blob
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 20-07-2004.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: CBlobResult
+      - FUNCTIONALITY: Standard constructor
+      - PARAMETERS:
+      - RESULT:
+      - creates an empty set of blobs
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  CBlobResult::CBlobResult()
+  {
+    m_blobs = blob_vector();
+  }
+
+  /**
+    - FUNCIÓ: CBlobResult
+    - FUNCIONALITAT: Constructor a partir d'una imatge. Inicialitza la seqüència de blobs
+    amb els blobs resultants de l'anàlisi de blobs de la imatge.
+    - PARÀMETRES:
+    - source: imatge d'on s'extreuran els blobs
+    - mask: màscara a aplicar. Només es calcularan els blobs on la màscara sigui
+    diferent de 0. Els blobs que toquin a un pixel 0 de la màscara seran
+    considerats exteriors.
+    - threshold: llindar que s'aplicarà a la imatge source abans de calcular els blobs
+    - findmoments: indica si s'han de calcular els moments de cada blob
+    - RESULTAT:
+    - objecte CBlobResult amb els blobs de la imatge source
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: CBlob
+      - FUNCTIONALITY: Constructor from an image. Fills an object with all the blobs in
+      the image
+      - PARAMETERS:
+      - source: image to extract the blobs from
+      - mask: optional mask to apply. The blobs will be extracted where the mask is
+      not 0. All the neighbouring blobs where the mask is 0 will be extern blobs
+      - threshold: threshold level to apply to the image before computing blobs
+      - findmoments: true to calculate the blob moments (slower)
+      - RESULT:
+      - object with all the blobs in the image. It throws an EXCEPCIO_CALCUL_BLOBS
+      if some error appears in the BlobAnalysis function
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  CBlobResult::CBlobResult(IplImage *source, IplImage *mask, int threshold, bool findmoments)
+  {
+    bool success;
+
+    try
+    {
+      // cridem la funció amb el marc a true=1=blanc (així no unirà els blobs externs)
+      success = BlobAnalysis(source, (uchar)threshold, mask, true, findmoments, m_blobs);
+    }
+    catch (...)
+    {
+      success = false;
+    }
+
+    if (!success) throw EXCEPCIO_CALCUL_BLOBS;
+  }
+
+  /**
+    - FUNCIÓ: CBlobResult
+    - FUNCIONALITAT: Constructor de còpia. Inicialitza la seqüència de blobs
+    amb els blobs del paràmetre.
+    - PARÀMETRES:
+    - source: objecte que es copiarà
+    - RESULTAT:
+    - objecte CBlobResult amb els blobs de l'objecte source
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: CBlobResult
+      - FUNCTIONALITY: Copy constructor
+      - PARAMETERS:
+      - source: object to copy
+      - RESULT:
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  CBlobResult::CBlobResult(const CBlobResult &source)
+  {
+    m_blobs = blob_vector(source.GetNumBlobs());
+
+    // creem el nou a partir del passat com a paràmetre
+    m_blobs = blob_vector(source.GetNumBlobs());
+    // copiem els blobs de l'origen a l'actual
+    blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
+    blob_vector::iterator pBlobsDst = m_blobs.begin();
+
+    while (pBlobsSrc != source.m_blobs.end())
+    {
+      // no podem cridar a l'operador = ja que blob_vector és un
+      // vector de CBlob*. Per tant, creem un blob nou a partir del
+      // blob original
+      *pBlobsDst = new CBlob(**pBlobsSrc);
+      ++pBlobsSrc;
+      ++pBlobsDst;
+    }
+  }
+
+
+
+  /**
+    - FUNCIÓ: ~CBlobResult
+    - FUNCIONALITAT: Destructor estandard.
+    - PARÀMETRES:
+    - RESULTAT:
+    - Allibera la memòria reservada de cadascun dels blobs de la classe
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: ~CBlobResult
+      - FUNCTIONALITY: Destructor
+      - PARAMETERS:
+      - RESULT:
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  CBlobResult::~CBlobResult()
+  {
+    ClearBlobs();
+  }
+
+  /**************************************************************************
+    Operadors / Operators
+    **************************************************************************/
+
+
+    /**
+      - FUNCIÓ: operador =
+      - FUNCIONALITAT: Assigna un objecte source a l'actual
+      - PARÀMETRES:
+      - source: objecte a assignar
+      - RESULTAT:
+      - Substitueix els blobs actuals per els de l'objecte source
+      - RESTRICCIONS:
+      - AUTOR: Ricard Borràs
+      - DATA DE CREACIÓ: 25-05-2005.
+      - MODIFICACIÓ: Data. Autor. Descripció.
+      */
+      /**
+        - FUNCTION: Assigment operator
+        - FUNCTIONALITY:
+        - PARAMETERS:
+        - RESULT:
+        - RESTRICTIONS:
+        - AUTHOR: Ricard Borràs
+        - CREATION DATE: 25-05-2005.
+        - MODIFICATION: Date. Author. Description.
+        */
+  CBlobResult& CBlobResult::operator=(const CBlobResult& source)
+  {
+    // si ja són el mateix, no cal fer res
+    if (this != &source)
+    {
+      // alliberem el conjunt de blobs antic
+      for (int i = 0; i < GetNumBlobs(); i++)
+      {
+        delete m_blobs[i];
+      }
+      m_blobs.clear();
+      // creem el nou a partir del passat com a paràmetre
+      m_blobs = blob_vector(source.GetNumBlobs());
+      // copiem els blobs de l'origen a l'actual
+      blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
+      blob_vector::iterator pBlobsDst = m_blobs.begin();
+
+      while (pBlobsSrc != source.m_blobs.end())
+      {
+        // no podem cridar a l'operador = ja que blob_vector és un
+        // vector de CBlob*. Per tant, creem un blob nou a partir del
+        // blob original
+        *pBlobsDst = new CBlob(**pBlobsSrc);
+        ++pBlobsSrc;
+        ++pBlobsDst;
+      }
+    }
+    return *this;
+  }
+
+
+  /**
+    - FUNCIÓ: operador +
+    - FUNCIONALITAT: Concatena els blobs de dos CBlobResult
+    - PARÀMETRES:
+    - source: d'on s'agafaran els blobs afegits a l'actual
+    - RESULTAT:
+    - retorna un nou CBlobResult amb els dos CBlobResult concatenats
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 25-05-2005.
+    - NOTA: per la implementació, els blobs del paràmetre es posen en ordre invers
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: + operator
+      - FUNCTIONALITY: Joins the blobs in source with the current ones
+      - PARAMETERS:
+      - source: object to copy the blobs
+      - RESULT:
+      - object with the actual blobs and the source blobs
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  CBlobResult CBlobResult::operator+(const CBlobResult& source)
+  {
+    //creem el resultat a partir dels blobs actuals
+    CBlobResult resultat(*this);
+
+    // reservem memòria per als nous blobs
+    resultat.m_blobs.resize(resultat.GetNumBlobs() + source.GetNumBlobs());
+
+    // declarem els iterador per recòrrer els blobs d'origen i desti
+    blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
+    blob_vector::iterator pBlobsDst = resultat.m_blobs.end();
+
+    // insertem els blobs de l'origen a l'actual
+    while (pBlobsSrc != source.m_blobs.end())
+    {
+      --pBlobsDst;
+      *pBlobsDst = new CBlob(**pBlobsSrc);
+      ++pBlobsSrc;
+    }
+
+    return resultat;
+  }
+
+  /**************************************************************************
+    Operacions / Operations
+    **************************************************************************/
+
+    /**
+      - FUNCIÓ: AddBlob
+      - FUNCIONALITAT: Afegeix un blob al conjunt
+      - PARÀMETRES:
+      - blob: blob a afegir
+      - RESULTAT:
+      - modifica el conjunt de blobs actual
+      - RESTRICCIONS:
+      - AUTOR: Ricard Borràs
+      - DATA DE CREACIÓ: 2006/03/01
+      - MODIFICACIÓ: Data. Autor. Descripció.
+      */
+  void CBlobResult::AddBlob(CBlob *blob)
+  {
+    if (blob != NULL)
+      m_blobs.push_back(new CBlob(blob));
+  }
+
+
+  /**
+    - FUNCIÓ: GetSTLResult
+    - FUNCIONALITAT: Calcula el resultat especificat sobre tots els blobs de la classe
+    - PARÀMETRES:
+    - evaluador: Qualsevol objecte derivat de COperadorBlob
+    - RESULTAT:
+    - Retorna un array de double's STL amb el resultat per cada blob
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: GetResult
+      - FUNCTIONALITY: Computes the function evaluador on all the blobs of the class
+      and returns a vector with the result
+      - PARAMETERS:
+      - evaluador: function to apply to each blob (any object derived from the
+      COperadorBlob class )
+      - RESULT:
+      - vector with all the results in the same order as the blobs
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  double_stl_vector CBlobResult::GetSTLResult(funcio_calculBlob *evaluador) const
+  {
+    if (GetNumBlobs() <= 0)
+    {
+      return double_stl_vector();
+    }
+
+    // definim el resultat
+    double_stl_vector result = double_stl_vector(GetNumBlobs());
+    // i iteradors sobre els blobs i el resultat
+    double_stl_vector::iterator itResult = result.begin();
+    blob_vector::const_iterator itBlobs = m_blobs.begin();
+
+    // avaluem la funció en tots els blobs
+    while (itBlobs != m_blobs.end())
+    {
+      *itResult = (*evaluador)(**itBlobs);
+      ++itBlobs;
+      ++itResult;
+    }
+    return result;
+  }
+
+  /**
+    - FUNCIÓ: GetNumber
+    - FUNCIONALITAT: Calcula el resultat especificat sobre un únic blob de la classe
+    - PARÀMETRES:
+    - evaluador: Qualsevol objecte derivat de COperadorBlob
+    - indexblob: número de blob del que volem calcular el resultat.
+    - RESULTAT:
+    - Retorna un double amb el resultat
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: GetNumber
+      - FUNCTIONALITY: Computes the function evaluador on a blob of the class
+      - PARAMETERS:
+      - indexBlob: index of the blob to compute the function
+      - evaluador: function to apply to each blob (any object derived from the
+      COperadorBlob class )
+      - RESULT:
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  double CBlobResult::GetNumber(int indexBlob, funcio_calculBlob *evaluador) const
+  {
+    if (indexBlob < 0 || indexBlob >= GetNumBlobs())
+      RaiseError(EXCEPTION_BLOB_OUT_OF_BOUNDS);
+    return (*evaluador)(*m_blobs[indexBlob]);
+  }
+
+  /////////////////////////// FILTRAT DE BLOBS ////////////////////////////////////
+
+  /**
+    - FUNCIÓ: Filter
+    - FUNCIONALITAT: Filtra els blobs de la classe i deixa el resultat amb només
+    els blobs que han passat el filtre.
+    El filtrat es basa en especificar condicions sobre un resultat dels blobs
+    i seleccionar (o excloure) aquells blobs que no compleixen una determinada
+    condicio
+    - PARÀMETRES:
+    - dst: variable per deixar els blobs filtrats
+    - filterAction:	acció de filtrat. Incloure els blobs trobats (B_INCLUDE),
+    o excloure els blobs trobats (B_EXCLUDE)
+    - evaluador: Funció per evaluar els blobs (qualsevol objecte derivat de COperadorBlob
+    - Condition: tipus de condició que ha de superar la mesura (FilterType)
+    sobre cada blob per a ser considerat.
+    B_EQUAL,B_NOT_EQUAL,B_GREATER,B_LESS,B_GREATER_OR_EQUAL,
+    B_LESS_OR_EQUAL,B_INSIDE,B_OUTSIDE
+    - LowLimit:  valor numèric per a la comparació (Condition) de la mesura (FilterType)
+    - HighLimit: valor numèric per a la comparació (Condition) de la mesura (FilterType)
+    (només té sentit per a aquelles condicions que tenen dos valors
+    (B_INSIDE, per exemple).
+    - RESULTAT:
+    - Deixa els blobs resultants del filtrat a destination
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: Filter
+      - FUNCTIONALITY: Get some blobs from the class based on conditions on measures
+      of the blobs.
+      - PARAMETERS:
+      - dst: where to store the selected blobs
+      - filterAction:	B_INCLUDE: include the blobs which pass the filter in the result
+      B_EXCLUDE: exclude the blobs which pass the filter in the result
+      - evaluador: Object to evaluate the blob
+      - Condition: How to decide if  the result returned by evaluador on each blob
+      is included or not. It can be:
+      B_EQUAL,B_NOT_EQUAL,B_GREATER,B_LESS,B_GREATER_OR_EQUAL,
+      B_LESS_OR_EQUAL,B_INSIDE,B_OUTSIDE
+      - LowLimit:  numerical value to evaluate the Condition on evaluador(blob)
+      - HighLimit: numerical value to evaluate the Condition on evaluador(blob).
+      Only useful for B_INSIDE and B_OUTSIDE
+      - RESULT:
+      - It returns on dst the blobs that accomplish (B_INCLUDE) or discards (B_EXCLUDE)
+      the Condition on the result returned by evaluador on each blob
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  void CBlobResult::Filter(CBlobResult &dst,
+    int filterAction,
+    funcio_calculBlob *evaluador,
+    int condition,
+    double lowLimit, double highLimit /*=0*/)
+
+  {
+    int i, numBlobs;
+    bool resultavaluacio;
+    double_stl_vector avaluacioBlobs;
+    double_stl_vector::iterator itavaluacioBlobs;
+
+    if (GetNumBlobs() <= 0) return;
+    if (!evaluador) return;
+    //avaluem els blobs amb la funció pertinent
+    avaluacioBlobs = GetSTLResult(evaluador);
+    itavaluacioBlobs = avaluacioBlobs.begin();
+    numBlobs = GetNumBlobs();
+    switch (condition)
+    {
+    case B_EQUAL:
+      for (i = 0; i < numBlobs; i++, itavaluacioBlobs++)
+      {
+        resultavaluacio = *itavaluacioBlobs == lowLimit;
+        if ((resultavaluacio && filterAction == B_INCLUDE) ||
+          (!resultavaluacio && filterAction == B_EXCLUDE))
+        {
+          dst.m_blobs.push_back(new CBlob(GetBlob(i)));
+        }
+      }
+      break;
+    case B_NOT_EQUAL:
+      for (i = 0; i < numBlobs; i++, itavaluacioBlobs++)
+      {
+        resultavaluacio = *itavaluacioBlobs != lowLimit;
+        if ((resultavaluacio && filterAction == B_INCLUDE) ||
+          (!resultavaluacio && filterAction == B_EXCLUDE))
+        {
+          dst.m_blobs.push_back(new CBlob(GetBlob(i)));
+        }
+      }
+      break;
+    case B_GREATER:
+      for (i = 0; i < numBlobs; i++, itavaluacioBlobs++)
+      {
+        resultavaluacio = *itavaluacioBlobs > lowLimit;
+        if ((resultavaluacio && filterAction == B_INCLUDE) ||
+          (!resultavaluacio && filterAction == B_EXCLUDE))
+        {
+          dst.m_blobs.push_back(new CBlob(GetBlob(i)));
+        }
+      }
+      break;
+    case B_LESS:
+      for (i = 0; i < numBlobs; i++, itavaluacioBlobs++)
+      {
+        resultavaluacio = *itavaluacioBlobs < lowLimit;
+        if ((resultavaluacio && filterAction == B_INCLUDE) ||
+          (!resultavaluacio && filterAction == B_EXCLUDE))
+        {
+          dst.m_blobs.push_back(new CBlob(GetBlob(i)));
+        }
+      }
+      break;
+    case B_GREATER_OR_EQUAL:
+      for (i = 0; i < numBlobs; i++, itavaluacioBlobs++)
+      {
+        resultavaluacio = *itavaluacioBlobs >= lowLimit;
+        if ((resultavaluacio && filterAction == B_INCLUDE) ||
+          (!resultavaluacio && filterAction == B_EXCLUDE))
+        {
+          dst.m_blobs.push_back(new CBlob(GetBlob(i)));
+        }
+      }
+      break;
+    case B_LESS_OR_EQUAL:
+      for (i = 0; i < numBlobs; i++, itavaluacioBlobs++)
+      {
+        resultavaluacio = *itavaluacioBlobs <= lowLimit;
+        if ((resultavaluacio && filterAction == B_INCLUDE) ||
+          (!resultavaluacio && filterAction == B_EXCLUDE))
+        {
+          dst.m_blobs.push_back(new CBlob(GetBlob(i)));
+        }
+      }
+      break;
+    case B_INSIDE:
+      for (i = 0; i < numBlobs; i++, itavaluacioBlobs++)
+      {
+        resultavaluacio = (*itavaluacioBlobs >= lowLimit) && (*itavaluacioBlobs <= highLimit);
+        if ((resultavaluacio && filterAction == B_INCLUDE) ||
+          (!resultavaluacio && filterAction == B_EXCLUDE))
+        {
+          dst.m_blobs.push_back(new CBlob(GetBlob(i)));
+        }
+      }
+      break;
+    case B_OUTSIDE:
+      for (i = 0; i < numBlobs; i++, itavaluacioBlobs++)
+      {
+        resultavaluacio = (*itavaluacioBlobs < lowLimit) || (*itavaluacioBlobs > highLimit);
+        if ((resultavaluacio && filterAction == B_INCLUDE) ||
+          (!resultavaluacio && filterAction == B_EXCLUDE))
+        {
+          dst.m_blobs.push_back(new CBlob(GetBlob(i)));
+        }
+      }
+      break;
+    }
+
+
+    // en cas de voler filtrar un CBlobResult i deixar-ho en el mateix CBlobResult
+    // ( operacio inline )
+    if (&dst == this)
+    {
+      // esborrem els primers blobs ( que són els originals )
+      // ja que els tindrem replicats al final si passen el filtre
+      blob_vector::iterator itBlobs = m_blobs.begin();
+      for (int i = 0; i < numBlobs; i++)
+      {
+        delete *itBlobs;
+        ++itBlobs;
+      }
+      m_blobs.erase(m_blobs.begin(), itBlobs);
+    }
+  }
+
+
+  /**
+    - FUNCIÓ: GetBlob
+    - FUNCIONALITAT: Retorna un blob si aquest existeix (index != -1)
+    - PARÀMETRES:
+    - indexblob: index del blob a retornar
+    - RESULTAT:
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /*
+      - FUNCTION: GetBlob
+      - FUNCTIONALITY: Gets the n-th blob (without ordering the blobs)
+      - PARAMETERS:
+      - indexblob: index in the blob array
+      - RESULT:
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  CBlob CBlobResult::GetBlob(int indexblob) const
+  {
+    if (indexblob < 0 || indexblob >= GetNumBlobs())
+      RaiseError(EXCEPTION_BLOB_OUT_OF_BOUNDS);
+
+    return *m_blobs[indexblob];
+  }
+  CBlob *CBlobResult::GetBlob(int indexblob)
+  {
+    if (indexblob < 0 || indexblob >= GetNumBlobs())
+      RaiseError(EXCEPTION_BLOB_OUT_OF_BOUNDS);
+
+    return m_blobs[indexblob];
+  }
+
+  /**
+    - FUNCIÓ: GetNthBlob
+    - FUNCIONALITAT: Retorna l'enèssim blob segons un determinat criteri
+    - PARÀMETRES:
+    - criteri: criteri per ordenar els blobs (objectes derivats de COperadorBlob)
+    - nBlob: index del blob a retornar
+    - dst: on es retorna el resultat
+    - RESULTAT:
+    - retorna el blob nBlob a dst ordenant els blobs de la classe segons el criteri
+    en ordre DESCENDENT. Per exemple, per obtenir el blob major:
+    GetNthBlob( CBlobGetArea(), 0, blobMajor );
+    GetNthBlob( CBlobGetArea(), 1, blobMajor ); (segon blob més gran)
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /*
+      - FUNCTION: GetNthBlob
+      - FUNCTIONALITY: Gets the n-th blob ordering first the blobs with some criteria
+      - PARAMETERS:
+      - criteri: criteria to order the blob array
+      - nBlob: index of the returned blob in the ordered blob array
+      - dst: where to store the result
+      - RESULT:
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  void CBlobResult::GetNthBlob(funcio_calculBlob *criteri, int nBlob, CBlob &dst) const
+  {
+    // verifiquem que no estem accedint fora el vector de blobs
+    if (nBlob < 0 || nBlob >= GetNumBlobs())
+    {
+      //RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS );
+      dst = CBlob();
+      return;
+    }
+
+    double_stl_vector avaluacioBlobs, avaluacioBlobsOrdenat;
+    double valorEnessim;
+
+    //avaluem els blobs amb la funció pertinent
+    avaluacioBlobs = GetSTLResult(criteri);
+
+    avaluacioBlobsOrdenat = double_stl_vector(GetNumBlobs());
+
+    // obtenim els nBlob primers resultats (en ordre descendent)
+    std::partial_sort_copy(avaluacioBlobs.begin(),
+      avaluacioBlobs.end(),
+      avaluacioBlobsOrdenat.begin(),
+      avaluacioBlobsOrdenat.end(),
+      std::greater<double>());
+
+    valorEnessim = avaluacioBlobsOrdenat[nBlob];
+
+    // busquem el primer blob que té el valor n-ssim
+    double_stl_vector::const_iterator itAvaluacio = avaluacioBlobs.begin();
+
+    bool trobatBlob = false;
+    int indexBlob = 0;
+    while (itAvaluacio != avaluacioBlobs.end() && !trobatBlob)
+    {
+      if (*itAvaluacio == valorEnessim)
+      {
+        trobatBlob = true;
+        dst = CBlob(GetBlob(indexBlob));
+      }
+      ++itAvaluacio;
+      indexBlob++;
+    }
+  }
+
+  /**
+    - FUNCIÓ: ClearBlobs
+    - FUNCIONALITAT: Elimina tots els blobs de l'objecte
+    - PARÀMETRES:
+    - RESULTAT:
+    - Allibera tota la memòria dels blobs
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs Navarra
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /*
+      - FUNCTION: ClearBlobs
+      - FUNCTIONALITY: Clears all the blobs from the object and releases all its memory
+      - PARAMETERS:
+      - RESULT:
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  void CBlobResult::ClearBlobs()
+  {
+    /*for( int i = 0; i < GetNumBlobs(); i++ )
+      {
+      delete m_blobs[i];
+      }*/
+    blob_vector::iterator itBlobs = m_blobs.begin();
+    while (itBlobs != m_blobs.end())
+    {
+      delete *itBlobs;
+      ++itBlobs;
+    }
+
+    m_blobs.clear();
+  }
+
+  /**
+    - FUNCIÓ: RaiseError
+    - FUNCIONALITAT: Funció per a notificar errors al l'usuari (en debug) i llença
+    les excepcions
+    - PARÀMETRES:
+    - errorCode: codi d'error
+    - RESULTAT:
+    - Ensenya un missatge a l'usuari (en debug) i llença una excepció
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs Navarra
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /*
+      - FUNCTION: RaiseError
+      - FUNCTIONALITY: Error handling function
+      - PARAMETERS:
+      - errorCode: reason of the error
+      - RESULT:
+      - in _DEBUG version, shows a message box with the error. In release is silent.
+      In both cases throws an exception with the error.
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  void CBlobResult::RaiseError(const int errorCode) const
+  {
+    throw errorCode;
+  }
+
+
+
+  /**************************************************************************
+    Auxiliars / Auxiliary functions
+    **************************************************************************/
+
+
+    /**
+      - FUNCIÓ: PrintBlobs
+      - FUNCIONALITAT: Escriu els paràmetres (àrea, perímetre, exterior, mitjana)
+      de tots els blobs a un fitxer.
+      - PARÀMETRES:
+      - nom_fitxer: path complet del fitxer amb el resultat
+      - RESULTAT:
+      - RESTRICCIONS:
+      - AUTOR: Ricard Borràs
+      - DATA DE CREACIÓ: 25-05-2005.
+      - MODIFICACIÓ: Data. Autor. Descripció.
+      */
+      /*
+        - FUNCTION: PrintBlobs
+        - FUNCTIONALITY: Prints some blob features in an ASCII file
+        - PARAMETERS:
+        - nom_fitxer: full path + filename to generate
+        - RESULT:
+        - RESTRICTIONS:
+        - AUTHOR: Ricard Borràs
+        - CREATION DATE: 25-05-2005.
+        - MODIFICATION: Date. Author. Description.
+        */
+  void CBlobResult::PrintBlobs(char *nom_fitxer) const
+  {
+    double_stl_vector area, /*perimetre,*/ exterior, mitjana, compacitat, longitud,
+      externPerimeter, perimetreConvex, perimetre;
+    int i;
+    FILE *fitxer_sortida;
+
+    area = GetSTLResult(CBlobGetArea());
+    perimetre = GetSTLResult(CBlobGetPerimeter());
+    exterior = GetSTLResult(CBlobGetExterior());
+    mitjana = GetSTLResult(CBlobGetMean());
+    compacitat = GetSTLResult(CBlobGetCompactness());
+    longitud = GetSTLResult(CBlobGetLength());
+    externPerimeter = GetSTLResult(CBlobGetExternPerimeter());
+    perimetreConvex = GetSTLResult(CBlobGetHullPerimeter());
+
+    fitxer_sortida = fopen(nom_fitxer, "w");
+
+    for (i = 0; i < GetNumBlobs(); i++)
+    {
+      fprintf(fitxer_sortida, "blob %d ->\t a=%7.0f\t p=%8.2f (%8.2f extern)\t pconvex=%8.2f\t ext=%.0f\t m=%7.2f\t c=%3.2f\t l=%8.2f\n",
+        i, area[i], perimetre[i], externPerimeter[i], perimetreConvex[i], exterior[i], mitjana[i], compacitat[i], longitud[i]);
+    }
+    fclose(fitxer_sortida);
+
+  }
+
+}
diff --git a/package_bgs/jmo/BlobResult.h b/package_bgs/MultiLayer/BlobResult.h
similarity index 80%
rename from package_bgs/jmo/BlobResult.h
rename to package_bgs/MultiLayer/BlobResult.h
index b232a978d03b748d6d58df0b80c593d26dc757ad..aa3e37b31c12998d96a91c3493f25557ad4e5a32 100644
--- a/package_bgs/jmo/BlobResult.h
+++ b/package_bgs/MultiLayer/BlobResult.h
@@ -40,29 +40,26 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-/************************************************************************
-        BlobResult.h
+ /************************************************************************
+         BlobResult.h
 
-        FUNCIONALITAT: Definici� de la classe CBlobResult
-        AUTOR: Inspecta S.L.
-        MODIFICACIONS (Modificaci�, Autor, Data):
+         FUNCIONALITAT: Definició de la classe CBlobResult
+         AUTOR: Inspecta S.L.
+         MODIFICACIONS (Modificació, Autor, Data):
 
-        FUNCTIONALITY: Definition of the CBlobResult class
-        AUTHOR: Inspecta S.L.
-        MODIFICATIONS (Modification, Author, Date):
+         FUNCTIONALITY: Definition of the CBlobResult class
+         AUTHOR: Inspecta S.L.
+         MODIFICATIONS (Modification, Author, Date):
 
-        **************************************************************************/
+         **************************************************************************/
 #pragma once
 
-#if !defined(_CLASSE_BLOBRESULT_INCLUDED)
-#define _CLASSE_BLOBRESULT_INCLUDED
-
 #include "BlobLibraryConfiguration.h"
 #include <math.h>
-//#include "cxcore.h"
+         //#include "cxcore.h"
 #include <vector>
 #include <functional>
-#include <opencv2/core/types_c.h>
+#include "OpenCvLegacyIncludes.h"
 #include "blob.h"
 
 typedef std::vector<double> double_stl_vector;
@@ -71,8 +68,8 @@ typedef std::vector<double> double_stl_vector;
   Filtres / Filters
   **************************************************************************/
 
-//! accions que es poden fer amb els filtres
-//! Actions performed by a filter (include or exclude blobs)
+  //! accions que es poden fer amb els filtres
+  //! Actions performed by a filter (include or exclude blobs)
 #define B_INCLUDE				1L
 #define B_EXCLUDE				2L
 
@@ -92,23 +89,23 @@ typedef std::vector<double> double_stl_vector;
   Excepcions / Exceptions
   **************************************************************************/
 
-//! Excepcions llen�ades per les funcions:
+  //! Excepcions llençades per les funcions:
 #define EXCEPTION_BLOB_OUT_OF_BOUNDS	1000
 #define EXCEPCIO_CALCUL_BLOBS			1001
 
 namespace Blob
 {
 
-  //! definici� de que es un vector de blobs
+  //! definició de que es un vector de blobs
   typedef std::vector<CBlob*>	blob_vector;
 
   /**
-    Classe que cont� un conjunt de blobs i permet extreure'n propietats
-    o filtrar-los segons determinats criteris.
-    Class to calculate the blobs of an image and calculate some properties
-    on them. Also, the class provides functions to filter the blobs using
-    some criteria.
-    */
+      Classe que conté un conjunt de blobs i permet extreure'n propietats
+      o filtrar-los segons determinats criteris.
+      Class to calculate the blobs of an image and calculate some properties
+      on them. Also, the class provides functions to filter the blobs using
+      some criteria.
+      */
   class CBlobResult
   {
   public:
@@ -119,7 +116,7 @@ namespace Blob
     //! constructor a partir d'una imatge
     //! Image constructor, it creates an object with the blobs of the image
     CBlobResult(IplImage *source, IplImage *mask, int threshold, bool findmoments);
-    //! constructor de c�pia
+    //! constructor de còpia
     //! Copy constructor
     CBlobResult(const CBlobResult &source);
     //! Destructor
@@ -139,7 +136,7 @@ namespace Blob
 #ifdef MATRIXCV_ACTIU
     //! Calcula un valor sobre tots els blobs de la classe retornant una MatrixCV
     //! Computes some property on all the blobs of the class
-    double_vector GetResult( funcio_calculBlob *evaluador ) const;
+    double_vector GetResult(funcio_calculBlob *evaluador) const;
 #endif
     //! Calcula un valor sobre tots els blobs de la classe retornant un std::vector<double>
     //! Computes some property on all the blobs of the class
@@ -149,17 +146,17 @@ namespace Blob
     //! Computes some property on one blob of the class
     double GetNumber(int indexblob, funcio_calculBlob *evaluador) const;
 
-    //! Retorna aquells blobs que compleixen les condicions del filtre en el destination 
+    //! Retorna aquells blobs que compleixen les condicions del filtre en el destination
     //! Filters the blobs of the class using some property
     void Filter(CBlobResult &dst,
       int filterAction, funcio_calculBlob *evaluador,
       int condition, double lowLimit, double highLimit = 0);
 
-    //! Retorna l'en�ssim blob segons un determinat criteri
+    //! Retorna l'enèssim blob segons un determinat criteri
     //! Sorts the blobs of the class acording to some criteria and returns the n-th blob
     void GetNthBlob(funcio_calculBlob *criteri, int nBlob, CBlob &dst) const;
 
-    //! Retorna el blob en�ssim
+    //! Retorna el blob enèssim
     //! Gets the n-th blob of the class ( without sorting )
     CBlob GetBlob(int indexblob) const;
     CBlob *GetBlob(int indexblob);
@@ -185,7 +182,7 @@ namespace Blob
 
   private:
 
-    //! Funci� per gestionar els errors
+    //! Funció per gestionar els errors
     //! Function to manage the errors
     void RaiseError(const int errorCode) const;
 
@@ -197,6 +194,3 @@ namespace Blob
   };
 
 }
-
-#endif // !defined(_CLASSE_BLOBRESULT_INCLUDED)
-
diff --git a/package_bgs/jmo/CMultiLayerBGS.cpp b/package_bgs/MultiLayer/CMultiLayerBGS.cpp
similarity index 99%
rename from package_bgs/jmo/CMultiLayerBGS.cpp
rename to package_bgs/MultiLayer/CMultiLayerBGS.cpp
index 6daa9b9bf1480194166cc131ca4dc9ddde20f9a0..43417361cff3902bc8bf8bdfa0ba2a2f20c8b1b1 100644
--- a/package_bgs/jmo/CMultiLayerBGS.cpp
+++ b/package_bgs/MultiLayer/CMultiLayerBGS.cpp
@@ -53,7 +53,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 #include <fstream>						// file I/O
 #include <cmath>						// math includes
 #include <iostream>                                             // I/O streams
-#include <opencv2/legacy/compat.hpp>
+#include "OpenCvLegacyIncludes.h"
 
 using namespace Blob;
 
@@ -220,16 +220,16 @@ void CMultiLayerBGS::MergeImages(int num, ...) {
 
   int img_idx = 0;
   for (a = 0; a < nRows; a++)
-  for (b = 0; b < nCols; b++) {
-    if (img_idx >= num)
-      break;
+    for (b = 0; b < nCols; b++) {
+      if (img_idx >= num)
+        break;
 
-    imgROIRect = cvRect(b * imgSize.width, a * imgSize.height, imgSize.width, imgSize.height);
+      imgROIRect = cvRect(b * imgSize.width, a * imgSize.height, imgSize.width, imgSize.height);
 
-    cvSetImageROI(ppIplImg[num], imgROIRect);
-    cvCopyImage(ppIplImg[img_idx++], ppIplImg[num]);
-    cvResetImageROI(ppIplImg[num]);
-  }
+      cvSetImageROI(ppIplImg[num], imgROIRect);
+      cvCopy(ppIplImg[img_idx++], ppIplImg[num]);
+      cvResetImageROI(ppIplImg[num]);
+    }
 
   delete[] ppIplImg;
 }
@@ -369,7 +369,7 @@ void CMultiLayerBGS::SetBkMaskImage(IplImage *mask_img) {
   if (m_pBkMaskImg == NULL) {
     m_pBkMaskImg = cvCreateImage(cvGetSize(mask_img), mask_img->depth, mask_img->nChannels);
   }
-  cvCopyImage(mask_img, m_pBkMaskImg);
+  cvCopy(mask_img, m_pBkMaskImg);
 }
 
 void CMultiLayerBGS::BackgroundSubtractionProcess() {
@@ -691,7 +691,7 @@ void CMultiLayerBGS::BackgroundSubtractionProcess() {
               removed_modes[a] = false;
               if (LBPs[lbp_idxes[a]].bg_layer_num > curLBP->bg_layer_num &&
                 LBPs[lbp_idxes[a]].weight < LBPs[lbp_idxes[a]].max_weight * 0.9f) { /* remove layers */
-                //LBPs[lbp_idxes[a]].bg_layer_num = 0;
+              //LBPs[lbp_idxes[a]].bg_layer_num = 0;
                 removed_modes[a] = true;
                 removed_bg_layers = true;
               }
@@ -835,7 +835,7 @@ void CMultiLayerBGS::GetBackgroundImage(IplImage *bk_img) {
   ODC.SetImageData(bg_img, org_data);
   delete[] org_data;
 
-  cvCopyImage(m_pBgImg, bk_img);
+  cvCopy(m_pBgImg, bk_img);
 }
 
 void CMultiLayerBGS::GetForegroundImage(IplImage *fg_img, CvScalar bg_color) {
@@ -865,7 +865,7 @@ void CMultiLayerBGS::GetForegroundMaskImage(IplImage *fg_mask_img) {
   if (m_pROI && (m_pROI->width <= 0 || m_pROI->height <= 0))
     return;
 
-  //cvCopyImage(m_pFgMaskImg, fg_mask_img);
+  //cvCopy(m_pFgMaskImg, fg_mask_img);
   if (m_pROI) {
     cvSetImageROI(m_pFgMaskImg, *m_pROI);
     cvSetImageROI(fg_mask_img, *m_pROI);
@@ -1391,7 +1391,7 @@ void CMultiLayerBGS::GetCurrentLayeredBackgroundImage(int layered_no, IplImage *
 }
 
 void CMultiLayerBGS::GetColoredBgMultiLayeredImage(IplImage *bg_multi_layer_img, CvScalar *layer_colors) {
-  cvCopyImage(m_pOrgImg, bg_multi_layer_img);
+  cvCopy(m_pOrgImg, bg_multi_layer_img);
 
   COpencvDataConversion<uchar, uchar> ODC;
 
diff --git a/package_bgs/jmo/CMultiLayerBGS.h b/package_bgs/MultiLayer/CMultiLayerBGS.h
similarity index 96%
rename from package_bgs/jmo/CMultiLayerBGS.h
rename to package_bgs/MultiLayer/CMultiLayerBGS.h
index c8698f6272595f7dd0c22ba95546a616641cffee..78a0527ddb75bcce0f324ec0ecd52d017bc0c529 100644
--- a/package_bgs/jmo/CMultiLayerBGS.h
+++ b/package_bgs/MultiLayer/CMultiLayerBGS.h
@@ -43,9 +43,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 // BackgroundSubtraction.h: interface for the CBackgroundSubtraction class.
 //
 //////////////////////////////////////////////////////////////////////
-
-#if !defined(_MULTI_LAYER_BGS_H_)
-#define _MULTI_LAYER_BGS_H_
+#pragma once
 
 /*
 Since the used fast cross bilateral filter codes can not be compiled under Windows,
@@ -124,16 +122,16 @@ public:
     float weight_updating_learn_rate_per_second,	// mode's weight updating learning rate per second
     float low_init_mode_weight);			// the low initial mode weight
 
-  //-------------------------------------------------------------
-  //   PROVIDE A POINTER TO THE INPUT IMAGE
-  //   -> INDICATE WHERE THE NEW IMAGE TO PROCESS IS STORED
-  //
-  //   Here assumes that the input image will contain RGB images.
-  //   The memory of this image is handled by the caller.
-  //
-  //    The return value indicate whether the actual Background
-  //    Subtraction algorithm handles RGB images (1) or not (0).
-  //
+//-------------------------------------------------------------
+//   PROVIDE A POINTER TO THE INPUT IMAGE
+//   -> INDICATE WHERE THE NEW IMAGE TO PROCESS IS STORED
+//
+//   Here assumes that the input image will contain RGB images.
+//   The memory of this image is handled by the caller.
+//
+//    The return value indicate whether the actual Background
+//    Subtraction algorithm handles RGB images (1) or not (0).
+//
   int   SetRGBInputImage(IplImage  *  inputImage, CvRect *roi = NULL);
 
   //-------------------------------------------------------------
@@ -308,6 +306,3 @@ public:
   CMultiLayerBGS();
   virtual ~CMultiLayerBGS();
 };
-
-#endif // !defined(_MULTI_LAYER_BGS_H_)
-
diff --git a/package_bgs/jmo/LocalBinaryPattern.cpp b/package_bgs/MultiLayer/LocalBinaryPattern.cpp
similarity index 95%
rename from package_bgs/jmo/LocalBinaryPattern.cpp
rename to package_bgs/MultiLayer/LocalBinaryPattern.cpp
index 6967cf4eb84e538df152b6d8636a4511da312c9d..060b9ea959af92ea290fe056b88457963c6fae0d 100644
--- a/package_bgs/jmo/LocalBinaryPattern.cpp
+++ b/package_bgs/MultiLayer/LocalBinaryPattern.cpp
@@ -105,13 +105,13 @@ void CLocalBinaryPattern::Initialization(IplImage **first_imgs, int imgs_num, in
   m_nMaxShift.y = 0;
   int shift_idx = 0;
   for (a = 0; a < m_nLBPLevelNum; a++)
-  for (b = 0; b < m_pNeigPointsNums[a]; b++) {
-    // compute the offset of neig point
-    CalNeigPixelOffset(m_pRadiuses[a], m_pNeigPointsNums[a], b, m_pXYShifts[shift_idx].x, m_pXYShifts[shift_idx].y);
-    m_nMaxShift.x = MAX(m_nMaxShift.x, m_pXYShifts[shift_idx].x);
-    m_nMaxShift.y = MAX(m_nMaxShift.y, m_pXYShifts[shift_idx].y);
-    shift_idx++;
-  }
+    for (b = 0; b < m_pNeigPointsNums[a]; b++) {
+      // compute the offset of neig point
+      CalNeigPixelOffset(m_pRadiuses[a], m_pNeigPointsNums[a], b, m_pXYShifts[shift_idx].x, m_pXYShifts[shift_idx].y);
+      m_nMaxShift.x = MAX(m_nMaxShift.x, m_pXYShifts[shift_idx].x);
+      m_nMaxShift.y = MAX(m_nMaxShift.y, m_pXYShifts[shift_idx].y);
+      shift_idx++;
+    }
 
   m_fRobustWhiteNoise = robust_white_noise;
 }
@@ -155,7 +155,7 @@ void CLocalBinaryPattern::ComputeLBP(PixelLBPStruct *PLBP, CvRect *roi)
 
         if (roi) {
           int x, y;
-          for (y = 0; y < roi->height; y++)  {
+          for (y = 0; y < roi->height; y++) {
             _PLBP = PLBP + (y + roi->y)*m_cvImgSize.width + roi->x;
             for (x = 0; x < roi->width; x++) {
               cur_pattern = (*_PLBP++).cur_pattern;
diff --git a/package_bgs/jmo/LocalBinaryPattern.h b/package_bgs/MultiLayer/LocalBinaryPattern.h
similarity index 96%
rename from package_bgs/jmo/LocalBinaryPattern.h
rename to package_bgs/MultiLayer/LocalBinaryPattern.h
index 987a2c2655052a7ea3961bae8b8a899e6f32aaf0..40d43790f96292be18559c6056912ed4c7537469 100644
--- a/package_bgs/jmo/LocalBinaryPattern.h
+++ b/package_bgs/MultiLayer/LocalBinaryPattern.h
@@ -43,11 +43,9 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 // LocalBinaryPattern.h: interface for the CLocalBinaryPattern class.
 //
 //////////////////////////////////////////////////////////////////////
+#pragma once
 
-#if !defined(_LOCAL_BINARY_PATTERN_H_)
-#define _LOCAL_BINARY_PATTERN_H_
-
-#include <opencv2/opencv.hpp>
+#include "OpenCvLegacyIncludes.h"
 #include "BGS.h"
 
 
@@ -98,6 +96,3 @@ private:
 
   IplImage* m_pShiftedImg;
 };
-
-#endif // !defined(_LOCAL_BINARY_PATTERN_H_)
-
diff --git a/package_bgs/jmo/OpenCvDataConversion.h b/package_bgs/MultiLayer/OpenCvDataConversion.h
similarity index 97%
rename from package_bgs/jmo/OpenCvDataConversion.h
rename to package_bgs/MultiLayer/OpenCvDataConversion.h
index a47563e59b74be9ee95c46ce0279368465158631..18371b3bf632163ee95eda0ea280cb7d978cfc11 100644
--- a/package_bgs/jmo/OpenCvDataConversion.h
+++ b/package_bgs/MultiLayer/OpenCvDataConversion.h
@@ -43,11 +43,9 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 // OpencvDataConversion.h: interface for the COpencvDataConversion class.
 //
 //////////////////////////////////////////////////////////////////////
+#pragma once
 
-#if !defined(_OPENCV_DATA_CONVERSION_H_)
-#define _OPENCV_DATA_CONVERSION_H_
-
-#include <opencv2/opencv.hpp>
+#include "OpenCvLegacyIncludes.h"
 #include <stdio.h>
 
 template <class TI, class TM>		/* class TI - the type of image data, class TM - the type of matrix data */
@@ -219,6 +217,3 @@ public:
   COpencvDataConversion() {};
   virtual ~COpencvDataConversion() {};
 };
-
-#endif // !defined(_OPENCV_DATA_CONVERSION_H_)
-
diff --git a/package_bgs/MultiLayer/OpenCvLegacyIncludes.h b/package_bgs/MultiLayer/OpenCvLegacyIncludes.h
new file mode 100644
index 0000000000000000000000000000000000000000..9d30c0ef28c2fd8d15e4daf933b0dd79cfa14441
--- /dev/null
+++ b/package_bgs/MultiLayer/OpenCvLegacyIncludes.h
@@ -0,0 +1,50 @@
+/*
+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/>.
+*/
+/* --- --- ---
+* Copyright (C) 2008--2010 Idiap Research Institute (.....@idiap.ch)
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+* 3. The name of the author may not be used to endorse or promote products
+*    derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+// OpenCvLegacyIncludes.h: necessary includes to compile with OpenCV 3.
+//
+//////////////////////////////////////////////////////////////////////
+#pragma once
+
+#include "opencv2/core/core_c.h"
+#include "opencv2/core/types_c.h"
+#include "opencv2/imgproc/imgproc_c.h"
diff --git a/package_bgs/MultiLayer/blob.cpp b/package_bgs/MultiLayer/blob.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5e0fa45fac0ee03a3ffa6c33e2f89ea82df5a9b7
--- /dev/null
+++ b/package_bgs/MultiLayer/blob.cpp
@@ -0,0 +1,1148 @@
+/*
+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/>.
+*/
+/* --- --- ---
+* Copyright (C) 2008--2010 Idiap Research Institute (.....@idiap.ch)
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+* 3. The name of the author may not be used to endorse or promote products
+*    derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/************************************************************************
+Blob.cpp
+
+- FUNCIONALITAT: Implementació de la classe CBlob
+- AUTOR: Inspecta S.L.
+MODIFICACIONS (Modificació, Autor, Data):
+
+
+FUNCTIONALITY: Implementation of the CBlob class and some helper classes to perform
+some calculations on it
+AUTHOR: Inspecta S.L.
+MODIFICATIONS (Modification, Author, Date):
+
+**************************************************************************/
+
+
+#include <limits.h>
+#include "blob.h"
+
+namespace Blob
+{
+
+  /**
+    - FUNCIÓ: CBlob
+    - FUNCIONALITAT: Constructor estàndard
+    - PARÀMETRES:
+    - RESULTAT:
+    - inicialització de totes les variables internes i de l'storage i la sequencia
+    per a les cantonades del blob
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: CBlob
+      - FUNCTIONALITY: Standard constructor
+      - PARAMETERS:
+      - RESULT:
+      - memory allocation for the blob edges and initialization of member variables
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  CBlob::CBlob()
+  {
+    etiqueta = -1;		// Flag indicates null region
+    exterior = 0;
+    area = 0.0f;
+    perimeter = 0.0f;
+    parent = -1;
+    minx = LONG_MAX;
+    maxx = 0;
+    miny = LONG_MAX;
+    maxy = 0;
+    sumx = 0;
+    sumy = 0;
+    sumxx = 0;
+    sumyy = 0;
+    sumxy = 0;
+    mean = 0;
+    stddev = 0;
+    externPerimeter = 0;
+
+    m_storage = cvCreateMemStorage(0);
+    edges = cvCreateSeq(CV_SEQ_KIND_GENERIC | CV_32SC2,
+      sizeof(CvContour),
+      sizeof(CvPoint), m_storage);
+  }
+
+  /**
+    - FUNCIÓ: CBlob
+    - FUNCIONALITAT: Constructor de còpia
+    - PARÀMETRES:
+    - RESULTAT:
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: CBlob
+      - FUNCTIONALITY: Copy constructor
+      - PARAMETERS:
+      - RESULT:
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  CBlob::CBlob(const CBlob &src)
+  {
+    // copiem les propietats del blob origen a l'actual
+    etiqueta = src.etiqueta;
+    exterior = src.exterior;
+    area = src.Area();
+    perimeter = src.Perimeter();
+    parent = src.parent;
+    minx = src.minx;
+    maxx = src.maxx;
+    miny = src.miny;
+    maxy = src.maxy;
+    sumx = src.sumx;
+    sumy = src.sumy;
+    sumxx = src.sumxx;
+    sumyy = src.sumyy;
+    sumxy = src.sumxy;
+    mean = src.mean;
+    stddev = src.stddev;
+    externPerimeter = src.externPerimeter;
+
+    // copiem els edges del blob origen a l'actual
+    CvSeqReader reader;
+    CvSeqWriter writer;
+    CvPoint edgeactual;
+
+    // creem una sequencia buida per als edges
+    m_storage = cvCreateMemStorage(0);
+    edges = cvCreateSeq(CV_SEQ_KIND_GENERIC | CV_32SC2,
+      sizeof(CvContour),
+      sizeof(CvPoint), m_storage);
+
+    cvStartReadSeq(src.Edges(), &reader);
+    cvStartAppendToSeq(edges, &writer);
+
+    for (int i = 0; i < src.Edges()->total; i++)
+    {
+      CV_READ_SEQ_ELEM(edgeactual, reader);
+      CV_WRITE_SEQ_ELEM(edgeactual, writer);
+    }
+
+    cvEndWriteSeq(&writer);
+  }
+  CBlob::CBlob(const CBlob *src)
+  {
+    // copiem les propietats del blob origen a l'actual
+    etiqueta = src->etiqueta;
+    exterior = src->exterior;
+    area = src->Area();
+    perimeter = src->Perimeter();
+    parent = src->parent;
+    minx = src->minx;
+    maxx = src->maxx;
+    miny = src->miny;
+    maxy = src->maxy;
+    sumx = src->sumx;
+    sumy = src->sumy;
+    sumxx = src->sumxx;
+    sumyy = src->sumyy;
+    sumxy = src->sumxy;
+    mean = src->mean;
+    stddev = src->stddev;
+    externPerimeter = src->externPerimeter;
+
+    // copiem els edges del blob origen a l'actual
+    CvSeqReader reader;
+    CvSeqWriter writer;
+    CvPoint edgeactual;
+
+    // creem una sequencia buida per als edges
+    m_storage = cvCreateMemStorage(0);
+    edges = cvCreateSeq(CV_SEQ_KIND_GENERIC | CV_32SC2,
+      sizeof(CvContour),
+      sizeof(CvPoint), m_storage);
+
+    cvStartReadSeq(src->Edges(), &reader);
+    cvStartAppendToSeq(edges, &writer);
+
+    for (int i = 0; i < src->Edges()->total; i++)
+    {
+      CV_READ_SEQ_ELEM(edgeactual, reader);
+      CV_WRITE_SEQ_ELEM(edgeactual, writer);
+    }
+
+    cvEndWriteSeq(&writer);
+  }
+
+  /**
+    - FUNCIÓ: ~CBlob
+    - FUNCIONALITAT: Destructor estàndard
+    - PARÀMETRES:
+    - RESULTAT:
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: CBlob
+      - FUNCTIONALITY: Standard destructor
+      - PARAMETERS:
+      - RESULT:
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  CBlob::~CBlob()
+  {
+    // Eliminar vèrtexs del blob
+    cvClearSeq(edges);
+    // i la zona de memòria on són
+    cvReleaseMemStorage(&m_storage);
+  }
+
+  /**
+    - FUNCIÓ: operator=
+    - FUNCIONALITAT: Operador d'assignació
+    - PARÀMETRES:
+    - src: blob a assignar a l'actual
+    - RESULTAT:
+    - Substitueix el blob actual per el src
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: Assigment operator
+      - FUNCTIONALITY: Assigns a blob to the current
+      - PARAMETERS:
+      - src: blob to assign
+      - RESULT:
+      - the current blob is replaced by the src blob
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  CBlob& CBlob::operator=(const CBlob &src)
+  {
+    // si ja són el mateix, no cal fer res
+    if (this != &src)
+    {
+      // Eliminar vèrtexs del blob
+      cvClearSeq(edges);
+      // i la zona de memòria on són
+      cvReleaseMemStorage(&m_storage);
+
+      // creem una sequencia buida per als edges
+      m_storage = cvCreateMemStorage(0);
+      edges = cvCreateSeq(CV_SEQ_KIND_GENERIC | CV_32SC2,
+        sizeof(CvContour),
+        sizeof(CvPoint), m_storage);
+
+      // copiem les propietats del blob origen a l'actual
+      etiqueta = src.etiqueta;
+      exterior = src.exterior;
+      area = src.Area();
+      perimeter = src.Perimeter();
+      parent = src.parent;
+      minx = src.minx;
+      maxx = src.maxx;
+      miny = src.miny;
+      maxy = src.maxy;
+      sumx = src.sumx;
+      sumy = src.sumy;
+      sumxx = src.sumxx;
+      sumyy = src.sumyy;
+      sumxy = src.sumxy;
+      mean = src.mean;
+      stddev = src.stddev;
+      externPerimeter = src.externPerimeter;
+
+      // copiem els edges del blob origen a l'actual
+      CvSeqReader reader;
+      CvSeqWriter writer;
+      CvPoint edgeactual;
+
+      cvStartReadSeq(src.Edges(), &reader);
+      cvStartAppendToSeq(edges, &writer);
+
+      for (int i = 0; i < src.Edges()->total; i++)
+      {
+        CV_READ_SEQ_ELEM(edgeactual, reader);
+        CV_WRITE_SEQ_ELEM(edgeactual, writer);
+      }
+
+      cvEndWriteSeq(&writer);
+    }
+    return *this;
+  }
+
+  /**
+    - FUNCIÓ: FillBlob
+    - FUNCIONALITAT: Pinta l'interior d'un blob amb el color especificat
+    - PARÀMETRES:
+    - imatge: imatge on es vol pintar el el blob
+    - color: color amb que es vol pintar el blob
+    - RESULTAT:
+    - retorna la imatge d'entrada amb el blob pintat
+    - RESTRICCIONS:
+    - AUTOR:
+    - Ricard Borràs
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: FillBlob
+      - FUNCTIONALITY:
+      - Fills the blob with a specified colour
+      - PARAMETERS:
+      - imatge: where to paint
+      - color: colour to paint the blob
+      - RESULT:
+      - modifies input image and returns the seed point used to fill the blob
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  void CBlob::FillBlob(IplImage *imatge, CvScalar color, int offsetX /*=0*/, int offsetY /*=0*/) const
+  {
+
+    //verifiquem que existeixi el blob i que tingui cantonades
+    if (edges == NULL || edges->total == 0) return;
+
+    CvPoint edgeactual, pt1, pt2;
+    CvSeqReader reader;
+    vectorPunts vectorEdges = vectorPunts(edges->total);
+    vectorPunts::iterator itEdges, itEdgesSeguent;
+    bool dinsBlob;
+    int yActual;
+
+    // passem els punts del blob a un vector de punts de les STL
+    cvStartReadSeq(edges, &reader);
+    itEdges = vectorEdges.begin();
+    while (itEdges != vectorEdges.end())
+    {
+      CV_READ_SEQ_ELEM(edgeactual, reader);
+      *itEdges = edgeactual;
+      ++itEdges;
+    }
+    // ordenem el vector per les Y's i les X's d'esquerra a dreta
+    std::sort(vectorEdges.begin(), vectorEdges.end(), comparaCvPoint());
+
+    // recorrem el vector ordenat i fem linies entre punts consecutius
+    itEdges = vectorEdges.begin();
+    itEdgesSeguent = vectorEdges.begin() + 1;
+    dinsBlob = true;
+    while (itEdges != (vectorEdges.end() - 1))
+    {
+      yActual = (*itEdges).y;
+
+      if (((*itEdges).x != (*itEdgesSeguent).x) &&
+        ((*itEdgesSeguent).y == yActual)
+        )
+      {
+        if (dinsBlob)
+        {
+          pt1 = *itEdges;
+          pt1.x += offsetX;
+          pt1.y += offsetY;
+
+          pt2 = *itEdgesSeguent;
+          pt2.x += offsetX;
+          pt2.y += offsetY;
+
+          cvLine(imatge, pt1, pt2, color);
+        }
+        dinsBlob = !dinsBlob;
+      }
+      ++itEdges;
+      ++itEdgesSeguent;
+      if ((*itEdges).y != yActual) dinsBlob = true;
+    }
+    vectorEdges.clear();
+  }
+
+  /**
+    - FUNCIÓ: CopyEdges
+    - FUNCIONALITAT: Afegeix els vèrtexs del blob al blob destination
+    - PARÀMETRES:
+    - destination: blob al que volem afegir els vèrtexs
+    - RESULTAT:
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: CopyEdges
+      - FUNCTIONALITY: Adds the blob edges to destination
+      - PARAMETERS:
+      - destination: where to add the edges
+      - RESULT:
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  void CBlob::CopyEdges(CBlob &destination) const
+  {
+    CvSeqReader reader;
+    CvSeqWriter writer;
+    CvPoint edgeactual;
+
+    cvStartReadSeq(edges, &reader);
+    cvStartAppendToSeq(destination.Edges(), &writer);
+
+    for (int i = 0; i < edges->total; i++)
+    {
+      CV_READ_SEQ_ELEM(edgeactual, reader);
+      CV_WRITE_SEQ_ELEM(edgeactual, writer);
+    }
+
+    cvEndWriteSeq(&writer);
+  }
+
+  /**
+    - FUNCIÓ: ClearEdges
+    - FUNCIONALITAT: Elimina els vèrtexs del blob
+    - PARÀMETRES:
+    - RESULTAT:
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: ClearEdges
+      - FUNCTIONALITY: Delete current blob edges
+      - PARAMETERS:
+      - RESULT:
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  void CBlob::ClearEdges()
+  {
+    // Eliminar vèrtexs del blob eliminat
+    cvClearSeq(edges);
+  }
+
+  /**
+    - FUNCIÓ: GetConvexHull
+    - FUNCIONALITAT: Retorna el poligon convex del blob
+    - PARÀMETRES:
+    - dst: sequencia on desarem el resultat (no ha d'estar inicialitzada)
+    - RESULTAT:
+    - true si tot ha anat bé
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: GetConvexHull
+      - FUNCTIONALITY: Calculates the convex hull polygon of the blob
+      - PARAMETERS:
+      - dst: where to store the result
+      - RESULT:
+      - true if no error ocurred
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  bool CBlob::GetConvexHull(CvSeq **dst) const
+  {
+    if (edges != NULL && edges->total > 0)
+    {
+      *dst = cvConvexHull2(edges, 0, CV_CLOCKWISE, 0);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+    - FUNCIÓ: GetEllipse
+    - FUNCIONALITAT: Retorna l'ellipse que s'ajusta millor a les cantonades del blob
+    - PARÀMETRES:
+    - RESULTAT:
+    - estructura amb l'ellipse
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 25-05-2005.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: GetEllipse
+      - FUNCTIONALITY: Calculates the ellipse that best fits the edges of the blob
+      - PARAMETERS:
+      - RESULT:
+      - CvBox2D struct with the calculated ellipse
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  CvBox2D CBlob::GetEllipse() const
+  {
+    CvBox2D elipse;
+    // necessitem 6 punts per calcular l'elipse
+    if (edges != NULL && edges->total > 6)
+    {
+      elipse = cvFitEllipse2(edges);
+    }
+    else
+    {
+      elipse.center.x = 0.0;
+      elipse.center.y = 0.0;
+      elipse.size.width = 0.0;
+      elipse.size.height = 0.0;
+      elipse.angle = 0.0;
+    }
+    return elipse;
+  }
+
+
+
+  /***************************************************************************
+    Implementació de les classes per al càlcul de característiques sobre el blob
+
+    Implementation of the helper classes to perform operations on blobs
+    **************************************************************************/
+
+    /**
+      - FUNCIÓ: Moment
+      - FUNCIONALITAT: Calcula el moment pq del blob
+      - RESULTAT:
+      - retorna el moment pq especificat o 0 si el moment no està implementat
+      - RESTRICCIONS:
+      - Implementats els moments pq: 00, 01, 10, 20, 02
+      - AUTOR: Ricard Borràs
+      - DATA DE CREACIÓ: 20-07-2004.
+      - MODIFICACIÓ: Data. Autor. Descripció.
+      */
+      /**
+        - FUNCTION: Moment
+        - FUNCTIONALITY: Calculates the pq moment of the blob
+        - PARAMETERS:
+        - RESULT:
+        - returns the pq moment or 0 if the moment it is not implemented
+        - RESTRICTIONS:
+        - Currently, only implemented the 00, 01, 10, 20, 02 pq moments
+        - AUTHOR: Ricard Borràs
+        - CREATION DATE: 20-07-2004.
+        - MODIFICATION: Date. Author. Description.
+        */
+  double CBlobGetMoment::operator()(const CBlob &blob) const
+  {
+    //Moment 00
+    if ((m_p == 0) && (m_q == 0))
+      return blob.Area();
+
+    //Moment 10
+    if ((m_p == 1) && (m_q == 0))
+      return blob.SumX();
+
+    //Moment 01
+    if ((m_p == 0) && (m_q == 1))
+      return blob.SumY();
+
+    //Moment 20
+    if ((m_p == 2) && (m_q == 0))
+      return blob.SumXX();
+
+    //Moment 02
+    if ((m_p == 0) && (m_q == 2))
+      return blob.SumYY();
+
+    return 0;
+  }
+
+  /**
+    - FUNCIÓ: HullPerimeter
+    - FUNCIONALITAT: Calcula la longitud del perimetre convex del blob.
+    Fa servir la funció d'OpenCV cvConvexHull2 per a
+    calcular el perimetre convex.
+
+    - PARÀMETRES:
+    - RESULTAT:
+    - retorna la longitud del perímetre convex del blob. Si el blob no té coordenades
+    associades retorna el perímetre normal del blob.
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 20-07-2004.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: CBlobGetHullPerimeter
+      - FUNCTIONALITY: Calculates the convex hull perimeter of the blob
+      - PARAMETERS:
+      - RESULT:
+      - returns the convex hull perimeter of the blob or the perimeter if the
+      blob edges could not be retrieved
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  double CBlobGetHullPerimeter::operator()(const CBlob &blob) const
+  {
+    if (blob.Edges() != NULL && blob.Edges()->total > 0)
+    {
+      CvSeq *hull = cvConvexHull2(blob.Edges(), 0, CV_CLOCKWISE, 1);
+      return fabs(cvArcLength(hull, CV_WHOLE_SEQ, 1));
+    }
+    return blob.Perimeter();
+  }
+
+  double CBlobGetHullArea::operator()(const CBlob &blob) const
+  {
+    if (blob.Edges() != NULL && blob.Edges()->total > 0)
+    {
+      CvSeq *hull = cvConvexHull2(blob.Edges(), 0, CV_CLOCKWISE, 1);
+      return fabs(cvContourArea(hull));
+    }
+    return blob.Perimeter();
+  }
+
+  /**
+    - FUNCIÓ: MinX_at_MinY
+    - FUNCIONALITAT: Calcula el valor MinX a MinY.
+    - PARÀMETRES:
+    - blob: blob del que volem calcular el valor
+    - RESULTAT:
+    - retorna la X minima en la Y minima.
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 20-07-2004.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: CBlobGetMinXatMinY
+      - FUNCTIONALITY: Calculates the minimum X on the minimum Y
+      - PARAMETERS:
+      - RESULT:
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  double CBlobGetMinXatMinY::operator()(const CBlob &blob) const
+  {
+    double MinX_at_MinY = LONG_MAX;
+
+    CvSeqReader reader;
+    CvPoint edgeactual;
+
+    cvStartReadSeq(blob.Edges(), &reader);
+
+    for (int j = 0; j < blob.Edges()->total; j++)
+    {
+      CV_READ_SEQ_ELEM(edgeactual, reader);
+      if ((edgeactual.y == blob.MinY()) && (edgeactual.x < MinX_at_MinY))
+      {
+        MinX_at_MinY = edgeactual.x;
+      }
+    }
+
+    return MinX_at_MinY;
+  }
+
+  /**
+    - FUNCIÓ: MinY_at_MaxX
+    - FUNCIONALITAT: Calcula el valor MinX a MaxX.
+    - PARÀMETRES:
+    - blob: blob del que volem calcular el valor
+    - RESULTAT:
+    - retorna la Y minima en la X maxima.
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 20-07-2004.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: CBlobGetMinXatMinY
+      - FUNCTIONALITY: Calculates the minimum Y on the maximum X
+      - PARAMETERS:
+      - RESULT:
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  double CBlobGetMinYatMaxX::operator()(const CBlob &blob) const
+  {
+    double MinY_at_MaxX = LONG_MAX;
+
+    CvSeqReader reader;
+    CvPoint edgeactual;
+
+    cvStartReadSeq(blob.Edges(), &reader);
+
+    for (int j = 0; j < blob.Edges()->total; j++)
+    {
+      CV_READ_SEQ_ELEM(edgeactual, reader);
+      if ((edgeactual.x == blob.MaxX()) && (edgeactual.y < MinY_at_MaxX))
+      {
+        MinY_at_MaxX = edgeactual.y;
+      }
+    }
+
+    return MinY_at_MaxX;
+  }
+
+  /**
+    - FUNCIÓ: MaxX_at_MaxY
+    - FUNCIONALITAT: Calcula el valor MaxX a MaxY.
+    - PARÀMETRES:
+    - blob: blob del que volem calcular el valor
+    - RESULTAT:
+    - retorna la X maxima en la Y maxima.
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 20-07-2004.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: CBlobGetMaxXatMaxY
+      - FUNCTIONALITY: Calculates the maximum X on the maximum Y
+      - PARAMETERS:
+      - RESULT:
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  double CBlobGetMaxXatMaxY::operator()(const CBlob &blob) const
+  {
+    double MaxX_at_MaxY = LONG_MIN;
+
+    CvSeqReader reader;
+    CvPoint edgeactual;
+
+    cvStartReadSeq(blob.Edges(), &reader);
+
+    for (int j = 0; j < blob.Edges()->total; j++)
+    {
+      CV_READ_SEQ_ELEM(edgeactual, reader);
+      if ((edgeactual.y == blob.MaxY()) && (edgeactual.x > MaxX_at_MaxY))
+      {
+        MaxX_at_MaxY = edgeactual.x;
+      }
+    }
+
+    return MaxX_at_MaxY;
+  }
+
+  /**
+    - FUNCIÓ: MaxY_at_MinX
+    - FUNCIONALITAT: Calcula el valor MaxY a MinX.
+    - PARÀMETRES:
+    - blob: blob del que volem calcular el valor
+    - RESULTAT:
+    - retorna la Y maxima en la X minima.
+    - RESTRICCIONS:
+    - AUTOR: Ricard Borràs
+    - DATA DE CREACIÓ: 20-07-2004.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: CBlobGetMaxYatMinX
+      - FUNCTIONALITY: Calculates the maximum Y on the minimum X
+      - PARAMETERS:
+      - RESULT:
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  double CBlobGetMaxYatMinX::operator()(const CBlob &blob) const
+  {
+    double MaxY_at_MinX = LONG_MIN;
+
+    CvSeqReader reader;
+    CvPoint edgeactual;
+
+    cvStartReadSeq(blob.Edges(), &reader);
+
+    for (int j = 0; j < blob.Edges()->total; j++)
+    {
+      CV_READ_SEQ_ELEM(edgeactual, reader);
+      if ((edgeactual.x == blob.MinY()) && (edgeactual.y > MaxY_at_MinX))
+      {
+        MaxY_at_MinX = edgeactual.y;
+      }
+    }
+
+    return MaxY_at_MinX;
+  }
+
+  /**
+    Retorna l'elongació del blob (longitud/amplada)
+    */
+    /**
+      - FUNCTION: CBlobGetElongation
+      - FUNCTIONALITY: Calculates the elongation of the blob ( length/breadth )
+      - PARAMETERS:
+      - RESULT:
+      - RESTRICTIONS:
+      - See below to see how the lenght and the breadth are aproximated
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  double CBlobGetElongation::operator()(const CBlob &blob) const
+  {
+    double ampladaC, longitudC, amplada, longitud;
+
+    ampladaC = (double)(blob.Perimeter() + sqrt(pow(blob.Perimeter(), 2) - 16 * blob.Area())) / 4;
+    if (ampladaC <= 0.0) return 0;
+    longitudC = (double)blob.Area() / ampladaC;
+
+    longitud = MAX(longitudC, ampladaC);
+    amplada = MIN(longitudC, ampladaC);
+
+    return (double)longitud / amplada;
+  }
+
+  /**
+    Retorna la compacitat del blob
+    */
+    /**
+      - FUNCTION: CBlobGetCompactness
+      - FUNCTIONALITY: Calculates the compactness of the blob
+      ( maximum for circle shaped blobs, minimum for the rest)
+      - PARAMETERS:
+      - RESULT:
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  double CBlobGetCompactness::operator()(const CBlob &blob) const
+  {
+    if (blob.Area() != 0.0)
+      return (double)pow(blob.Perimeter(), 2) / (4 * CV_PI*blob.Area());
+    else
+      return 0.0;
+  }
+
+  /**
+    Retorna la rugositat del blob
+    */
+    /**
+      - FUNCTION: CBlobGetRoughness
+      - FUNCTIONALITY: Calculates the roughness of the blob
+      ( ratio between perimeter and convex hull perimeter)
+      - PARAMETERS:
+      - RESULT:
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  double CBlobGetRoughness::operator()(const CBlob &blob) const
+  {
+    CBlobGetHullPerimeter getHullPerimeter = CBlobGetHullPerimeter();
+
+    double hullPerimeter = getHullPerimeter(blob);
+
+    if (hullPerimeter != 0.0)
+      return blob.Perimeter() / hullPerimeter;//HullPerimeter();
+
+    return 0.0;
+  }
+
+  /**
+    Retorna la longitud del blob
+    */
+    /**
+      - FUNCTION: CBlobGetLength
+      - FUNCTIONALITY: Calculates the lenght of the blob (the biggest axis of the blob)
+      - PARAMETERS:
+      - RESULT:
+      - RESTRICTIONS:
+      - The lenght is an aproximation to the real lenght
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  double CBlobGetLength::operator()(const CBlob &blob) const
+  {
+    double ampladaC, longitudC;
+    double tmp;
+
+    tmp = blob.Perimeter()*blob.Perimeter() - 16 * blob.Area();
+
+    if (tmp > 0.0)
+      ampladaC = (double)(blob.Perimeter() + sqrt(tmp)) / 4;
+    // error intrínsec en els càlculs de l'àrea i el perímetre
+    else
+      ampladaC = (double)(blob.Perimeter()) / 4;
+
+    if (ampladaC <= 0.0) return 0;
+    longitudC = (double)blob.Area() / ampladaC;
+
+    return MAX(longitudC, ampladaC);
+  }
+
+  /**
+    Retorna l'amplada del blob
+    */
+    /**
+      - FUNCTION: CBlobGetBreadth
+      - FUNCTIONALITY: Calculates the breadth of the blob (the smallest axis of the blob)
+      - PARAMETERS:
+      - RESULT:
+      - RESTRICTIONS:
+      - The breadth is an aproximation to the real breadth
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  double CBlobGetBreadth::operator()(const CBlob &blob) const
+  {
+    double ampladaC, longitudC;
+    double tmp;
+
+    tmp = blob.Perimeter()*blob.Perimeter() - 16 * blob.Area();
+
+    if (tmp > 0.0)
+      ampladaC = (double)(blob.Perimeter() + sqrt(tmp)) / 4;
+    // error intrínsec en els càlculs de l'àrea i el perímetre
+    else
+      ampladaC = (double)(blob.Perimeter()) / 4;
+
+    if (ampladaC <= 0.0) return 0;
+    longitudC = (double)blob.Area() / ampladaC;
+
+    return MIN(longitudC, ampladaC);
+  }
+
+  /**
+    Calcula la distància entre un punt i el centre del blob
+    */
+    /**
+      - FUNCTION: CBlobGetDistanceFromPoint
+      - FUNCTIONALITY: Calculates the euclidean distance between the blob center and
+      the point specified in the constructor
+      - PARAMETERS:
+      - RESULT:
+      - RESTRICTIONS:
+      - AUTHOR: Ricard Borràs
+      - CREATION DATE: 25-05-2005.
+      - MODIFICATION: Date. Author. Description.
+      */
+  double CBlobGetDistanceFromPoint::operator()(const CBlob &blob) const
+  {
+    double xmitjana, ymitjana;
+    CBlobGetXCenter getXCenter;
+    CBlobGetYCenter getYCenter;
+
+    xmitjana = m_x - getXCenter(blob);
+    ymitjana = m_y - getYCenter(blob);
+
+    return sqrt((xmitjana*xmitjana) + (ymitjana*ymitjana));
+  }
+
+  /**
+    - FUNCIÓ: BlobGetXYInside
+    - FUNCIONALITAT: Calcula si un punt cau dins de la capsa rectangular
+    del blob
+    - RESULTAT:
+    - retorna 1 si hi està; 0 si no
+    - RESTRICCIONS:
+    - AUTOR: Francesc Pinyol Margalef
+    - DATA DE CREACIÓ: 16-01-2006.
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+    /**
+      - FUNCTION: BlobGetXYInside
+      - FUNCTIONALITY: Calculates whether a point is inside the
+      rectangular bounding box of a blob
+      - PARAMETERS:
+      - RESULT:
+      - returns 1 if it is inside; o if not
+      - RESTRICTIONS:
+      - AUTHOR: Francesc Pinyol Margalef
+      - CREATION DATE: 16-01-2006.
+      - MODIFICATION: Date. Author. Description.
+      */
+  double CBlobGetXYInside::operator()(const CBlob &blob) const
+  {
+    if (blob.Edges() == NULL || blob.Edges()->total == 0) return 0.0;
+
+    // passem els punts del blob a un vector de punts de les STL
+    CvSeqReader reader;
+    CBlob::vectorPunts vectorEdges;
+    CBlob::vectorPunts::iterator itEdges, itEdgesSeguent;
+    CvPoint edgeactual;
+    bool dinsBlob;
+
+    // agafem tots els punts amb la mateixa y que l'actual
+    cvStartReadSeq(blob.Edges(), &reader);
+
+    for (int i = 0; i < blob.Edges()->total; i++)
+    {
+      CV_READ_SEQ_ELEM(edgeactual, reader);
+      if (edgeactual.y == m_p.y)
+        vectorEdges.push_back(edgeactual);
+    }
+
+    if (vectorEdges.empty()) return 0.0;
+
+    // ordenem el vector per les Y's i les X's d'esquerra a dreta
+    std::sort(vectorEdges.begin(), vectorEdges.end(), CBlob::comparaCvPoint());
+
+    // recorrem el punts del blob de la mateixa fila que el punt d'entrada
+    // i mirem si la X del punt d'entrada està entre dos coordenades "plenes"
+    // del blob
+    itEdges = vectorEdges.begin();
+    itEdgesSeguent = vectorEdges.begin() + 1;
+    dinsBlob = true;
+
+    while (itEdges != (vectorEdges.end() - 1))
+    {
+      if ((*itEdges).x <= m_p.x && (*itEdgesSeguent).x >= m_p.x && dinsBlob)
+      {
+        vectorEdges.clear();
+        return 1.0;
+      }
+
+      ++itEdges;
+      ++itEdgesSeguent;
+      dinsBlob = !dinsBlob;
+    }
+
+    vectorEdges.clear();
+    return 0.0;
+  }
+
+#ifdef BLOB_OBJECT_FACTORY
+
+  /**
+    - FUNCIÓ: RegistraTotsOperadors
+    - FUNCIONALITAT: Registrar tots els operadors definits a blob.h
+    - PARÀMETRES:
+    - fabricaOperadorsBlob: fàbrica on es registraran els operadors
+    - RESULTAT:
+    - Modifica l'objecte fabricaOperadorsBlob
+    - RESTRICCIONS:
+    - Només es registraran els operadors de blob.h. Si se'n volen afegir, cal afegir-los amb
+    el mètode Register de la fàbrica.
+    - AUTOR: rborras
+    - DATA DE CREACIÓ: 2006/05/18
+    - MODIFICACIÓ: Data. Autor. Descripció.
+    */
+  void RegistraTotsOperadors(t_OperadorBlobFactory &fabricaOperadorsBlob)
+  {
+    // blob shape
+    fabricaOperadorsBlob.Register(CBlobGetArea().GetNom(), Type2Type<CBlobGetArea>());
+    fabricaOperadorsBlob.Register(CBlobGetBreadth().GetNom(), Type2Type<CBlobGetBreadth>());
+    fabricaOperadorsBlob.Register(CBlobGetCompactness().GetNom(), Type2Type<CBlobGetCompactness>());
+    fabricaOperadorsBlob.Register(CBlobGetElongation().GetNom(), Type2Type<CBlobGetElongation>());
+    fabricaOperadorsBlob.Register(CBlobGetExterior().GetNom(), Type2Type<CBlobGetExterior>());
+    fabricaOperadorsBlob.Register(CBlobGetLength().GetNom(), Type2Type<CBlobGetLength>());
+    fabricaOperadorsBlob.Register(CBlobGetPerimeter().GetNom(), Type2Type<CBlobGetPerimeter>());
+    fabricaOperadorsBlob.Register(CBlobGetRoughness().GetNom(), Type2Type<CBlobGetRoughness>());
+
+    // extern pixels
+    fabricaOperadorsBlob.Register(CBlobGetExternPerimeterRatio().GetNom(), Type2Type<CBlobGetExternPerimeterRatio>());
+    fabricaOperadorsBlob.Register(CBlobGetExternHullPerimeterRatio().GetNom(), Type2Type<CBlobGetExternHullPerimeterRatio>());
+    fabricaOperadorsBlob.Register(CBlobGetExternPerimeter().GetNom(), Type2Type<CBlobGetExternPerimeter>());
+
+
+    // hull
+    fabricaOperadorsBlob.Register(CBlobGetHullPerimeter().GetNom(), Type2Type<CBlobGetHullPerimeter>());
+    fabricaOperadorsBlob.Register(CBlobGetHullArea().GetNom(), Type2Type<CBlobGetHullArea>());
+
+
+    // elipse info
+    fabricaOperadorsBlob.Register(CBlobGetMajorAxisLength().GetNom(), Type2Type<CBlobGetMajorAxisLength>());
+    fabricaOperadorsBlob.Register(CBlobGetMinorAxisLength().GetNom(), Type2Type<CBlobGetMinorAxisLength>());
+    fabricaOperadorsBlob.Register(CBlobGetAxisRatio().GetNom(), Type2Type<CBlobGetAxisRatio>());
+    fabricaOperadorsBlob.Register(CBlobGetOrientation().GetNom(), Type2Type<CBlobGetOrientation>());
+    fabricaOperadorsBlob.Register(CBlobGetOrientationCos().GetNom(), Type2Type<CBlobGetOrientationCos>());
+    fabricaOperadorsBlob.Register(CBlobGetAreaElipseRatio().GetNom(), Type2Type<CBlobGetAreaElipseRatio>());
+
+    // min an max
+    fabricaOperadorsBlob.Register(CBlobGetMaxX().GetNom(), Type2Type<CBlobGetMaxX>());
+    fabricaOperadorsBlob.Register(CBlobGetMaxY().GetNom(), Type2Type<CBlobGetMaxY>());
+    fabricaOperadorsBlob.Register(CBlobGetMinX().GetNom(), Type2Type<CBlobGetMinX>());
+    fabricaOperadorsBlob.Register(CBlobGetMinY().GetNom(), Type2Type<CBlobGetMinY>());
+
+    fabricaOperadorsBlob.Register(CBlobGetMaxXatMaxY().GetNom(), Type2Type<CBlobGetMaxXatMaxY>());
+    fabricaOperadorsBlob.Register(CBlobGetMaxYatMinX().GetNom(), Type2Type<CBlobGetMaxYatMinX>());
+    fabricaOperadorsBlob.Register(CBlobGetMinXatMinY().GetNom(), Type2Type<CBlobGetMinXatMinY>());
+    fabricaOperadorsBlob.Register(CBlobGetMinYatMaxX().GetNom(), Type2Type<CBlobGetMinYatMaxX>());
+
+    // grey level stats
+    fabricaOperadorsBlob.Register(CBlobGetMean().GetNom(), Type2Type<CBlobGetMean>());
+    fabricaOperadorsBlob.Register(CBlobGetStdDev().GetNom(), Type2Type<CBlobGetStdDev>());
+
+    // coordinate info
+    fabricaOperadorsBlob.Register(CBlobGetXYInside().GetNom(), Type2Type<CBlobGetXYInside>());
+    fabricaOperadorsBlob.Register(CBlobGetDiffY().GetNom(), Type2Type<CBlobGetDiffY>());
+    fabricaOperadorsBlob.Register(CBlobGetDiffX().GetNom(), Type2Type<CBlobGetDiffX>());
+    fabricaOperadorsBlob.Register(CBlobGetXCenter().GetNom(), Type2Type<CBlobGetXCenter>());
+    fabricaOperadorsBlob.Register(CBlobGetYCenter().GetNom(), Type2Type<CBlobGetYCenter>());
+    fabricaOperadorsBlob.Register(CBlobGetDistanceFromPoint().GetNom(), Type2Type<CBlobGetDistanceFromPoint>());
+
+    // moments
+    fabricaOperadorsBlob.Register(CBlobGetMoment().GetNom(), Type2Type<CBlobGetMoment>());
+
+  }
+
+#endif
+
+}
+
diff --git a/package_bgs/jmo/blob.h b/package_bgs/MultiLayer/blob.h
similarity index 87%
rename from package_bgs/jmo/blob.h
rename to package_bgs/MultiLayer/blob.h
index 67bdf11f856c6b0b00814be6872b6d16a03e10e1..b7d5fe1ce788cf21d5e978807243f8f2847027e3 100644
--- a/package_bgs/jmo/blob.h
+++ b/package_bgs/MultiLayer/blob.h
@@ -43,9 +43,9 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 /************************************************************************
 Blob.h
 
-FUNCIONALITAT: Definici� de la classe CBlob
+FUNCIONALITAT: Definició de la classe CBlob
 AUTOR: Inspecta S.L.
-MODIFICACIONS (Modificaci�, Autor, Data):
+MODIFICACIONS (Modificació, Autor, Data):
 
 FUNCTIONALITY: Definition of the CBlob class and some helper classes to perform
 some calculations on it
@@ -53,51 +53,46 @@ AUTHOR: Inspecta S.L.
 MODIFICATIONS (Modification, Author, Date):
 
 **************************************************************************/
-
-//! Disable warnings referred to 255 character truncation for the std:map
-//#pragma warning( disable : 4786 ) 
-
-#ifndef CBLOB_INSPECTA_INCLUDED
-#define CBLOB_INSPECTA_INCLUDED
+#pragma once
 
 //#include "cxcore.h"
 #include "BlobLibraryConfiguration.h"
 #include <functional>
 #include <vector>
 #include <algorithm>
-#include <opencv2/core/types_c.h>
-//! Factor de conversi� de graus a radians
+#include "OpenCvLegacyIncludes.h"
+//! Factor de conversió de graus a radians
 #define DEGREE2RAD		(CV_PI / 180.0)
 
 namespace Blob
 {
 
   /**
-  Classe que representa un blob, ent�s com un conjunt de pixels del
-  mateix color contigus en una imatge binaritzada.
+    Classe que representa un blob, entés com un conjunt de pixels del
+    mateix color contigus en una imatge binaritzada.
 
-  Class to represent a blob, a group of connected pixels in a binary image
-  */
+    Class to represent a blob, a group of connected pixels in a binary image
+    */
   class CBlob
   {
   public:
-    //! Constructor est�ndard
+    //! Constructor estàndard
     //! Standard constructor
     CBlob();
-    //! Constructor de c�pia
+    //! Constructor de còpia
     //! Copy constructor
     CBlob(const CBlob &src);
     CBlob(const CBlob *src);
 
-    //! Destructor est�ndard
+    //! Destructor estàndard
     //! Standard Destructor
     ~CBlob();
 
-    //! Operador d'assignaci�
+    //! Operador d'assignació
     //! Assigment operator
     CBlob& operator=(const CBlob &src);
 
-    //! Indica si el blob est� buit ( no t� cap info associada )
+    //! Indica si el blob està buit ( no té cap info associada )
     //! Shows if the blob has associated information
     bool IsEmpty() const
     {
@@ -107,13 +102,13 @@ namespace Blob
     //! Neteja les cantonades del blob
     //! Clears the edges of the blob
     void ClearEdges();
-    //! Copia les cantonades del blob a un altre (les afegeix al dest�)
+    //! Copia les cantonades del blob a un altre (les afegeix al destí)
     //! Adds the blob edges to another blob
     void CopyEdges(CBlob &destination) const;
     //! Retorna el poligon convex del blob
     //! Calculates the convex hull of the blob
     bool GetConvexHull(CvSeq **dst) const;
-    //! Calcula l'elipse que s'adapta als v�rtexs del blob
+    //! Calcula l'elipse que s'adapta als vèrtexs del blob
     //! Fits an ellipse to the blob edges
     CvBox2D GetEllipse() const;
 
@@ -124,8 +119,8 @@ namespace Blob
     //! Funcions GET sobre els valors dels blobs
     //! Get functions
 
-    inline int Label() const	{ return etiqueta; }
-    inline int Parent() const	{ return parent; }
+    inline int Label() const { return etiqueta; }
+    inline int Parent() const { return parent; }
     inline double Area() const { return area; }
     inline double Perimeter() const { return perimeter; }
     inline double ExternPerimeter() const { return externPerimeter; }
@@ -176,14 +171,14 @@ namespace Blob
     //! mitjana
     //! mean of the grey scale values of the blob pixels
     double mean;
-    //! desviaci� standard
+    //! desviació standard
     //! standard deviation of the grey scale values of the blob pixels
     double stddev;
 
-    //! �rea de mem�ria on es desaran els punts de contorn del blob
+    //! àrea de memòria on es desaran els punts de contorn del blob
     //! storage which contains the edges of the blob
     CvMemStorage *m_storage;
-    //!	Sequ�ncia de punts del contorn del blob
+    //!	Sequència de punts del contorn del blob
     //! Sequence with the edges of the blob
     CvSeq *edges;
 
@@ -194,7 +189,7 @@ namespace Blob
     //! Helper class to compare two CvPoints (for sorting in FillBlob)
     struct comparaCvPoint : public std::binary_function<CvPoint, CvPoint, bool>
     {
-      //! Definim que un punt �s menor com m�s amunt a la dreta estigui
+      //! Definim que un punt és menor com més amunt a la dreta estigui
       bool operator()(CvPoint a, CvPoint b)
       {
         if (a.y == b.y)
@@ -208,22 +203,22 @@ namespace Blob
 
 
   /**************************************************************************
-  Definici� de les classes per a fer operacions sobre els blobs
+    Definició de les classes per a fer operacions sobre els blobs
 
-  Helper classes to perform operations on blobs
-  **************************************************************************/
+    Helper classes to perform operations on blobs
+    **************************************************************************/
 
 
-  //! Classe d'on derivarem totes les operacions sobre els blobs
-  //! Interface to derive all blob operations
+    //! Classe d'on derivarem totes les operacions sobre els blobs
+    //! Interface to derive all blob operations
   class COperadorBlob
   {
   public:
-    virtual ~COperadorBlob(){};
+    virtual ~COperadorBlob() {};
 
-    //! Aplica l'operaci� al blob
+    //! Aplica l'operació al blob
     virtual double operator()(const CBlob &blob) const = 0;
-    //! Obt� el nom de l'operador
+    //! Obté el nom de l'operador
     virtual const char *GetNom() const = 0;
 
     operator COperadorBlob*() const
@@ -236,8 +231,8 @@ namespace Blob
 
 #ifdef BLOB_OBJECT_FACTORY
   /**
-  Funci� per comparar dos identificadors dins de la f�brica de COperadorBlobs
-  */
+    Funció per comparar dos identificadors dins de la fàbrica de COperadorBlobs
+    */
   struct functorComparacioIdOperador
   {
     bool operator()(const char* s1, const char* s2) const
@@ -249,12 +244,12 @@ namespace Blob
   //! Definition of Object factory type for COperadorBlob objects
   typedef ObjectFactory<COperadorBlob, const char *, functorComparacioIdOperador > t_OperadorBlobFactory;
 
-  //! Funci� global per a registrar tots els operadors definits a blob.h
-  void RegistraTotsOperadors( t_OperadorBlobFactory &fabricaOperadorsBlob );
+  //! Funció global per a registrar tots els operadors definits a blob.h
+  void RegistraTotsOperadors(t_OperadorBlobFactory &fabricaOperadorsBlob);
 
 #endif
 
-  //! Classe per calcular l'�rea d'un blob
+  //! Classe per calcular l'àrea d'un blob
   //! Class to get the area of a blob
   class CBlobGetArea : public COperadorBlob
   {
@@ -284,7 +279,7 @@ namespace Blob
     }
   };
 
-  //! Classe que diu si un blob �s extern o no
+  //! Classe que diu si un blob és extern o no
   //! Class to get the extern flag of a blob
   class CBlobGetExterior : public COperadorBlob
   {
@@ -314,7 +309,7 @@ namespace Blob
     }
   };
 
-  //! Classe per calcular la desviaci� est�ndard dels nivells de gris d'un blob
+  //! Classe per calcular la desviació estàndard dels nivells de gris d'un blob
   //! Class to get the standard deviation of the grey level values of a blob
   class CBlobGetStdDev : public COperadorBlob
   {
@@ -365,7 +360,7 @@ namespace Blob
     }
   };
 
-  //! Classe per calcular la difer�ncia en X del blob
+  //! Classe per calcular la diferència en X del blob
   class CBlobGetDiffX : public COperadorBlob
   {
   public:
@@ -379,7 +374,7 @@ namespace Blob
     }
   };
 
-  //! Classe per calcular la difer�ncia en X del blob
+  //! Classe per calcular la diferència en X del blob
   class CBlobGetDiffY : public COperadorBlob
   {
   public:
@@ -398,7 +393,7 @@ namespace Blob
   class CBlobGetMoment : public COperadorBlob
   {
   public:
-    //! Constructor est�ndard
+    //! Constructor estàndard
     //! Standard constructor (gets the 00 moment)
     CBlobGetMoment()
     {
@@ -434,7 +429,7 @@ namespace Blob
     }
   };
 
-  //! Classe per calcular l'�rea del poligon convex d'un blob
+  //! Classe per calcular l'àrea del poligon convex d'un blob
   //! Class to calculate the convex hull area of a blob
   class CBlobGetHullArea : public COperadorBlob
   {
@@ -494,7 +489,7 @@ namespace Blob
     }
   };
 
-  //! Classe per a calcular la x m�nima
+  //! Classe per a calcular la x mínima
   //! Class to get the minimum x
   class CBlobGetMinX : public COperadorBlob
   {
@@ -509,7 +504,7 @@ namespace Blob
     }
   };
 
-  //! Classe per a calcular la x m�xima
+  //! Classe per a calcular la x màxima
   //! Class to get the maximum x
   class CBlobGetMaxX : public COperadorBlob
   {
@@ -524,7 +519,7 @@ namespace Blob
     }
   };
 
-  //! Classe per a calcular la y m�nima
+  //! Classe per a calcular la y mínima
   //! Class to get the minimum y
   class CBlobGetMinY : public COperadorBlob
   {
@@ -539,7 +534,7 @@ namespace Blob
     }
   };
 
-  //! Classe per a calcular la y m�xima
+  //! Classe per a calcular la y màxima
   //! Class to get the maximum y
   class CBlobGetMaxY : public COperadorBlob
   {
@@ -579,7 +574,7 @@ namespace Blob
     }
   };
 
-  //! Classe per calcular la dist�ncia entre el centre del blob i un punt donat
+  //! Classe per calcular la distància entre el centre del blob i un punt donat
   //! Class to calculate the euclidean distance between the center of a blob and a given point
   class CBlobGetDistanceFromPoint : public COperadorBlob
   {
@@ -603,7 +598,7 @@ namespace Blob
     }
 
   private:
-    // coordenades del punt on volem calcular la dist�ncia
+    // coordenades del punt on volem calcular la distància
     double m_x, m_y;
   };
 
@@ -623,8 +618,8 @@ namespace Blob
   };
 
   //! Classe per calcular el ratio entre el perimetre i nombre pixels externs
-  //! valors propers a 0 indiquen que la majoria del blob �s intern
-  //! valors propers a 1 indiquen que la majoria del blob �s extern
+  //! valors propers a 0 indiquen que la majoria del blob és intern
+  //! valors propers a 1 indiquen que la majoria del blob és extern
   //! Class to calculate the ratio between the perimeter and the number of extern pixels
   class CBlobGetExternPerimeterRatio : public COperadorBlob
   {
@@ -643,8 +638,8 @@ namespace Blob
   };
 
   //! Classe per calcular el ratio entre el perimetre convex i nombre pixels externs
-  //! valors propers a 0 indiquen que la majoria del blob �s intern
-  //! valors propers a 1 indiquen que la majoria del blob �s extern
+  //! valors propers a 0 indiquen que la majoria del blob és intern
+  //! valors propers a 1 indiquen que la majoria del blob és extern
   //! Class to calculate the ratio between the perimeter and the number of extern pixels
   class CBlobGetExternHullPerimeterRatio : public COperadorBlob
   {
@@ -713,7 +708,7 @@ namespace Blob
   };
 
   //! Classe per calcular el ratio entre l'area de la elipse i la de la taca
-  //! Class 
+  //! Class
   class CBlobGetAreaElipseRatio : public COperadorBlob
   {
   public:
@@ -755,7 +750,7 @@ namespace Blob
     }
   };
 
-  //! Classe per calcular l'orientaci� de l'ellipse del blob en radians
+  //! Classe per calcular l'orientació de l'ellipse del blob en radians
   //! Class to calculate the orientation of the ellipse that fits the blob edges in radians
   class CBlobGetOrientation : public COperadorBlob
   {
@@ -776,7 +771,7 @@ namespace Blob
     }
   };
 
-  //! Classe per calcular el cosinus de l'orientaci� de l'ellipse del blob
+  //! Classe per calcular el cosinus de l'orientació de l'ellipse del blob
   //! Class to calculate the cosinus of the orientation of the ellipse that fits the blob edges
   class CBlobGetOrientationCos : public COperadorBlob
   {
@@ -793,7 +788,7 @@ namespace Blob
   };
 
 
-  //! Classe per calcular el ratio entre l'eix major i menor de la el�lipse
+  //! Classe per calcular el ratio entre l'eix major i menor de la el·lipse
   //! Class to calculate the ratio between both axes of the ellipse
   class CBlobGetAxisRatio : public COperadorBlob
   {
@@ -816,7 +811,7 @@ namespace Blob
   class CBlobGetXYInside : public COperadorBlob
   {
   public:
-    //! Constructor est�ndard
+    //! Constructor estàndard
     //! Standard constructor
     CBlobGetXYInside()
     {
@@ -841,6 +836,3 @@ namespace Blob
   };
 
 }
-
-#endif //CBLOB_INSPECTA_INCLUDED
-
diff --git a/package_bgs/PAWCS.cpp b/package_bgs/PAWCS.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..908b3aeb83769663b1bf3f2219b78de64e4492e5
--- /dev/null
+++ b/package_bgs/PAWCS.cpp
@@ -0,0 +1,93 @@
+/*
+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 "PAWCS.h"
+
+using namespace bgslibrary::algorithms;
+
+PAWCS::PAWCS() : pPAWCS(nullptr),
+fRelLBSPThreshold(BGSPAWCS_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD),
+nDescDistThresholdOffset(BGSPAWCS_DEFAULT_DESC_DIST_THRESHOLD_OFFSET),
+nMinColorDistThreshold(BGSPAWCS_DEFAULT_MIN_COLOR_DIST_THRESHOLD),
+nMaxNbWords(BGSPAWCS_DEFAULT_MAX_NB_WORDS),
+nSamplesForMovingAvgs(BGSPAWCS_DEFAULT_N_SAMPLES_FOR_MV_AVGS)
+{
+  std::cout << "PAWCS()" << std::endl;
+  setup("./config/PAWCS.xml");
+}
+PAWCS::~PAWCS()
+{
+  if (pPAWCS)
+    delete pPAWCS;
+  std::cout << "~PAWCS()" << std::endl;
+}
+
+void PAWCS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+{
+  init(img_input, img_output, img_bgmodel);
+
+  if (firstTime)
+  {
+    pPAWCS = new BackgroundSubtractorPAWCS(
+      fRelLBSPThreshold, nDescDistThresholdOffset, nMinColorDistThreshold,
+      nMaxNbWords, nSamplesForMovingAvgs);
+
+    pPAWCS->initialize(img_input, cv::Mat(img_input.size(), CV_8UC1, cv::Scalar_<uchar>(255)));
+    firstTime = false;
+  }
+
+  pPAWCS->apply(img_input, img_foreground);
+  pPAWCS->getBackgroundImage(img_background);
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+  {
+    imshow("PAWCS FG", img_foreground);
+    imshow("PAWCS BG", img_background);
+  }
+#endif
+
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
+}
+
+void PAWCS::saveConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
+
+  cvWriteReal(fs, "fRelLBSPThreshold", fRelLBSPThreshold);
+  cvWriteInt(fs, "nDescDistThresholdOffset", nDescDistThresholdOffset);
+  cvWriteInt(fs, "nMinColorDistThreshold", nMinColorDistThreshold);
+  cvWriteInt(fs, "nMaxNbWords", nMaxNbWords);
+  cvWriteInt(fs, "nSamplesForMovingAvgs", nSamplesForMovingAvgs);
+  cvWriteInt(fs, "showOutput", showOutput);
+
+  cvReleaseFileStorage(&fs);
+}
+
+void PAWCS::loadConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  fRelLBSPThreshold = cvReadRealByName(fs, nullptr, "fRelLBSPThreshold", BGSPAWCS_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD);
+  nDescDistThresholdOffset = cvReadIntByName(fs, nullptr, "nDescDistThresholdOffset", BGSPAWCS_DEFAULT_DESC_DIST_THRESHOLD_OFFSET);
+  nMinColorDistThreshold = cvReadIntByName(fs, nullptr, "nMinColorDistThreshold", BGSPAWCS_DEFAULT_MIN_COLOR_DIST_THRESHOLD);
+  nMaxNbWords = cvReadIntByName(fs, nullptr, "nMaxNbWords", BGSPAWCS_DEFAULT_MAX_NB_WORDS);
+  nSamplesForMovingAvgs = cvReadIntByName(fs, nullptr, "nSamplesForMovingAvgs", BGSPAWCS_DEFAULT_N_SAMPLES_FOR_MV_AVGS);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
+
+  cvReleaseFileStorage(&fs);
+}
diff --git a/package_bgs/PAWCS.h b/package_bgs/PAWCS.h
new file mode 100644
index 0000000000000000000000000000000000000000..173bcf6917a2c6c253ca933538609be416feee63
--- /dev/null
+++ b/package_bgs/PAWCS.h
@@ -0,0 +1,48 @@
+/*
+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
+
+#include "IBGS.h"
+#include "LBSP/BackgroundSubtractorPAWCS.h"
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class PAWCS : public IBGS
+    {
+    private:
+      BackgroundSubtractorPAWCS* pPAWCS;
+
+      float fRelLBSPThreshold;
+      size_t nDescDistThresholdOffset;
+      size_t nMinColorDistThreshold;
+      size_t nMaxNbWords;
+      size_t nSamplesForMovingAvgs;
+
+    public:
+      PAWCS();
+      ~PAWCS();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/PBAS/PBAS.cpp b/package_bgs/PBAS/PBAS.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bc3ad40178d1302ac29860e3ae61b202508a26c0
--- /dev/null
+++ b/package_bgs/PBAS/PBAS.cpp
@@ -0,0 +1,585 @@
+/*
+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 "PBAS.h"
+
+PBAS::PBAS(void) : N(20), R_lower(18), Raute_min(2), T_lower(2), T_upper(200), R_scale(5), R_incdec(0.05), T_dec(0.05), T_inc(1)
+{
+  std::cout << "PBAS()" << std::endl;
+
+  //feature vector
+  alpha = 7.0;
+  beta = 1.0;
+  formerMeanNorm = 0;
+  width = 0;
+
+  //result image
+  foregroundValue = 255;
+  backgroundValue = 0;
+
+  //length of random array
+  countOfRandomNumb = 1000;
+
+  //the T(x_i) value needs initiation
+  T_init = R_lower;
+
+  //check if something is moving in the picture
+  isMove = false;
+
+  //for init, count number of runs
+  runs = 0;
+  newInitialization();
+}
+
+void PBAS::newInitialization()
+{
+  if (!randomN.empty())
+    randomN.clear();
+
+  if (!randomX.empty())
+    randomX.clear();
+
+  if (!randomY.empty())
+    randomY.clear();
+
+  if (!randomMinDist.empty())
+    randomMinDist.clear();
+
+  if (!randomT.empty())
+    randomT.clear();
+
+  if (!randomTN.empty())
+    randomTN.clear();
+
+  for (int l = 0; l < countOfRandomNumb; l++)
+  {
+    randomN.push_back((int)randomGenerator.uniform((int)0, (int)N));
+    randomX.push_back((int)randomGenerator.uniform(-1, +2));
+    randomY.push_back((int)randomGenerator.uniform(-1, +2));
+    randomMinDist.push_back((int)randomGenerator.uniform((int)0, (int)N));
+    randomT.push_back((int)randomGenerator.uniform((int)0, (int)T_upper));
+    randomTN.push_back((int)randomGenerator.uniform((int)0, (int)T_upper));
+  }
+}
+
+PBAS::~PBAS(void)
+{
+  std::cout << "~PBAS()" << std::endl;
+
+  randomN.clear();
+  randomX.clear();
+  randomY.clear();
+  randomMinDist.clear();
+  randomT.clear();
+  randomTN.clear();
+
+  for (int k = 0; k < backgroundModel.size(); ++k)
+  {
+    if (chans == 1)
+    {
+      backgroundModel.at(k).at(0).release();
+      backgroundModel.at(k).at(1).release();
+    }
+    else
+    {
+      backgroundModel.at(k).at(0).release();
+      backgroundModel.at(k).at(1).release();
+      backgroundModel.at(k).at(2).release();
+
+      backgroundModel.at(k).at(3).release();
+      backgroundModel.at(k).at(4).release();
+      backgroundModel.at(k).at(5).release();
+    }
+  }
+
+  backgroundModel.clear();
+  meanMinDist.release();
+
+  actualR.release();
+  actualT.release();
+
+  sobelX.release();
+  sobelY.release();
+}
+
+bool PBAS::process(cv::Mat* input, cv::Mat* output)
+{
+  if (width != input->cols)
+  {
+    width = input->cols;
+    chans = input->channels();
+    height = input->rows;
+
+    if (input->rows < 1 || input->cols < 1)
+    {
+      std::cout << "Error: Occurrence of to small (or empty?) image size in PBAS. STOPPING " << std::endl;
+      return false;
+    }
+  }
+
+  //iniate the background model
+  init(input);
+
+  resultMap = new cv::Mat(input->rows, input->cols, CV_8UC1);
+
+  //calculate features
+  calculateFeatures(&currentFeatures, input);
+
+  //set sumMagnitude to zero at beginning and then sum up in the loop
+  sumMagnitude = 0;
+  long glCounterFore = 0;
+  isMove = false;
+
+  //Here starts the whole processing of each pixel of the image
+  // for each pixel
+  for (int j = 0; j < resultMap->rows; ++j)
+  {
+    resultMap_Pt = resultMap->ptr<uchar>(j);
+    currentFeaturesM_Pt.clear();
+    currentFeaturesC_Pt.clear();
+    std::vector<float*> fT;
+    std::vector<uchar*> uT;
+    B_Mag_Pts.clear();
+    B_Col_Pts.clear();
+
+    for (int z = 0; z < chans; ++z)
+    {
+      currentFeaturesM_Pt.push_back(currentFeatures.at(z).ptr<float>(j));
+      currentFeaturesC_Pt.push_back(currentFeatures.at(z + chans).ptr<uchar>(j));
+
+      B_Mag_Pts.push_back(fT);
+
+      B_Col_Pts.push_back(uT);
+    }
+
+    meanMinDist_Pt = meanMinDist.ptr<float>(j);
+    actualR_Pt = actualR.ptr<float>(j);
+    actualT_Pt = actualT.ptr<float>(j);
+
+    for (int k = 0; k < runs; ++k)
+    {
+      for (int z = 0; z < chans; ++z)
+      {
+        B_Mag_Pts.at(z).push_back(backgroundModel.at(k).at(z).ptr<float>(j));
+        B_Col_Pts.at(z).push_back(backgroundModel.at(k).at(z + chans).ptr<uchar>(j));
+      }
+    }
+
+    for (int i = 0; i < resultMap->cols; ++i)
+    {
+      //Compare each pixel to in the worst runtime-case each background model
+      int count = 0;
+      int index = 0;
+
+      double norm = 0.0;
+      double dist = 0.0;
+      double minDist = 1000.0;
+      int entry = randomGenerator.uniform(3, countOfRandomNumb - 4);
+
+      do
+      {
+        if (chans == 3)
+        {
+          norm = sqrt(
+            (((double)B_Mag_Pts.at(0).at(index)[i] - ((double)*currentFeaturesM_Pt.at(0)))*((double)B_Mag_Pts.at(0).at(index)[i] - ((double)*currentFeaturesM_Pt.at(0)))) +
+            (((double)B_Mag_Pts.at(1).at(index)[i] - ((double)*currentFeaturesM_Pt.at(1)))*((double)B_Mag_Pts.at(1).at(index)[i] - ((double)*currentFeaturesM_Pt.at(1)))) +
+            (((double)B_Mag_Pts.at(2).at(index)[i] - ((double)*currentFeaturesM_Pt.at(2)))*((double)B_Mag_Pts.at(2).at(index)[i] - ((double)*currentFeaturesM_Pt.at(2))))
+          );
+
+          dist = sqrt(
+            (((double)B_Col_Pts.at(0).at(index)[i] - ((double)*currentFeaturesC_Pt.at(0)))*((double)B_Col_Pts.at(0).at(index)[i] - ((double)*currentFeaturesC_Pt.at(0)))) +
+            (((double)B_Col_Pts.at(1).at(index)[i] - ((double)*currentFeaturesC_Pt.at(1)))*((double)B_Col_Pts.at(1).at(index)[i] - ((double)*currentFeaturesC_Pt.at(1)))) +
+            (((double)B_Col_Pts.at(2).at(index)[i] - ((double)*currentFeaturesC_Pt.at(2)))*((double)B_Col_Pts.at(2).at(index)[i] - ((double)*currentFeaturesC_Pt.at(2))))
+          );
+        }
+        else
+        {
+          norm = abs((((double)B_Mag_Pts.at(0).at(index)[i] -
+            ((double)*currentFeaturesM_Pt.at(0)))*((double)B_Mag_Pts.at(0).at(index)[i] - ((double)*currentFeaturesM_Pt.at(0)))));
+
+          dist = abs((((double)B_Col_Pts.at(0).at(index)[i] -
+            ((double)*currentFeaturesC_Pt.at(0)))*((double)B_Col_Pts.at(0).at(index)[i] - ((double)*currentFeaturesC_Pt.at(0))))
+          );
+        }
+        dist = ((double)alpha*(norm / formerMeanMag) + beta*dist);
+
+        if ((dist < *actualR_Pt))
+        {
+          ++count;
+          if (minDist > dist)
+            minDist = dist;
+        }
+        else
+        {
+          sumMagnitude += (double)(norm);
+          ++glCounterFore;
+        }
+        ++index;
+      } while ((count < Raute_min) && (index < runs));
+
+
+      //#############################################
+      //update backgroundmodel
+      // is BACKGROUND
+      if (count >= Raute_min)
+      {
+        *resultMap_Pt = 0;
+        double ratio = std::ceil((double)T_upper / (double)(*actualT_Pt));
+        //in the first run every distance is zero, because there is no background model
+        //in the secont run, we have already one image as background model, hence a
+        // reasonable minDist could be found -> because of the partly 1/run changing in the running average, we set in the first try meanMinDist to the actual minDist value
+        if (runs < N && runs > 2)
+        {
+          *meanMinDist_Pt = ((((float)(runs - 1)) * (*meanMinDist_Pt)) + (float)minDist) / ((float)runs);
+        }
+        else if (runs < N && runs == 2)
+        {
+          *meanMinDist_Pt = (float)minDist;
+        }
+
+        //1. update model
+        if (runs == N)
+        {
+          //Update current pixel
+          //check if random numer is smaller than ratio
+          if (randomT.at(entry) < ratio)
+          {
+            // replace randomly chosen sample
+            int rand = randomN.at(entry + 1); //randomGenerator.uniform((int)0,(int)N-1);
+            for (int z = 0; z < chans; ++z)
+            {
+              B_Mag_Pts.at(z).at(rand)[i] = (float)*currentFeaturesM_Pt.at(z);
+              B_Col_Pts.at(z).at(rand)[i] = (uchar)*currentFeaturesC_Pt.at(z);
+
+            }
+
+            *meanMinDist_Pt = ((((float)(N - 1)) * (*meanMinDist_Pt)) + (float)minDist) / ((float)N);
+          }
+
+          //Update neighboring pixel model
+          if (randomTN.at(entry) < ratio)
+          {
+            //choose neighboring pixel randomly
+            int xNeigh = randomX.at(entry) + i;
+            int yNeigh = randomY.at(entry) + j;
+            checkValid(&xNeigh, &yNeigh);
+
+            // replace randomly chosen sample
+            int rand = randomN.at(entry - 1);
+            for (int z = 0; z < chans; ++z)
+            {
+              (backgroundModel.at(rand)).at(z).at<float>(yNeigh, xNeigh) = currentFeatures.at(z).at<float>(yNeigh, xNeigh);
+              (backgroundModel.at(rand)).at(z + chans).at<uchar>(yNeigh, xNeigh) = currentFeatures.at(z + chans).at<uchar>(yNeigh, xNeigh);
+            }
+          }
+        }
+      }
+      else
+      {
+        // store pixel as foreground
+        *resultMap_Pt = 255;
+
+        //there is some movement
+        isMove = true;
+      }
+
+      //#######################//#######################//#######################//#######################
+      //control loops
+      //#######################//#######################//#######################//#######################
+      //update R
+      decisionThresholdRegulator(actualR_Pt, meanMinDist_Pt);
+
+      //update T
+      learningRateRegulator(actualT_Pt, meanMinDist_Pt, resultMap_Pt);
+
+      //#######################//#######################//#######################//#######################
+      //#######################//#######################//#######################//#######################
+
+      //jump to next pixel
+      ++resultMap_Pt;
+      for (int z = 0; z < chans; ++z)
+      {
+        ++currentFeaturesM_Pt.at(z);
+        ++currentFeaturesC_Pt.at(z);
+      }
+
+      ++meanMinDist_Pt;
+      ++actualR_Pt;
+      ++actualT_Pt;
+    }
+  }
+
+  resultMap->copyTo(*output);
+
+  //if there is no foreground -> no magnitudes fount
+  //-> initiate some low value to prevent diving through zero
+  double meanMag = sumMagnitude / (double)(glCounterFore + 1); //height*width);
+
+  if (meanMag > 20)
+    formerMeanMag = meanMag;
+  else
+    formerMeanMag = 20;
+
+  delete resultMap;
+
+  for (int z = 0; z < chans; ++z)
+  {
+    currentFeatures.at(z + chans).release();
+    currentFeatures.at(z).release();
+  }
+
+  return true;
+}
+
+void PBAS::decisionThresholdRegulator(float* pt, float* meanDist)
+{
+  //update R
+  double tempR = *pt;
+  double newThresh = (*meanDist)*R_scale;
+
+  if (tempR < newThresh)
+  {
+    tempR += tempR * R_incdec;
+  }
+  else
+  {
+    tempR -= tempR * R_incdec;
+  }
+
+  if (tempR >= R_lower)
+    *pt = (float)tempR;
+  else
+    *pt = (float)R_lower;
+}
+
+void PBAS::learningRateRegulator(float* pt, float* meanDist, uchar* isFore)
+{
+  //time update
+  double tempT = *pt;
+
+  if ((int)*isFore < 128)
+  {
+    tempT -= T_inc / (*meanDist + 1.0);
+  }
+  else
+  {
+    tempT += T_dec / (*meanDist + 1.0);
+  }
+
+  if (tempT > T_lower && tempT < T_upper)
+    *pt = (float)tempT;
+}
+
+void PBAS::checkValid(int *x, int *y)
+{
+  if (*x < 0)
+  {
+    *x = 0;
+  }
+  else if (*x >= width)
+  {
+    *x = width - 1;
+  }
+
+  if (*y < 0)
+  {
+    *y = 0;
+  }
+  else if (*y >= height)
+  {
+    *y = height - 1;
+  }
+}
+
+void PBAS::init(cv::Mat* input)
+{
+  if (runs < N)
+  {
+    std::vector<cv::Mat> init;
+    calculateFeatures(&init, input);
+    backgroundModel.push_back(init);
+
+    if (chans == 1)
+    {
+      init.at(0).release();
+      init.at(1).release();
+    }
+    else
+    {
+      init.at(0).release();
+      init.at(1).release();
+      init.at(2).release();
+      init.at(3).release();
+      init.at(4).release();
+      init.at(5).release();
+    }
+
+    init.clear();
+
+    if (runs == 0)
+    {
+      meanMinDist.create(input->size(), CV_32FC1);
+      meanMinDist.zeros(input->rows, input->cols, CV_32FC1);
+
+      actualR.create(input->rows, input->cols, CV_32FC1);
+      actualT.create(input->rows, input->cols, CV_32FC1);
+
+      float* ptRs, *ptTs; //, *ptM;
+      for (int rows = 0; rows < actualR.rows; ++rows)
+      {
+        ptRs = actualR.ptr<float>(rows);
+        ptTs = actualT.ptr<float>(rows);
+
+        for (int cols = 0; cols < actualR.cols; ++cols)
+        {
+          ptRs[cols] = (float)R_lower;
+          ptTs[cols] = (float)T_init;
+        }
+      }
+    }
+
+    ++runs;
+  }
+}
+
+void PBAS::calculateFeatures(std::vector<cv::Mat>* feature, cv::Mat* inputImage)
+{
+  if (!feature->empty())
+    feature->clear();
+
+  cv::Mat mag[3], dir;
+
+  if (inputImage->channels() == 3)
+  {
+    std::vector<cv::Mat> rgbChannels(3);
+    cv::split(*inputImage, rgbChannels);
+
+    for (int l = 0; l < 3; ++l)
+    {
+      cv::Sobel(rgbChannels.at(l), sobelX, CV_32F, 1, 0, 3, 1, 0.0);
+      cv::Sobel(rgbChannels.at(l), sobelY, CV_32F, 0, 1, 3, 1, 0.0);
+
+      // Compute the L2 norm and direction of the gradient
+      cv::cartToPolar(sobelX, sobelY, mag[l], dir, true);
+      feature->push_back(mag[l]);
+      sobelX.release();
+      sobelY.release();
+    }
+
+    feature->push_back(rgbChannels.at(0));
+    feature->push_back(rgbChannels.at(1));
+    feature->push_back(rgbChannels.at(2));
+    rgbChannels.at(0).release();
+    rgbChannels.at(1).release();
+    rgbChannels.at(2).release();
+  }
+  else
+  {
+    cv::Sobel(*inputImage, sobelX, CV_32F, 1, 0, 3, 1, 0.0);
+    cv::Sobel(*inputImage, sobelY, CV_32F, 0, 1, 3, 1, 0.0);
+
+    // Compute the L2 norm and direction of the gradient
+    cv::cartToPolar(sobelX, sobelY, mag[0], dir, true);
+    feature->push_back(mag[0]);
+
+    cv::Mat temp;
+    inputImage->copyTo(temp);
+    feature->push_back(temp);
+    temp.release();
+  }
+
+  mag[0].release();
+  mag[1].release();
+  mag[2].release();
+  dir.release();
+}
+
+void PBAS::setN(int temp)
+{
+  N = temp;
+  newInitialization();
+}
+
+void PBAS::setRaute_min(int temp)
+{
+  Raute_min = temp;
+}
+
+void PBAS::setR_lower(double temp)
+{
+  R_lower = temp;
+}
+
+void PBAS::setR_incdec(double temp)
+{
+  R_incdec = temp;
+}
+
+void PBAS::setR_scale(double temp)
+{
+  R_scale = temp;
+}
+
+void PBAS::setT_init(double temp)
+{
+  T_init = temp;
+}
+
+void PBAS::setT_lower(double temp)
+{
+  T_lower = temp;
+}
+
+void PBAS::setT_upper(double temp)
+{
+  T_upper = temp;
+  newInitialization();
+}
+
+void PBAS::setT_dec(double temp)
+{
+  T_dec = temp;
+}
+
+void PBAS::setT_inc(double temp)
+{
+  T_inc = temp;
+}
+
+void PBAS::setAlpha(double temp)
+{
+  alpha = temp;
+}
+
+void PBAS::setBeta(double temp)
+{
+  beta = temp;
+}
+
+bool PBAS::isMovement()
+{
+  return isMove;
+}
+
+//cv::Mat* PBAS::getR1_xi()
+//{
+//	return &actualR;
+//}
+//
+//cv::Mat* PBAS::getT_xi()
+//{
+//	return &actualT;
+//}
diff --git a/package_bgs/PBAS/PBAS.h b/package_bgs/PBAS/PBAS.h
new file mode 100644
index 0000000000000000000000000000000000000000..9014a280bb9fc2e762813d2f02470377fc4b6c9a
--- /dev/null
+++ b/package_bgs/PBAS/PBAS.h
@@ -0,0 +1,207 @@
+/*
+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/>.
+*/
+//Implementation of the PBAS from:
+//
+//M. Hofmann, P. Tiefenbacher, G. Rigoll 
+//"Background Segmentation with Feedback: The Pixel-Based Adaptive Segmenter", 
+//in proc of IEEE Workshop on Change Detection, 2012
+//
+//Note: some changes, to improve the speed and memory requirements, were achieved in comparison to the 
+//described PBAS algorithm in the paper above.
+//
+//Example usage:
+// //Somewhere during initalization:
+// #include "PBAS.h"
+// #include <opencv2/opencv.hpp>
+// PBAS pbas;
+//
+// //you might want to change some parameters of the PBAS here...
+// ....
+//
+// //repeat for each frame
+// //make gaussian blur for reducing image noise
+//cv::Mat bluredImage;
+//cv::Mat pbastResult;
+//cv::GaussianBlur(singleFrame, bluredImage, cv::Size(5,5), 1.5);
+// 
+// //process image and receive segmentation in pbasResult
+//pbas.process(&bluredImage, &pbasResult);
+//
+// //make medianBlur on the result to reduce "salt and pepper noise"
+// //of the per pixel wise segmentation
+//cv::medianBlur(pbasResult, pbasResult, 5);
+//
+//
+//
+//Author: P.Tiefenbacher, https://sites.google.com/site/pbassegmenter/
+//Technische Universität München, Germany
+//Date: 22-May-2012, Version:0.1
+///////////
+#pragma once
+
+#include <iostream>
+#include <opencv2/opencv.hpp>
+//#include <highgui.h>
+
+class PBAS
+{
+public:
+  PBAS(void);
+  ~PBAS(void);
+  bool process(cv::Mat* input, cv::Mat* output);
+
+  void setN(int);
+  void setRaute_min(int);
+  void setR_lower(double);
+  void setR_incdec(double);
+  void setR_scale(double);
+  void setT_init(double);
+  void setT_lower(double);
+  void setT_upper(double);
+  void setT_dec(double);
+  void setT_inc(double);
+  void setAlpha(double);
+  void setBeta(double);
+
+  bool isMovement();
+
+
+private:
+  void calculateFeatures(std::vector<cv::Mat>* feature, cv::Mat* inputImage);
+  void checkValid(int *x, int *y);
+  void decisionThresholdRegulator(float* pt, float* meanDistArr);
+  void learningRateRegulator(float* pt, float* meanDist, uchar* isFore);
+  void init(cv::Mat*);
+  void newInitialization();
+
+  cv::Mat meanMinDist;
+  float* meanMinDist_Pt;
+
+
+
+  int width, height;
+  int chans;
+
+  //balance of feature pixel value to conture value
+  double alpha, beta;
+  //##################################################################################
+
+  double formerMeanNorm;
+
+  //define value of foreground/background pixels
+  int foregroundValue, backgroundValue;
+
+  //##################################################################################
+  //random number parameters
+
+  //random number generator
+  cv::RNG randomGenerator;
+
+  //length of random array initialization
+  long countOfRandomNumb;
+
+  //pre - initialize the randomNumbers for better performance
+  std::vector<int> randomN, randomMinDist, randomX, randomY, randomT, randomTN;
+
+  //###################################################################################
+
+  //check if something is moving
+  bool isMove;
+
+  //for init, count number of runs
+  int runs;
+
+
+  cv::Mat* resultMap;
+  std::vector<cv::Mat> currentFeatures;
+
+  std::vector<float*> currentFeaturesM_Pt;
+  std::vector<uchar*> currentFeaturesC_Pt;
+  uchar* resultMap_Pt;
+
+  std::vector<std::vector<float*>>B_Mag_Pts;
+  std::vector<std::vector<uchar*>>B_Col_Pts;
+
+  double sumMagnitude;
+  double formerMeanMag;
+  float formerDistanceBack;
+
+  //####################################################################################
+  //N - Number: Defining the size of the background-history-model
+  // number of samples per pixel
+  //size of background history B(x_i)
+  int N;
+  // background model
+  std::vector<std::vector<cv::Mat>> backgroundModel;
+  //####################################################################################
+  //####################################################################################
+  //R-Threshhold - Variables
+  //minimal Threshold for foreground and initial value of R(x_i)
+  // radius of the sphere -> lower border boundary
+  double R_lower;
+
+  //factor which defines new threshold of R(x_i) together with meanMinDist(x_i)
+  // scale for the sphere threshhold to define pixel-based Thresholds
+  double R_scale;
+
+  //decreasing / increasing factor of R(x_i)
+  // increasing/decreasing factor for the r-Threshold based on the result of rTreshScale * meanMinDistBackground
+  double R_incdec;
+
+  cv::Mat actualR;
+  float* actualR_Pt; //new pixel-based r-threshhold -> pointer to arrays
+  //#####################################################################################
+  //####################################################################################
+  //counter for minimal distance to background
+  // Defining the number of background-model-images, which have a lowerDIstance to the current Image than defined by the R-Thresholds, that are necessary
+  // to decide that this pixel is background
+  int Raute_min;
+  //#####################################################################################
+  //####################################################################################
+  //initial value of inverse update factor T(x_i)
+  // Initialize the background-model update rate
+  double T_init;
+
+  //increasing Factor of the update rate 1/T(x_i)
+  // scale that defines the increasing of the update rate of the background model, if the current pixel is background
+  //--> more frequently updates if pixel is background because, there shouln't be any change
+  double T_inc;
+
+  //upper boundary of T(x_i)
+  // defining an upper value, that nrSubsampling can achieve, thus it doesn't reach to an infinite value, where actually no update is possible
+  // at all
+  double T_upper;
+
+  //lower boundary of T(x_i)
+  // defining a minimum value for nrSubsampling --> base value 2.0
+  double T_lower;
+
+  //decreasing factor of the update rate 1/T(x_i)
+  // opposite scale to increasingRateScale, for decreasing the update rate of the background model, if the current pixel is foreground
+  //--> Thesis: Our Foreground is a real moving object -> thus the background-model is good, so don't update it
+  double T_dec;
+
+  //holds update rate of current pixel
+  cv::Mat actualT;
+  float* actualT_Pt;
+
+  //#####################################################################################
+
+
+  cv::Mat sobelX, sobelY;
+};
+
diff --git a/package_bgs/PixelBasedAdaptiveSegmenter.cpp b/package_bgs/PixelBasedAdaptiveSegmenter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8a3de97dd3413df895b05148862d484d8189982c
--- /dev/null
+++ b/package_bgs/PixelBasedAdaptiveSegmenter.cpp
@@ -0,0 +1,126 @@
+/*
+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 "PixelBasedAdaptiveSegmenter.h"
+
+using namespace bgslibrary::algorithms;
+
+PixelBasedAdaptiveSegmenter::PixelBasedAdaptiveSegmenter() :
+  enableInputBlur(true), enableOutputBlur(true),
+  alpha(7.0), beta(1.0), N(20), Raute_min(2), R_incdec(0.05), R_lower(18),
+  R_scale(5), T_dec(0.05), T_inc(1), T_init(18), T_lower(2), T_upper(200)
+{
+  std::cout << "PixelBasedAdaptiveSegmenter()" << std::endl;
+  setup("./config/PixelBasedAdaptiveSegmenter.xml");
+}
+
+PixelBasedAdaptiveSegmenter::~PixelBasedAdaptiveSegmenter()
+{
+  std::cout << "~PixelBasedAdaptiveSegmenter()" << std::endl;
+}
+
+void PixelBasedAdaptiveSegmenter::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+{
+  init(img_input, img_output, img_bgmodel);
+
+  if (firstTime)
+  {
+    pbas.setAlpha(alpha);
+    pbas.setBeta(beta);
+    pbas.setN(N);
+    pbas.setRaute_min(Raute_min);
+    pbas.setR_incdec(R_incdec);
+    pbas.setR_lower(R_lower);
+    pbas.setR_scale(R_scale);
+    pbas.setT_dec(T_dec);
+    pbas.setT_inc(T_inc);
+    pbas.setT_init(T_init);
+    pbas.setT_lower(T_lower);
+    pbas.setT_upper(T_upper);
+  }
+
+  cv::Mat img_input_new;
+  if (enableInputBlur)
+    cv::GaussianBlur(img_input, img_input_new, cv::Size(5, 5), 1.5);
+  else
+    img_input.copyTo(img_input_new);
+
+  pbas.process(&img_input_new, &img_foreground);
+  img_background = cv::Mat::zeros(img_input.size(), img_input.type());
+
+  if (enableOutputBlur)
+    cv::medianBlur(img_foreground, img_foreground, 5);
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+    cv::imshow("PBAS", img_foreground);
+#endif
+
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
+
+  firstTime = false;
+}
+
+void PixelBasedAdaptiveSegmenter::saveConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
+
+  cvWriteInt(fs, "enableInputBlur", enableInputBlur);
+  cvWriteInt(fs, "enableOutputBlur", enableOutputBlur);
+
+  cvWriteReal(fs, "alpha", alpha);
+  cvWriteReal(fs, "beta", beta);
+  cvWriteInt(fs, "N", N);
+  cvWriteInt(fs, "Raute_min", Raute_min);
+  cvWriteReal(fs, "R_incdec", R_incdec);
+  cvWriteInt(fs, "R_lower", R_lower);
+  cvWriteInt(fs, "R_scale", R_scale);
+  cvWriteReal(fs, "T_dec", T_dec);
+  cvWriteInt(fs, "T_inc", T_inc);
+  cvWriteInt(fs, "T_init", T_init);
+  cvWriteInt(fs, "T_lower", T_lower);
+  cvWriteInt(fs, "T_upper", T_upper);
+
+  cvWriteInt(fs, "showOutput", showOutput);
+
+  cvReleaseFileStorage(&fs);
+}
+
+void PixelBasedAdaptiveSegmenter::loadConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  enableInputBlur = cvReadIntByName(fs, nullptr, "enableInputBlur", true);
+  enableOutputBlur = cvReadIntByName(fs, nullptr, "enableOutputBlur", true);
+
+  alpha = cvReadRealByName(fs, nullptr, "alpha", 7.0);
+  beta = cvReadRealByName(fs, nullptr, "beta", 1.0);
+  N = cvReadIntByName(fs, nullptr, "N", 20);
+  Raute_min = cvReadIntByName(fs, nullptr, "Raute_min", 2);
+  R_incdec = cvReadRealByName(fs, nullptr, "R_incdec", 0.05);
+  R_lower = cvReadIntByName(fs, nullptr, "R_lower", 18);
+  R_scale = cvReadIntByName(fs, nullptr, "R_scale", 5);
+  T_dec = cvReadRealByName(fs, nullptr, "T_dec", 0.05);
+  T_inc = cvReadIntByName(fs, nullptr, "T_inc", 1);
+  T_init = cvReadIntByName(fs, nullptr, "T_init", 18);
+  T_lower = cvReadIntByName(fs, nullptr, "T_lower", 2);
+  T_upper = cvReadIntByName(fs, nullptr, "T_upper", 200);
+
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
+
+  cvReleaseFileStorage(&fs);
+}
diff --git a/package_bgs/PixelBasedAdaptiveSegmenter.h b/package_bgs/PixelBasedAdaptiveSegmenter.h
new file mode 100644
index 0000000000000000000000000000000000000000..36dd0ad03a206ff7858dafe0279e3ed280a0f6d4
--- /dev/null
+++ b/package_bgs/PixelBasedAdaptiveSegmenter.h
@@ -0,0 +1,58 @@
+/*
+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
+
+#include "IBGS.h"
+#include "PBAS/PBAS.h"
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class PixelBasedAdaptiveSegmenter : public IBGS
+    {
+    private:
+      PBAS pbas;
+
+      bool enableInputBlur;
+      bool enableOutputBlur;
+
+      float alpha;
+      float beta;
+      int N;
+      int Raute_min;
+      float R_incdec;
+      int R_lower;
+      int R_scale;
+      float T_dec;
+      int T_inc;
+      int T_init;
+      int T_lower;
+      int T_upper;
+
+    public:
+      PixelBasedAdaptiveSegmenter();
+      ~PixelBasedAdaptiveSegmenter();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/SigmaDelta.cpp b/package_bgs/SigmaDelta.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d3052265052e1429745f1905fc2b354bf6ffd834
--- /dev/null
+++ b/package_bgs/SigmaDelta.cpp
@@ -0,0 +1,101 @@
+/*
+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 "SigmaDelta.h"
+
+using namespace bgslibrary::algorithms;
+
+SigmaDelta::SigmaDelta() :
+  ampFactor(1), minVar(15), maxVar(255), algorithm(sdLaMa091New())
+{
+  applyParams();
+  std::cout << "SigmaDelta()" << std::endl;
+  setup("./config/SigmaDelta.xml");
+}
+
+SigmaDelta::~SigmaDelta()
+{
+  sdLaMa091Free(algorithm);
+  std::cout << "~SigmaDelta()" << std::endl;
+}
+
+void SigmaDelta::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+{
+  init(img_input, img_output, img_bgmodel);
+
+  if (firstTime)
+  {
+    sdLaMa091AllocInit_8u_C3R(algorithm, img_input.data, img_input.cols, img_input.rows, img_input.step);
+    img_foreground = cv::Mat(img_input.size(), CV_8UC1);
+    img_background = cv::Mat(img_input.size(), CV_8UC3);
+    firstTime = false;
+  }
+  else
+  {
+    cv::Mat img_output_tmp(img_input.rows, img_input.cols, CV_8UC3);
+    sdLaMa091Update_8u_C3R(algorithm, img_input.data, img_output_tmp.data);
+
+    unsigned char* tmpBuffer = (unsigned char*)img_output_tmp.data;
+    unsigned char* outBuffer = (unsigned char*)img_foreground.data;
+
+    for (size_t i = 0; i < img_foreground.total(); ++i) {
+      *outBuffer = *tmpBuffer;
+      ++outBuffer;
+      tmpBuffer += img_output_tmp.channels();
+    }
+  }
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+    cv::imshow("Sigma-Delta", img_foreground);
+#endif
+
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
+}
+
+void SigmaDelta::saveConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
+
+  cvWriteInt(fs, "ampFactor", ampFactor);
+  cvWriteInt(fs, "minVar", minVar);
+  cvWriteInt(fs, "maxVar", maxVar);
+  cvWriteInt(fs, "showOutput", showOutput);
+
+  cvReleaseFileStorage(&fs);
+}
+
+void SigmaDelta::loadConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  ampFactor = cvReadIntByName(fs, nullptr, "ampFactor", 1);
+  minVar = cvReadIntByName(fs, nullptr, "minVar", 15);
+  maxVar = cvReadIntByName(fs, nullptr, "maxVar", 255);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
+
+  applyParams();
+
+  cvReleaseFileStorage(&fs);
+}
+
+void SigmaDelta::applyParams()
+{
+  sdLaMa091SetAmplificationFactor(algorithm, ampFactor);
+  sdLaMa091SetMinimalVariance(algorithm, minVar);
+  sdLaMa091SetMaximalVariance(algorithm, maxVar);
+}
diff --git a/package_bgs/SigmaDelta.h b/package_bgs/SigmaDelta.h
new file mode 100644
index 0000000000000000000000000000000000000000..c7b1a2c660323a11672fb399a092b81139392d2a
--- /dev/null
+++ b/package_bgs/SigmaDelta.h
@@ -0,0 +1,49 @@
+/*
+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
+
+#include "IBGS.h"
+
+//extern "C" {
+#include "SigmaDelta/sdLaMa091.h"
+//}
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class SigmaDelta : public IBGS
+    {
+    private:
+      unsigned int ampFactor;
+      unsigned int minVar;
+      unsigned int maxVar;
+      sdLaMa091_t* algorithm;
+
+    public:
+      SigmaDelta();
+      ~SigmaDelta();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+      void applyParams();
+    };
+  }
+}
diff --git a/package_bgs/bl/sdLaMa091.cpp b/package_bgs/SigmaDelta/sdLaMa091.cpp
similarity index 97%
rename from package_bgs/bl/sdLaMa091.cpp
rename to package_bgs/SigmaDelta/sdLaMa091.cpp
index 7071438d86ea8ce3a030081b2d85a0b4b3e2d4b0..286556be49ff77e7d7f5b406bc40e675c4dfafa6 100644
--- a/package_bgs/bl/sdLaMa091.cpp
+++ b/package_bgs/SigmaDelta/sdLaMa091.cpp
@@ -84,7 +84,7 @@ static inline uint8_t max(uint8_t a, uint8_t b) {
 }
 
 sdLaMa091_t* sdLaMa091New(void) {
-  sdLaMa091_t* sdLaMa091 = (sdLaMa091_t*) malloc(sizeof(*sdLaMa091));
+  sdLaMa091_t* sdLaMa091 = (sdLaMa091_t*)malloc(sizeof(*sdLaMa091));
 
 #ifdef DEFENSIVE_ALLOC
   if (sdLaMa091 == NULL) {
@@ -151,7 +151,7 @@ int32_t sdLaMa091AllocInit_8u_C1R(sdLaMa091_t* sdLaMa091,
   sdLaMa091->numBytes = stride * height;
   sdLaMa091->unusedBytes = stride - sdLaMa091->width;
 
-  sdLaMa091->Mt = (uint8_t*) malloc(sdLaMa091->numBytes);
+  sdLaMa091->Mt = (uint8_t*)malloc(sdLaMa091->numBytes);
 #ifdef DEFENSIVE_ALLOC
   if (sdLaMa091->Mt == NULL) {
     outputError("Cannot allocate sdLaMa091->Mt table");
@@ -160,7 +160,7 @@ int32_t sdLaMa091AllocInit_8u_C1R(sdLaMa091_t* sdLaMa091,
 #endif 
   memcpy(sdLaMa091->Mt, image_data, sdLaMa091->numBytes);
 
-  sdLaMa091->Ot = (uint8_t*) malloc(sdLaMa091->numBytes);
+  sdLaMa091->Ot = (uint8_t*)malloc(sdLaMa091->numBytes);
 #ifdef DEFENSIVE_ALLOC
   if (sdLaMa091->Ot == NULL) {
     outputError("Cannot allocate sdLaMa091->Ot table");
@@ -170,16 +170,16 @@ int32_t sdLaMa091AllocInit_8u_C1R(sdLaMa091_t* sdLaMa091,
   uint8_t* workOt = sdLaMa091->Ot;
 
   for (uint32_t i = 0; i < sdLaMa091->numBytes; i += sdLaMa091->stride) {
-    
+
     for (uint32_t j = 0; j < sdLaMa091->width; ++j, ++workOt)
       *workOt = 0;
 
-    
+
     if (sdLaMa091->unusedBytes > 0)
       workOt += sdLaMa091->unusedBytes;
   }
 
-  sdLaMa091->Vt = (uint8_t*) malloc(sdLaMa091->numBytes);
+  sdLaMa091->Vt = (uint8_t*)malloc(sdLaMa091->numBytes);
 #ifdef DEFENSIVE_ALLOC
   if (sdLaMa091->Vt == NULL) {
     outputError("Cannot allocate sdLaMa091->Vt table");
@@ -188,13 +188,13 @@ int32_t sdLaMa091AllocInit_8u_C1R(sdLaMa091_t* sdLaMa091,
 #endif
   uint8_t* workVt = sdLaMa091->Vt;
 
-  
+
   for (uint32_t i = 0; i < sdLaMa091->numBytes; i += sdLaMa091->stride) {
-    
+
     for (uint32_t j = 0; j < sdLaMa091->width; ++j, ++workVt)
       *workVt = sdLaMa091->Vmin;
 
-    
+
     if (sdLaMa091->unusedBytes > 0)
       workVt += sdLaMa091->unusedBytes;
   }
@@ -375,13 +375,13 @@ int32_t sdLaMa091Update_8u_C1R(sdLaMa091_t* sdLaMa091,
   }
 #endif 
 
-  
+
   const uint8_t* workImage = image_data;
   uint8_t* workMt = sdLaMa091->Mt;
 
-  
+
   for (uint32_t i = 0; i < sdLaMa091->numBytes; i += sdLaMa091->stride) {
-    
+
     for (uint32_t j = 0; j < sdLaMa091->width; ++j, ++workImage, ++workMt) {
       if (*workMt < *workImage)
         ++(*workMt);
@@ -389,7 +389,7 @@ int32_t sdLaMa091Update_8u_C1R(sdLaMa091_t* sdLaMa091,
         --(*workMt);
     }
 
-    
+
     if (sdLaMa091->unusedBytes > 0) {
       workImage += sdLaMa091->unusedBytes;
       workMt += sdLaMa091->unusedBytes;
@@ -400,14 +400,14 @@ int32_t sdLaMa091Update_8u_C1R(sdLaMa091_t* sdLaMa091,
   workMt = sdLaMa091->Mt;
   uint8_t* workOt = sdLaMa091->Ot;
 
-  
+
   for (uint32_t i = 0; i < sdLaMa091->numBytes; i += sdLaMa091->stride) {
-    
+
     for (uint32_t j = 0; j < sdLaMa091->width; ++j, ++workImage, ++workMt,
       ++workOt)
       *workOt = absVal(*workMt - *workImage);
 
-    
+
     if (sdLaMa091->unusedBytes > 0) {
       workImage += sdLaMa091->unusedBytes;
       workMt += sdLaMa091->unusedBytes;
@@ -415,13 +415,13 @@ int32_t sdLaMa091Update_8u_C1R(sdLaMa091_t* sdLaMa091,
     }
   }
 
-  
+
   workOt = sdLaMa091->Ot;
   uint8_t* workVt = sdLaMa091->Vt;
 
-  
+
   for (uint32_t i = 0; i < sdLaMa091->numBytes; i += sdLaMa091->stride) {
-    
+
     for (uint32_t j = 0; j < sdLaMa091->width; ++j, ++workOt, ++workVt) {
       uint32_t ampOt = sdLaMa091->N * *workOt;
 
@@ -433,30 +433,30 @@ int32_t sdLaMa091Update_8u_C1R(sdLaMa091_t* sdLaMa091,
       *workVt = max(min(*workVt, sdLaMa091->Vmax), sdLaMa091->Vmin);
     }
 
-    
+
     if (sdLaMa091->unusedBytes > 0) {
       workOt += sdLaMa091->unusedBytes;
       workVt += sdLaMa091->unusedBytes;
     }
   }
 
-  
+
   workOt = sdLaMa091->Ot;
   workVt = sdLaMa091->Vt;
 
-  
+
   for (uint32_t i = 0; i < sdLaMa091->numBytes; i += sdLaMa091->stride) {
-    
+
     for (uint32_t j = 0; j < sdLaMa091->width; ++j, ++segmentation_map,
       ++workOt, ++workVt) {
-      
+
       if (*workOt < *workVt)
         *segmentation_map = BACKGROUND;
       else
         *segmentation_map = FOREGROUND;
     }
 
-    
+
     if (sdLaMa091->unusedBytes > 0) {
       segmentation_map += sdLaMa091->unusedBytes;
       workOt += sdLaMa091->unusedBytes;
@@ -525,13 +525,13 @@ int32_t sdLaMa091Update_8u_C3R(sdLaMa091_t* sdLaMa091,
   }
 #endif 
 
-  
+
   const uint8_t* workImage = image_data;
   uint8_t* workMt = sdLaMa091->Mt;
 
-  
+
   for (uint32_t i = 0; i < sdLaMa091->numBytes; i += sdLaMa091->stride) {
-    
+
     for (uint32_t j = 0; j < sdLaMa091->rgbWidth; ++j, ++workImage, ++workMt) {
       if (*workMt < *workImage)
         ++(*workMt);
@@ -539,26 +539,26 @@ int32_t sdLaMa091Update_8u_C3R(sdLaMa091_t* sdLaMa091,
         --(*workMt);
     }
 
-    
+
     if (sdLaMa091->rgbUnusedBytes > 0) {
       workImage += sdLaMa091->rgbUnusedBytes;
       workMt += sdLaMa091->rgbUnusedBytes;
     }
   }
 
-  
+
   workImage = image_data;
   workMt = sdLaMa091->Mt;
   uint8_t* workOt = sdLaMa091->Ot;
 
-  
+
   for (uint32_t i = 0; i < sdLaMa091->numBytes; i += sdLaMa091->stride) {
-    
+
     for (uint32_t j = 0; j < sdLaMa091->rgbWidth; ++j, ++workImage, ++workMt,
       ++workOt)
       *workOt = absVal(*workMt - *workImage);
 
-    
+
     if (sdLaMa091->rgbUnusedBytes > 0) {
       workImage += sdLaMa091->rgbUnusedBytes;
       workMt += sdLaMa091->rgbUnusedBytes;
@@ -569,9 +569,9 @@ int32_t sdLaMa091Update_8u_C3R(sdLaMa091_t* sdLaMa091,
   workOt = sdLaMa091->Ot;
   uint8_t* workVt = sdLaMa091->Vt;
 
-  
+
   for (uint32_t i = 0; i < sdLaMa091->numBytes; i += sdLaMa091->stride) {
-    
+
     for (uint32_t j = 0; j < sdLaMa091->rgbWidth; ++j, ++workOt, ++workVt) {
       uint32_t ampOt = sdLaMa091->N * *workOt;
 
@@ -583,7 +583,7 @@ int32_t sdLaMa091Update_8u_C3R(sdLaMa091_t* sdLaMa091,
       *workVt = max(min(*workVt, sdLaMa091->Vmax), sdLaMa091->Vmin);
     }
 
-    
+
     if (sdLaMa091->rgbUnusedBytes > 0) {
       workOt += sdLaMa091->rgbUnusedBytes;
       workVt += sdLaMa091->rgbUnusedBytes;
@@ -593,19 +593,19 @@ int32_t sdLaMa091Update_8u_C3R(sdLaMa091_t* sdLaMa091,
   workOt = sdLaMa091->Ot;
   workVt = sdLaMa091->Vt;
 
-  
+
   for (uint32_t i = 0; i < sdLaMa091->numBytes; i += sdLaMa091->stride) {
-    
+
     uint32_t numColor = 0;
-    
+
     bool isForeground = false;
 
-    
+
     for (uint32_t j = 0; j < sdLaMa091->rgbWidth; ++j, ++workOt, ++workVt) {
       if (*workOt >= *workVt)
         isForeground = true;
 
-      
+
       if (numColor == BLUE) {
         if (isForeground) {
           *segmentation_map = FOREGROUND;
@@ -626,7 +626,7 @@ int32_t sdLaMa091Update_8u_C3R(sdLaMa091_t* sdLaMa091,
       numColor = (numColor + 1) % CHANNELS;
     }
 
-    
+
     if (sdLaMa091->rgbUnusedBytes > 0) {
       segmentation_map += sdLaMa091->rgbUnusedBytes;
       workOt += sdLaMa091->rgbUnusedBytes;
diff --git a/package_bgs/bl/sdLaMa091.h b/package_bgs/SigmaDelta/sdLaMa091.h
similarity index 96%
rename from package_bgs/bl/sdLaMa091.h
rename to package_bgs/SigmaDelta/sdLaMa091.h
index bec93fb505c5a46f75ca938418ae5fc38cff360e..cf9e777d913a35d9bd5fa79e7baf62f4cdfb9f78 100644
--- a/package_bgs/bl/sdLaMa091.h
+++ b/package_bgs/SigmaDelta/sdLaMa091.h
@@ -14,11 +14,9 @@ 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/>.
 */
-#ifndef SD_LA_MA_091_H_
-#define SD_LA_MA_091_H_
+#pragma once
 
 #include <errno.h>
-#include "stdbool.h"
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -68,5 +66,3 @@ int32_t sdLaMa091Update_8u_C3R(sdLaMa091_t* sdLaMa091,
   uint8_t* segmentation_map);
 
 int32_t sdLaMa091Free(sdLaMa091_t* sdLaMa091);
-
-#endif
diff --git a/package_bgs/StaticFrameDifferenceBGS.cpp b/package_bgs/StaticFrameDifference.cpp
similarity index 53%
rename from package_bgs/StaticFrameDifferenceBGS.cpp
rename to package_bgs/StaticFrameDifference.cpp
index 3463c457b2ae509560903d76d46ff8d2a61daf5d..2faa40c71f103b5b233ca223f1fd351cc2125f3e 100644
--- a/package_bgs/StaticFrameDifferenceBGS.cpp
+++ b/package_bgs/StaticFrameDifference.cpp
@@ -14,41 +14,41 @@ 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 "StaticFrameDifferenceBGS.h"
+#include "StaticFrameDifference.h"
 
-StaticFrameDifferenceBGS::StaticFrameDifferenceBGS() : firstTime(true), enableThreshold(true), threshold(15), showOutput(true)
+using namespace bgslibrary::algorithms;
+
+StaticFrameDifference::StaticFrameDifference() :
+  enableThreshold(true), threshold(15)
 {
-  std::cout << "StaticFrameDifferenceBGS()" << std::endl;
+  std::cout << "StaticFrameDifference()" << std::endl;
+  setup("./config/StaticFrameDifference.xml");
 }
 
-StaticFrameDifferenceBGS::~StaticFrameDifferenceBGS()
+StaticFrameDifference::~StaticFrameDifference()
 {
-  std::cout << "~StaticFrameDifferenceBGS()" << std::endl;
+  std::cout << "~StaticFrameDifference()" << std::endl;
 }
 
-void StaticFrameDifferenceBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+void StaticFrameDifference::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
+  init(img_input, img_output, img_bgmodel);
 
-  if(img_background.empty())
+  if (img_background.empty())
     img_input.copyTo(img_background);
-  
-  loadConfig();
-
-  if(firstTime)
-    saveConfig();
 
   cv::absdiff(img_input, img_background, img_foreground);
 
-  if(img_foreground.channels() == 3)
+  if (img_foreground.channels() == 3)
     cv::cvtColor(img_foreground, img_foreground, CV_BGR2GRAY);
 
-  if(enableThreshold)
+  if (enableThreshold)
     cv::threshold(img_foreground, img_foreground, threshold, 255, cv::THRESH_BINARY);
 
-  if(showOutput)
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
     cv::imshow("Static Frame Difference", img_foreground);
+#endif
 
   img_foreground.copyTo(img_output);
   img_background.copyTo(img_bgmodel);
@@ -56,9 +56,9 @@ void StaticFrameDifferenceBGS::process(const cv::Mat &img_input, cv::Mat &img_ou
   firstTime = false;
 }
 
-void StaticFrameDifferenceBGS::saveConfig()
+void StaticFrameDifference::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/StaticFrameDifferenceBGS.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteInt(fs, "enableThreshold", enableThreshold);
   cvWriteInt(fs, "threshold", threshold);
@@ -67,13 +67,13 @@ void StaticFrameDifferenceBGS::saveConfig()
   cvReleaseFileStorage(&fs);
 }
 
-void StaticFrameDifferenceBGS::loadConfig()
+void StaticFrameDifference::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/StaticFrameDifferenceBGS.xml", 0, CV_STORAGE_READ);
-  
-  enableThreshold = cvReadIntByName(fs, 0, "enableThreshold", true);
-  threshold = cvReadIntByName(fs, 0, "threshold", 15);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  enableThreshold = cvReadIntByName(fs, nullptr, "enableThreshold", true);
+  threshold = cvReadIntByName(fs, nullptr, "threshold", 15);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
-}
\ No newline at end of file
+}
diff --git a/package_bgs/StaticFrameDifference.h b/package_bgs/StaticFrameDifference.h
new file mode 100644
index 0000000000000000000000000000000000000000..8c8474c6ed065178f1275e23baa826caaab5fb36
--- /dev/null
+++ b/package_bgs/StaticFrameDifference.h
@@ -0,0 +1,42 @@
+/*
+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
+
+#include "IBGS.h"
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class StaticFrameDifference : public IBGS
+    {
+    private:
+      bool enableThreshold;
+      int threshold;
+
+    public:
+      StaticFrameDifference();
+      ~StaticFrameDifference();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/SuBSENSE.cpp b/package_bgs/SuBSENSE.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c8a0e5d11b8a952d72c721ae55d8793b642a2294
--- /dev/null
+++ b/package_bgs/SuBSENSE.cpp
@@ -0,0 +1,96 @@
+/*
+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 "SuBSENSE.h"
+
+using namespace bgslibrary::algorithms;
+
+SuBSENSE::SuBSENSE() :
+  pSubsense(0),
+  fRelLBSPThreshold(BGSSUBSENSE_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD),
+  nDescDistThresholdOffset(BGSSUBSENSE_DEFAULT_DESC_DIST_THRESHOLD_OFFSET),
+  nMinColorDistThreshold(BGSSUBSENSE_DEFAULT_MIN_COLOR_DIST_THRESHOLD),
+  nBGSamples(BGSSUBSENSE_DEFAULT_NB_BG_SAMPLES),
+  nRequiredBGSamples(BGSSUBSENSE_DEFAULT_REQUIRED_NB_BG_SAMPLES),
+  nSamplesForMovingAvgs(BGSSUBSENSE_DEFAULT_N_SAMPLES_FOR_MV_AVGS)
+{
+  std::cout << "SuBSENSE()" << std::endl;
+}
+
+SuBSENSE::~SuBSENSE() {
+  if (pSubsense)
+    delete pSubsense;
+  std::cout << "~SuBSENSE()" << std::endl;
+}
+
+void SuBSENSE::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+{
+  init(img_input, img_output, img_bgmodel);
+
+  if (firstTime)
+  {
+    pSubsense = new BackgroundSubtractorSuBSENSE(
+      fRelLBSPThreshold, nDescDistThresholdOffset, nMinColorDistThreshold,
+      nBGSamples, nRequiredBGSamples, nSamplesForMovingAvgs);
+
+    pSubsense->initialize(img_input, cv::Mat(img_input.size(), CV_8UC1, cv::Scalar_<uchar>(255)));
+    firstTime = false;
+  }
+
+  pSubsense->apply(img_input, img_foreground);
+  pSubsense->getBackgroundImage(img_background);
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+  {
+    imshow("SuBSENSE FG", img_foreground);
+    imshow("SuBSENSE BG", img_background);
+  }
+#endif
+
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
+}
+
+void SuBSENSE::saveConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
+
+  cvWriteReal(fs, "fRelLBSPThreshold", fRelLBSPThreshold);
+  cvWriteInt(fs, "nDescDistThresholdOffset", nDescDistThresholdOffset);
+  cvWriteInt(fs, "nMinColorDistThreshold", nMinColorDistThreshold);
+  cvWriteInt(fs, "nBGSamples", nBGSamples);
+  cvWriteInt(fs, "nRequiredBGSamples", nRequiredBGSamples);
+  cvWriteInt(fs, "nSamplesForMovingAvgs", nSamplesForMovingAvgs);
+  cvWriteInt(fs, "showOutput", showOutput);
+
+  cvReleaseFileStorage(&fs);
+}
+
+void SuBSENSE::loadConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  fRelLBSPThreshold = cvReadRealByName(fs, nullptr, "fRelLBSPThreshold", BGSSUBSENSE_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD);
+  nDescDistThresholdOffset = cvReadIntByName(fs, nullptr, "nDescDistThresholdOffset", BGSSUBSENSE_DEFAULT_DESC_DIST_THRESHOLD_OFFSET);
+  nMinColorDistThreshold = cvReadIntByName(fs, nullptr, "nMinColorDistThreshold", BGSSUBSENSE_DEFAULT_MIN_COLOR_DIST_THRESHOLD);
+  nBGSamples = cvReadIntByName(fs, nullptr, "nBGSamples", BGSSUBSENSE_DEFAULT_NB_BG_SAMPLES);
+  nRequiredBGSamples = cvReadIntByName(fs, nullptr, "nRequiredBGSamples", BGSSUBSENSE_DEFAULT_REQUIRED_NB_BG_SAMPLES);
+  nSamplesForMovingAvgs = cvReadIntByName(fs, nullptr, "nSamplesForMovingAvgs", BGSSUBSENSE_DEFAULT_N_SAMPLES_FOR_MV_AVGS);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
+
+  cvReleaseFileStorage(&fs);
+}
diff --git a/package_bgs/SuBSENSE.h b/package_bgs/SuBSENSE.h
new file mode 100644
index 0000000000000000000000000000000000000000..9ac9aa6f2fcbe04592b1abf5682245885238d07a
--- /dev/null
+++ b/package_bgs/SuBSENSE.h
@@ -0,0 +1,49 @@
+/*
+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
+
+#include "IBGS.h"
+#include "LBSP/BackgroundSubtractorSuBSENSE.h"
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class SuBSENSE : public IBGS
+    {
+    private:
+      BackgroundSubtractorSuBSENSE* pSubsense;
+
+      float fRelLBSPThreshold;
+      size_t nDescDistThresholdOffset;
+      size_t nMinColorDistThreshold;
+      size_t nBGSamples;
+      size_t nRequiredBGSamples;
+      size_t nSamplesForMovingAvgs;
+
+    public:
+      SuBSENSE();
+      ~SuBSENSE();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/T2F/FuzzyUtils.cpp b/package_bgs/T2F/FuzzyUtils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a151136e6eb946138bb411ef9bf9d6088e8d789c
--- /dev/null
+++ b/package_bgs/T2F/FuzzyUtils.cpp
@@ -0,0 +1,512 @@
+/*
+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 "FuzzyUtils.h"
+
+FuzzyUtils::FuzzyUtils(void) {}
+
+FuzzyUtils::~FuzzyUtils(void) {}
+
+void FuzzyUtils::LBP(IplImage* InputImage, IplImage* LBPimage)
+{
+  PixelUtils p;
+
+  float* neighberPixel = (float*)malloc(9 * sizeof(float));
+  float* BinaryValue = (float*)malloc(9 * sizeof(float));
+  float* CarreExp = (float*)malloc(9 * sizeof(float));
+  float* valLBP = (float*)malloc(1 * sizeof(float));
+
+  *valLBP = 0;
+
+  int x = 0, y = 0;
+
+  // on implemente les 8 valeurs puissance de 2 qui correspondent aux 8 elem. d'image voisins au elem. d'image central
+  *(CarreExp + 0) = 1.0;
+  *(CarreExp + 1) = 2.0;
+  *(CarreExp + 2) = 4.0;
+  *(CarreExp + 3) = 8.0;
+  *(CarreExp + 4) = 0.0;
+  *(CarreExp + 5) = 16.0;
+  *(CarreExp + 6) = 32.0;
+  *(CarreExp + 7) = 64.0;
+  *(CarreExp + 8) = 128.0;
+
+  //le calcule de LBP
+  //pour les 4 coins
+  /* 1.*/
+  if (x == 0 && y == 0)
+  {
+    p.getNeighberhoodGrayPixel(InputImage, x, y, neighberPixel);
+    getBinValue(neighberPixel, BinaryValue, 4, 0);
+    *valLBP = *valLBP + ((*(BinaryValue + 1))*(*(CarreExp + 1)) + (*(BinaryValue + 2))*(*(CarreExp + 2)) + (*(BinaryValue + 3))*(*(CarreExp + 3))) / 255.0;
+    p.PutGrayPixel(LBPimage, x, y, *valLBP);
+  }
+
+  /* 2.*/
+  if (x == 0 && y == InputImage->width)
+  {
+    *valLBP = 0;
+    p.getNeighberhoodGrayPixel(InputImage, x, y, neighberPixel);
+    getBinValue(neighberPixel, BinaryValue, 4, 1);
+    *valLBP = *valLBP + ((*(BinaryValue))*(*(CarreExp)) + (*(BinaryValue + 2))*(*(CarreExp + 2)) + (*(BinaryValue + 3))*(*(CarreExp + 3))) / 255.0;
+    p.PutGrayPixel(LBPimage, x, y, *valLBP);
+  }
+
+  /* 3.*/
+  if (x == InputImage->height && y == 0)
+  {
+    *valLBP = 0;
+    p.getNeighberhoodGrayPixel(InputImage, x, y, neighberPixel);
+    getBinValue(neighberPixel, BinaryValue, 4, 2);
+    *valLBP = *valLBP + ((*(BinaryValue))*(*(CarreExp)) + (*(BinaryValue + 1))*(*(CarreExp + 1)) + (*(BinaryValue + 3))*(*(CarreExp + 3))) / 255.0;
+    p.PutGrayPixel(LBPimage, x, y, *valLBP);
+  }
+
+  /* 4.*/
+  if (x == InputImage->height && y == InputImage->width)
+  {
+    *valLBP = 0;
+    p.getNeighberhoodGrayPixel(InputImage, x, y, neighberPixel);
+    getBinValue(neighberPixel, BinaryValue, 4, 3);
+    *valLBP = *valLBP + ((*(BinaryValue))*(*(CarreExp)) + (*(BinaryValue + 1))*(*(CarreExp + 1)) + (*(BinaryValue + 2))*(*(CarreExp + 2))) / 255.0;
+    p.PutGrayPixel(LBPimage, x, y, *valLBP);
+  }
+
+  //le calcul de LBP pour la première ligne : L(0)
+  if (x == 0 && (y != 0 && y != InputImage->width))
+  {
+    for (int y = 1; y < InputImage->width - 1; y++)
+    {
+      p.getNeighberhoodGrayPixel(InputImage, x, y, neighberPixel);
+      getBinValue(neighberPixel, BinaryValue, 6, 4);
+      *valLBP = 0;
+      *valLBP = *valLBP + ((*(BinaryValue))*(*(CarreExp)) + (*(BinaryValue + 1))*(*(CarreExp + 1)) + (*(BinaryValue + 2))*(*(CarreExp + 2)) + (*(BinaryValue + 3))*(*(CarreExp + 3)) + (*(BinaryValue + 5))*(*(CarreExp + 5))) / 255.0;
+      p.PutGrayPixel(LBPimage, x, y, *valLBP);
+    }
+  }
+
+  //le calcul de LBP pour la dernière colonne : C(w)
+  if ((x != 0 && x != InputImage->height) && y == InputImage->width)
+  {
+    for (int x = 1; x < InputImage->height - 1; x++)
+    {
+      p.getNeighberhoodGrayPixel(InputImage, x, y, neighberPixel);
+      getBinValue(neighberPixel, BinaryValue, 6, 4);
+      *valLBP = 0;
+      *valLBP = *valLBP + ((*(BinaryValue))*(*(CarreExp)) + (*(BinaryValue + 1))*(*(CarreExp + 1)) + (*(BinaryValue + 2))*(*(CarreExp + 2)) + (*(BinaryValue + 3))*(*(CarreExp + 3)) + (*(BinaryValue + 5))*(*(CarreExp + 5))) / 255.0;
+      p.PutGrayPixel(LBPimage, x, y, *valLBP);
+    }
+  }
+
+  //le calcul de LBP pour la dernière ligne : L(h)
+  if (x == InputImage->height && (y != 0 && y != InputImage->width))
+  {
+    for (int y = 1; y < InputImage->width - 1; y++)
+    {
+      p.getNeighberhoodGrayPixel(InputImage, x, y, neighberPixel);
+      getBinValue(neighberPixel, BinaryValue, 6, 1);
+      *valLBP = 0;
+      *valLBP = *valLBP + ((*(BinaryValue))*(*(CarreExp)) + (*(BinaryValue + 2))*(*(CarreExp + 2)) + (*(BinaryValue + 3))*(*(CarreExp + 3)) + (*(BinaryValue + 4))*(*(CarreExp + 4)) + (*(BinaryValue + 5))*(*(CarreExp + 5))) / 255.0;
+      p.PutGrayPixel(LBPimage, x, y, *valLBP);
+    }
+  }
+
+  //le calcul de LBP pour la première colonne : C(0)
+  if ((x != 0 && x != InputImage->height) && y == 0)
+  {
+    for (int x = 1; x < InputImage->height - 1; x++)
+    {
+      p.getNeighberhoodGrayPixel(InputImage, x, y, neighberPixel);
+      getBinValue(neighberPixel, BinaryValue, 6, 2);
+      *valLBP = 0;
+      *valLBP = *valLBP + ((*(BinaryValue))*(*(CarreExp + 5)) + (*(BinaryValue + 1))*(*(CarreExp + 6)) + (*(BinaryValue + 3))*(*(CarreExp + 3)) + (*(BinaryValue + 4))*(*(CarreExp)) + (*(BinaryValue + 5))*(*(CarreExp + 1))) / 255.0;
+      p.PutGrayPixel(LBPimage, x, y, *valLBP);
+    }
+  }
+
+  //pour le reste des elements d'image
+  for (int y = 1; y < InputImage->height - 1; y++)
+  {
+    for (int x = 1; x < InputImage->width - 1; x++)
+    {
+      p.getNeighberhoodGrayPixel(InputImage, x, y, neighberPixel);
+      getBinValue(neighberPixel, BinaryValue, 9, 4);
+      //le calcul de la valeur du LBP pour chaque elem. d'im.
+      *valLBP = 0;
+      for (int l = 0; l < 9; l++)
+        *valLBP = *valLBP + ((*(BinaryValue + l)) * (*(CarreExp + l))) / 255.0;
+      //printf("\nvalLBP(%d,%d)=%f",x,y,*valLBP);
+      p.PutGrayPixel(LBPimage, x, y, *valLBP);
+    }
+  }
+
+  free(neighberPixel);
+  free(BinaryValue);
+  free(CarreExp);
+  free(valLBP);
+}
+
+void FuzzyUtils::getBinValue(float* neighberGrayPixel, float* BinaryValue, int m, int n)
+{
+  // la comparaison entre la valeur d'elem d'image central et les valeurs des elem. d'im. voisins
+  // m = le numero des elements (4, 6 ou 9);
+  // n = la position de l'element central;
+
+  int h = 0;
+  for (int k = 0; k < m; k++)
+  {
+    if (*(neighberGrayPixel + k) >= *(neighberGrayPixel + n))
+    {
+      *(BinaryValue + h) = 1;
+      h++;
+    }
+    else
+    {
+      *(BinaryValue + h) = 0;
+      h++;
+    }
+  }
+}
+
+void FuzzyUtils::SimilarityDegreesImage(IplImage* CurrentImage, IplImage* BGImage, IplImage* DeltaImage, int n, int color_space)
+{
+  PixelUtils p;
+  int i, j;
+
+  if (n == 1)
+  {
+    float* CurrentGrayPixel = (float*)malloc(1 * (sizeof(float)));
+    float* BGGrayPixel = (float*)malloc(1 * (sizeof(float)));
+    float* DeltaGrayPixel = (float*)malloc(1 * (sizeof(float)));
+
+    for (i = 0; i < CurrentImage->width; i++)
+    {
+      for (j = 0; j < CurrentImage->height; j++)
+      {
+        p.GetGrayPixel(CurrentImage, i, j, CurrentGrayPixel);
+        p.GetGrayPixel(BGImage, i, j, BGGrayPixel);
+        RatioPixels(CurrentGrayPixel, BGGrayPixel, DeltaGrayPixel, 1);
+        p.PutGrayPixel(DeltaImage, i, j, *DeltaGrayPixel);
+      }
+    }
+
+    free(CurrentGrayPixel);
+    free(BGGrayPixel);
+    free(DeltaGrayPixel);
+  }
+
+  if (n != 1)
+  {
+    IplImage* ConvertedCurrentImage = cvCreateImage(cvSize(CurrentImage->width, CurrentImage->height), IPL_DEPTH_32F, 3);
+    IplImage* ConvertedBGImage = cvCreateImage(cvSize(CurrentImage->width, CurrentImage->height), IPL_DEPTH_32F, 3);
+
+    float* ConvertedCurrentPixel = (float*)malloc(3 * (sizeof(float)));
+    float* ConvertedBGPixel = (float*)malloc(3 * (sizeof(float)));
+    float* DeltaConvertedPixel = (float*)malloc(3 * (sizeof(float)));
+
+    p.ColorConversion(CurrentImage, ConvertedCurrentImage, color_space);
+    p.ColorConversion(BGImage, ConvertedBGImage, color_space);
+
+    for (i = 0; i < CurrentImage->width; i++)
+    {
+      for (j = 0; j < CurrentImage->height; j++)
+      {
+        p.GetPixel(ConvertedCurrentImage, i, j, ConvertedCurrentPixel);
+        p.GetPixel(ConvertedBGImage, i, j, ConvertedBGPixel);
+        RatioPixels(ConvertedCurrentPixel, ConvertedBGPixel, DeltaConvertedPixel, 3);
+        p.PutPixel(DeltaImage, i, j, DeltaConvertedPixel);
+      }
+    }
+
+    free(ConvertedCurrentPixel);
+    free(ConvertedBGPixel);
+    free(DeltaConvertedPixel);
+
+    cvReleaseImage(&ConvertedCurrentImage);
+    cvReleaseImage(&ConvertedBGImage);
+  }
+}
+
+void FuzzyUtils::RatioPixels(float* CurrentPixel, float* BGPixel, float* DeltaPixel, int n)
+{
+  if (n == 1)
+  {
+    if (*CurrentPixel < *BGPixel)
+      *DeltaPixel = *CurrentPixel / *BGPixel;
+
+    if (*CurrentPixel > *BGPixel)
+      *DeltaPixel = *BGPixel / *CurrentPixel;
+
+    if (*CurrentPixel == *BGPixel)
+      *DeltaPixel = 1.0;
+  }
+
+  if (n == 3)
+    for (int i = 0; i < 3; i++)
+    {
+      if (*(CurrentPixel + i) < *(BGPixel + i))
+        *(DeltaPixel + i) = *(CurrentPixel + i) / *(BGPixel + i);
+
+      if (*(CurrentPixel + i) > *(BGPixel + i))
+        *(DeltaPixel + i) = *(BGPixel + i) / *(CurrentPixel + i);
+
+      if (*(CurrentPixel + i) == *(BGPixel + i))
+        *(DeltaPixel + i) = 1.0;
+    }
+}
+
+void FuzzyUtils::getFuzzyIntegralSugeno(IplImage* H, IplImage* Delta, int n, float *MeasureG, IplImage* OutputImage)
+{
+  // MeasureG : est un vecteur contenant 3 mesure g (g1,g2,g3) tel que : g1+g2+g3=1
+  // n : =2 cad aggreger les 2 images "H" et "Delta"
+  //	   =1 cad aggreger uniquement les valeurs des composantes couleurs de l'image "Delta"
+
+  PixelUtils p;
+
+  float* HTexturePixel = (float*)malloc(1 * sizeof(float));
+  float* DeltaOhtaPixel = (float*)malloc(3 * (sizeof(float)));
+  int *Indice = (int*)malloc(3 * (sizeof(int)));
+  float *HI = (float*)malloc(3 * (sizeof(float)));
+  float *Integral = (float*)malloc(3 * (sizeof(float)));
+  float* X = (float*)malloc(1 * sizeof(float));
+  float* XiXj = (float*)malloc(1 * sizeof(float));
+  float IntegralFlou;
+
+  *Indice = 0;
+  *(Indice + 1) = 1;
+  *(Indice + 2) = 2;
+  *X = 1.0;
+
+  for (int i = 0; i < H->width; i++)
+  {
+    for (int j = 0; j < H->height; j++)
+    {
+      p.GetGrayPixel(H, i, j, HTexturePixel);
+      p.GetPixel(Delta, i, j, DeltaOhtaPixel);
+
+      *(HI + 0) = *(HTexturePixel + 0);
+      *(HI + 1) = *(DeltaOhtaPixel + 0);
+      *(HI + 2) = *(DeltaOhtaPixel + 1);
+
+      Trier(HI, 3, Indice);
+
+      *XiXj = *(MeasureG + (*(Indice + 1))) + (*(MeasureG + (*(Indice + 2))));
+
+      *(Integral + 0) = min((HI + (*(Indice + 0))), X);
+      *(Integral + 1) = min((HI + (*(Indice + 1))), XiXj);
+      *(Integral + 2) = min((HI + (*(Indice + 2))), ((MeasureG + (*(Indice + 2)))));
+
+      IntegralFlou = max(Integral, 3);
+      p.PutGrayPixel(OutputImage, i, j, IntegralFlou);
+    }
+  }
+
+  free(HTexturePixel);
+  free(DeltaOhtaPixel);
+  free(Indice);
+  free(HI);
+  free(X);
+  free(XiXj);
+  free(Integral);
+}
+
+void FuzzyUtils::getFuzzyIntegralChoquet(IplImage* H, IplImage* Delta, int n, float *MeasureG, IplImage* OutputImage)
+{
+  // MeasureG : est un vecteur contenant 3 mesure g (g1,g2,g3) tel que : g1+g2+g3=1
+  // n : =2 cad aggreger les 2 images "H" et "Delta"
+  //	   =1 cad aggreger uniquement les valeurs des composantes couleurs de l'image "Delta"
+
+  PixelUtils p;
+
+  float* HTexturePixel = (float*)malloc(1 * sizeof(float));
+  float* DeltaOhtaPixel = (float*)malloc(3 * (sizeof(float)));
+  int *Indice = (int*)malloc(3 * (sizeof(int)));
+  float *HI = (float*)malloc(3 * (sizeof(float)));
+  float *Integral = (float*)malloc(3 * (sizeof(float)));
+  float* X = (float*)malloc(1 * sizeof(float));
+  float* XiXj = (float*)malloc(1 * sizeof(float));
+  float IntegralFlou;
+
+  *Indice = 0;
+  *(Indice + 1) = 1;
+  *(Indice + 2) = 2;
+  *X = 1.0;
+
+  for (int i = 0; i < Delta->width; i++)
+  {
+    for (int j = 0; j < Delta->height; j++)
+    {
+      if (n == 2)
+      {
+        p.GetGrayPixel(H, i, j, HTexturePixel);
+        p.GetPixel(Delta, i, j, DeltaOhtaPixel);
+
+        *(HI + 0) = *(HTexturePixel + 0);
+        *(HI + 1) = *(DeltaOhtaPixel + 0);
+        *(HI + 2) = *(DeltaOhtaPixel + 1);
+      }
+
+      if (n == 1)
+      {
+        //remplir HI par les valeurs des 3 composantes couleurs uniquement
+        p.GetPixel(Delta, i, j, DeltaOhtaPixel);
+
+        *(HI + 0) = *(DeltaOhtaPixel + 0);
+        //*(HI+0) = *(DeltaOhtaPixel+2);
+        *(HI + 1) = *(DeltaOhtaPixel + 1);
+        *(HI + 2) = *(DeltaOhtaPixel + 2);
+      }
+
+      Trier(HI, 3, Indice);
+      *XiXj = *(MeasureG + (*(Indice + 1))) + (*(MeasureG + (*(Indice + 2))));
+
+      *(Integral + 0) = *(HI + (*(Indice + 0)))* (*X - *XiXj);
+      *(Integral + 1) = *(HI + (*(Indice + 1)))* (*XiXj - *(MeasureG + (*(Indice + 2))));
+      *(Integral + 2) = *(HI + (*(Indice + 2)))* (*(MeasureG + (*(Indice + 2))));
+
+      IntegralFlou = *(Integral + 0) + *(Integral + 1) + *(Integral + 2);
+      p.PutGrayPixel(OutputImage, i, j, IntegralFlou);
+    }
+  }
+
+  free(HTexturePixel);
+  free(DeltaOhtaPixel);
+  free(Indice);
+  free(HI);
+  free(X);
+  free(XiXj);
+  free(Integral);
+}
+
+void FuzzyUtils::FuzzyMeasureG(float g1, float g2, float g3, float *G)
+{
+  *(G + 0) = g1;
+  *(G + 1) = g2;
+  *(G + 2) = g3;
+}
+
+void FuzzyUtils::Trier(float* g, int n, int* index)
+{
+  // Cette fonction trie un vecteur g par ordre croissant et
+  // sort egalement l'indice des elements selon le trie dans le vecteur "index" supposé initialisé par des valeurs de 1 a n
+
+  float t;
+  int r, a, b;
+
+  for (a = 1; a <= n; a++)
+  {
+    for (b = n - 1; b >= a; b--)
+      if (*(g + b - 1) < (*(g + b)))
+      {
+        // ordre croissant des élements
+        t = *(g + b - 1);
+        *(g + b - 1) = *(g + b);
+        *(g + b) = t;
+
+        // ordre des indices des élements du vecteur g
+        r = *(index + b - 1);
+        *(index + b - 1) = *(index + b);
+        *(index + b) = r;
+      }
+  }
+}
+
+float FuzzyUtils::min(float *a, float *b)
+{
+  float min = 0;
+
+  if (*a >= (*b))
+    min = *b;
+  else
+    min = *a;
+
+  return min;
+}
+
+float FuzzyUtils::max(float* g, int n)
+{
+  float max = 0;
+
+  for (int i = 0; i < n; i++)
+  {
+    if (*(g + i) >= max)
+      max = *(g + i);
+  }
+
+  return max;
+}
+
+void FuzzyUtils::gDeDeux(float* a, float* b, float* lambda)
+{
+  float* c = (float*)malloc(1 * sizeof(float));
+  *c = *a + (*b) + (*lambda) * (*a) * (*b);
+}
+
+void FuzzyUtils::getLambda(float* g)
+{
+  float a, b;
+  float* lambda = (float*)malloc(1 * sizeof(float));
+
+  a = (*(g + 0) * (*(g + 1)) + (*(g + 1)) * (*(g + 2)) + (*(g + 0)) * (*(g + 2)));
+  *lambda = -(*(g + 0) * (*(g + 1)) + (*(g + 1)) * (*(g + 2)) + (*(g + 0)) * (*(g + 2))) / (*(g + 0) * (*(g + 1)) * (*(g + 2)));
+  b = (*(g + 0) * (*(g + 1)) * (*(g + 2)));
+
+  //printf("\na:%f",a);
+  //printf("\nb:%f",b);
+  //printf("\nlambda:%f", *lambda);
+
+  free(lambda);
+}
+
+void FuzzyUtils::AdaptativeSelectiveBackgroundModelUpdate(IplImage* CurrentImage, IplImage* BGImage, IplImage* OutputImage, IplImage* Integral, float seuil, float alpha)
+{
+  PixelUtils p;
+
+  float beta = 0.0;
+  float* CurentImagePixel = (float*)malloc(3 * sizeof(float));
+  float* BGImagePixel = (float*)malloc(3 * sizeof(float));
+  float* OutputImagePixel = (float*)malloc(3 * sizeof(float));
+  float* IntegralImagePixel = (float*)malloc(1 * sizeof(float));
+  float *Maximum = (float*)malloc(1 * sizeof(float));
+  float *Minimum = (float*)malloc(1 * sizeof(float));
+
+  p.ForegroundMaximum(Integral, Maximum, 1);
+  p.ForegroundMinimum(Integral, Minimum, 1);
+
+  for (int i = 0; i < CurrentImage->width; i++)
+  {
+    for (int j = 0; j < CurrentImage->height; j++)
+    {
+      p.GetPixel(CurrentImage, i, j, CurentImagePixel);
+      p.GetPixel(BGImage, i, j, BGImagePixel);
+      p.GetGrayPixel(Integral, i, j, IntegralImagePixel);
+
+      beta = 1 - ((*IntegralImagePixel) - ((*Minimum / (*Minimum - *Maximum)) * (*IntegralImagePixel) - (*Minimum * (*Maximum) / (*Minimum - *Maximum))));
+
+      for (int k = 0; k < 3; k++)
+        *(OutputImagePixel + k) = beta * (*(BGImagePixel + k)) + (1 - beta) * (alpha * (*(CurentImagePixel + k)) + (1 - alpha) * (*(BGImagePixel + k)));
+
+      p.PutPixel(OutputImage, i, j, OutputImagePixel);
+    }
+  }
+
+  free(CurentImagePixel);
+  free(BGImagePixel);
+  free(OutputImagePixel);
+  free(IntegralImagePixel);
+  free(Maximum);
+  free(Minimum);
+}
diff --git a/package_bgs/tb/FuzzyUtils.h b/package_bgs/T2F/FuzzyUtils.h
similarity index 86%
rename from package_bgs/tb/FuzzyUtils.h
rename to package_bgs/T2F/FuzzyUtils.h
index 43fc9ad4b0fdbefb084655c7469f5a913e617050..9a53a83f23d06742be9c5d33c7ff4fc5b776bce8 100644
--- a/package_bgs/tb/FuzzyUtils.h
+++ b/package_bgs/T2F/FuzzyUtils.h
@@ -15,19 +15,8 @@ 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
-/*
-Code provided by Thierry BOUWMANS
-
-Maitre de Conf�rences
-Laboratoire MIA
-Universit� de La Rochelle
-17000 La Rochelle
-France
-tbouwman@univ-lr.fr
 
-http://sites.google.com/site/thierrybouwmans/
-*/
-#include "PixelUtils.h"
+#include "../../package_analysis/PixelUtils.h"
 
 class FuzzyUtils
 {
@@ -44,7 +33,7 @@ public:
   void getFuzzyIntegralSugeno(IplImage* H, IplImage* Delta, int n, float *MeasureG, IplImage* OutputImage);
   void getFuzzyIntegralChoquet(IplImage* H, IplImage* Delta, int n, float *MeasureG, IplImage* OutputImage);
   void FuzzyMeasureG(float g1, float g2, float g3, float *G);
-  void Trier(float* g, int n, int* index);		
+  void Trier(float* g, int n, int* index);
   float min(float *a, float *b);
   float max(float *g, int n);
   void gDeDeux(float* a, float* b, float* lambda);
diff --git a/package_bgs/tb/MRF.cpp b/package_bgs/T2F/MRF.cpp
similarity index 58%
rename from package_bgs/tb/MRF.cpp
rename to package_bgs/T2F/MRF.cpp
index cfde8af470bdfdb588d9be501639738709be254a..291a84612f53b482317d1cc4eefae70c681d7de4 100644
--- a/package_bgs/tb/MRF.cpp
+++ b/package_bgs/T2F/MRF.cpp
@@ -58,68 +58,68 @@ MRF_TC::MRF_TC()
 
 MRF_TC::~MRF_TC()
 {
-  delete []classes;
-  delete []old_labeling;
-  delete []in_image_data;
-  delete []local_evidence;
+  delete[]classes;
+  delete[]old_labeling;
+  delete[]in_image_data;
+  delete[]local_evidence;
 }
 
 double MRF_TC::TimeEnergy2(int i, int j, int label)
 {
   double energy = 0.0;
-  
-  if(old_labeling[i][j] == (label*255))
+
+  if (old_labeling[i][j] == (label * 255))
     energy -= beta_time;
   else
     energy += beta_time;
 
-  if(i != height-1) // south
+  if (i != height - 1) // south
   {
-    if(label*255 == old_labeling[i+1][j])
+    if (label * 255 == old_labeling[i + 1][j])
       energy -= beta_time;
     else
       energy += beta_time;
 
-    if((j != width-1) && (label*255 == old_labeling[i+1][j+1]))
+    if ((j != width - 1) && (label * 255 == old_labeling[i + 1][j + 1]))
       energy -= beta_time;
     else
       energy += beta_time;
-    
-    if((j != 0) && (label*255 == old_labeling[i+1][j-1]))
+
+    if ((j != 0) && (label * 255 == old_labeling[i + 1][j - 1]))
       energy -= beta_time;
     else
       energy += beta_time;
   }
 
-  if(j != width-1) // east
+  if (j != width - 1) // east
   {
-    if(label*255 == old_labeling[i][j+1])
+    if (label * 255 == old_labeling[i][j + 1])
       energy -= beta_time;
     else
       energy += beta_time;
   }
 
-  if(i != 0) // nord
+  if (i != 0) // nord
   {
-    if(label*255 == old_labeling[i-1][j])
+    if (label * 255 == old_labeling[i - 1][j])
       energy -= beta_time;
     else
       energy += beta_time;
 
-    if((j != width-1) && (label*255 == old_labeling[i-1][j+1]))
+    if ((j != width - 1) && (label * 255 == old_labeling[i - 1][j + 1]))
       energy -= beta_time;
     else
       energy += beta_time;
-    
-    if((j != 0) && (label*255 == old_labeling[i-1][j-1]))
+
+    if ((j != 0) && (label * 255 == old_labeling[i - 1][j - 1]))
       energy -= beta_time;
     else
       energy += beta_time;
   }
 
-  if(j != 0) // west
+  if (j != 0) // west
   {
-    if(label*255 == old_labeling[i][j-1])
+    if (label * 255 == old_labeling[i][j - 1])
       energy -= beta_time;
     else
       energy += beta_time;
@@ -132,53 +132,53 @@ double MRF_TC::Doubleton2(int i, int j, int label)
 {
   double energy = 0.0;
 
-  if(i != height-1) // south
+  if (i != height - 1) // south
   {
-    if(label == classes[i+1][j])
+    if (label == classes[i + 1][j])
       energy -= beta;
     else
       energy += beta;
 
-    if((j != width-1) && (label == classes[i+1][j+1]))
+    if ((j != width - 1) && (label == classes[i + 1][j + 1]))
       energy -= beta;
     else
       energy += beta;
-    
-    if((j != 0) && (label == classes[i+1][j-1]))
+
+    if ((j != 0) && (label == classes[i + 1][j - 1]))
       energy -= beta;
     else
       energy += beta;
   }
 
-  if(j != width-1) // east
+  if (j != width - 1) // east
   {
-    if(label == classes[i][j+1])
+    if (label == classes[i][j + 1])
       energy -= beta;
     else
       energy += beta;
   }
 
-  if(i != 0) // nord
+  if (i != 0) // nord
   {
-    if(label == classes[i-1][j])
+    if (label == classes[i - 1][j])
       energy -= beta;
     else
       energy += beta;
 
-    if((j != width-1) && (label == classes[i-1][j+1]))
+    if ((j != width - 1) && (label == classes[i - 1][j + 1]))
       energy -= beta;
     else
       energy += beta;
 
-    if((j != 0) && (label == classes[i-1][j-1]))
+    if ((j != 0) && (label == classes[i - 1][j - 1]))
       energy -= beta;
     else
       energy += beta;
   }
 
-  if(j != 0) // west
+  if (j != 0) // west
   {
-    if(label == classes[i][j-1])
+    if (label == classes[i][j - 1])
       energy -= beta;
     else
       energy += beta;
@@ -196,17 +196,17 @@ void MRF_TC::OnIterationOver2(void)
 void MRF_TC::Build_Classes_OldLabeling_InImage_LocalEnergy()
 {
   int i;
-  classes = new int* [height];
+  classes = new int*[height];
   old_labeling = new int *[height];
-  in_image_data = new int* [height];
-  local_evidence = new float* [height];
+  in_image_data = new int*[height];
+  local_evidence = new float*[height];
 
-  for(i = 0; i < height; ++i)
+  for (i = 0; i < height; ++i)
   {
     classes[i] = new int[width];
     old_labeling[i] = new int[width];
     in_image_data[i] = new int[width];
-    local_evidence[i] = new float[width*2];
+    local_evidence[i] = new float[width * 2];
   }
 }
 
@@ -215,19 +215,19 @@ void MRF_TC::InitEvidence2(GMM *gmm, HMM *hmm, IplImage *labeling)
   int i, j;
 
   background = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3);
-  cvCopy(background2,background.Ptr());
+  cvCopy(background2, background.Ptr());
 
   unsigned char *in_data = (unsigned char *)(in_image->imageData);
   unsigned char *labeling_data = (unsigned char *)(labeling->imageData);
 
-  for(i = 0; i < height; ++i)
+  for (i = 0; i < height; ++i)
   {
-    for(j = 0; j < width; ++j)
+    for (j = 0; j < width; ++j)
     {
-      in_image_data[i][j] = in_data[(i*in_image->widthStep)+j];
-      old_labeling[i][j] = labeling_data[i*width+j];
-      
-      if(in_image_data[i][j] == 255)
+      in_image_data[i][j] = in_data[(i*in_image->widthStep) + j];
+      old_labeling[i][j] = labeling_data[i*width + j];
+
+      if (in_image_data[i][j] == 255)
         classes[i][j] = 1;
       else
         classes[i][j] = 0;
@@ -241,29 +241,29 @@ void MRF_TC::InitEvidence2(GMM *gmm, HMM *hmm, IplImage *labeling)
     float pixel;
 
     int modes = 3;
-    float mu;	
+    float mu;
 
-    for(i = 0; i < height; ++i)
+    for (i = 0; i < height; ++i)
     {
-      for(j = 0; j < width; ++j)
+      for (j = 0; j < width; ++j)
       {
-        variance = gmm[(i*width+j) * modes+0].variance;
-        muR = gmm[(i*width+j) * modes+0].muR;
-        muG = gmm[(i*width+j) * modes+0].muG;
-        muB = gmm[(i*width+j) * modes+0].muB;
+        variance = gmm[(i*width + j) * modes + 0].variance;
+        muR = gmm[(i*width + j) * modes + 0].muR;
+        muG = gmm[(i*width + j) * modes + 0].muG;
+        muB = gmm[(i*width + j) * modes + 0].muB;
 
-        mu = (muR + muG + muB)/3;
+        mu = (muR + muG + muB) / 3;
 
-        pixel = (background(i,j,0) + background(i,j,1) + background(i,j,2))/3;
+        pixel = (background(i, j, 0) + background(i, j, 1) + background(i, j, 2)) / 3;
 
-        if(variance == 0) variance = 1;
+        if (variance == 0) variance = 1;
 
-        local_evidence[i][j*2+0] = pow((pixel-mu),2)/2/variance;
+        local_evidence[i][j * 2 + 0] = pow((pixel - mu), 2) / 2 / variance;
 
-        if(pixel >= mu)
-          local_evidence[i][j*2+1] = pow((pixel - mu - 2.5*sqrt(variance)),2)/2/variance;
+        if (pixel >= mu)
+          local_evidence[i][j * 2 + 1] = pow((pixel - mu - 2.5*sqrt(variance)), 2) / 2 / variance;
         else
-          local_evidence[i][j*2+1] = pow((pixel - mu + 2.5*sqrt(variance)),2)/2/variance;
+          local_evidence[i][j * 2 + 1] = pow((pixel - mu + 2.5*sqrt(variance)), 2) / 2 / variance;
       }
     }
   }
@@ -274,12 +274,12 @@ void MRF_TC::CreateOutput2()
   int i, j;
   unsigned char *out_data;
 
-  out_data = (unsigned char *) out_image->imageData;
+  out_data = (unsigned char *)out_image->imageData;
 
   // create output image
   for (i = 0; i < height; ++i)
-    for(j = 0; j < width; ++j)
-      out_data[(i*width) + j] = (unsigned char)((classes[i][j])*255);
+    for (j = 0; j < width; ++j)
+      out_data[(i*width) + j] = (unsigned char)((classes[i][j]) * 255);
 }
 
 //calculate the whole energy
@@ -288,12 +288,12 @@ double MRF_TC::CalculateEnergy2()
   double sum = 0.0;
   int i, j, k;
   // !FAIL!
-  for(i = 0; i < height; ++i)
+  for (i = 0; i < height; ++i)
   {
-    for(j = 0; j < width; ++j)
+    for (j = 0; j < width; ++j)
     {
       k = classes[i][j];
-      sum = sum + local_evidence[i][j*2+k] + Doubleton2(i,j,k) + TimeEnergy2(i, j, k);//min the value
+      sum = sum + local_evidence[i][j * 2 + k] + Doubleton2(i, j, k) + TimeEnergy2(i, j, k);//min the value
     }
   }
   //sum = 0.1;
@@ -303,7 +303,7 @@ double MRF_TC::CalculateEnergy2()
 // local energy
 double MRF_TC::LocalEnergy2(int i, int j, int label)
 {
-  return local_evidence[i][j*2+label] + Doubleton2(i,j,label) + TimeEnergy2(i,j,label);
+  return local_evidence[i][j * 2 + label] + Doubleton2(i, j, label) + TimeEnergy2(i, j, label);
 }
 
 void MRF_TC::ICM2()
@@ -317,22 +317,22 @@ void MRF_TC::ICM2()
 
   do
   {
-    for(i = 0; i < height; ++i)
-      for(j = 0; j < width; ++j)
+    for (i = 0; i < height; ++i)
+      for (j = 0; j < width; ++j)
       {
-        localenergy0 = LocalEnergy2(i,j,0);
-        localenergy1 = LocalEnergy2(i,j,1);
-        
-        if(localenergy0 < localenergy1)
+        localenergy0 = LocalEnergy2(i, j, 0);
+        localenergy1 = LocalEnergy2(i, j, 1);
+
+        if (localenergy0 < localenergy1)
           classes[i][j] = 0;
         else
           classes[i][j] = 1;
       }
 
-      //E = CalculateEnergy2();
-      //summa_deltaE = fabs(E_old-E);
-      //E_old = E;
-      ++K;
-      OnIterationOver2();
-  }while(K < 2);
+    //E = CalculateEnergy2();
+    //summa_deltaE = fabs(E_old-E);
+    //E_old = E;
+    ++K;
+    OnIterationOver2();
+  } while (K < 2);
 }
diff --git a/package_bgs/tb/MRF.h b/package_bgs/T2F/MRF.h
similarity index 95%
rename from package_bgs/tb/MRF.h
rename to package_bgs/T2F/MRF.h
index c74589958988c2b9f38895650f651d8fdb57bbfe..1276a30da751e5ee936b19235b72338b1ea2bef8 100644
--- a/package_bgs/tb/MRF.h
+++ b/package_bgs/T2F/MRF.h
@@ -14,8 +14,7 @@ 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/>.
 */
-#ifndef MRF_H
-#define MRF_H
+#pragma once
 
 #include "T2FMRF.h"
 
@@ -53,7 +52,7 @@ namespace Algorithms
 
       //////////////////////////////////////////////////////////////////////////
       // alpha value for MMD
-      double alpha;		            
+      double alpha;
 
       //////////////////////////////////////////////////////////////////////////
       //current global energy
@@ -64,7 +63,7 @@ namespace Algorithms
       int K;
 
       //////////////////////////////////////////////////////////////////////////
-      //labeling image 
+      //labeling image
       int **classes;
       //input image
       int **in_image_data;
@@ -75,7 +74,7 @@ namespace Algorithms
     /************************************************************************/
     /* the Markov Random Field with time constraints for T2FGMM   */
     /************************************************************************/
-    class MRF_TC: public MRF
+    class MRF_TC : public MRF
     {
     private:
       double beta_time;
@@ -103,5 +102,3 @@ namespace Algorithms
     };
   }
 }
-
-#endif
diff --git a/package_bgs/tb/T2FGMM.cpp b/package_bgs/T2F/T2FGMM.cpp
similarity index 69%
rename from package_bgs/tb/T2FGMM.cpp
rename to package_bgs/T2F/T2FGMM.cpp
index a49407b7aa1005622c634b408132452dfdb8ed52..6ff99978d2804c3530e4950379ddf2506ed5e034 100644
--- a/package_bgs/tb/T2FGMM.cpp
+++ b/package_bgs/T2F/T2FGMM.cpp
@@ -17,8 +17,8 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 /****************************************************************************
 *
 * T2FGMM.cpp
-* 
-* Purpose: Implementation of the T2 Fuzzy Gaussian Mixture Models (T2GMMs) 
+*
+* Purpose: Implementation of the T2 Fuzzy Gaussian Mixture Models (T2GMMs)
 * "Modeling of Dynamic Backgrounds by Type-2 Fuzzy Gaussians Mixture Models"
 * Author: Fida El Baf, Thierry Bouwmans, September 2008.
 
@@ -33,9 +33,9 @@ int compareT2FGMM(const void* _gmm1, const void* _gmm2)
   GMM gmm1 = *(GMM*)_gmm1;
   GMM gmm2 = *(GMM*)_gmm2;
 
-  if(gmm1.significants < gmm2.significants)
+  if (gmm1.significants < gmm2.significants)
     return 1;
-  else if(gmm1.significants == gmm2.significants)
+  else if (gmm1.significants == gmm2.significants)
     return 0;
   else
     return -1;
@@ -53,10 +53,10 @@ T2FGMM::~T2FGMM()
 
 void T2FGMM::Initalize(const BgsParams& param)
 {
-  m_params = (T2FGMMParams&) param;
+  m_params = (T2FGMMParams&)param;
 
   // Tbf - the threshold
-  m_bg_threshold = 0.75f;	// 1-cf from the paper 
+  m_bg_threshold = 0.75f;	// 1-cf from the paper
 
   // Tgenerate - the threshold
   m_variance = 36.0f;		// sigma for the new mode
@@ -71,11 +71,11 @@ void T2FGMM::Initalize(const BgsParams& param)
 
   // Factor control for the T2FGMM-UM [0,3]
   //km = (float) 1.5;
-  km = (float) m_params.KM();
+  km = (float)m_params.KM();
 
   // Factor control for the T2FGMM-UV [0.3,1]
   //kv = (float) 0.6;
-  kv = (float) m_params.KV();
+  kv = (float)m_params.KV();
 }
 
 RgbImage* T2FGMM::Background()
@@ -87,7 +87,7 @@ void T2FGMM::InitModel(const RgbImage& data)
 {
   m_modes_per_pixel.Clear();
 
-  for(unsigned int i = 0; i < m_params.Size()*m_params.MaxModes(); ++i)
+  for (unsigned int i = 0; i < m_params.Size()*m_params.MaxModes(); ++i)
   {
     m_modes[i].weight = 0;
     m_modes[i].variance = 0;
@@ -98,13 +98,13 @@ void T2FGMM::InitModel(const RgbImage& data)
   }
 }
 
-void T2FGMM::Update(int frame_num, const RgbImage& data,  const BwImage& update_mask)
+void T2FGMM::Update(int frame_num, const RgbImage& data, const BwImage& update_mask)
 {
   // it doesn't make sense to have conditional updates in the GMM framework
 }
 
-void T2FGMM::SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned char& numModes, 
-                           unsigned char& low_threshold, unsigned char& high_threshold)
+void T2FGMM::SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned char& numModes,
+  unsigned char& low_threshold, unsigned char& high_threshold)
 {
   // calculate distances to the modes (+ sort???)
   // here we need to go in descending order!!!
@@ -119,19 +119,19 @@ void T2FGMM::SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned char&
   // calculate number of Gaussians to include in the background model
   int backgroundGaussians = 0;
   double sum = 0.0;
-  for(int i = 0; i < numModes; ++i)
+  for (int i = 0; i < numModes; ++i)
   {
-    if(sum < m_bg_threshold)
+    if (sum < m_bg_threshold)
     {
       backgroundGaussians++;
-      sum += m_modes[posPixel+i].weight;
+      sum += m_modes[posPixel + i].weight;
     }
     else
       break;
   }
 
   // update all distributions and check for match with current pixel
-  for(int iModes = 0; iModes < numModes; iModes++)
+  for (int iModes = 0; iModes < numModes; iModes++)
   {
     pos = posPixel + iModes;
     float weight = m_modes[pos].weight;
@@ -159,45 +159,45 @@ void T2FGMM::SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned char&
       float HB;
 
       // T2FGMM-UM
-      if(m_params.Type() == TYPE_T2FGMM_UM)
+      if (m_params.Type() == TYPE_T2FGMM_UM)
       {
-        if((pixel(0)<muR-km*var)|| (pixel(0)>muR+km*var))
-          HR=2*km*dR/var;
+        if ((pixel(0) < muR - km*var) || (pixel(0) > muR + km*var))
+          HR = 2 * km*dR / var;
         else
-          HR=dR*dR/(2*var*var)+km*dR/var+km*km/2;
+          HR = dR*dR / (2 * var*var) + km*dR / var + km*km / 2;
 
-        if((pixel(1)<muG-km*var)|| (pixel(1)>muG+km*var))
-          HG=2*km*dG/var;
+        if ((pixel(1) < muG - km*var) || (pixel(1) > muG + km*var))
+          HG = 2 * km*dG / var;
         else
-          HG=dG*dG/(2*var*var)+km*dG/var+km*km/2;
+          HG = dG*dG / (2 * var*var) + km*dG / var + km*km / 2;
 
-        if((pixel(2)<muB-km*var)|| (pixel(2)>muB+km*var))
-          HB=2*km*dB/var;
+        if ((pixel(2) < muB - km*var) || (pixel(2) > muB + km*var))
+          HB = 2 * km*dB / var;
         else
-          HB=dB*dB/(2*var*var)+km*dB/var+km*km/2;
+          HB = dB*dB / (2 * var*var) + km*dB / var + km*km / 2;
       }
 
       // T2FGMM-UV
-      if(m_params.Type() == TYPE_T2FGMM_UV)
+      if (m_params.Type() == TYPE_T2FGMM_UV)
       {
-        HR = (1/(kv*kv)-kv*kv) * (pixel(0)-muR) * (pixel(0)-muR)/(2*var);
-        HG = (1/(kv*kv)-kv*kv) * (pixel(1)-muG) * (pixel(1)-muG)/(2*var);
-        HB = (1/(kv*kv)-kv*kv) * (pixel(2)-muB) * (pixel(2)-muB)/(2*var);
+        HR = (1 / (kv*kv) - kv*kv) * (pixel(0) - muR) * (pixel(0) - muR) / (2 * var);
+        HG = (1 / (kv*kv) - kv*kv) * (pixel(1) - muG) * (pixel(1) - muG) / (2 * var);
+        HB = (1 / (kv*kv) - kv*kv) * (pixel(2) - muB) * (pixel(2) - muB) / (2 * var);
       }
-      
+
       // calculate the squared distance
       float dist = (HR*HR + HG*HG + HB*HB);
 
-      if(dist < m_params.HighThreshold()*var && iModes < backgroundGaussians)
+      if (dist < m_params.HighThreshold()*var && iModes < backgroundGaussians)
         bBackgroundHigh = true;
 
       // a match occurs when the pixel is within sqrt(fTg) standard deviations of the distribution
-      if(dist < m_params.LowThreshold()*var)
+      if (dist < m_params.LowThreshold()*var)
       {
         bFitsPDF = true;
 
         // check if this Gaussian is part of the background model
-        if(iModes < backgroundGaussians) 
+        if (iModes < backgroundGaussians)
           bBackgroundLow = true;
 
         //update distribution
@@ -209,16 +209,16 @@ void T2FGMM::SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned char&
         m_modes[pos].muB = muB - k*(dB);
 
         //limit the variance
-        float sigmanew = var + k*(dist-var);
-        m_modes[pos].variance = sigmanew < 4 ? 4 : sigmanew > 5*m_variance ? 5*m_variance : sigmanew;
+        float sigmanew = var + k*(dist - var);
+        m_modes[pos].variance = sigmanew < 4 ? 4 : sigmanew > 5 * m_variance ? 5 * m_variance : sigmanew;
         m_modes[pos].significants = m_modes[pos].weight / sqrt(m_modes[pos].variance);
       }
       else
       {
         weight = fOneMinAlpha*weight;
-        if(weight < 0.0)
+        if (weight < 0.0)
         {
-          weight=0.0;
+          weight = 0.0;
           numModes--;
         }
 
@@ -229,9 +229,9 @@ void T2FGMM::SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned char&
     else
     {
       weight = fOneMinAlpha*weight;
-      if(weight < 0.0)
+      if (weight < 0.0)
       {
-        weight=0.0;
+        weight = 0.0;
         numModes--;
       }
       m_modes[pos].weight = weight;
@@ -243,25 +243,25 @@ void T2FGMM::SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned char&
 
   // renormalize weights so they add to one
   double invTotalWeight = 1.0 / totalWeight;
-  for(int iLocal = 0; iLocal < numModes; iLocal++)
+  for (int iLocal = 0; iLocal < numModes; iLocal++)
   {
     m_modes[posPixel + iLocal].weight *= (float)invTotalWeight;
-    m_modes[posPixel + iLocal].significants = m_modes[posPixel + iLocal].weight 
+    m_modes[posPixel + iLocal].significants = m_modes[posPixel + iLocal].weight
       / sqrt(m_modes[posPixel + iLocal].variance);
   }
 
-  // Sort significance values so they are in desending order. 
-  qsort(&m_modes[posPixel],  numModes, sizeof(GMM), compareT2FGMM);
+  // Sort significance values so they are in desending order.
+  qsort(&m_modes[posPixel], numModes, sizeof(GMM), compareT2FGMM);
 
   // make new mode if needed and exit
-  if(!bFitsPDF)
+  if (!bFitsPDF)
   {
-    if(numModes < m_params.MaxModes())
+    if (numModes < m_params.MaxModes())
       numModes++;
     //else
-      // the weakest mode will be replaced
-    
-    pos = posPixel + numModes-1;
+    // the weakest mode will be replaced
+
+    pos = posPixel + numModes - 1;
 
     m_modes[pos].muR = pixel.ch[0];
     m_modes[pos].muG = pixel.ch[1];
@@ -277,26 +277,26 @@ void T2FGMM::SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned char&
     //renormalize weights
     int iLocal;
     float sum = 0.0;
-    for(iLocal = 0; iLocal < numModes; iLocal++)
-      sum += m_modes[posPixel+ iLocal].weight;
-    
-    double invSum = 1.0/sum;
-    for(iLocal = 0; iLocal < numModes; iLocal++)
+    for (iLocal = 0; iLocal < numModes; iLocal++)
+      sum += m_modes[posPixel + iLocal].weight;
+
+    double invSum = 1.0 / sum;
+    for (iLocal = 0; iLocal < numModes; iLocal++)
     {
       m_modes[posPixel + iLocal].weight *= (float)invSum;
       m_modes[posPixel + iLocal].significants = m_modes[posPixel + iLocal].weight / sqrt(m_modes[posPixel + iLocal].variance);
     }
   }
 
-  // Sort significance values so they are in desending order. 
+  // Sort significance values so they are in desending order.
   qsort(&(m_modes[posPixel]), numModes, sizeof(GMM), compareT2FGMM);
 
-  if(bBackgroundLow)
+  if (bBackgroundLow)
     low_threshold = BACKGROUND;
   else
     low_threshold = FOREGROUND;
-  
-  if(bBackgroundHigh)
+
+  if (bBackgroundHigh)
     high_threshold = BACKGROUND;
   else
     high_threshold = FOREGROUND;
@@ -316,21 +316,21 @@ void T2FGMM::Subtract(int frame_num, const RgbImage& data, BwImage& low_threshol
   long posPixel;
 
   // update each pixel of the image
-  for(unsigned int r = 0; r < m_params.Height(); ++r)
+  for (unsigned int r = 0; r < m_params.Height(); ++r)
   {
-    for(unsigned int c = 0; c < m_params.Width(); ++c)
-    {		
+    for (unsigned int c = 0; c < m_params.Width(); ++c)
+    {
       // update model + background subtract
       posPixel = (r*m_params.Width() + c) * m_params.MaxModes();
 
-      SubtractPixel(posPixel, data(r,c), m_modes_per_pixel(r,c), low_threshold, high_threshold);
+      SubtractPixel(posPixel, data(r, c), m_modes_per_pixel(r, c), low_threshold, high_threshold);
 
-      low_threshold_mask(r,c) = low_threshold;
-      high_threshold_mask(r,c) = high_threshold;
+      low_threshold_mask(r, c) = low_threshold;
+      high_threshold_mask(r, c) = high_threshold;
 
-      m_background(r,c,0) = (unsigned char) m_modes[posPixel].muR;
-      m_background(r,c,1) = (unsigned char) m_modes[posPixel].muG;
-      m_background(r,c,2) = (unsigned char) m_modes[posPixel].muB;
+      m_background(r, c, 0) = (unsigned char)m_modes[posPixel].muR;
+      m_background(r, c, 1) = (unsigned char)m_modes[posPixel].muG;
+      m_background(r, c, 2) = (unsigned char)m_modes[posPixel].muB;
     }
   }
 }
diff --git a/package_bgs/tb/T2FGMM.h b/package_bgs/T2F/T2FGMM.h
similarity index 92%
rename from package_bgs/tb/T2FGMM.h
rename to package_bgs/T2F/T2FGMM.h
index 7d966db3b313fb073e6765c6d0f8531350bdb4c8..203c3509275b72a85b90226d9ada0ce0791dcce5 100644
--- a/package_bgs/tb/T2FGMM.h
+++ b/package_bgs/T2F/T2FGMM.h
@@ -18,18 +18,16 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * T2FGMM.h
 *
-* Purpose: Implementation of the T2 Fuzzy Gaussian Mixture Models (T2GMMs) 
+* Purpose: Implementation of the T2 Fuzzy Gaussian Mixture Models (T2GMMs)
 * "Modeling of Dynamic Backgrounds by Type-2 Fuzzy Gaussians Mixture Models"
 * Author: Fida El Baf, Thierry Bouwmans, September 2008
 *
 * This code is based on code by Z. Zivkovic's written for his enhanced GMM
-* background subtraction algorithm: 
+* background subtraction algorithm:
 *
 * Zivkovic's code can be obtained at: www.zoranz.net
 ******************************************************************************/
-
-#ifndef T2F_GMM_
-#define T2F_GMM_
+#pragma once
 
 #include "../dp/Bgs.h"
 #include "../dp/GrimsonGMM.h"
@@ -55,9 +53,9 @@ namespace Algorithms
       float &KV() { return m_kv; }
 
     private:
-      // Threshold on the squared dist. to decide when a sample is close to an existing 
-      // components. If it is not close to any a new component will be generated. 
-      // Smaller threshold values lead to more generated components and higher threshold values 
+      // Threshold on the squared dist. to decide when a sample is close to an existing
+      // components. If it is not close to any a new component will be generated.
+      // Smaller threshold values lead to more generated components and higher threshold values
       // lead to a small number of components but they can grow too large.
       //
       // It is usual easiest to think of these thresholds as being the number of variances away
@@ -66,7 +64,7 @@ namespace Algorithms
       float m_high_threshold;
 
       // alpha - speed of update - if the time interval you want to average over is T
-      // set alpha=1/T. 
+      // set alpha=1/T.
       float m_alpha;
 
       // Maximum number of modes (Gaussian components) that will be used per pixel
@@ -92,12 +90,12 @@ namespace Algorithms
       void Initalize(const BgsParams& param);
 
       void InitModel(const RgbImage& data);
-      void Subtract(int frame_num, const RgbImage& data, BwImage& low_threshold_mask, BwImage& high_threshold_mask);	
+      void Subtract(int frame_num, const RgbImage& data, BwImage& low_threshold_mask, BwImage& high_threshold_mask);
       void Update(int frame_num, const RgbImage& data, const BwImage& update_mask);
 
       RgbImage* Background();
 
-    private:	
+    private:
       void SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned char& numModes, unsigned char& lowThreshold, unsigned char& highThreshold);
 
       // User adjustable parameters
@@ -109,8 +107,8 @@ namespace Algorithms
       // it is considered foreground
       float m_bg_threshold; //1-cf from the paper
 
-      // Initial variance for the newly generated components. 
-      // It will will influence the speed of adaptation. A good guess should be made. 
+      // Initial variance for the newly generated components.
+      // It will will influence the speed of adaptation. A good guess should be made.
       // A simple way is to estimate the typical standard deviation from the images.
       float m_variance;
 
@@ -131,5 +129,3 @@ namespace Algorithms
     };
   }
 }
-
-#endif
diff --git a/package_bgs/tb/T2FMRF.cpp b/package_bgs/T2F/T2FMRF.cpp
similarity index 70%
rename from package_bgs/tb/T2FMRF.cpp
rename to package_bgs/T2F/T2FMRF.cpp
index 372f564fe434ec0d9010e644cf8a8f2f65d32c87..e722d0240e7da9d898d37ce5b8f726201bcb95bd 100644
--- a/package_bgs/tb/T2FMRF.cpp
+++ b/package_bgs/T2F/T2FMRF.cpp
@@ -18,12 +18,12 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * T2FMRF.cpp
 *
-* Purpose: Implementation of the T2 Fuzzy Gaussian Mixture Models (T2GMMs) 
+* Purpose: Implementation of the T2 Fuzzy Gaussian Mixture Models (T2GMMs)
 * "Modeling of Dynamic Backgrounds by Type-2 Fuzzy Gaussians Mixture Models"
 * Author: Fida El Baf, Thierry Bouwmans, September 2008
 *
 * This code is based on code by Z. Zivkovic's written for his enhanced GMM
-* background subtraction algorithm: 
+* background subtraction algorithm:
 *
 * Zivkovic's code can be obtained at: www.zoranz.net
 ******************************************************************************/
@@ -37,9 +37,9 @@ int compareT2FMRF(const void* _gmm1, const void* _gmm2)
   GMM gmm1 = *(GMM*)_gmm1;
   GMM gmm2 = *(GMM*)_gmm2;
 
-  if(gmm1.significants < gmm2.significants)
+  if (gmm1.significants < gmm2.significants)
     return 1;
-  else if(gmm1.significants == gmm2.significants)
+  else if (gmm1.significants == gmm2.significants)
     return 0;
   else
     return -1;
@@ -66,10 +66,10 @@ T2FMRF::~T2FMRF()
 
 void T2FMRF::Initalize(const BgsParams& param)
 {
-  m_params = (T2FMRFParams&) param;
+  m_params = (T2FMRFParams&)param;
 
   // Tbf - the threshold
-  m_bg_threshold = 0.75f;	// 1-cf from the paper 
+  m_bg_threshold = 0.75f;	// 1-cf from the paper
 
   // Tgenerate - the threshold
   m_variance = 36.0f;		// sigma for the new mode
@@ -87,11 +87,11 @@ void T2FMRF::Initalize(const BgsParams& param)
 
   // Factor control for the T2FGMM-UM [0,3]
   // km = (float) 2; //1.5;
-  km = (float) m_params.KM();
+  km = (float)m_params.KM();
 
   // Factor control for the T2FGMM-UV [0.3,1]
   // kv = (float) 0.9; //0.6;
-  kv = (float) m_params.KV();
+  kv = (float)m_params.KV();
 }
 
 RgbImage* T2FMRF::Background()
@@ -103,7 +103,7 @@ void T2FMRF::InitModel(const RgbImage& data)
 {
   m_modes_per_pixel.Clear();
 
-  for(unsigned int i = 0; i < m_params.Size()*m_params.MaxModes(); ++i)
+  for (unsigned int i = 0; i < m_params.Size()*m_params.MaxModes(); ++i)
   {
     m_modes[i].weight = 0;
     m_modes[i].variance = 0;
@@ -124,13 +124,13 @@ void T2FMRF::InitModel(const RgbImage& data)
   }
 }
 
-void T2FMRF::Update(int frame_num, const RgbImage& data,  const BwImage& update_mask)
+void T2FMRF::Update(int frame_num, const RgbImage& data, const BwImage& update_mask)
 {
   // it doesn't make sense to have conditional updates in the GMM framework
 }
 
-void T2FMRF::SubtractPixel(long posPixel, long posGMode, const RgbPixel& pixel, unsigned char& numModes, 
-                           unsigned char& low_threshold, unsigned char& high_threshold)
+void T2FMRF::SubtractPixel(long posPixel, long posGMode, const RgbPixel& pixel, unsigned char& numModes,
+  unsigned char& low_threshold, unsigned char& high_threshold)
 {
   // calculate distances to the modes (+ sort???)
   // here we need to go in descending order!!!
@@ -144,7 +144,7 @@ void T2FMRF::SubtractPixel(long posPixel, long posGMode, const RgbPixel& pixel,
   float Ab2f = m_state[posPixel].Ab2f;
   float Af2b = m_state[posPixel].Af2b;
   float Af2f = m_state[posPixel].Af2f;
-  float T = m_state[posPixel].T;
+  //float T = m_state[posPixel].T;
 
   float fOneMinAlpha = 1 - m_params.Alpha();
   float totalWeight = 0.0f;
@@ -152,12 +152,12 @@ void T2FMRF::SubtractPixel(long posPixel, long posGMode, const RgbPixel& pixel,
   // calculate number of Gaussians to include in the background model
   int backgroundGaussians = 0;
   double sum = 0.0;
-  for(int i = 0; i < numModes; ++i)
+  for (int i = 0; i < numModes; ++i)
   {
-    if(sum < m_bg_threshold)
+    if (sum < m_bg_threshold)
     {
       backgroundGaussians++;
-      sum += m_modes[posGMode+i].weight;
+      sum += m_modes[posGMode + i].weight;
     }
     else
       break;
@@ -192,57 +192,57 @@ void T2FMRF::SubtractPixel(long posPixel, long posGMode, const RgbPixel& pixel,
       float HB;
 
       // T2FMRF-UM
-      if(m_params.Type() == TYPE_T2FMRF_UM)
+      if (m_params.Type() == TYPE_T2FMRF_UM)
       {
-        if((pixel(0) < muR-km*var) || (pixel(0) > muR+km*var))
-          HR = 2*km*dR/var;
+        if ((pixel(0) < muR - km*var) || (pixel(0) > muR + km*var))
+          HR = 2 * km*dR / var;
         else
-          HR = dR*dR/(2*var*var)+km*dR/var+km*km/2;
+          HR = dR*dR / (2 * var*var) + km*dR / var + km*km / 2;
 
-        if((pixel(1) < muG-km*var) || (pixel(1) > muG+km*var))
-          HG = 2*km*dG/var;
+        if ((pixel(1) < muG - km*var) || (pixel(1) > muG + km*var))
+          HG = 2 * km*dG / var;
         else
-          HG = dG*dG/(2*var*var)+km*dG/var+km*km/2;
+          HG = dG*dG / (2 * var*var) + km*dG / var + km*km / 2;
 
-        if((pixel(2) < muB-km*var) || (pixel(2) > muB+km*var))
-          HB = 2*km*dB/var;
+        if ((pixel(2) < muB - km*var) || (pixel(2) > muB + km*var))
+          HB = 2 * km*dB / var;
         else
-          HB = dB*dB/(2*var*var)+km*dB/var+km*km/2;
+          HB = dB*dB / (2 * var*var) + km*dB / var + km*km / 2;
       }
 
       // T2FGMM-UV
-      if(m_params.Type() == TYPE_T2FMRF_UV)
+      if (m_params.Type() == TYPE_T2FMRF_UV)
       {
-        HR = (1/(kv*kv)-kv*kv) * (pixel(0)-muR) * (pixel(0)-muR)/(2*var);
-        HG = (1/(kv*kv)-kv*kv) * (pixel(1)-muG) * (pixel(1)-muG)/(2*var);
-        HB = (1/(kv*kv)-kv*kv) * (pixel(2)-muB) * (pixel(2)-muB)/(2*var);
+        HR = (1 / (kv*kv) - kv*kv) * (pixel(0) - muR) * (pixel(0) - muR) / (2 * var);
+        HG = (1 / (kv*kv) - kv*kv) * (pixel(1) - muG) * (pixel(1) - muG) / (2 * var);
+        HB = (1 / (kv*kv) - kv*kv) * (pixel(2) - muB) * (pixel(2) - muB) / (2 * var);
       }
 
       float ro;
       if (CurrentState == background)
       {
-        if (Ab2b!=0) ro = (Ab2f/Ab2b);
+        if (Ab2b != 0) ro = (Ab2f / Ab2b);
         else ro = 10;
       }
       else
       {
-        if(Af2b!=0) ro = (Af2f/Af2b);
+        if (Af2b != 0) ro = (Af2f / Af2b);
         else ro = 10;
       }
-      
+
       // calculate the squared distance
       float dist = (HR*HR + HG*HG + HB*HB);
 
-      if(dist < m_params.HighThreshold()*var && iModes < backgroundGaussians)
+      if (dist < m_params.HighThreshold()*var && iModes < backgroundGaussians)
         bBackgroundHigh = true;
 
       // a match occurs when the pixel is within sqrt(fTg) standard deviations of the distribution
-      if(dist < m_params.LowThreshold()*var)
+      if (dist < m_params.LowThreshold()*var)
       {
         bFitsPDF = true;
 
         // check if this Gaussian is part of the background model
-        if(iModes < backgroundGaussians) 
+        if (iModes < backgroundGaussians)
           bBackgroundLow = true;
 
         //update distribution
@@ -254,8 +254,8 @@ void T2FMRF::SubtractPixel(long posPixel, long posGMode, const RgbPixel& pixel,
         m_modes[pos].muB = muB - k*(dB);
 
         //limit the variance
-        float sigmanew = var + k*(dist-var);
-        m_modes[pos].variance = sigmanew < 4 ? 4 : sigmanew > 5*m_variance ? 5*m_variance : sigmanew;
+        float sigmanew = var + k*(dist - var);
+        m_modes[pos].variance = sigmanew < 4 ? 4 : sigmanew > 5 * m_variance ? 5 * m_variance : sigmanew;
         m_modes[pos].significants = m_modes[pos].weight / sqrt(m_modes[pos].variance);
       }
       else
@@ -263,7 +263,7 @@ void T2FMRF::SubtractPixel(long posPixel, long posGMode, const RgbPixel& pixel,
         weight = fOneMinAlpha*weight;
         if (weight < 0.0)
         {
-          weight=0.0;
+          weight = 0.0;
           numModes--;
         }
 
@@ -276,7 +276,7 @@ void T2FMRF::SubtractPixel(long posPixel, long posGMode, const RgbPixel& pixel,
       weight = fOneMinAlpha*weight;
       if (weight < 0.0)
       {
-        weight=0.0;
+        weight = 0.0;
         numModes--;
       }
       m_modes[pos].weight = weight;
@@ -294,18 +294,18 @@ void T2FMRF::SubtractPixel(long posPixel, long posGMode, const RgbPixel& pixel,
     m_modes[posGMode + iLocal].significants = m_modes[posGMode + iLocal].weight / sqrt(m_modes[posGMode + iLocal].variance);
   }
 
-  // Sort significance values so they are in desending order. 
-  qsort(&m_modes[posGMode],  numModes, sizeof(GMM), compareT2FMRF);
+  // Sort significance values so they are in desending order.
+  qsort(&m_modes[posGMode], numModes, sizeof(GMM), compareT2FMRF);
 
   // make new mode if needed and exit
-  if(!bFitsPDF)
+  if (!bFitsPDF)
   {
-    if(numModes < m_params.MaxModes())
+    if (numModes < m_params.MaxModes())
       numModes++;
     //else
-      // the weakest mode will be replaced
-    
-    pos = posGMode + numModes-1;
+    // the weakest mode will be replaced
+
+    pos = posGMode + numModes - 1;
 
     m_modes[pos].muR = pixel.ch[0];
     m_modes[pos].muG = pixel.ch[1];
@@ -313,7 +313,7 @@ void T2FMRF::SubtractPixel(long posPixel, long posGMode, const RgbPixel& pixel,
     m_modes[pos].variance = m_variance;
     m_modes[pos].significants = 0;			// will be set below
 
-    if(numModes == 1)
+    if (numModes == 1)
       m_modes[pos].weight = 1;
     else
       m_modes[pos].weight = m_params.Alpha();
@@ -321,33 +321,33 @@ void T2FMRF::SubtractPixel(long posPixel, long posGMode, const RgbPixel& pixel,
     //renormalize weights
     int iLocal;
     float sum = 0.0;
-    for(iLocal = 0; iLocal < numModes; iLocal++)
-      sum += m_modes[posGMode+ iLocal].weight;
-    
-    double invSum = 1.0/sum;
-    for(iLocal = 0; iLocal < numModes; iLocal++)
+    for (iLocal = 0; iLocal < numModes; iLocal++)
+      sum += m_modes[posGMode + iLocal].weight;
+
+    double invSum = 1.0 / sum;
+    for (iLocal = 0; iLocal < numModes; iLocal++)
     {
       m_modes[posGMode + iLocal].weight *= (float)invSum;
       m_modes[posGMode + iLocal].significants = m_modes[posPixel + iLocal].weight / sqrt(m_modes[posGMode + iLocal].variance);
     }
   }
 
-  // Sort significance values so they are in desending order. 
+  // Sort significance values so they are in desending order.
   qsort(&(m_modes[posGMode]), numModes, sizeof(GMM), compareT2FMRF);
 
-  if(bBackgroundLow)
+  if (bBackgroundLow)
   {
     low_threshold = BACKGROUND;
     m_state[posPixel].State = background;
 
-    if(CurrentState == background)
+    if (CurrentState == background)
     {
       float b2b = fOneMinAlpha*Ab2b + m_params.Alpha();
       float b2f = fOneMinAlpha*Ab2f;
 
       float b = b2b + b2f;
-      m_state[posPixel].Ab2b = b2b/b;
-      m_state[posPixel].Ab2f = b2f/b;
+      m_state[posPixel].Ab2b = b2b / b;
+      m_state[posPixel].Ab2f = b2f / b;
       m_state[posPixel].T = m_state[posPixel].Ab2b;
     }
     else
@@ -356,8 +356,8 @@ void T2FMRF::SubtractPixel(long posPixel, long posGMode, const RgbPixel& pixel,
       float f2f = fOneMinAlpha*Af2f;
 
       float f = f2b + f2f;
-      m_state[posPixel].Af2b = f2b/f;
-      m_state[posPixel].Af2f = f2f/f;
+      m_state[posPixel].Af2b = f2b / f;
+      m_state[posPixel].Af2f = f2f / f;
       m_state[posPixel].T = m_state[posPixel].Af2b;
     }
   }
@@ -366,14 +366,14 @@ void T2FMRF::SubtractPixel(long posPixel, long posGMode, const RgbPixel& pixel,
     low_threshold = FOREGROUND;
     m_state[posPixel].State = foreground;
 
-    if(CurrentState == background)
+    if (CurrentState == background)
     {
       float b2b = fOneMinAlpha*Ab2b;
       float b2f = fOneMinAlpha*Ab2f + m_params.Alpha();
 
       float b = b2b + b2f;
-      m_state[posPixel].Ab2b = b2b/b;
-      m_state[posPixel].Ab2f = b2f/b;
+      m_state[posPixel].Ab2b = b2b / b;
+      m_state[posPixel].Ab2f = b2f / b;
       m_state[posPixel].T = m_state[posPixel].Ab2b;
     }
     else
@@ -382,13 +382,13 @@ void T2FMRF::SubtractPixel(long posPixel, long posGMode, const RgbPixel& pixel,
       float f2f = fOneMinAlpha*Af2f + m_params.Alpha();
 
       float f = f2b + f2f;
-      m_state[posPixel].Af2b = f2b/f;
-      m_state[posPixel].Af2f = f2f/f;
+      m_state[posPixel].Af2b = f2b / f;
+      m_state[posPixel].Af2f = f2f / f;
       m_state[posPixel].T = m_state[posPixel].Af2b;
     }
   }
 
-  if(bBackgroundHigh)
+  if (bBackgroundHigh)
     high_threshold = BACKGROUND;
   else
     high_threshold = FOREGROUND;
@@ -402,30 +402,30 @@ void T2FMRF::SubtractPixel(long posPixel, long posGMode, const RgbPixel& pixel,
 //					(the memory should already be reserved) 
 //					values: 255-foreground, 125-shadow, 0-background
 ///////////////////////////////////////////////////////////////////////////////
-void T2FMRF::Subtract(int frame_num, const RgbImage& data,  
-                      BwImage& low_threshold_mask, BwImage& high_threshold_mask)
+void T2FMRF::Subtract(int frame_num, const RgbImage& data,
+  BwImage& low_threshold_mask, BwImage& high_threshold_mask)
 {
   unsigned char low_threshold, high_threshold;
   long posPixel;
   long posGMode;
 
   // update each pixel of the image
-  for(unsigned int r = 0; r < m_params.Height(); ++r)
+  for (unsigned int r = 0; r < m_params.Height(); ++r)
   {
-    for(unsigned int c = 0; c < m_params.Width(); ++c)
-    {		
+    for (unsigned int c = 0; c < m_params.Width(); ++c)
+    {
       // update model + background subtract
       posPixel = r*m_params.Width() + c;
       posGMode = (r*m_params.Width() + c) * m_params.MaxModes();
 
-      SubtractPixel(posPixel, posGMode, data(r,c), m_modes_per_pixel(r,c), low_threshold, high_threshold);
+      SubtractPixel(posPixel, posGMode, data(r, c), m_modes_per_pixel(r, c), low_threshold, high_threshold);
 
-      low_threshold_mask(r,c) = low_threshold;
-      high_threshold_mask(r,c) = high_threshold;
+      low_threshold_mask(r, c) = low_threshold;
+      high_threshold_mask(r, c) = high_threshold;
 
-      m_background(r,c,0) = (unsigned char) m_modes[posGMode].muR;
-      m_background(r,c,1) = (unsigned char) m_modes[posGMode].muG;
-      m_background(r,c,2) = (unsigned char) m_modes[posGMode].muB;
+      m_background(r, c, 0) = (unsigned char)m_modes[posGMode].muR;
+      m_background(r, c, 1) = (unsigned char)m_modes[posGMode].muG;
+      m_background(r, c, 2) = (unsigned char)m_modes[posGMode].muB;
     }
   }
 }
diff --git a/package_bgs/tb/T2FMRF.h b/package_bgs/T2F/T2FMRF.h
similarity index 91%
rename from package_bgs/tb/T2FMRF.h
rename to package_bgs/T2F/T2FMRF.h
index 00e464c310bfbb2f6795f22451b27aa4fe5a92ab..1015426eabeb83055fe3d4969c0d8fab4fda0775 100644
--- a/package_bgs/tb/T2FMRF.h
+++ b/package_bgs/T2F/T2FMRF.h
@@ -18,18 +18,16 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * T2FMRF.h
 *
-* Purpose: Implementation of the T2 Fuzzy Gaussian Mixture Models (T2GMMs) 
+* Purpose: Implementation of the T2 Fuzzy Gaussian Mixture Models (T2GMMs)
 * "Modeling of Dynamic Backgrounds by Type-2 Fuzzy Gaussians Mixture Models"
 * Author: Fida El Baf, Thierry Bouwmans, September 2008
 *
 * This code is based on code by Z. Zivkovic's written for his enhanced GMM
-* background subtraction algorithm: 
+* background subtraction algorithm:
 *
 * Zivkovic's code can be obtained at: www.zoranz.net
 ******************************************************************************/
-
-#ifndef T2F_MRF_
-#define T2F_MRF_
+#pragma once
 
 #include "../dp/Bgs.h"
 #include "../dp/GrimsonGMM.h"
@@ -41,9 +39,9 @@ namespace Algorithms
     const int TYPE_T2FMRF_UM = 0;
     const int TYPE_T2FMRF_UV = 1;
 
-    enum HiddenState {background, foreground};
+    enum HiddenState { background, foreground };
 
-    typedef struct HMMState 
+    typedef struct HMMState
     {
       float T;
       //Hidden State
@@ -80,9 +78,9 @@ namespace Algorithms
       float &KV() { return m_kv; }
 
     private:
-      // Threshold on the squared dist. to decide when a sample is close to an existing 
-      // components. If it is not close to any a new component will be generated. 
-      // Smaller threshold values lead to more generated components and higher threshold values 
+      // Threshold on the squared dist. to decide when a sample is close to an existing
+      // components. If it is not close to any a new component will be generated.
+      // Smaller threshold values lead to more generated components and higher threshold values
       // lead to a small number of components but they can grow too large.
       //
       // It is usual easiest to think of these thresholds as being the number of variances away
@@ -91,7 +89,7 @@ namespace Algorithms
       float m_high_threshold;
 
       // alpha - speed of update - if the time interval you want to average over is T
-      // set alpha=1/T. 
+      // set alpha=1/T.
       float m_alpha;
 
       // Maximum number of modes (Gaussian components) that will be used per pixel
@@ -116,7 +114,7 @@ namespace Algorithms
 
       void Initalize(const BgsParams& param);
       void InitModel(const RgbImage& data);
-      void Subtract(int frame_num, const RgbImage& data, BwImage& low_threshold_mask, BwImage& high_threshold_mask);	
+      void Subtract(int frame_num, const RgbImage& data, BwImage& low_threshold_mask, BwImage& high_threshold_mask);
       void Update(int frame_num, const RgbImage& data, const BwImage& update_mask);
 
       RgbImage* Background();
@@ -124,7 +122,7 @@ namespace Algorithms
       GMM *gmm(void);
       HMM *hmm(void);
 
-    private:	
+    private:
       void SubtractPixel(long posPixel, long posGMode, const RgbPixel& pixel, unsigned char& numModes, unsigned char& lowThreshold, unsigned char& highThreshold);
 
       // User adjustable parameters
@@ -136,8 +134,8 @@ namespace Algorithms
       // it is considered foreground
       float m_bg_threshold; //1-cf from the paper
 
-      // Initial variance for the newly generated components. 
-      // It will will influence the speed of adaptation. A good guess should be made. 
+      // Initial variance for the newly generated components.
+      // It will will influence the speed of adaptation. A good guess should be made.
       // A simple way is to estimate the typical standard deviation from the images.
       float m_variance;
 
@@ -160,5 +158,3 @@ namespace Algorithms
     };
   }
 }
-
-#endif
diff --git a/package_bgs/tb/T2FGMM_UM.cpp b/package_bgs/T2FGMM_UM.cpp
similarity index 64%
rename from package_bgs/tb/T2FGMM_UM.cpp
rename to package_bgs/T2FGMM_UM.cpp
index 31a5338068580281d41a3d0af2c959a31d33b8a2..ad1b40e82ae8e504a7713a3f8d87afe8bc0897b8 100644
--- a/package_bgs/tb/T2FGMM_UM.cpp
+++ b/package_bgs/T2FGMM_UM.cpp
@@ -16,9 +16,13 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "T2FGMM_UM.h"
 
-T2FGMM_UM::T2FGMM_UM() : firstTime(true), frameNumber(0), threshold(9.0), alpha(0.01), km(1.5f), kv(0.6f), gaussians(3), showOutput(true) 
+using namespace bgslibrary::algorithms;
+
+T2FGMM_UM::T2FGMM_UM() :
+  frameNumber(0), threshold(9.0), alpha(0.01), km(1.5f), kv(0.6f), gaussians(3)
 {
   std::cout << "T2FGMM_UM()" << std::endl;
+  setup("./config/T2FGMM_UM.xml");
 }
 
 T2FGMM_UM::~T2FGMM_UM()
@@ -28,23 +32,16 @@ T2FGMM_UM::~T2FGMM_UM()
 
 void T2FGMM_UM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if(firstTime)
-    saveConfig();
-
+  init(img_input, img_output, img_bgmodel);
   frame = new IplImage(img_input);
-  
-  if(firstTime)
+
+  if (firstTime)
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if(firstTime)
+  if (firstTime)
   {
-    int width	= img_input.size().width;
+    int width = img_input.size().width;
     int height = img_input.size().height;
 
     lowThresholdMask = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
@@ -55,7 +52,7 @@ void T2FGMM_UM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
 
     params.SetFrameSize(width, height);
     params.LowThreshold() = threshold;
-    params.HighThreshold() = 2*params.LowThreshold();
+    params.HighThreshold() = 2 * params.LowThreshold();
     params.Alpha() = alpha;
     params.MaxModes() = gaussians;
     params.Type() = TYPE_T2FGMM_UM;
@@ -69,13 +66,18 @@ void T2FGMM_UM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
   bgs.Subtract(frameNumber, frame_data, lowThresholdMask, highThresholdMask);
   lowThresholdMask.Clear();
   bgs.Update(frameNumber, frame_data, lowThresholdMask);
-  
-  cv::Mat foreground(highThresholdMask.Ptr());
 
-  if(showOutput)
-    cv::imshow("T2FGMM-UM", foreground);
-  
-  foreground.copyTo(img_output);
+  img_foreground = cv::cvarrToMat(highThresholdMask.Ptr());
+  img_background = cv::cvarrToMat(bgs.Background()->Ptr());
+  //img_background = cv::Mat::zeros(img_input.size(), img_input.type());
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+    cv::imshow("T2FGMM-UM", img_foreground);
+#endif
+
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
 
   delete frame;
   firstTime = false;
@@ -84,7 +86,7 @@ void T2FGMM_UM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
 
 void T2FGMM_UM::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/T2FGMM_UM.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteReal(fs, "threshold", threshold);
   cvWriteReal(fs, "alpha", alpha);
@@ -98,14 +100,14 @@ void T2FGMM_UM::saveConfig()
 
 void T2FGMM_UM::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/T2FGMM_UM.xml", 0, CV_STORAGE_READ);
-  
-  threshold = cvReadRealByName(fs, 0, "threshold", 9.0);
-  alpha = cvReadRealByName(fs, 0, "alpha", 0.01);
-  km = cvReadRealByName(fs, 0, "km", 1.5);
-  kv = cvReadRealByName(fs, 0, "kv", 0.6);
-  gaussians = cvReadIntByName(fs, 0, "gaussians", 3);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  threshold = cvReadRealByName(fs, nullptr, "threshold", 9.0);
+  alpha = cvReadRealByName(fs, nullptr, "alpha", 0.01);
+  km = cvReadRealByName(fs, nullptr, "km", 1.5);
+  kv = cvReadRealByName(fs, nullptr, "kv", 0.6);
+  gaussians = cvReadIntByName(fs, nullptr, "gaussians", 3);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/tb/T2FGMM_UM.h b/package_bgs/T2FGMM_UM.h
similarity index 52%
rename from package_bgs/tb/T2FGMM_UM.h
rename to package_bgs/T2FGMM_UM.h
index ae6e29f89c52af779cd20a04afde16a5cd271e57..c58aeb756e40f43ba838901d5ff691df25338666 100644
--- a/package_bgs/tb/T2FGMM_UM.h
+++ b/package_bgs/T2FGMM_UM.h
@@ -16,43 +16,42 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-#include "T2FGMM.h"
+#include "IBGS.h"
+#include "T2F/T2FGMM.h"
 
 using namespace Algorithms::BackgroundSubtraction;
 
-class T2FGMM_UM : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  long frameNumber;
-  IplImage* frame;
-  RgbImage frame_data;
-
-  T2FGMMParams params;
-  T2FGMM bgs;
-  BwImage lowThresholdMask;
-  BwImage highThresholdMask;
-
-  double threshold;
-  double alpha;
-  float km;
-  float kv;
-  int gaussians;
-  bool showOutput;
-
-public:
-  T2FGMM_UM();
-  ~T2FGMM_UM();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
-
+  namespace algorithms
+  {
+    class T2FGMM_UM : public IBGS
+    {
+    private:
+      long frameNumber;
+      IplImage* frame;
+      RgbImage frame_data;
+
+      T2FGMMParams params;
+      T2FGMM bgs;
+      BwImage lowThresholdMask;
+      BwImage highThresholdMask;
+
+      double threshold;
+      double alpha;
+      float km;
+      float kv;
+      int gaussians;
+
+    public:
+      T2FGMM_UM();
+      ~T2FGMM_UM();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/tb/T2FGMM_UV.cpp b/package_bgs/T2FGMM_UV.cpp
similarity index 64%
rename from package_bgs/tb/T2FGMM_UV.cpp
rename to package_bgs/T2FGMM_UV.cpp
index c6f99f198f2dd498402ea1d9526bd635358541b9..4e9708f68ef88b82f5495e8185c310858d982fa1 100644
--- a/package_bgs/tb/T2FGMM_UV.cpp
+++ b/package_bgs/T2FGMM_UV.cpp
@@ -16,9 +16,13 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "T2FGMM_UV.h"
 
-T2FGMM_UV::T2FGMM_UV() : firstTime(true), frameNumber(0), threshold(9.0), alpha(0.01), km(1.5f), kv(0.6f), gaussians(3), showOutput(true) 
+using namespace bgslibrary::algorithms;
+
+T2FGMM_UV::T2FGMM_UV() :
+  frameNumber(0), threshold(9.0), alpha(0.01), km(1.5f), kv(0.6f), gaussians(3)
 {
   std::cout << "T2FGMM_UV()" << std::endl;
+  setup("./config/T2FGMM_UV.xml");
 }
 
 T2FGMM_UV::~T2FGMM_UV()
@@ -28,23 +32,16 @@ T2FGMM_UV::~T2FGMM_UV()
 
 void T2FGMM_UV::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if(firstTime)
-    saveConfig();
-
+  init(img_input, img_output, img_bgmodel);
   frame = new IplImage(img_input);
-  
-  if(firstTime)
+
+  if (firstTime)
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if(firstTime)
+  if (firstTime)
   {
-    int width	= img_input.size().width;
+    int width = img_input.size().width;
     int height = img_input.size().height;
 
     lowThresholdMask = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
@@ -55,7 +52,7 @@ void T2FGMM_UV::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
 
     params.SetFrameSize(width, height);
     params.LowThreshold() = threshold;
-    params.HighThreshold() = 2*params.LowThreshold();
+    params.HighThreshold() = 2 * params.LowThreshold();
     params.Alpha() = alpha;
     params.MaxModes() = gaussians;
     params.Type() = TYPE_T2FGMM_UV;
@@ -69,13 +66,18 @@ void T2FGMM_UV::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
   bgs.Subtract(frameNumber, frame_data, lowThresholdMask, highThresholdMask);
   lowThresholdMask.Clear();
   bgs.Update(frameNumber, frame_data, lowThresholdMask);
-  
-  cv::Mat foreground(highThresholdMask.Ptr());
 
-  if(showOutput)
-    cv::imshow("T2FGMM-UV", foreground);
-  
-  foreground.copyTo(img_output);
+  img_foreground = cv::cvarrToMat(highThresholdMask.Ptr());
+  img_background = cv::cvarrToMat(bgs.Background()->Ptr());
+  //img_background = cv::Mat::zeros(img_input.size(), img_input.type());
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+    cv::imshow("T2FGMM-UV", img_foreground);
+#endif
+
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
 
   delete frame;
   firstTime = false;
@@ -84,7 +86,7 @@ void T2FGMM_UV::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
 
 void T2FGMM_UV::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/T2FGMM_UV.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteReal(fs, "threshold", threshold);
   cvWriteReal(fs, "alpha", alpha);
@@ -98,14 +100,14 @@ void T2FGMM_UV::saveConfig()
 
 void T2FGMM_UV::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/T2FGMM_UV.xml", 0, CV_STORAGE_READ);
-  
-  threshold = cvReadRealByName(fs, 0, "threshold", 9.0);
-  alpha = cvReadRealByName(fs, 0, "alpha", 0.01);
-  km = cvReadRealByName(fs, 0, "km", 1.5);
-  kv = cvReadRealByName(fs, 0, "kv", 0.6);
-  gaussians = cvReadIntByName(fs, 0, "gaussians", 3);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  threshold = cvReadRealByName(fs, nullptr, "threshold", 9.0);
+  alpha = cvReadRealByName(fs, nullptr, "alpha", 0.01);
+  km = cvReadRealByName(fs, nullptr, "km", 1.5);
+  kv = cvReadRealByName(fs, nullptr, "kv", 0.6);
+  gaussians = cvReadIntByName(fs, nullptr, "gaussians", 3);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/tb/T2FGMM_UV.h b/package_bgs/T2FGMM_UV.h
similarity index 52%
rename from package_bgs/tb/T2FGMM_UV.h
rename to package_bgs/T2FGMM_UV.h
index 79edcc229900ca6cef612e82661ec2c78f68e60d..6102f3a21c99939d0b71316768378b01e7e983f9 100644
--- a/package_bgs/tb/T2FGMM_UV.h
+++ b/package_bgs/T2FGMM_UV.h
@@ -16,43 +16,42 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-#include "T2FGMM.h"
+#include "IBGS.h"
+#include "T2F/T2FGMM.h"
 
 using namespace Algorithms::BackgroundSubtraction;
 
-class T2FGMM_UV : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  long frameNumber;
-  IplImage* frame;
-  RgbImage frame_data;
-
-  T2FGMMParams params;
-  T2FGMM bgs;
-  BwImage lowThresholdMask;
-  BwImage highThresholdMask;
-
-  double threshold;
-  double alpha;
-  float km;
-  float kv;
-  int gaussians;
-  bool showOutput;
-
-public:
-  T2FGMM_UV();
-  ~T2FGMM_UV();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
-
+  namespace algorithms
+  {
+    class T2FGMM_UV : public IBGS
+    {
+    private:
+      long frameNumber;
+      IplImage* frame;
+      RgbImage frame_data;
+
+      T2FGMMParams params;
+      T2FGMM bgs;
+      BwImage lowThresholdMask;
+      BwImage highThresholdMask;
+
+      double threshold;
+      double alpha;
+      float km;
+      float kv;
+      int gaussians;
+
+    public:
+      T2FGMM_UV();
+      ~T2FGMM_UV();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/tb/T2FMRF_UM.cpp b/package_bgs/T2FMRF_UM.cpp
similarity index 59%
rename from package_bgs/tb/T2FMRF_UM.cpp
rename to package_bgs/T2FMRF_UM.cpp
index 5b41d8ae2c1acb72f43eb9bbedd6662577f22b3a..e0e6dae44dc315f70e0c5b93ca817438f656da17 100644
--- a/package_bgs/tb/T2FMRF_UM.cpp
+++ b/package_bgs/T2FMRF_UM.cpp
@@ -16,10 +16,13 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "T2FMRF_UM.h"
 
-T2FMRF_UM::T2FMRF_UM() : firstTime(true), frameNumber(0), threshold(9.0), alpha(0.01), 
-km(2.f), kv(0.9f), gaussians(3), showOutput(true) 
+using namespace bgslibrary::algorithms;
+
+T2FMRF_UM::T2FMRF_UM() :
+  frameNumber(0), threshold(9.0), alpha(0.01), km(2.f), kv(0.9f), gaussians(3)
 {
   std::cout << "T2FMRF_UM()" << std::endl;
+  setup("./config/DPMean.xml");
 }
 
 T2FMRF_UM::~T2FMRF_UM()
@@ -29,23 +32,16 @@ T2FMRF_UM::~T2FMRF_UM()
 
 void T2FMRF_UM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if(firstTime)
-    saveConfig();
-
+  init(img_input, img_output, img_bgmodel);
   frame = new IplImage(img_input);
-  
-  if(firstTime)
+
+  if (firstTime)
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if(firstTime)
+  if (firstTime)
   {
-    int width	= img_input.size().width;
+    int width = img_input.size().width;
     int height = img_input.size().height;
 
     lowThresholdMask = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
@@ -56,7 +52,7 @@ void T2FMRF_UM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
 
     params.SetFrameSize(width, height);
     params.LowThreshold() = threshold;
-    params.HighThreshold() = 2*params.LowThreshold();
+    params.HighThreshold() = 2 * params.LowThreshold();
     params.Alpha() = alpha;
     params.MaxModes() = gaussians;
     params.Type() = TYPE_T2FMRF_UM;
@@ -70,7 +66,7 @@ void T2FMRF_UM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
     old = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
 
     mrf.height = height;
-	  mrf.width = width;
+    mrf.width = width;
     mrf.Build_Classes_OldLabeling_InImage_LocalEnergy();
 
     firstTime = false;
@@ -80,32 +76,37 @@ void T2FMRF_UM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
   cvCopy(lowThresholdMask.Ptr(), old);
 
   /************************************************************************/
-	/* the code for MRF, it can be noted when using other methods   */
-	/************************************************************************/
-	//the optimization process is done when the foreground detection is stable, 
-	if(frameNumber >= 10)
-	{
-		gmm = bgs.gmm();
-		hmm = bgs.hmm();
-		mrf.background2 = frame_data.Ptr();
-		mrf.in_image = lowThresholdMask.Ptr();
-		mrf.out_image = lowThresholdMask.Ptr();
-		mrf.InitEvidence2(gmm,hmm,old_labeling);
-		mrf.ICM2();
-		cvCopy(mrf.out_image, lowThresholdMask.Ptr());
-	}
+  /* the code for MRF, it can be noted when using other methods   */
+  /************************************************************************/
+  //the optimization process is done when the foreground detection is stable,
+  if (frameNumber >= 10)
+  {
+    gmm = bgs.gmm();
+    hmm = bgs.hmm();
+    mrf.background2 = frame_data.Ptr();
+    mrf.in_image = lowThresholdMask.Ptr();
+    mrf.out_image = lowThresholdMask.Ptr();
+    mrf.InitEvidence2(gmm, hmm, old_labeling);
+    mrf.ICM2();
+    cvCopy(mrf.out_image, lowThresholdMask.Ptr());
+  }
 
   cvCopy(old, old_labeling);
 
   lowThresholdMask.Clear();
   bgs.Update(frameNumber, frame_data, lowThresholdMask);
-  
-  cv::Mat foreground(highThresholdMask.Ptr());
 
-  if(showOutput)
-    cv::imshow("T2FMRF-UM", foreground);
-  
-  foreground.copyTo(img_output);
+  img_foreground = cv::cvarrToMat(highThresholdMask.Ptr());
+  img_background = cv::cvarrToMat(bgs.Background()->Ptr());
+  //img_background = cv::Mat::zeros(img_input.size(), img_input.type());
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+    cv::imshow("T2FMRF-UM", img_foreground);
+#endif
+
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
 
   delete frame;
   frameNumber++;
@@ -113,7 +114,7 @@ void T2FMRF_UM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
 
 void T2FMRF_UM::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/T2FMRF_UM.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteReal(fs, "threshold", threshold);
   cvWriteReal(fs, "alpha", alpha);
@@ -127,14 +128,14 @@ void T2FMRF_UM::saveConfig()
 
 void T2FMRF_UM::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/T2FMRF_UM.xml", 0, CV_STORAGE_READ);
-  
-  threshold = cvReadRealByName(fs, 0, "threshold", 9.0);
-  alpha = cvReadRealByName(fs, 0, "alpha", 0.01);
-  km = cvReadRealByName(fs, 0, "km", 2);
-  kv = cvReadRealByName(fs, 0, "kv", 0.9);
-  gaussians = cvReadIntByName(fs, 0, "gaussians", 3);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  threshold = cvReadRealByName(fs, nullptr, "threshold", 9.0);
+  alpha = cvReadRealByName(fs, nullptr, "alpha", 0.01);
+  km = cvReadRealByName(fs, nullptr, "km", 2);
+  kv = cvReadRealByName(fs, nullptr, "kv", 0.9);
+  gaussians = cvReadIntByName(fs, nullptr, "gaussians", 3);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/T2FMRF_UM.h b/package_bgs/T2FMRF_UM.h
new file mode 100644
index 0000000000000000000000000000000000000000..01f6014c44dfb33526f0c9e97646d52ccad8cb48
--- /dev/null
+++ b/package_bgs/T2FMRF_UM.h
@@ -0,0 +1,64 @@
+/*
+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
+
+#include "IBGS.h"
+#include "T2F/MRF.h"
+
+using namespace Algorithms::BackgroundSubtraction;
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class T2FMRF_UM : public IBGS
+    {
+    private:
+      long frameNumber;
+      IplImage *frame;
+      RgbImage frame_data;
+
+      IplImage *old_labeling;
+      IplImage *old;
+
+      T2FMRFParams params;
+      T2FMRF bgs;
+      BwImage lowThresholdMask;
+      BwImage highThresholdMask;
+
+      double threshold;
+      double alpha;
+      float km;
+      float kv;
+      int gaussians;
+
+      MRF_TC mrf;
+      GMM *gmm;
+      HMM *hmm;
+
+    public:
+      T2FMRF_UM();
+      ~T2FMRF_UM();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/tb/T2FMRF_UV.cpp b/package_bgs/T2FMRF_UV.cpp
similarity index 59%
rename from package_bgs/tb/T2FMRF_UV.cpp
rename to package_bgs/T2FMRF_UV.cpp
index 03f259557a9b2a514e74926839a3a5cdfb93a780..7f43c027541c7953b9aa91c2031ff0b256b8e729 100644
--- a/package_bgs/tb/T2FMRF_UV.cpp
+++ b/package_bgs/T2FMRF_UV.cpp
@@ -16,10 +16,13 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "T2FMRF_UV.h"
 
-T2FMRF_UV::T2FMRF_UV() : firstTime(true), frameNumber(0), threshold(9.0), alpha(0.01), 
-km(2.f), kv(0.9f), gaussians(3), showOutput(true) 
+using namespace bgslibrary::algorithms;
+
+T2FMRF_UV::T2FMRF_UV() :
+  frameNumber(0), threshold(9.0), alpha(0.01), km(2.f), kv(0.9f), gaussians(3)
 {
   std::cout << "T2FMRF_UV()" << std::endl;
+  setup("./config/T2FMRF_UV.xml");
 }
 
 T2FMRF_UV::~T2FMRF_UV()
@@ -29,23 +32,16 @@ T2FMRF_UV::~T2FMRF_UV()
 
 void T2FMRF_UV::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if(firstTime)
-    saveConfig();
-
+  init(img_input, img_output, img_bgmodel);
   frame = new IplImage(img_input);
-  
-  if(firstTime)
+
+  if (firstTime)
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if(firstTime)
+  if (firstTime)
   {
-    int width	= img_input.size().width;
+    int width = img_input.size().width;
     int height = img_input.size().height;
 
     lowThresholdMask = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
@@ -56,7 +52,7 @@ void T2FMRF_UV::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
 
     params.SetFrameSize(width, height);
     params.LowThreshold() = threshold;
-    params.HighThreshold() = 2*params.LowThreshold();
+    params.HighThreshold() = 2 * params.LowThreshold();
     params.Alpha() = alpha;
     params.MaxModes() = gaussians;
     params.Type() = TYPE_T2FMRF_UV;
@@ -70,7 +66,7 @@ void T2FMRF_UV::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
     old = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
 
     mrf.height = height;
-	  mrf.width = width;
+    mrf.width = width;
     mrf.Build_Classes_OldLabeling_InImage_LocalEnergy();
 
     firstTime = false;
@@ -80,32 +76,37 @@ void T2FMRF_UV::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
   cvCopy(lowThresholdMask.Ptr(), old);
 
   /************************************************************************/
-	/* the code for MRF, it can be noted when using other methods   */
-	/************************************************************************/
-	//the optimization process is done when the foreground detection is stable, 
-	if(frameNumber >= 10)
-	{
-		gmm = bgs.gmm();
-		hmm = bgs.hmm();
-		mrf.background2 = frame_data.Ptr();
-		mrf.in_image = lowThresholdMask.Ptr();
-		mrf.out_image = lowThresholdMask.Ptr();
-		mrf.InitEvidence2(gmm,hmm,old_labeling);
-		mrf.ICM2();
-		cvCopy(mrf.out_image, lowThresholdMask.Ptr());
-	}
+  /* the code for MRF, it can be noted when using other methods   */
+  /************************************************************************/
+  //the optimization process is done when the foreground detection is stable,
+  if (frameNumber >= 10)
+  {
+    gmm = bgs.gmm();
+    hmm = bgs.hmm();
+    mrf.background2 = frame_data.Ptr();
+    mrf.in_image = lowThresholdMask.Ptr();
+    mrf.out_image = lowThresholdMask.Ptr();
+    mrf.InitEvidence2(gmm, hmm, old_labeling);
+    mrf.ICM2();
+    cvCopy(mrf.out_image, lowThresholdMask.Ptr());
+  }
 
   cvCopy(old, old_labeling);
 
   lowThresholdMask.Clear();
   bgs.Update(frameNumber, frame_data, lowThresholdMask);
-  
-  cv::Mat foreground(highThresholdMask.Ptr());
 
-  if(showOutput)
-    cv::imshow("T2FMRF-UV", foreground);
-  
-  foreground.copyTo(img_output);
+  img_foreground = cv::cvarrToMat(highThresholdMask.Ptr());
+  img_background = cv::cvarrToMat(bgs.Background()->Ptr());
+  //img_background = cv::Mat::zeros(img_input.size(), img_input.type());
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+    cv::imshow("T2FMRF-UV", img_foreground);
+#endif
+
+  img_foreground.copyTo(img_output);
+  img_background.copyTo(img_bgmodel);
 
   delete frame;
   frameNumber++;
@@ -113,7 +114,7 @@ void T2FMRF_UV::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
 
 void T2FMRF_UV::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/T2FMRF_UV.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteReal(fs, "threshold", threshold);
   cvWriteReal(fs, "alpha", alpha);
@@ -127,14 +128,14 @@ void T2FMRF_UV::saveConfig()
 
 void T2FMRF_UV::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/T2FMRF_UV.xml", 0, CV_STORAGE_READ);
-  
-  threshold = cvReadRealByName(fs, 0, "threshold", 9.0);
-  alpha = cvReadRealByName(fs, 0, "alpha", 0.01);
-  km = cvReadRealByName(fs, 0, "km", 2);
-  kv = cvReadRealByName(fs, 0, "kv", 0.9);
-  gaussians = cvReadIntByName(fs, 0, "gaussians", 3);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  threshold = cvReadRealByName(fs, nullptr, "threshold", 9.0);
+  alpha = cvReadRealByName(fs, nullptr, "alpha", 0.01);
+  km = cvReadRealByName(fs, nullptr, "km", 2);
+  kv = cvReadRealByName(fs, nullptr, "kv", 0.9);
+  gaussians = cvReadIntByName(fs, nullptr, "gaussians", 3);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/T2FMRF_UV.h b/package_bgs/T2FMRF_UV.h
new file mode 100644
index 0000000000000000000000000000000000000000..1c6917185365563acdc11d0aec41556ddd0ab429
--- /dev/null
+++ b/package_bgs/T2FMRF_UV.h
@@ -0,0 +1,64 @@
+/*
+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
+
+#include "IBGS.h"
+#include "T2F/MRF.h"
+
+using namespace Algorithms::BackgroundSubtraction;
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class T2FMRF_UV : public IBGS
+    {
+    private:
+      long frameNumber;
+      IplImage *frame;
+      RgbImage frame_data;
+
+      IplImage *old_labeling;
+      IplImage *old;
+
+      T2FMRFParams params;
+      T2FMRF bgs;
+      BwImage lowThresholdMask;
+      BwImage highThresholdMask;
+
+      double threshold;
+      double alpha;
+      float km;
+      float kv;
+      int gaussians;
+
+      MRF_TC mrf;
+      GMM *gmm;
+      HMM *hmm;
+
+    public:
+      T2FMRF_UV();
+      ~T2FMRF_UV();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/TwoPoints.cpp b/package_bgs/TwoPoints.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..aee46848fd6b87082b0d42bb2bd4849aca319b9b
--- /dev/null
+++ b/package_bgs/TwoPoints.cpp
@@ -0,0 +1,112 @@
+/*
+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 "TwoPoints.h"
+
+using namespace bgslibrary::algorithms;
+
+TwoPoints::TwoPoints() :
+  matchingThreshold(DEFAULT_MATCH_THRESH),
+  updateFactor(DEFAULT_UPDATE_FACTOR), model(nullptr)
+{
+  std::cout << "TwoPoints()" << std::endl;
+  //model = static_cast<twopointsModel_t*>(libtwopointsModel_New());
+  model = libtwopointsModel_New();
+  setup("./config/TwoPoints.xml");
+}
+
+TwoPoints::~TwoPoints()
+{
+  std::cout << "~TwoPoints()" << std::endl;
+  libtwopointsModel_Free(model);
+}
+
+void TwoPoints::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+{
+  init(img_input, img_output, img_bgmodel);
+
+  if (img_input.empty())
+    return;
+
+  cv::Mat updatingMask;
+  cv::Mat img_input_grayscale;
+
+  // Convert input image to a grayscale image
+  cvtColor(img_input, img_input_grayscale, CV_BGR2GRAY);
+
+  if (firstTime)
+  {
+    // Create a buffer for the output image.
+    //img_output = Mat(img_input.rows, img_input.cols, CV_8UC1);
+
+    // Initialization of the ViBe model.
+    libtwopointsModel_AllocInit_8u_C1R(model, img_input_grayscale.data, img_input.cols, img_input.rows);
+
+    // Sets default model values.
+    // libvibeModel_Sequential_SetMatchingThreshold(model, matchingThreshold);
+    // libvibeModel_Sequential_SetUpdateFactor(model, updateFactor);
+  }
+
+  libtwopointsModel_Segmentation_8u_C1R(model, img_input_grayscale.data, img_output.data);
+
+  updatingMask = cv::Mat(img_input.rows, img_input.cols, CV_8UC1);
+  // Work on the output and define the updating mask
+  for (int i = 0; i < img_input.cols * img_input.rows; i++)
+  {
+    if (img_output.data[i] == 0) // Foreground pixel
+    {
+      updatingMask.data[i] = 0;
+      img_output.data[i] = 255;
+    }
+    else // Background
+    {
+      updatingMask.data[i] = 255;
+      img_output.data[i] = 0;
+    }
+  }
+
+  libtwopointsModel_Update_8u_C1R(model, img_input_grayscale.data, updatingMask.data);
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+    imshow("Two points", img_output);
+#endif
+
+  firstTime = false;
+}
+
+void TwoPoints::saveConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
+
+  cvWriteInt(fs, "matchingThreshold", matchingThreshold);
+  cvWriteInt(fs, "updateFactor", updateFactor);
+  cvWriteInt(fs, "showOutput", showOutput);
+
+  cvReleaseFileStorage(&fs);
+}
+
+void TwoPoints::loadConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  matchingThreshold = cvReadRealByName(fs, nullptr, "matchingThreshold", DEFAULT_MATCH_THRESH);
+  updateFactor = cvReadRealByName(fs, nullptr, "updateFactor", DEFAULT_UPDATE_FACTOR);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", false);
+
+  cvReleaseFileStorage(&fs);
+}
diff --git a/package_bgs/TwoPoints.h b/package_bgs/TwoPoints.h
new file mode 100644
index 0000000000000000000000000000000000000000..b42c2311a09c07d7ef3c4146f7c2cccc65769742
--- /dev/null
+++ b/package_bgs/TwoPoints.h
@@ -0,0 +1,46 @@
+/*
+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
+
+#include "IBGS.h"
+#include "TwoPoints/two_points.h"
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class TwoPoints : public IBGS
+    {
+    private:
+      static const int DEFAULT_MATCH_THRESH = 20;
+      static const int DEFAULT_UPDATE_FACTOR = 16;
+      int matchingThreshold;
+      int updateFactor;
+      twopointsModel_t* model;
+
+    public:
+      TwoPoints();
+      ~TwoPoints();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/TwoPoints/two_points.cpp b/package_bgs/TwoPoints/two_points.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d8ee86b49c7c21c82c8b47b018caff354a389d13
--- /dev/null
+++ b/package_bgs/TwoPoints/two_points.cpp
@@ -0,0 +1,394 @@
+/*
+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 <assert.h>
+
+#include "two_points.h"
+
+static unsigned int abs_uint(const int i)
+{
+  return (i >= 0) ? i : -i;
+}
+
+struct twopointsModel
+{
+  /* Parameters. */
+  uint32_t width;
+  uint32_t height;
+  uint32_t numberOfSamples;
+  uint32_t matchingThreshold;
+  uint32_t matchingNumber;
+  uint32_t updateFactor;
+
+  /* Storage for the history. */
+  uint8_t *historyImage1;
+  uint8_t *historyImage2;
+
+  /* Buffers with random values. */
+  uint32_t *jump;
+  int *neighbor;
+};
+
+// -----------------------------------------------------------------------------
+// Creates the data structure
+// -----------------------------------------------------------------------------
+twopointsModel_t *libtwopointsModel_New()
+{
+  /* Model structure alloc. */
+  twopointsModel_t *model = NULL;
+  model = (twopointsModel_t*)calloc(1, sizeof(*model));
+  assert(model != NULL);
+
+  /* Default parameters values. */
+  model->matchingThreshold = 20;
+  model->updateFactor = 16;
+
+  /* Storage for the history. */
+  model->historyImage1 = NULL;
+  model->historyImage2 = NULL;
+
+  /* Buffers with random values. */
+  model->jump = NULL;
+  model->neighbor = NULL;
+
+  return(model);
+}
+
+// ----------------------------------------------------------------------------
+// Frees the structure
+// ----------------------------------------------------------------------------
+int32_t libtwopointsModel_Free(twopointsModel_t *model)
+{
+  if (model == NULL)
+    return(-1);
+
+  if (model->historyImage1 != NULL) {
+    free(model->historyImage1);
+    model->historyImage1 = NULL;
+  }
+  if (model->historyImage2 != NULL) {
+    free(model->historyImage2);
+    model->historyImage2 = NULL;
+  }
+  if (model->jump != NULL) {
+    free(model->jump);
+    model->jump = NULL;
+  }
+  if (model->neighbor != NULL) {
+    free(model->neighbor);
+    model->neighbor = NULL;
+  }
+  free(model);
+
+  return(0);
+}
+
+// -----------------------------------------------------------------------------
+// Allocates and initializes a C1R model structure
+// -----------------------------------------------------------------------------
+int32_t libtwopointsModel_AllocInit_8u_C1R(
+  twopointsModel_t *model,
+  const uint8_t *image_data,
+  const uint32_t width,
+  const uint32_t height
+)
+{
+  // Some basic checks. */
+  assert((image_data != NULL) && (model != NULL));
+  assert((width > 0) && (height > 0));
+
+  /* Finish model alloc - parameters values cannot be changed anymore. */
+  model->width = width;
+  model->height = height;
+
+  /* Creates the historyImage structure. */
+  model->historyImage1 = NULL;
+  model->historyImage1 = (uint8_t*)malloc(width * height * sizeof(uint8_t));
+  model->historyImage2 = NULL;
+  model->historyImage2 = (uint8_t*)malloc(width * height * sizeof(uint8_t));
+
+  assert(model->historyImage1 != NULL);
+  assert(model->historyImage2 != NULL);
+
+  for (int index = width * height - 1; index >= 0; --index) {
+    uint8_t value = image_data[index];
+
+    int value_plus_noise = value - 10;
+    if (value_plus_noise < 0) { value_plus_noise = 0; }
+    if (value_plus_noise > 255) { value_plus_noise = 255; }
+    model->historyImage1[index] = value_plus_noise;
+
+    value_plus_noise = value + 10;
+    if (value_plus_noise < 0) { value_plus_noise = 0; }
+    if (value_plus_noise > 255) { value_plus_noise = 255; }
+    model->historyImage2[index] = value_plus_noise;
+
+    // Swaps the two values if needed
+    if (model->historyImage1[index] > model->historyImage2[index]) {
+      uint8_t val = model->historyImage1[index];
+      model->historyImage1[index] = model->historyImage2[index];
+      model->historyImage2[index] = val;
+    }
+  }
+
+  /* Fills the buffers with random values. */
+  int size = (width > height) ? 2 * width + 1 : 2 * height + 1;
+
+  model->jump = (uint32_t*)malloc(size * sizeof(*(model->jump)));
+  assert(model->jump != NULL);
+
+  model->neighbor = (int*)malloc(size * sizeof(*(model->neighbor)));
+  assert(model->neighbor != NULL);
+
+
+  for (int i = 0; i < size; ++i) {
+    model->jump[i] = (rand() % (2 * model->updateFactor)) + 1;            // Values between 1 and 2 * updateFactor.
+    model->neighbor[i] = ((rand() % 3) - 1) + ((rand() % 3) - 1) * width; // Values between { -width - 1, ... , width + 1 }.
+  }
+
+  return(0);
+}
+
+// -----------------------------------------------------------------------------
+// Segmentation of a C1R model
+// -----------------------------------------------------------------------------
+int32_t libtwopointsModel_Segmentation_8u_C1R(
+  twopointsModel_t *model,
+  const uint8_t *image_data,
+  uint8_t *segmentation_map
+)
+{
+  assert((image_data != NULL) && (model != NULL) && (segmentation_map != NULL));
+  assert((model->width > 0) && (model->height > 0));
+  assert((model->jump != NULL) && (model->neighbor != NULL));
+
+  /* Some variables. */
+  uint32_t width = model->width;
+  uint32_t height = model->height;
+  uint32_t matchingThreshold = model->matchingThreshold;
+
+  uint8_t *historyImage1 = model->historyImage1;
+  uint8_t *historyImage2 = model->historyImage2;
+
+  /* Segmentation. */
+  memset(segmentation_map, 0, width * height);
+
+  uint8_t *first = historyImage1;
+  for (int index = width * height - 1; index >= 0; --index) {
+    // We adapt the threshold
+    matchingThreshold = model->matchingThreshold;
+    if (matchingThreshold < abs_uint(historyImage2[index] - historyImage1[index])) {
+      matchingThreshold = abs_uint(historyImage2[index] - historyImage1[index]);
+    }
+    if (abs_uint(image_data[index] - first[index]) <= matchingThreshold)
+      segmentation_map[index]++;
+  }
+
+  first = historyImage2;
+  for (int index = width * height - 1; index >= 0; --index) {
+    // We adapt the threshold
+    matchingThreshold = model->matchingThreshold;
+    if (matchingThreshold < abs_uint(historyImage2[index] - historyImage1[index])) {
+      matchingThreshold = abs_uint(historyImage2[index] - historyImage1[index]);
+    }
+    if (abs_uint(image_data[index] - first[index]) <= matchingThreshold)
+      segmentation_map[index]++;
+  }
+
+  return(0);
+}
+
+// ----------------------------------------------------------------------------
+// Update a C1R model
+// ----------------------------------------------------------------------------
+int doUpdate(const uint8_t value)
+{
+  if (value == 0) return 0;
+  else return 1;
+}
+
+
+int32_t libtwopointsModel_Update_8u_C1R(
+  twopointsModel_t *model,
+  const uint8_t *image_data,
+  uint8_t *updating_mask
+)
+{
+  assert((image_data != NULL) && (model != NULL) && (updating_mask != NULL));
+  assert((model->width > 0) && (model->height > 0));
+  assert((model->jump != NULL) && (model->neighbor != NULL));
+
+  // Some variables.
+  uint32_t width = model->width;
+  uint32_t height = model->height;
+
+  uint8_t *historyImage1 = model->historyImage1;
+  uint8_t *historyImage2 = model->historyImage2;
+
+  // Updating.
+  uint32_t *jump = model->jump;
+  int *neighbor = model->neighbor;
+
+  // All the frame, except the border.
+  uint32_t shift, indX, indY;
+  unsigned int x, y;
+
+  for (y = 1; y < height - 1; ++y) {
+    shift = rand() % width;
+    indX = jump[shift]; // index_jump should never be zero (> 1).
+
+    while (indX < width - 1) {
+      int index = indX + y * width;
+
+      if (doUpdate(updating_mask[index])) {
+        uint8_t value = image_data[index];
+        // In-place substitution.
+        // if (2*value < (historyImage1[index]+historyImage2[index]) ) {
+        if (rand() % 2 == 0) {
+          historyImage1[index] = value;
+        }
+        else {
+          historyImage2[index] = value;
+        }
+
+        // Propagation
+        int index_neighbor = index + neighbor[shift];
+        if (2 * value < (historyImage1[index_neighbor] + historyImage2[index_neighbor])) {
+          // if (rand()%2 == 0 ) {
+          historyImage1[index_neighbor] = value;
+        }
+        else {
+          historyImage2[index_neighbor] = value;
+        }
+      }
+
+      ++shift;
+      indX += jump[shift];
+    }
+  }
+
+  // First row.
+  y = 0;
+  shift = rand() % width;
+  indX = jump[shift]; // index_jump should never be zero (> 1).
+
+  while (indX <= width - 1) {
+    int index = indX + y * width;
+
+    if (doUpdate(updating_mask[index])) {
+      uint8_t value = image_data[index];
+      // In-place substitution.
+      // if (2*value < (historyImage1[index]+historyImage2[index]) ) {
+      if (rand() % 2 == 0) {
+        historyImage1[index] = value;
+      }
+      else {
+        historyImage2[index] = value;
+      }
+    }
+
+    ++shift;
+    indX += jump[shift];
+  }
+
+  // Last row.
+  y = height - 1;
+  shift = rand() % width;
+  indX = jump[shift]; // index_jump should never be zero (> 1).
+
+  while (indX <= width - 1) {
+    int index = indX + y * width;
+
+    if (doUpdate(updating_mask[index])) {
+      uint8_t value = image_data[index];
+      // In-place substitution.
+      // if (2*value < (historyImage1[index]+historyImage2[index]) ) {
+      if (rand() % 2 == 0) {
+        historyImage1[index] = value;
+      }
+      else {
+        historyImage2[index] = value;
+      }
+    }
+
+    ++shift;
+    indX += jump[shift];
+  }
+
+  // First column.
+  x = 0;
+  shift = rand() % height;
+  indY = jump[shift]; // index_jump should never be zero (> 1).
+
+  while (indY <= height - 1) {
+    int index = x + indY * width;
+
+    if (doUpdate(updating_mask[index])) {
+      uint8_t value = image_data[index];
+      // In-place substitution.
+      // if (2*value < (historyImage1[index]+historyImage2[index]) ) {
+      if (rand() % 2 == 0) {
+        historyImage1[index] = value;
+      }
+      else {
+        historyImage2[index] = value;
+      }
+    }
+
+    ++shift;
+    indY += jump[shift];
+  }
+
+  // Last column.
+  x = width - 1;
+  shift = rand() % height;
+  indY = jump[shift]; // index_jump should never be zero (> 1).
+
+  while (indY <= height - 1) {
+    int index = x + indY * width;
+
+    if (doUpdate(updating_mask[index])) {
+      uint8_t value = image_data[index];
+      // In-place substitution.
+      // if (2*value < (historyImage1[index]+historyImage2[index]) ) {
+      if (rand() % 2 == 0) {
+        historyImage1[index] = value;
+      }
+      else {
+        historyImage2[index] = value;
+      }
+    }
+
+    ++shift;
+    indY += jump[shift];
+  }
+
+  // The first pixel!
+  if (rand() % model->updateFactor == 0) {
+    if (doUpdate(updating_mask[0])) {
+      uint8_t value = image_data[0];
+      // In-place substitution.
+      if (rand() % 2 == 0) {
+        historyImage1[0] = value;
+      }
+      else {
+        historyImage2[0] = value;
+      }
+    }
+  }
+
+  return(0);
+}
diff --git a/package_bgs/TwoPoints/two_points.h b/package_bgs/TwoPoints/two_points.h
new file mode 100644
index 0000000000000000000000000000000000000000..a64152a2b6ca84857775ffd68c64461ab1fbe940
--- /dev/null
+++ b/package_bgs/TwoPoints/two_points.h
@@ -0,0 +1,50 @@
+/*
+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
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#define COLOR_BACKGROUND   0 /*!< Default label for background pixels */
+#define COLOR_FOREGROUND 255 /*!< Default label for foreground pixels. Note that some authors chose any value different from 0 instead */
+
+typedef struct twopointsModel twopointsModel_t;
+
+twopointsModel_t *libtwopointsModel_New();
+
+int32_t libtwopointsModel_Free(twopointsModel_t *model);
+
+int32_t libtwopointsModel_AllocInit_8u_C1R(
+  twopointsModel_t *model,
+  const uint8_t *image_data,
+  const uint32_t width,
+  const uint32_t height
+);
+
+int32_t libtwopointsModel_Segmentation_8u_C1R(
+  twopointsModel_t *model,
+  const uint8_t *image_data,
+  uint8_t *segmentation_map
+);
+
+int32_t libtwopointsModel_Update_8u_C1R(
+  twopointsModel_t *model,
+  const uint8_t *image_data,
+  uint8_t *updating_mask
+);
diff --git a/package_bgs/ViBe.cpp b/package_bgs/ViBe.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0d3125f0759d14cc00a608350f97e8883e8a8c22
--- /dev/null
+++ b/package_bgs/ViBe.cpp
@@ -0,0 +1,98 @@
+/*
+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 "ViBe.h"
+
+using namespace bgslibrary::algorithms;
+
+ViBe::ViBe() :
+  //numberOfSamples(DEFAULT_NUM_SAMPLES),
+  matchingThreshold(DEFAULT_MATCH_THRESH),
+  matchingNumber(DEFAULT_MATCH_NUM),
+  updateFactor(DEFAULT_UPDATE_FACTOR),
+  model(nullptr)
+{
+  std::cout << "ViBe()" << std::endl;
+  model = libvibeModel_Sequential_New();
+  setup("./config/ViBe.xml");
+}
+
+ViBe::~ViBe()
+{
+  std::cout << "~ViBe()" << std::endl;
+  libvibeModel_Sequential_Free(model);
+}
+
+void ViBe::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+{
+  init(img_input, img_output, img_bgmodel);
+
+  if (img_input.empty())
+    return;
+
+  if (firstTime)
+  {
+    /* Create a buffer for the output image. */
+    //img_output = cv::Mat(img_input.rows, img_input.cols, CV_8UC1);
+
+    /* Initialization of the ViBe model. */
+    libvibeModel_Sequential_AllocInit_8u_C3R(model, img_input.data, img_input.cols, img_input.rows);
+
+    /* Sets default model values. */
+    //libvibeModel_Sequential_SetNumberOfSamples(model, numberOfSamples);
+    libvibeModel_Sequential_SetMatchingThreshold(model, matchingThreshold);
+    libvibeModel_Sequential_SetMatchingNumber(model, matchingNumber);
+    libvibeModel_Sequential_SetUpdateFactor(model, updateFactor);
+  }
+
+  libvibeModel_Sequential_Segmentation_8u_C3R(model, img_input.data, img_output.data);
+  //libvibeModel_Sequential_Update_8u_C3R(model, model_img_input.data, img_output.data);
+  libvibeModel_Sequential_Update_8u_C3R(model, img_input.data, img_output.data);
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+    imshow("ViBe", img_output);
+#endif
+
+  firstTime = false;
+}
+
+void ViBe::saveConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
+
+  //cvWriteInt(fs, "numberOfSamples", numberOfSamples);
+  cvWriteInt(fs, "matchingThreshold", matchingThreshold);
+  cvWriteInt(fs, "matchingNumber", matchingNumber);
+  cvWriteInt(fs, "updateFactor", updateFactor);
+  cvWriteInt(fs, "showOutput", showOutput);
+
+  cvReleaseFileStorage(&fs);
+}
+
+void ViBe::loadConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  //numberOfSamples = cvReadIntByName(fs, nullptr, "numberOfSamples", DEFAULT_NUM_SAMPLES);
+  matchingThreshold = cvReadRealByName(fs, nullptr, "matchingThreshold", DEFAULT_MATCH_THRESH);
+  matchingNumber = cvReadRealByName(fs, nullptr, "matchingNumber", DEFAULT_MATCH_NUM);
+  updateFactor = cvReadRealByName(fs, nullptr, "updateFactor", DEFAULT_UPDATE_FACTOR);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", false);
+
+  cvReleaseFileStorage(&fs);
+}
diff --git a/package_bgs/ViBe.h b/package_bgs/ViBe.h
new file mode 100644
index 0000000000000000000000000000000000000000..c8014cbc15b99175947ed1115f3bd8b4144249d4
--- /dev/null
+++ b/package_bgs/ViBe.h
@@ -0,0 +1,52 @@
+/*
+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
+
+#include "IBGS.h"
+#include "ViBe/vibe-background-sequential.h"
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class ViBe : public IBGS
+    {
+    private:
+      static const int DEFAULT_NUM_SAMPLES = 20;
+      static const int DEFAULT_MATCH_THRESH = 20;
+      static const int DEFAULT_MATCH_NUM = 2;
+      static const int DEFAULT_UPDATE_FACTOR = 16;
+
+    private:
+      //int numberOfSamples;
+      int matchingThreshold;
+      int matchingNumber;
+      int updateFactor;
+      vibeModel_Sequential_t* model;
+
+    public:
+      ViBe();
+      ~ViBe();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/ViBe/LICENSE b/package_bgs/ViBe/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..7f22a77a7a03a5c0dfe893128692c47b79a59d15
--- /dev/null
+++ b/package_bgs/ViBe/LICENSE
@@ -0,0 +1,44 @@
+  Authors:
+  --------
+  Olivier Barnich and
+  Marc Van Droogenbroeck <m.vandroogenbroeck@ulg.ac.be>
+  
+  Licence:
+  --------
+  ViBe is covered by a patent (see http://www.ulg.ac.be/telecom/research/vibe).
+  We do not provide the source code but provide an object file and an interface.
+
+  Permission to use ViBe without payment of fee is granted 
+  for nonprofit educational and research purposes only.
+
+  This work may not be copied or reproduced in whole or in part for any 
+  purpose. 
+
+  Copying, reproduction, or republishing for any purpose shall require 
+  a license. Please contact the author in such cases.
+  All the code is provided without any guarantee.
+
+
+ How to refer to us:
+ -------------------
+
+ If you want to refer to this work, please cite the following publications:
+
+ Barnich and M. Van Droogenbroeck. ViBe: A universal background subtraction algorithm for video sequences. In IEEE Transactions on Image Processing, 20(6):1709-1724, June 2011. 
+
+@article{Barnich2011ViBe,
+  title = {{ViBe}: A universal background subtraction algorithm for video sequences},
+  author = {O. Barnich and M. {Van Droogenbroeck}},
+  journal = {IEEE Transactions on Image Processing},
+  volume = {20},
+  number = {6},
+  pages = {1709-1724},
+  month = {June},
+  year = {2011},
+  keywords = {ViBe, Background, Background subtraction, Segmentation, Motion, Motion detection},
+  pdf = {http://orbi.ulg.ac.be/bitstream/2268/81248/1/Barnich2011ViBe.pdf},
+  doi = {10.1109/TIP.2010.2101613},
+  url = {http://hdl.handle.net/2268/81248} 
+}
+
+
diff --git a/package_bgs/ViBe/vibe-background-sequential.cpp b/package_bgs/ViBe/vibe-background-sequential.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c4b91781d4662220f54eec84a6d74b1669d94ce7
--- /dev/null
+++ b/package_bgs/ViBe/vibe-background-sequential.cpp
@@ -0,0 +1,929 @@
+/*
+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/>.
+*/
+/**
+@file vibe-background-sequential.c
+@brief Implementation of vibe-background-sequential.h
+@author Marc Van Droogenbroeck
+@date May 2014
+*/
+#include <assert.h>
+#include <time.h>
+
+#include "vibe-background-sequential.h"
+
+#define NUMBER_OF_HISTORY_IMAGES 2
+
+uint32_t distance_Han2014Improved(uint8_t pixel, uint8_t bg)
+{
+  uint8_t min, max;
+
+  // Computes R = 0.13 min{ max[bg,26], 230}
+  max = 26;
+  if (bg > max) { max = bg; }
+
+  min = 230;
+  if (min > max) { min = max; }
+
+  return (uint32_t)(0.13*min);
+}
+
+static int abs_uint(const int i)
+{
+  return (i >= 0) ? i : -i;
+}
+
+static int32_t distance_is_close_8u_C3R(uint8_t r1, uint8_t g1, uint8_t b1, uint8_t r2, uint8_t g2, uint8_t b2, uint32_t threshold)
+{
+  return (abs_uint(r1 - r2) + abs_uint(g1 - g2) + abs_uint(b1 - b2) <= 4.5 * threshold);
+}
+
+struct vibeModel_Sequential
+{
+  /* Parameters. */
+  uint32_t width;
+  uint32_t height;
+  uint32_t numberOfSamples;
+  uint32_t matchingThreshold;
+  uint32_t matchingNumber;
+  uint32_t updateFactor;
+
+  /* Storage for the history. */
+  uint8_t *historyImage;
+  uint8_t *historyBuffer;
+  uint32_t lastHistoryImageSwapped;
+
+  /* Buffers with random values. */
+  uint32_t *jump;
+  int *neighbor;
+  uint32_t *position;
+};
+
+// -----------------------------------------------------------------------------
+// Print parameters
+// -----------------------------------------------------------------------------
+uint32_t libvibeModel_Sequential_PrintParameters(const vibeModel_Sequential_t *model)
+{
+  printf(
+    "Using ViBe background subtraction algorithm\n"
+    "  - Number of samples per pixel:       %03d\n"
+    "  - Number of matches needed:          %03d\n"
+    "  - Matching threshold:                %03d\n"
+    "  - Model update subsampling factor:   %03d\n",
+    libvibeModel_Sequential_GetNumberOfSamples(model),
+    libvibeModel_Sequential_GetMatchingNumber(model),
+    libvibeModel_Sequential_GetMatchingThreshold(model),
+    libvibeModel_Sequential_GetUpdateFactor(model)
+  );
+
+  return(0);
+}
+
+// -----------------------------------------------------------------------------
+// Creates the data structure
+// -----------------------------------------------------------------------------
+vibeModel_Sequential_t *libvibeModel_Sequential_New()
+{
+  /* Model structure alloc. */
+  vibeModel_Sequential_t *model = NULL;
+  model = (vibeModel_Sequential_t*)calloc(1, sizeof(*model));
+  assert(model != NULL);
+
+  /* Default parameters values. */
+  model->numberOfSamples = 20;
+  model->matchingThreshold = 20;
+  model->matchingNumber = 2;
+  model->updateFactor = 16;
+
+  /* Storage for the history. */
+  model->historyImage = NULL;
+  model->historyBuffer = NULL;
+  model->lastHistoryImageSwapped = 0;
+
+  /* Buffers with random values. */
+  model->jump = NULL;
+  model->neighbor = NULL;
+  model->position = NULL;
+
+  return(model);
+}
+
+// -----------------------------------------------------------------------------
+// Some "Get-ers"
+// -----------------------------------------------------------------------------
+uint32_t libvibeModel_Sequential_GetNumberOfSamples(const vibeModel_Sequential_t *model)
+{
+  assert(model != NULL); return(model->numberOfSamples);
+}
+
+uint32_t libvibeModel_Sequential_GetMatchingNumber(const vibeModel_Sequential_t *model)
+{
+  assert(model != NULL); return(model->matchingNumber);
+}
+
+uint32_t libvibeModel_Sequential_GetMatchingThreshold(const vibeModel_Sequential_t *model)
+{
+  assert(model != NULL); return(model->matchingThreshold);
+}
+
+uint32_t libvibeModel_Sequential_GetUpdateFactor(const vibeModel_Sequential_t *model)
+{
+  assert(model != NULL); return(model->updateFactor);
+}
+
+// -----------------------------------------------------------------------------
+// Some "Set-ers"
+// -----------------------------------------------------------------------------
+int32_t libvibeModel_Sequential_SetMatchingThreshold(
+  vibeModel_Sequential_t *model,
+  const uint32_t matchingThreshold
+) {
+  assert(model != NULL);
+  assert(matchingThreshold > 0);
+
+  model->matchingThreshold = matchingThreshold;
+
+  return(0);
+}
+
+// -----------------------------------------------------------------------------
+int32_t libvibeModel_Sequential_SetMatchingNumber(
+  vibeModel_Sequential_t *model,
+  const uint32_t matchingNumber
+) {
+  assert(model != NULL);
+  assert(matchingNumber > 0);
+
+  model->matchingNumber = matchingNumber;
+
+  return(0);
+}
+
+// -----------------------------------------------------------------------------
+int32_t libvibeModel_Sequential_SetUpdateFactor(
+  vibeModel_Sequential_t *model,
+  const uint32_t updateFactor
+) {
+  assert(model != NULL);
+  assert(updateFactor > 0);
+
+  model->updateFactor = updateFactor;
+
+  /* We also need to change the values of the jump buffer ! */
+  assert(model->jump != NULL);
+
+  /* Shifts. */
+  int size = (model->width > model->height) ? 2 * model->width + 1 : 2 * model->height + 1;
+
+  for (int i = 0; i < size; ++i)
+    model->jump[i] = (updateFactor == 1) ? 1 : (rand() % (2 * model->updateFactor)) + 1; // 1 or values between 1 and 2 * updateFactor.
+
+  return(0);
+}
+
+// ----------------------------------------------------------------------------
+// Frees the structure
+// ----------------------------------------------------------------------------
+int32_t libvibeModel_Sequential_Free(vibeModel_Sequential_t *model)
+{
+  if (model == NULL)
+    return(-1);
+
+  if (model->historyBuffer == NULL) {
+    free(model);
+    return(0);
+  }
+
+  free(model->historyImage);
+  free(model->historyBuffer);
+  free(model->jump);
+  free(model->neighbor);
+  free(model->position);
+  free(model);
+
+  return(0);
+}
+
+// -----------------------------------------------------------------------------
+// Allocates and initializes a C1R model structure
+// -----------------------------------------------------------------------------
+int32_t libvibeModel_Sequential_AllocInit_8u_C1R(
+  vibeModel_Sequential_t *model,
+  const uint8_t *image_data,
+  const uint32_t width,
+  const uint32_t height
+) {
+  // Some basic checks. */
+  assert((image_data != NULL) && (model != NULL));
+  assert((width > 0) && (height > 0));
+
+  /* Finish model alloc - parameters values cannot be changed anymore. */
+  model->width = width;
+  model->height = height;
+
+  /* Creates the historyImage structure. */
+  model->historyImage = NULL;
+  model->historyImage = (uint8_t*)malloc(NUMBER_OF_HISTORY_IMAGES * width * height * sizeof(*(model->historyImage)));
+
+  assert(model->historyImage != NULL);
+
+  for (int i = 0; i < NUMBER_OF_HISTORY_IMAGES; ++i) {
+    for (int index = width * height - 1; index >= 0; --index)
+      model->historyImage[i * width * height + index] = image_data[index];
+  }
+
+  /* Now creates and fills the history buffer. */
+  model->historyBuffer = (uint8_t*)malloc(width * height * (model->numberOfSamples - NUMBER_OF_HISTORY_IMAGES) * sizeof(uint8_t));
+  assert(model->historyBuffer != NULL);
+
+  for (int index = width * height - 1; index >= 0; --index) {
+    uint8_t value = image_data[index];
+
+    for (int x = 0; x < model->numberOfSamples - NUMBER_OF_HISTORY_IMAGES; ++x) {
+      int value_plus_noise = value + rand() % 20 - 10;
+
+      if (value_plus_noise < 0) { value_plus_noise = 0; }
+      if (value_plus_noise > 255) { value_plus_noise = 255; }
+
+      model->historyBuffer[index * (model->numberOfSamples - NUMBER_OF_HISTORY_IMAGES) + x] = value_plus_noise;
+    }
+  }
+
+  /* Fills the buffers with random values. */
+  int size = (width > height) ? 2 * width + 1 : 2 * height + 1;
+
+  model->jump = (uint32_t*)malloc(size * sizeof(*(model->jump)));
+  assert(model->jump != NULL);
+
+  model->neighbor = (int*)malloc(size * sizeof(*(model->neighbor)));
+  assert(model->neighbor != NULL);
+
+  model->position = (uint32_t*)malloc(size * sizeof(*(model->position)));
+  assert(model->position != NULL);
+
+  for (int i = 0; i < size; ++i) {
+    model->jump[i] = (rand() % (2 * model->updateFactor)) + 1;            // Values between 1 and 2 * updateFactor.
+    model->neighbor[i] = ((rand() % 3) - 1) + ((rand() % 3) - 1) * width; // Values between { -width - 1, ... , width + 1 }.
+    model->position[i] = rand() % (model->numberOfSamples);               // Values between 0 and numberOfSamples - 1.
+  }
+
+  return(0);
+}
+
+// -----------------------------------------------------------------------------
+// Segmentation of a C1R model
+// -----------------------------------------------------------------------------
+int32_t libvibeModel_Sequential_Segmentation_8u_C1R(
+  vibeModel_Sequential_t *model,
+  const uint8_t *image_data,
+  uint8_t *segmentation_map
+) {
+  /* Basic checks. */
+  assert((image_data != NULL) && (model != NULL) && (segmentation_map != NULL));
+  assert((model->width > 0) && (model->height > 0));
+  assert(model->historyBuffer != NULL);
+  assert((model->jump != NULL) && (model->neighbor != NULL) && (model->position != NULL));
+
+  /* Some variables. */
+  uint32_t width = model->width;
+  uint32_t height = model->height;
+  uint32_t matchingNumber = model->matchingNumber;
+  uint32_t matchingThreshold = model->matchingThreshold;
+
+  uint8_t *historyImage = model->historyImage;
+  uint8_t *historyBuffer = model->historyBuffer;
+
+  /* Segmentation. */
+  memset(segmentation_map, matchingNumber - 1, width * height);
+
+  /* First history Image structure. */
+  for (int index = width * height - 1; index >= 0; --index) {
+    //if (abs_uint(image_data[index] - historyImage[index]) > matchingThreshold)
+    if (abs_uint(image_data[index] - historyImage[index]) > distance_Han2014Improved(image_data[index], historyImage[index]))
+      segmentation_map[index] = matchingNumber;
+  }
+
+  /* Next historyImages. */
+  for (int i = 1; i < NUMBER_OF_HISTORY_IMAGES; ++i) {
+    uint8_t *pels = historyImage + i * width * height;
+
+    for (int index = width * height - 1; index >= 0; --index) {
+      // if (abs_uint(image_data[index] - pels[index]) <= matchingThreshold)
+      if (abs_uint(image_data[index] - pels[index]) <= distance_Han2014Improved(image_data[index], pels[index]))
+        --segmentation_map[index];
+    }
+  }
+
+  /* For swapping. */
+  model->lastHistoryImageSwapped = (model->lastHistoryImageSwapped + 1) % NUMBER_OF_HISTORY_IMAGES;
+  uint8_t *swappingImageBuffer = historyImage + (model->lastHistoryImageSwapped) * width * height;
+
+  /* Now, we move in the buffer and leave the historyImages. */
+  int numberOfTests = (model->numberOfSamples - NUMBER_OF_HISTORY_IMAGES);
+
+  for (int index = width * height - 1; index >= 0; --index) {
+    if (segmentation_map[index] > 0) {
+      /* We need to check the full border and swap values with the first or second historyImage.
+       * We still need to find a match before we can stop our search.
+       */
+      uint32_t indexHistoryBuffer = index * numberOfTests;
+      uint8_t currentValue = image_data[index];
+
+      for (int i = numberOfTests; i > 0; --i, ++indexHistoryBuffer) {
+        // if (abs_uint(currentValue - historyBuffer[indexHistoryBuffer]) <= matchingThreshold) {
+        if (abs_uint(currentValue - historyBuffer[indexHistoryBuffer]) <= distance_Han2014Improved(currentValue, historyBuffer[indexHistoryBuffer])) {
+          --segmentation_map[index];
+
+          /* Swaping: Putting found value in history image buffer. */
+          uint8_t temp = swappingImageBuffer[index];
+          swappingImageBuffer[index] = historyBuffer[indexHistoryBuffer];
+          historyBuffer[indexHistoryBuffer] = temp;
+
+          /* Exit inner loop. */
+          if (segmentation_map[index] <= 0) break;
+        }
+      } // for
+    } // if
+  } // for
+
+  /* Produces the output. Note that this step is application-dependent. */
+  for (uint8_t *mask = segmentation_map; mask < segmentation_map + (width * height); ++mask)
+    if (*mask > 0) *mask = COLOR_FOREGROUND;
+
+  return(0);
+}
+
+// ----------------------------------------------------------------------------
+// Update a C1R model
+// ----------------------------------------------------------------------------
+int32_t libvibeModel_Sequential_Update_8u_C1R(
+  vibeModel_Sequential_t *model,
+  const uint8_t *image_data,
+  uint8_t *updating_mask
+) {
+  /* Basic checks . */
+  assert((image_data != NULL) && (model != NULL) && (updating_mask != NULL));
+  assert((model->width > 0) && (model->height > 0));
+  assert(model->historyBuffer != NULL);
+  assert((model->jump != NULL) && (model->neighbor != NULL) && (model->position != NULL));
+
+  /* Some variables. */
+  uint32_t width = model->width;
+  uint32_t height = model->height;
+
+  uint8_t *historyImage = model->historyImage;
+  uint8_t *historyBuffer = model->historyBuffer;
+
+  /* Some utility variable. */
+  int numberOfTests = (model->numberOfSamples - NUMBER_OF_HISTORY_IMAGES);
+
+  /* Updating. */
+  uint32_t *jump = model->jump;
+  int *neighbor = model->neighbor;
+  uint32_t *position = model->position;
+
+  /* All the frame, except the border. */
+  uint32_t shift, indX, indY;
+  int x, y;
+
+  for (y = 1; y < height - 1; ++y) {
+    shift = rand() % width;
+    indX = jump[shift]; // index_jump should never be zero (> 1).
+
+    while (indX < width - 1) {
+      int index = indX + y * width;
+
+      if (updating_mask[index] == COLOR_BACKGROUND) {
+        /* In-place substitution. */
+        uint8_t value = image_data[index];
+        int index_neighbor = index + neighbor[shift];
+
+        if (position[shift] < NUMBER_OF_HISTORY_IMAGES) {
+          historyImage[index + position[shift] * width * height] = value;
+          historyImage[index_neighbor + position[shift] * width * height] = value;
+        }
+        else {
+          int pos = position[shift] - NUMBER_OF_HISTORY_IMAGES;
+          historyBuffer[index * numberOfTests + pos] = value;
+          historyBuffer[index_neighbor * numberOfTests + pos] = value;
+        }
+      }
+
+      ++shift;
+      indX += jump[shift];
+    }
+  }
+
+  /* First row. */
+  y = 0;
+  shift = rand() % width;
+  indX = jump[shift]; // index_jump should never be zero (> 1).
+
+  while (indX <= width - 1) {
+    int index = indX + y * width;
+
+    if (updating_mask[index] == COLOR_BACKGROUND) {
+      if (position[shift] < NUMBER_OF_HISTORY_IMAGES)
+        historyImage[index + position[shift] * width * height] = image_data[index];
+      else {
+        int pos = position[shift] - NUMBER_OF_HISTORY_IMAGES;
+        historyBuffer[index * numberOfTests + pos] = image_data[index];
+      }
+    }
+
+    ++shift;
+    indX += jump[shift];
+  }
+
+  /* Last row. */
+  y = height - 1;
+  shift = rand() % width;
+  indX = jump[shift]; // index_jump should never be zero (> 1).
+
+  while (indX <= width - 1) {
+    int index = indX + y * width;
+
+    if (updating_mask[index] == COLOR_BACKGROUND) {
+      if (position[shift] < NUMBER_OF_HISTORY_IMAGES)
+        historyImage[index + position[shift] * width * height] = image_data[index];
+      else {
+        int pos = position[shift] - NUMBER_OF_HISTORY_IMAGES;
+        historyBuffer[index * numberOfTests + pos] = image_data[index];
+      }
+    }
+
+    ++shift;
+    indX += jump[shift];
+  }
+
+  /* First column. */
+  x = 0;
+  shift = rand() % height;
+  indY = jump[shift]; // index_jump should never be zero (> 1).
+
+  while (indY <= height - 1) {
+    int index = x + indY * width;
+
+    if (updating_mask[index] == COLOR_BACKGROUND) {
+      if (position[shift] < NUMBER_OF_HISTORY_IMAGES)
+        historyImage[index + position[shift] * width * height] = image_data[index];
+      else {
+        int pos = position[shift] - NUMBER_OF_HISTORY_IMAGES;
+        historyBuffer[index * numberOfTests + pos] = image_data[index];
+      }
+    }
+
+    ++shift;
+    indY += jump[shift];
+  }
+
+  /* Last column. */
+  x = width - 1;
+  shift = rand() % height;
+  indY = jump[shift]; // index_jump should never be zero (> 1).
+
+  while (indY <= height - 1) {
+    int index = x + indY * width;
+
+    if (updating_mask[index] == COLOR_BACKGROUND) {
+      if (position[shift] < NUMBER_OF_HISTORY_IMAGES)
+        historyImage[index + position[shift] * width * height] = image_data[index];
+      else {
+        int pos = position[shift] - NUMBER_OF_HISTORY_IMAGES;
+        historyBuffer[index * numberOfTests + pos] = image_data[index];
+      }
+    }
+
+    ++shift;
+    indY += jump[shift];
+  }
+
+  /* The first pixel! */
+  if (rand() % model->updateFactor == 0) {
+    if (updating_mask[0] == 0) {
+      int position = rand() % model->numberOfSamples;
+
+      if (position < NUMBER_OF_HISTORY_IMAGES)
+        historyImage[position * width * height] = image_data[0];
+      else {
+        int pos = position - NUMBER_OF_HISTORY_IMAGES;
+        historyBuffer[pos] = image_data[0];
+      }
+    }
+  }
+
+  return(0);
+}
+
+// ----------------------------------------------------------------------------
+// -------------------------- The same for C3R models -------------------------
+// ----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// Allocates and initializes a C3R model structure
+// -----------------------------------------------------------------------------
+int32_t libvibeModel_Sequential_AllocInit_8u_C3R(
+  vibeModel_Sequential_t *model,
+  const uint8_t *image_data,
+  const uint32_t width,
+  const uint32_t height
+) {
+  /* Some basic checks. */
+  assert((image_data != NULL) && (model != NULL));
+  assert((width > 0) && (height > 0));
+
+  /* Finish model alloc - parameters values cannot be changed anymore. */
+  model->width = width;
+  model->height = height;
+
+  /* Creates the historyImage structure. */
+  model->historyImage = NULL;
+  model->historyImage = (uint8_t*)malloc(NUMBER_OF_HISTORY_IMAGES * (3 * width) * height * sizeof(uint8_t));
+  assert(model->historyImage != NULL);
+
+  for (int i = 0; i < NUMBER_OF_HISTORY_IMAGES; ++i) {
+    for (int index = (3 * width) * height - 1; index >= 0; --index)
+      model->historyImage[i * (3 * width) * height + index] = image_data[index];
+  }
+
+  assert(model->historyImage != NULL);
+
+  /* Now creates and fills the history buffer. */
+  model->historyBuffer = (uint8_t *)malloc((3 * width) * height * (model->numberOfSamples - NUMBER_OF_HISTORY_IMAGES) * sizeof(uint8_t));
+  assert(model->historyBuffer != NULL);
+
+  for (int index = (3 * width) * height - 1; index >= 0; --index) {
+    uint8_t value = image_data[index];
+
+    for (int x = 0; x < model->numberOfSamples - NUMBER_OF_HISTORY_IMAGES; ++x) {
+      int value_plus_noise = value + rand() % 20 - 10;
+
+      if (value_plus_noise < 0) { value_plus_noise = 0; }
+      if (value_plus_noise > 255) { value_plus_noise = 255; }
+
+      model->historyBuffer[index * (model->numberOfSamples - NUMBER_OF_HISTORY_IMAGES) + x] = value_plus_noise;
+    }
+  }
+
+  /* Fills the buffers with random values. */
+  int size = (width > height) ? 2 * width + 1 : 2 * height + 1;
+
+  model->jump = (uint32_t*)malloc(size * sizeof(*(model->jump)));
+  assert(model->jump != NULL);
+
+  model->neighbor = (int*)malloc(size * sizeof(*(model->neighbor)));
+  assert(model->neighbor != NULL);
+
+  model->position = (uint32_t*)malloc(size * sizeof(*(model->position)));
+  assert(model->position != NULL);
+
+  for (int i = 0; i < size; ++i) {
+    model->jump[i] = (rand() % (2 * model->updateFactor)) + 1;            // Values between 1 and 2 * updateFactor.
+    model->neighbor[i] = ((rand() % 3) - 1) + ((rand() % 3) - 1) * width; // Values between { width - 1, ... , width + 1 }.
+    model->position[i] = rand() % (model->numberOfSamples);               // Values between 0 and numberOfSamples - 1.
+  }
+
+  return(0);
+}
+
+// -----------------------------------------------------------------------------
+// Segmentation of a C3R model
+// -----------------------------------------------------------------------------
+int32_t libvibeModel_Sequential_Segmentation_8u_C3R(
+  vibeModel_Sequential_t *model,
+  const uint8_t *image_data,
+  uint8_t *segmentation_map
+) {
+  /* Basic checks. */
+  assert((image_data != NULL) && (model != NULL) && (segmentation_map != NULL));
+  assert((model->width > 0) && (model->height > 0));
+  assert(model->historyBuffer != NULL);
+  assert((model->jump != NULL) && (model->neighbor != NULL) && (model->position != NULL));
+
+  /* Some variables. */
+  uint32_t width = model->width;
+  uint32_t height = model->height;
+  uint32_t matchingNumber = model->matchingNumber;
+  uint32_t matchingThreshold = model->matchingThreshold;
+
+  uint8_t *historyImage = model->historyImage;
+  uint8_t *historyBuffer = model->historyBuffer;
+
+  /* Segmentation. */
+  memset(segmentation_map, matchingNumber - 1, width * height);
+
+  /* First history Image structure. */
+  uint8_t *first = historyImage;
+
+  for (int index = width * height - 1; index >= 0; --index) {
+    if (
+      !distance_is_close_8u_C3R(
+        image_data[3 * index], image_data[3 * index + 1], image_data[3 * index + 2],
+        first[3 * index], first[3 * index + 1], first[3 * index + 2], matchingThreshold
+      )
+      )
+      segmentation_map[index] = matchingNumber;
+  }
+
+  /* Next historyImages. */
+  for (int i = 1; i < NUMBER_OF_HISTORY_IMAGES; ++i) {
+    uint8_t *pels = historyImage + i * (3 * width) * height;
+
+    for (int index = width * height - 1; index >= 0; --index) {
+      if (
+        distance_is_close_8u_C3R(
+          image_data[3 * index], image_data[3 * index + 1], image_data[3 * index + 2],
+          pels[3 * index], pels[3 * index + 1], pels[3 * index + 2], matchingThreshold
+        )
+        )
+        --segmentation_map[index];
+    }
+  }
+
+  // For swapping
+  model->lastHistoryImageSwapped = (model->lastHistoryImageSwapped + 1) % NUMBER_OF_HISTORY_IMAGES;
+  uint8_t *swappingImageBuffer = historyImage + (model->lastHistoryImageSwapped) * (3 * width) * height;
+
+  // Now, we move in the buffer and leave the historyImages
+  int numberOfTests = (model->numberOfSamples - NUMBER_OF_HISTORY_IMAGES);
+
+  for (int index = width * height - 1; index >= 0; --index) {
+    if (segmentation_map[index] > 0) {
+      /* We need to check the full border and swap values with the first or second historyImage.
+       * We still need to find a match before we can stop our search.
+       */
+      uint32_t indexHistoryBuffer = (3 * index) * numberOfTests;
+
+      for (int i = numberOfTests; i > 0; --i, indexHistoryBuffer += 3) {
+        if (
+          distance_is_close_8u_C3R(
+            image_data[(3 * index)], image_data[(3 * index) + 1], image_data[(3 * index) + 2],
+            historyBuffer[indexHistoryBuffer], historyBuffer[indexHistoryBuffer + 1], historyBuffer[indexHistoryBuffer + 2],
+            matchingThreshold
+          )
+          )
+          --segmentation_map[index];
+
+        /* Swaping: Putting found value in history image buffer. */
+        uint8_t temp_r = swappingImageBuffer[(3 * index)];
+        uint8_t temp_g = swappingImageBuffer[(3 * index) + 1];
+        uint8_t temp_b = swappingImageBuffer[(3 * index) + 2];
+
+        swappingImageBuffer[(3 * index)] = historyBuffer[indexHistoryBuffer];
+        swappingImageBuffer[(3 * index) + 1] = historyBuffer[indexHistoryBuffer + 1];
+        swappingImageBuffer[(3 * index) + 2] = historyBuffer[indexHistoryBuffer + 2];
+
+        historyBuffer[indexHistoryBuffer] = temp_r;
+        historyBuffer[indexHistoryBuffer + 1] = temp_g;
+        historyBuffer[indexHistoryBuffer + 2] = temp_b;
+
+        /* Exit inner loop. */
+        if (segmentation_map[index] <= 0) break;
+      } // for
+    } // if
+  } // for
+
+  /* Produces the output. Note that this step is application-dependent. */
+  for (uint8_t *mask = segmentation_map; mask < segmentation_map + (width * height); ++mask)
+    if (*mask > 0) *mask = COLOR_FOREGROUND;
+
+  return(0);
+}
+
+// ----------------------------------------------------------------------------
+// Update a C3R model
+// ----------------------------------------------------------------------------
+int32_t libvibeModel_Sequential_Update_8u_C3R(
+  vibeModel_Sequential_t *model,
+  const uint8_t *image_data,
+  uint8_t *updating_mask
+) {
+  /* Basic checks. */
+  assert((image_data != NULL) && (model != NULL) && (updating_mask != NULL));
+  assert((model->width > 0) && (model->height > 0));
+  assert(model->historyBuffer != NULL);
+  assert((model->jump != NULL) && (model->neighbor != NULL) && (model->position != NULL));
+
+  /* Some variables. */
+  uint32_t width = model->width;
+  uint32_t height = model->height;
+
+  uint8_t *historyImage = model->historyImage;
+  uint8_t *historyBuffer = model->historyBuffer;
+
+  /* Some utility variable. */
+  int numberOfTests = (model->numberOfSamples - NUMBER_OF_HISTORY_IMAGES);
+
+  /* Updating. */
+  uint32_t *jump = model->jump;
+  int *neighbor = model->neighbor;
+  uint32_t *position = model->position;
+
+  /* All the frame, except the border. */
+  uint32_t shift, indX, indY;
+  int x, y;
+
+  for (y = 1; y < height - 1; ++y) {
+    shift = rand() % width;
+    indX = jump[shift]; // index_jump should never be zero (> 1).
+
+    while (indX < width - 1) {
+      int index = indX + y * width;
+
+      if (updating_mask[index] == COLOR_BACKGROUND) {
+        /* In-place substitution. */
+        uint8_t r = image_data[3 * index];
+        uint8_t g = image_data[3 * index + 1];
+        uint8_t b = image_data[3 * index + 2];
+
+        int index_neighbor = 3 * (index + neighbor[shift]);
+
+        if (position[shift] < NUMBER_OF_HISTORY_IMAGES) {
+          historyImage[3 * index + position[shift] * (3 * width) * height] = r;
+          historyImage[3 * index + position[shift] * (3 * width) * height + 1] = g;
+          historyImage[3 * index + position[shift] * (3 * width) * height + 2] = b;
+
+          historyImage[index_neighbor + position[shift] * (3 * width) * height] = r;
+          historyImage[index_neighbor + position[shift] * (3 * width) * height + 1] = g;
+          historyImage[index_neighbor + position[shift] * (3 * width) * height + 2] = r;
+        }
+        else {
+          int pos = position[shift] - NUMBER_OF_HISTORY_IMAGES;
+
+          historyBuffer[(3 * index) * numberOfTests + 3 * pos] = r;
+          historyBuffer[(3 * index) * numberOfTests + 3 * pos + 1] = g;
+          historyBuffer[(3 * index) * numberOfTests + 3 * pos + 2] = b;
+
+          historyBuffer[index_neighbor * numberOfTests + 3 * pos] = r;
+          historyBuffer[index_neighbor * numberOfTests + 3 * pos + 1] = g;
+          historyBuffer[index_neighbor * numberOfTests + 3 * pos + 2] = b;
+        }
+      }
+
+      ++shift;
+      indX += jump[shift];
+    }
+  }
+
+  /* First row. */
+  y = 0;
+  shift = rand() % width;
+  indX = jump[shift]; // index_jump should never be zero (> 1).
+
+  while (indX <= width - 1) {
+    int index = indX + y * width;
+
+    uint8_t r = image_data[3 * index];
+    uint8_t g = image_data[3 * index + 1];
+    uint8_t b = image_data[3 * index + 2];
+
+    if (updating_mask[index] == COLOR_BACKGROUND) {
+      if (position[shift] < NUMBER_OF_HISTORY_IMAGES) {
+        historyImage[3 * index + position[shift] * (3 * width) * height] = r;
+        historyImage[3 * index + position[shift] * (3 * width) * height + 1] = g;
+        historyImage[3 * index + position[shift] * (3 * width) * height + 2] = b;
+      }
+      else {
+        int pos = position[shift] - NUMBER_OF_HISTORY_IMAGES;
+
+        historyBuffer[(3 * index) * numberOfTests + 3 * pos] = r;
+        historyBuffer[(3 * index) * numberOfTests + 3 * pos + 1] = g;
+        historyBuffer[(3 * index) * numberOfTests + 3 * pos + 2] = b;
+      }
+    }
+
+    ++shift;
+    indX += jump[shift];
+  }
+
+  /* Last row. */
+  y = height - 1;
+  shift = rand() % width;
+  indX = jump[shift]; // index_jump should never be zero (> 1).
+
+  while (indX <= width - 1) {
+    int index = indX + y * width;
+
+    uint8_t r = image_data[3 * index];
+    uint8_t g = image_data[3 * index + 1];
+    uint8_t b = image_data[3 * index + 2];
+
+    if (updating_mask[index] == COLOR_BACKGROUND) {
+      if (position[shift] < NUMBER_OF_HISTORY_IMAGES) {
+        historyImage[3 * index + position[shift] * (3 * width) * height] = r;
+        historyImage[3 * index + position[shift] * (3 * width) * height + 1] = g;
+        historyImage[3 * index + position[shift] * (3 * width) * height + 2] = b;
+      }
+      else {
+        int pos = position[shift] - NUMBER_OF_HISTORY_IMAGES;
+
+        historyBuffer[(3 * index) * numberOfTests + 3 * pos] = r;
+        historyBuffer[(3 * index) * numberOfTests + 3 * pos + 1] = g;
+        historyBuffer[(3 * index) * numberOfTests + 3 * pos + 2] = b;
+      }
+    }
+
+    ++shift;
+    indX += jump[shift];
+  }
+
+  /* First column. */
+  x = 0;
+  shift = rand() % height;
+  indY = jump[shift]; // index_jump should never be zero (> 1).
+
+  while (indY <= height - 1) {
+    int index = x + indY * width;
+
+    uint8_t r = image_data[3 * index];
+    uint8_t g = image_data[3 * index + 1];
+    uint8_t b = image_data[3 * index + 2];
+
+    if (updating_mask[index] == COLOR_BACKGROUND) {
+      if (position[shift] < NUMBER_OF_HISTORY_IMAGES) {
+        historyImage[3 * index + position[shift] * (3 * width) * height] = r;
+        historyImage[3 * index + position[shift] * (3 * width) * height + 1] = g;
+        historyImage[3 * index + position[shift] * (3 * width) * height + 2] = b;
+      }
+      else {
+        int pos = position[shift] - NUMBER_OF_HISTORY_IMAGES;
+        historyBuffer[(3 * index) * numberOfTests + 3 * pos] = r;
+        historyBuffer[(3 * index) * numberOfTests + 3 * pos + 1] = g;
+        historyBuffer[(3 * index) * numberOfTests + 3 * pos + 2] = b;
+      }
+    }
+
+    ++shift;
+    indY += jump[shift];
+  }
+
+  /* Last column. */
+  x = width - 1;
+  shift = rand() % height;
+  indY = jump[shift]; // index_jump should never be zero (> 1).
+
+  while (indY <= height - 1) {
+    int index = x + indY * width;
+
+    uint8_t r = image_data[3 * index];
+    uint8_t g = image_data[3 * index + 1];
+    uint8_t b = image_data[3 * index + 2];
+
+    if (updating_mask[index] == COLOR_BACKGROUND) {
+      if (position[shift] < NUMBER_OF_HISTORY_IMAGES) {
+        historyImage[3 * index + position[shift] * (3 * width) * height] = r;
+        historyImage[3 * index + position[shift] * (3 * width) * height + 1] = g;
+        historyImage[3 * index + position[shift] * (3 * width) * height + 2] = b;
+      }
+      else {
+        int pos = position[shift] - NUMBER_OF_HISTORY_IMAGES;
+
+        historyBuffer[(3 * index) * numberOfTests + 3 * pos] = r;
+        historyBuffer[(3 * index) * numberOfTests + 3 * pos + 1] = g;
+        historyBuffer[(3 * index) * numberOfTests + 3 * pos + 2] = b;
+      }
+    }
+
+    ++shift;
+    indY += jump[shift];
+  }
+
+  /* The first pixel! */
+  if (rand() % model->updateFactor == 0) {
+    if (updating_mask[0] == 0) {
+      int position = rand() % model->numberOfSamples;
+
+      uint8_t r = image_data[0];
+      uint8_t g = image_data[1];
+      uint8_t b = image_data[2];
+
+      if (position < NUMBER_OF_HISTORY_IMAGES) {
+        historyImage[position * (3 * width) * height] = r;
+        historyImage[position * (3 * width) * height + 1] = g;
+        historyImage[position * (3 * width) * height + 2] = b;
+      }
+      else {
+        int pos = position - NUMBER_OF_HISTORY_IMAGES;
+
+        historyBuffer[3 * pos] = r;
+        historyBuffer[3 * pos + 1] = g;
+        historyBuffer[3 * pos + 2] = b;
+      }
+    }
+  }
+
+  return(0);
+}
diff --git a/package_bgs/ViBe/vibe-background-sequential.h b/package_bgs/ViBe/vibe-background-sequential.h
new file mode 100644
index 0000000000000000000000000000000000000000..068c7d1b70365d88cb9931b8ce96e337ac0ca4f1
--- /dev/null
+++ b/package_bgs/ViBe/vibe-background-sequential.h
@@ -0,0 +1,293 @@
+/*
+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/>.
+*/
+/**
+  @file vibe-background-sequential.h
+  @brief Interface for the ViBe library
+  @author Marc Van Droogenbroeck
+  @date July 2014
+  @details
+
+  Full documentation is available online at:
+     http://www.ulg.ac.be/telecom/research/vibe/doc
+
+  All technical details are available in the following paper:
+<em>O. Barnich and M. Van Droogenbroeck. ViBe: A universal background subtraction algorithm for video sequences. IEEE Transactions on Image Processing, 20(6):1709-1724, June 2011.</em>
+
+\verbatim
+BiBTeX information
+
+  @article{Barnich2011ViBe,
+  title = {{ViBe}: A universal background subtraction algorithm for video sequences},
+  author = {O. Barnich and M. {Van Droogenbroeck}},
+  journal = {IEEE Transactions on Image Processing},
+  volume = {20},
+  number = {6},
+  pages = {1709-1724},
+  month = {June},
+  year = {2011},
+  keywords = {ViBe, Background, Background subtraction, Segmentation, Motion, Motion detection},
+  pdf = {http://orbi.ulg.ac.be/bitstream/2268/145853/1/Barnich2011ViBe.pdf},
+  doi = {10.1109/TIP.2010.2101613},
+  url = {http://hdl.handle.net/2268/145853}
+  }
+\endverbatim
+See
+\cite Barnich2011ViBe
+*/
+#pragma once
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#define COLOR_BACKGROUND   0 /*!< Default label for background pixels */
+#define COLOR_FOREGROUND 255 /*!< Default label for foreground pixels. Note that some authors chose any value different from 0 instead */
+
+/**
+ * \typedef struct vibeModel_Sequential_t
+ * \brief Data structure for the background subtraction model.
+ *
+ * This data structure contains the background model as well as some paramaters value.
+ * The code is designed to hide all the implementation details to the user to ease its use.
+ */
+typedef struct vibeModel_Sequential vibeModel_Sequential_t;
+
+/**
+ * Allocation of a new data structure where the background model will be stored.
+ * Please note that this function only creates the structure to host the data.
+ * This data structures will only be filled with a call to \ref libvibeModel_Sequential_AllocInit_8u_C1R.
+ *
+ * \result A pointer to a newly allocated \ref vibeModel_Sequential_t
+ * structure, or <tt>NULL</tt> in the case of an error.
+ */
+vibeModel_Sequential_t *libvibeModel_Sequential_New();
+
+/**
+ * ViBe uses several parameters.
+ * You can print and change some of them if you want. However, default
+ * value should meet your needs for most videos.
+ *
+ * @param model The data structure with ViBe's background subtraction model and parameters.
+ * @return
+ */
+uint32_t libvibeModel_Sequential_PrintParameters(const vibeModel_Sequential_t *model);
+
+/**
+ * Setter.
+ *
+ * @param model The data structure with ViBe's background subtraction model and parameters.
+ * @param numberOfSamples
+ * @return
+ */
+int32_t libvibeModel_Sequential_SetNumberOfSamples(
+  vibeModel_Sequential_t *model,
+  const uint32_t numberOfSamples
+);
+
+/**
+ * Setter.
+ *
+ * @param model The data structure with ViBe's background subtraction model and parameters.
+ * @return
+ */
+uint32_t libvibeModel_Sequential_GetNumberOfSamples(const vibeModel_Sequential_t *model);
+
+/**
+ * Setter.
+ *
+ * @param model The data structure with ViBe's background subtraction model and parameters.
+ * @param matchingThreshold
+ * @return
+ */
+int32_t libvibeModel_Sequential_SetMatchingThreshold(
+  vibeModel_Sequential_t *model,
+  const uint32_t matchingThreshold
+);
+
+/**
+ * Setter.
+ *
+ * @param model The data structure with ViBe's background subtraction model and parameters.
+ * @return
+ */
+uint32_t libvibeModel_Sequential_GetMatchingThreshold(const vibeModel_Sequential_t *model);
+
+/**
+ * Setter.
+ *
+ * @param model The data structure with ViBe's background subtraction model and parameters.
+ * @param matchingNumber
+ * @return
+ */
+int32_t libvibeModel_Sequential_SetMatchingNumber(
+  vibeModel_Sequential_t *model,
+  const uint32_t matchingNumber
+);
+
+/**
+ * Setter.
+ *
+ * @param model The data structure with ViBe's background subtraction model and parameters.
+ * @param updateFactor New value for the update factor. Please note that the update factor is to be understood as a probability of updating. More specifically, an update factor of 16 means that 1 out of every 16 background pixels is updated. Likewise, an update factor of 1 means that every background pixel is updated.
+ * @return
+ */
+int32_t libvibeModel_Sequential_SetUpdateFactor(
+  vibeModel_Sequential_t *model,
+  const uint32_t updateFactor
+);
+
+/**
+ * Getter.
+ *
+ * @param model The data structure with ViBe's background subtraction model and parameters.
+ * @return
+ */
+uint32_t libvibeModel_Sequential_GetMatchingNumber(const vibeModel_Sequential_t *model);
+
+
+/**
+ * Getter.
+ *
+ * @param model The data structure with ViBe's background subtraction model and parameters.
+ * @return
+ */
+uint32_t libvibeModel_Sequential_GetUpdateFactor(const vibeModel_Sequential_t *model);
+
+/**
+ * \brief Frees all the memory used by the <tt>model</tt> and deallocates the structure.
+ *
+ * This function frees all the memory allocated by \ref libvibeModel_SequentialNew and
+ * \ref libvibeModel_Sequential_AllocInit_8u_C1R or \ref libvibeModel_Sequential_AllocInit_8u_C3R.
+ * @param model The data structure with ViBe's background subtraction model and parameters.
+ * @return
+ */
+int32_t libvibeModel_Sequential_Free(vibeModel_Sequential_t *model);
+
+/**
+ * The two following functions allocate the required memory according to the
+ * model parameters and the dimensions of the input images.
+ * You must use the "C1R" function for grayscale images and the "C3R" for color
+ * images.
+ * These 2 functions also initialize the background model using the content
+ * of *image_data which is the pixel buffer of the first image of your stream.
+ */
+ // -------------------------  Single channel images ----------------------------
+ /**
+  *
+  * @param model The data structure with ViBe's background subtraction model and parameters.
+  * @param image_data
+  * @param width
+  * @param height
+  * @return
+  */
+int32_t libvibeModel_Sequential_AllocInit_8u_C1R(
+  vibeModel_Sequential_t *model,
+  const uint8_t *image_data,
+  const uint32_t width,
+  const uint32_t height
+);
+
+/* These 2 functions perform 2 operations:
+ *   - they classify the pixels *image_data using the provided model and store
+ *     the results in *segmentation_map.
+ *   - they update *model according to these results and the content of
+ *     *image_data.
+ * You must use the "C1R" function for grayscale images and the "C3R" for color
+ * images.
+ */
+ /**
+  *
+  * @param model The data structure with ViBe's background subtraction model and parameters.
+  * @param image_data
+  * @param segmentation_map
+  * @return
+  */
+int32_t libvibeModel_Sequential_Segmentation_8u_C1R(
+  vibeModel_Sequential_t *model,
+  const uint8_t *image_data,
+  uint8_t *segmentation_map
+);
+
+/**
+ *
+ * @param model The data structure with ViBe's background subtraction model and parameters.
+ * @param image_data
+ * @param updating_mask
+ * @return
+ */
+int32_t libvibeModel_Sequential_Update_8u_C1R(
+  vibeModel_Sequential_t *model,
+  const uint8_t *image_data,
+  uint8_t *updating_mask
+);
+
+// -------------------------  Three channel images -----------------------------
+/**
+ * The pixel values of color images are arranged in the following order
+ * RGBRGBRGB... (or HSVHSVHSVHSVHSVHSV...)
+ *
+ * @param model The data structure with ViBe's background subtraction model and parameters.
+ * @param image_data
+ * @param width
+ * @param height
+ * @return
+ */
+int32_t libvibeModel_Sequential_AllocInit_8u_C3R(
+  vibeModel_Sequential_t *model,
+  const uint8_t *image_data,
+  const uint32_t width,
+  const uint32_t height
+);
+
+/* These 2 functions perform 2 operations:
+ *   - they classify the pixels *image_data using the provided model and store
+ *     the results in *segmentation_map.
+ *   - they update *model according to these results and the content of
+ *     *image_data.
+ * You must use the "C1R" function for grayscale images and the "C3R" for color
+ * images.
+ */
+ /**
+  * The pixel values of color images are arranged in the following order
+  * RGBRGBRGB... (or HSVHSVHSVHSVHSVHSV...)
+  *
+  * @param model The data structure with ViBe's background subtraction model and parameters.
+  * @param image_data
+  * @param segmentation_map
+  * @return
+  */
+int32_t libvibeModel_Sequential_Segmentation_8u_C3R(
+  vibeModel_Sequential_t *model,
+  const uint8_t *image_data,
+  uint8_t *segmentation_map
+);
+
+/**
+ * The pixel values of color images are arranged in the following order
+ * RGBRGBRGB... (or HSVHSVHSVHSVHSVHSV...)
+ *
+ * @param model The data structure with ViBe's background subtraction model and parameters.
+ * @param image_data
+ * @param updating_mask
+ * @return
+ */
+int32_t libvibeModel_Sequential_Update_8u_C3R(
+  vibeModel_Sequential_t *model,
+  const uint8_t *image_data,
+  uint8_t *updating_mask
+);
diff --git a/package_bgs/av/VuMeter.cpp b/package_bgs/VuMeter.cpp
similarity index 52%
rename from package_bgs/av/VuMeter.cpp
rename to package_bgs/VuMeter.cpp
index 29a1477f536a06058f76bc51384c12712b0db761..99baee9c28d48391d96634dd0931624050402226 100644
--- a/package_bgs/av/VuMeter.cpp
+++ b/package_bgs/VuMeter.cpp
@@ -16,9 +16,13 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "VuMeter.h"
 
-VuMeter::VuMeter() : firstTime(true), showOutput(true), enableFilter(true), binSize(8), alpha(0.995), threshold(0.03)
+using namespace bgslibrary::algorithms;
+
+VuMeter::VuMeter() :
+  enableFilter(true), binSize(8), alpha(0.995), threshold(0.03)
 {
   std::cout << "VuMeter()" << std::endl;
+  setup("./config/VuMeter.xml");
 }
 
 VuMeter::~VuMeter()
@@ -32,69 +36,62 @@ VuMeter::~VuMeter()
 
 void VuMeter::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-  else
-    frame = new IplImage(img_input);
-
-  loadConfig();
+  init(img_input, img_output, img_bgmodel);
+  frame = new IplImage(img_input);
 
-  if(firstTime)
+  if (firstTime)
   {
     bgs.SetAlpha(alpha);
     bgs.SetBinSize(binSize);
     bgs.SetThreshold(threshold);
 
-    gray = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1);
-    cvCvtColor(frame,gray,CV_RGB2GRAY);
+    gray = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1);
+    cvCvtColor(frame, gray, CV_RGB2GRAY);
 
-    background = cvCreateImage(cvGetSize(gray),IPL_DEPTH_8U,1);
+    background = cvCreateImage(cvGetSize(gray), IPL_DEPTH_8U, 1);
     cvCopy(gray, background);
 
-    mask = cvCreateImage(cvGetSize(gray),IPL_DEPTH_8U,1);
+    mask = cvCreateImage(cvGetSize(gray), IPL_DEPTH_8U, 1);
     cvZero(mask);
-
-    saveConfig();
   }
   else
-    cvCvtColor(frame,gray,CV_RGB2GRAY);
-  
-  bgs.UpdateBackground(gray,background,mask);
-  cv::Mat img_foreground(mask);
-  cv::Mat img_bkg(background);
+    cvCvtColor(frame, gray, CV_RGB2GRAY);
+
+  bgs.UpdateBackground(gray, background, mask);
+  img_foreground = cv::cvarrToMat(mask);
+  img_background = cv::cvarrToMat(background);
 
-  if(enableFilter)
+  if (enableFilter)
   {
-    cv::erode(img_foreground,img_foreground,cv::Mat());
+    cv::erode(img_foreground, img_foreground, cv::Mat());
     cv::medianBlur(img_foreground, img_foreground, 5);
   }
 
-  if(showOutput)
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
   {
-    if(!img_foreground.empty())
-      cv::imshow("VuMeter", img_foreground);
-    
-    if(!img_bkg.empty())
-      cv::imshow("VuMeter Bkg Model", img_bkg);
+    cv::imshow("VuMeter", img_foreground);
+    cv::imshow("VuMeter Bkg Model", img_background);
   }
+#endif
 
   img_foreground.copyTo(img_output);
-  img_bkg.copyTo(img_bgmodel);
-  
+  img_background.copyTo(img_bgmodel);
+
   delete frame;
   firstTime = false;
 }
 
 void VuMeter::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/VuMeter.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteInt(fs, "enableFilter", enableFilter);
-  
+
   cvWriteInt(fs, "binSize", binSize);
   cvWriteReal(fs, "alpha", alpha);
   cvWriteReal(fs, "threshold", threshold);
-  
+
   cvWriteInt(fs, "showOutput", showOutput);
 
   cvReleaseFileStorage(&fs);
@@ -102,15 +99,15 @@ void VuMeter::saveConfig()
 
 void VuMeter::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/VuMeter.xml", 0, CV_STORAGE_READ);
-  
-  enableFilter = cvReadIntByName(fs, 0, "enableFilter", true);
-  
-  binSize = cvReadIntByName(fs, 0, "binSize", 8);
-  alpha = cvReadRealByName(fs, 0, "alpha", 0.995);
-  threshold = cvReadRealByName(fs, 0, "threshold", 0.03);
-  
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  enableFilter = cvReadIntByName(fs, nullptr, "enableFilter", true);
+
+  binSize = cvReadIntByName(fs, nullptr, "binSize", 8);
+  alpha = cvReadRealByName(fs, nullptr, "alpha", 0.995);
+  threshold = cvReadRealByName(fs, nullptr, "threshold", 0.03);
+
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/VuMeter.h b/package_bgs/VuMeter.h
new file mode 100644
index 0000000000000000000000000000000000000000..fefd3ec724e3d57455abc2657540c498468bc468
--- /dev/null
+++ b/package_bgs/VuMeter.h
@@ -0,0 +1,52 @@
+/*
+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
+
+#include "IBGS.h"
+#include "VuMeter/TBackgroundVuMeter.h"
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class VuMeter : public IBGS
+    {
+    private:
+      TBackgroundVuMeter bgs;
+
+      IplImage *frame;
+      IplImage *gray;
+      IplImage *background;
+      IplImage *mask;
+
+      bool enableFilter;
+      int binSize;
+      double alpha;
+      double threshold;
+
+    public:
+      VuMeter();
+      ~VuMeter();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/av/TBackground.cpp b/package_bgs/VuMeter/TBackground.cpp
similarity index 77%
rename from package_bgs/av/TBackground.cpp
rename to package_bgs/VuMeter/TBackground.cpp
index d05bbd27db892c71b2e9788c25278813039763ae..4e93729fa376894c1406a94314e74e5b8a15cec1 100644
--- a/package_bgs/av/TBackground.cpp
+++ b/package_bgs/VuMeter/TBackground.cpp
@@ -72,19 +72,19 @@ bool TBackground::isInitOk(IplImage * pSource, IplImage *pBackground, IplImage *
 {
   bool bResult = true;
 
-  if(pSource == NULL || pSource->nChannels != 1 || pSource->depth != IPL_DEPTH_8U)
+  if (pSource == NULL || pSource->nChannels != 1 || pSource->depth != IPL_DEPTH_8U)
     bResult = false;
 
-  if(bResult)
+  if (bResult)
   {
     int nbl, nbc;
     nbl = pSource->height;
     nbc = pSource->width;
-    
-    if(pBackground == NULL || pBackground->width != nbc || pBackground->height != nbl || pBackground->imageSize != pSource->imageSize)
+
+    if (pBackground == NULL || pBackground->width != nbc || pBackground->height != nbl || pBackground->imageSize != pSource->imageSize)
       bResult = false;
-    
-    if(pMotionMask == NULL || pMotionMask->width != nbc || pMotionMask->height != nbl || pMotionMask->imageSize != pSource->imageSize)
+
+    if (pMotionMask == NULL || pMotionMask->width != nbc || pMotionMask->height != nbl || pMotionMask->imageSize != pSource->imageSize)
       bResult = false;
   }
 
@@ -100,7 +100,7 @@ IplImage *TBackground::CreateTestImg()
 {
   IplImage *pImage = cvCreateImage(cvSize(256, 256), IPL_DEPTH_8U, 3);
 
-  if(pImage != NULL)
+  if (pImage != NULL)
     cvSetZero(pImage);
 
   return pImage;
@@ -112,33 +112,33 @@ int TBackground::UpdateTest(IplImage *pSource, IplImage *pBackground, IplImage *
   CvScalar Color;
   unsigned char *ptr;
 
-  if(pTest == NULL || !isInitOk(pSource, pBackground, pSource))
+  if (pTest == NULL || !isInitOk(pSource, pBackground, pSource))
     nErr = 1;
 
-  if(!nErr)
+  if (!nErr)
   {
-    if(pTest->width != 256 || pTest->height != 256 || pTest->nChannels != 3)
+    if (pTest->width != 256 || pTest->height != 256 || pTest->nChannels != 3)
       nErr = 1;
 
-    if(nX < 0 || nX > pSource->width || nY < 0 || nY > pSource->height)
+    if (nX < 0 || nX > pSource->width || nY < 0 || nY > pSource->height)
       nErr = 1;
 
-    switch(nInd)
+    switch (nInd)
     {
-      case 0 : Color = cvScalar(128, 0, 0); break;
-      case 1 : Color = cvScalar(0, 128, 0); break;
-      case 2 : Color = cvScalar(0, 0, 128); break;
-      default : nErr = 1;
+    case 0: Color = cvScalar(128, 0, 0); break;
+    case 1: Color = cvScalar(0, 128, 0); break;
+    case 2: Color = cvScalar(0, 0, 128); break;
+    default: nErr = 1;
     }
   }
 
-  if(!nErr)
+  if (!nErr)
   {
     int l, c;
     // recupere l'indice de la colonne
     ptr = (unsigned char *)(pTest->imageData);
     c = *ptr;
-    
+
     // efface la colonne
     cvLine(pTest, cvPoint(c, 0), cvPoint(c, 255), cvScalar(0));
     *ptr += 1;
diff --git a/package_bgs/av/TBackground.h b/package_bgs/VuMeter/TBackground.h
similarity index 99%
rename from package_bgs/av/TBackground.h
rename to package_bgs/VuMeter/TBackground.h
index 463063f6e15046398dcfd5ea8867fd66bafedfd2..dbaaa6c3e672f7b3360bd7229a047e4e9351bab1 100644
--- a/package_bgs/av/TBackground.h
+++ b/package_bgs/VuMeter/TBackground.h
@@ -26,7 +26,6 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 #include <iostream>
 #include <opencv2/opencv.hpp>
 
-
 class TBackground
 {
 public:
diff --git a/package_bgs/av/TBackgroundVuMeter.cpp b/package_bgs/VuMeter/TBackgroundVuMeter.cpp
similarity index 74%
rename from package_bgs/av/TBackgroundVuMeter.cpp
rename to package_bgs/VuMeter/TBackgroundVuMeter.cpp
index 7fade7a5a2a10629df3d63798d347771749d50b2..c4fd7a7511fb08bd2604617a51aa775917d81a07 100644
--- a/package_bgs/av/TBackgroundVuMeter.cpp
+++ b/package_bgs/VuMeter/TBackgroundVuMeter.cpp
@@ -46,11 +46,11 @@ void TBackgroundVuMeter::Clear(void)
 {
   TBackground::Clear();
 
-  if(m_pHist != NULL)
+  if (m_pHist != NULL)
   {
-    for(int i = 0; i < m_nBinCount; ++i)
+    for (int i = 0; i < m_nBinCount; ++i)
     {
-      if(m_pHist[i] != NULL)
+      if (m_pHist[i] != NULL)
         cvReleaseImage(&m_pHist[i]);
     }
 
@@ -68,14 +68,14 @@ void TBackgroundVuMeter::Reset(void)
 
   TBackground::Reset();
 
-  if(m_pHist != NULL)
+  if (m_pHist != NULL)
   {
     //		fVal = (m_nBinCount != 0) ? (float)(1.0 / (double)m_nBinCount) : (float)0.0;
     fVal = 0.0;
 
-    for(int i = 0; i < m_nBinCount; ++i)
+    for (int i = 0; i < m_nBinCount; ++i)
     {
-      if(m_pHist[i] != NULL)
+      if (m_pHist[i] != NULL)
       {
         cvSetZero(m_pHist[i]);
         cvAddS(m_pHist[i], cvScalar(fVal), m_pHist[i]);
@@ -98,18 +98,18 @@ std::string TBackgroundVuMeter::GetParameterName(int nInd)
 
   nNb = TBackground::GetParameterCount();
 
-  if(nInd >= nNb)
+  if (nInd >= nNb)
   {
     nInd -= nNb;
 
-    switch(nInd)
+    switch (nInd)
     {
-    case 0 : csResult = "Bin size"; break;
-    case 1 : csResult = "Alpha"; break;
-    case 2 : csResult = "Threshold"; break;
+    case 0: csResult = "Bin size"; break;
+    case 1: csResult = "Alpha"; break;
+    case 2: csResult = "Threshold"; break;
     }
   }
-  else 
+  else
     csResult = TBackground::GetParameterName(nInd);
 
   return csResult;
@@ -122,22 +122,22 @@ std::string TBackgroundVuMeter::GetParameterValue(int nInd)
 
   nNb = TBackground::GetParameterCount();
 
-  if(nInd >= nNb)
+  if (nInd >= nNb)
   {
     nInd -= nNb;
 
     char buff[100];
-    
-    switch(nInd)
+
+    switch (nInd)
     {
-      case 0 : sprintf(buff, "%d", m_nBinSize); break;
-      case 1 : sprintf(buff, "%.3f", m_fAlpha); break;
-      case 2 : sprintf(buff, "%.2f", m_fThreshold); break;
+    case 0: sprintf(buff, "%d", m_nBinSize); break;
+    case 1: sprintf(buff, "%.3f", m_fAlpha); break;
+    case 2: sprintf(buff, "%.2f", m_fThreshold); break;
     }
 
     csResult = buff;
   }
-  else 
+  else
     csResult = TBackground::GetParameterValue(nInd);
 
   return csResult;
@@ -151,19 +151,19 @@ int TBackgroundVuMeter::SetParameterValue(int nInd, std::string csNew)
 
   nNb = TBackground::GetParameterCount();
 
-  if(nInd >= nNb)
+  if (nInd >= nNb)
   {
     nInd -= nNb;
 
-    switch(nInd)
+    switch (nInd)
     {
-      case 0 : SetBinSize(atoi(csNew.c_str())); break;
-      case 1 : SetAlpha(atof(csNew.c_str())); break;
-      case 2 : SetThreshold(atof(csNew.c_str())); break;
-      default : nErr = 1;
+    case 0: SetBinSize(atoi(csNew.c_str())); break;
+    case 1: SetAlpha(atof(csNew.c_str())); break;
+    case 2: SetThreshold(atof(csNew.c_str())); break;
+    default: nErr = 1;
     }
   }
-  else 
+  else
     nErr = TBackground::SetParameterValue(nInd, csNew);
 
   return nErr;
@@ -178,42 +178,42 @@ int TBackgroundVuMeter::Init(IplImage * pSource)
 
   nErr = TBackground::Init(pSource);
 
-  if(pSource == NULL)
+  if (pSource == NULL)
     nErr = 1;
 
   // calcul le nb de bin
-  if(!nErr)
+  if (!nErr)
   {
     nbl = pSource->height;
     nbc = pSource->width;
     m_nBinCount = (m_nBinSize != 0) ? 256 / m_nBinSize : 0;
 
-    if(m_nBinCount <= 0 || m_nBinCount > 256)
+    if (m_nBinCount <= 0 || m_nBinCount > 256)
       nErr = 1;
   }
 
   // creation du tableau de pointeur
-  if(!nErr)
+  if (!nErr)
   {
     m_pHist = new IplImage *[m_nBinCount];
 
-    if(m_pHist == NULL)
+    if (m_pHist == NULL)
       nErr = 1;
   }
 
   // creation des images
-  if(!nErr)
+  if (!nErr)
   {
-    for(int i = 0; i < m_nBinCount; ++i)
+    for (int i = 0; i < m_nBinCount; ++i)
     {
       m_pHist[i] = cvCreateImage(cvSize(nbc, nbl), IPL_DEPTH_32F, 1);
 
-      if(m_pHist[i] == NULL)
+      if (m_pHist[i] == NULL)
         nErr = 1;
     }
   }
 
-  if(!nErr) 
+  if (!nErr)
     Reset();
   else
     Clear();
@@ -228,28 +228,28 @@ bool TBackgroundVuMeter::isInitOk(IplImage * pSource, IplImage *pBackground, Ipl
 
   bResult = TBackground::isInitOk(pSource, pBackground, pMotionMask);
 
-  if(pSource == NULL)
+  if (pSource == NULL)
     bResult = false;
 
-  if(m_nBinSize == 0)
+  if (m_nBinSize == 0)
     bResult = false;
 
-  if(bResult)
+  if (bResult)
   {
     i = (m_nBinSize != 0) ? 256 / m_nBinSize : 0;
 
-    if(i != m_nBinCount || m_pHist == NULL)
+    if (i != m_nBinCount || m_pHist == NULL)
       bResult = false;
   }
 
-  if(bResult)
+  if (bResult)
   {
     int nbl = pSource->height;
     int nbc = pSource->width;
 
-    for(i = 0; i < m_nBinCount; ++i)
+    for (i = 0; i < m_nBinCount; ++i)
     {
-      if(m_pHist[i] == NULL || m_pHist[i]->width != nbc || m_pHist[i]->height != nbl)
+      if (m_pHist[i] == NULL || m_pHist[i]->width != nbc || m_pHist[i]->height != nbl)
         bResult = false;
     }
   }
@@ -263,10 +263,10 @@ int TBackgroundVuMeter::UpdateBackground(IplImage *pSource, IplImage *pBackgroun
   unsigned char *ptrs, *ptrb, *ptrm;
   float *ptr1, *ptr2;
 
-  if(!isInitOk(pSource, pBackground, pMotionMask))
+  if (!isInitOk(pSource, pBackground, pMotionMask))
     nErr = Init(pSource);
-  
-  if(!nErr)
+
+  if (!nErr)
   {
     m_nCount++;
     int nbc = pSource->width;
@@ -274,23 +274,23 @@ int TBackgroundVuMeter::UpdateBackground(IplImage *pSource, IplImage *pBackgroun
     unsigned char v = m_nBinSize;
 
     // multiplie tout par alpha
-    for(int i = 0; i < m_nBinCount; ++i)
+    for (int i = 0; i < m_nBinCount; ++i)
       cvConvertScale(m_pHist[i], m_pHist[i], m_fAlpha, 0.0);
 
-    for(int l = 0; l < nbl; ++l)
+    for (int l = 0; l < nbl; ++l)
     {
       ptrs = (unsigned char *)(pSource->imageData + pSource->widthStep * l);
       ptrm = (unsigned char *)(pMotionMask->imageData + pMotionMask->widthStep * l);
       ptrb = (unsigned char *)(pBackground->imageData + pBackground->widthStep * l);
 
-      for(int c = 0; c < nbc; ++c, ptrs++, ptrb++, ptrm++)
+      for (int c = 0; c < nbc; ++c, ptrs++, ptrb++, ptrm++)
       {
-        // recherche le bin � augmenter
+        // recherche le bin à augmenter
         int i = *ptrs / v;
-        
-        if(i < 0 || i >= m_nBinCount)
+
+        if (i < 0 || i >= m_nBinCount)
           i = 0;
-        
+
         ptr1 = (float *)(m_pHist[i]->imageData + m_pHist[i]->widthStep * l);
         ptr1 += c;
 
@@ -299,19 +299,19 @@ int TBackgroundVuMeter::UpdateBackground(IplImage *pSource, IplImage *pBackgroun
 
         // recherche le bin du fond actuel
         i = *ptrb / v;
-        
-        if(i < 0 || i >= m_nBinCount)
+
+        if (i < 0 || i >= m_nBinCount)
           i = 0;
-        
+
         ptr2 = (float *)(m_pHist[i]->imageData + m_pHist[i]->widthStep * l);
         ptr2 += c;
 
-        if(*ptr2 < *ptr1)
+        if (*ptr2 < *ptr1)
           *ptrb = *ptrs;
       }
     }
 
-    if(m_nCount < 5)
+    if (m_nCount < 5)
       cvSetZero(pMotionMask);
   }
 
@@ -322,10 +322,10 @@ IplImage *TBackgroundVuMeter::CreateTestImg()
 {
   IplImage *pImage = NULL;
 
-  if(m_nBinCount > 0)
+  if (m_nBinCount > 0)
     pImage = cvCreateImage(cvSize(m_nBinCount, 100), IPL_DEPTH_8U, 3);
 
-  if(pImage != NULL)
+  if (pImage != NULL)
     cvSetZero(pImage);
 
   return pImage;
@@ -336,31 +336,31 @@ int TBackgroundVuMeter::UpdateTest(IplImage *pSource, IplImage *pBackground, Ipl
   int nErr = 0;
   float *ptrf;
 
-  if(pTest == NULL || !isInitOk(pSource, pBackground, pSource)) 
+  if (pTest == NULL || !isInitOk(pSource, pBackground, pSource))
     nErr = 1;
 
-  if(!nErr)
+  if (!nErr)
   {
     int nbl = pTest->height;
     int nbc = pTest->width;
 
-    if(nbl != 100 || nbc != m_nBinCount) 
+    if (nbl != 100 || nbc != m_nBinCount)
       nErr = 1;
 
-    if(nX < 0 || nX >= pSource->width || nY < 0 || nY >= pSource->height)
+    if (nX < 0 || nX >= pSource->width || nY < 0 || nY >= pSource->height)
       nErr = 1;
   }
 
-  if(!nErr)
+  if (!nErr)
   {
     cvSetZero(pTest);
 
-    for(int i = 0; i < m_nBinCount; ++i)
+    for (int i = 0; i < m_nBinCount; ++i)
     {
       ptrf = (float *)(m_pHist[i]->imageData + m_pHist[i]->widthStep * nY);
       ptrf += nX;
 
-      if(*ptrf >= 0 || *ptrf <= 1.0) {
+      if (*ptrf >= 0 || *ptrf <= 1.0) {
         cvLine(pTest, cvPoint(i, 100), cvPoint(i, (int)(100.0 * (1.0 - *ptrf))), cvScalar(0, 255, 0));
       }
     }
diff --git a/package_bgs/av/TBackgroundVuMeter.h b/package_bgs/VuMeter/TBackgroundVuMeter.h
similarity index 95%
rename from package_bgs/av/TBackgroundVuMeter.h
rename to package_bgs/VuMeter/TBackgroundVuMeter.h
index 1a19324f08c8d20b4bb2fd972a9920e73b2adae8..36fe0d0b99ad0b8da8c4696cd931ecec1713bad6 100644
--- a/package_bgs/av/TBackgroundVuMeter.h
+++ b/package_bgs/VuMeter/TBackgroundVuMeter.h
@@ -44,13 +44,13 @@ public:
   virtual std::string GetParameterValue(int nInd);
   virtual int SetParameterValue(int nInd, std::string csNew);
 
-  inline void SetBinSize(int nNew) { m_nBinSize = (nNew > 0 && nNew < 255) ?  nNew : 8; }
+  inline void SetBinSize(int nNew) { m_nBinSize = (nNew > 0 && nNew < 255) ? nNew : 8; }
   inline double GetBinSize() { return m_nBinSize; }
 
-  inline void SetAlpha(double fNew) { m_fAlpha = (fNew > 0.0 && fNew < 1.0) ?  fNew : 0.995; }
+  inline void SetAlpha(double fNew) { m_fAlpha = (fNew > 0.0 && fNew < 1.0) ? fNew : 0.995; }
   inline double GetAlpha() { return m_fAlpha; }
 
-  inline void SetThreshold(double fNew) { m_fThreshold = (fNew > 0.0 && fNew < 1.0) ?  fNew : 0.03; }
+  inline void SetThreshold(double fNew) { m_fThreshold = (fNew > 0.0 && fNew < 1.0) ? fNew : 0.03; }
   inline double GetThreshold() { return m_fThreshold; }
 
 protected:
diff --git a/package_bgs/WeightedMovingMeanBGS.cpp b/package_bgs/WeightedMovingMean.cpp
similarity index 51%
rename from package_bgs/WeightedMovingMeanBGS.cpp
rename to package_bgs/WeightedMovingMean.cpp
index 841c467393c3012aff42eac1a36b44321b024b80..3a427fc0e6926b721f809fca66a86b05841a29fd 100644
--- a/package_bgs/WeightedMovingMeanBGS.cpp
+++ b/package_bgs/WeightedMovingMean.cpp
@@ -14,77 +14,72 @@ 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 "WeightedMovingMeanBGS.h"
+#include "WeightedMovingMean.h"
 
-WeightedMovingMeanBGS::WeightedMovingMeanBGS() : firstTime(true), enableWeight(true), enableThreshold(true), threshold(15), showOutput(true), showBackground(false)
+using namespace bgslibrary::algorithms;
+
+WeightedMovingMean::WeightedMovingMean() :
+  enableWeight(true), enableThreshold(true), threshold(15)
 {
-  std::cout << "WeightedMovingMeanBGS()" << std::endl;
+  std::cout << "WeightedMovingMean()" << std::endl;
+  setup("./config/WeightedMovingMean.xml");
 }
 
-WeightedMovingMeanBGS::~WeightedMovingMeanBGS()
+WeightedMovingMean::~WeightedMovingMean()
 {
-  std::cout << "~WeightedMovingMeanBGS()" << std::endl;
+  std::cout << "~WeightedMovingMean()" << std::endl;
 }
 
-void WeightedMovingMeanBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+void WeightedMovingMean::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if(firstTime)
-    saveConfig();
+  init(img_input, img_output, img_bgmodel);
 
-  if(img_input_prev_1.empty())
-  {
+  if (img_input_prev_1.empty()) {
     img_input.copyTo(img_input_prev_1);
     return;
   }
 
-  if(img_input_prev_2.empty())
-  {
+  if (img_input_prev_2.empty()) {
     img_input_prev_1.copyTo(img_input_prev_2);
     img_input.copyTo(img_input_prev_1);
     return;
   }
-  
+
   cv::Mat img_input_f(img_input.size(), CV_32F);
-  img_input.convertTo(img_input_f, CV_32F, 1./255.);
+  img_input.convertTo(img_input_f, CV_32F, 1. / 255.);
 
   cv::Mat img_input_prev_1_f(img_input.size(), CV_32F);
-  img_input_prev_1.convertTo(img_input_prev_1_f, CV_32F, 1./255.);
+  img_input_prev_1.convertTo(img_input_prev_1_f, CV_32F, 1. / 255.);
 
   cv::Mat img_input_prev_2_f(img_input.size(), CV_32F);
-  img_input_prev_2.convertTo(img_input_prev_2_f, CV_32F, 1./255.);
+  img_input_prev_2.convertTo(img_input_prev_2_f, CV_32F, 1. / 255.);
 
   cv::Mat img_background_f(img_input.size(), CV_32F);
-  
-  if(enableWeight)
+
+  if (enableWeight)
     img_background_f = ((img_input_f * 0.5) + (img_input_prev_1_f * 0.3) + (img_input_prev_2_f * 0.2));
   else
-    img_background_f = ((img_input_f) + (img_input_prev_1_f) + (img_input_prev_2_f)) / 3.0;
-
-  cv::Mat img_background(img_background_f.size(), CV_8U);
+    img_background_f = ((img_input_f)+(img_input_prev_1_f)+(img_input_prev_2_f)) / 3.0;
 
   double minVal, maxVal;
   minVal = 0.; maxVal = 1.;
-  img_background_f.convertTo(img_background, CV_8U, 255.0/(maxVal - minVal), -minVal);
-  
-  if(showBackground)
-    cv::imshow("W Moving Mean BG Model", img_background);
+  img_background_f.convertTo(img_background, CV_8U, 255.0 / (maxVal - minVal), -minVal);
 
-  cv::Mat img_foreground;
   cv::absdiff(img_input, img_background, img_foreground);
 
-  if(img_foreground.channels() == 3)
+  if (img_foreground.channels() == 3)
     cv::cvtColor(img_foreground, img_foreground, CV_BGR2GRAY);
 
-  if(enableThreshold)
+  if (enableThreshold)
     cv::threshold(img_foreground, img_foreground, threshold, 255, cv::THRESH_BINARY);
 
-  if(showOutput)
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+  {
     cv::imshow("W Moving Mean FG Mask", img_foreground);
+    cv::imshow("W Moving Mean BG Model", img_background);
+  }
+#endif
 
   img_foreground.copyTo(img_output);
   img_background.copyTo(img_bgmodel);
@@ -95,28 +90,26 @@ void WeightedMovingMeanBGS::process(const cv::Mat &img_input, cv::Mat &img_outpu
   firstTime = false;
 }
 
-void WeightedMovingMeanBGS::saveConfig()
+void WeightedMovingMean::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/WeightedMovingMeanBGS.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteInt(fs, "enableWeight", enableWeight);
   cvWriteInt(fs, "enableThreshold", enableThreshold);
   cvWriteInt(fs, "threshold", threshold);
   cvWriteInt(fs, "showOutput", showOutput);
-  cvWriteInt(fs, "showBackground", showBackground);
 
   cvReleaseFileStorage(&fs);
 }
 
-void WeightedMovingMeanBGS::loadConfig()
+void WeightedMovingMean::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/WeightedMovingMeanBGS.xml", 0, CV_STORAGE_READ);
-  
-  enableWeight = cvReadIntByName(fs, 0, "enableWeight", true);
-  enableThreshold = cvReadIntByName(fs, 0, "enableThreshold", true);
-  threshold = cvReadIntByName(fs, 0, "threshold", 15);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
-  showBackground = cvReadIntByName(fs, 0, "showBackground", false);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  enableWeight = cvReadIntByName(fs, nullptr, "enableWeight", true);
+  enableThreshold = cvReadIntByName(fs, nullptr, "enableThreshold", true);
+  threshold = cvReadIntByName(fs, nullptr, "threshold", 15);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
 
   cvReleaseFileStorage(&fs);
-}
\ No newline at end of file
+}
diff --git a/package_bgs/WeightedMovingMean.h b/package_bgs/WeightedMovingMean.h
new file mode 100644
index 0000000000000000000000000000000000000000..4a1a3c5fddb5c68c5c4eb8025f2427b143ff6b3a
--- /dev/null
+++ b/package_bgs/WeightedMovingMean.h
@@ -0,0 +1,45 @@
+/*
+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
+
+#include "IBGS.h"
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class WeightedMovingMean : public IBGS
+    {
+    private:
+      cv::Mat img_input_prev_1;
+      cv::Mat img_input_prev_2;
+      bool enableWeight;
+      bool enableThreshold;
+      int threshold;
+
+    public:
+      WeightedMovingMean();
+      ~WeightedMovingMean();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/WeightedMovingVarianceBGS.cpp b/package_bgs/WeightedMovingVariance.cpp
similarity index 62%
rename from package_bgs/WeightedMovingVarianceBGS.cpp
rename to package_bgs/WeightedMovingVariance.cpp
index 0317a3cfe24438995a6f9a538140539e401ce0e9..2855a92629094c5e6314b351181d9d7cb806032d 100644
--- a/package_bgs/WeightedMovingVarianceBGS.cpp
+++ b/package_bgs/WeightedMovingVariance.cpp
@@ -14,68 +14,61 @@ 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 "WeightedMovingVarianceBGS.h"
+#include "WeightedMovingVariance.h"
 
-WeightedMovingVarianceBGS::WeightedMovingVarianceBGS() : firstTime(true), enableWeight(true), 
-  enableThreshold(true), threshold(15), showOutput(true)
+using namespace bgslibrary::algorithms;
+
+WeightedMovingVariance::WeightedMovingVariance() :
+  enableWeight(true), enableThreshold(true), threshold(15)
 {
-  std::cout << "WeightedMovingVarianceBGS()" << std::endl;
+  std::cout << "WeightedMovingVariance()" << std::endl;
+  setup("./config/WeightedMovingVariance.xml");
 }
 
-WeightedMovingVarianceBGS::~WeightedMovingVarianceBGS()
+WeightedMovingVariance::~WeightedMovingVariance()
 {
-  std::cout << "~WeightedMovingVarianceBGS()" << std::endl;
+  std::cout << "~WeightedMovingVariance()" << std::endl;
 }
 
-void WeightedMovingVarianceBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+void WeightedMovingVariance::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
-  if(img_input.empty())
-    return;
-
-  loadConfig();
+  init(img_input, img_output, img_bgmodel);
 
-  if(firstTime)
-    saveConfig();
-
-  if(img_input_prev_1.empty())
-  {
+  if (img_input_prev_1.empty()) {
     img_input.copyTo(img_input_prev_1);
     return;
   }
 
-  if(img_input_prev_2.empty())
-  {
+  if (img_input_prev_2.empty()) {
     img_input_prev_1.copyTo(img_input_prev_2);
     img_input.copyTo(img_input_prev_1);
     return;
   }
 
   cv::Mat img_input_f(img_input.size(), CV_32F);
-  img_input.convertTo(img_input_f, CV_32F, 1./255.);
+  img_input.convertTo(img_input_f, CV_32F, 1. / 255.);
 
   cv::Mat img_input_prev_1_f(img_input.size(), CV_32F);
-  img_input_prev_1.convertTo(img_input_prev_1_f, CV_32F, 1./255.);
+  img_input_prev_1.convertTo(img_input_prev_1_f, CV_32F, 1. / 255.);
 
   cv::Mat img_input_prev_2_f(img_input.size(), CV_32F);
-  img_input_prev_2.convertTo(img_input_prev_2_f, CV_32F, 1./255.);
-
-  cv::Mat img_foreground;
+  img_input_prev_2.convertTo(img_input_prev_2_f, CV_32F, 1. / 255.);
 
   // Weighted mean
   cv::Mat img_mean_f(img_input.size(), CV_32F);
-  
-  if(enableWeight)
+
+  if (enableWeight)
     img_mean_f = ((img_input_f * 0.5) + (img_input_prev_1_f * 0.3) + (img_input_prev_2_f * 0.2));
   else
     img_mean_f = ((img_input_f * 0.3) + (img_input_prev_1_f * 0.3) + (img_input_prev_2_f * 0.3));
-  
+
   // Weighted variance
   cv::Mat img_1_f(img_input.size(), CV_32F);
   cv::Mat img_2_f(img_input.size(), CV_32F);
   cv::Mat img_3_f(img_input.size(), CV_32F);
   cv::Mat img_4_f(img_input.size(), CV_32F);
 
-  if(enableWeight)
+  if (enableWeight)
   {
     img_1_f = computeWeightedVariance(img_input_f, img_mean_f, 0.5);
     img_2_f = computeWeightedVariance(img_input_prev_1_f, img_mean_f, 0.3);
@@ -89,73 +82,71 @@ void WeightedMovingVarianceBGS::process(const cv::Mat &img_input, cv::Mat &img_o
     img_3_f = computeWeightedVariance(img_input_prev_2_f, img_mean_f, 0.3);
     img_4_f = (img_1_f + img_2_f + img_3_f);
   }
-  
+
   // Standard deviation
   cv::Mat img_sqrt_f(img_input.size(), CV_32F);
   cv::sqrt(img_4_f, img_sqrt_f);
   cv::Mat img_sqrt(img_input.size(), CV_8U);
   double minVal, maxVal;
   minVal = 0.; maxVal = 1.;
-  img_sqrt_f.convertTo(img_sqrt, CV_8U, 255.0/(maxVal - minVal), -minVal);
+  img_sqrt_f.convertTo(img_sqrt, CV_8U, 255.0 / (maxVal - minVal), -minVal);
   img_sqrt.copyTo(img_foreground);
 
-  if(img_foreground.channels() == 3)
+  if (img_foreground.channels() == 3)
     cv::cvtColor(img_foreground, img_foreground, CV_BGR2GRAY);
 
-  if(enableThreshold)
+  if (enableThreshold)
     cv::threshold(img_foreground, img_foreground, threshold, 255, cv::THRESH_BINARY);
 
-  if(showOutput)
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
     cv::imshow("W Moving Variance", img_foreground);
+#endif
 
   img_foreground.copyTo(img_output);
 
+  img_background = cv::Mat::zeros(img_input.size(), img_input.type());
+  img_background.copyTo(img_bgmodel);
+
   img_input_prev_1.copyTo(img_input_prev_2);
   img_input.copyTo(img_input_prev_1);
-  
-  firstTime = false;
-}
 
-//unused
-cv::Mat WeightedMovingVarianceBGS::computeWeightedMean(const std::vector<cv::Mat> &v_img_input_f, const std::vector<double> &weights)
-{
-  cv::Mat img;
-  return img;
+  firstTime = false;
 }
 
-cv::Mat WeightedMovingVarianceBGS::computeWeightedVariance(const cv::Mat &img_input_f, const cv::Mat &img_mean_f, const double weight)
+cv::Mat WeightedMovingVariance::computeWeightedVariance(const cv::Mat &img_input_f, const cv::Mat &img_mean_f, const double weight)
 {
   //ERROR in return (weight * ((cv::abs(img_input_f - img_mean_f))^2.));
-  
+
   cv::Mat img_f_absdiff(img_input_f.size(), CV_32F);
   cv::absdiff(img_input_f, img_mean_f, img_f_absdiff);
   cv::Mat img_f_pow(img_input_f.size(), CV_32F);
   cv::pow(img_f_absdiff, 2.0, img_f_pow);
   cv::Mat img_f = weight * img_f_pow;
-  
+
   return img_f;
 }
 
-void WeightedMovingVarianceBGS::saveConfig()
+void WeightedMovingVariance::saveConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/WeightedMovingVarianceBGS.xml", 0, CV_STORAGE_WRITE);
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
 
   cvWriteInt(fs, "enableWeight", enableWeight);
   cvWriteInt(fs, "enableThreshold", enableThreshold);
   cvWriteInt(fs, "threshold", threshold);
   cvWriteInt(fs, "showOutput", showOutput);
-  
+
   cvReleaseFileStorage(&fs);
 }
 
-void WeightedMovingVarianceBGS::loadConfig()
+void WeightedMovingVariance::loadConfig()
 {
-  CvFileStorage* fs = cvOpenFileStorage("./config/WeightedMovingVarianceBGS.xml", 0, CV_STORAGE_READ);
-  
-  enableWeight = cvReadIntByName(fs, 0, "enableWeight", true);
-  enableThreshold = cvReadIntByName(fs, 0, "enableThreshold", true);
-  threshold = cvReadIntByName(fs, 0, "threshold", 15);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
-  
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  enableWeight = cvReadIntByName(fs, nullptr, "enableWeight", true);
+  enableThreshold = cvReadIntByName(fs, nullptr, "enableThreshold", true);
+  threshold = cvReadIntByName(fs, nullptr, "threshold", 15);
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);
+
   cvReleaseFileStorage(&fs);
 }
diff --git a/package_bgs/WeightedMovingVariance.h b/package_bgs/WeightedMovingVariance.h
new file mode 100644
index 0000000000000000000000000000000000000000..79198b4a9e2fadd0c21f701e0b45e67a9b3dc488
--- /dev/null
+++ b/package_bgs/WeightedMovingVariance.h
@@ -0,0 +1,46 @@
+/*
+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
+
+#include "IBGS.h"
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class WeightedMovingVariance : public IBGS
+    {
+    private:
+      cv::Mat img_input_prev_1;
+      cv::Mat img_input_prev_2;
+      bool enableWeight;
+      bool enableThreshold;
+      int threshold;
+
+    public:
+      WeightedMovingVariance();
+      ~WeightedMovingVariance();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+      cv::Mat computeWeightedVariance(const cv::Mat &img_input_f, const cv::Mat &img_mean_f, const double weight);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/WeightedMovingVarianceBGS.h b/package_bgs/WeightedMovingVarianceBGS.h
deleted file mode 100644
index 88c2ec821399aea86f6895e4c23263c3bcb996bb..0000000000000000000000000000000000000000
--- a/package_bgs/WeightedMovingVarianceBGS.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-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
-
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "IBGS.h"
-
-class WeightedMovingVarianceBGS : public IBGS
-{
-private:
-  bool firstTime;
-  cv::Mat img_input_prev_1;
-  cv::Mat img_input_prev_2;
-  bool enableWeight;
-  bool enableThreshold;
-  int threshold;
-  bool showOutput;
-
-public:
-  WeightedMovingVarianceBGS();
-  ~WeightedMovingVarianceBGS();
-
-  cv::Mat computeWeightedMean(const std::vector<cv::Mat> &v_img_input_f, const std::vector<double> &weights);
-  cv::Mat computeWeightedVariance(const cv::Mat &img_input_f, const cv::Mat &img_mean_f, const double weight);
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
diff --git a/package_bgs/_template_/Amber.cpp b/package_bgs/_template_/Amber.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2e29ac07369b7a84c16b6bbab0e03cdcf23344d2
--- /dev/null
+++ b/package_bgs/_template_/Amber.cpp
@@ -0,0 +1,112 @@
+/*
+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 "Amber.h"
+
+using namespace bgslibrary::algorithms;
+
+Amber::Amber() : model(nullptr)
+{
+  std::cout << "Amber()" << std::endl;
+  /* Initialization of the Amber model */
+  model = libamberModelNew();
+  setup("./config/Amber.xml");
+}
+
+Amber::~Amber()
+{
+  std::cout << "~Amber()" << std::endl;
+  libamberModelFree(model);
+}
+
+void Amber::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+{
+  init(img_input, img_output, img_bgmodel);
+
+  if (img_input.empty())
+    return;
+
+  // Start the initialization
+  unsigned int width = img_input.cols;
+  unsigned int height = img_input.rows;
+
+  if (img_input.channels() != 3)
+  {
+    std::cout << "Only works for 3 channels images. Sorry for that" << std::endl;
+    return;
+  }
+
+  unsigned int stride = width * 3;
+  unsigned char* image = static_cast<unsigned char*>(img_input.data);
+
+  if (firstTime)
+  {
+    /* Create a buffer for the output image */
+    //img_output = Mat(img_input.rows, img_input.cols, CV_8UC1);
+
+    /* Sets default model values */
+    // libamberModelSetNumberOfSamples(model, nbSamples);
+    // libamberModelSetMatchingThreshold(model, matchingThreshold);
+    // libamberModelSetMatchingNumber(model, matchingNumber);
+    // libamberModelSetUpdateFactor(model, init_subsamplingFactor);
+    // libamberModelPrintParameters(model);
+
+    /* Initiliazes the Amber model */
+    libamberModelAllocInit_8u_C3R(model, image, width, height);
+  }
+
+  /* Create temporary buffers */
+  unsigned char* output_segmentationMap = static_cast<unsigned char*>(calloc(width * height, sizeof(unsigned char)));
+  libamberGetSegmentation_8u_C3R(model, image, output_segmentationMap);
+
+  unsigned char* oBuffer = static_cast<unsigned char*>(img_output.data);
+  unsigned char* tmpSegmentationMap = output_segmentationMap;
+
+  for (int i = 0; i < width * height; i++)
+  {
+    *oBuffer = *tmpSegmentationMap;
+
+    ++oBuffer;
+    ++tmpSegmentationMap;
+  }
+
+#ifndef MEX_COMPILE_FLAG
+  if (showOutput)
+    imshow("Amber", img_output);
+#endif
+
+  firstTime = false;
+  free(output_segmentationMap);
+}
+
+void Amber::saveConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);
+
+  cvWriteInt(fs, "showOutput", showOutput);
+
+  cvReleaseFileStorage(&fs);
+}
+
+void Amber::loadConfig()
+{
+  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);
+
+  showOutput = cvReadIntByName(fs, nullptr, "showOutput", false);
+
+  cvReleaseFileStorage(&fs);
+}
diff --git a/package_bgs/_template_/Amber.h b/package_bgs/_template_/Amber.h
new file mode 100644
index 0000000000000000000000000000000000000000..37f0f8deca5fc5c0d32ce8614bd0820be1f3dfd2
--- /dev/null
+++ b/package_bgs/_template_/Amber.h
@@ -0,0 +1,45 @@
+/*
+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
+
+#include <math.h>
+#include <sys/types.h>
+
+#include "../IBGS.h"
+#include "amber/amber.h"
+
+namespace bgslibrary
+{
+  namespace algorithms
+  {
+    class Amber : public IBGS
+    {
+    private:
+      amberModel* model;
+
+    public:
+      Amber();
+      ~Amber();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig();
+      void loadConfig();
+    };
+  }
+}
diff --git a/package_bgs/_template_/MyBGS.cpp b/package_bgs/_template_/MyBGS.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..10d55884f8d33c9980d71f653e7c3b26227e7f8d
--- /dev/null
+++ b/package_bgs/_template_/MyBGS.cpp
@@ -0,0 +1,44 @@
+/*
+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 "MyBGS.h"
+
+using namespace bgslibrary::algorithms;
+
+MyBGS::MyBGS() {}
+MyBGS::~MyBGS() {}
+
+void MyBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
+{
+  if (img_input.empty())
+    return;
+
+  if (img_previous.empty())
+    img_input.copyTo(img_previous);
+
+  cv::Mat img_foreground;
+  cv::absdiff(img_previous, img_input, img_foreground);
+
+  if (img_foreground.channels() == 3)
+    cv::cvtColor(img_foreground, img_foreground, CV_BGR2GRAY);
+
+  cv::threshold(img_foreground, img_foreground, 15, 255, cv::THRESH_BINARY);
+
+  img_foreground.copyTo(img_output);
+  img_previous.copyTo(img_bgmodel);
+
+  img_input.copyTo(img_previous);
+}
diff --git a/package_bgs/ck/LbpMrf.h b/package_bgs/_template_/MyBGS.h
similarity index 65%
rename from package_bgs/ck/LbpMrf.h
rename to package_bgs/_template_/MyBGS.h
index 6fd72673a16d0f649b58d08b9f16b6ca5b786c2d..dea2a2fa3bbc2163a9afc822351f8c2f9bcbfb3e 100644
--- a/package_bgs/ck/LbpMrf.h
+++ b/package_bgs/_template_/MyBGS.h
@@ -16,29 +16,28 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
 
-#include <iostream>
 #include <opencv2/opencv.hpp>
 
 #include "../IBGS.h"
 
-class MotionDetection;
-
-class LbpMrf : public IBGS
+namespace bgslibrary
 {
-private:
-  bool firstTime;
-  MotionDetection* Detector;
-  cv::Mat img_foreground;
-  cv::Mat img_segmentation;
-  bool showOutput;
-
-public:
-  LbpMrf();
-  ~LbpMrf();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
+  namespace algorithms
+  {
+    class MyBGS : public IBGS
+    {
+    private:
+      cv::Mat img_previous;
+
+    public:
+      MyBGS();
+      ~MyBGS();
+
+      void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
+
+    private:
+      void saveConfig() {}
+      void loadConfig() {}
+    };
+  }
+}
diff --git a/package_bgs/_template_/amber/amber.c b/package_bgs/_template_/amber/amber.c
new file mode 100644
index 0000000000000000000000000000000000000000..00bdfb14a5006b825448657d8f565469eaa6dc93
--- /dev/null
+++ b/package_bgs/_template_/amber/amber.c
@@ -0,0 +1,80 @@
+/*
+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 "amber.h"
+
+#define COLOR_BACKGROUND   0
+#define COLOR_FOREGROUND 255
+
+amberModel* libamberModelNew()
+{
+  /* model structure alloc */
+  amberModel* model = NULL;
+  model = (amberModel*)calloc(1, sizeof(amberModel));
+  assert(model != NULL);
+
+  /* default parameters values */
+  model->height = 0;
+
+  return(model);
+}
+
+// --------------------------------------------------
+int32_t libamberModelAllocInit_8u_C3R(amberModel* model,
+  const uint8_t *image_data,
+  const uint32_t width,
+  const uint32_t height)
+{
+
+  /* basic checks */
+  assert((image_data != NULL) && (model != NULL));
+  assert((model->width > 0) && (model->height > 0));
+
+  /* finish model alloc - parameters values cannot be changed anymore */
+  model->width = width;
+  model->height = height;
+
+  return(0);
+}
+
+// --------------------------------------------------
+int32_t libamberGetSegmentation_8u_C3R(amberModel* model,
+  const uint8_t *image_data,
+  uint8_t *segmentation_map)
+{
+  /* basic checks */
+  assert((image_data != NULL) && (model != NULL) && (segmentation_map != NULL));
+  assert((model->width > 0) && (model->height > 0));
+
+  return(0);
+}
+
+// --------------------------------------------------
+int32_t libamberModelFree(amberModel* model)
+{
+  if (model == NULL)
+    return(-1);
+
+  free(model);
+
+  return(0);
+}
+
+/* For compilation with g++ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/package_bgs/_template_/amber/amber.h b/package_bgs/_template_/amber/amber.h
new file mode 100644
index 0000000000000000000000000000000000000000..02061795f1ef211b8907c3d16f43123e6099d380
--- /dev/null
+++ b/package_bgs/_template_/amber/amber.h
@@ -0,0 +1,64 @@
+/*
+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
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+#define COLOR_BACKGROUND   0
+#define COLOR_FOREGROUND 255
+
+/* For compilation with g++ */
+#ifdef __cplusplus
+extern "C"
+{
+#endif 
+  /* end of addition for compilation with g++ */
+
+#ifndef _STDINT_H  
+// This is used to make it compatible for cross-compilation
+  typedef unsigned char uint8_t;
+  typedef int int32_t;
+  typedef unsigned int uint32_t;
+#endif // _STDINT_H 
+
+  typedef struct {
+    uint32_t width;
+    uint32_t height;
+  } amberModel;
+
+  /** Allocation of a new data structure where the background model
+     will be stored */
+  amberModel* libamberModelNew();
+
+  int32_t libamberModelAllocInit_8u_C3R(amberModel* model,
+    const uint8_t *image_data,
+    const uint32_t width,
+    const uint32_t height);
+
+  int32_t libamberGetSegmentation_8u_C3R(amberModel* model,
+    const uint8_t *image_data,
+    uint8_t *segmentation_map);
+
+
+  int32_t libamberModelFree(amberModel* model);
+
+  /* For compilation with g++ */
+#ifdef __cplusplus
+}
+#endif 
diff --git a/package_bgs/ae/KDE.h b/package_bgs/ae/KDE.h
deleted file mode 100644
index adcc659f1a0bc93f00962eb4039dcb3a751e0724..0000000000000000000000000000000000000000
--- a/package_bgs/ae/KDE.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-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
-
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "NPBGSubtractor.h"
-#include "../IBGS.h"
-
-class KDE : public IBGS
-{
-private:
-  NPBGSubtractor *p;
-  int rows;
-  int cols;
-  int color_channels;
-  int SequenceLength;
-  int TimeWindowSize;
-  int SDEstimationFlag;
-  int lUseColorRatiosFlag;
-  double th;
-  double alpha;
-  int framesToLearn;
-  int frameNumber;
-  bool firstTime;
-  bool showOutput;
-
-  cv::Mat img_foreground;
-  unsigned char *FGImage;
-  unsigned char *FilteredFGImage;
-  unsigned char **DisplayBuffers;
-
-public:
-  KDE();
-  ~KDE();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-  
-private:
-  void saveConfig();
-  void loadConfig();
-};
diff --git a/package_bgs/ae/NPBGSubtractor.cpp b/package_bgs/ae/NPBGSubtractor.cpp
deleted file mode 100644
index 3f0620f6281e24f6a3eddd34024835bb0adc3b29..0000000000000000000000000000000000000000
--- a/package_bgs/ae/NPBGSubtractor.cpp
+++ /dev/null
@@ -1,1160 +0,0 @@
-/*
-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/>.
-*/
-/*
-*
-* Copyright 2001 by Ahmed Elgammal All  rights reserved.
-*
-* Permission to use, copy,  or modify this software and  its documentation
-* for  educational  and  research purposes only and without fee  is hereby
-* granted, provided  that this copyright notice and the original authors's
-* name appear  on all copies and supporting documentation.  If individual
-* files are  separated from  this  distribution directory  structure, this
-* copyright notice must be included.  For any other uses of this software,
-* in original or  modified form, including but not limited to distribution
-* in whole or in  part, specific  prior permission  must be  obtained from
-* Author or UMIACS.  These programs shall not  be  used, rewritten, or  
-* adapted as  the basis  of  a commercial  software  or  hardware product 
-* without first obtaining appropriate licenses  from Author. 
-* Other than these cases, no part of this software may be used or
-* distributed without written permission of the author.
-*
-* Neither the author nor UMIACS make any representations about the 
-* suitability of this software for any purpose.  It is provided 
-* "as is" without express or implied warranty.
-*
-* Ahmed Elgammal
-* 
-* University of Maryland at College Park
-* UMIACS
-* A.V. Williams Bldg. 
-* CollegePark, MD 20742
-* E-mail:  elgammal@umiacs.umd.edu
-*
-**/
-
-// NPBGSubtractor.cpp: implementation of the NPBGSubtractor class.
-//
-//////////////////////////////////////////////////////////////////////
-
-#include "NPBGSubtractor.h"
-#include <assert.h>
-#include <math.h>
-#include <string.h>
-
-//#ifdef _DEBUG
-//#undef THIS_FILE
-//static char THIS_FILE[]=__FILE__;
-//#define new DEBUG_NEW
-//#endif
-
-void BGR2SnGnRn(unsigned char * in_image,
-                unsigned char * out_image,
-                unsigned int rows,
-                unsigned int cols)
-{
-  unsigned int i;
-  unsigned int r2,r3;
-  unsigned int r,g,b;
-  double s;
-
-  for(i = 0; i < rows*cols*3; i += 3)
-  {
-    b=in_image[i];
-    g=in_image[i+1];
-    r=in_image[i+2];
-
-    // calculate color ratios
-    s = (double) 255 / (double) (b+g+r+30);
-
-    r2 =(unsigned int) ((g+10) * s );
-    r3 =(unsigned int) ((r+10) * s );
-
-    out_image[i]   = (unsigned char) (((unsigned int) b+g+r) / 3);
-    out_image[i+1] = (unsigned char) (r2 > 255 ? 255 : r2) ;
-    out_image[i+2] = (unsigned char) (r3 > 255 ? 255 : r3) ;
-  }
-}
-
-void UpdateDiffHist(unsigned char * image1, unsigned char * image2, DynamicMedianHistogram * pHist)
-{
-  unsigned int j;
-  int bin,diff;
-
-  unsigned int  imagesize	= pHist->imagesize;
-  unsigned char histbins	= pHist->histbins;
-  unsigned char *pAbsDiffHist = pHist->Hist;
-
-  int histbins_1 = histbins-1;
-  
-  for(j = 0; j < imagesize; j++)
-  {
-    diff = (int) image1[j] - (int) image2[j];
-    diff = abs(diff);
-    // update histogram
-    bin = (diff < histbins ? diff : histbins_1);
-    pAbsDiffHist[j*histbins+bin]++;
-  }
-}
-
-void FindHistMedians(DynamicMedianHistogram * pAbsDiffHist)
-{
-  unsigned char * Hist		   = pAbsDiffHist->Hist;
-  unsigned char * MedianBins = pAbsDiffHist->MedianBins;
-  unsigned char * AccSum	   = pAbsDiffHist->AccSum;
-  unsigned char histsum		   = pAbsDiffHist->histsum;
-  unsigned char histbins		 = pAbsDiffHist->histbins;
-  unsigned int imagesize		 = pAbsDiffHist->imagesize;
-
-  int sum;
-  int bin;
-  unsigned int histindex;
-  unsigned char medianCount=histsum/2;
-  unsigned int j;
-
-  // find medians
-  for(j = 0; j < imagesize; j++)
-  {
-    // find the median
-    bin=0;
-    sum=0;
-
-    histindex=j*histbins;
-
-    while(sum < medianCount)
-    {
-      sum+=Hist[histindex+bin];
-      bin++;
-    }
-
-    bin--;
-
-    MedianBins[j]=bin;
-    AccSum[j]=sum;
-  }
-}
-
-DynamicMedianHistogram BuildAbsDiffHist(unsigned char * pSequence,
-  unsigned int rows,
-  unsigned int cols,
-  unsigned int color_channels,
-  unsigned int SequenceLength,
-  unsigned int histbins)
-{
-
-  unsigned int imagesize=rows*cols*color_channels;
-  unsigned int i;
-
-  DynamicMedianHistogram Hist;
-
-  unsigned char *pAbsDiffHist = new unsigned char[rows*cols*color_channels*histbins];
-  unsigned char *pMedianBins = new unsigned char[rows*cols*color_channels];
-  unsigned char *pMedianFreq = new unsigned char[rows*cols*color_channels];
-  unsigned char *pAccSum = new unsigned char[rows*cols*color_channels];
-
-  memset(pAbsDiffHist,0,rows*cols*color_channels*histbins);
-
-  Hist.Hist = pAbsDiffHist;
-  Hist.MedianBins = pMedianBins;
-  Hist.MedianFreq = pMedianFreq;
-  Hist.AccSum = pAccSum;
-  Hist.histbins = histbins;
-  Hist.imagesize = rows*cols*color_channels;
-  Hist.histsum = SequenceLength-1;
-
-  unsigned char *image1, *image2;
-  for(i = 1; i < SequenceLength; i++)
-  {
-    // find diff between frame i,i-1;
-    image1 = pSequence+(i-1)*imagesize;
-    image2 = pSequence+(i)*imagesize;
-
-    UpdateDiffHist(image1,image2,&Hist);
-  }
-
-  FindHistMedians(&Hist);
-
-  return Hist;
-}
-
-void EstimateSDsFromAbsDiffHist(DynamicMedianHistogram * pAbsDiffHist,
-                                unsigned char * pSDs,
-                                unsigned int imagesize,
-                                double MinSD,
-                                double MaxSD,
-                                unsigned int kernelbins)
-{
-  double v;
-  double kernelbinfactor=(kernelbins-1)/(MaxSD-MinSD);
-  int medianCount; 
-  int sum;
-  int bin;
-  unsigned int histindex;
-  unsigned int j;
-  unsigned int x1,x2;
-
-  unsigned char *Hist		    =pAbsDiffHist->Hist;
-  unsigned char *MedianBins	=pAbsDiffHist->MedianBins;
-  unsigned char *AccSum		  =pAbsDiffHist->AccSum;
-  unsigned char histsum		  =pAbsDiffHist->histsum;
-  unsigned char histbins		=pAbsDiffHist->histbins;
-
-  medianCount=(histsum)/2 ;
-
-  for(j = 0; j < imagesize; j++)
-  {
-    histindex=j*histbins;
-
-    bin=MedianBins[j];
-    sum=AccSum[j];
-
-    x1=sum-Hist[histindex+bin];
-    x2=sum;
-
-    // interpolate to get the median
-    // x1 < 50 % < x2
-
-    v =1.04 * ((double) bin-(double) (x2-medianCount)/ (double) (x2-x1));
-    v=( v <= MinSD ? MinSD : v);
-
-    // convert sd to kernel table bin
-
-    bin=(int) (v>=MaxSD ? kernelbins-1 : floor((v-MinSD)*kernelbinfactor+.5));
-
-    assert(bin>=0 && bin < kernelbins );
-
-    pSDs[j]=bin;
-  }
-}
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-NPBGSubtractor::NPBGSubtractor(){}
-
-NPBGSubtractor::~NPBGSubtractor()
-{
-  delete AbsDiffHist.Hist;
-  delete AbsDiffHist.MedianBins;
-  delete AbsDiffHist.MedianFreq;
-  delete AbsDiffHist.AccSum;
-  delete KernelTable;
-  delete BGModel->SDbinsImage;
-  delete BGModel;
-  delete Pimage1;
-  delete Pimage2;
-  delete tempFrame;
-  delete imageindex->List;
-  delete imageindex;
-}
-
-int NPBGSubtractor::Intialize(unsigned int prows,
-                              unsigned int pcols,
-                              unsigned int pcolor_channels,
-                              unsigned int SequenceLength,
-                              unsigned int pTimeWindowSize,
-                              unsigned char pSDEstimationFlag,
-                              unsigned char pUseColorRatiosFlag)
-{
-
-  rows=prows;
-  cols=pcols;
-  color_channels=pcolor_channels;
-  imagesize=rows*cols*color_channels;
-  SdEstimateFlag = pSDEstimationFlag;
-  UseColorRatiosFlag=pUseColorRatiosFlag;
-  //SampleSize = SequenceLength;
-
-  AdaptBGFlag = FALSE;
-  //
-  SubsetFlag = TRUE;
-
-  UpdateSDRate = 0;
-
-  BGModel = new NPBGmodel(rows,cols,color_channels,SequenceLength,pTimeWindowSize,500);
-
-  Pimage1= new double[rows*cols];
-  Pimage2= new double[rows*cols];
-
-  tempFrame= new unsigned char[rows*cols*3];
-
-  imageindex = new ImageIndex;
-  imageindex->List= new unsigned int [rows*cols];
-
-  // error checking
-  if (BGModel==NULL)
-    return 0;
-
-  return 1;
-}
-
-void NPBGSubtractor::AddFrame(unsigned char *ImageBuffer)
-{
-  if(UseColorRatiosFlag && color_channels==3)
-    BGR2SnGnRn(ImageBuffer,ImageBuffer,rows,cols);
-  
-  BGModel->AddFrame(ImageBuffer);
-}
-
-void NPBGSubtractor::Estimation()
-{
-  int SampleSize=BGModel->SampleSize;
-
-  memset(BGModel->TemporalMask,0,rows*cols*BGModel->TemporalBufferLength);
-
-  //BGModel->AccMask= new unsigned int [rows*cols];
-  memset(BGModel->AccMask,0,rows*cols*sizeof(unsigned int));
-
-  unsigned char *pSDs = new unsigned char[rows*cols*color_channels];
-
-  //DynamicMedianHistogram AbsDiffHist;
-
-  int Abshistbins = 20;
-
-  TimeIndex=0;
-
-  // estimate standard deviations 
-
-  if(SdEstimateFlag)
-  {
-    AbsDiffHist = BuildAbsDiffHist(BGModel->Sequence,rows,cols,color_channels,SampleSize,Abshistbins);
-    EstimateSDsFromAbsDiffHist(&AbsDiffHist,pSDs,imagesize,SEGMAMIN,SEGMAMAX,SEGMABINS);
-  }
-  else
-  {
-    unsigned int bin;
-    bin = (unsigned int) floor(((DEFAULTSEGMA-SEGMAMIN)*SEGMABINS)/(SEGMAMAX-SEGMAMIN));
-    memset(pSDs,bin,rows*cols*color_channels*sizeof(unsigned char));
-  }
-
-  BGModel->SDbinsImage=pSDs;
-
-  // Generate the Kernel
-  KernelTable = new KernelLUTable(KERNELHALFWIDTH,SEGMAMIN,SEGMAMAX,SEGMABINS);
-}
-
-/*********************************************************************/
-
-void BuildImageIndex(unsigned char * Image,
-                     ImageIndex * imageIndex,
-                     unsigned int rows,
-                     unsigned int cols)
-{
-  unsigned int i,j;
-  unsigned int r,c;
-  unsigned int * image_list;
-
-  j=cols+1;
-  i=0;
-  image_list=imageIndex->List;
-
-  for(r = 1; r < rows-1; r++)
-  {
-    for(c = 1; c < cols-1; c++)
-    {
-      if(Image[j])
-        image_list[i++]=j;
-      
-      j++;
-    }
-    j+=2;
-  }
-
-  imageIndex->cnt = i;
-}
-
-/*********************************************************************/
-
-void HystExpandOperatorIndexed(unsigned char * inImage,
-                               ImageIndex * inIndex,
-                               double * Pimage,
-                               double hyst_th,
-                               unsigned char * outImage,
-                               ImageIndex * outIndex,
-                               unsigned int urows,
-                               unsigned int ucols)
-{
-  unsigned int * in_list;
-  unsigned int in_cnt;
-  unsigned int * out_list;
-
-  int rows,cols;
-
-  int Nbr[9];
-  unsigned int i,j;
-  unsigned int k;
-  unsigned int idx;
-
-  rows=(int)  urows;
-  cols=(int)  ucols;
-
-  in_cnt=inIndex->cnt;
-  in_list=inIndex->List;
-
-  Nbr[0]=-cols-1;
-  Nbr[1]=-cols;
-  Nbr[2]=-cols+1;
-  Nbr[3]=-1;
-  Nbr[4]=0;
-  Nbr[5]=1;
-  Nbr[6]=cols-1;
-  Nbr[7]=cols;
-  Nbr[8]=cols+1;
-
-  memset(outImage,0,rows*cols);
-
-  out_list=outIndex->List;
-  k=0;
-  
-  for(i = 0; i < in_cnt; i++)
-  {
-    for(j = 0; j < 9; j++)
-    {
-      idx = in_list[i] + Nbr[j];
-
-      if(Pimage[idx] < hyst_th)
-        outImage[idx] = 255;
-    }
-  }
-
-  // build index for out image
-  BuildImageIndex(outImage,outIndex,urows,ucols);
-}
-
-/*********************************************************************/
-
-void HystShrinkOperatorIndexed(unsigned char * inImage,
-                               ImageIndex * inIndex,
-                               double * Pimage,
-                               double hyst_th,
-                               unsigned char * outImage,
-                               ImageIndex * outIndex,
-                               unsigned int urows,
-                               unsigned int ucols)
-{
-  unsigned int * in_list;
-  unsigned int in_cnt;
-  unsigned int * out_list;
-
-  int rows,cols;
-
-  int Nbr[9];
-  unsigned int i,j;
-  unsigned int k,idx;
-
-  rows=(int) urows;
-  cols=(int) ucols;
-
-  in_cnt=inIndex->cnt;
-  in_list=inIndex->List;
-
-  Nbr[0]=-cols-1;
-  Nbr[1]=-cols;
-  Nbr[2]=-cols+1;
-  Nbr[3]=-1;
-  Nbr[4]=0;
-  Nbr[5]=1;
-  Nbr[6]=cols-1;
-  Nbr[7]=cols;
-  Nbr[8]=cols+1;
-
-  memset(outImage,0,rows*cols);
-
-  out_list=outIndex->List;
-  k=0;
-  
-  for(i = 0; i < in_cnt; i++)
-  {
-    idx = in_list[i];
-    j = 0;
-
-    while(j < 9 && inImage[idx+Nbr[j]])
-      j++;
-    
-    if(j >= 9 || Pimage[idx] <= hyst_th)
-      outImage[idx]=255;
-  }
-
-  BuildImageIndex(outImage,outIndex,rows,cols);
-}
-
-/*********************************************************************/
-
-void ExpandOperatorIndexed(unsigned char * inImage,
-                           ImageIndex * inIndex,
-                           unsigned char * outImage,
-                           ImageIndex * outIndex,
-                           unsigned int urows,
-                           unsigned int ucols)
-{
-  unsigned int * in_list;
-  unsigned int in_cnt;
-  unsigned int * out_list;
-
-  int rows,cols;
-
-  int Nbr[9];
-  unsigned int i,j;
-  unsigned int k;
-  unsigned int idx;
-
-  rows=(int)  urows;
-  cols=(int)  ucols;
-
-  in_cnt=inIndex->cnt;
-  in_list=inIndex->List;
-
-  Nbr[0]=-cols-1;
-  Nbr[1]=-cols;
-  Nbr[2]=-cols+1;
-  Nbr[3]=-1;
-  Nbr[4]=0;
-  Nbr[5]=1;
-  Nbr[6]=cols-1;
-  Nbr[7]=cols;
-  Nbr[8]=cols+1;
-
-
-  memset(outImage,0,rows*cols);
-
-
-  out_list=outIndex->List;
-  k=0;
-  for (i=0; i<in_cnt;i++)
-    for (j=0;j<9;j++) {
-      idx=in_list[i]+Nbr[j];
-      outImage[idx]=255;
-    }
-
-
-    // build index for out image
-
-    BuildImageIndex(outImage,outIndex,rows,cols);
-
-}
-
-/*********************************************************************/
-
-void ShrinkOperatorIndexed(unsigned char * inImage,
-                           ImageIndex * inIndex,
-                           unsigned char * outImage,
-                           ImageIndex * outIndex,
-                           unsigned int urows,
-                           unsigned int ucols)
-{
-
-  unsigned int * in_list;
-  unsigned int in_cnt;
-  unsigned int * out_list;
-
-  int rows,cols;
-
-  int Nbr[9];
-  unsigned int i,j;
-  unsigned int k,idx;
-
-  rows=(int) urows;
-  cols=(int) ucols;
-
-  in_cnt=inIndex->cnt;
-  in_list=inIndex->List;
-
-  Nbr[0]=-cols-1;
-  Nbr[1]=-cols;
-  Nbr[2]=-cols+1;
-  Nbr[3]=-1;
-  Nbr[4]=0;
-  Nbr[5]=1;
-  Nbr[6]=cols-1;
-  Nbr[7]=cols;
-  Nbr[8]=cols+1;
-
-
-  memset(outImage,0,rows*cols);
-
-  out_list=outIndex->List;
-  k=0;
-  for (i=0; i<in_cnt;i++) {
-    idx=in_list[i];
-    j=0;
-
-    while ( j<9 && inImage[idx+Nbr[j]]){
-      j++;
-    }
-
-    if (j>=9) {
-      outImage[idx]=255;
-    }
-  }
-
-  BuildImageIndex(outImage,outIndex,rows,cols);
-}
-
-/*********************************************************************/
-
-void NoiseFilter_o(unsigned char * Image,
-                   unsigned char * ResultIm,
-                   int rows,
-                   int cols,
-                   unsigned char th)
-{
-  /* assuming input is 1 for on, 0 for off */
-
-
-  int r,c;
-  unsigned char *p,*n,*nw,*ne,*e,*w,*s,*sw,*se;
-  unsigned int v;
-  unsigned int TH;
-
-  unsigned char * ResultPtr;
-
-  TH=255*th;
-
-  memset(ResultIm,0,rows*cols);
-
-  p=Image+cols+1;
-  ResultPtr=ResultIm+cols+1;
-
-  for(r=1;r<rows-1;r++)
-  {
-    for(c=1;c<cols-1;c++)
-    {
-      if (*p)
-      {
-        n=p-cols;
-        ne=n+1;
-        nw=n-1;
-        e=p+1;
-        w=p-1;
-        s=p+cols;
-        se=s+1;
-        sw=s-1;
-
-        v=(unsigned int) *nw+*n+*ne+*w+*e+*sw+*s+*se;
-
-        if (v>=TH)
-          *ResultPtr=255;
-        else
-          *ResultPtr=0;
-      }
-      p++;
-      ResultPtr++;
-    }
-    p+=2;
-    ResultPtr+=2;
-  }
-}
-
-/*********************************************************************/
-
-void NPBGSubtractor::SequenceBGUpdate_Pairs(unsigned char * image,
-                                            unsigned char * Mask)
-{
-  unsigned int i,ic;
-  unsigned char * pSequence 	=BGModel->Sequence;
-  unsigned char * PixelQTop		=BGModel->PixelQTop;
-  unsigned int Top						=BGModel->Top;
-  unsigned int rate;
-
-  int TemporalBufferTop						=(int) BGModel->TemporalBufferTop;
-  unsigned char * pTemporalBuffer	= BGModel->TemporalBuffer;
-  unsigned char * pTemporalMask		= BGModel->TemporalMask;
-  int TemporalBufferLength				= BGModel->TemporalBufferLength;
-
-  unsigned int * AccMask		=	BGModel->AccMask;
-  unsigned int ResetMaskTh	= BGModel->ResetMaskTh;
-
-  unsigned char *pAbsDiffHist = AbsDiffHist.Hist;
-  unsigned char histbins = AbsDiffHist.histbins;
-  int histbins_1=histbins-1;
-
-  int TimeWindowSize = BGModel->TimeWindowSize;
-  int SampleSize = BGModel->SampleSize;
-
-  int TemporalBufferNext;
-
-  unsigned int imagebuffersize=rows*cols*color_channels;
-  unsigned int imagespatialsize=rows*cols;
-
-  unsigned char mask;
-
-  unsigned int histindex;
-  unsigned char diff;
-  unsigned char bin;
-
-  static int TBCount=0;
-
-  unsigned char * pTBbase1, * pTBbase2;
-  unsigned char * pModelbase1, * pModelbase2;
-
-  rate=TimeWindowSize/SampleSize;
-  rate=(rate > 2) ? rate : 2;
-
-
-  TemporalBufferNext=(TemporalBufferTop+1) 
-    % TemporalBufferLength;
-
-  // pointers to Masks : Top and Next
-  unsigned char * pTMaskTop=pTemporalMask+TemporalBufferTop*imagespatialsize;
-  unsigned char * pTMaskNext=pTemporalMask+TemporalBufferNext*imagespatialsize;
-
-  // pointers to TB frames: Top and Next
-  unsigned char * pTBTop=pTemporalBuffer+TemporalBufferTop*imagebuffersize;
-  unsigned char * pTBNext=pTemporalBuffer+TemporalBufferNext*imagebuffersize;
-
-  if ( ((TimeIndex) % rate == 0)  && TBCount >= TemporalBufferLength )
-  {
-    for(i=0,ic=0;i<imagespatialsize;i++,ic+=color_channels)
-    {
-      mask= * (pTMaskTop+i) || * (pTMaskNext+i);
-
-      if(!mask)
-      {
-        // pointer to TB pixels to be added to the model
-        pTBbase1=pTBTop+ic;
-        pTBbase2=pTBNext+ic;
-
-        // pointers to Model pixels to be replaced
-        pModelbase1=pSequence+PixelQTop[i]*imagebuffersize+ic;
-        pModelbase2=pSequence+((PixelQTop[i]+1)% SampleSize)*imagebuffersize+ic;
-
-        // update Deviation Histogram
-        if(SdEstimateFlag)
-        {
-          if(color_channels==1)
-          {
-            histindex=i*histbins;	
-
-            // add new pair from temporal buffer
-            diff=(unsigned char) abs((int) *pTBbase1 - (int) *pTBbase2);
-            bin=(diff < histbins ? diff : histbins_1);
-            pAbsDiffHist[histindex+bin]++;
-
-
-            // remove old pair from the model
-            diff=(unsigned char) abs((int) *pModelbase1-(int) *pModelbase2);
-            bin=(diff < histbins ? diff : histbins_1);
-            pAbsDiffHist[histindex+bin]--;
-          }
-          else
-          {
-            // color
-
-            // add new pair from temporal buffer
-            histindex=ic*histbins;	
-            diff=abs(*pTBbase1 -
-              *pTBbase2);
-            bin=(diff < histbins ? diff : histbins_1);
-            pAbsDiffHist[histindex+bin]++;
-
-            histindex+=histbins;	
-            diff=abs(*(pTBbase1+1) -
-              *(pTBbase2+1));
-            bin=(diff < histbins ? diff : histbins_1);
-            pAbsDiffHist[histindex+bin]++;
-
-            histindex+=histbins;	
-            diff=abs(*(pTBbase1+2) -
-              *(pTBbase2+2));
-            bin=(diff < histbins ? diff : histbins_1);
-            pAbsDiffHist[histindex+bin]++;
-
-            // remove old pair from the model
-            histindex=ic*histbins;	
-
-            diff=abs(*pModelbase1-
-              *pModelbase2);
-            bin=(diff < histbins ? diff : histbins_1);
-            pAbsDiffHist[histindex+bin]--;
-
-            histindex+=histbins;	
-            diff=abs(*(pModelbase1+1)-
-              *(pModelbase2+1));
-            bin=(diff < histbins ? diff : histbins_1);
-            pAbsDiffHist[histindex+bin]--;
-
-            histindex+=histbins;	
-            diff=abs(*(pModelbase1+2)-
-              *(pModelbase2+2));
-            bin=(diff < histbins ? diff : histbins_1);
-            pAbsDiffHist[histindex+bin]--;
-          }
-        }
-
-        // add new pair into the model
-        memcpy(pModelbase1,pTBbase1, color_channels*sizeof(unsigned char));
-
-        memcpy(pModelbase2,pTBbase2, color_channels*sizeof(unsigned char));
-
-        PixelQTop[i]=(PixelQTop[i]+2) % SampleSize;
-      }
-    }
-  } // end if (sampling event)
-
-  // update temporal buffer
-  // add new frame to Temporal buffer.
-  memcpy(pTBTop,image,imagebuffersize);
-
-  // update AccMask
-  // update new Mask with information in AccMask
-
-  for (i=0;i<rows*cols;i++)
-  {
-    if (Mask[i])
-      AccMask[i]++;
-    else
-      AccMask[i]=0;
-
-    if (AccMask[i] > ResetMaskTh)
-      Mask[i]=0;
-  }
-
-  // add new mask
-  memcpy(pTMaskTop,Mask,imagespatialsize);
-
-  // advance Temporal buffer pointer
-  TemporalBufferTop=(TemporalBufferTop+1) % TemporalBufferLength;
-
-  BGModel->TemporalBufferTop=TemporalBufferTop;
-
-  TBCount++;
-
-  // estimate SDs
-
-  if (SdEstimateFlag && UpdateSDRate && ((TimeIndex) % UpdateSDRate == 0))
-  {
-    double MaxSD = KernelTable->maxsegma;
-    double MinSD = KernelTable->minsegma;
-    int KernelBins = KernelTable->segmabins;
-
-    unsigned char * pSDs= BGModel->SDbinsImage;
-
-    FindHistMedians(&(AbsDiffHist));
-    EstimateSDsFromAbsDiffHist(&(AbsDiffHist),pSDs,imagebuffersize,MinSD,MaxSD,KernelBins);
-  }
-
-  TimeIndex++;
-}
-
-/*********************************************************************/
-
-void DisplayPropabilityImageWithThresholding(double * Pimage,
-                                             unsigned char * DisplayImage,
-                                             double Threshold,
-                                             unsigned int rows,
-                                             unsigned int cols)
-{
-  double p;
-
-  for(unsigned int i=0;i<rows*cols;i++)
-  {
-    p = Pimage[i];
-
-    DisplayImage[i]=(p > Threshold) ?  0 : 255;
-  }
-}
-
-/*********************************************************************/
-
-void NPBGSubtractor::NPBGSubtraction_Subset_Kernel(
-  unsigned char * image,
-  unsigned char * FGImage,
-  unsigned char * FilteredFGImage)
-{
-  unsigned int i,j;
-  unsigned char *pSequence 	=BGModel->Sequence;
-
-  unsigned int SampleSize			= BGModel->SampleSize;
-
-  double *kerneltable	= KernelTable->kerneltable;
-  int KernelHalfWidth		= KernelTable->tablehalfwidth;
-  double *KernelSum			= KernelTable->kernelsums;
-  double KernelMaxSigma = KernelTable->maxsegma;
-  double KernelMinSigma = KernelTable->minsegma;
-  int KernelBins				= KernelTable->segmabins;
-  unsigned char * SDbins= BGModel->SDbinsImage;
-
-  unsigned char * SaturationImage=FilteredFGImage;
-
-  // default sigmas .. to be removed.
-  double sigma1;
-  double sigma2;
-  double sigma3;
-
-  sigma1=2.25;
-  sigma2=2.25;
-  sigma3=2.25;
-
-  double p;
-  double th;
-
-  double alpha;
-
-  alpha= AlphaValue;
-
-  /* intialize FG image */
-
-  memset(FGImage,0,rows*cols);
-
-  //Threshold=1;
-  th = Threshold * SampleSize;
-
-  double sum=0,kernel1,kernel2,kernel3;
-  int k,g;
-
-
-  if (color_channels==1) 
-  {
-    // gray scale
-
-    int kernelbase;
-    
-    for (i=0;i<rows*cols;i++)
-    {
-      kernelbase=SDbins[i]*(2*KernelHalfWidth+1);
-      sum=0;
-      j=0;
-
-      while (j<SampleSize && sum < th)
-      {
-        g=pSequence[j*imagesize+i];
-        k= g-  image[i] +KernelHalfWidth;
-        sum+=kerneltable[kernelbase+k];
-        j++;
-      }
-
-      p=sum/j;
-      Pimage1[i]=p;
-    }
-  }
-  else if (UseColorRatiosFlag && SubsetFlag)
-  {
-    // color ratios
-
-    unsigned int ig;
-    int base;
-
-    int kernelbase1;
-    int kernelbase2;
-    int kernelbase3;
-
-    unsigned int kerneltablewidth=2*KernelHalfWidth+1;
-
-    double beta=3.0;    // minimum bound on the range.
-    double betau=100.0;
-
-    double beta_over_alpha = beta / alpha;
-    double betau_over_alpha = betau / alpha;
-
-
-    double brightness_lowerbound = 1-alpha;
-    double brightness_upperbound = 1+alpha;
-    int x1,x2;
-    unsigned int SubsampleCount;
-
-    for (i=0,ig=0;i<imagesize;i+=3,ig++)
-    {
-      kernelbase1=SDbins[i]*kerneltablewidth;
-      kernelbase2=SDbins[i+1]*kerneltablewidth;
-      kernelbase3=SDbins[i+2]*kerneltablewidth;
-
-      sum=0;
-      j=0;
-      SubsampleCount=0;
-
-      while (j<SampleSize && sum < th)
-      {
-        base=j*imagesize+i;
-        g=pSequence[base];
-        
-        if (g < beta_over_alpha)
-        {
-          x1=(int) (g-beta);
-          x2=(int) (g+beta);
-        }
-        else if (g > betau_over_alpha)
-        {
-          x1=(int) (g-betau);
-          x2=(int) (g+betau);
-        }
-        else
-        {
-          x1=(int) (g*brightness_lowerbound+0.5);
-          x2=(int) (g*brightness_upperbound+0.5);
-        }
-
-        if(x1<image[i] && image[i] <x2)
-        {
-          g=pSequence[base+1];
-          k= (g-  image[i+1]) +KernelHalfWidth;
-          kernel2=kerneltable[kernelbase2+k];
-
-          g=pSequence[base+2];
-          k= (g-  image[i+2]) +KernelHalfWidth;
-          kernel3=kerneltable[kernelbase3+k];
-
-          sum+=kernel2*kernel3;
-
-          SubsampleCount++;
-        }
-        j++;
-      }
-
-      p=sum / j;
-      Pimage1[ig]=p;
-    }	
-  }
-  else if (UseColorRatiosFlag && ! SubsetFlag)
-  {
-    // color ratios
-
-    unsigned int ig;
-    int base;
-    int bin;
-
-    int kernelbase1;
-    int kernelbase2;
-    int kernelbase3;
-
-    unsigned int kerneltablewidth=2*KernelHalfWidth+1;
-
-    int gmin,gmax;
-    double gfactor;
-
-    gmax=200;
-    gmin=10;
-
-    gfactor = (KernelMaxSigma-KernelMinSigma) / (double) (gmax - gmin);
-
-    for (i=0,ig=0;i<imagesize;i+=3,ig++)
-    {
-
-      bin=(int) floor(((alpha*16-KernelMinSigma)*KernelBins)/(KernelMaxSigma-KernelMinSigma));
-
-      kernelbase1=bin*kerneltablewidth;
-      kernelbase2=SDbins[i+1]*kerneltablewidth;
-      kernelbase3=SDbins[i+2]*kerneltablewidth;
-
-      sum=0;
-      j=0;
-
-      while (j<SampleSize && sum < th)
-      {
-        base=j*imagesize+i;
-        g=pSequence[base];
-
-        if (g < gmin )
-          bin=0;
-        else if (g > gmax)
-          bin = KernelBins -1 ;
-        else
-          bin= (int) ((g-gmin) * gfactor + 0.5);
-        
-        kernelbase1=bin*kerneltablewidth;
-
-        k= (g-  image[i]) +KernelHalfWidth;
-        kernel1=kerneltable[kernelbase1+k];
-
-        g=pSequence[base+1];
-        k= (g-  image[i+1]) +KernelHalfWidth;
-        kernel2=kerneltable[kernelbase2+k];
-
-        g=pSequence[base+2];
-        k= (g-  image[i+2]) +KernelHalfWidth;
-        kernel3=kerneltable[kernelbase3+k];
-
-        sum+=kernel1*kernel2*kernel3;
-        j++;
-      }
-
-      p=sum / j;
-      Pimage1[ig]=p;
-    }
-  }
-  else // RGB color
-  {
-    unsigned int ig;
-    int base;
-
-    int kernelbase1;
-    int kernelbase2;
-    int kernelbase3;
-    unsigned int kerneltablewidth=2*KernelHalfWidth+1;
-
-    for (i=0,ig=0;i<imagesize;i+=3,ig++)
-    {
-      // used extimated kernel width to access the right kernel
-      kernelbase1=SDbins[i]*kerneltablewidth;
-      kernelbase2=SDbins[i+1]*kerneltablewidth;
-      kernelbase3=SDbins[i+2]*kerneltablewidth;
-
-      sum=0;
-      j=0;
-      while (j<SampleSize && sum < th)
-      {
-        base=j*imagesize+i;
-        g=pSequence[base];
-        k= (g-  image[i]) +KernelHalfWidth;
-        kernel1=kerneltable[kernelbase1+k];
-
-        g=pSequence[base+1];
-        k= (g-  image[i+1]) +KernelHalfWidth;
-        kernel2=kerneltable[kernelbase2+k];
-
-        g=pSequence[base+2];
-        k= (g-  image[i+2]) +KernelHalfWidth;
-        kernel3=kerneltable[kernelbase3+k];
-
-        sum+=kernel1*kernel2*kernel3;
-        j++;
-      }
-      
-      p=sum/j;
-      Pimage1[ig]=p;
-    }
-  }
-
-  DisplayPropabilityImageWithThresholding(Pimage1,FGImage,Threshold,rows,cols);
-}
-
-/*********************************************************************/
-
-void NPBGSubtractor::NBBGSubtraction(unsigned char * Frame,
-                                     unsigned char * FGImage,
-                                     unsigned char * FilteredFGImage,
-                                     unsigned char ** DisplayBuffers)
-{
-  if(UseColorRatiosFlag)
-    BGR2SnGnRn(Frame,tempFrame,rows,cols);
-  else
-    memcpy(tempFrame,Frame,rows*cols*color_channels);
-
-  NPBGSubtraction_Subset_Kernel(tempFrame,FGImage,FilteredFGImage);	
-  /*NoiseFilter_o(FGImage,DisplayBuffers[3],rows,cols,4);
-  BuildImageIndex(DisplayBuffers[3],imageindex,rows,cols);
-
-  ExpandOperatorIndexed(DisplayBuffers[3],imageindex,DisplayBuffers[4],imageindex,rows,cols);
-  ShrinkOperatorIndexed(DisplayBuffers[4],imageindex,FilteredFGImage,imageindex,rows,cols);
-
-  memset(DisplayBuffers[3],0,rows*cols);*/
-}
-
-void NPBGSubtractor::Update(unsigned char * FGMask)
-{
-  if(UpdateBGFlag)
-    SequenceBGUpdate_Pairs(tempFrame,FGMask);
-}
diff --git a/package_bgs/av/VuMeter.h b/package_bgs/av/VuMeter.h
deleted file mode 100644
index a2334cafdc99e695a8d36dcdef200ceaf4d80d91..0000000000000000000000000000000000000000
--- a/package_bgs/av/VuMeter.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-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
-
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "TBackgroundVuMeter.h"
-#include "../IBGS.h"
-
-class VuMeter : public IBGS
-{
-private:
-  TBackgroundVuMeter bgs;
-
-  IplImage *frame;
-  IplImage *gray;
-  IplImage *background;
-  IplImage *mask;
-  
-  bool firstTime;
-  bool showOutput;
-  bool enableFilter;
-  
-  int binSize;
-  double alpha;
-  double threshold;
-  
-public:
-  VuMeter();
-  ~VuMeter();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
diff --git a/package_bgs/bgslibrary.h b/package_bgs/bgslibrary.h
new file mode 100644
index 0000000000000000000000000000000000000000..3895ba85b6f9e646e76965506563f3a0c635eb26
--- /dev/null
+++ b/package_bgs/bgslibrary.h
@@ -0,0 +1,65 @@
+/*
+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
+
+#include "FrameDifference.h"
+#include "StaticFrameDifference.h"
+#include "WeightedMovingMean.h"
+#include "WeightedMovingVariance.h"
+#include "MixtureOfGaussianV1.h" // Only for OpenCV >= 2
+#include "MixtureOfGaussianV2.h"
+#include "AdaptiveBackgroundLearning.h"
+#include "AdaptiveSelectiveBackgroundLearning.h"
+#include "KNN.h" // Only for OpenCV >= 3
+#include "GMG.h" // Only for OpenCV >= 2.4.3
+#include "DPAdaptiveMedian.h"
+#include "DPGrimsonGMM.h"
+#include "DPZivkovicAGMM.h"
+#include "DPMean.h"
+#include "DPWrenGA.h"
+#include "DPPratiMediod.h"
+#include "DPEigenbackground.h"
+#include "DPTexture.h"
+#include "T2FGMM_UM.h"
+#include "T2FGMM_UV.h"
+#include "T2FMRF_UM.h"
+#include "T2FMRF_UV.h"
+#include "FuzzySugenoIntegral.h"
+#include "FuzzyChoquetIntegral.h"
+#include "LBSimpleGaussian.h"
+#include "LBFuzzyGaussian.h"
+#include "LBMixtureOfGaussians.h"
+#include "LBAdaptiveSOM.h"
+#include "LBFuzzyAdaptiveSOM.h"
+#include "LBP_MRF.h"
+#include "MultiLayer.h"
+#include "PixelBasedAdaptiveSegmenter.h"
+#include "VuMeter.h"
+#include "KDE.h"
+#include "IndependentMultimodal.h"
+#include "MultiCue.h"
+#include "SigmaDelta.h"
+#include "SuBSENSE.h"
+#include "LOBSTER.h"
+#include "PAWCS.h"
+#include "TwoPoints.h"
+#include "ViBe.h"
+
+//#include "_template_/MyBGS.h"
+//#include "_template_/Amber.h"
+
+using namespace bgslibrary::algorithms;
diff --git a/package_bgs/bl/SigmaDeltaBGS.cpp b/package_bgs/bl/SigmaDeltaBGS.cpp
deleted file mode 100644
index a9c7914f427dc5cecd75b2fa6e7fa51247096d2b..0000000000000000000000000000000000000000
--- a/package_bgs/bl/SigmaDeltaBGS.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-#include "SigmaDeltaBGS.h"
-
-SigmaDeltaBGS::SigmaDeltaBGS() :
-firstTime(true),
-ampFactor(1),
-minVar(15),
-maxVar(255),
-algorithm(sdLaMa091New()),
-showOutput(true) {
-
-  applyParams();
-  std::cout << "SigmaDeltaBGS()" << std::endl;
-}
-
-SigmaDeltaBGS::~SigmaDeltaBGS() {
-  sdLaMa091Free(algorithm);
-  std::cout << "~SigmaDeltaBGS()" << std::endl;
-}
-
-void SigmaDeltaBGS::process(
-  const cv::Mat &img_input,
-  cv::Mat &img_output,
-  cv::Mat &img_bgmodel
-  ) {
-  if (img_input.empty())
-    return;
-
-  loadConfig();
-
-  if (firstTime) {
-    saveConfig();
-    sdLaMa091AllocInit_8u_C3R(algorithm, img_input.data, img_input.cols, img_input.rows, img_input.step);
-
-    firstTime = false;
-    return;
-  }
-
-  img_output = cv::Mat(img_input.rows, img_input.cols, CV_8UC1);
-  cv::Mat img_output_tmp(img_input.rows, img_input.cols, CV_8UC3);
-
-  sdLaMa091Update_8u_C3R(algorithm, img_input.data, img_output_tmp.data);
-
-  unsigned char* tmpBuffer = (unsigned char*)img_output_tmp.data;
-  unsigned char* outBuffer = (unsigned char*)img_output.data;
-
-  for (size_t i = 0; i < img_output.total(); ++i) {
-    *outBuffer = *tmpBuffer;
-
-    ++outBuffer;
-    tmpBuffer += img_output_tmp.channels();
-  }
-
-  if (showOutput)
-    cv::imshow("Sigma-Delta", img_output);
-}
-
-void SigmaDeltaBGS::saveConfig() {
-  CvFileStorage* fs = cvOpenFileStorage("./config/SigmaDeltaBGS.xml", 0, CV_STORAGE_WRITE);
-
-  cvWriteInt(fs, "ampFactor", ampFactor);
-  cvWriteInt(fs, "minVar", minVar);
-  cvWriteInt(fs, "maxVar", maxVar);
-  cvWriteInt(fs, "showOutput", showOutput);
-
-  cvReleaseFileStorage(&fs);
-}
-
-void SigmaDeltaBGS::loadConfig() {
-  CvFileStorage* fs = cvOpenFileStorage("./config/SigmaDeltaBGS.xml", 0, CV_STORAGE_READ);
-
-  ampFactor = cvReadIntByName(fs, 0, "ampFactor", 1);
-  minVar = cvReadIntByName(fs, 0, "minVar", 15);
-  maxVar = cvReadIntByName(fs, 0, "maxVar", 255);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
-
-  applyParams();
-
-  cvReleaseFileStorage(&fs);
-}
-
-void SigmaDeltaBGS::applyParams() {
-  sdLaMa091SetAmplificationFactor(algorithm, ampFactor);
-  sdLaMa091SetMinimalVariance(algorithm, minVar);
-  sdLaMa091SetMaximalVariance(algorithm, maxVar);
-}
diff --git a/package_bgs/bl/SigmaDeltaBGS.h b/package_bgs/bl/SigmaDeltaBGS.h
deleted file mode 100644
index a4be2711d634982d9e3af8266476e91ec85efeaf..0000000000000000000000000000000000000000
--- a/package_bgs/bl/SigmaDeltaBGS.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#pragma once
-
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-
-//extern "C" {
-#include "sdLaMa091.h"
-//}
-
-class SigmaDeltaBGS : public IBGS {
-private:
-
-  bool firstTime;
-  unsigned int ampFactor;
-  unsigned int minVar;
-  unsigned int maxVar;
-  sdLaMa091_t* algorithm;
-  bool showOutput;
-
-public:
-
-  SigmaDeltaBGS();
-
-  ~SigmaDeltaBGS();
-
-  void process(
-    const cv::Mat &img_input,
-    cv::Mat &img_output,
-    cv::Mat &img_bgmodel
-    );
-
-private:
-
-  void saveConfig();
-
-  void loadConfig();
-
-  void applyParams();
-};
diff --git a/package_bgs/bl/stdbool.h b/package_bgs/bl/stdbool.h
deleted file mode 100644
index abeb3b877f62de18eec0e6a32694d80ef5ced273..0000000000000000000000000000000000000000
--- a/package_bgs/bl/stdbool.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-//#ifndef false
-//  #define false   0
-//#endif
-
-//#ifndef true
-//  #define true    1
-//#endif
-
-//#ifndef bool
-//  #define bool int
-//#endif
-
-// #ifdef _WIN32
-// #endif
diff --git a/package_bgs/ck/MEDefs.cpp b/package_bgs/ck/MEDefs.cpp
deleted file mode 100644
index 93473537cbd5b7de0ce6ffc1dcc17f380004b91f..0000000000000000000000000000000000000000
--- a/package_bgs/ck/MEDefs.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  This file is part of the AiBO+ project
- *
- *  Copyright (C) 2005-2013 Csaba Kertész (csaba.kertesz@gmail.com)
- *
- *  AiBO+ 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 2 of the License, or
- *  (at your option) any later version.
- *
- *  AiBO+ 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 this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
- *
- */
-
-#include "MEDefs.hpp"
-
-#include <math.h>
-
-float MERound(float number)
-{
-	double FracPart = 0.0;
-	double IntPart = 0.0;
-	float Ret = 0.0;
-
-	FracPart = modf((double)number, &IntPart);
-	if (number >= 0)
-	{
-	  Ret = (float)(FracPart >= 0.5 ? IntPart+1 : IntPart);
-	} else {
-	  Ret = (float)(FracPart <= -0.5 ? IntPart-1 : IntPart);
-	}
-	return Ret;
-}
diff --git a/package_bgs/ck/README.TXT b/package_bgs/ck/README.TXT
deleted file mode 100644
index d76c6a3438d3b26fb98b3355f6359b2474ccea34..0000000000000000000000000000000000000000
--- a/package_bgs/ck/README.TXT
+++ /dev/null
@@ -1,135 +0,0 @@
-###################################################################
-#                                                                 #
-#    MAXFLOW - software for computing mincut/maxflow in a graph   #
-#                        Version 2.2                              #
-#    http://www.cs.cornell.edu/People/vnk/software.html           #
-#                                                                 #
-#    Yuri Boykov (yuri@csd.uwo.ca)                                #
-#    Vladimir Kolmogorov (vnk@cs.cornell.edu)                     #
-#    2001                                                         #
-#                                                                 #
-###################################################################
-
-1. Introduction.
-
-This software library implements the maxflow algorithm
-described in
-
-	An Experimental Comparison of Min-Cut/Max-Flow Algorithms
-	for Energy Minimization in Vision.
-	Yuri Boykov and Vladimir Kolmogorov.
-	In IEEE Transactions on Pattern Analysis and Machine Intelligence (PAMI), 
-	September 2004
-
-This algorithm was developed by Yuri Boykov and Vladimir Kolmogorov
-at Siemens Corporate Research. To make it available for public use,
-it was later reimplemented by Vladimir Kolmogorov based on open publications.
-
-If you use this software for research purposes, you should cite
-the aforementioned paper in any resulting publication.
-
-Tested under windows, Visual C++ 6.0 compiler and unix (SunOS 5.8
-and RedHat Linux 7.0, GNU c++ compiler).
-
-##################################################################
-
-2. License.
-
-    Copyright 2001 Vladimir Kolmogorov (vnk@cs.cornell.edu), Yuri Boykov (yuri@csd.uwo.ca).
-
-    This program 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 2 of the License, or
-    (at your option) any later version.
-
-    This program 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 this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-##################################################################
-
-3. Graph representation.
-
-There are two versions of the algorithm using different
-graph representations (adjacency list and forward star).
-The former one uses more than twice as much memory as the
-latter one but is 10-20% faster.
-
-Memory allocation (assuming that all capacities are 'short' - 2 bytes):
-
-                 |   Nodes    |   Arcs
-------------------------------------------
-Adjacency list   | *24 bytes  | *14 bytes
-Forward star     | *28 bytes  |  6 bytes
-
-(* means that often it should be rounded up to be a multiple of 4
-- some compilers (e.g. Visual C++) seem to round up elements
-of arrays unless the are structures containing only char[].)
-
-Note that arcs are always added in pairs - in forward and reverse directions.
-Arcs between nodes and terminals (the source and the sink) are
-not stored as arcs, but rather as a part of nodes.
-
-The assumption for the forward star representation is that
-the maximum number of arcs per node (except the source
-and the sink) is much less than ARC_BLOCK_SIZE (1024 by default).
-
-Both versions have the same interface.
-
-##################################################################
-
-4. Example usage.
-
-This section shows how to use the library to compute
-a minimum cut on the following graph:
-
-		        SOURCE
-		       /       \
-		     1/         \2
-		     /      3    \
-		   node0 -----> node1
-		     |   <-----   |
-		     |      4     |
-		     \            /
-		     5\          /6
-		       \        /
-		          SINK
-
-///////////////////////////////////////////////////
-
-#include <stdio.h>
-#include "graph.h"
-
-void main()
-{
-	Graph::node_id nodes[2];
-	Graph *g = new Graph();
-
-	nodes[0] = g -> add_node();
-	nodes[1] = g -> add_node();
-	g -> set_tweights(nodes[0], 1, 5);
-	g -> set_tweights(nodes[1], 2, 6);
-	g -> add_edge(nodes[0], nodes[1], 3, 4);
-
-	Graph::flowtype flow = g -> maxflow();
-
-	printf("Flow = %d\n", flow);
-	printf("Minimum cut:\n");
-	if (g->what_segment(nodes[0]) == Graph::SOURCE)
-		printf("node0 is in the SOURCE set\n");
-	else
-		printf("node0 is in the SINK set\n");
-	if (g->what_segment(nodes[1]) == Graph::SOURCE)
-		printf("node1 is in the SOURCE set\n");
-	else
-		printf("node1 is in the SINK set\n");
-
-	delete g;
-}
-
-///////////////////////////////////////////////////
diff --git a/package_bgs/db/IndependentMultimodalBGS.cpp b/package_bgs/db/IndependentMultimodalBGS.cpp
deleted file mode 100644
index 5312075379640840adfa22993158942cf6fe7c86..0000000000000000000000000000000000000000
--- a/package_bgs/db/IndependentMultimodalBGS.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-#include "IndependentMultimodalBGS.h"
-
-IndependentMultimodalBGS::IndependentMultimodalBGS() : fps(10), firstTime(true), showOutput(true){
-  pIMBS = new BackgroundSubtractorIMBS(fps);
-}
-IndependentMultimodalBGS::~IndependentMultimodalBGS(){
-  delete pIMBS;
-}
-
-void IndependentMultimodalBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
-{
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if (firstTime)
-    saveConfig();
-
-  //get the fgmask and update the background model
-  pIMBS->apply(img_input, img_foreground);
-  
-  //get background image
-  pIMBS->getBackgroundImage(img_background);
-
-  img_foreground.copyTo(img_output);
-  img_background.copyTo(img_bgmodel);
-
-  if (showOutput)
-  {
-    cv::imshow("IMBS FG", img_foreground);
-    cv::imshow("IMBS BG", img_background);
-  }
-
-  firstTime = false;
-}
-
-void IndependentMultimodalBGS::saveConfig()
-{
-  CvFileStorage* fs = cvOpenFileStorage("./config/IndependentMultimodalBGS.xml", 0, CV_STORAGE_WRITE);
-
-  cvWriteInt(fs, "showOutput", showOutput);
-
-  cvReleaseFileStorage(&fs);
-}
-
-void IndependentMultimodalBGS::loadConfig()
-{
-  CvFileStorage* fs = cvOpenFileStorage("./config/IndependentMultimodalBGS.xml", 0, CV_STORAGE_READ);
-
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
-
-  cvReleaseFileStorage(&fs);
-}
diff --git a/package_bgs/db/IndependentMultimodalBGS.h b/package_bgs/db/IndependentMultimodalBGS.h
deleted file mode 100644
index 64b83bde099398725cffea0dc26bf69843ae61f7..0000000000000000000000000000000000000000
--- a/package_bgs/db/IndependentMultimodalBGS.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-
-#include <opencv2/opencv.hpp>
-
-
-#include "imbs.hpp"
-
-#include "../IBGS.h"
-
-class IndependentMultimodalBGS : public IBGS
-{
-private:
-  BackgroundSubtractorIMBS* pIMBS;
-  int fps;
-  bool firstTime;
-  cv::Mat img_foreground;
-  cv::Mat img_background;
-  bool showOutput;
-  
-public:
-  IndependentMultimodalBGS();
-  ~IndependentMultimodalBGS();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
\ No newline at end of file
diff --git a/package_bgs/dp/AdaptiveMedianBGS.cpp b/package_bgs/dp/AdaptiveMedianBGS.cpp
index 16b3988c17c67cc60531f2cb9ea135d1336c6adc..da1add9124b0e3488df2fb2a57f4a2704f992c5c 100644
--- a/package_bgs/dp/AdaptiveMedianBGS.cpp
+++ b/package_bgs/dp/AdaptiveMedianBGS.cpp
@@ -18,7 +18,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * AdaptiveMedianBGS.cpp
 *
-* Purpose: Implementation of the simple adaptive median background 
+* Purpose: Implementation of the simple adaptive median background
 *		  		 subtraction algorithm described in:
 *	  			 "Segmentation and tracking of piglets in images"
 * 						by McFarlane and Schofield
@@ -37,77 +37,77 @@ using namespace Algorithms::BackgroundSubtraction;
 
 void AdaptiveMedianBGS::Initalize(const BgsParams& param)
 {
-	m_params = (AdaptiveMedianParams&)param;
+  m_params = (AdaptiveMedianParams&)param;
 
-	m_median = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 3);
-	cvSet(m_median.Ptr(), CV_RGB(BACKGROUND,BACKGROUND,BACKGROUND));
+  m_median = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 3);
+  cvSet(m_median.Ptr(), CV_RGB(BACKGROUND, BACKGROUND, BACKGROUND));
 }
 
 RgbImage* AdaptiveMedianBGS::Background()
 {
-	return &m_median;
+  return &m_median;
 }
 
 void AdaptiveMedianBGS::InitModel(const RgbImage& data)
 {
-	// initialize the background model
-	for (unsigned int r = 0; r < m_params.Height(); ++r)
-	{
-		for(unsigned int c = 0; c < m_params.Width(); ++c)
-		{
-			m_median(r,c) = data(r,c);
-		}
-	}
+  // initialize the background model
+  for (unsigned int r = 0; r < m_params.Height(); ++r)
+  {
+    for (unsigned int c = 0; c < m_params.Width(); ++c)
+    {
+      m_median(r, c) = data(r, c);
+    }
+  }
 }
 
-void AdaptiveMedianBGS::Update(int frame_num, const RgbImage& data,  const BwImage& update_mask)
+void AdaptiveMedianBGS::Update(int frame_num, const RgbImage& data, const BwImage& update_mask)
 {
-	if(frame_num % m_params.SamplingRate() == 1)
-	{
-		// update background model
-		for (unsigned int r = 0; r < m_params.Height(); ++r)
-		{
-			for(unsigned int c = 0; c < m_params.Width(); ++c)
-			{
-				// perform conditional updating only if we are passed the learning phase
-				if(update_mask(r,c) == BACKGROUND || frame_num < m_params.LearningFrames())
-				{
-					for(int ch = 0; ch < NUM_CHANNELS; ++ch)
-					{
-						if(data(r,c,ch) > m_median(r,c,ch))
-						{
-							m_median(r,c,ch)++;
-						}
-						else if(data(r,c,ch) < m_median(r,c,ch))
-						{
-							m_median(r,c,ch)--;
-						}
-					}
-				}
-			}
-		}
-	}
+  if (frame_num % m_params.SamplingRate() == 1)
+  {
+    // update background model
+    for (unsigned int r = 0; r < m_params.Height(); ++r)
+    {
+      for (unsigned int c = 0; c < m_params.Width(); ++c)
+      {
+        // perform conditional updating only if we are passed the learning phase
+        if (update_mask(r, c) == BACKGROUND || frame_num < m_params.LearningFrames())
+        {
+          for (int ch = 0; ch < NUM_CHANNELS; ++ch)
+          {
+            if (data(r, c, ch) > m_median(r, c, ch))
+            {
+              m_median(r, c, ch)++;
+            }
+            else if (data(r, c, ch) < m_median(r, c, ch))
+            {
+              m_median(r, c, ch)--;
+            }
+          }
+        }
+      }
+    }
+  }
 }
 
-void AdaptiveMedianBGS::SubtractPixel(int r, int c, const RgbPixel& pixel, 
-																			unsigned char& low_threshold, unsigned char& high_threshold)
+void AdaptiveMedianBGS::SubtractPixel(int r, int c, const RgbPixel& pixel,
+  unsigned char& low_threshold, unsigned char& high_threshold)
 {
-	// perform background subtraction
-	low_threshold = high_threshold = FOREGROUND;
-	
-	int diffR = abs(pixel(0) - m_median(r,c,0));
-	int diffG = abs(pixel(1) - m_median(r,c,1));
-	int diffB = abs(pixel(2) - m_median(r,c,2));
-	
-	if(diffR <= m_params.LowThreshold() && diffG <= m_params.LowThreshold() &&  diffB <= m_params.LowThreshold())
-	{
-		low_threshold = BACKGROUND;
-	}
-
-	if(diffR <= m_params.HighThreshold() && diffG <= m_params.HighThreshold() &&  diffB <= m_params.HighThreshold())
-	{
-		high_threshold = BACKGROUND;
-	}
+  // perform background subtraction
+  low_threshold = high_threshold = FOREGROUND;
+
+  int diffR = abs(pixel(0) - m_median(r, c, 0));
+  int diffG = abs(pixel(1) - m_median(r, c, 1));
+  int diffB = abs(pixel(2) - m_median(r, c, 2));
+
+  if (diffR <= m_params.LowThreshold() && diffG <= m_params.LowThreshold() && diffB <= m_params.LowThreshold())
+  {
+    low_threshold = BACKGROUND;
+  }
+
+  if (diffR <= m_params.HighThreshold() && diffG <= m_params.HighThreshold() && diffB <= m_params.HighThreshold())
+  {
+    high_threshold = BACKGROUND;
+  }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -118,23 +118,23 @@ void AdaptiveMedianBGS::SubtractPixel(int r, int c, const RgbPixel& pixel,
 //					(the memory should already be reserved) 
 //					values: 255-foreground, 0-background
 ///////////////////////////////////////////////////////////////////////////////
-void AdaptiveMedianBGS::Subtract(int frame_num, const RgbImage& data, 
-																	BwImage& low_threshold_mask, BwImage& high_threshold_mask)
+void AdaptiveMedianBGS::Subtract(int frame_num, const RgbImage& data,
+  BwImage& low_threshold_mask, BwImage& high_threshold_mask)
 {
-	unsigned char low_threshold, high_threshold;
-
-	// update each pixel of the image
-	for(unsigned int r = 0; r < m_params.Height(); ++r)
-	{
-		for(unsigned int c = 0; c < m_params.Width(); ++c)
-		{	
-			// perform background subtraction
-			SubtractPixel(r, c, data(r,c), low_threshold, high_threshold);
-
-			// setup silhouette mask
-			low_threshold_mask(r,c) = low_threshold;
-			high_threshold_mask(r,c) = high_threshold;
-		}
-	}
+  unsigned char low_threshold, high_threshold;
+
+  // update each pixel of the image
+  for (unsigned int r = 0; r < m_params.Height(); ++r)
+  {
+    for (unsigned int c = 0; c < m_params.Width(); ++c)
+    {
+      // perform background subtraction
+      SubtractPixel(r, c, data(r, c), low_threshold, high_threshold);
+
+      // setup silhouette mask
+      low_threshold_mask(r, c) = low_threshold;
+      high_threshold_mask(r, c) = high_threshold;
+    }
+  }
 }
 
diff --git a/package_bgs/dp/AdaptiveMedianBGS.h b/package_bgs/dp/AdaptiveMedianBGS.h
index d199b81896bae228d42d8685566502344ecbeb29..79a04b39ab60dae865fb0b38af2f1108c4e18df7 100644
--- a/package_bgs/dp/AdaptiveMedianBGS.h
+++ b/package_bgs/dp/AdaptiveMedianBGS.h
@@ -18,7 +18,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * AdaptiveMedianBGS.hpp
 *
-* Purpose: Implementation of the simple adaptive median background 
+* Purpose: Implementation of the simple adaptive median background
 *		  		 subtraction algorithm described in:
 *	  			 "Segmentation and tracking of piglets in images"
 * 						by McFarlane and Schofield
@@ -26,64 +26,65 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * Author: Donovan Parks, September 2007
 
 Example:
-		Algorithms::BackgroundSubtraction::AdaptiveMedianParams params;
-		params.SetFrameSize(width, height);
-		params.LowThreshold() = 40;
-		params.HighThreshold() = 2*params.LowThreshold();
-		params.SamplingRate() = 7;
-		params.LearningFrames() = 30;
-
-		Algorithms::BackgroundSubtraction::AdaptiveMedianBGS bgs;
-		bgs.Initalize(params);
+    Algorithms::BackgroundSubtraction::AdaptiveMedianParams params;
+    params.SetFrameSize(width, height);
+    params.LowThreshold() = 40;
+    params.HighThreshold() = 2*params.LowThreshold();
+    params.SamplingRate() = 7;
+    params.LearningFrames() = 30;
+
+    Algorithms::BackgroundSubtraction::AdaptiveMedianBGS bgs;
+    bgs.Initalize(params);
 ******************************************************************************/
+#pragma once
 
 #include "Bgs.h"
 
 namespace Algorithms
 {
-	namespace BackgroundSubtraction
-	{
-		// --- Parameters used by the Adaptive Median BGS algorithm ---
-		class AdaptiveMedianParams : public BgsParams
-		{
-		public:
-			unsigned char &LowThreshold() { return m_low_threshold; }
-			unsigned char &HighThreshold() { return m_high_threshold; }
+  namespace BackgroundSubtraction
+  {
+    // --- Parameters used by the Adaptive Median BGS algorithm ---
+    class AdaptiveMedianParams : public BgsParams
+    {
+    public:
+      unsigned char &LowThreshold() { return m_low_threshold; }
+      unsigned char &HighThreshold() { return m_high_threshold; }
 
-			int &SamplingRate() { return m_samplingRate; }
-			int &LearningFrames() { return m_learning_frames; }
+      int &SamplingRate() { return m_samplingRate; }
+      int &LearningFrames() { return m_learning_frames; }
 
-		private:
-			unsigned char m_low_threshold;
-			unsigned char m_high_threshold;
+    private:
+      unsigned char m_low_threshold;
+      unsigned char m_high_threshold;
 
-			int m_samplingRate;
-			int m_learning_frames;
-		};
+      int m_samplingRate;
+      int m_learning_frames;
+    };
 
 
-		// --- Adaptive Median BGS algorithm ---
-		class AdaptiveMedianBGS : public Bgs 
-		{
-		public:
-			virtual ~AdaptiveMedianBGS() {}
+    // --- Adaptive Median BGS algorithm ---
+    class AdaptiveMedianBGS : public Bgs
+    {
+    public:
+      virtual ~AdaptiveMedianBGS() {}
 
-			void Initalize(const BgsParams& param);
+      void Initalize(const BgsParams& param);
 
-			void InitModel(const RgbImage& data);
-			void Subtract(int frame_num, const RgbImage& data,  
-											BwImage& low_threshold_mask, BwImage& high_threshold_mask);	
-			void Update(int frame_num, const RgbImage& data,  const BwImage& update_mask);
+      void InitModel(const RgbImage& data);
+      void Subtract(int frame_num, const RgbImage& data,
+        BwImage& low_threshold_mask, BwImage& high_threshold_mask);
+      void Update(int frame_num, const RgbImage& data, const BwImage& update_mask);
 
-			RgbImage* Background();
+      RgbImage* Background();
 
-		private:	
-			void SubtractPixel(int r, int c, const RgbPixel& pixel, 
-													unsigned char& low_threshold, unsigned char& high_threshold);
+    private:
+      void SubtractPixel(int r, int c, const RgbPixel& pixel,
+        unsigned char& low_threshold, unsigned char& high_threshold);
 
-			AdaptiveMedianParams m_params;
+      AdaptiveMedianParams m_params;
 
-			RgbImage m_median;
-		};
-	}
+      RgbImage m_median;
+    };
+  }
 }
diff --git a/package_bgs/dp/Bgs.h b/package_bgs/dp/Bgs.h
index 5f91246e0aa87fd2a43e86d58e663998fbb56e7c..26fff70ea503cfb5737f53ae1991efbb529ff598 100644
--- a/package_bgs/dp/Bgs.h
+++ b/package_bgs/dp/Bgs.h
@@ -23,45 +23,41 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * Author: Donovan Parks, October 2007
 *
 ******************************************************************************/
-
-#ifndef BGS_H_
-#define BGS_H_
+#pragma once
 
 #include "Image.h"
 #include "BgsParams.h"
 
 namespace Algorithms
 {
-	namespace BackgroundSubtraction
-	{
-		class Bgs
-		{
-		public:
-			static const int BACKGROUND = 0;
-			static const int FOREGROUND = 255;
+namespace BackgroundSubtraction
+{
+class Bgs
+{
+public:
+  static const int BACKGROUND = 0;
+  static const int FOREGROUND = 255;
 
-			virtual ~Bgs() {}
+  virtual ~Bgs() {}
 
-			// Initialize any data required by the BGS algorithm. Should be called once before calling
-			// any of the following functions.
-			virtual void Initalize(const BgsParams& param) = 0;
+  // Initialize any data required by the BGS algorithm. Should be called once before calling
+  // any of the following functions.
+  virtual void Initalize(const BgsParams& param) = 0;
 
-			// Initialize the background model. Typically, the background model is initialized using the first
-			// frame of the incoming video stream, but alternatives are possible.
-			virtual void InitModel(const RgbImage& data) = 0;
+  // Initialize the background model. Typically, the background model is initialized using the first
+  // frame of the incoming video stream, but alternatives are possible.
+  virtual void InitModel(const RgbImage& data) = 0;
 
-			// Subtract the current frame from the background model and produce a binary foreground mask using
-			// both a low and high threshold value.
-			virtual void Subtract(int frame_num, const RgbImage& data,  
-															BwImage& low_threshold_mask, BwImage& high_threshold_mask) = 0;	
+  // Subtract the current frame from the background model and produce a binary foreground mask using
+  // both a low and high threshold value.
+  virtual void Subtract(int frame_num, const RgbImage& data,
+                        BwImage& low_threshold_mask, BwImage& high_threshold_mask) = 0;
 
-			// Update the background model. Only pixels set to background in update_mask are updated.
-			virtual void Update(int frame_num, const RgbImage& data,  const BwImage& update_mask) = 0;
+  // Update the background model. Only pixels set to background in update_mask are updated.
+  virtual void Update(int frame_num, const RgbImage& data,  const BwImage& update_mask) = 0;
 
-			// Return the current background model.
-			virtual RgbImage *Background() = 0;
-		};
-	}
+  // Return the current background model.
+  virtual RgbImage *Background() = 0;
+};
+}
 }
-
-#endif
diff --git a/package_bgs/dp/BgsParams.h b/package_bgs/dp/BgsParams.h
index a63b1ac3cff432124bd0608c20f586f0e97eefab..d2e7d29e084cffc798f968c0290b304e62071a50 100644
--- a/package_bgs/dp/BgsParams.h
+++ b/package_bgs/dp/BgsParams.h
@@ -24,36 +24,32 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * Author: Donovan Parks, May 2008
 *
 ******************************************************************************/
-
-#ifndef BGS_PARAMS_H_
-#define BGS_PARAMS_H_
+#pragma once
 
 namespace Algorithms
 {
-	namespace BackgroundSubtraction
-	{
-		class BgsParams
-		{
-		public:
-			virtual ~BgsParams() {}
-
-			virtual void SetFrameSize(unsigned int width, unsigned int height)
-			{
-				m_width = width;
-				m_height = height;
-				m_size = width*height;
-			}
-
-			unsigned int &Width() { return m_width; }
-			unsigned int &Height() { return m_height; }
-			unsigned int &Size() { return m_size; }
-
-		protected:
-			unsigned int m_width;
-			unsigned int m_height;
-			unsigned int m_size;
-		};
-	}
+namespace BackgroundSubtraction
+{
+class BgsParams
+{
+public:
+  virtual ~BgsParams() {}
+
+  virtual void SetFrameSize(unsigned int width, unsigned int height)
+  {
+    m_width = width;
+    m_height = height;
+    m_size = width*height;
+  }
+
+  unsigned int &Width() { return m_width; }
+  unsigned int &Height() { return m_height; }
+  unsigned int &Size() { return m_size; }
+
+protected:
+  unsigned int m_width;
+  unsigned int m_height;
+  unsigned int m_size;
+};
+}
 }
-
-#endif
diff --git a/package_bgs/dp/DPAdaptiveMedianBGS.cpp b/package_bgs/dp/DPAdaptiveMedianBGS.cpp
deleted file mode 100644
index 0ae68fe830c77accbac22ac58227a56785a326fe..0000000000000000000000000000000000000000
--- a/package_bgs/dp/DPAdaptiveMedianBGS.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
-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 "DPAdaptiveMedianBGS.h"
-
-DPAdaptiveMedianBGS::DPAdaptiveMedianBGS() : firstTime(true), frameNumber(0), threshold(40), samplingRate(7), learningFrames(30), showOutput(true) 
-{
-  std::cout << "DPAdaptiveMedianBGS()" << std::endl;
-}
-
-DPAdaptiveMedianBGS::~DPAdaptiveMedianBGS()
-{
-  std::cout << "~DPAdaptiveMedianBGS()" << std::endl;
-}
-
-void DPAdaptiveMedianBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
-{
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if(firstTime)
-    saveConfig();
-
-  frame = new IplImage(img_input);
-  
-  if(firstTime)
-    frame_data.ReleaseMemory(false);
-  frame_data = frame;
-
-  if(firstTime)
-  {
-    int width	= img_input.size().width;
-    int height = img_input.size().height;
-
-    lowThresholdMask = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
-    lowThresholdMask.Ptr()->origin = IPL_ORIGIN_BL;
-
-    highThresholdMask = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
-    highThresholdMask.Ptr()->origin = IPL_ORIGIN_BL;
-
-    params.SetFrameSize(width, height);
-    params.LowThreshold() = threshold;
-    params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing 
-    params.SamplingRate() = samplingRate;
-    params.LearningFrames() = learningFrames;
-    
-    bgs.Initalize(params);
-    bgs.InitModel(frame_data);
-
-    std::cout << "threshold: " << threshold << std::endl;
-    std::cout << "samplingRate: " << samplingRate << std::endl;
-    std::cout << "learningFrames: " << learningFrames << std::endl;
-    std::cout << "showOutput: " << showOutput << std::endl;
-  }
-
-  bgs.Subtract(frameNumber, frame_data, lowThresholdMask, highThresholdMask);
-  lowThresholdMask.Clear();
-  bgs.Update(frameNumber, frame_data, lowThresholdMask);
-  
-  cv::Mat foreground(highThresholdMask.Ptr());
-  cv::Mat background(bgs.Background()->Ptr());
-
-  if(showOutput){
-    cv::imshow("Adaptive Median FG (McFarlane&Schofield)", foreground);
-    cv::imshow("Adaptive Median BG (McFarlane&Schofield)", background);
-  }
-  
-  foreground.copyTo(img_output);
-  background.copyTo(img_bgmodel);
-
-  delete frame;
-  firstTime = false;
-  frameNumber++;
-}
-
-void DPAdaptiveMedianBGS::saveConfig()
-{
-  CvFileStorage* fs = cvOpenFileStorage("./config/DPAdaptiveMedianBGS.xml", 0, CV_STORAGE_WRITE);
-
-  cvWriteInt(fs, "threshold", threshold);
-  cvWriteInt(fs, "samplingRate", samplingRate);
-  cvWriteInt(fs, "learningFrames", learningFrames);
-  cvWriteInt(fs, "showOutput", showOutput);
-
-  cvReleaseFileStorage(&fs);
-}
-
-void DPAdaptiveMedianBGS::loadConfig()
-{
-  CvFileStorage* fs = cvOpenFileStorage("./config/DPAdaptiveMedianBGS.xml", 0, CV_STORAGE_READ);
-  
-  threshold = cvReadIntByName(fs, 0, "threshold", 40);
-  samplingRate = cvReadIntByName(fs, 0, "samplingRate", 7);
-  learningFrames = cvReadIntByName(fs, 0, "learningFrames", 30);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
-
-  cvReleaseFileStorage(&fs);
-}
diff --git a/package_bgs/dp/DPAdaptiveMedianBGS.h b/package_bgs/dp/DPAdaptiveMedianBGS.h
deleted file mode 100644
index a5dd3879b383f91664b22341e433a6683aed4407..0000000000000000000000000000000000000000
--- a/package_bgs/dp/DPAdaptiveMedianBGS.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-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
-
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-#include "AdaptiveMedianBGS.h"
-
-using namespace Algorithms::BackgroundSubtraction;
-
-class DPAdaptiveMedianBGS : public IBGS
-{
-private:
-  bool firstTime;
-  long frameNumber;
-  IplImage* frame;
-  RgbImage frame_data;
-
-  AdaptiveMedianParams params;
-  AdaptiveMedianBGS bgs;
-  BwImage lowThresholdMask;
-  BwImage highThresholdMask;
-
-  int threshold;
-  int samplingRate;
-  int learningFrames;
-  bool showOutput;
-
-public:
-  DPAdaptiveMedianBGS();
-  ~DPAdaptiveMedianBGS();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
-
diff --git a/package_bgs/dp/DPPratiMediodBGS.h b/package_bgs/dp/DPPratiMediodBGS.h
deleted file mode 100644
index 8aa641622bf1d57c7e4e3540ceafcf7ed4b5fdcf..0000000000000000000000000000000000000000
--- a/package_bgs/dp/DPPratiMediodBGS.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-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
-
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-#include "PratiMediodBGS.h"
-
-using namespace Algorithms::BackgroundSubtraction;
-
-class DPPratiMediodBGS : public IBGS
-{
-private:
-  bool firstTime;
-  long frameNumber;
-  IplImage* frame;
-  RgbImage frame_data;
-
-  PratiParams params;
-  PratiMediodBGS bgs;
-  BwImage lowThresholdMask;
-  BwImage highThresholdMask;
-
-  int threshold;
-  int samplingRate;
-  int historySize;
-  int weight;
-  bool showOutput;
-
-public:
-  DPPratiMediodBGS();
-  ~DPPratiMediodBGS();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
-
diff --git a/package_bgs/dp/DPTextureBGS.h b/package_bgs/dp/DPTextureBGS.h
deleted file mode 100644
index c29e7e92d5048348d67e080b377ed227b1874967..0000000000000000000000000000000000000000
--- a/package_bgs/dp/DPTextureBGS.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-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
-
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-#include "TextureBGS.h"
-//#include "ConnectedComponents.h"
-
-class DPTextureBGS : public IBGS
-{
-private:
-  bool firstTime;
-  bool showOutput;
-
-  int width;
-  int height;
-  int size;
-  TextureBGS bgs;
-  IplImage* frame;
-  RgbImage image;
-  BwImage fgMask;
-  BwImage tempMask;
-  TextureArray* bgModel;
-  RgbImage texture;
-  unsigned char* modeArray;
-  TextureHistogram* curTextureHist;
-  //ConnectedComponents cc;
-  //CBlobResult largeBlobs;
-  //IplConvKernel* dilateElement;
-  //IplConvKernel* erodeElement;
-  //bool enableFiltering;
-
-public:
-  DPTextureBGS();
-  ~DPTextureBGS();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
diff --git a/package_bgs/dp/Eigenbackground.cpp b/package_bgs/dp/Eigenbackground.cpp
index 2d2c3ef3d85a26d0653e7b17f3486a4e4affa903..dceb4cd2c4442d53703bf21ea957ed341535fd64 100644
--- a/package_bgs/dp/Eigenbackground.cpp
+++ b/package_bgs/dp/Eigenbackground.cpp
@@ -18,7 +18,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Eigenbackground.cpp
 *
-* Purpose: Implementation of the Eigenbackground background subtraction 
+* Purpose: Implementation of the Eigenbackground background subtraction
 *					 algorithm developed by Oliver et al.
 *
 * Author: Donovan Parks, September 2007
@@ -34,157 +34,157 @@ using namespace Algorithms::BackgroundSubtraction;
 
 Eigenbackground::Eigenbackground()
 {
-	m_pcaData = NULL;
-	m_pcaAvg = NULL;
-	m_eigenValues = NULL;
-	m_eigenVectors = NULL;
+  m_pcaData = NULL;
+  m_pcaAvg = NULL;
+  m_eigenValues = NULL;
+  m_eigenVectors = NULL;
 }
 
 Eigenbackground::~Eigenbackground()
 {
-	if(m_pcaData != NULL) cvReleaseMat(&m_pcaData);
-	if(m_pcaAvg != NULL) cvReleaseMat(&m_pcaAvg);
-	if(m_eigenValues != NULL) cvReleaseMat(&m_eigenValues);
-	if(m_eigenVectors != NULL) cvReleaseMat(&m_eigenVectors);
+  if (m_pcaData != NULL) cvReleaseMat(&m_pcaData);
+  if (m_pcaAvg != NULL) cvReleaseMat(&m_pcaAvg);
+  if (m_eigenValues != NULL) cvReleaseMat(&m_eigenValues);
+  if (m_eigenVectors != NULL) cvReleaseMat(&m_eigenVectors);
 }
 
 void Eigenbackground::Initalize(const BgsParams& param)
 {
-	m_params = (EigenbackgroundParams&)param;
-	
-	m_background = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 3);
-	m_background.Clear();
+  m_params = (EigenbackgroundParams&)param;
+
+  m_background = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 3);
+  m_background.Clear();
 }
 
 void Eigenbackground::InitModel(const RgbImage& data)
 {
-	if(m_pcaData != NULL) cvReleaseMat(&m_pcaData);
-	if(m_pcaAvg != NULL) cvReleaseMat(&m_pcaAvg);
-	if(m_eigenValues != NULL) cvReleaseMat(&m_eigenValues);
-	if(m_eigenVectors != NULL) cvReleaseMat(&m_eigenVectors);
+  if (m_pcaData != NULL) cvReleaseMat(&m_pcaData);
+  if (m_pcaAvg != NULL) cvReleaseMat(&m_pcaAvg);
+  if (m_eigenValues != NULL) cvReleaseMat(&m_eigenValues);
+  if (m_eigenVectors != NULL) cvReleaseMat(&m_eigenVectors);
 
-	m_pcaData = cvCreateMat(m_params.HistorySize(), m_params.Size()*3, CV_8UC1);
+  m_pcaData = cvCreateMat(m_params.HistorySize(), m_params.Size() * 3, CV_8UC1);
 
-	m_background.Clear();
+  m_background.Clear();
 }
 
-void Eigenbackground::Update(int frame_num, const RgbImage& data,  const BwImage& update_mask)
+void Eigenbackground::Update(int frame_num, const RgbImage& data, const BwImage& update_mask)
 {
-	// the eigenbackground model is not updated (serious limitation!)
+  // the eigenbackground model is not updated (serious limitation!)
 }
 
-void Eigenbackground::Subtract(int frame_num, const RgbImage& data,  
-																BwImage& low_threshold_mask, BwImage& high_threshold_mask)
+void Eigenbackground::Subtract(int frame_num, const RgbImage& data,
+  BwImage& low_threshold_mask, BwImage& high_threshold_mask)
 {
-	// create eigenbackground
-	if(frame_num == m_params.HistorySize())
-	{
-		// create the eigenspace
-		m_pcaAvg = cvCreateMat( 1, m_pcaData->cols, CV_32F );
-		m_eigenValues = cvCreateMat( m_pcaData->rows, 1, CV_32F ); 
-		m_eigenVectors = cvCreateMat( m_pcaData->rows, m_pcaData->cols, CV_32F );
-		cvCalcPCA(m_pcaData, m_pcaAvg, m_eigenValues, m_eigenVectors, CV_PCA_DATA_AS_ROW);
-
-		int index = 0;
-		for(unsigned int r = 0; r < m_params.Height(); ++r)
-		{
-			for(unsigned int c = 0; c < m_params.Width(); ++c)
-			{
-				for(int ch = 0; ch < m_background.Ptr()->nChannels; ++ch)
-				{
-					m_background(r,c,0) = static_cast<unsigned char>(cvmGet(m_pcaAvg,0,index)+0.5);
-					index++;
-				}
-			}
-		}
-	}
-
-	if(frame_num >= m_params.HistorySize())
-	{
-		// project new image into the eigenspace
-		int w = data.Ptr()->width;
-		int h = data.Ptr()->height;
-		int ch = data.Ptr()->nChannels;
-		CvMat* dataPt = cvCreateMat(1, w*h*ch, CV_8UC1); 
-		CvMat data_row;
-		cvGetRow(dataPt, &data_row, 0);
-		cvReshape(&data_row, &data_row, 3, data.Ptr()->height); 
-		cvCopy(data.Ptr(), &data_row); 
-
-		CvMat* proj = cvCreateMat(1, m_params.EmbeddedDim(), CV_32F);
-		cvProjectPCA(dataPt, m_pcaAvg, m_eigenVectors, proj);
-
-		// reconstruct point
-		CvMat* result = cvCreateMat(1, m_pcaData->cols, CV_32F);
-		cvBackProjectPCA(proj, m_pcaAvg, m_eigenVectors, result);
-
-		// calculate Euclidean distance between new image and its eigenspace projection
-		int index = 0;
-		for(unsigned int r = 0; r < m_params.Height(); ++r)
-		{
-			for(unsigned int c = 0; c < m_params.Width(); ++c)
-			{
-				double dist = 0;
-				bool bgLow = true;
-				bool bgHigh = true;
-				for(int ch = 0; ch < 3; ++ch)
-				{
-					dist = (data(r,c,ch) - cvmGet(result,0,index))*(data(r,c,ch) - cvmGet(result,0,index));
-					if(dist > m_params.LowThreshold())
-						bgLow = false;
-					if(dist > m_params.HighThreshold())
-						bgHigh = false;
-					index++;
-				}
-				
-				if(!bgLow)
-				{
-					low_threshold_mask(r,c) = FOREGROUND;
-				}
-				else
-				{
-					low_threshold_mask(r,c) = BACKGROUND;
-				}
-
-				if(!bgHigh)
-				{
-					high_threshold_mask(r,c) = FOREGROUND;
-				}
-				else
-				{
-					high_threshold_mask(r,c) = BACKGROUND;
-				}
-			}
-		}
-		
-		cvReleaseMat(&result);
-		cvReleaseMat(&proj);		
-		cvReleaseMat(&dataPt);
-	}
-	else 
-	{
-		// set entire image to background since there is not enough information yet
-		// to start performing background subtraction
-		for(unsigned int r = 0; r < m_params.Height(); ++r)
-		{
-			for(unsigned int c = 0; c < m_params.Width(); ++c)
-			{
-				low_threshold_mask(r,c) = BACKGROUND;
-				high_threshold_mask(r,c) = BACKGROUND;
-			}
-		}
-	}
-
-	UpdateHistory(frame_num, data);
+  // create eigenbackground
+  if (frame_num == m_params.HistorySize())
+  {
+    // create the eigenspace
+    m_pcaAvg = cvCreateMat(1, m_pcaData->cols, CV_32F);
+    m_eigenValues = cvCreateMat(m_pcaData->rows, 1, CV_32F);
+    m_eigenVectors = cvCreateMat(m_pcaData->rows, m_pcaData->cols, CV_32F);
+    cvCalcPCA(m_pcaData, m_pcaAvg, m_eigenValues, m_eigenVectors, CV_PCA_DATA_AS_ROW);
+
+    int index = 0;
+    for (unsigned int r = 0; r < m_params.Height(); ++r)
+    {
+      for (unsigned int c = 0; c < m_params.Width(); ++c)
+      {
+        for (int ch = 0; ch < m_background.Ptr()->nChannels; ++ch)
+        {
+          m_background(r, c, 0) = static_cast<unsigned char>(cvmGet(m_pcaAvg, 0, index) + 0.5);
+          index++;
+        }
+      }
+    }
+  }
+
+  if (frame_num >= m_params.HistorySize())
+  {
+    // project new image into the eigenspace
+    int w = data.Ptr()->width;
+    int h = data.Ptr()->height;
+    int ch = data.Ptr()->nChannels;
+    CvMat* dataPt = cvCreateMat(1, w*h*ch, CV_8UC1);
+    CvMat data_row;
+    cvGetRow(dataPt, &data_row, 0);
+    cvReshape(&data_row, &data_row, 3, data.Ptr()->height);
+    cvCopy(data.Ptr(), &data_row);
+
+    CvMat* proj = cvCreateMat(1, m_params.EmbeddedDim(), CV_32F);
+    cvProjectPCA(dataPt, m_pcaAvg, m_eigenVectors, proj);
+
+    // reconstruct point
+    CvMat* result = cvCreateMat(1, m_pcaData->cols, CV_32F);
+    cvBackProjectPCA(proj, m_pcaAvg, m_eigenVectors, result);
+
+    // calculate Euclidean distance between new image and its eigenspace projection
+    int index = 0;
+    for (unsigned int r = 0; r < m_params.Height(); ++r)
+    {
+      for (unsigned int c = 0; c < m_params.Width(); ++c)
+      {
+        double dist = 0;
+        bool bgLow = true;
+        bool bgHigh = true;
+        for (int ch = 0; ch < 3; ++ch)
+        {
+          dist = (data(r, c, ch) - cvmGet(result, 0, index))*(data(r, c, ch) - cvmGet(result, 0, index));
+          if (dist > m_params.LowThreshold())
+            bgLow = false;
+          if (dist > m_params.HighThreshold())
+            bgHigh = false;
+          index++;
+        }
+
+        if (!bgLow)
+        {
+          low_threshold_mask(r, c) = FOREGROUND;
+        }
+        else
+        {
+          low_threshold_mask(r, c) = BACKGROUND;
+        }
+
+        if (!bgHigh)
+        {
+          high_threshold_mask(r, c) = FOREGROUND;
+        }
+        else
+        {
+          high_threshold_mask(r, c) = BACKGROUND;
+        }
+      }
+    }
+
+    cvReleaseMat(&result);
+    cvReleaseMat(&proj);
+    cvReleaseMat(&dataPt);
+  }
+  else
+  {
+    // set entire image to background since there is not enough information yet
+    // to start performing background subtraction
+    for (unsigned int r = 0; r < m_params.Height(); ++r)
+    {
+      for (unsigned int c = 0; c < m_params.Width(); ++c)
+      {
+        low_threshold_mask(r, c) = BACKGROUND;
+        high_threshold_mask(r, c) = BACKGROUND;
+      }
+    }
+  }
+
+  UpdateHistory(frame_num, data);
 }
 
 void Eigenbackground::UpdateHistory(int frame_num, const RgbImage& new_frame)
 {
-	if(frame_num < m_params.HistorySize())
-	{
-		CvMat src_row;
-		cvGetRow(m_pcaData, &src_row, frame_num);
-		cvReshape(&src_row, &src_row, 3, new_frame.Ptr()->height);
-		cvCopy(new_frame.Ptr(), &src_row);
-	}
+  if (frame_num < m_params.HistorySize())
+  {
+    CvMat src_row;
+    cvGetRow(m_pcaData, &src_row, frame_num);
+    cvReshape(&src_row, &src_row, 3, new_frame.Ptr()->height);
+    cvCopy(new_frame.Ptr(), &src_row);
+  }
 }
diff --git a/package_bgs/dp/Eigenbackground.h b/package_bgs/dp/Eigenbackground.h
index 721b7356e453be4903f19698de7b2b4b150578e7..10ed189696c08296181fc0c1eb54a61a81f2dd7a 100644
--- a/package_bgs/dp/Eigenbackground.h
+++ b/package_bgs/dp/Eigenbackground.h
@@ -18,7 +18,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Eigenbackground.hpp
 *
-* Purpose: Implementation of the Eigenbackground background subtraction 
+* Purpose: Implementation of the Eigenbackground background subtraction
 *					 algorithm developed by Oliver et al.
 *
 * Author: Donovan Parks, September 2007
@@ -30,16 +30,14 @@ Example:
 Algorithms::BackgroundSubtraction::EigenbackgroundParams params;
 params.SetFrameSize(width, height);
 params.LowThreshold() = 15*15;
-params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing 
+params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing
 params.HistorySize() = 100;
 params.EmbeddedDim() = 20;
 
 Algorithms::BackgroundSubtraction::Eigenbackground bgs;
 bgs.Initalize(params);
 ******************************************************************************/
-
-#ifndef _ELGAMMAL_H_
-#define _ELGAMMAL_H_
+#pragma once
 
 #include "Bgs.h"
 
@@ -77,9 +75,9 @@ namespace Algorithms
       void Initalize(const BgsParams& param);
 
       void InitModel(const RgbImage& data);
-      void Subtract(int frame_num, const RgbImage& data,  
-        BwImage& low_threshold_mask, BwImage& high_threshold_mask);	
-      void Update(int frame_num, const RgbImage& data,  const BwImage& update_mask);
+      void Subtract(int frame_num, const RgbImage& data,
+        BwImage& low_threshold_mask, BwImage& high_threshold_mask);
+      void Update(int frame_num, const RgbImage& data, const BwImage& update_mask);
 
       RgbImage* Background() { return &m_background; }
 
@@ -90,12 +88,10 @@ namespace Algorithms
 
       CvMat* m_pcaData;
       CvMat* m_pcaAvg;
-      CvMat* m_eigenValues; 
+      CvMat* m_eigenValues;
       CvMat* m_eigenVectors;
 
       RgbImage m_background;
     };
   }
 }
-
-#endif
diff --git a/package_bgs/dp/Error.h b/package_bgs/dp/Error.h
index cdbb222c4bdc9ec92b5c2aad3bd02c06fd39c2b9..81cbbebcf8181bc40bddc526bc3ebb88ec6a0ea8 100644
--- a/package_bgs/dp/Error.h
+++ b/package_bgs/dp/Error.h
@@ -23,14 +23,9 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * Author: Donovan Parks, July 2007
 *
 ******************************************************************************/
-
-#ifndef ERROR_H
-#define ERROR_H
+#pragma once
 
 bool Error(const char* msg, const char* code, int data);
-
 bool TraceInit(const char* filename);
 void Trace(const char* msg);
 void TraceClose();
-
-#endif
diff --git a/package_bgs/dp/GrimsonGMM.cpp b/package_bgs/dp/GrimsonGMM.cpp
index ff9c26261b4775d89f8207da29c646e001087877..4cf6f35e8e9ae30c19481c8fbcc7ef4f250df15f 100644
--- a/package_bgs/dp/GrimsonGMM.cpp
+++ b/package_bgs/dp/GrimsonGMM.cpp
@@ -18,7 +18,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * GrimsonGMM.cpp
 *
-* Purpose: Implementation of the Gaussian mixture model (GMM) background 
+* Purpose: Implementation of the Gaussian mixture model (GMM) background
 *		  		 subtraction described in:
 *	  			 "Adaptive background mixture models for real-time tracking"
 * 						by Chris Stauffer and W.E.L Grimson
@@ -26,16 +26,16 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * Author: Donovan Parks, September 2007
 *
 * This code is based on code by Z. Zivkovic's written for his enhanced GMM
-* background subtraction algorithm: 
+* background subtraction algorithm:
 *
 *	"Improved adaptive Gausian mixture model for background subtraction"
-*		Z.Zivkovic 
+*		Z.Zivkovic
 *		International Conference Pattern Recognition, UK, August, 2004
 *
 *
-* "Efficient Adaptive Density Estimapion per Image Pixel for the 
+* "Efficient Adaptive Density Estimapion per Image Pixel for the
 *			Task of Background Subtraction"
-*		Z.Zivkovic, F. van der Heijden 
+*		Z.Zivkovic, F. van der Heijden
 *		Pattern Recognition Letters, vol. 27, no. 7, pages 773-780, 2006.
 *
 * Zivkovic's code can be obtained at: www.zoranz.net
@@ -47,252 +47,252 @@ using namespace Algorithms::BackgroundSubtraction;
 
 int compareGMM(const void* _gmm1, const void* _gmm2)
 {
-	GMM gmm1 = *(GMM*)_gmm1;
-	GMM gmm2 = *(GMM*)_gmm2;
-
-	if(gmm1.significants < gmm2.significants)
-		return 1;
-	else if(gmm1.significants == gmm2.significants)
-		return 0;
-	else
-		return -1;
+  GMM gmm1 = *(GMM*)_gmm1;
+  GMM gmm2 = *(GMM*)_gmm2;
+
+  if (gmm1.significants < gmm2.significants)
+    return 1;
+  else if (gmm1.significants == gmm2.significants)
+    return 0;
+  else
+    return -1;
 }
 
 GrimsonGMM::GrimsonGMM()
 {
-	m_modes = NULL;
+  m_modes = NULL;
 }
 
 GrimsonGMM::~GrimsonGMM()
 {
-	delete[] m_modes;
+  delete[] m_modes;
 }
 
 void GrimsonGMM::Initalize(const BgsParams& param)
 {
-	m_params = (GrimsonParams&)param;
+  m_params = (GrimsonParams&)param;
 
-	// Tbf - the threshold
-	m_bg_threshold = 0.75f;	// 1-cf from the paper 
+  // Tbf - the threshold
+  m_bg_threshold = 0.75f;	// 1-cf from the paper
 
-	// Tgenerate - the threshold
-	m_variance = 36.0f;		// sigma for the new mode
+  // Tgenerate - the threshold
+  m_variance = 36.0f;		// sigma for the new mode
 
-	// GMM for each pixel
-	m_modes = new GMM[m_params.Size()*m_params.MaxModes()];
+  // GMM for each pixel
+  m_modes = new GMM[m_params.Size()*m_params.MaxModes()];
 
-	// used modes per pixel
-	m_modes_per_pixel = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 1);
+  // used modes per pixel
+  m_modes_per_pixel = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 1);
 
-	m_background = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 3);
+  m_background = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 3);
 }
 
 RgbImage* GrimsonGMM::Background()
 {
-	return &m_background;
+  return &m_background;
 }
 
 void GrimsonGMM::InitModel(const RgbImage& data)
 {
-	m_modes_per_pixel.Clear();
-
-	for(unsigned int i = 0; i < m_params.Size()*m_params.MaxModes(); ++i)
-	{
-		m_modes[i].weight = 0;
-		m_modes[i].variance = 0;
-		m_modes[i].muR = 0;
-		m_modes[i].muG = 0;
-		m_modes[i].muB = 0;
-		m_modes[i].significants = 0;
-	}
+  m_modes_per_pixel.Clear();
+
+  for (unsigned int i = 0; i < m_params.Size()*m_params.MaxModes(); ++i)
+  {
+    m_modes[i].weight = 0;
+    m_modes[i].variance = 0;
+    m_modes[i].muR = 0;
+    m_modes[i].muG = 0;
+    m_modes[i].muB = 0;
+    m_modes[i].significants = 0;
+  }
 }
 
-void GrimsonGMM::Update(int frame_num, const RgbImage& data,  const BwImage& update_mask)
+void GrimsonGMM::Update(int frame_num, const RgbImage& data, const BwImage& update_mask)
 {
-	// it doesn't make sense to have conditional updates in the GMM framework
+  // it doesn't make sense to have conditional updates in the GMM framework
 }
 
-void GrimsonGMM::SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned char& numModes, 
-																	unsigned char& low_threshold, unsigned char& high_threshold)
+void GrimsonGMM::SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned char& numModes,
+  unsigned char& low_threshold, unsigned char& high_threshold)
 {
-	// calculate distances to the modes (+ sort???)
-	// here we need to go in descending order!!!
-	long pos;
-	bool bFitsPDF=false;
-	bool bBackgroundLow=false;
-	bool bBackgroundHigh=false;
-
-	float fOneMinAlpha = 1-m_params.Alpha();
-
-	float totalWeight = 0.0f;
-
-	// calculate number of Gaussians to include in the background model
-	int backgroundGaussians = 0;
-	double sum = 0.0;
-	for(int i = 0; i < numModes; ++i)
-	{
-		if(sum < m_bg_threshold)
-		{
-			backgroundGaussians++;
-			sum += m_modes[posPixel+i].weight;
-		}
-		else
-		{
-			break;
-		}
-	}
-
-	// update all distributions and check for match with current pixel
-	for (int iModes=0; iModes < numModes; iModes++)
-	{
-		pos=posPixel+iModes;
-		float weight = m_modes[pos].weight;
-
-		// fit not found yet
-		if (!bFitsPDF)
-		{
-			//check if it belongs to some of the modes
-			//calculate distance
-			float var = m_modes[pos].variance;
-			float muR = m_modes[pos].muR;
-			float muG = m_modes[pos].muG;
-			float muB = m_modes[pos].muB;
-		
-			float dR=muR - pixel(0);
-			float dG=muG - pixel(1);
-			float dB=muB - pixel(2);
-
-			// calculate the squared distance
-			float dist = (dR*dR + dG*dG + dB*dB);
-
-			if(dist < m_params.HighThreshold()*var && iModes < backgroundGaussians)
-				bBackgroundHigh = true;
-			
-			// a match occurs when the pixel is within sqrt(fTg) standard deviations of the distribution
-			if(dist < m_params.LowThreshold()*var)
-			{
-				bFitsPDF=true;
-
-				// check if this Gaussian is part of the background model
-				if(iModes < backgroundGaussians) 
-					bBackgroundLow = true;
-
-				//update distribution
-				float k = m_params.Alpha()/weight;
-				weight = fOneMinAlpha*weight + m_params.Alpha();
-				m_modes[pos].weight = weight;
-				m_modes[pos].muR = muR - k*(dR);
-				m_modes[pos].muG = muG - k*(dG);
-				m_modes[pos].muB = muB - k*(dB);
-
-				//limit the variance
-				float sigmanew = var + k*(dist-var);
-				m_modes[pos].variance = sigmanew < 4 ? 4 : sigmanew > 5*m_variance ? 5*m_variance : sigmanew;
-				m_modes[pos].significants = m_modes[pos].weight / sqrt(m_modes[pos].variance);
-			}
-			else
-			{
-				weight = fOneMinAlpha*weight;
-				if (weight < 0.0)
-				{
-					weight=0.0;
-					numModes--;
-				}
-
-				m_modes[pos].weight = weight;
-				m_modes[pos].significants = m_modes[pos].weight / sqrt(m_modes[pos].variance);
-			}
-		}
-		else
-		{
-			weight = fOneMinAlpha*weight;
-			if (weight < 0.0)
-			{
-				weight=0.0;
-				numModes--;
-			}
-			m_modes[pos].weight = weight;
-			m_modes[pos].significants = m_modes[pos].weight / sqrt(m_modes[pos].variance);
-		}
-
-		totalWeight += weight;
-	}
-
-	// renormalize weights so they add to one
-	double invTotalWeight = 1.0 / totalWeight;
-	for (int iLocal = 0; iLocal < numModes; iLocal++)
-	{
-		m_modes[posPixel + iLocal].weight *= (float)invTotalWeight;
-		m_modes[posPixel + iLocal].significants = m_modes[posPixel + iLocal].weight 
-																								/ sqrt(m_modes[posPixel + iLocal].variance);
-	}
-
-	// Sort significance values so they are in desending order. 
-	qsort(&m_modes[posPixel],  numModes, sizeof(GMM), compareGMM);
-
-	// make new mode if needed and exit
-	if (!bFitsPDF)
-	{
-		if (numModes < m_params.MaxModes())
-		{
-			numModes++;
-		}
-		else
-		{
-			// the weakest mode will be replaced
-		}
-
-		pos = posPixel + numModes-1;
-		
-		m_modes[pos].muR = pixel.ch[0];
-		m_modes[pos].muG = pixel.ch[1];
-		m_modes[pos].muB = pixel.ch[2];
-		m_modes[pos].variance = m_variance;
-		m_modes[pos].significants = 0;			// will be set below
-
-    if (numModes==1)
-			m_modes[pos].weight = 1;
-		else
-			m_modes[pos].weight = m_params.Alpha();
-
-		//renormalize weights
-		int iLocal;
-		float sum = 0.0;
-		for (iLocal = 0; iLocal < numModes; iLocal++)
-		{
-			sum += m_modes[posPixel+ iLocal].weight;
-		}
-
-		double invSum = 1.0/sum;
-		for (iLocal = 0; iLocal < numModes; iLocal++)
-		{
-			m_modes[posPixel + iLocal].weight *= (float)invSum;
-			m_modes[posPixel + iLocal].significants = m_modes[posPixel + iLocal].weight 
-																								/ sqrt(m_modes[posPixel + iLocal].variance);
-
-		}
-	}
-
-	// Sort significance values so they are in desending order. 
-	qsort(&(m_modes[posPixel]), numModes, sizeof(GMM), compareGMM);
-
-	if(bBackgroundLow)
-	{
-		low_threshold = BACKGROUND;
-	}
-	else
-	{
-		low_threshold = FOREGROUND;
-	}
-
-	if(bBackgroundHigh)
-	{
-		high_threshold = BACKGROUND;
-	}
-	else
-	{
-		high_threshold = FOREGROUND;
-	}
+  // calculate distances to the modes (+ sort???)
+  // here we need to go in descending order!!!
+  long pos;
+  bool bFitsPDF = false;
+  bool bBackgroundLow = false;
+  bool bBackgroundHigh = false;
+
+  float fOneMinAlpha = 1 - m_params.Alpha();
+
+  float totalWeight = 0.0f;
+
+  // calculate number of Gaussians to include in the background model
+  int backgroundGaussians = 0;
+  double sum = 0.0;
+  for (int i = 0; i < numModes; ++i)
+  {
+    if (sum < m_bg_threshold)
+    {
+      backgroundGaussians++;
+      sum += m_modes[posPixel + i].weight;
+    }
+    else
+    {
+      break;
+    }
+  }
+
+  // update all distributions and check for match with current pixel
+  for (int iModes = 0; iModes < numModes; iModes++)
+  {
+    pos = posPixel + iModes;
+    float weight = m_modes[pos].weight;
+
+    // fit not found yet
+    if (!bFitsPDF)
+    {
+      //check if it belongs to some of the modes
+      //calculate distance
+      float var = m_modes[pos].variance;
+      float muR = m_modes[pos].muR;
+      float muG = m_modes[pos].muG;
+      float muB = m_modes[pos].muB;
+
+      float dR = muR - pixel(0);
+      float dG = muG - pixel(1);
+      float dB = muB - pixel(2);
+
+      // calculate the squared distance
+      float dist = (dR*dR + dG*dG + dB*dB);
+
+      if (dist < m_params.HighThreshold()*var && iModes < backgroundGaussians)
+        bBackgroundHigh = true;
+
+      // a match occurs when the pixel is within sqrt(fTg) standard deviations of the distribution
+      if (dist < m_params.LowThreshold()*var)
+      {
+        bFitsPDF = true;
+
+        // check if this Gaussian is part of the background model
+        if (iModes < backgroundGaussians)
+          bBackgroundLow = true;
+
+        //update distribution
+        float k = m_params.Alpha() / weight;
+        weight = fOneMinAlpha*weight + m_params.Alpha();
+        m_modes[pos].weight = weight;
+        m_modes[pos].muR = muR - k*(dR);
+        m_modes[pos].muG = muG - k*(dG);
+        m_modes[pos].muB = muB - k*(dB);
+
+        //limit the variance
+        float sigmanew = var + k*(dist - var);
+        m_modes[pos].variance = sigmanew < 4 ? 4 : sigmanew > 5 * m_variance ? 5 * m_variance : sigmanew;
+        m_modes[pos].significants = m_modes[pos].weight / sqrt(m_modes[pos].variance);
+      }
+      else
+      {
+        weight = fOneMinAlpha*weight;
+        if (weight < 0.0)
+        {
+          weight = 0.0;
+          numModes--;
+        }
+
+        m_modes[pos].weight = weight;
+        m_modes[pos].significants = m_modes[pos].weight / sqrt(m_modes[pos].variance);
+      }
+    }
+    else
+    {
+      weight = fOneMinAlpha*weight;
+      if (weight < 0.0)
+      {
+        weight = 0.0;
+        numModes--;
+      }
+      m_modes[pos].weight = weight;
+      m_modes[pos].significants = m_modes[pos].weight / sqrt(m_modes[pos].variance);
+    }
+
+    totalWeight += weight;
+  }
+
+  // renormalize weights so they add to one
+  double invTotalWeight = 1.0 / totalWeight;
+  for (int iLocal = 0; iLocal < numModes; iLocal++)
+  {
+    m_modes[posPixel + iLocal].weight *= (float)invTotalWeight;
+    m_modes[posPixel + iLocal].significants = m_modes[posPixel + iLocal].weight
+      / sqrt(m_modes[posPixel + iLocal].variance);
+  }
+
+  // Sort significance values so they are in desending order.
+  qsort(&m_modes[posPixel], numModes, sizeof(GMM), compareGMM);
+
+  // make new mode if needed and exit
+  if (!bFitsPDF)
+  {
+    if (numModes < m_params.MaxModes())
+    {
+      numModes++;
+    }
+    else
+    {
+      // the weakest mode will be replaced
+    }
+
+    pos = posPixel + numModes - 1;
+
+    m_modes[pos].muR = pixel.ch[0];
+    m_modes[pos].muG = pixel.ch[1];
+    m_modes[pos].muB = pixel.ch[2];
+    m_modes[pos].variance = m_variance;
+    m_modes[pos].significants = 0;			// will be set below
+
+    if (numModes == 1)
+      m_modes[pos].weight = 1;
+    else
+      m_modes[pos].weight = m_params.Alpha();
+
+    //renormalize weights
+    int iLocal;
+    float sum = 0.0;
+    for (iLocal = 0; iLocal < numModes; iLocal++)
+    {
+      sum += m_modes[posPixel + iLocal].weight;
+    }
+
+    double invSum = 1.0 / sum;
+    for (iLocal = 0; iLocal < numModes; iLocal++)
+    {
+      m_modes[posPixel + iLocal].weight *= (float)invSum;
+      m_modes[posPixel + iLocal].significants = m_modes[posPixel + iLocal].weight
+        / sqrt(m_modes[posPixel + iLocal].variance);
+
+    }
+  }
+
+  // Sort significance values so they are in desending order.
+  qsort(&(m_modes[posPixel]), numModes, sizeof(GMM), compareGMM);
+
+  if (bBackgroundLow)
+  {
+    low_threshold = BACKGROUND;
+  }
+  else
+  {
+    low_threshold = FOREGROUND;
+  }
+
+  if (bBackgroundHigh)
+  {
+    high_threshold = BACKGROUND;
+  }
+  else
+  {
+    high_threshold = FOREGROUND;
+  }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -303,29 +303,29 @@ void GrimsonGMM::SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned ch
 //					(the memory should already be reserved) 
 //					values: 255-foreground, 125-shadow, 0-background
 ///////////////////////////////////////////////////////////////////////////////
-void GrimsonGMM::Subtract(int frame_num, const RgbImage& data,  
-														BwImage& low_threshold_mask, BwImage& high_threshold_mask)
+void GrimsonGMM::Subtract(int frame_num, const RgbImage& data,
+  BwImage& low_threshold_mask, BwImage& high_threshold_mask)
 {
-	unsigned char low_threshold, high_threshold;
-	long posPixel;
-
-	// update each pixel of the image
-	for(unsigned int r = 0; r < m_params.Height(); ++r)
-	{
-		for(unsigned int c = 0; c < m_params.Width(); ++c)
-		{		
-			// update model + background subtract
-			posPixel=(r*m_params.Width()+c)*m_params.MaxModes();
-			
-			SubtractPixel(posPixel, data(r,c), m_modes_per_pixel(r,c), low_threshold, high_threshold);
-			
-			low_threshold_mask(r,c) = low_threshold;
-			high_threshold_mask(r,c) = high_threshold;
-
-			m_background(r,c,0) = (unsigned char)m_modes[posPixel].muR;
-			m_background(r,c,1) = (unsigned char)m_modes[posPixel].muG;
-			m_background(r,c,2) = (unsigned char)m_modes[posPixel].muB;
-		}
-	}
+  unsigned char low_threshold, high_threshold;
+  long posPixel;
+
+  // update each pixel of the image
+  for (unsigned int r = 0; r < m_params.Height(); ++r)
+  {
+    for (unsigned int c = 0; c < m_params.Width(); ++c)
+    {
+      // update model + background subtract
+      posPixel = (r*m_params.Width() + c)*m_params.MaxModes();
+
+      SubtractPixel(posPixel, data(r, c), m_modes_per_pixel(r, c), low_threshold, high_threshold);
+
+      low_threshold_mask(r, c) = low_threshold;
+      high_threshold_mask(r, c) = high_threshold;
+
+      m_background(r, c, 0) = (unsigned char)m_modes[posPixel].muR;
+      m_background(r, c, 1) = (unsigned char)m_modes[posPixel].muG;
+      m_background(r, c, 2) = (unsigned char)m_modes[posPixel].muB;
+    }
+  }
 }
 
diff --git a/package_bgs/dp/GrimsonGMM.h b/package_bgs/dp/GrimsonGMM.h
index a177a803bbd81f8da79f0b9afbe86ff1cdd276fc..2c0f77232801d24f14d7b8b8b04d2af536565a1e 100644
--- a/package_bgs/dp/GrimsonGMM.h
+++ b/package_bgs/dp/GrimsonGMM.h
@@ -18,7 +18,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * GrimsonGMM.cpp
 *
-* Purpose: Implementation of the Gaussian mixture model (GMM) background 
+* Purpose: Implementation of the Gaussian mixture model (GMM) background
 *		  		 subtraction described in:
 *	  			 "Adaptive background mixture models for real-time tracking"
 * 						by Chris Stauffer and W.E.L Grimson
@@ -26,125 +26,121 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * Author: Donovan Parks, September 2007
 *
 * This code is based on code by Z. Zivkovic's written for his enhanced GMM
-* background subtraction algorithm: 
+* background subtraction algorithm:
 *
 *	"Improved adaptive Gausian mixture model for background subtraction"
-*		Z.Zivkovic 
+*		Z.Zivkovic
 *		International Conference Pattern Recognition, UK, August, 2004
 *
 *
-* "Efficient Adaptive Density Estimapion per Image Pixel for the 
+* "Efficient Adaptive Density Estimapion per Image Pixel for the
 *			Task of Background Subtraction"
-*		Z.Zivkovic, F. van der Heijden 
+*		Z.Zivkovic, F. van der Heijden
 *		Pattern Recognition Letters, vol. 27, no. 7, pages 773-780, 2006.
 *
 * Zivkovic's code can be obtained at: www.zoranz.net
 
 Example:
-		Algorithms::BackgroundSubtraction::GrimsonParams params;
-		params.SetFrameSize(width, height);
-		params.LowThreshold() = 3.0f*3.0f;
-		params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing 
-		params.Alpha() = 0.001f;
-		params.MaxModes() = 3;
-
-		Algorithms::BackgroundSubtraction::GrimsonGMM bgs;
-		bgs.Initalize(params);
+    Algorithms::BackgroundSubtraction::GrimsonParams params;
+    params.SetFrameSize(width, height);
+    params.LowThreshold() = 3.0f*3.0f;
+    params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing
+    params.Alpha() = 0.001f;
+    params.MaxModes() = 3;
+
+    Algorithms::BackgroundSubtraction::GrimsonGMM bgs;
+    bgs.Initalize(params);
 ******************************************************************************/
-
-#ifndef GRIMSON_GMM_
-#define GRIMSON_GMM_
+#pragma once
 
 #include "Bgs.h"
 
 namespace Algorithms
 {
-	namespace BackgroundSubtraction
-	{
-		typedef struct GMMGaussian
-		{
-			float variance;
-			float muR;
-			float muG;
-			float muB;
-			float weight;
-			float significants;		// this is equal to weight / standard deviation and is used to
-														// determine which Gaussians should be part of the background model
-		} GMM;
-
-		// --- User adjustable parameters used by the Grimson GMM BGS algorithm ---
-		class GrimsonParams : public BgsParams
-		{
-		public:
-			float &LowThreshold() { return m_low_threshold; }
-			float &HighThreshold() { return m_high_threshold; }
-
-			float &Alpha() { return m_alpha; }
-			int &MaxModes() { return m_max_modes; }
-
-		private:
-			// Threshold on the squared dist. to decide when a sample is close to an existing 
-			// components. If it is not close to any a new component will be generated. 
-			// Smaller threshold values lead to more generated components and higher threshold values 
-			// lead to a small number of components but they can grow too large.
-			//
-			// It is usual easiest to think of these thresholds as being the number of variances away
-			// from the mean of a pixel before it is considered to be from the foreground.
-			float m_low_threshold;
-			float m_high_threshold;
-
-			// alpha - speed of update - if the time interval you want to average over is T
-			// set alpha=1/T. 
-			float m_alpha;
-
-			// Maximum number of modes (Gaussian components) that will be used per pixel
-			int m_max_modes;
-		};
-
-		// --- Grimson GMM BGS algorithm ---
-		class GrimsonGMM : public Bgs
-		{
-		public:
-			GrimsonGMM();
-			~GrimsonGMM();
-
-			void Initalize(const BgsParams& param);
-
-			void InitModel(const RgbImage& data);
-			void Subtract(int frame_num, const RgbImage& data,  
-											BwImage& low_threshold_mask, BwImage& high_threshold_mask);	
-			void Update(int frame_num, const RgbImage& data,  const BwImage& update_mask);
-
-			RgbImage* Background();
-
-		private:	
-			void SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned char& numModes, 
-													unsigned char& lowThreshold, unsigned char& highThreshold);
-
-			// User adjustable parameters
-			GrimsonParams m_params;
-
-			// Threshold when the component becomes significant enough to be included into
-			// the background model. It is the TB = 1-cf from the paper. So I use cf=0.1 => TB=0.9
-			// For alpha=0.001 it means that the mode should exist for approximately 105 frames before
-			// it is considered foreground
-			float m_bg_threshold; //1-cf from the paper
-
-			// Initial variance for the newly generated components. 
-			// It will will influence the speed of adaptation. A good guess should be made. 
-			// A simple way is to estimate the typical standard deviation from the images.
-			float m_variance;
-
-			// Dynamic array for the mixture of Gaussians
-			GMM* m_modes;
-
-			// Number of Gaussian components per pixel
-			BwImage m_modes_per_pixel;
-
-			// Current background model
-			RgbImage m_background;
-		};
-	}
+  namespace BackgroundSubtraction
+  {
+    typedef struct GMMGaussian
+    {
+      float variance;
+      float muR;
+      float muG;
+      float muB;
+      float weight;
+      float significants;		// this is equal to weight / standard deviation and is used to
+      // determine which Gaussians should be part of the background model
+    } GMM;
+
+    // --- User adjustable parameters used by the Grimson GMM BGS algorithm ---
+    class GrimsonParams : public BgsParams
+    {
+    public:
+      float &LowThreshold() { return m_low_threshold; }
+      float &HighThreshold() { return m_high_threshold; }
+
+      float &Alpha() { return m_alpha; }
+      int &MaxModes() { return m_max_modes; }
+
+    private:
+      // Threshold on the squared dist. to decide when a sample is close to an existing
+      // components. If it is not close to any a new component will be generated.
+      // Smaller threshold values lead to more generated components and higher threshold values
+      // lead to a small number of components but they can grow too large.
+      //
+      // It is usual easiest to think of these thresholds as being the number of variances away
+      // from the mean of a pixel before it is considered to be from the foreground.
+      float m_low_threshold;
+      float m_high_threshold;
+
+      // alpha - speed of update - if the time interval you want to average over is T
+      // set alpha=1/T.
+      float m_alpha;
+
+      // Maximum number of modes (Gaussian components) that will be used per pixel
+      int m_max_modes;
+    };
+
+    // --- Grimson GMM BGS algorithm ---
+    class GrimsonGMM : public Bgs
+    {
+    public:
+      GrimsonGMM();
+      ~GrimsonGMM();
+
+      void Initalize(const BgsParams& param);
+
+      void InitModel(const RgbImage& data);
+      void Subtract(int frame_num, const RgbImage& data,
+        BwImage& low_threshold_mask, BwImage& high_threshold_mask);
+      void Update(int frame_num, const RgbImage& data, const BwImage& update_mask);
+
+      RgbImage* Background();
+
+    private:
+      void SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned char& numModes,
+        unsigned char& lowThreshold, unsigned char& highThreshold);
+
+      // User adjustable parameters
+      GrimsonParams m_params;
+
+      // Threshold when the component becomes significant enough to be included into
+      // the background model. It is the TB = 1-cf from the paper. So I use cf=0.1 => TB=0.9
+      // For alpha=0.001 it means that the mode should exist for approximately 105 frames before
+      // it is considered foreground
+      float m_bg_threshold; //1-cf from the paper
+
+      // Initial variance for the newly generated components.
+      // It will will influence the speed of adaptation. A good guess should be made.
+      // A simple way is to estimate the typical standard deviation from the images.
+      float m_variance;
+
+      // Dynamic array for the mixture of Gaussians
+      GMM* m_modes;
+
+      // Number of Gaussian components per pixel
+      BwImage m_modes_per_pixel;
+
+      // Current background model
+      RgbImage m_background;
+    };
+  }
 }
-
-#endif
diff --git a/package_bgs/dp/Image.cpp b/package_bgs/dp/Image.cpp
index f00febda47ff02b170ddbed9e9d5ed9bf1d4214e..92119c246c8d366b3f7addaabefe0c013fa25b7e 100644
--- a/package_bgs/dp/Image.cpp
+++ b/package_bgs/dp/Image.cpp
@@ -18,59 +18,59 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Image.hpp
 *
-* Purpose:  C++ wrapper for OpenCV IplImage which supports simple and 
+* Purpose:  C++ wrapper for OpenCV IplImage which supports simple and
 *						efficient access to the image data
 *
 * Author: Donovan Parks, September 2007
 *
-* Based on code from: 
+* Based on code from:
 *  http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/opencv-intro.hpptml
 ******************************************************************************/
 
 #include "Image.h"
 
 ImageBase::~ImageBase()
-{ 
-  if(imgp != NULL && m_bReleaseMemory)
+{
+  if (imgp != NULL && m_bReleaseMemory)
     cvReleaseImage(&imgp);
-  imgp = NULL;	
+  imgp = NULL;
 }
 
 void DensityFilter(BwImage& image, BwImage& filtered, int minDensity, unsigned char fgValue)
 {
-  for(int r = 1; r < image.Ptr()->height-1; ++r)
+  for (int r = 1; r < image.Ptr()->height - 1; ++r)
   {
-    for(int c = 1; c < image.Ptr()->width-1; ++c)
+    for (int c = 1; c < image.Ptr()->width - 1; ++c)
     {
       int count = 0;
-      if(image(r,c) == fgValue)
+      if (image(r, c) == fgValue)
       {
-        if(image(r-1,c-1) == fgValue)
+        if (image(r - 1, c - 1) == fgValue)
           count++;
-        if(image(r-1,c) == fgValue)
+        if (image(r - 1, c) == fgValue)
           count++;
-        if(image(r-1,c+1) == fgValue)
+        if (image(r - 1, c + 1) == fgValue)
           count++;
-        if(image(r,c-1) == fgValue)
+        if (image(r, c - 1) == fgValue)
           count++;
-        if(image(r,c+1) == fgValue)
+        if (image(r, c + 1) == fgValue)
           count++;
-        if(image(r+1,c-1) == fgValue)
+        if (image(r + 1, c - 1) == fgValue)
           count++;
-        if(image(r+1,c) == fgValue)
+        if (image(r + 1, c) == fgValue)
           count++;
-        if(image(r+1,c+1) == fgValue)
+        if (image(r + 1, c + 1) == fgValue)
           count++;
 
-        if(count < minDensity)
-          filtered(r,c) = 0;
+        if (count < minDensity)
+          filtered(r, c) = 0;
         else
-          filtered(r,c) = fgValue;
+          filtered(r, c) = fgValue;
       }
       else
       {
-        filtered(r,c) = 0;
+        filtered(r, c) = 0;
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/package_bgs/dp/Image.h b/package_bgs/dp/Image.h
index 58fe50d922442141de026d128b4d0cc99335e1cd..6c0b5b3257486489597f8c9dae47dc6cec304d8b 100644
--- a/package_bgs/dp/Image.h
+++ b/package_bgs/dp/Image.h
@@ -18,17 +18,15 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Image.h
 *
-* Purpose:  C++ wrapper for OpenCV IplImage which supports simple and 
+* Purpose:  C++ wrapper for OpenCV IplImage which supports simple and
 *						efficient access to the image data
 *
 * Author: Donovan Parks, September 2007
 *
-* Based on code from: 
+* Based on code from:
 *  http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/opencv-intro.html
 ******************************************************************************/
-
-#ifndef _IMAGE_H_
-#define _IMAGE_H_
+#pragma once
 
 #include <opencv2/opencv.hpp>
 //#include <cxcore.h>
@@ -36,30 +34,30 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 // --- Image Iterator ---------------------------------------------------------
 
 template <class T>
-class ImageIterator 
+class ImageIterator
 {
-public: 
-  ImageIterator(IplImage* image, int x=0, int y=0, int dx= 0, int dy=0) :
-    i(x), j(y), i0(0) 
-  {    
+public:
+  ImageIterator(IplImage* image, int x = 0, int y = 0, int dx = 0, int dy = 0) :
+    i(x), j(y), i0(0)
+  {
     data = reinterpret_cast<T*>(image->imageData);
     step = image->widthStep / sizeof(T);
 
-    nl= image->height;
-    if ((y+dy)>0 && (y+dy) < nl) 
-      nl= y+dy;
+    nl = image->height;
+    if ((y + dy) > 0 && (y + dy) < nl)
+      nl = y + dy;
 
-    if (y<0) 
-      j=0;
+    if (y < 0)
+      j = 0;
 
     data += step*j;
 
     nc = image->width;
-    if ((x+dx) > 0 && (x+dx) < nc) 
-      nc = x+dx;
+    if ((x + dx) > 0 && (x + dx) < nc)
+      nc = x + dx;
 
     nc *= image->nChannels;
-    if (x>0) 
+    if (x > 0)
       i0 = x*image->nChannels;
     i = i0;
 
@@ -71,26 +69,26 @@ public:
   bool operator!() const { return j < nl; }
 
   /* next pixel */
-  ImageIterator& operator++() 
+  ImageIterator& operator++()
   {
     i++;
-    if (i >= nc) 
-    { 
-      i=i0; 
-      j++; 
-      data += step; 
+    if (i >= nc)
+    {
+      i = i0;
+      j++;
+      data += step;
     }
     return *this;
   }
 
-  ImageIterator& operator+=(int s) 
+  ImageIterator& operator+=(int s)
   {
-    i+=s;
-    if (i >= nc) 
-    { 
-      i=i0; 
-      j++; 
-      data += step; 
+    i += s;
+    if (i >= nc)
+    {
+      i = i0;
+      j++;
+      data += step;
     }
     return *this;
   }
@@ -101,18 +99,18 @@ public:
   const T operator*() const { return data[i]; }
 
   const T neighbor(int dx, int dy) const
-  { 
-    return *(data+dy*step+i+dx); 
+  {
+    return *(data + dy*step + i + dx);
   }
 
-  T* operator&() const { return data+i; }
+  T* operator&() const { return data + i; }
 
   /* current pixel coordinates */
-  int column() const { return i/nch; }
+  int column() const { return i / nch; }
   int line() const { return j; }
 
 private:
-  int i, i0,j;
+  int i, i0, j;
   T* data;
   int step;
   int nl, nc;
@@ -128,7 +126,7 @@ const unsigned char NUM_CHANNELS = 3;
 class RgbPixel
 {
 public:
-  RgbPixel() {;}
+  RgbPixel() { ; }
   RgbPixel(unsigned char _r, unsigned char _g, unsigned char _b)
   {
     ch[0] = _r; ch[1] = _g; ch[2] = _b;
@@ -156,7 +154,7 @@ public:
 class RgbPixelFloat
 {
 public:
-  RgbPixelFloat() {;}
+  RgbPixelFloat() { ; }
   RgbPixelFloat(float _r, float _g, float _b)
   {
     ch[0] = _r; ch[1] = _g; ch[2] = _b;
@@ -199,14 +197,14 @@ public:
     cvReleaseImage(&imgp);
   }
 
-  void operator=(IplImage* img) 
-  { 
+  void operator=(IplImage* img)
+  {
     imgp = img;
   }
 
   // copy-constructor
   ImageBase(const ImageBase& rhs)
-  {	
+  {
     // it is very inefficent if this copy-constructor is called
     assert(false);
   }
@@ -237,31 +235,31 @@ public:
     cvZero(imgp);
   }
 
-  void operator=(IplImage* img) 
-  { 
+  void operator=(IplImage* img)
+  {
     imgp = img;
   }
 
   // channel-level access using image(row, col, channel)
   inline unsigned char& operator()(const int r, const int c, const int ch)
   {
-    return (unsigned char &)imgp->imageData[r*imgp->widthStep+c*imgp->nChannels+ch];
+    return (unsigned char &)imgp->imageData[r*imgp->widthStep + c*imgp->nChannels + ch];
   }
 
   inline const unsigned char& operator()(const int r, const int c, const int ch) const
   {
-    return (unsigned char &)imgp->imageData[r*imgp->widthStep+c*imgp->nChannels+ch];
+    return (unsigned char &)imgp->imageData[r*imgp->widthStep + c*imgp->nChannels + ch];
   }
 
   // RGB pixel-level access using image(row, col)
-  inline RgbPixel& operator()(const int r, const int c) 
+  inline RgbPixel& operator()(const int r, const int c)
   {
-    return (RgbPixel &)imgp->imageData[r*imgp->widthStep+c*imgp->nChannels];
+    return (RgbPixel &)imgp->imageData[r*imgp->widthStep + c*imgp->nChannels];
   }
 
   inline const RgbPixel& operator()(const int r, const int c) const
   {
-    return (RgbPixel &)imgp->imageData[r*imgp->widthStep+c*imgp->nChannels];
+    return (RgbPixel &)imgp->imageData[r*imgp->widthStep + c*imgp->nChannels];
   }
 };
 
@@ -275,31 +273,31 @@ public:
     cvZero(imgp);
   }
 
-  void operator=(IplImage* img) 
-  { 
+  void operator=(IplImage* img)
+  {
     imgp = img;
   }
 
   // channel-level access using image(row, col, channel)
   inline float& operator()(const int r, const int c, const int ch)
   {
-    return (float &)imgp->imageData[r*imgp->widthStep+(c*imgp->nChannels+ch)*sizeof(float)];
+    return (float &)imgp->imageData[r*imgp->widthStep + (c*imgp->nChannels + ch) * sizeof(float)];
   }
 
   inline float operator()(const int r, const int c, const int ch) const
   {
-    return (float)imgp->imageData[r*imgp->widthStep+(c*imgp->nChannels+ch)*sizeof(float)];
+    return (float)imgp->imageData[r*imgp->widthStep + (c*imgp->nChannels + ch) * sizeof(float)];
   }
 
   // RGB pixel-level access using image(row, col)
-  inline RgbPixelFloat& operator()(const int r, const int c) 
+  inline RgbPixelFloat& operator()(const int r, const int c)
   {
-    return (RgbPixelFloat &)imgp->imageData[r*imgp->widthStep+c*imgp->nChannels*sizeof(float)];
+    return (RgbPixelFloat &)imgp->imageData[r*imgp->widthStep + c*imgp->nChannels * sizeof(float)];
   }
 
   inline const RgbPixelFloat& operator()(const int r, const int c) const
   {
-    return (RgbPixelFloat &)imgp->imageData[r*imgp->widthStep+c*imgp->nChannels*sizeof(float)];
+    return (RgbPixelFloat &)imgp->imageData[r*imgp->widthStep + c*imgp->nChannels * sizeof(float)];
   }
 };
 
@@ -313,20 +311,20 @@ public:
     cvZero(imgp);
   }
 
-  void operator=(IplImage* img) 
-  { 
+  void operator=(IplImage* img)
+  {
     imgp = img;
   }
 
   // pixel-level access using image(row, col)
   inline unsigned char& operator()(const int r, const int c)
   {
-    return (unsigned char &)imgp->imageData[r*imgp->widthStep+c];
+    return (unsigned char &)imgp->imageData[r*imgp->widthStep + c];
   }
 
   inline unsigned char operator()(const int r, const int c) const
   {
-    return (unsigned char)imgp->imageData[r*imgp->widthStep+c];
+    return (unsigned char)imgp->imageData[r*imgp->widthStep + c];
   }
 };
 
@@ -340,25 +338,23 @@ public:
     cvZero(imgp);
   }
 
-  void operator=(IplImage* img) 
-  { 
+  void operator=(IplImage* img)
+  {
     imgp = img;
   }
 
   // pixel-level access using image(row, col)
   inline float& operator()(const int r, const int c)
   {
-    return (float &)imgp->imageData[r*imgp->widthStep+c*sizeof(float)];
+    return (float &)imgp->imageData[r*imgp->widthStep + c * sizeof(float)];
   }
 
   inline float operator()(const int r, const int c) const
   {
-    return (float)imgp->imageData[r*imgp->widthStep+c*sizeof(float)];
+    return (float)imgp->imageData[r*imgp->widthStep + c * sizeof(float)];
   }
 };
 
 // --- Image Functions --------------------------------------------------------
 
 void DensityFilter(BwImage& image, BwImage& filtered, int minDensity, unsigned char fgValue);
-
-#endif
diff --git a/package_bgs/dp/MeanBGS.cpp b/package_bgs/dp/MeanBGS.cpp
index b8df8958dec2e8fd1a0735861134be91b3b7d25e..51781588671b3714278c9614cecd8cfef5f5baa0 100644
--- a/package_bgs/dp/MeanBGS.cpp
+++ b/package_bgs/dp/MeanBGS.cpp
@@ -18,7 +18,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * MeanBGS.h
 *
-* Purpose: Implementation of a simple temporal mean background 
+* Purpose: Implementation of a simple temporal mean background
 *		  		 subtraction algorithm.
 *
 * Author: Donovan Parks, September 2007
@@ -31,72 +31,72 @@ using namespace Algorithms::BackgroundSubtraction;
 
 void MeanBGS::Initalize(const BgsParams& param)
 {
-	m_params = (MeanParams&)param;
+  m_params = (MeanParams&)param;
 
-	m_mean = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_32F, 3);
-	m_background = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 3);
+  m_mean = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_32F, 3);
+  m_background = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 3);
 }
 
 void MeanBGS::InitModel(const RgbImage& data)
 {
-	for (unsigned int r = 0; r < m_params.Height(); ++r)
-	{
-		for(unsigned int c = 0; c < m_params.Width(); ++c)
-		{
-			for(int ch = 0; ch < NUM_CHANNELS; ++ch)
-			{
-				m_mean(r,c,ch) = (float)data(r,c,ch);
-			}
-		}
-	}
+  for (unsigned int r = 0; r < m_params.Height(); ++r)
+  {
+    for (unsigned int c = 0; c < m_params.Width(); ++c)
+    {
+      for (int ch = 0; ch < NUM_CHANNELS; ++ch)
+      {
+        m_mean(r, c, ch) = (float)data(r, c, ch);
+      }
+    }
+  }
 }
 
-void MeanBGS::Update(int frame_num, const RgbImage& data,  const BwImage& update_mask)
+void MeanBGS::Update(int frame_num, const RgbImage& data, const BwImage& update_mask)
 {
-	// update background model
-	for (unsigned int r = 0; r < m_params.Height(); ++r)
-	{
-		for(unsigned int c = 0; c < m_params.Width(); ++c)
-		{
-			// perform conditional updating only if we are passed the learning phase
-			if(update_mask(r,c) == BACKGROUND || frame_num < m_params.LearningFrames())
-			{
-				// update B/G model
-				float mean;
-				for(int ch = 0; ch < NUM_CHANNELS; ++ch)
-				{
-					mean = m_params.Alpha() * m_mean(r,c,ch) + (1.0f-m_params.Alpha()) * data(r,c,ch);
-					m_mean(r,c,ch) = mean;
-					m_background(r,c,ch) = (unsigned char)(mean + 0.5);
-				}
-			}
-		}
-	}
+  // update background model
+  for (unsigned int r = 0; r < m_params.Height(); ++r)
+  {
+    for (unsigned int c = 0; c < m_params.Width(); ++c)
+    {
+      // perform conditional updating only if we are passed the learning phase
+      if (update_mask(r, c) == BACKGROUND || frame_num < m_params.LearningFrames())
+      {
+        // update B/G model
+        float mean;
+        for (int ch = 0; ch < NUM_CHANNELS; ++ch)
+        {
+          mean = m_params.Alpha() * m_mean(r, c, ch) + (1.0f - m_params.Alpha()) * data(r, c, ch);
+          m_mean(r, c, ch) = mean;
+          m_background(r, c, ch) = (unsigned char)(mean + 0.5);
+        }
+      }
+    }
+  }
 }
 
-void MeanBGS::SubtractPixel(int r, int c, const RgbPixel& pixel, 
-															unsigned char& low_threshold, 
-															unsigned char& high_threshold)
+void MeanBGS::SubtractPixel(int r, int c, const RgbPixel& pixel,
+  unsigned char& low_threshold,
+  unsigned char& high_threshold)
 {
-	// calculate distance to sample point
-	float dist = 0;
-	for(int ch = 0; ch < NUM_CHANNELS; ++ch)
-	{
-		dist += (pixel(ch)-m_mean(r,c,ch))*(pixel(ch)-m_mean(r,c,ch));
-	}
-
-	// determine if sample point is F/G or B/G pixel
-	low_threshold = BACKGROUND;
-	if(dist > m_params.LowThreshold())
-	{
-		low_threshold = FOREGROUND;
-	}
-
-	high_threshold = BACKGROUND;
-	if(dist > m_params.HighThreshold())
-	{
-		high_threshold = FOREGROUND;
-	}
+  // calculate distance to sample point
+  float dist = 0;
+  for (int ch = 0; ch < NUM_CHANNELS; ++ch)
+  {
+    dist += (pixel(ch) - m_mean(r, c, ch))*(pixel(ch) - m_mean(r, c, ch));
+  }
+
+  // determine if sample point is F/G or B/G pixel
+  low_threshold = BACKGROUND;
+  if (dist > m_params.LowThreshold())
+  {
+    low_threshold = FOREGROUND;
+  }
+
+  high_threshold = BACKGROUND;
+  if (dist > m_params.HighThreshold())
+  {
+    high_threshold = FOREGROUND;
+  }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -106,26 +106,22 @@ void MeanBGS::SubtractPixel(int r, int c, const RgbPixel& pixel,
 //  output - a pointer to the data of a gray value image of the same size 
 //					values: 255-foreground, 0-background
 ///////////////////////////////////////////////////////////////////////////////
-void MeanBGS::Subtract(int frame_num, const RgbImage& data, 
-												BwImage& low_threshold_mask, BwImage& high_threshold_mask)
+void MeanBGS::Subtract(int frame_num, const RgbImage& data,
+  BwImage& low_threshold_mask, BwImage& high_threshold_mask)
 {
-	unsigned char low_threshold, high_threshold;
-
-	// update each pixel of the image
-	for(unsigned int r = 0; r < m_params.Height(); ++r)
-	{
-		for(unsigned int c = 0; c < m_params.Width(); ++c)
-		{	
-			// perform background subtraction + update background model
-			SubtractPixel(r, c, data(r,c), low_threshold, high_threshold);
-
-			// setup silhouette mask
-			low_threshold_mask(r,c) = low_threshold;
-			high_threshold_mask(r,c) = high_threshold;
-		}
-	}
+  unsigned char low_threshold, high_threshold;
+
+  // update each pixel of the image
+  for (unsigned int r = 0; r < m_params.Height(); ++r)
+  {
+    for (unsigned int c = 0; c < m_params.Width(); ++c)
+    {
+      // perform background subtraction + update background model
+      SubtractPixel(r, c, data(r, c), low_threshold, high_threshold);
+
+      // setup silhouette mask
+      low_threshold_mask(r, c) = low_threshold;
+      high_threshold_mask(r, c) = high_threshold;
+    }
+  }
 }
-
-
-
-
diff --git a/package_bgs/dp/MeanBGS.h b/package_bgs/dp/MeanBGS.h
index 247e09493a6af6bd954d2c6be825f31007fe5c76..306af1a8083dba5d34354354f6093f42661846b1 100644
--- a/package_bgs/dp/MeanBGS.h
+++ b/package_bgs/dp/MeanBGS.h
@@ -18,7 +18,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * MeanBGS.hpp
 *
-* Purpose: Implementation of a simple temporal mean background 
+* Purpose: Implementation of a simple temporal mean background
 *		  		 subtraction algorithm.
 *
 * Author: Donovan Parks, September 2007
@@ -28,13 +28,14 @@ Example:
 Algorithms::BackgroundSubtraction::MeanParams params;
 params.SetFrameSize(width, height);
 params.LowThreshold() = 3*30*30;
-params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing 
+params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing
 params.Alpha() = 1e-6f;
 params.LearningFrames() = 30;
 
 Algorithms::BackgroundSubtraction::MeanBGS bgs;
 bgs.Initalize(params);
 ******************************************************************************/
+#pragma once
 
 #include "Bgs.h"
 
@@ -54,7 +55,7 @@ namespace Algorithms
       int &LearningFrames() { return m_learning_frames; }
 
     private:
-      // A pixel is considered to be from the background if the squared distance between 
+      // A pixel is considered to be from the background if the squared distance between
       // it and the background model is less than the threshold.
       unsigned int m_low_threshold;
       unsigned int m_high_threshold;
@@ -73,14 +74,14 @@ namespace Algorithms
       void Initalize(const BgsParams& param);
 
       void InitModel(const RgbImage& data);
-      void Subtract(int frame_num, const RgbImage& data,  
-        BwImage& low_threshold_mask, BwImage& high_threshold_mask);	
-      void Update(int frame_num, const RgbImage& data,  const BwImage& update_mask);
+      void Subtract(int frame_num, const RgbImage& data,
+        BwImage& low_threshold_mask, BwImage& high_threshold_mask);
+      void Update(int frame_num, const RgbImage& data, const BwImage& update_mask);
 
       RgbImage* Background() { return &m_background; }
 
-    private:	
-      void SubtractPixel(int r, int c, const RgbPixel& pixel, 
+    private:
+      void SubtractPixel(int r, int c, const RgbPixel& pixel,
         unsigned char& lowThreshold, unsigned char& highThreshold);
 
       MeanParams m_params;
@@ -91,8 +92,3 @@ namespace Algorithms
 
   }
 }
-
-
-
-
-
diff --git a/package_bgs/dp/PratiMediodBGS.cpp b/package_bgs/dp/PratiMediodBGS.cpp
index 2256ceba6fa5eb911729303c6ba1d891a5cedce3..5a15cec302737468bbc2b5376cd3286af4871c00 100644
--- a/package_bgs/dp/PratiMediodBGS.cpp
+++ b/package_bgs/dp/PratiMediodBGS.cpp
@@ -18,7 +18,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * PratiMediodBGS.h
 *
-* Purpose: Implementation of the temporal median background 
+* Purpose: Implementation of the temporal median background
 *		  		 subtraction algorithm described in:
 *
 * [1] "Detecting Moving Objects, Shosts, and Shadows in Video Stream"
@@ -29,7 +29,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Author: Donovan Parks, September 2007
 *
-* Please note that this is not an implementation of the complete system 
+* Please note that this is not an implementation of the complete system
 * given in the above papers. It simply implements the temporal media background
 * subtraction algorithm.
 ******************************************************************************/
@@ -40,202 +40,202 @@ using namespace Algorithms::BackgroundSubtraction;
 
 PratiMediodBGS::PratiMediodBGS()
 {
-	m_median_buffer = NULL;
+  m_median_buffer = NULL;
 }
 
 PratiMediodBGS::~PratiMediodBGS()
 {
-	delete[] m_median_buffer;
+  delete[] m_median_buffer;
 }
 
 void PratiMediodBGS::Initalize(const BgsParams& param)
 {
-	m_params = (PratiParams&)param;
+  m_params = (PratiParams&)param;
 
-	m_mask_low_threshold = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 1);
-	m_mask_high_threshold = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 1);
+  m_mask_low_threshold = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 1);
+  m_mask_high_threshold = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 1);
 
-	m_background = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 3);
+  m_background = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 3);
 
-	m_median_buffer = new MEDIAN_BUFFER[m_params.Size()];
+  m_median_buffer = new MEDIAN_BUFFER[m_params.Size()];
 }
 
 void PratiMediodBGS::InitModel(const RgbImage& data)
 {
-	// there is no need to initialize the mode since it needs a buffer of frames
-	// before it can performing background subtraction
+  // there is no need to initialize the mode since it needs a buffer of frames
+  // before it can performing background subtraction
 }
 
-void PratiMediodBGS::Update(int frame_num, const RgbImage& data,  const BwImage& update_mask)
+void PratiMediodBGS::Update(int frame_num, const RgbImage& data, const BwImage& update_mask)
 {
-	// update the image buffer with the new frame and calculate new median values
-	if(frame_num % m_params.SamplingRate() == 0)
-	{
-		if(m_median_buffer[0].dist.size() == m_params.HistorySize())
-		{
-			// subtract distance to sample being removed from all distances
-			for(unsigned int r = 0; r < m_params.Height(); ++r)
-			{
-				for(unsigned int c = 0; c < m_params.Width(); ++c)
-				{	
-					int i = r*m_params.Width()+c;
-
-					if(update_mask(r,c) == BACKGROUND)
-					{
-						int oldPos = m_median_buffer[i].pos;
-						for(unsigned int s = 0; s < m_median_buffer[i].pixels.size(); ++s)
-						{
-							int maxDist = 0;
-							for(int ch = 0; ch < NUM_CHANNELS; ++ch)
-							{
-								int tempDist = abs(m_median_buffer[i].pixels.at(oldPos)(ch) 
-																		- m_median_buffer[i].pixels.at(s)(ch));
-								if(tempDist > maxDist)
-									maxDist = tempDist;
-							}
-
-							m_median_buffer[i].dist.at(s) -= maxDist;
-						}
-				
-						int dist;
-						UpdateMediod(r, c, data, dist);
-						m_median_buffer[i].dist.at(oldPos) = dist;
-						m_median_buffer[i].pixels.at(oldPos) = data(r,c);
-						m_median_buffer[i].pos++;
-						if(m_median_buffer[i].pos >= m_params.HistorySize())
-							m_median_buffer[i].pos = 0;
-					}
-				}
-			}
-		}
-		else
-		{
-			// calculate sum of L-inf distances for new point and 
-			// add distance from each sample point to this point to their L-inf sum
-			int dist;
-			for(unsigned int r = 0; r < m_params.Height(); ++r)
-			{
-				for(unsigned int c = 0; c < m_params.Width(); ++c)
-				{	
-					int index = r*m_params.Width()+c;
-					UpdateMediod(r, c, data, dist);
-					m_median_buffer[index].dist.push_back(dist);
-					m_median_buffer[index].pos = 0;
-					m_median_buffer[index].pixels.push_back(data(r,c)); 
-				}
-			}
-		}
-	}
+  // update the image buffer with the new frame and calculate new median values
+  if (frame_num % m_params.SamplingRate() == 0)
+  {
+    if (m_median_buffer[0].dist.size() == m_params.HistorySize())
+    {
+      // subtract distance to sample being removed from all distances
+      for (unsigned int r = 0; r < m_params.Height(); ++r)
+      {
+        for (unsigned int c = 0; c < m_params.Width(); ++c)
+        {
+          int i = r*m_params.Width() + c;
+
+          if (update_mask(r, c) == BACKGROUND)
+          {
+            int oldPos = m_median_buffer[i].pos;
+            for (unsigned int s = 0; s < m_median_buffer[i].pixels.size(); ++s)
+            {
+              int maxDist = 0;
+              for (int ch = 0; ch < NUM_CHANNELS; ++ch)
+              {
+                int tempDist = abs(m_median_buffer[i].pixels.at(oldPos)(ch)
+                  - m_median_buffer[i].pixels.at(s)(ch));
+                if (tempDist > maxDist)
+                  maxDist = tempDist;
+              }
+
+              m_median_buffer[i].dist.at(s) -= maxDist;
+            }
+
+            int dist;
+            UpdateMediod(r, c, data, dist);
+            m_median_buffer[i].dist.at(oldPos) = dist;
+            m_median_buffer[i].pixels.at(oldPos) = data(r, c);
+            m_median_buffer[i].pos++;
+            if (m_median_buffer[i].pos >= m_params.HistorySize())
+              m_median_buffer[i].pos = 0;
+          }
+        }
+      }
+    }
+    else
+    {
+      // calculate sum of L-inf distances for new point and
+      // add distance from each sample point to this point to their L-inf sum
+      int dist;
+      for (unsigned int r = 0; r < m_params.Height(); ++r)
+      {
+        for (unsigned int c = 0; c < m_params.Width(); ++c)
+        {
+          int index = r*m_params.Width() + c;
+          UpdateMediod(r, c, data, dist);
+          m_median_buffer[index].dist.push_back(dist);
+          m_median_buffer[index].pos = 0;
+          m_median_buffer[index].pixels.push_back(data(r, c));
+        }
+      }
+    }
+  }
 }
 
 void PratiMediodBGS::UpdateMediod(int r, int c, const RgbImage& new_frame, int& dist)
 {
-	// calculate sum of L-inf distances for new point and 
-	// add distance from each sample point to this point to their L-inf sum
-	unsigned int i = (r*m_params.Width()+c);
-
-	m_median_buffer[i].medianDist = INT_MAX;
-
-	int L_inf_dist = 0;
-	for(unsigned int s = 0; s < m_median_buffer[i].dist.size(); ++s)
-	{
-		int maxDist = 0;
-		for(int ch = 0; ch < NUM_CHANNELS; ++ch)
-		{
-			int tempDist = abs(m_median_buffer[i].pixels.at(s)(ch) - new_frame(r,c,ch));
-			if(tempDist > maxDist)
-				maxDist = tempDist;
-		}
-
-		// check if point from this frame in the image buffer is the median
-		m_median_buffer[i].dist.at(s) += maxDist;
-		if(m_median_buffer[i].dist.at(s) < m_median_buffer[i].medianDist)
-		{
-			m_median_buffer[i].medianDist = m_median_buffer[i].dist.at(s);
-			m_median_buffer[i].median = m_median_buffer[i].pixels.at(s);
-		}
-
-		L_inf_dist += maxDist;
-	}
-
-	dist = L_inf_dist;
-
-	// check if the new point is the median
-	if(L_inf_dist < m_median_buffer[i].medianDist)
-	{
-		m_median_buffer[i].medianDist = L_inf_dist;
-		m_median_buffer[i].median = new_frame(r,c);
-	}
+  // calculate sum of L-inf distances for new point and
+  // add distance from each sample point to this point to their L-inf sum
+  unsigned int i = (r*m_params.Width() + c);
+
+  m_median_buffer[i].medianDist = INT_MAX;
+
+  int L_inf_dist = 0;
+  for (unsigned int s = 0; s < m_median_buffer[i].dist.size(); ++s)
+  {
+    int maxDist = 0;
+    for (int ch = 0; ch < NUM_CHANNELS; ++ch)
+    {
+      int tempDist = abs(m_median_buffer[i].pixels.at(s)(ch) - new_frame(r, c, ch));
+      if (tempDist > maxDist)
+        maxDist = tempDist;
+    }
+
+    // check if point from this frame in the image buffer is the median
+    m_median_buffer[i].dist.at(s) += maxDist;
+    if (m_median_buffer[i].dist.at(s) < m_median_buffer[i].medianDist)
+    {
+      m_median_buffer[i].medianDist = m_median_buffer[i].dist.at(s);
+      m_median_buffer[i].median = m_median_buffer[i].pixels.at(s);
+    }
+
+    L_inf_dist += maxDist;
+  }
+
+  dist = L_inf_dist;
+
+  // check if the new point is the median
+  if (L_inf_dist < m_median_buffer[i].medianDist)
+  {
+    m_median_buffer[i].medianDist = L_inf_dist;
+    m_median_buffer[i].median = new_frame(r, c);
+  }
 }
 
 void PratiMediodBGS::Combine(const BwImage& low_mask, const BwImage& high_mask, BwImage& output)
 {
-	for(unsigned int r = 0; r < m_params.Height(); ++r)
-	{
-		for(unsigned int c = 0; c < m_params.Width(); ++c)
-		{
-			output(r,c) = BACKGROUND;
-
-			if(r == 0 || c == 0 || r == m_params.Height()-1 || c == m_params.Width()-1)
-				continue;	
-			
-			if(high_mask(r,c) == FOREGROUND)
-			{
-				output(r,c) = FOREGROUND;
-			}
-			else if(low_mask(r,c) == FOREGROUND)
-			{
-				// consider the pixel to be a F/G pixel if it is 8-connected to
-				// a F/G pixel in the high mask
-				// check if there is an 8-connected foreground pixel
-				if(high_mask(r-1,c-1))	
-					output(r,c) = FOREGROUND;
-				else if(high_mask(r-1,c))	
-					output(r,c) = FOREGROUND;
-				else if(high_mask(r-1,c+1))	
-					output(r,c) = FOREGROUND;
-				else if(high_mask(r,c-1))	
-					output(r,c) = FOREGROUND;
-				else if(high_mask(r,c+1))	
-					output(r,c) = FOREGROUND;
-				else if(high_mask(r+1,c-1))	
-					output(r,c) = FOREGROUND;
-				else if(high_mask(r+1,c))	
-					output(r,c) = FOREGROUND;
-				else if(high_mask(r+1,c+1))	
-					output(r,c) = FOREGROUND;
-			}
-		}
-	}
+  for (unsigned int r = 0; r < m_params.Height(); ++r)
+  {
+    for (unsigned int c = 0; c < m_params.Width(); ++c)
+    {
+      output(r, c) = BACKGROUND;
+
+      if (r == 0 || c == 0 || r == m_params.Height() - 1 || c == m_params.Width() - 1)
+        continue;
+
+      if (high_mask(r, c) == FOREGROUND)
+      {
+        output(r, c) = FOREGROUND;
+      }
+      else if (low_mask(r, c) == FOREGROUND)
+      {
+        // consider the pixel to be a F/G pixel if it is 8-connected to
+        // a F/G pixel in the high mask
+        // check if there is an 8-connected foreground pixel
+        if (high_mask(r - 1, c - 1))
+          output(r, c) = FOREGROUND;
+        else if (high_mask(r - 1, c))
+          output(r, c) = FOREGROUND;
+        else if (high_mask(r - 1, c + 1))
+          output(r, c) = FOREGROUND;
+        else if (high_mask(r, c - 1))
+          output(r, c) = FOREGROUND;
+        else if (high_mask(r, c + 1))
+          output(r, c) = FOREGROUND;
+        else if (high_mask(r + 1, c - 1))
+          output(r, c) = FOREGROUND;
+        else if (high_mask(r + 1, c))
+          output(r, c) = FOREGROUND;
+        else if (high_mask(r + 1, c + 1))
+          output(r, c) = FOREGROUND;
+      }
+    }
+  }
 }
 
 void PratiMediodBGS::CalculateMasks(int r, int c, const RgbPixel& pixel)
 {
-	int pos = r*m_params.Width()+c;
-
-	// calculate l-inf distance between current value and median value
-	unsigned char dist = 0;
-	for(int ch = 0; ch < NUM_CHANNELS; ++ch)
-	{
-		int tempDist = abs(pixel(ch) - m_median_buffer[pos].median(ch));
-		if(tempDist > dist)
-			dist = tempDist;
-	}
-	m_background(r,c) = m_median_buffer[pos].median;
-
-	// check if pixel is a B/G or F/G pixel according to the low threshold B/G model
-	m_mask_low_threshold(r,c) = BACKGROUND;
-	if(dist > m_params.LowThreshold())
-	{
-		m_mask_low_threshold(r,c) = FOREGROUND;
-	}
-
-	// check if pixel is a B/G or F/G pixel according to the high threshold B/G model
-	m_mask_high_threshold(r,c)= BACKGROUND;
-	if(dist > m_params.HighThreshold())
-	{
-		m_mask_high_threshold(r,c) = FOREGROUND;
-	}
+  int pos = r*m_params.Width() + c;
+
+  // calculate l-inf distance between current value and median value
+  unsigned char dist = 0;
+  for (int ch = 0; ch < NUM_CHANNELS; ++ch)
+  {
+    int tempDist = abs(pixel(ch) - m_median_buffer[pos].median(ch));
+    if (tempDist > dist)
+      dist = tempDist;
+  }
+  m_background(r, c) = m_median_buffer[pos].median;
+
+  // check if pixel is a B/G or F/G pixel according to the low threshold B/G model
+  m_mask_low_threshold(r, c) = BACKGROUND;
+  if (dist > m_params.LowThreshold())
+  {
+    m_mask_low_threshold(r, c) = FOREGROUND;
+  }
+
+  // check if pixel is a B/G or F/G pixel according to the high threshold B/G model
+  m_mask_high_threshold(r, c) = BACKGROUND;
+  if (dist > m_params.HighThreshold())
+  {
+    m_mask_high_threshold(r, c) = FOREGROUND;
+  }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -245,29 +245,29 @@ void PratiMediodBGS::CalculateMasks(int r, int c, const RgbPixel& pixel)
 //  output - a pointer to the data of a gray value image of the same size 
 //					values: 255-foreground, 0-background
 ///////////////////////////////////////////////////////////////////////////////
-void PratiMediodBGS::Subtract(int frame_num, const RgbImage& data, 
-																BwImage& low_threshold_mark, BwImage& high_threshold_mark)
+void PratiMediodBGS::Subtract(int frame_num, const RgbImage& data,
+  BwImage& low_threshold_mark, BwImage& high_threshold_mark)
 {
-	if(frame_num < m_params.HistorySize())
-	{
-		low_threshold_mark.Clear();
-		high_threshold_mark.Clear();
-		return;
-	}
-
-	// update each pixel of the image
-	for(unsigned int r = 0; r < m_params.Height(); ++r)
-	{
-		for(unsigned int c = 0; c < m_params.Width(); ++c)
-		{	
-			// need at least one frame of data before we can start calculating the masks
-			CalculateMasks(r, c, data(r,c));
-		}
-	}
-
-	// combine low and high threshold masks
-	Combine(m_mask_low_threshold, m_mask_high_threshold, low_threshold_mark);
-	Combine(m_mask_low_threshold, m_mask_high_threshold, high_threshold_mark);
+  if (frame_num < m_params.HistorySize())
+  {
+    low_threshold_mark.Clear();
+    high_threshold_mark.Clear();
+    return;
+  }
+
+  // update each pixel of the image
+  for (unsigned int r = 0; r < m_params.Height(); ++r)
+  {
+    for (unsigned int c = 0; c < m_params.Width(); ++c)
+    {
+      // need at least one frame of data before we can start calculating the masks
+      CalculateMasks(r, c, data(r, c));
+    }
+  }
+
+  // combine low and high threshold masks
+  Combine(m_mask_low_threshold, m_mask_high_threshold, low_threshold_mark);
+  Combine(m_mask_low_threshold, m_mask_high_threshold, high_threshold_mark);
 }
 
 
diff --git a/package_bgs/dp/PratiMediodBGS.h b/package_bgs/dp/PratiMediodBGS.h
index bc8cb7fdf94a8eead4b79cdf5403ce4f0d74d8f4..6bc8f922411e1fbfabb322248fca0d4c295fb58e 100644
--- a/package_bgs/dp/PratiMediodBGS.h
+++ b/package_bgs/dp/PratiMediodBGS.h
@@ -18,7 +18,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * PratiMediodBGS.hpp
 *
-* Purpose: Implementation of the temporal median background 
+* Purpose: Implementation of the temporal median background
 *		  		 subtraction algorithm described in:
 *
 * [1] "Detecting Moving Objects, Shosts, and Shadows in Video Stream"
@@ -29,7 +29,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Author: Donovan Parks, September 2007
 *
-* Please note that this is not an implementation of the complete system 
+* Please note that this is not an implementation of the complete system
 * given in the above papers. It simply implements the temporal media background
 * subtraction algorithm.
 
@@ -37,7 +37,7 @@ Example:
 Algorithms::BackgroundSubtraction::PratiParams params;
 params.SetFrameSize(width, height);
 params.LowThreshold() = 30;
-params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing 
+params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing
 params.SamplingRate() = 5;
 params.HistorySize() = 16;
 params.Weight() = 5;
@@ -45,9 +45,7 @@ params.Weight() = 5;
 Algorithms::BackgroundSubtraction::PratiMediodBGS bgs;
 bgs.Initalize(params);
 ******************************************************************************/
-
-#ifndef PRATI_MEDIA_BGS_H
-#define PRATI_MEDIA_BGS_H
+#pragma once
 
 #include <vector>
 #include "Bgs.h"
@@ -68,9 +66,9 @@ namespace Algorithms
       int &HistorySize() { return m_history_size; }
 
     private:
-      // The low threshold is used to supress noise. The high thresohld is used 
-      // to find pixels highly likely to be foreground. This implementation uses an L-inf 
-      // distance measure and a pixel p is considered F/G if D(I(p), B(p)) > threshold. 
+      // The low threshold is used to supress noise. The high thresohld is used
+      // to find pixels highly likely to be foreground. This implementation uses an L-inf
+      // distance measure and a pixel p is considered F/G if D(I(p), B(p)) > threshold.
       // The two threshold maps are combined as in [2].
       unsigned int m_low_threshold;
       unsigned int m_high_threshold;
@@ -88,9 +86,9 @@ namespace Algorithms
     };
 
     // --- Prati Mediod BGS algorithm ---
-    class PratiMediodBGS : public Bgs 
+    class PratiMediodBGS : public Bgs
     {
-    private:	
+    private:
       // sum of L-inf distances from a sample point to all other sample points
       struct MEDIAN_BUFFER
       {
@@ -109,13 +107,13 @@ namespace Algorithms
       void Initalize(const BgsParams& param);
 
       void InitModel(const RgbImage& data);
-      void Subtract(int frame_num, const RgbImage& data,  
-        BwImage& low_threshold_mask, BwImage& high_threshold_mask);	
-      void Update(int frame_num, const RgbImage& data,  const BwImage& update_mask);
+      void Subtract(int frame_num, const RgbImage& data,
+        BwImage& low_threshold_mask, BwImage& high_threshold_mask);
+      void Update(int frame_num, const RgbImage& data, const BwImage& update_mask);
 
       RgbImage* Background() { return &m_background; }
 
-    private:	
+    private:
       MEDIAN_BUFFER* m_median_buffer;
 
       void CalculateMasks(int r, int c, const RgbPixel& pixel);
@@ -132,11 +130,3 @@ namespace Algorithms
 
   }
 }
-
-#endif
-
-
-
-
-
-
diff --git a/package_bgs/dp/TextureBGS.cpp b/package_bgs/dp/TextureBGS.cpp
index 62684f8df6b8bcbbf4db38e9d32c456045d77153..920f140eecbf302c3e9b4faeecfb08d22c5c9fbd 100644
--- a/package_bgs/dp/TextureBGS.cpp
+++ b/package_bgs/dp/TextureBGS.cpp
@@ -16,40 +16,40 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "TextureBGS.h"
 
-TextureBGS::TextureBGS(){}
-TextureBGS::~TextureBGS(){}
+TextureBGS::TextureBGS() {}
+TextureBGS::~TextureBGS() {}
 
 void TextureBGS::LBP(RgbImage& image, RgbImage& texture)
 {
-  for(int y = TEXTURE_R; y < image.Ptr()->height-TEXTURE_R; ++y)
+  for (int y = TEXTURE_R; y < image.Ptr()->height - TEXTURE_R; ++y)
   {
-    for(int x = TEXTURE_R; x < image.Ptr()->width-TEXTURE_R; ++x)
-    {		
-      for(int ch = 0; ch < NUM_CHANNELS; ++ch)
+    for (int x = TEXTURE_R; x < image.Ptr()->width - TEXTURE_R; ++x)
+    {
+      for (int ch = 0; ch < NUM_CHANNELS; ++ch)
       {
         unsigned char textureCode = 0;
         int centerValue = (int)image(y, x, ch);
 
         // this only works for a texture radius of 2
-        if(centerValue - (int)image(y-2, x, ch) + HYSTERSIS >= 0)
+        if (centerValue - (int)image(y - 2, x, ch) + HYSTERSIS >= 0)
           textureCode += 1;
 
-        if(centerValue - (int)image(y-1, x-2, ch) + HYSTERSIS >= 0)
+        if (centerValue - (int)image(y - 1, x - 2, ch) + HYSTERSIS >= 0)
           textureCode += 2;
 
-        if(centerValue - (int)image(y-1, x+2, ch) + HYSTERSIS >= 0)
+        if (centerValue - (int)image(y - 1, x + 2, ch) + HYSTERSIS >= 0)
           textureCode += 4;
 
-        if(centerValue - (int)image(y+1, x-2, ch) + HYSTERSIS >= 0)
+        if (centerValue - (int)image(y + 1, x - 2, ch) + HYSTERSIS >= 0)
           textureCode += 8;
 
-        if(centerValue - (int)image(y+1, x+2, ch) + HYSTERSIS >= 0)
+        if (centerValue - (int)image(y + 1, x + 2, ch) + HYSTERSIS >= 0)
           textureCode += 16;
 
-        if(centerValue - (int)image(y+2, x, ch) + HYSTERSIS >= 0)
+        if (centerValue - (int)image(y + 2, x, ch) + HYSTERSIS >= 0)
           textureCode += 32;
 
-        texture(y,x,ch) = textureCode;
+        texture(y, x, ch) = textureCode;
       }
     }
   }
@@ -58,14 +58,14 @@ void TextureBGS::LBP(RgbImage& image, RgbImage& texture)
 void TextureBGS::Histogram(RgbImage& texture, TextureHistogram* curTextureHist)
 {
   // calculate histogram within a 2*REGION_R square
-  for(int y = REGION_R+TEXTURE_R; y < texture.Ptr()->height-REGION_R-TEXTURE_R; ++y)
+  for (int y = REGION_R + TEXTURE_R; y < texture.Ptr()->height - REGION_R - TEXTURE_R; ++y)
   {
-    for(int x = REGION_R+TEXTURE_R; x < texture.Ptr()->width-REGION_R-TEXTURE_R; ++x)
-    {	
-      int index = x+y*(texture.Ptr()->width);
+    for (int x = REGION_R + TEXTURE_R; x < texture.Ptr()->width - REGION_R - TEXTURE_R; ++x)
+    {
+      int index = x + y*(texture.Ptr()->width);
 
       // clear histogram
-      for(int i = 0; i < NUM_BINS; ++i)
+      for (int i = 0; i < NUM_BINS; ++i)
       {
         curTextureHist[index].r[i] = 0;
         curTextureHist[index].g[i] = 0;
@@ -73,13 +73,13 @@ void TextureBGS::Histogram(RgbImage& texture, TextureHistogram* curTextureHist)
       }
 
       // calculate histogram
-      for(int j = -REGION_R; j <= REGION_R; ++j)
+      for (int j = -REGION_R; j <= REGION_R; ++j)
       {
-        for(int i = -REGION_R; i <= REGION_R; ++i)
+        for (int i = -REGION_R; i <= REGION_R; ++i)
         {
-          curTextureHist[index].r[texture(y+j,x+i,2)]++;
-          curTextureHist[index].g[texture(y+j,x+i,1)]++;
-          curTextureHist[index].b[texture(y+j,x+i,0)]++;
+          curTextureHist[index].r[texture(y + j, x + i, 2)]++;
+          curTextureHist[index].g[texture(y + j, x + i, 1)]++;
+          curTextureHist[index].b[texture(y + j, x + i, 0)]++;
         }
       }
     }
@@ -88,66 +88,66 @@ void TextureBGS::Histogram(RgbImage& texture, TextureHistogram* curTextureHist)
 
 int TextureBGS::ProximityMeasure(TextureHistogram& bgTexture, TextureHistogram& curTextureHist)
 {
-  int proximity = 0;	
-  for(int i = 0; i < NUM_BINS; ++i)
+  int proximity = 0;
+  for (int i = 0; i < NUM_BINS; ++i)
   {
     proximity += std::min(bgTexture.r[i], curTextureHist.r[i]);
     proximity += std::min(bgTexture.g[i], curTextureHist.g[i]);
     proximity += std::min(bgTexture.b[i], curTextureHist.b[i]);
   }
 
-  return proximity;	
+  return proximity;
 }
 
-void TextureBGS::BgsCompare(TextureArray* bgModel, TextureHistogram* curTextureHist, 
-                unsigned char* modeArray, float threshold, BwImage& fgMask)
+void TextureBGS::BgsCompare(TextureArray* bgModel, TextureHistogram* curTextureHist,
+  unsigned char* modeArray, float threshold, BwImage& fgMask)
 {
   cvZero(fgMask.Ptr());
 
-  for(int y = REGION_R+TEXTURE_R; y < fgMask.Ptr()->height-REGION_R-TEXTURE_R; ++y)
+  for (int y = REGION_R + TEXTURE_R; y < fgMask.Ptr()->height - REGION_R - TEXTURE_R; ++y)
   {
-    for(int x = REGION_R+TEXTURE_R; x < fgMask.Ptr()->width-REGION_R-TEXTURE_R; ++x)
-    {	
-      int index = x+y*(fgMask.Ptr()->width);
+    for (int x = REGION_R + TEXTURE_R; x < fgMask.Ptr()->width - REGION_R - TEXTURE_R; ++x)
+    {
+      int index = x + y*(fgMask.Ptr()->width);
 
       // find closest matching texture in background model
       int maxProximity = -1;
 
-      for(int m = 0; m < NUM_MODES; ++m)
+      for (int m = 0; m < NUM_MODES; ++m)
       {
         int proximity = ProximityMeasure(bgModel[index].mode[m], curTextureHist[index]);
 
-        if(proximity > maxProximity)
+        if (proximity > maxProximity)
         {
           maxProximity = proximity;
           modeArray[index] = m;
         }
       }
 
-      if(maxProximity < threshold)
-        fgMask(y,x) = 255;
+      if (maxProximity < threshold)
+        fgMask(y, x) = 255;
     }
   }
 }
 
-void TextureBGS::UpdateModel(BwImage& fgMask, TextureArray* bgModel, 
-                 TextureHistogram* curTextureHist, unsigned char* modeArray)
+void TextureBGS::UpdateModel(BwImage& fgMask, TextureArray* bgModel,
+  TextureHistogram* curTextureHist, unsigned char* modeArray)
 {
-  for(int y = REGION_R+TEXTURE_R; y < fgMask.Ptr()->height-REGION_R-TEXTURE_R; ++y)
+  for (int y = REGION_R + TEXTURE_R; y < fgMask.Ptr()->height - REGION_R - TEXTURE_R; ++y)
   {
-    for(int x = REGION_R+TEXTURE_R; x < fgMask.Ptr()->width-REGION_R-TEXTURE_R; ++x)
-    {		
-      int index = x+y*(fgMask.Ptr()->width);
+    for (int x = REGION_R + TEXTURE_R; x < fgMask.Ptr()->width - REGION_R - TEXTURE_R; ++x)
+    {
+      int index = x + y*(fgMask.Ptr()->width);
 
-      if(fgMask(y,x) == 0)
+      if (fgMask(y, x) == 0)
       {
-        for(int i = 0; i < NUM_BINS; ++i)
+        for (int i = 0; i < NUM_BINS; ++i)
         {
           bgModel[index].mode[modeArray[index]].r[i]
-          = (unsigned char)(ALPHA*curTextureHist[index].r[i]
-          + (1-ALPHA)*bgModel[index].mode[modeArray[index]].r[i] + 0.5);
+            = (unsigned char)(ALPHA*curTextureHist[index].r[i]
+              + (1 - ALPHA)*bgModel[index].mode[modeArray[index]].r[i] + 0.5);
         }
-      }				
+      }
     }
-  }	
+  }
 }
diff --git a/package_bgs/dp/TextureBGS.h b/package_bgs/dp/TextureBGS.h
index 573e6f9af7992833f310dba72aa9a4e5e72bc771..2650f04cb1b55a8a71ce157e40b9806a73d7a8af 100644
--- a/package_bgs/dp/TextureBGS.h
+++ b/package_bgs/dp/TextureBGS.h
@@ -14,6 +14,8 @@ 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
+
 #include <math.h>
 #include "Image.h"
 
@@ -23,7 +25,7 @@ const int TEXTURE_R = 2;		// Note: the code currently assumes this value is 2
 const int NUM_BINS = 64;		// 2^TEXTURE_POINTS
 const int HYSTERSIS = 3;
 const double ALPHA = 0.05f;
-const double THRESHOLD = 0.5*(REGION_R+REGION_R+1)*(REGION_R+REGION_R+1)*NUM_CHANNELS;
+const double THRESHOLD = 0.5*(REGION_R + REGION_R + 1)*(REGION_R + REGION_R + 1)*NUM_CHANNELS;
 const int NUM_MODES = 1;		// The paper describes how multiple modes can be maintained,
 // but this implementation does not fully support more than one
 
@@ -48,8 +50,8 @@ public:
   void LBP(RgbImage& image, RgbImage& texture);
   void Histogram(RgbImage& texture, TextureHistogram* curTextureHist);
   int ProximityMeasure(TextureHistogram& bgTexture, TextureHistogram& curTextureHist);
-  void BgsCompare(TextureArray* bgModel, TextureHistogram* curTextureHist, 
-                unsigned char* modeArray, float threshold, BwImage& fgMask);
-  void UpdateModel(BwImage& fgMask, TextureArray* bgModel, 
-                 TextureHistogram* curTextureHist, unsigned char* modeArray);
+  void BgsCompare(TextureArray* bgModel, TextureHistogram* curTextureHist,
+    unsigned char* modeArray, float threshold, BwImage& fgMask);
+  void UpdateModel(BwImage& fgMask, TextureArray* bgModel,
+    TextureHistogram* curTextureHist, unsigned char* modeArray);
 };
diff --git a/package_bgs/dp/WrenGA.cpp b/package_bgs/dp/WrenGA.cpp
index 16e2640b79b02fe51bf486c62754a6a21455f534..80a9e27e746cf14789f7001f412b50adafa87f0d 100644
--- a/package_bgs/dp/WrenGA.cpp
+++ b/package_bgs/dp/WrenGA.cpp
@@ -18,7 +18,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * WrenGA.h
 *
-* Purpose: Implementation of the running Gaussian average background 
+* Purpose: Implementation of the running Gaussian average background
 *		  		 subtraction algorithm described in:
 *	  			 "Pfinder: real-time tracking of the human body"
 * 						by C. Wren et al (1997)
@@ -36,114 +36,114 @@ using namespace Algorithms::BackgroundSubtraction;
 
 WrenGA::WrenGA()
 {
-	m_gaussian = NULL;
+  m_gaussian = NULL;
 }
 
 WrenGA::~WrenGA()
 {
-	delete[] m_gaussian;
+  delete[] m_gaussian;
 }
 
 void WrenGA::Initalize(const BgsParams& param)
 {
-	m_params = (WrenParams&)param;
-
-	m_variance = 36.0f;
-
-	// GMM for each pixel
-	m_gaussian = new GAUSSIAN[m_params.Size()];
-	for(unsigned int i = 0; i < m_params.Size(); ++i)
-	{
-		for(int ch = 0; ch < NUM_CHANNELS; ++ch)
-		{
-			m_gaussian[i].mu[ch] = 0;
-			m_gaussian[i].var[ch] = 0;
-		}
-	}
-
-	m_background = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 3);
+  m_params = (WrenParams&)param;
+
+  m_variance = 36.0f;
+
+  // GMM for each pixel
+  m_gaussian = new GAUSSIAN[m_params.Size()];
+  for (unsigned int i = 0; i < m_params.Size(); ++i)
+  {
+    for (int ch = 0; ch < NUM_CHANNELS; ++ch)
+    {
+      m_gaussian[i].mu[ch] = 0;
+      m_gaussian[i].var[ch] = 0;
+    }
+  }
+
+  m_background = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 3);
 }
 
 void WrenGA::InitModel(const RgbImage& data)
 {
-	int pos = 0;
-
-	for(unsigned int r = 0; r < m_params.Height(); ++r)
-	{
-		for(unsigned int c = 0; c < m_params.Width(); ++c)
-		{
-			for(int ch = 0; ch < NUM_CHANNELS; ++ch)
-			{	
-				m_gaussian[pos].mu[ch] = data(r,c,ch);
-				m_gaussian[pos].var[ch] = m_variance;
-			}
-
-			pos++;
-		}
-	}
+  int pos = 0;
+
+  for (unsigned int r = 0; r < m_params.Height(); ++r)
+  {
+    for (unsigned int c = 0; c < m_params.Width(); ++c)
+    {
+      for (int ch = 0; ch < NUM_CHANNELS; ++ch)
+      {
+        m_gaussian[pos].mu[ch] = data(r, c, ch);
+        m_gaussian[pos].var[ch] = m_variance;
+      }
+
+      pos++;
+    }
+  }
 }
 
-void WrenGA::Update(int frame_num, const RgbImage& data,  const BwImage& update_mask)
+void WrenGA::Update(int frame_num, const RgbImage& data, const BwImage& update_mask)
 {
-	int pos = 0;
-
-	for(unsigned int r = 0; r < m_params.Height(); ++r)
-	{
-		for(unsigned int c = 0; c < m_params.Width(); ++c)
-		{
-			// perform conditional updating only if we are passed the learning phase
-			if(update_mask(r,c) == BACKGROUND || frame_num < m_params.LearningFrames())
-			{
-				float dR = m_gaussian[pos].mu[0] - data(r,c,0);
-				float dG = m_gaussian[pos].mu[1] - data(r,c,1);
-				float dB = m_gaussian[pos].mu[2] - data(r,c,2);
-
-				float dist = (dR*dR + dG*dG + dB*dB);
-
-				m_gaussian[pos].mu[0] -= m_params.Alpha()*(dR);
-				m_gaussian[pos].mu[1] -= m_params.Alpha()*(dG);
-				m_gaussian[pos].mu[2] -= m_params.Alpha()*(dB);
-
-				float sigmanew = m_gaussian[pos].var[0] + m_params.Alpha()*(dist-m_gaussian[pos].var[0]);
-				m_gaussian[pos].var[0] = sigmanew < 4 ? 4 : sigmanew > 5*m_variance ? 5*m_variance : sigmanew;
-
-				m_background(r, c, 0) = (unsigned char)(m_gaussian[pos].mu[0] + 0.5);
-				m_background(r, c, 1) = (unsigned char)(m_gaussian[pos].mu[1] + 0.5);
-				m_background(r, c, 2) = (unsigned char)(m_gaussian[pos].mu[2] + 0.5);
-			}
-
-			pos++;
-		}
-	}
+  int pos = 0;
+
+  for (unsigned int r = 0; r < m_params.Height(); ++r)
+  {
+    for (unsigned int c = 0; c < m_params.Width(); ++c)
+    {
+      // perform conditional updating only if we are passed the learning phase
+      if (update_mask(r, c) == BACKGROUND || frame_num < m_params.LearningFrames())
+      {
+        float dR = m_gaussian[pos].mu[0] - data(r, c, 0);
+        float dG = m_gaussian[pos].mu[1] - data(r, c, 1);
+        float dB = m_gaussian[pos].mu[2] - data(r, c, 2);
+
+        float dist = (dR*dR + dG*dG + dB*dB);
+
+        m_gaussian[pos].mu[0] -= m_params.Alpha()*(dR);
+        m_gaussian[pos].mu[1] -= m_params.Alpha()*(dG);
+        m_gaussian[pos].mu[2] -= m_params.Alpha()*(dB);
+
+        float sigmanew = m_gaussian[pos].var[0] + m_params.Alpha()*(dist - m_gaussian[pos].var[0]);
+        m_gaussian[pos].var[0] = sigmanew < 4 ? 4 : sigmanew > 5 * m_variance ? 5 * m_variance : sigmanew;
+
+        m_background(r, c, 0) = (unsigned char)(m_gaussian[pos].mu[0] + 0.5);
+        m_background(r, c, 1) = (unsigned char)(m_gaussian[pos].mu[1] + 0.5);
+        m_background(r, c, 2) = (unsigned char)(m_gaussian[pos].mu[2] + 0.5);
+      }
+
+      pos++;
+    }
+  }
 }
 
-void WrenGA::SubtractPixel(int r, int c, const RgbPixel& pixel, 
-															unsigned char& low_threshold, 
-															unsigned char& high_threshold)
+void WrenGA::SubtractPixel(int r, int c, const RgbPixel& pixel,
+  unsigned char& low_threshold,
+  unsigned char& high_threshold)
 {
-	unsigned int pos = r*m_params.Width()+c;
-
-	// calculate distance between model and pixel
-	float mu[NUM_CHANNELS];
-	float var[1];
-	float delta[NUM_CHANNELS];
-	float dist = 0;
-	for(int ch = 0; ch < NUM_CHANNELS; ++ch)
-	{
-		mu[ch] = m_gaussian[pos].mu[ch];
-		var[0] = m_gaussian[pos].var[0];
-		delta[ch] = mu[ch] - pixel(ch);
-		dist += delta[ch]*delta[ch];
-	}
-
-	// calculate the squared distance and see if pixel fits the B/G model
-	low_threshold = BACKGROUND;
-	high_threshold = BACKGROUND;
-
-	if(dist > m_params.LowThreshold()*var[0])
-		low_threshold = FOREGROUND;
-	if(dist > m_params.HighThreshold()*var[0])
-		high_threshold = FOREGROUND;
+  unsigned int pos = r*m_params.Width() + c;
+
+  // calculate distance between model and pixel
+  float mu[NUM_CHANNELS];
+  float var[1];
+  float delta[NUM_CHANNELS];
+  float dist = 0;
+  for (int ch = 0; ch < NUM_CHANNELS; ++ch)
+  {
+    mu[ch] = m_gaussian[pos].mu[ch];
+    var[0] = m_gaussian[pos].var[0];
+    delta[ch] = mu[ch] - pixel(ch);
+    dist += delta[ch] * delta[ch];
+  }
+
+  // calculate the squared distance and see if pixel fits the B/G model
+  low_threshold = BACKGROUND;
+  high_threshold = BACKGROUND;
+
+  if (dist > m_params.LowThreshold()*var[0])
+    low_threshold = FOREGROUND;
+  if (dist > m_params.HighThreshold()*var[0])
+    high_threshold = FOREGROUND;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -154,20 +154,20 @@ void WrenGA::SubtractPixel(int r, int c, const RgbPixel& pixel,
 //					(the memory should already be reserved) 
 //					values: 255-foreground, 125-shadow, 0-background
 ///////////////////////////////////////////////////////////////////////////////
-void WrenGA::Subtract(int frame_num, const RgbImage& data, 
-												BwImage& low_threshold_mask, BwImage& high_threshold_mask)
+void WrenGA::Subtract(int frame_num, const RgbImage& data,
+  BwImage& low_threshold_mask, BwImage& high_threshold_mask)
 {
-	unsigned char low_threshold, high_threshold;
-
-	// update each pixel of the image
-	for(unsigned int r = 0; r < m_params.Height(); ++r)
-	{
-		for(unsigned int c = 0; c < m_params.Width(); ++c)
-		{
-			SubtractPixel(r, c, data(r,c), low_threshold, high_threshold);
-			low_threshold_mask(r,c) = low_threshold;
-			high_threshold_mask(r,c) = high_threshold;
-		}
-	}
+  unsigned char low_threshold, high_threshold;
+
+  // update each pixel of the image
+  for (unsigned int r = 0; r < m_params.Height(); ++r)
+  {
+    for (unsigned int c = 0; c < m_params.Width(); ++c)
+    {
+      SubtractPixel(r, c, data(r, c), low_threshold, high_threshold);
+      low_threshold_mask(r, c) = low_threshold;
+      high_threshold_mask(r, c) = high_threshold;
+    }
+  }
 }
 
diff --git a/package_bgs/dp/WrenGA.h b/package_bgs/dp/WrenGA.h
index 116c292a9adfc6f9c80313865d5b501daec8e269..97e97ee7022c0ff3964332d083e93858fabe038c 100644
--- a/package_bgs/dp/WrenGA.h
+++ b/package_bgs/dp/WrenGA.h
@@ -18,7 +18,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * WrenGA.hpp
 *
-* Purpose: Implementation of the running Gaussian average background 
+* Purpose: Implementation of the running Gaussian average background
 *		  		 subtraction algorithm described in:
 *	  			 "Pfinder: real-time tracking of the human body"
 * 						by C. Wren et al (1997)
@@ -33,16 +33,14 @@ Example:
 Algorithms::BackgroundSubtraction::WrenParams params;
 params.SetFrameSize(width, height);
 params.LowThreshold() = 3.5f*3.5f;
-params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing 
+params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing
 params.Alpha() = 0.005f;
 params.LearningFrames() = 30;
 
 Algorithms::BackgroundSubtraction::WrenGA bgs;
 bgs.Initalize(params);
 ******************************************************************************/
-
-#ifndef WREN_GA_H
-#define WREN_GA_H
+#pragma once
 
 #include "Bgs.h"
 
@@ -74,7 +72,7 @@ namespace Algorithms
     // --- Mean BGS algorithm ---
     class WrenGA : public Bgs
     {
-    private:	
+    private:
       struct GAUSSIAN
       {
         float mu[NUM_CHANNELS];
@@ -88,19 +86,19 @@ namespace Algorithms
       void Initalize(const BgsParams& param);
 
       void InitModel(const RgbImage& data);
-      void Subtract(int frame_num, const RgbImage& data,  
-        BwImage& low_threshold_mask, BwImage& high_threshold_mask);	
-      void Update(int frame_num, const RgbImage& data,  const BwImage& update_mask);
+      void Subtract(int frame_num, const RgbImage& data,
+        BwImage& low_threshold_mask, BwImage& high_threshold_mask);
+      void Update(int frame_num, const RgbImage& data, const BwImage& update_mask);
 
       RgbImage* Background() { return &m_background; }
 
-    private:	
-      void SubtractPixel(int r, int c, const RgbPixel& pixel, 
+    private:
+      void SubtractPixel(int r, int c, const RgbPixel& pixel,
         unsigned char& lowThreshold, unsigned char& highThreshold);
 
       WrenParams m_params;
 
-      // Initial variance for the newly generated components. 
+      // Initial variance for the newly generated components.
       float m_variance;
 
       // dynamic array for the mixture of Gaussians
@@ -110,11 +108,3 @@ namespace Algorithms
     };
   }
 }
-
-#endif
-
-
-
-
-
-
diff --git a/package_bgs/dp/ZivkovicAGMM.cpp b/package_bgs/dp/ZivkovicAGMM.cpp
index 041ffc43ca598d9035dc20018602e1a6ac22d905..f73d5a145b80710cff510063b1762c260b9c333f 100644
--- a/package_bgs/dp/ZivkovicAGMM.cpp
+++ b/package_bgs/dp/ZivkovicAGMM.cpp
@@ -18,7 +18,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * ZivkovicAGMM.cpp
 *
-* Purpose: Implementation of the Gaussian mixture model (GMM) background 
+* Purpose: Implementation of the Gaussian mixture model (GMM) background
 *		  		 subtraction algorithm developed by Z. Zivkovic.
 *
 * Author: Donovan Parks, September 2007
@@ -28,13 +28,13 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * following papers:
 *
 *	"Improved adaptive Gausian mixture model for background subtraction"
-*		Z.Zivkovic 
+*		Z.Zivkovic
 *		International Conference Pattern Recognition, UK, August, 2004
 *
 *
-* "Efficient Adaptive Density Estimapion per Image Pixel for the 
+* "Efficient Adaptive Density Estimapion per Image Pixel for the
 *			Task of Background Subtraction"
-*		Z.Zivkovic, F. van der Heijden 
+*		Z.Zivkovic, F. van der Heijden
 *		Pattern Recognition Letters, vol. 27, no. 7, pages 773-780, 2006.
 *
 * Zivkovic's code can be obtained at: www.zoranz.net
@@ -46,328 +46,328 @@ using namespace Algorithms::BackgroundSubtraction;
 
 ZivkovicAGMM::ZivkovicAGMM()
 {
-	m_modes = NULL;
-	m_modes_per_pixel = NULL;
+  m_modes = NULL;
+  m_modes_per_pixel = NULL;
 }
 
 ZivkovicAGMM::~ZivkovicAGMM()
 {
-	delete[] m_modes;
-	delete[] m_modes_per_pixel;
+  delete[] m_modes;
+  delete[] m_modes_per_pixel;
 }
 
 void ZivkovicAGMM::Initalize(const BgsParams& param)
 {
-	m_params = (ZivkovicParams&)param;
+  m_params = (ZivkovicParams&)param;
 
-	m_num_bands = 3;							//always 3 - not implemented for other values!
-	m_bg_threshold = 0.75f;				//1-cf from the paper 
-	m_variance = 36.0f;						// variance for the new mode
-	m_complexity_prior = 0.05f;		// complexity reduction prior constant
+  m_num_bands = 3;							//always 3 - not implemented for other values!
+  m_bg_threshold = 0.75f;				//1-cf from the paper
+  m_variance = 36.0f;						// variance for the new mode
+  m_complexity_prior = 0.05f;		// complexity reduction prior constant
 
-	// GMM for each pixel
-	m_modes = new GMM[m_params.Size()*m_params.MaxModes()];
+  // GMM for each pixel
+  m_modes = new GMM[m_params.Size()*m_params.MaxModes()];
 
-	// used modes per pixel
-	m_modes_per_pixel = new unsigned char[m_params.Size()];
+  // used modes per pixel
+  m_modes_per_pixel = new unsigned char[m_params.Size()];
 
-	m_background = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 3);
+  m_background = cvCreateImage(cvSize(m_params.Width(), m_params.Height()), IPL_DEPTH_8U, 3);
 }
 
 void ZivkovicAGMM::InitModel(const RgbImage& data)
 {
-	for(unsigned int i = 0; i < m_params.Size(); ++i)
-	{
-		m_modes_per_pixel[i] = 0;
-	}
-
-	for(unsigned int i = 0; i < m_params.Size()*m_params.MaxModes(); ++i)
-	{
-		m_modes[i].weight = 0;
-		m_modes[i].sigma = 0;
-		m_modes[i].muR = 0;
-		m_modes[i].muG = 0;
-		m_modes[i].muB = 0;
-	}
+  for (unsigned int i = 0; i < m_params.Size(); ++i)
+  {
+    m_modes_per_pixel[i] = 0;
+  }
+
+  for (unsigned int i = 0; i < m_params.Size()*m_params.MaxModes(); ++i)
+  {
+    m_modes[i].weight = 0;
+    m_modes[i].sigma = 0;
+    m_modes[i].muR = 0;
+    m_modes[i].muG = 0;
+    m_modes[i].muB = 0;
+  }
 }
 
-void ZivkovicAGMM::Update(int frame_num, const RgbImage& data,  const BwImage& update_mask)
+void ZivkovicAGMM::Update(int frame_num, const RgbImage& data, const BwImage& update_mask)
 {
-	// it doesn't make sense to have conditional updates in the GMM framework
+  // it doesn't make sense to have conditional updates in the GMM framework
 }
 
-void ZivkovicAGMM::SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned char* pModesUsed, 
-																	unsigned char& low_threshold, unsigned char& high_threshold)
+void ZivkovicAGMM::SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned char* pModesUsed,
+  unsigned char& low_threshold, unsigned char& high_threshold)
 {
-	//calculate distances to the modes (+ sort???)
-	//here we need to go in descending order!!!
-	long pos;
-	bool bFitsPDF=0;
-	bool bBackgroundLow=false;
-	bool bBackgroundHigh=false;
-
-	float fOneMinAlpha = 1-m_params.Alpha();
-
-	float prune = -m_params.Alpha()*m_complexity_prior;
-
-	int nModes =* pModesUsed;
-	float totalWeight = 0.0f;
-
-	// calculate number of Gaussians to include in the background model
-	int backgroundGaussians = 0;
-	double sum = 0.0;
-	for(int i = 0; i < nModes; ++i)
-	{
-		if(sum < m_bg_threshold)
-		{
-			backgroundGaussians++;
-			sum += m_modes[posPixel+i].weight;
-		}
-		else
-		{
-			break;
-		}
-	}
-
-	// update all distributions and check for match with current pixel
-	for (int iModes = 0; iModes < nModes; iModes++)
-	{
-		pos=posPixel+iModes;
-		float weight = m_modes[pos].weight;
-
-		//fit not found yet
-		if (!bFitsPDF)
-		{
-			//check if it belongs to some of the modes
-			//calculate distance
-			float var = m_modes[pos].sigma;
-			float muR = m_modes[pos].muR;
-			float muG = m_modes[pos].muG;
-			float muB = m_modes[pos].muB;
-		
-			float dR=muR - pixel(0);
-			float dG=muG - pixel(1);
-			float dB=muB - pixel(2);
-			
-			// calculate the squared distance
-			float dist = (dR*dR + dG*dG + dB*dB);
-
-			if(dist < m_params.HighThreshold()*var && iModes < backgroundGaussians)
-				bBackgroundHigh = true;
-			
-			//check fit
-			if (dist < m_params.LowThreshold()*var)
-			{
-				/////
-				//belongs to the mode
-				bFitsPDF = true;
-
-				// check if this Gaussian is part of the background model
-				if(iModes < backgroundGaussians) 
-					bBackgroundLow = true;
-
-				//update distribution
-				float k = m_params.Alpha()/weight;
-				weight = fOneMinAlpha*weight+prune;
-				weight += m_params.Alpha();
-				m_modes[pos].weight = weight;
-				m_modes[pos].muR = muR - k*(dR);
-				m_modes[pos].muG = muG - k*(dG);
-				m_modes[pos].muB = muB - k*(dB);
-
-				//limit update speed for cov matrice
-				//not needed
-				//k=k>20*m_m_params.Alpha()?20*m_m_params.Alpha():k;
-				//float sigmanew = var + k*((0.33*(dR*dR+dG*dG+dB*dB))-var);
-				//float sigmanew = var + k*((dR*dR+dG*dG+dB*dB)-var);
-				//float sigmanew = var + k*((0.33*dist)-var);
-				float sigmanew = var + k*(dist-var);
-
-				//limit the variance
-				m_modes[pos].sigma = sigmanew < 4 ? 4 : sigmanew > 5*m_variance ? 5*m_variance : sigmanew;
-
-				// Sort weights so they are in desending order. Note that only the weight for this
-				// mode will increase and that the weight for all modes that were previously larger than
-				// this one have already been modified and will not be modified again. Thus, we just need to 
-				// the correct position of this mode in the already sorted list.
-
-				// Zivkovic implementation has been modified for clarity, but the results are equivalent
-				/*
-				for (int iLocal = iModes;iLocal>0;iLocal--)
-				{
-					long posLocal=posPixel + iLocal;
-					if (weight < (m_modes[posLocal-1].weight))
-					{
-						break;
-					}
-					else
-					{
-						//swap
-						GMM temp = m_modes[posLocal];
-						m_modes[posLocal] = m_modes[posLocal-1];
-						m_modes[posLocal-1] = temp;
-					}
-				}
-				*/
-
-				for (int iLocal = iModes; iLocal > 0; iLocal--)
-				{
-					long posLocal = posPixel + iLocal;
-					if (m_modes[posLocal].weight > m_modes[posLocal-1].weight)
-					{
-						//swap
-						GMM temp = m_modes[posLocal];
-						m_modes[posLocal] = m_modes[posLocal-1];
-						m_modes[posLocal-1] = temp;
-					}
-					else
-					{
-						break;
-					}
-				}
-			}
-			else
-			{
-				weight = fOneMinAlpha*weight+prune;
-				//check prune
-				if (weight < -prune)
-				{
-					weight=0.0;
-					nModes--;
-				}
-				m_modes[pos].weight = weight;
-			}
-			//check if it fits the current mode (2.5 sigma)
-			///////
-		}
-		//fit not found yet
-		/////
-		else
-		{
-			weight = fOneMinAlpha*weight + prune;
-			//check prune
-			if (weight < -prune)
-			{
-				weight=0.0;
-				nModes--;
-			}
-			m_modes[pos].weight = weight;
-		}
-		totalWeight += weight;
-	}
-
-	//renormalize weights so they sum to 1
-	for (int iLocal = 0; iLocal < nModes; iLocal++)
-	{
-		m_modes[posPixel+ iLocal].weight = m_modes[posPixel+ iLocal].weight/totalWeight;
-	}
-	
-	//make new mode if needed and exit
-	if (!bFitsPDF)
-	{
-		if (nModes == m_params.MaxModes())
-		{
-			//replace the weakest
-		}
-		else
-		{
-			nModes++;
-		}
-		pos = posPixel + nModes-1;
-
-    if (nModes==1)
-			m_modes[pos].weight=1;
-		else
-			m_modes[pos].weight=m_params.Alpha();
-
-		// Zivkovic implementation changes as this will not result in the
-		// weights adding to 1
-		/*
-		int iLocal;
-		for (iLocal = 0; iLocal < m_params.MaxModes()odes-1; iLocal++)
-		{
-			m_modes[posPixel+ iLocal].weight *= fOneMinAlpha;
-		}
-		*/
-
-		// Revised implementation:
-		//renormalize weights
-		int iLocal;
-		float sum = 0.0;
-		for (iLocal = 0; iLocal < nModes; iLocal++)
-		{
-			sum += m_modes[posPixel+ iLocal].weight;
-		}
-
-		float invSum = 1.0f/sum;
-		for (iLocal = 0; iLocal < nModes; iLocal++)
-		{
-			m_modes[posPixel+ iLocal].weight *= invSum;
-		}
-
-		m_modes[pos].muR=pixel(0);
-		m_modes[pos].muG=pixel(1);
-		m_modes[pos].muB=pixel(2);
-		m_modes[pos].sigma=m_variance;
-
-		// Zivkovic implementation to sort GMM so they are sorted in descending order according to their weight.
-		// It has been revised for clarity, but the results are equivalent
-		/*
-		for (iLocal = m_params.MaxModes()odes-1; iLocal > 0; iLocal--)
-		{
-			long posLocal = posPixel + iLocal;
-			if (m_params.Alpha() < (m_modes[posLocal-1].weight))
-			{
-				break;
-			}
-			else
-			{
-				//swap
-				GMM temp = m_modes[posLocal];
-				m_modes[posLocal] = m_modes[posLocal-1];
-				m_modes[posLocal-1] = temp;
-			}
-		}
-		*/
-
-		// sort GMM so they are sorted in descending order according to their weight
-		for (iLocal = nModes-1; iLocal > 0; iLocal--)
-		{
-			long posLocal = posPixel + iLocal;
-			if (m_modes[posLocal].weight > m_modes[posLocal-1].weight)
-			{
-				//swap
-				GMM temp = m_modes[posLocal];
-				m_modes[posLocal] = m_modes[posLocal-1];
-				m_modes[posLocal-1] = temp;
-			}
-			else
-			{
-				break;
-			}
-		}
-	}
-
-	//set the number of modes
-	*pModesUsed=nModes;
-
-	if(bBackgroundLow)
-	{
-		low_threshold = BACKGROUND;
-	}
-	else
-	{
-		low_threshold = FOREGROUND;
-	}
-
-	if(bBackgroundHigh)
-	{
-		high_threshold = BACKGROUND;
-	}
-	else
-	{
-		high_threshold = FOREGROUND;
-	}
+  //calculate distances to the modes (+ sort???)
+  //here we need to go in descending order!!!
+  long pos;
+  bool bFitsPDF = 0;
+  bool bBackgroundLow = false;
+  bool bBackgroundHigh = false;
+
+  float fOneMinAlpha = 1 - m_params.Alpha();
+
+  float prune = -m_params.Alpha()*m_complexity_prior;
+
+  int nModes = *pModesUsed;
+  float totalWeight = 0.0f;
+
+  // calculate number of Gaussians to include in the background model
+  int backgroundGaussians = 0;
+  double sum = 0.0;
+  for (int i = 0; i < nModes; ++i)
+  {
+    if (sum < m_bg_threshold)
+    {
+      backgroundGaussians++;
+      sum += m_modes[posPixel + i].weight;
+    }
+    else
+    {
+      break;
+    }
+  }
+
+  // update all distributions and check for match with current pixel
+  for (int iModes = 0; iModes < nModes; iModes++)
+  {
+    pos = posPixel + iModes;
+    float weight = m_modes[pos].weight;
+
+    //fit not found yet
+    if (!bFitsPDF)
+    {
+      //check if it belongs to some of the modes
+      //calculate distance
+      float var = m_modes[pos].sigma;
+      float muR = m_modes[pos].muR;
+      float muG = m_modes[pos].muG;
+      float muB = m_modes[pos].muB;
+
+      float dR = muR - pixel(0);
+      float dG = muG - pixel(1);
+      float dB = muB - pixel(2);
+
+      // calculate the squared distance
+      float dist = (dR*dR + dG*dG + dB*dB);
+
+      if (dist < m_params.HighThreshold()*var && iModes < backgroundGaussians)
+        bBackgroundHigh = true;
+
+      //check fit
+      if (dist < m_params.LowThreshold()*var)
+      {
+        /////
+        //belongs to the mode
+        bFitsPDF = true;
+
+        // check if this Gaussian is part of the background model
+        if (iModes < backgroundGaussians)
+          bBackgroundLow = true;
+
+        //update distribution
+        float k = m_params.Alpha() / weight;
+        weight = fOneMinAlpha*weight + prune;
+        weight += m_params.Alpha();
+        m_modes[pos].weight = weight;
+        m_modes[pos].muR = muR - k*(dR);
+        m_modes[pos].muG = muG - k*(dG);
+        m_modes[pos].muB = muB - k*(dB);
+
+        //limit update speed for cov matrice
+        //not needed
+        //k=k>20*m_m_params.Alpha()?20*m_m_params.Alpha():k;
+        //float sigmanew = var + k*((0.33*(dR*dR+dG*dG+dB*dB))-var);
+        //float sigmanew = var + k*((dR*dR+dG*dG+dB*dB)-var);
+        //float sigmanew = var + k*((0.33*dist)-var);
+        float sigmanew = var + k*(dist - var);
+
+        //limit the variance
+        m_modes[pos].sigma = sigmanew < 4 ? 4 : sigmanew > 5 * m_variance ? 5 * m_variance : sigmanew;
+
+        // Sort weights so they are in desending order. Note that only the weight for this
+        // mode will increase and that the weight for all modes that were previously larger than
+        // this one have already been modified and will not be modified again. Thus, we just need to
+        // the correct position of this mode in the already sorted list.
+
+        // Zivkovic implementation has been modified for clarity, but the results are equivalent
+        /*
+        for (int iLocal = iModes;iLocal>0;iLocal--)
+        {
+          long posLocal=posPixel + iLocal;
+          if (weight < (m_modes[posLocal-1].weight))
+          {
+            break;
+          }
+          else
+          {
+            //swap
+            GMM temp = m_modes[posLocal];
+            m_modes[posLocal] = m_modes[posLocal-1];
+            m_modes[posLocal-1] = temp;
+          }
+        }
+        */
+
+        for (int iLocal = iModes; iLocal > 0; iLocal--)
+        {
+          long posLocal = posPixel + iLocal;
+          if (m_modes[posLocal].weight > m_modes[posLocal - 1].weight)
+          {
+            //swap
+            GMM temp = m_modes[posLocal];
+            m_modes[posLocal] = m_modes[posLocal - 1];
+            m_modes[posLocal - 1] = temp;
+          }
+          else
+          {
+            break;
+          }
+        }
+      }
+      else
+      {
+        weight = fOneMinAlpha*weight + prune;
+        //check prune
+        if (weight < -prune)
+        {
+          weight = 0.0;
+          nModes--;
+        }
+        m_modes[pos].weight = weight;
+      }
+      //check if it fits the current mode (2.5 sigma)
+      ///////
+    }
+    //fit not found yet
+    /////
+    else
+    {
+      weight = fOneMinAlpha*weight + prune;
+      //check prune
+      if (weight < -prune)
+      {
+        weight = 0.0;
+        nModes--;
+      }
+      m_modes[pos].weight = weight;
+    }
+    totalWeight += weight;
+  }
+
+  //renormalize weights so they sum to 1
+  for (int iLocal = 0; iLocal < nModes; iLocal++)
+  {
+    m_modes[posPixel + iLocal].weight = m_modes[posPixel + iLocal].weight / totalWeight;
+  }
+
+  //make new mode if needed and exit
+  if (!bFitsPDF)
+  {
+    if (nModes == m_params.MaxModes())
+    {
+      //replace the weakest
+    }
+    else
+    {
+      nModes++;
+    }
+    pos = posPixel + nModes - 1;
+
+    if (nModes == 1)
+      m_modes[pos].weight = 1;
+    else
+      m_modes[pos].weight = m_params.Alpha();
+
+    // Zivkovic implementation changes as this will not result in the
+    // weights adding to 1
+    /*
+    int iLocal;
+    for (iLocal = 0; iLocal < m_params.MaxModes()odes-1; iLocal++)
+    {
+      m_modes[posPixel+ iLocal].weight *= fOneMinAlpha;
+    }
+    */
+
+    // Revised implementation:
+    //renormalize weights
+    int iLocal;
+    float sum = 0.0;
+    for (iLocal = 0; iLocal < nModes; iLocal++)
+    {
+      sum += m_modes[posPixel + iLocal].weight;
+    }
+
+    float invSum = 1.0f / sum;
+    for (iLocal = 0; iLocal < nModes; iLocal++)
+    {
+      m_modes[posPixel + iLocal].weight *= invSum;
+    }
+
+    m_modes[pos].muR = pixel(0);
+    m_modes[pos].muG = pixel(1);
+    m_modes[pos].muB = pixel(2);
+    m_modes[pos].sigma = m_variance;
+
+    // Zivkovic implementation to sort GMM so they are sorted in descending order according to their weight.
+    // It has been revised for clarity, but the results are equivalent
+    /*
+    for (iLocal = m_params.MaxModes()odes-1; iLocal > 0; iLocal--)
+    {
+      long posLocal = posPixel + iLocal;
+      if (m_params.Alpha() < (m_modes[posLocal-1].weight))
+      {
+        break;
+      }
+      else
+      {
+        //swap
+        GMM temp = m_modes[posLocal];
+        m_modes[posLocal] = m_modes[posLocal-1];
+        m_modes[posLocal-1] = temp;
+      }
+    }
+    */
+
+    // sort GMM so they are sorted in descending order according to their weight
+    for (iLocal = nModes - 1; iLocal > 0; iLocal--)
+    {
+      long posLocal = posPixel + iLocal;
+      if (m_modes[posLocal].weight > m_modes[posLocal - 1].weight)
+      {
+        //swap
+        GMM temp = m_modes[posLocal];
+        m_modes[posLocal] = m_modes[posLocal - 1];
+        m_modes[posLocal - 1] = temp;
+      }
+      else
+      {
+        break;
+      }
+    }
+  }
+
+  //set the number of modes
+  *pModesUsed = nModes;
+
+  if (bBackgroundLow)
+  {
+    low_threshold = BACKGROUND;
+  }
+  else
+  {
+    low_threshold = FOREGROUND;
+  }
+
+  if (bBackgroundHigh)
+  {
+    high_threshold = BACKGROUND;
+  }
+  else
+  {
+    high_threshold = FOREGROUND;
+  }
 }
 
 
@@ -379,30 +379,30 @@ void ZivkovicAGMM::SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned
 //					(the memory should already be reserved) 
 //					values: 255-foreground, 125-shadow, 0-background
 ///////////////////////////////////////////////////////////////////////////////
-void ZivkovicAGMM::Subtract(int frame_num, const RgbImage& data,  
-															BwImage& low_threshold_mask, BwImage& high_threshold_mask)
+void ZivkovicAGMM::Subtract(int frame_num, const RgbImage& data,
+  BwImage& low_threshold_mask, BwImage& high_threshold_mask)
 {
-	unsigned char low_threshold, high_threshold;
-
-	// update each pixel of the image
-	long posPixel;
-	unsigned char* pUsedModes=m_modes_per_pixel;
-	for(unsigned int r = 0; r < m_params.Height(); ++r)
-	{
-		for(unsigned int c = 0; c < m_params.Width(); ++c)
-		{
-			//update model+ background subtract
-			posPixel=(r*m_params.Width()+c)*m_params.MaxModes();
-			SubtractPixel(posPixel, data(r,c), pUsedModes, low_threshold, high_threshold);
-			low_threshold_mask(r,c) = low_threshold;
-			high_threshold_mask(r,c) = high_threshold;
-
-			m_background(r,c,0) = (unsigned char)m_modes[posPixel].muR;
-			m_background(r,c,1) = (unsigned char)m_modes[posPixel].muG;
-			m_background(r,c,2) = (unsigned char)m_modes[posPixel].muB;
-
-			pUsedModes++;
-		}
-	}
+  unsigned char low_threshold, high_threshold;
+
+  // update each pixel of the image
+  long posPixel;
+  unsigned char* pUsedModes = m_modes_per_pixel;
+  for (unsigned int r = 0; r < m_params.Height(); ++r)
+  {
+    for (unsigned int c = 0; c < m_params.Width(); ++c)
+    {
+      //update model+ background subtract
+      posPixel = (r*m_params.Width() + c)*m_params.MaxModes();
+      SubtractPixel(posPixel, data(r, c), pUsedModes, low_threshold, high_threshold);
+      low_threshold_mask(r, c) = low_threshold;
+      high_threshold_mask(r, c) = high_threshold;
+
+      m_background(r, c, 0) = (unsigned char)m_modes[posPixel].muR;
+      m_background(r, c, 1) = (unsigned char)m_modes[posPixel].muG;
+      m_background(r, c, 2) = (unsigned char)m_modes[posPixel].muB;
+
+      pUsedModes++;
+    }
+  }
 }
 
diff --git a/package_bgs/dp/ZivkovicAGMM.h b/package_bgs/dp/ZivkovicAGMM.h
index 1cd99b0211aa31056dc4df69cb3672138eedf3ae..07da9c340edc612e69ee7d6dc1ead7a7f4062b44 100644
--- a/package_bgs/dp/ZivkovicAGMM.h
+++ b/package_bgs/dp/ZivkovicAGMM.h
@@ -18,7 +18,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 *
 * ZivkovicAGMM.hpp
 *
-* Purpose: Implementation of the Gaussian mixture model (GMM) background 
+* Purpose: Implementation of the Gaussian mixture model (GMM) background
 *		  		 subtraction algorithm developed by Z. Zivkovic.
 *
 * Author: Donovan Parks, September 2007
@@ -28,13 +28,13 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * following papers:
 *
 *	"Improved adaptive Gausian mixture model for background subtraction"
-*		Z.Zivkovic 
+*		Z.Zivkovic
 *		International Conference Pattern Recognition, UK, August, 2004
 *
 *
-* "Efficient Adaptive Density Estimapion per Image Pixel for the 
+* "Efficient Adaptive Density Estimapion per Image Pixel for the
 *			Task of Background Subtraction"
-*		Z.Zivkovic, F. van der Heijden 
+*		Z.Zivkovic, F. van der Heijden
 *		Pattern Recognition Letters, vol. 27, no. 7, pages 773-780, 2006.
 *
 * Zivkovic's code can be obtained at: www.zoranz.net
@@ -43,16 +43,14 @@ Example:
 Algorithms::BackgroundSubtraction::ZivkovicParams params;
 params.SetFrameSize(width, height);
 params.LowThreshold() = 5.0f*5.0f;
-params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing 
+params.HighThreshold() = 2*params.LowThreshold();	// Note: high threshold is used by post-processing
 params.Alpha() = 0.001f;
 params.MaxModes() = 3;
 
 Algorithms::BackgroundSubtraction::ZivkovicAGMM bgs;
 bgs.Initalize(params);
 ******************************************************************************/
-
-#ifndef ZIVKOVIC_AGMM_H
-#define ZIVKOVIC_AGMM_H
+#pragma once
 
 #include "Bgs.h"
 
@@ -71,18 +69,18 @@ namespace Algorithms
       int &MaxModes() { return m_max_modes; }
 
     private:
-      // Threshold on the squared dist. to decide when a sample is close to an existing 
-      // components. If it is not close to any a new component will be generated. 
-      // Smaller threshold values lead to more generated components and higher threshold values 
+      // Threshold on the squared dist. to decide when a sample is close to an existing
+      // components. If it is not close to any a new component will be generated.
+      // Smaller threshold values lead to more generated components and higher threshold values
       // lead to a small number of components but they can grow too large.
       //
-      // It is usual easiest to think of these thresholds as being the number of variances (not standard deviations) 
+      // It is usual easiest to think of these thresholds as being the number of variances (not standard deviations)
       // away from the mean of a pixel before it is considered to be from the foreground.
       float m_low_threshold;
       float m_high_threshold;
 
       // alpha - speed of update - if the time interval you want to average over is T
-      // set alpha=1/T. 
+      // set alpha=1/T.
       float m_alpha;
 
       // Maximum number of modes (Gaussian components) that will be used per pixel
@@ -109,14 +107,14 @@ namespace Algorithms
       void Initalize(const BgsParams& param);
 
       void InitModel(const RgbImage& data);
-      void Subtract(int frame_num, const RgbImage& data,  
-        BwImage& low_threshold_mask, BwImage& high_threshold_mask);	
-      void Update(int frame_num, const RgbImage& data,  const BwImage& update_mask);
+      void Subtract(int frame_num, const RgbImage& data,
+        BwImage& low_threshold_mask, BwImage& high_threshold_mask);
+      void Update(int frame_num, const RgbImage& data, const BwImage& update_mask);
 
       RgbImage* Background() { return &m_background; }
 
     private:
-      void SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned char* pModesUsed, 
+      void SubtractPixel(long posPixel, const RgbPixel& pixel, unsigned char* pModesUsed,
         unsigned char& lowThreshold, unsigned char& highThreshold);
 
       // User adjustable parameters
@@ -128,13 +126,13 @@ namespace Algorithms
       // it is considered foreground
       float m_bg_threshold; //1-cf from the paper
 
-      // Initial variance for the newly generated components. 
-      // It will will influence the speed of adaptation. A good guess should be made. 
+      // Initial variance for the newly generated components.
+      // It will will influence the speed of adaptation. A good guess should be made.
       // A simple way is to estimate the typical standard deviation from the images.
       float m_variance;
 
       // This is related to the number of samples needed to accept that a component
-      // actually exists. 
+      // actually exists.
       float m_complexity_prior;
 
       //data
@@ -150,11 +148,3 @@ namespace Algorithms
     };
   }
 }
-
-#endif
-
-
-
-
-
-
diff --git a/package_bgs/jmo/BlobResult.cpp b/package_bgs/jmo/BlobResult.cpp
deleted file mode 100644
index 1a047c7dc9035e017eab230f1e49e401d25780cc..0000000000000000000000000000000000000000
--- a/package_bgs/jmo/BlobResult.cpp
+++ /dev/null
@@ -1,847 +0,0 @@
-/*
-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/>.
-*/
-/* --- --- ---
-* Copyright (C) 2008--2010 Idiap Research Institute (.....@idiap.ch)
-* All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-* 1. Redistributions of source code must retain the above copyright
-*    notice, this list of conditions and the following disclaimer.
-* 2. Redistributions in binary form must reproduce the above copyright
-*    notice, this list of conditions and the following disclaimer in the
-*    documentation and/or other materials provided with the distribution.
-* 3. The name of the author may not be used to endorse or promote products
-*    derived from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/************************************************************************
-BlobResult.cpp
-
-FUNCIONALITAT: Implementaci� de la classe CBlobResult
-AUTOR: Inspecta S.L.
-MODIFICACIONS (Modificaci�, Autor, Data):
-
-**************************************************************************/
-
-#include <limits.h>
-#include <stdio.h>
-#include <functional>
-#include <algorithm>
-#include "BlobResult.h"
-#include "BlobExtraction.h"
-
-/**************************************************************************
-Constructors / Destructors
-**************************************************************************/
-
-namespace Blob
-{
-
-  /**
-  - FUNCI�: CBlobResult
-  - FUNCIONALITAT: Constructor estandard.
-  - PAR�METRES:
-  - RESULTAT:
-  - Crea un CBlobResult sense cap blob
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 20-07-2004.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: CBlobResult
-  - FUNCTIONALITY: Standard constructor
-  - PARAMETERS:
-  - RESULT:
-  - creates an empty set of blobs
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  CBlobResult::CBlobResult()
-  {
-    m_blobs = blob_vector();
-  }
-
-  /**
-  - FUNCI�: CBlobResult
-  - FUNCIONALITAT: Constructor a partir d'una imatge. Inicialitza la seq��ncia de blobs
-  amb els blobs resultants de l'an�lisi de blobs de la imatge.
-  - PAR�METRES:
-  - source: imatge d'on s'extreuran els blobs
-  - mask: m�scara a aplicar. Nom�s es calcularan els blobs on la m�scara sigui
-  diferent de 0. Els blobs que toquin a un pixel 0 de la m�scara seran
-  considerats exteriors.
-  - threshold: llindar que s'aplicar� a la imatge source abans de calcular els blobs
-  - findmoments: indica si s'han de calcular els moments de cada blob
-  - RESULTAT:
-  - objecte CBlobResult amb els blobs de la imatge source
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: CBlob
-  - FUNCTIONALITY: Constructor from an image. Fills an object with all the blobs in
-  the image
-  - PARAMETERS:
-  - source: image to extract the blobs from
-  - mask: optional mask to apply. The blobs will be extracted where the mask is
-  not 0. All the neighbouring blobs where the mask is 0 will be extern blobs
-  - threshold: threshold level to apply to the image before computing blobs
-  - findmoments: true to calculate the blob moments (slower)
-  - RESULT:
-  - object with all the blobs in the image. It throws an EXCEPCIO_CALCUL_BLOBS
-  if some error appears in the BlobAnalysis function
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  CBlobResult::CBlobResult(IplImage *source, IplImage *mask, int threshold, bool findmoments)
-  {
-    bool success;
-
-    try
-    {
-      // cridem la funci� amb el marc a true=1=blanc (aix� no unir� els blobs externs)
-      success = BlobAnalysis(source, (uchar)threshold, mask, true, findmoments, m_blobs);
-    }
-    catch (...)
-    {
-      success = false;
-    }
-
-    if (!success) throw EXCEPCIO_CALCUL_BLOBS;
-  }
-
-  /**
-  - FUNCI�: CBlobResult
-  - FUNCIONALITAT: Constructor de c�pia. Inicialitza la seq��ncia de blobs
-  amb els blobs del par�metre.
-  - PAR�METRES:
-  - source: objecte que es copiar�
-  - RESULTAT:
-  - objecte CBlobResult amb els blobs de l'objecte source
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: CBlobResult
-  - FUNCTIONALITY: Copy constructor
-  - PARAMETERS:
-  - source: object to copy
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  CBlobResult::CBlobResult(const CBlobResult &source)
-  {
-    m_blobs = blob_vector(source.GetNumBlobs());
-
-    // creem el nou a partir del passat com a par�metre
-    m_blobs = blob_vector(source.GetNumBlobs());
-    // copiem els blobs de l'origen a l'actual
-    blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
-    blob_vector::iterator pBlobsDst = m_blobs.begin();
-
-    while (pBlobsSrc != source.m_blobs.end())
-    {
-      // no podem cridar a l'operador = ja que blob_vector �s un 
-      // vector de CBlob*. Per tant, creem un blob nou a partir del
-      // blob original
-      *pBlobsDst = new CBlob(**pBlobsSrc);
-      ++pBlobsSrc;
-      ++pBlobsDst;
-    }
-  }
-
-
-
-  /**
-  - FUNCI�: ~CBlobResult
-  - FUNCIONALITAT: Destructor estandard.
-  - PAR�METRES:
-  - RESULTAT:
-  - Allibera la mem�ria reservada de cadascun dels blobs de la classe
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: ~CBlobResult
-  - FUNCTIONALITY: Destructor
-  - PARAMETERS:
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  CBlobResult::~CBlobResult()
-  {
-    ClearBlobs();
-  }
-
-  /**************************************************************************
-  Operadors / Operators
-  **************************************************************************/
-
-
-  /**
-  - FUNCI�: operador =
-  - FUNCIONALITAT: Assigna un objecte source a l'actual
-  - PAR�METRES:
-  - source: objecte a assignar
-  - RESULTAT:
-  - Substitueix els blobs actuals per els de l'objecte source
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: Assigment operator
-  - FUNCTIONALITY:
-  - PARAMETERS:
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  CBlobResult& CBlobResult::operator=(const CBlobResult& source)
-  {
-    // si ja s�n el mateix, no cal fer res
-    if (this != &source)
-    {
-      // alliberem el conjunt de blobs antic
-      for (int i = 0; i < GetNumBlobs(); i++)
-      {
-        delete m_blobs[i];
-      }
-      m_blobs.clear();
-      // creem el nou a partir del passat com a par�metre
-      m_blobs = blob_vector(source.GetNumBlobs());
-      // copiem els blobs de l'origen a l'actual
-      blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
-      blob_vector::iterator pBlobsDst = m_blobs.begin();
-
-      while (pBlobsSrc != source.m_blobs.end())
-      {
-        // no podem cridar a l'operador = ja que blob_vector �s un 
-        // vector de CBlob*. Per tant, creem un blob nou a partir del
-        // blob original
-        *pBlobsDst = new CBlob(**pBlobsSrc);
-        ++pBlobsSrc;
-        ++pBlobsDst;
-      }
-    }
-    return *this;
-  }
-
-
-  /**
-  - FUNCI�: operador +
-  - FUNCIONALITAT: Concatena els blobs de dos CBlobResult
-  - PAR�METRES:
-  - source: d'on s'agafaran els blobs afegits a l'actual
-  - RESULTAT:
-  - retorna un nou CBlobResult amb els dos CBlobResult concatenats
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - NOTA: per la implementaci�, els blobs del par�metre es posen en ordre invers
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: + operator
-  - FUNCTIONALITY: Joins the blobs in source with the current ones
-  - PARAMETERS:
-  - source: object to copy the blobs
-  - RESULT:
-  - object with the actual blobs and the source blobs
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  CBlobResult CBlobResult::operator+(const CBlobResult& source)
-  {
-    //creem el resultat a partir dels blobs actuals
-    CBlobResult resultat(*this);
-
-    // reservem mem�ria per als nous blobs
-    resultat.m_blobs.resize(resultat.GetNumBlobs() + source.GetNumBlobs());
-
-    // declarem els iterador per rec�rrer els blobs d'origen i desti
-    blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
-    blob_vector::iterator pBlobsDst = resultat.m_blobs.end();
-
-    // insertem els blobs de l'origen a l'actual
-    while (pBlobsSrc != source.m_blobs.end())
-    {
-      --pBlobsDst;
-      *pBlobsDst = new CBlob(**pBlobsSrc);
-      ++pBlobsSrc;
-    }
-
-    return resultat;
-  }
-
-  /**************************************************************************
-  Operacions / Operations
-  **************************************************************************/
-
-  /**
-  - FUNCI�: AddBlob
-  - FUNCIONALITAT: Afegeix un blob al conjunt
-  - PAR�METRES:
-  - blob: blob a afegir
-  - RESULTAT:
-  - modifica el conjunt de blobs actual
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 2006/03/01
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  void CBlobResult::AddBlob(CBlob *blob)
-  {
-    if (blob != NULL)
-      m_blobs.push_back(new CBlob(blob));
-  }
-
-
-  /**
-  - FUNCI�: GetSTLResult
-  - FUNCIONALITAT: Calcula el resultat especificat sobre tots els blobs de la classe
-  - PAR�METRES:
-  - evaluador: Qualsevol objecte derivat de COperadorBlob
-  - RESULTAT:
-  - Retorna un array de double's STL amb el resultat per cada blob
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: GetResult
-  - FUNCTIONALITY: Computes the function evaluador on all the blobs of the class
-  and returns a vector with the result
-  - PARAMETERS:
-  - evaluador: function to apply to each blob (any object derived from the
-  COperadorBlob class )
-  - RESULT:
-  - vector with all the results in the same order as the blobs
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  double_stl_vector CBlobResult::GetSTLResult(funcio_calculBlob *evaluador) const
-  {
-    if (GetNumBlobs() <= 0)
-    {
-      return double_stl_vector();
-    }
-
-    // definim el resultat
-    double_stl_vector result = double_stl_vector(GetNumBlobs());
-    // i iteradors sobre els blobs i el resultat
-    double_stl_vector::iterator itResult = result.begin();
-    blob_vector::const_iterator itBlobs = m_blobs.begin();
-
-    // avaluem la funci� en tots els blobs
-    while (itBlobs != m_blobs.end())
-    {
-      *itResult = (*evaluador)(**itBlobs);
-      ++itBlobs;
-      ++itResult;
-    }
-    return result;
-  }
-
-  /**
-  - FUNCI�: GetNumber
-  - FUNCIONALITAT: Calcula el resultat especificat sobre un �nic blob de la classe
-  - PAR�METRES:
-  - evaluador: Qualsevol objecte derivat de COperadorBlob
-  - indexblob: n�mero de blob del que volem calcular el resultat.
-  - RESULTAT:
-  - Retorna un double amb el resultat
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: GetNumber
-  - FUNCTIONALITY: Computes the function evaluador on a blob of the class
-  - PARAMETERS:
-  - indexBlob: index of the blob to compute the function
-  - evaluador: function to apply to each blob (any object derived from the
-  COperadorBlob class )
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  double CBlobResult::GetNumber(int indexBlob, funcio_calculBlob *evaluador) const
-  {
-    if (indexBlob < 0 || indexBlob >= GetNumBlobs())
-      RaiseError(EXCEPTION_BLOB_OUT_OF_BOUNDS);
-    return (*evaluador)(*m_blobs[indexBlob]);
-  }
-
-  /////////////////////////// FILTRAT DE BLOBS ////////////////////////////////////
-
-  /**
-  - FUNCI�: Filter
-  - FUNCIONALITAT: Filtra els blobs de la classe i deixa el resultat amb nom�s
-  els blobs que han passat el filtre.
-  El filtrat es basa en especificar condicions sobre un resultat dels blobs
-  i seleccionar (o excloure) aquells blobs que no compleixen una determinada
-  condicio
-  - PAR�METRES:
-  - dst: variable per deixar els blobs filtrats
-  - filterAction:	acci� de filtrat. Incloure els blobs trobats (B_INCLUDE),
-  o excloure els blobs trobats (B_EXCLUDE)
-  - evaluador: Funci� per evaluar els blobs (qualsevol objecte derivat de COperadorBlob
-  - Condition: tipus de condici� que ha de superar la mesura (FilterType)
-  sobre cada blob per a ser considerat.
-  B_EQUAL,B_NOT_EQUAL,B_GREATER,B_LESS,B_GREATER_OR_EQUAL,
-  B_LESS_OR_EQUAL,B_INSIDE,B_OUTSIDE
-  - LowLimit:  valor num�ric per a la comparaci� (Condition) de la mesura (FilterType)
-  - HighLimit: valor num�ric per a la comparaci� (Condition) de la mesura (FilterType)
-  (nom�s t� sentit per a aquelles condicions que tenen dos valors
-  (B_INSIDE, per exemple).
-  - RESULTAT:
-  - Deixa els blobs resultants del filtrat a destination
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: Filter
-  - FUNCTIONALITY: Get some blobs from the class based on conditions on measures
-  of the blobs.
-  - PARAMETERS:
-  - dst: where to store the selected blobs
-  - filterAction:	B_INCLUDE: include the blobs which pass the filter in the result
-  B_EXCLUDE: exclude the blobs which pass the filter in the result
-  - evaluador: Object to evaluate the blob
-  - Condition: How to decide if  the result returned by evaluador on each blob
-  is included or not. It can be:
-  B_EQUAL,B_NOT_EQUAL,B_GREATER,B_LESS,B_GREATER_OR_EQUAL,
-  B_LESS_OR_EQUAL,B_INSIDE,B_OUTSIDE
-  - LowLimit:  numerical value to evaluate the Condition on evaluador(blob)
-  - HighLimit: numerical value to evaluate the Condition on evaluador(blob).
-  Only useful for B_INSIDE and B_OUTSIDE
-  - RESULT:
-  - It returns on dst the blobs that accomplish (B_INCLUDE) or discards (B_EXCLUDE)
-  the Condition on the result returned by evaluador on each blob
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  void CBlobResult::Filter(CBlobResult &dst,
-    int filterAction,
-    funcio_calculBlob *evaluador,
-    int condition,
-    double lowLimit, double highLimit /*=0*/)
-
-  {
-    int i, numBlobs;
-    bool resultavaluacio;
-    double_stl_vector avaluacioBlobs;
-    double_stl_vector::iterator itavaluacioBlobs;
-
-    if (GetNumBlobs() <= 0) return;
-    if (!evaluador) return;
-    //avaluem els blobs amb la funci� pertinent	
-    avaluacioBlobs = GetSTLResult(evaluador);
-    itavaluacioBlobs = avaluacioBlobs.begin();
-    numBlobs = GetNumBlobs();
-    switch (condition)
-    {
-    case B_EQUAL:
-      for (i = 0; i < numBlobs; i++, itavaluacioBlobs++)
-      {
-        resultavaluacio = *itavaluacioBlobs == lowLimit;
-        if ((resultavaluacio && filterAction == B_INCLUDE) ||
-          (!resultavaluacio && filterAction == B_EXCLUDE))
-        {
-          dst.m_blobs.push_back(new CBlob(GetBlob(i)));
-        }
-      }
-      break;
-    case B_NOT_EQUAL:
-      for (i = 0; i < numBlobs; i++, itavaluacioBlobs++)
-      {
-        resultavaluacio = *itavaluacioBlobs != lowLimit;
-        if ((resultavaluacio && filterAction == B_INCLUDE) ||
-          (!resultavaluacio && filterAction == B_EXCLUDE))
-        {
-          dst.m_blobs.push_back(new CBlob(GetBlob(i)));
-        }
-      }
-      break;
-    case B_GREATER:
-      for (i = 0; i<numBlobs; i++, itavaluacioBlobs++)
-      {
-        resultavaluacio = *itavaluacioBlobs > lowLimit;
-        if ((resultavaluacio && filterAction == B_INCLUDE) ||
-          (!resultavaluacio && filterAction == B_EXCLUDE))
-        {
-          dst.m_blobs.push_back(new CBlob(GetBlob(i)));
-        }
-      }
-      break;
-    case B_LESS:
-      for (i = 0; i < numBlobs; i++, itavaluacioBlobs++)
-      {
-        resultavaluacio = *itavaluacioBlobs < lowLimit;
-        if ((resultavaluacio && filterAction == B_INCLUDE) ||
-          (!resultavaluacio && filterAction == B_EXCLUDE))
-        {
-          dst.m_blobs.push_back(new CBlob(GetBlob(i)));
-        }
-      }
-      break;
-    case B_GREATER_OR_EQUAL:
-      for (i = 0; i < numBlobs; i++, itavaluacioBlobs++)
-      {
-        resultavaluacio = *itavaluacioBlobs >= lowLimit;
-        if ((resultavaluacio && filterAction == B_INCLUDE) ||
-          (!resultavaluacio && filterAction == B_EXCLUDE))
-        {
-          dst.m_blobs.push_back(new CBlob(GetBlob(i)));
-        }
-      }
-      break;
-    case B_LESS_OR_EQUAL:
-      for (i = 0; i < numBlobs; i++, itavaluacioBlobs++)
-      {
-        resultavaluacio = *itavaluacioBlobs <= lowLimit;
-        if ((resultavaluacio && filterAction == B_INCLUDE) ||
-          (!resultavaluacio && filterAction == B_EXCLUDE))
-        {
-          dst.m_blobs.push_back(new CBlob(GetBlob(i)));
-        }
-      }
-      break;
-    case B_INSIDE:
-      for (i = 0; i < numBlobs; i++, itavaluacioBlobs++)
-      {
-        resultavaluacio = (*itavaluacioBlobs >= lowLimit) && (*itavaluacioBlobs <= highLimit);
-        if ((resultavaluacio && filterAction == B_INCLUDE) ||
-          (!resultavaluacio && filterAction == B_EXCLUDE))
-        {
-          dst.m_blobs.push_back(new CBlob(GetBlob(i)));
-        }
-      }
-      break;
-    case B_OUTSIDE:
-      for (i = 0; i < numBlobs; i++, itavaluacioBlobs++)
-      {
-        resultavaluacio = (*itavaluacioBlobs < lowLimit) || (*itavaluacioBlobs > highLimit);
-        if ((resultavaluacio && filterAction == B_INCLUDE) ||
-          (!resultavaluacio && filterAction == B_EXCLUDE))
-        {
-          dst.m_blobs.push_back(new CBlob(GetBlob(i)));
-        }
-      }
-      break;
-    }
-
-
-    // en cas de voler filtrar un CBlobResult i deixar-ho en el mateix CBlobResult
-    // ( operacio inline )
-    if (&dst == this)
-    {
-      // esborrem els primers blobs ( que s�n els originals )
-      // ja que els tindrem replicats al final si passen el filtre
-      blob_vector::iterator itBlobs = m_blobs.begin();
-      for (int i = 0; i < numBlobs; i++)
-      {
-        delete *itBlobs;
-        ++itBlobs;
-      }
-      m_blobs.erase(m_blobs.begin(), itBlobs);
-    }
-  }
-
-
-  /**
-  - FUNCI�: GetBlob
-  - FUNCIONALITAT: Retorna un blob si aquest existeix (index != -1)
-  - PAR�METRES:
-  - indexblob: index del blob a retornar
-  - RESULTAT:
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /*
-  - FUNCTION: GetBlob
-  - FUNCTIONALITY: Gets the n-th blob (without ordering the blobs)
-  - PARAMETERS:
-  - indexblob: index in the blob array
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  CBlob CBlobResult::GetBlob(int indexblob) const
-  {
-    if (indexblob < 0 || indexblob >= GetNumBlobs())
-      RaiseError(EXCEPTION_BLOB_OUT_OF_BOUNDS);
-
-    return *m_blobs[indexblob];
-  }
-  CBlob *CBlobResult::GetBlob(int indexblob)
-  {
-    if (indexblob < 0 || indexblob >= GetNumBlobs())
-      RaiseError(EXCEPTION_BLOB_OUT_OF_BOUNDS);
-
-    return m_blobs[indexblob];
-  }
-
-  /**
-  - FUNCI�: GetNthBlob
-  - FUNCIONALITAT: Retorna l'en�ssim blob segons un determinat criteri
-  - PAR�METRES:
-  - criteri: criteri per ordenar els blobs (objectes derivats de COperadorBlob)
-  - nBlob: index del blob a retornar
-  - dst: on es retorna el resultat
-  - RESULTAT:
-  - retorna el blob nBlob a dst ordenant els blobs de la classe segons el criteri
-  en ordre DESCENDENT. Per exemple, per obtenir el blob major:
-  GetNthBlob( CBlobGetArea(), 0, blobMajor );
-  GetNthBlob( CBlobGetArea(), 1, blobMajor ); (segon blob m�s gran)
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /*
-  - FUNCTION: GetNthBlob
-  - FUNCTIONALITY: Gets the n-th blob ordering first the blobs with some criteria
-  - PARAMETERS:
-  - criteri: criteria to order the blob array
-  - nBlob: index of the returned blob in the ordered blob array
-  - dst: where to store the result
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  void CBlobResult::GetNthBlob(funcio_calculBlob *criteri, int nBlob, CBlob &dst) const
-  {
-    // verifiquem que no estem accedint fora el vector de blobs
-    if (nBlob < 0 || nBlob >= GetNumBlobs())
-    {
-      //RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS );
-      dst = CBlob();
-      return;
-    }
-
-    double_stl_vector avaluacioBlobs, avaluacioBlobsOrdenat;
-    double valorEnessim;
-
-    //avaluem els blobs amb la funci� pertinent	
-    avaluacioBlobs = GetSTLResult(criteri);
-
-    avaluacioBlobsOrdenat = double_stl_vector(GetNumBlobs());
-
-    // obtenim els nBlob primers resultats (en ordre descendent)
-    std::partial_sort_copy(avaluacioBlobs.begin(),
-      avaluacioBlobs.end(),
-      avaluacioBlobsOrdenat.begin(),
-      avaluacioBlobsOrdenat.end(),
-      std::greater<double>());
-
-    valorEnessim = avaluacioBlobsOrdenat[nBlob];
-
-    // busquem el primer blob que t� el valor n-ssim
-    double_stl_vector::const_iterator itAvaluacio = avaluacioBlobs.begin();
-
-    bool trobatBlob = false;
-    int indexBlob = 0;
-    while (itAvaluacio != avaluacioBlobs.end() && !trobatBlob)
-    {
-      if (*itAvaluacio == valorEnessim)
-      {
-        trobatBlob = true;
-        dst = CBlob(GetBlob(indexBlob));
-      }
-      ++itAvaluacio;
-      indexBlob++;
-    }
-  }
-
-  /**
-  - FUNCI�: ClearBlobs
-  - FUNCIONALITAT: Elimina tots els blobs de l'objecte
-  - PAR�METRES:
-  - RESULTAT:
-  - Allibera tota la mem�ria dels blobs
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s Navarra
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /*
-  - FUNCTION: ClearBlobs
-  - FUNCTIONALITY: Clears all the blobs from the object and releases all its memory
-  - PARAMETERS:
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  void CBlobResult::ClearBlobs()
-  {
-    /*for( int i = 0; i < GetNumBlobs(); i++ )
-    {
-    delete m_blobs[i];
-    }*/
-    blob_vector::iterator itBlobs = m_blobs.begin();
-    while (itBlobs != m_blobs.end())
-    {
-      delete *itBlobs;
-      ++itBlobs;
-    }
-
-    m_blobs.clear();
-  }
-
-  /**
-  - FUNCI�: RaiseError
-  - FUNCIONALITAT: Funci� per a notificar errors al l'usuari (en debug) i llen�a
-  les excepcions
-  - PAR�METRES:
-  - errorCode: codi d'error
-  - RESULTAT:
-  - Ensenya un missatge a l'usuari (en debug) i llen�a una excepci�
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s Navarra
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /*
-  - FUNCTION: RaiseError
-  - FUNCTIONALITY: Error handling function
-  - PARAMETERS:
-  - errorCode: reason of the error
-  - RESULT:
-  - in _DEBUG version, shows a message box with the error. In release is silent.
-  In both cases throws an exception with the error.
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  void CBlobResult::RaiseError(const int errorCode) const
-  {
-    throw errorCode;
-  }
-
-
-
-  /**************************************************************************
-  Auxiliars / Auxiliary functions
-  **************************************************************************/
-
-
-  /**
-  - FUNCI�: PrintBlobs
-  - FUNCIONALITAT: Escriu els par�metres (�rea, per�metre, exterior, mitjana)
-  de tots els blobs a un fitxer.
-  - PAR�METRES:
-  - nom_fitxer: path complet del fitxer amb el resultat
-  - RESULTAT:
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /*
-  - FUNCTION: PrintBlobs
-  - FUNCTIONALITY: Prints some blob features in an ASCII file
-  - PARAMETERS:
-  - nom_fitxer: full path + filename to generate
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  void CBlobResult::PrintBlobs(char *nom_fitxer) const
-  {
-    double_stl_vector area, /*perimetre,*/ exterior, mitjana, compacitat, longitud,
-      externPerimeter, perimetreConvex, perimetre;
-    int i;
-    FILE *fitxer_sortida;
-
-    area = GetSTLResult(CBlobGetArea());
-    perimetre = GetSTLResult(CBlobGetPerimeter());
-    exterior = GetSTLResult(CBlobGetExterior());
-    mitjana = GetSTLResult(CBlobGetMean());
-    compacitat = GetSTLResult(CBlobGetCompactness());
-    longitud = GetSTLResult(CBlobGetLength());
-    externPerimeter = GetSTLResult(CBlobGetExternPerimeter());
-    perimetreConvex = GetSTLResult(CBlobGetHullPerimeter());
-
-    fitxer_sortida = fopen(nom_fitxer, "w");
-
-    for (i = 0; i < GetNumBlobs(); i++)
-    {
-      fprintf(fitxer_sortida, "blob %d ->\t a=%7.0f\t p=%8.2f (%8.2f extern)\t pconvex=%8.2f\t ext=%.0f\t m=%7.2f\t c=%3.2f\t l=%8.2f\n",
-        i, area[i], perimetre[i], externPerimeter[i], perimetreConvex[i], exterior[i], mitjana[i], compacitat[i], longitud[i]);
-    }
-    fclose(fitxer_sortida);
-
-  }
-
-}
diff --git a/package_bgs/jmo/MultiLayerBGS.h b/package_bgs/jmo/MultiLayerBGS.h
deleted file mode 100644
index 29db9466281f8c12eda1997552f1f5adff05378c..0000000000000000000000000000000000000000
--- a/package_bgs/jmo/MultiLayerBGS.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-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
-
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-#include "CMultiLayerBGS.h"
-
-class MultiLayerBGS : public IBGS
-{
-public:
-  enum Status
-  {
-    MLBGS_NONE = -1,
-    MLBGS_LEARN = 0,
-    MLBGS_DETECT = 1
-  };
-
-private:
-  bool firstTime;
-  long long frameNumber;
-  cv::Mat img_foreground;
-  cv::Mat img_merged;
-  cv::Mat img_background;
-  bool showOutput;
-  bool saveModel;
-  bool disableDetectMode;
-  bool disableLearning;
-  int detectAfter;
-  CMultiLayerBGS* BGS;
-  Status status;
-  IplImage* img;
-  IplImage* org_img;
-  IplImage* fg_img;
-  IplImage* bg_img;
-  IplImage* fg_prob_img;
-  IplImage* fg_mask_img;
-  IplImage* fg_prob_img3;
-  IplImage* merged_img;
-  std::string bg_model_preload;
-
-  bool loadDefaultParams;
-
-  int max_mode_num;
-  float weight_updating_constant;
-  float texture_weight;
-  float bg_mode_percent;
-  int pattern_neig_half_size;
-  float pattern_neig_gaus_sigma;
-  float bg_prob_threshold;
-  float bg_prob_updating_threshold;
-  int robust_LBP_constant;
-  float min_noised_angle;
-  float shadow_rate;
-  float highlight_rate;
-  float bilater_filter_sigma_s;
-  float bilater_filter_sigma_r;
-
-  float frame_duration;
-
-  float mode_learn_rate_per_second;
-  float weight_learn_rate_per_second;
-  float init_mode_weight;
-
-  float learn_mode_learn_rate_per_second;
-  float learn_weight_learn_rate_per_second;
-  float learn_init_mode_weight;
-
-  float detect_mode_learn_rate_per_second;
-  float detect_weight_learn_rate_per_second;
-  float detect_init_mode_weight;
-
-public:
-  MultiLayerBGS();
-  ~MultiLayerBGS();
-
-  void setStatus(Status status);
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void finish(void);
-  void saveConfig();
-  void loadConfig();
-};
\ No newline at end of file
diff --git a/package_bgs/jmo/blob.cpp b/package_bgs/jmo/blob.cpp
deleted file mode 100644
index 3629714ccf0b93e3b244f7c6070e5fe8396da44a..0000000000000000000000000000000000000000
--- a/package_bgs/jmo/blob.cpp
+++ /dev/null
@@ -1,1149 +0,0 @@
-/*
-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/>.
-*/
-/* --- --- ---
-* Copyright (C) 2008--2010 Idiap Research Institute (.....@idiap.ch)
-* All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-* 1. Redistributions of source code must retain the above copyright
-*    notice, this list of conditions and the following disclaimer.
-* 2. Redistributions in binary form must reproduce the above copyright
-*    notice, this list of conditions and the following disclaimer in the
-*    documentation and/or other materials provided with the distribution.
-* 3. The name of the author may not be used to endorse or promote products
-*    derived from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/************************************************************************
-Blob.cpp
-
-- FUNCIONALITAT: Implementaci� de la classe CBlob
-- AUTOR: Inspecta S.L.
-MODIFICACIONS (Modificaci�, Autor, Data):
-
-
-FUNCTIONALITY: Implementation of the CBlob class and some helper classes to perform
-some calculations on it
-AUTHOR: Inspecta S.L.
-MODIFICATIONS (Modification, Author, Date):
-
-**************************************************************************/
-
-
-#include <limits.h>
-#include "blob.h"
-#include <opencv2/opencv.hpp>
-
-namespace Blob
-{
-
-  /**
-  - FUNCI�: CBlob
-  - FUNCIONALITAT: Constructor est�ndard
-  - PAR�METRES:
-  - RESULTAT:
-  - inicialitzaci� de totes les variables internes i de l'storage i la sequencia
-  per a les cantonades del blob
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: CBlob
-  - FUNCTIONALITY: Standard constructor
-  - PARAMETERS:
-  - RESULT:
-  - memory allocation for the blob edges and initialization of member variables
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  CBlob::CBlob()
-  {
-    etiqueta = -1;		// Flag indicates null region
-    exterior = 0;
-    area = 0.0f;
-    perimeter = 0.0f;
-    parent = -1;
-    minx = LONG_MAX;
-    maxx = 0;
-    miny = LONG_MAX;
-    maxy = 0;
-    sumx = 0;
-    sumy = 0;
-    sumxx = 0;
-    sumyy = 0;
-    sumxy = 0;
-    mean = 0;
-    stddev = 0;
-    externPerimeter = 0;
-
-    m_storage = cvCreateMemStorage(0);
-    edges = cvCreateSeq(CV_SEQ_KIND_GENERIC | CV_32SC2,
-      sizeof(CvContour),
-      sizeof(CvPoint), m_storage);
-  }
-
-  /**
-  - FUNCI�: CBlob
-  - FUNCIONALITAT: Constructor de c�pia
-  - PAR�METRES:
-  - RESULTAT:
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: CBlob
-  - FUNCTIONALITY: Copy constructor
-  - PARAMETERS:
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  CBlob::CBlob(const CBlob &src)
-  {
-    // copiem les propietats del blob origen a l'actual
-    etiqueta = src.etiqueta;
-    exterior = src.exterior;
-    area = src.Area();
-    perimeter = src.Perimeter();
-    parent = src.parent;
-    minx = src.minx;
-    maxx = src.maxx;
-    miny = src.miny;
-    maxy = src.maxy;
-    sumx = src.sumx;
-    sumy = src.sumy;
-    sumxx = src.sumxx;
-    sumyy = src.sumyy;
-    sumxy = src.sumxy;
-    mean = src.mean;
-    stddev = src.stddev;
-    externPerimeter = src.externPerimeter;
-
-    // copiem els edges del blob origen a l'actual
-    CvSeqReader reader;
-    CvSeqWriter writer;
-    CvPoint edgeactual;
-
-    // creem una sequencia buida per als edges
-    m_storage = cvCreateMemStorage(0);
-    edges = cvCreateSeq(CV_SEQ_KIND_GENERIC | CV_32SC2,
-      sizeof(CvContour),
-      sizeof(CvPoint), m_storage);
-
-    cvStartReadSeq(src.Edges(), &reader);
-    cvStartAppendToSeq(edges, &writer);
-
-    for (int i = 0; i < src.Edges()->total; i++)
-    {
-      CV_READ_SEQ_ELEM(edgeactual, reader);
-      CV_WRITE_SEQ_ELEM(edgeactual, writer);
-    }
-
-    cvEndWriteSeq(&writer);
-  }
-  CBlob::CBlob(const CBlob *src)
-  {
-    // copiem les propietats del blob origen a l'actual
-    etiqueta = src->etiqueta;
-    exterior = src->exterior;
-    area = src->Area();
-    perimeter = src->Perimeter();
-    parent = src->parent;
-    minx = src->minx;
-    maxx = src->maxx;
-    miny = src->miny;
-    maxy = src->maxy;
-    sumx = src->sumx;
-    sumy = src->sumy;
-    sumxx = src->sumxx;
-    sumyy = src->sumyy;
-    sumxy = src->sumxy;
-    mean = src->mean;
-    stddev = src->stddev;
-    externPerimeter = src->externPerimeter;
-
-    // copiem els edges del blob origen a l'actual
-    CvSeqReader reader;
-    CvSeqWriter writer;
-    CvPoint edgeactual;
-
-    // creem una sequencia buida per als edges
-    m_storage = cvCreateMemStorage(0);
-    edges = cvCreateSeq(CV_SEQ_KIND_GENERIC | CV_32SC2,
-      sizeof(CvContour),
-      sizeof(CvPoint), m_storage);
-
-    cvStartReadSeq(src->Edges(), &reader);
-    cvStartAppendToSeq(edges, &writer);
-
-    for (int i = 0; i < src->Edges()->total; i++)
-    {
-      CV_READ_SEQ_ELEM(edgeactual, reader);
-      CV_WRITE_SEQ_ELEM(edgeactual, writer);
-    }
-
-    cvEndWriteSeq(&writer);
-  }
-
-  /**
-  - FUNCI�: ~CBlob
-  - FUNCIONALITAT: Destructor est�ndard
-  - PAR�METRES:
-  - RESULTAT:
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: CBlob
-  - FUNCTIONALITY: Standard destructor
-  - PARAMETERS:
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  CBlob::~CBlob()
-  {
-    // Eliminar v�rtexs del blob 
-    cvClearSeq(edges);
-    // i la zona de mem�ria on s�n
-    cvReleaseMemStorage(&m_storage);
-  }
-
-  /**
-  - FUNCI�: operator=
-  - FUNCIONALITAT: Operador d'assignaci�
-  - PAR�METRES:
-  - src: blob a assignar a l'actual
-  - RESULTAT:
-  - Substitueix el blob actual per el src
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: Assigment operator
-  - FUNCTIONALITY: Assigns a blob to the current
-  - PARAMETERS:
-  - src: blob to assign
-  - RESULT:
-  - the current blob is replaced by the src blob
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  CBlob& CBlob::operator=(const CBlob &src)
-  {
-    // si ja s�n el mateix, no cal fer res
-    if (this != &src)
-    {
-      // Eliminar v�rtexs del blob 
-      cvClearSeq(edges);
-      // i la zona de mem�ria on s�n
-      cvReleaseMemStorage(&m_storage);
-
-      // creem una sequencia buida per als edges
-      m_storage = cvCreateMemStorage(0);
-      edges = cvCreateSeq(CV_SEQ_KIND_GENERIC | CV_32SC2,
-        sizeof(CvContour),
-        sizeof(CvPoint), m_storage);
-
-      // copiem les propietats del blob origen a l'actual
-      etiqueta = src.etiqueta;
-      exterior = src.exterior;
-      area = src.Area();
-      perimeter = src.Perimeter();
-      parent = src.parent;
-      minx = src.minx;
-      maxx = src.maxx;
-      miny = src.miny;
-      maxy = src.maxy;
-      sumx = src.sumx;
-      sumy = src.sumy;
-      sumxx = src.sumxx;
-      sumyy = src.sumyy;
-      sumxy = src.sumxy;
-      mean = src.mean;
-      stddev = src.stddev;
-      externPerimeter = src.externPerimeter;
-
-      // copiem els edges del blob origen a l'actual
-      CvSeqReader reader;
-      CvSeqWriter writer;
-      CvPoint edgeactual;
-
-      cvStartReadSeq(src.Edges(), &reader);
-      cvStartAppendToSeq(edges, &writer);
-
-      for (int i = 0; i < src.Edges()->total; i++)
-      {
-        CV_READ_SEQ_ELEM(edgeactual, reader);
-        CV_WRITE_SEQ_ELEM(edgeactual, writer);
-      }
-
-      cvEndWriteSeq(&writer);
-    }
-    return *this;
-  }
-
-  /**
-  - FUNCI�: FillBlob
-  - FUNCIONALITAT: Pinta l'interior d'un blob amb el color especificat
-  - PAR�METRES:
-  - imatge: imatge on es vol pintar el el blob
-  - color: color amb que es vol pintar el blob
-  - RESULTAT:
-  - retorna la imatge d'entrada amb el blob pintat
-  - RESTRICCIONS:
-  - AUTOR:
-  - Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: FillBlob
-  - FUNCTIONALITY:
-  - Fills the blob with a specified colour
-  - PARAMETERS:
-  - imatge: where to paint
-  - color: colour to paint the blob
-  - RESULT:
-  - modifies input image and returns the seed point used to fill the blob
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  void CBlob::FillBlob(IplImage *imatge, CvScalar color, int offsetX /*=0*/, int offsetY /*=0*/) const
-  {
-
-    //verifiquem que existeixi el blob i que tingui cantonades
-    if (edges == NULL || edges->total == 0) return;
-
-    CvPoint edgeactual, pt1, pt2;
-    CvSeqReader reader;
-    vectorPunts vectorEdges = vectorPunts(edges->total);
-    vectorPunts::iterator itEdges, itEdgesSeguent;
-    bool dinsBlob;
-    int yActual;
-
-    // passem els punts del blob a un vector de punts de les STL
-    cvStartReadSeq(edges, &reader);
-    itEdges = vectorEdges.begin();
-    while (itEdges != vectorEdges.end())
-    {
-      CV_READ_SEQ_ELEM(edgeactual, reader);
-      *itEdges = edgeactual;
-      ++itEdges;
-    }
-    // ordenem el vector per les Y's i les X's d'esquerra a dreta
-    std::sort(vectorEdges.begin(), vectorEdges.end(), comparaCvPoint());
-
-    // recorrem el vector ordenat i fem linies entre punts consecutius
-    itEdges = vectorEdges.begin();
-    itEdgesSeguent = vectorEdges.begin() + 1;
-    dinsBlob = true;
-    while (itEdges != (vectorEdges.end() - 1))
-    {
-      yActual = (*itEdges).y;
-
-      if (((*itEdges).x != (*itEdgesSeguent).x) &&
-        ((*itEdgesSeguent).y == yActual)
-        )
-      {
-        if (dinsBlob)
-        {
-          pt1 = *itEdges;
-          pt1.x += offsetX;
-          pt1.y += offsetY;
-
-          pt2 = *itEdgesSeguent;
-          pt2.x += offsetX;
-          pt2.y += offsetY;
-
-          cvLine(imatge, pt1, pt2, color);
-        }
-        dinsBlob = !dinsBlob;
-      }
-      ++itEdges;
-      ++itEdgesSeguent;
-      if ((*itEdges).y != yActual) dinsBlob = true;
-    }
-    vectorEdges.clear();
-  }
-
-  /**
-  - FUNCI�: CopyEdges
-  - FUNCIONALITAT: Afegeix els v�rtexs del blob al blob destination
-  - PAR�METRES:
-  - destination: blob al que volem afegir els v�rtexs
-  - RESULTAT:
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: CopyEdges
-  - FUNCTIONALITY: Adds the blob edges to destination
-  - PARAMETERS:
-  - destination: where to add the edges
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  void CBlob::CopyEdges(CBlob &destination) const
-  {
-    CvSeqReader reader;
-    CvSeqWriter writer;
-    CvPoint edgeactual;
-
-    cvStartReadSeq(edges, &reader);
-    cvStartAppendToSeq(destination.Edges(), &writer);
-
-    for (int i = 0; i < edges->total; i++)
-    {
-      CV_READ_SEQ_ELEM(edgeactual, reader);
-      CV_WRITE_SEQ_ELEM(edgeactual, writer);
-    }
-
-    cvEndWriteSeq(&writer);
-  }
-
-  /**
-  - FUNCI�: ClearEdges
-  - FUNCIONALITAT: Elimina els v�rtexs del blob
-  - PAR�METRES:
-  - RESULTAT:
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: ClearEdges
-  - FUNCTIONALITY: Delete current blob edges
-  - PARAMETERS:
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  void CBlob::ClearEdges()
-  {
-    // Eliminar v�rtexs del blob eliminat
-    cvClearSeq(edges);
-  }
-
-  /**
-  - FUNCI�: GetConvexHull
-  - FUNCIONALITAT: Retorna el poligon convex del blob
-  - PAR�METRES:
-  - dst: sequencia on desarem el resultat (no ha d'estar inicialitzada)
-  - RESULTAT:
-  - true si tot ha anat b�
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: GetConvexHull
-  - FUNCTIONALITY: Calculates the convex hull polygon of the blob
-  - PARAMETERS:
-  - dst: where to store the result
-  - RESULT:
-  - true if no error ocurred
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  bool CBlob::GetConvexHull(CvSeq **dst) const
-  {
-    if (edges != NULL && edges->total > 0)
-    {
-      *dst = cvConvexHull2(edges, 0, CV_CLOCKWISE, 0);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-  - FUNCI�: GetEllipse
-  - FUNCIONALITAT: Retorna l'ellipse que s'ajusta millor a les cantonades del blob
-  - PAR�METRES:
-  - RESULTAT:
-  - estructura amb l'ellipse
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 25-05-2005.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: GetEllipse
-  - FUNCTIONALITY: Calculates the ellipse that best fits the edges of the blob
-  - PARAMETERS:
-  - RESULT:
-  - CvBox2D struct with the calculated ellipse
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  CvBox2D CBlob::GetEllipse() const
-  {
-    CvBox2D elipse;
-    // necessitem 6 punts per calcular l'elipse
-    if (edges != NULL && edges->total > 6)
-    {
-      elipse = cvFitEllipse2(edges);
-    }
-    else
-    {
-      elipse.center.x = 0.0;
-      elipse.center.y = 0.0;
-      elipse.size.width = 0.0;
-      elipse.size.height = 0.0;
-      elipse.angle = 0.0;
-    }
-    return elipse;
-  }
-
-
-
-  /***************************************************************************
-  Implementaci� de les classes per al c�lcul de caracter�stiques sobre el blob
-
-  Implementation of the helper classes to perform operations on blobs
-  **************************************************************************/
-
-  /**
-  - FUNCI�: Moment
-  - FUNCIONALITAT: Calcula el moment pq del blob
-  - RESULTAT:
-  - retorna el moment pq especificat o 0 si el moment no est� implementat
-  - RESTRICCIONS:
-  - Implementats els moments pq: 00, 01, 10, 20, 02
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 20-07-2004.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: Moment
-  - FUNCTIONALITY: Calculates the pq moment of the blob
-  - PARAMETERS:
-  - RESULT:
-  - returns the pq moment or 0 if the moment it is not implemented
-  - RESTRICTIONS:
-  - Currently, only implemented the 00, 01, 10, 20, 02 pq moments
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 20-07-2004.
-  - MODIFICATION: Date. Author. Description.
-  */
-  double CBlobGetMoment::operator()(const CBlob &blob) const
-  {
-    //Moment 00
-    if ((m_p == 0) && (m_q == 0))
-      return blob.Area();
-
-    //Moment 10
-    if ((m_p == 1) && (m_q == 0))
-      return blob.SumX();
-
-    //Moment 01
-    if ((m_p == 0) && (m_q == 1))
-      return blob.SumY();
-
-    //Moment 20
-    if ((m_p == 2) && (m_q == 0))
-      return blob.SumXX();
-
-    //Moment 02
-    if ((m_p == 0) && (m_q == 2))
-      return blob.SumYY();
-
-    return 0;
-  }
-
-  /**
-  - FUNCI�: HullPerimeter
-  - FUNCIONALITAT: Calcula la longitud del perimetre convex del blob.
-  Fa servir la funci� d'OpenCV cvConvexHull2 per a
-  calcular el perimetre convex.
-
-  - PAR�METRES:
-  - RESULTAT:
-  - retorna la longitud del per�metre convex del blob. Si el blob no t� coordenades
-  associades retorna el per�metre normal del blob.
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 20-07-2004.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: CBlobGetHullPerimeter
-  - FUNCTIONALITY: Calculates the convex hull perimeter of the blob
-  - PARAMETERS:
-  - RESULT:
-  - returns the convex hull perimeter of the blob or the perimeter if the
-  blob edges could not be retrieved
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  double CBlobGetHullPerimeter::operator()(const CBlob &blob) const
-  {
-    if (blob.Edges() != NULL && blob.Edges()->total > 0)
-    {
-      CvSeq *hull = cvConvexHull2(blob.Edges(), 0, CV_CLOCKWISE, 1);
-      return fabs(cvArcLength(hull, CV_WHOLE_SEQ, 1));
-    }
-    return blob.Perimeter();
-  }
-
-  double CBlobGetHullArea::operator()(const CBlob &blob) const
-  {
-    if (blob.Edges() != NULL && blob.Edges()->total > 0)
-    {
-      CvSeq *hull = cvConvexHull2(blob.Edges(), 0, CV_CLOCKWISE, 1);
-      return fabs(cvContourArea(hull));
-    }
-    return blob.Perimeter();
-  }
-
-  /**
-  - FUNCI�: MinX_at_MinY
-  - FUNCIONALITAT: Calcula el valor MinX a MinY.
-  - PAR�METRES:
-  - blob: blob del que volem calcular el valor
-  - RESULTAT:
-  - retorna la X minima en la Y minima.
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 20-07-2004.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: CBlobGetMinXatMinY
-  - FUNCTIONALITY: Calculates the minimum X on the minimum Y
-  - PARAMETERS:
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  double CBlobGetMinXatMinY::operator()(const CBlob &blob) const
-  {
-    double MinX_at_MinY = LONG_MAX;
-
-    CvSeqReader reader;
-    CvPoint edgeactual;
-
-    cvStartReadSeq(blob.Edges(), &reader);
-
-    for (int j = 0; j < blob.Edges()->total; j++)
-    {
-      CV_READ_SEQ_ELEM(edgeactual, reader);
-      if ((edgeactual.y == blob.MinY()) && (edgeactual.x < MinX_at_MinY))
-      {
-        MinX_at_MinY = edgeactual.x;
-      }
-    }
-
-    return MinX_at_MinY;
-  }
-
-  /**
-  - FUNCI�: MinY_at_MaxX
-  - FUNCIONALITAT: Calcula el valor MinX a MaxX.
-  - PAR�METRES:
-  - blob: blob del que volem calcular el valor
-  - RESULTAT:
-  - retorna la Y minima en la X maxima.
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 20-07-2004.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: CBlobGetMinXatMinY
-  - FUNCTIONALITY: Calculates the minimum Y on the maximum X
-  - PARAMETERS:
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  double CBlobGetMinYatMaxX::operator()(const CBlob &blob) const
-  {
-    double MinY_at_MaxX = LONG_MAX;
-
-    CvSeqReader reader;
-    CvPoint edgeactual;
-
-    cvStartReadSeq(blob.Edges(), &reader);
-
-    for (int j = 0; j < blob.Edges()->total; j++)
-    {
-      CV_READ_SEQ_ELEM(edgeactual, reader);
-      if ((edgeactual.x == blob.MaxX()) && (edgeactual.y < MinY_at_MaxX))
-      {
-        MinY_at_MaxX = edgeactual.y;
-      }
-    }
-
-    return MinY_at_MaxX;
-  }
-
-  /**
-  - FUNCI�: MaxX_at_MaxY
-  - FUNCIONALITAT: Calcula el valor MaxX a MaxY.
-  - PAR�METRES:
-  - blob: blob del que volem calcular el valor
-  - RESULTAT:
-  - retorna la X maxima en la Y maxima.
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 20-07-2004.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: CBlobGetMaxXatMaxY
-  - FUNCTIONALITY: Calculates the maximum X on the maximum Y
-  - PARAMETERS:
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  double CBlobGetMaxXatMaxY::operator()(const CBlob &blob) const
-  {
-    double MaxX_at_MaxY = LONG_MIN;
-
-    CvSeqReader reader;
-    CvPoint edgeactual;
-
-    cvStartReadSeq(blob.Edges(), &reader);
-
-    for (int j = 0; j<blob.Edges()->total; j++)
-    {
-      CV_READ_SEQ_ELEM(edgeactual, reader);
-      if ((edgeactual.y == blob.MaxY()) && (edgeactual.x > MaxX_at_MaxY))
-      {
-        MaxX_at_MaxY = edgeactual.x;
-      }
-    }
-
-    return MaxX_at_MaxY;
-  }
-
-  /**
-  - FUNCI�: MaxY_at_MinX
-  - FUNCIONALITAT: Calcula el valor MaxY a MinX.
-  - PAR�METRES:
-  - blob: blob del que volem calcular el valor
-  - RESULTAT:
-  - retorna la Y maxima en la X minima.
-  - RESTRICCIONS:
-  - AUTOR: Ricard Borr�s
-  - DATA DE CREACI�: 20-07-2004.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: CBlobGetMaxYatMinX
-  - FUNCTIONALITY: Calculates the maximum Y on the minimum X
-  - PARAMETERS:
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  double CBlobGetMaxYatMinX::operator()(const CBlob &blob) const
-  {
-    double MaxY_at_MinX = LONG_MIN;
-
-    CvSeqReader reader;
-    CvPoint edgeactual;
-
-    cvStartReadSeq(blob.Edges(), &reader);
-
-    for (int j = 0; j<blob.Edges()->total; j++)
-    {
-      CV_READ_SEQ_ELEM(edgeactual, reader);
-      if ((edgeactual.x == blob.MinY()) && (edgeactual.y > MaxY_at_MinX))
-      {
-        MaxY_at_MinX = edgeactual.y;
-      }
-    }
-
-    return MaxY_at_MinX;
-  }
-
-  /**
-  Retorna l'elongaci� del blob (longitud/amplada)
-  */
-  /**
-  - FUNCTION: CBlobGetElongation
-  - FUNCTIONALITY: Calculates the elongation of the blob ( length/breadth )
-  - PARAMETERS:
-  - RESULT:
-  - RESTRICTIONS:
-  - See below to see how the lenght and the breadth are aproximated
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  double CBlobGetElongation::operator()(const CBlob &blob) const
-  {
-    double ampladaC, longitudC, amplada, longitud;
-
-    ampladaC = (double)(blob.Perimeter() + sqrt(pow(blob.Perimeter(), 2) - 16 * blob.Area())) / 4;
-    if (ampladaC <= 0.0) return 0;
-    longitudC = (double)blob.Area() / ampladaC;
-
-    longitud = MAX(longitudC, ampladaC);
-    amplada = MIN(longitudC, ampladaC);
-
-    return (double)longitud / amplada;
-  }
-
-  /**
-  Retorna la compacitat del blob
-  */
-  /**
-  - FUNCTION: CBlobGetCompactness
-  - FUNCTIONALITY: Calculates the compactness of the blob
-  ( maximum for circle shaped blobs, minimum for the rest)
-  - PARAMETERS:
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  double CBlobGetCompactness::operator()(const CBlob &blob) const
-  {
-    if (blob.Area() != 0.0)
-      return (double)pow(blob.Perimeter(), 2) / (4 * CV_PI*blob.Area());
-    else
-      return 0.0;
-  }
-
-  /**
-  Retorna la rugositat del blob
-  */
-  /**
-  - FUNCTION: CBlobGetRoughness
-  - FUNCTIONALITY: Calculates the roughness of the blob
-  ( ratio between perimeter and convex hull perimeter)
-  - PARAMETERS:
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  double CBlobGetRoughness::operator()(const CBlob &blob) const
-  {
-    CBlobGetHullPerimeter getHullPerimeter = CBlobGetHullPerimeter();
-
-    double hullPerimeter = getHullPerimeter(blob);
-
-    if (hullPerimeter != 0.0)
-      return blob.Perimeter() / hullPerimeter;//HullPerimeter();
-
-    return 0.0;
-  }
-
-  /**
-  Retorna la longitud del blob
-  */
-  /**
-  - FUNCTION: CBlobGetLength
-  - FUNCTIONALITY: Calculates the lenght of the blob (the biggest axis of the blob)
-  - PARAMETERS:
-  - RESULT:
-  - RESTRICTIONS:
-  - The lenght is an aproximation to the real lenght
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  double CBlobGetLength::operator()(const CBlob &blob) const
-  {
-    double ampladaC, longitudC;
-    double tmp;
-
-    tmp = blob.Perimeter()*blob.Perimeter() - 16 * blob.Area();
-
-    if (tmp > 0.0)
-      ampladaC = (double)(blob.Perimeter() + sqrt(tmp)) / 4;
-    // error intr�nsec en els c�lculs de l'�rea i el per�metre 
-    else
-      ampladaC = (double)(blob.Perimeter()) / 4;
-
-    if (ampladaC <= 0.0) return 0;
-    longitudC = (double)blob.Area() / ampladaC;
-
-    return MAX(longitudC, ampladaC);
-  }
-
-  /**
-  Retorna l'amplada del blob
-  */
-  /**
-  - FUNCTION: CBlobGetBreadth
-  - FUNCTIONALITY: Calculates the breadth of the blob (the smallest axis of the blob)
-  - PARAMETERS:
-  - RESULT:
-  - RESTRICTIONS:
-  - The breadth is an aproximation to the real breadth
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  double CBlobGetBreadth::operator()(const CBlob &blob) const
-  {
-    double ampladaC, longitudC;
-    double tmp;
-
-    tmp = blob.Perimeter()*blob.Perimeter() - 16 * blob.Area();
-
-    if (tmp > 0.0)
-      ampladaC = (double)(blob.Perimeter() + sqrt(tmp)) / 4;
-    // error intr�nsec en els c�lculs de l'�rea i el per�metre 
-    else
-      ampladaC = (double)(blob.Perimeter()) / 4;
-
-    if (ampladaC <= 0.0) return 0;
-    longitudC = (double)blob.Area() / ampladaC;
-
-    return MIN(longitudC, ampladaC);
-  }
-
-  /**
-  Calcula la dist�ncia entre un punt i el centre del blob
-  */
-  /**
-  - FUNCTION: CBlobGetDistanceFromPoint
-  - FUNCTIONALITY: Calculates the euclidean distance between the blob center and
-  the point specified in the constructor
-  - PARAMETERS:
-  - RESULT:
-  - RESTRICTIONS:
-  - AUTHOR: Ricard Borr�s
-  - CREATION DATE: 25-05-2005.
-  - MODIFICATION: Date. Author. Description.
-  */
-  double CBlobGetDistanceFromPoint::operator()(const CBlob &blob) const
-  {
-    double xmitjana, ymitjana;
-    CBlobGetXCenter getXCenter;
-    CBlobGetYCenter getYCenter;
-
-    xmitjana = m_x - getXCenter(blob);
-    ymitjana = m_y - getYCenter(blob);
-
-    return sqrt((xmitjana*xmitjana) + (ymitjana*ymitjana));
-  }
-
-  /**
-  - FUNCI�: BlobGetXYInside
-  - FUNCIONALITAT: Calcula si un punt cau dins de la capsa rectangular
-  del blob
-  - RESULTAT:
-  - retorna 1 si hi est�; 0 si no
-  - RESTRICCIONS:
-  - AUTOR: Francesc Pinyol Margalef
-  - DATA DE CREACI�: 16-01-2006.
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  /**
-  - FUNCTION: BlobGetXYInside
-  - FUNCTIONALITY: Calculates whether a point is inside the
-  rectangular bounding box of a blob
-  - PARAMETERS:
-  - RESULT:
-  - returns 1 if it is inside; o if not
-  - RESTRICTIONS:
-  - AUTHOR: Francesc Pinyol Margalef
-  - CREATION DATE: 16-01-2006.
-  - MODIFICATION: Date. Author. Description.
-  */
-  double CBlobGetXYInside::operator()(const CBlob &blob) const
-  {
-    if (blob.Edges() == NULL || blob.Edges()->total == 0) return 0.0;
-
-    // passem els punts del blob a un vector de punts de les STL
-    CvSeqReader reader;
-    CBlob::vectorPunts vectorEdges;
-    CBlob::vectorPunts::iterator itEdges, itEdgesSeguent;
-    CvPoint edgeactual;
-    bool dinsBlob;
-
-    // agafem tots els punts amb la mateixa y que l'actual
-    cvStartReadSeq(blob.Edges(), &reader);
-
-    for (int i = 0; i < blob.Edges()->total; i++)
-    {
-      CV_READ_SEQ_ELEM(edgeactual, reader);
-      if (edgeactual.y == m_p.y)
-        vectorEdges.push_back(edgeactual);
-    }
-
-    if (vectorEdges.empty()) return 0.0;
-
-    // ordenem el vector per les Y's i les X's d'esquerra a dreta
-    std::sort(vectorEdges.begin(), vectorEdges.end(), CBlob::comparaCvPoint());
-
-    // recorrem el punts del blob de la mateixa fila que el punt d'entrada
-    // i mirem si la X del punt d'entrada est� entre dos coordenades "plenes"
-    // del blob
-    itEdges = vectorEdges.begin();
-    itEdgesSeguent = vectorEdges.begin() + 1;
-    dinsBlob = true;
-
-    while (itEdges != (vectorEdges.end() - 1))
-    {
-      if ((*itEdges).x <= m_p.x && (*itEdgesSeguent).x >= m_p.x && dinsBlob)
-      {
-        vectorEdges.clear();
-        return 1.0;
-      }
-
-      ++itEdges;
-      ++itEdgesSeguent;
-      dinsBlob = !dinsBlob;
-    }
-
-    vectorEdges.clear();
-    return 0.0;
-  }
-
-#ifdef BLOB_OBJECT_FACTORY
-
-  /**
-  - FUNCI�: RegistraTotsOperadors
-  - FUNCIONALITAT: Registrar tots els operadors definits a blob.h
-  - PAR�METRES:
-  - fabricaOperadorsBlob: f�brica on es registraran els operadors
-  - RESULTAT:
-  - Modifica l'objecte fabricaOperadorsBlob
-  - RESTRICCIONS:
-  - Nom�s es registraran els operadors de blob.h. Si se'n volen afegir, cal afegir-los amb 
-  el m�tode Register de la f�brica.
-  - AUTOR: rborras
-  - DATA DE CREACI�: 2006/05/18
-  - MODIFICACI�: Data. Autor. Descripci�.
-  */
-  void RegistraTotsOperadors( t_OperadorBlobFactory &fabricaOperadorsBlob )
-  {
-    // blob shape
-    fabricaOperadorsBlob.Register( CBlobGetArea().GetNom(), Type2Type<CBlobGetArea>());
-    fabricaOperadorsBlob.Register( CBlobGetBreadth().GetNom(), Type2Type<CBlobGetBreadth>());
-    fabricaOperadorsBlob.Register( CBlobGetCompactness().GetNom(), Type2Type<CBlobGetCompactness>());
-    fabricaOperadorsBlob.Register( CBlobGetElongation().GetNom(), Type2Type<CBlobGetElongation>());
-    fabricaOperadorsBlob.Register( CBlobGetExterior().GetNom(), Type2Type<CBlobGetExterior>());
-    fabricaOperadorsBlob.Register( CBlobGetLength().GetNom(), Type2Type<CBlobGetLength>());
-    fabricaOperadorsBlob.Register( CBlobGetPerimeter().GetNom(), Type2Type<CBlobGetPerimeter>());
-    fabricaOperadorsBlob.Register( CBlobGetRoughness().GetNom(), Type2Type<CBlobGetRoughness>());
-
-    // extern pixels
-    fabricaOperadorsBlob.Register( CBlobGetExternPerimeterRatio().GetNom(), Type2Type<CBlobGetExternPerimeterRatio>());
-    fabricaOperadorsBlob.Register( CBlobGetExternHullPerimeterRatio().GetNom(), Type2Type<CBlobGetExternHullPerimeterRatio>());
-    fabricaOperadorsBlob.Register( CBlobGetExternPerimeter().GetNom(), Type2Type<CBlobGetExternPerimeter>());
-
-
-    // hull 
-    fabricaOperadorsBlob.Register( CBlobGetHullPerimeter().GetNom(), Type2Type<CBlobGetHullPerimeter>());
-    fabricaOperadorsBlob.Register( CBlobGetHullArea().GetNom(), Type2Type<CBlobGetHullArea>());
-
-
-    // elipse info
-    fabricaOperadorsBlob.Register( CBlobGetMajorAxisLength().GetNom(), Type2Type<CBlobGetMajorAxisLength>());
-    fabricaOperadorsBlob.Register( CBlobGetMinorAxisLength().GetNom(), Type2Type<CBlobGetMinorAxisLength>());
-    fabricaOperadorsBlob.Register( CBlobGetAxisRatio().GetNom(), Type2Type<CBlobGetAxisRatio>());
-    fabricaOperadorsBlob.Register( CBlobGetOrientation().GetNom(), Type2Type<CBlobGetOrientation>());
-    fabricaOperadorsBlob.Register( CBlobGetOrientationCos().GetNom(), Type2Type<CBlobGetOrientationCos>());
-    fabricaOperadorsBlob.Register( CBlobGetAreaElipseRatio().GetNom(), Type2Type<CBlobGetAreaElipseRatio>());
-
-    // min an max
-    fabricaOperadorsBlob.Register( CBlobGetMaxX().GetNom(), Type2Type<CBlobGetMaxX>());
-    fabricaOperadorsBlob.Register( CBlobGetMaxY().GetNom(), Type2Type<CBlobGetMaxY>());
-    fabricaOperadorsBlob.Register( CBlobGetMinX().GetNom(), Type2Type<CBlobGetMinX>());
-    fabricaOperadorsBlob.Register( CBlobGetMinY().GetNom(), Type2Type<CBlobGetMinY>());
-
-    fabricaOperadorsBlob.Register( CBlobGetMaxXatMaxY().GetNom(), Type2Type<CBlobGetMaxXatMaxY>());
-    fabricaOperadorsBlob.Register( CBlobGetMaxYatMinX().GetNom(), Type2Type<CBlobGetMaxYatMinX>());
-    fabricaOperadorsBlob.Register( CBlobGetMinXatMinY().GetNom(), Type2Type<CBlobGetMinXatMinY>());
-    fabricaOperadorsBlob.Register( CBlobGetMinYatMaxX().GetNom(), Type2Type<CBlobGetMinYatMaxX>());
-
-    // grey level stats
-    fabricaOperadorsBlob.Register( CBlobGetMean().GetNom(), Type2Type<CBlobGetMean>());
-    fabricaOperadorsBlob.Register( CBlobGetStdDev().GetNom(), Type2Type<CBlobGetStdDev>());
-
-    // coordinate info
-    fabricaOperadorsBlob.Register( CBlobGetXYInside().GetNom(), Type2Type<CBlobGetXYInside>());
-    fabricaOperadorsBlob.Register( CBlobGetDiffY().GetNom(), Type2Type<CBlobGetDiffY>());
-    fabricaOperadorsBlob.Register( CBlobGetDiffX().GetNom(), Type2Type<CBlobGetDiffX>());
-    fabricaOperadorsBlob.Register( CBlobGetXCenter().GetNom(), Type2Type<CBlobGetXCenter>());
-    fabricaOperadorsBlob.Register( CBlobGetYCenter().GetNom(), Type2Type<CBlobGetYCenter>());
-    fabricaOperadorsBlob.Register( CBlobGetDistanceFromPoint().GetNom(), Type2Type<CBlobGetDistanceFromPoint>());
-
-    // moments
-    fabricaOperadorsBlob.Register( CBlobGetMoment().GetNom(), Type2Type<CBlobGetMoment>());
-
-  }
-
-#endif
-
-}
-
diff --git a/package_bgs/lb/BGModel.cpp b/package_bgs/lb/BGModel.cpp
index c42bec73e34dfb1dd83dc319bbb8569281521a62..3c73b53ce3f3ae7e8e4cb66304279ffd046fb85a 100644
--- a/package_bgs/lb/BGModel.cpp
+++ b/package_bgs/lb/BGModel.cpp
@@ -14,9 +14,9 @@ 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/>.
 */
-/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments  
+/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments
   BGModel.cpp
-    
+
   Copyright (C) 2011 Laurence Bender <lbender@untref.edu.ar>
 
     This program is free software; you can redistribute it and/or modify
@@ -38,11 +38,11 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
 
 namespace lb_library
 {
-  BGModel::BGModel(int width, int height): m_width(width), m_height(height)
+  BGModel::BGModel(int width, int height) : m_width(width), m_height(height)
   {
-    m_SrcImage = cvCreateImage(cvSize(m_width,m_height), IPL_DEPTH_8U, 3);
-    m_BGImage = cvCreateImage(cvSize(m_width,m_height), IPL_DEPTH_8U, 3);
-    m_FGImage = cvCreateImage(cvSize(m_width,m_height), IPL_DEPTH_8U, 3);
+    m_SrcImage = cvCreateImage(cvSize(m_width, m_height), IPL_DEPTH_8U, 3);
+    m_BGImage = cvCreateImage(cvSize(m_width, m_height), IPL_DEPTH_8U, 3);
+    m_FGImage = cvCreateImage(cvSize(m_width, m_height), IPL_DEPTH_8U, 3);
 
     cvZero(m_SrcImage);
     cvZero(m_BGImage);
@@ -51,9 +51,9 @@ namespace lb_library
 
   BGModel::~BGModel()
   {
-    if (m_SrcImage!=NULL) cvReleaseImage(&m_SrcImage);
-    if (m_BGImage!=NULL) cvReleaseImage(&m_BGImage);
-    if (m_FGImage!=NULL) cvReleaseImage(&m_FGImage);
+    if (m_SrcImage != NULL) cvReleaseImage(&m_SrcImage);
+    if (m_BGImage != NULL) cvReleaseImage(&m_BGImage);
+    if (m_FGImage != NULL) cvReleaseImage(&m_FGImage);
   }
 
   IplImage* BGModel::GetSrc()
@@ -73,15 +73,15 @@ namespace lb_library
 
   void BGModel::InitModel(IplImage* image)
   {
-    cvCopy(image,m_SrcImage);
+    cvCopy(image, m_SrcImage);
     Init();
     return;
   }
 
   void BGModel::UpdateModel(IplImage* image)
   {
-    cvCopy(image,m_SrcImage);
+    cvCopy(image, m_SrcImage);
     Update();
     return;
   }
-}
\ No newline at end of file
+}
diff --git a/package_bgs/lb/BGModel.h b/package_bgs/lb/BGModel.h
index 77f04902ca3dab6fce668d87490a77dfb3bd41b6..d47ad6242bd40995a94337b7bb511d8979851837 100644
--- a/package_bgs/lb/BGModel.h
+++ b/package_bgs/lb/BGModel.h
@@ -14,9 +14,9 @@ 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/>.
 */
-/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments  
+/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments
   BGModel.h
-    
+
   Copyright (C) 2011 Laurence Bender <lbender@untref.edu.ar>
 
     This program is free software; you can redistribute it and/or modify
@@ -33,9 +33,7 @@ along with BGSLibrary.  If not, see <http://www.gnu.org/licenses/>.
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-
-#ifndef BGMODEL_H
-#define BGMODEL_H
+#pragma once
 
 #include <opencv2/opencv.hpp>
 #include <math.h>
@@ -54,7 +52,7 @@ namespace lb_library
 
     void InitModel(IplImage* image);
     void UpdateModel(IplImage* image);
-  
+
     virtual void setBGModelParameter(int id, int value) {};
 
     virtual IplImage* GetSrc();
@@ -62,17 +60,15 @@ namespace lb_library
     virtual IplImage* GetBG();
 
   protected:
-  
+
     IplImage* m_SrcImage;
     IplImage* m_BGImage;
     IplImage* m_FGImage;
 
     const int m_width;
     const int m_height;
-  
+
     virtual void Init() = 0;
     virtual void Update() = 0;
   };
 }
-
-#endif
diff --git a/package_bgs/lb/BGModelFuzzyGauss.cpp b/package_bgs/lb/BGModelFuzzyGauss.cpp
index 8706b1376e76f635eae77759b2ab59c63808d152..b249052bc4920a77bc49c1d7e0b9a0acb0fbcdfc 100644
--- a/package_bgs/lb/BGModelFuzzyGauss.cpp
+++ b/package_bgs/lb/BGModelFuzzyGauss.cpp
@@ -14,7 +14,7 @@ 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/>.
 */
-/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments  
+/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments
 BGModelFuzzyGauss.cpp
 
 Copyright (C) 2011 Laurence Bender <lbender@untref.edu.ar>
@@ -40,7 +40,7 @@ namespace lb_library
 {
   namespace FuzzyGaussian
   {
-    BGModelFuzzyGauss::BGModelFuzzyGauss(int width, int height) : BGModel(width,height)
+    BGModelFuzzyGauss::BGModelFuzzyGauss(int width, int height) : BGModel(width, height)
     {
       m_alphamax = ALPHAFUZZYGAUSS;
       m_threshold = THRESHOLDFUZZYGAUSS * THRESHOLDFUZZYGAUSS;
@@ -53,7 +53,7 @@ namespace lb_library
       DBLRGB *pMu = m_pMu;
       DBLRGB *pVar = m_pVar;
 
-      for(int k = 0; k < (m_width * m_height); k++)
+      for (int k = 0; k < (m_width * m_height); k++)
       {
         pMu->Red = 0.0;
         pMu->Green = 0.0;
@@ -70,15 +70,15 @@ namespace lb_library
 
     BGModelFuzzyGauss::~BGModelFuzzyGauss()
     {
-      delete [] m_pMu;
-      delete [] m_pVar;
+      delete[] m_pMu;
+      delete[] m_pVar;
     }
 
     void BGModelFuzzyGauss::setBGModelParameter(int id, int value)
     {
-      double dvalue = (double)value/255.0;
+      double dvalue = (double)value / 255.0;
 
-      switch(id)
+      switch (id)
       {
       case 0:
         m_threshold = 100.0*dvalue*dvalue;
@@ -107,9 +107,9 @@ namespace lb_library
 
       Image<BYTERGB> prgbSrc(m_SrcImage);
 
-      for(int i = 0; i < m_height; i++)
+      for (int i = 0; i < m_height; i++)
       {
-        for(int j = 0; j < m_width; j++)
+        for (int j = 0; j < m_width; j++)
         {
           pMu->Red = prgbSrc[i][j].Red;
           pMu->Green = prgbSrc[i][j].Green;
@@ -136,13 +136,13 @@ namespace lb_library
       Image<BYTERGB> prgbBG(m_BGImage);
       Image<BYTERGB> prgbFG(m_FGImage);
 
-      for(int i = 0; i < m_height; i++)
+      for (int i = 0; i < m_height; i++)
       {
-        for(int j = 0; j < m_width; j++)
+        for (int j = 0; j < m_width; j++)
         {
-          double srcR = (double) prgbSrc[i][j].Red;
-          double srcG = (double) prgbSrc[i][j].Green;
-          double srcB = (double) prgbSrc[i][j].Blue;
+          double srcR = (double)prgbSrc[i][j].Red;
+          double srcG = (double)prgbSrc[i][j].Green;
+          double srcB = (double)prgbSrc[i][j].Blue;
 
           // Fuzzy background subtraction (Mahalanobis distance)
 
@@ -150,53 +150,53 @@ namespace lb_library
           double dg = srcG - pMu->Green;
           double db = srcB - pMu->Blue;
 
-          double d2 = dr*dr/pVar->Red + dg*dg/pVar->Green + db*db/pVar->Blue;
+          double d2 = dr*dr / pVar->Red + dg*dg / pVar->Green + db*db / pVar->Blue;
 
           double fuzzyBG = 1.0;
 
-          if(d2 < m_threshold)
-            fuzzyBG = d2/m_threshold;
+          if (d2 < m_threshold)
+            fuzzyBG = d2 / m_threshold;
 
           // Fuzzy running average
 
           double alpha = m_alphamax*exp(FUZZYEXP*fuzzyBG);
 
-          if(dr*dr > DBL_MIN)
+          if (dr*dr > DBL_MIN)
             pMu->Red += alpha*dr;
 
-          if(dg*dg > DBL_MIN)
+          if (dg*dg > DBL_MIN)
             pMu->Green += alpha*dg;
 
-          if(db*db > DBL_MIN)
+          if (db*db > DBL_MIN)
             pMu->Blue += alpha*db;
 
           double d;
 
           d = (srcR - pMu->Red)*(srcR - pMu->Red) - pVar->Red;
-          if(d*d > DBL_MIN)
+          if (d*d > DBL_MIN)
             pVar->Red += alpha*d;
 
           d = (srcG - pMu->Green)*(srcG - pMu->Green) - pVar->Green;
-          if(d*d > DBL_MIN)
+          if (d*d > DBL_MIN)
             pVar->Green += alpha*d;
 
           d = (srcB - pMu->Blue)*(srcB - pMu->Blue) - pVar->Blue;
-          if(d*d > DBL_MIN)
+          if (d*d > DBL_MIN)
             pVar->Blue += alpha*d;
 
-          pVar->Red = (std::max)(pVar->Red,m_noise);
-          pVar->Green = (std::max)(pVar->Green,m_noise);
-          pVar->Blue = (std::max)(pVar->Blue,m_noise);
+          pVar->Red = (std::max)(pVar->Red, m_noise);
+          pVar->Green = (std::max)(pVar->Green, m_noise);
+          pVar->Blue = (std::max)(pVar->Blue, m_noise);
 
           // Set foreground and background
 
-          if(fuzzyBG >= m_threshBG)
+          if (fuzzyBG >= m_threshBG)
             prgbFG[i][j].Red = prgbFG[i][j].Green = prgbFG[i][j].Blue = 255;
           else
             prgbFG[i][j].Red = prgbFG[i][j].Green = prgbFG[i][j].Blue = 0;
 
-          prgbBG[i][j].Red = (unsigned char)pMu->Red;			
-          prgbBG[i][j].Green = (unsigned char)pMu->Green;			
+          prgbBG[i][j].Red = (unsigned char)pMu->Red;
+          prgbBG[i][j].Green = (unsigned char)pMu->Green;
           prgbBG[i][j].Blue = (unsigned char)pMu->Blue;
 
           pMu++;
@@ -207,4 +207,4 @@ namespace lb_library
       return;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/package_bgs/lb/BGModelFuzzyGauss.h b/package_bgs/lb/BGModelFuzzyGauss.h
index 98a92e594c4783eca28bb85aba22cb1c2f125bd7..a73b7165080675520c3d6995074acbd1954795be 100644
--- a/package_bgs/lb/BGModelFuzzyGauss.h
+++ b/package_bgs/lb/BGModelFuzzyGauss.h
@@ -14,7 +14,7 @@ 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/>.
 */
-/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments  
+/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments
 BGModelFuzzyGauss.h
 
 Copyright (C) 2011 Laurence Bender <lbender@untref.edu.ar>
@@ -33,9 +33,7 @@ You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-
-#ifndef BGMODELFUZZYGAUSS_H
-#define BGMODELFUZZYGAUSS_H
+#pragma once
 
 #include "BGModel.h"
 
@@ -71,5 +69,3 @@ namespace lb_library
     };
   }
 }
-
-#endif
diff --git a/package_bgs/lb/BGModelFuzzySom.cpp b/package_bgs/lb/BGModelFuzzySom.cpp
index 189cb1aa3cd0faa138e70a197dafe6283eda0656..e7e59dda3b5c6c93209668edc50155c6d6d147bc 100644
--- a/package_bgs/lb/BGModelFuzzySom.cpp
+++ b/package_bgs/lb/BGModelFuzzySom.cpp
@@ -14,7 +14,7 @@ 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/>.
 */
-/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments  
+/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments
 BGModelFuzzySom.cpp
 
 Copyright (C) 2011 Laurence Bender <lbender@untref.edu.ar>
@@ -40,27 +40,27 @@ namespace lb_library
 {
   namespace FuzzyAdaptiveSOM
   {
-    BGModelFuzzySom::BGModelFuzzySom(int width, int height) : BGModel(width,height)
+    BGModelFuzzySom::BGModelFuzzySom(int width, int height) : BGModel(width, height)
     {
-      m_offset = (KERNEL - 1)/2;
+      m_offset = (KERNEL - 1) / 2;
 
-      if(SPAN_NEIGHBORS)
-        m_pad = 0;	
+      if (SPAN_NEIGHBORS)
+        m_pad = 0;
       else
         m_pad = m_offset;
 
       // SOM models
 
-      m_widthSOM = m_width*M + 2*m_offset + (m_width-1)*m_pad;
-      m_heightSOM = m_height*N + 2*m_offset + (m_height-1)*m_pad;
+      m_widthSOM = m_width*M + 2 * m_offset + (m_width - 1)*m_pad;
+      m_heightSOM = m_height*N + 2 * m_offset + (m_height - 1)*m_pad;
 
-      m_ppSOM = new DBLRGB*[m_heightSOM];	
-      for(int n = 0; n < m_heightSOM; n++)
+      m_ppSOM = new DBLRGB*[m_heightSOM];
+      for (int n = 0; n < m_heightSOM; n++)
         m_ppSOM[n] = new DBLRGB[m_widthSOM];
 
-      for(int j = 0; j < m_heightSOM; j++)
+      for (int j = 0; j < m_heightSOM; j++)
       {
-        for(int i = 0; i < m_widthSOM; i++)
+        for (int i = 0; i < m_widthSOM; i++)
         {
           m_ppSOM[j][i].Red = 0.0;
           m_ppSOM[j][i].Green = 0.0;
@@ -71,7 +71,7 @@ namespace lb_library
       // Create weights
 
       m_ppW = new double*[KERNEL];
-      for(int n = 0; n < KERNEL; n++)
+      for (int n = 0; n < KERNEL; n++)
         m_ppW[n] = new double[KERNEL];
 
       // Construct Gaussian kernel using Pascal's triangle
@@ -81,15 +81,15 @@ namespace lb_library
       m_Wmax = DBL_MIN;
 
       cN = 1;
-      for(int j = 0; j < KERNEL; j++)
+      for (int j = 0; j < KERNEL; j++)
       {
-        cM = 1;		
+        cM = 1;
 
-        for(int i = 0; i < KERNEL; i++)
+        for (int i = 0; i < KERNEL; i++)
         {
           m_ppW[j][i] = cN*cM;
 
-          if(m_ppW[j][i] > m_Wmax)
+          if (m_ppW[j][i] > m_Wmax)
             m_Wmax = m_ppW[j][i];
 
           cM = cM * (KERNEL - 1 - i) / (i + 1);
@@ -103,8 +103,8 @@ namespace lb_library
       m_epsilon1 = EPS1*EPS1;
       m_epsilon2 = EPS2*EPS2;
 
-      m_alpha1 = C1/m_Wmax;
-      m_alpha2 = C2/m_Wmax;
+      m_alpha1 = C1 / m_Wmax;
+      m_alpha2 = C2 / m_Wmax;
 
       m_K = 0;
       m_TSteps = TRAINING_STEPS;
@@ -112,22 +112,22 @@ namespace lb_library
 
     BGModelFuzzySom::~BGModelFuzzySom()
     {
-      for(int n = 0; n < m_heightSOM; n++)
-        delete [] m_ppSOM[n];
+      for (int n = 0; n < m_heightSOM; n++)
+        delete[] m_ppSOM[n];
 
-      delete [] m_ppSOM;
+      delete[] m_ppSOM;
 
-      for(int n = 0; n < KERNEL; n++)
-        delete [] m_ppW[n];
+      for (int n = 0; n < KERNEL; n++)
+        delete[] m_ppW[n];
 
-      delete [] m_ppW;
+      delete[] m_ppW;
     }
 
     void BGModelFuzzySom::setBGModelParameter(int id, int value)
     {
-      double dvalue = (double)value/255.0;
+      double dvalue = (double)value / 255.0;
 
-      switch(id)
+      switch (id)
       {
       case 0:
         m_epsilon2 = 255.0*255.0*dvalue*dvalue*dvalue*dvalue;
@@ -138,11 +138,11 @@ namespace lb_library
         break;
 
       case 2:
-        m_alpha2 = dvalue*dvalue*dvalue/m_Wmax;
+        m_alpha2 = dvalue*dvalue*dvalue / m_Wmax;
         break;
 
       case 3:
-        m_alpha1 = dvalue*dvalue*dvalue/m_Wmax;
+        m_alpha1 = dvalue*dvalue*dvalue / m_Wmax;
         break;
 
       case 5:
@@ -157,21 +157,21 @@ namespace lb_library
     {
       Image<BYTERGB> prgbSrc(m_SrcImage);
 
-      for(int j = 0; j < m_height; j++)
+      for (int j = 0; j < m_height; j++)
       {
         int jj = m_offset + j*(N + m_pad);
 
-        for(int i = 0; i < m_width; i++)
+        for (int i = 0; i < m_width; i++)
         {
-          int ii = m_offset + i*(M + m_pad);		
+          int ii = m_offset + i*(M + m_pad);
 
-          for(int l = 0; l < N; l++)
+          for (int l = 0; l < N; l++)
           {
-            for(int k = 0; k < M; k++)
+            for (int k = 0; k < M; k++)
             {
-              m_ppSOM[jj+l][ii+k].Red = (double)prgbSrc[j][i].Red;
-              m_ppSOM[jj+l][ii+k].Green = (double)prgbSrc[j][i].Green;
-              m_ppSOM[jj+l][ii+k].Blue = (double)prgbSrc[j][i].Blue;
+              m_ppSOM[jj + l][ii + k].Red = (double)prgbSrc[j][i].Red;
+              m_ppSOM[jj + l][ii + k].Green = (double)prgbSrc[j][i].Green;
+              m_ppSOM[jj + l][ii + k].Blue = (double)prgbSrc[j][i].Blue;
             }
           }
         }
@@ -184,11 +184,11 @@ namespace lb_library
 
     void BGModelFuzzySom::Update()
     {
-      double alpha,a;
+      double alpha, a;
       double epsilon;
 
       // calibration phase
-      if(m_K <= m_TSteps)
+      if (m_K <= m_TSteps)
       {
         epsilon = m_epsilon1;
         alpha = (m_alpha1 - m_K * (m_alpha1 - m_alpha2) / m_TSteps);
@@ -204,11 +204,11 @@ namespace lb_library
       Image<BYTERGB> prgbBG(m_BGImage);
       Image<BYTERGB> prgbFG(m_FGImage);
 
-      for(int j = 0; j < m_height; j++)
+      for (int j = 0; j < m_height; j++)
       {
         int jj = m_offset + j*(N + m_pad);
 
-        for(int i = 0; i < m_width; i++)
+        for (int i = 0; i < m_width; i++)
         {
           int ii = m_offset + i*(M + m_pad);
 
@@ -222,17 +222,17 @@ namespace lb_library
           int iiHit = ii;
           int jjHit = jj;
 
-          for(int l = 0; l < N; l++)
+          for (int l = 0; l < N; l++)
           {
-            for(int k = 0; k < M; k++)
+            for (int k = 0; k < M; k++)
             {
-              double dr = srcR - m_ppSOM[jj+l][ii+k].Red;
-              double dg = srcG - m_ppSOM[jj+l][ii+k].Green;
-              double db = srcB - m_ppSOM[jj+l][ii+k].Blue;
+              double dr = srcR - m_ppSOM[jj + l][ii + k].Red;
+              double dg = srcG - m_ppSOM[jj + l][ii + k].Green;
+              double db = srcB - m_ppSOM[jj + l][ii + k].Blue;
 
               double d2 = dr*dr + dg*dg + db*db;
 
-              if(d2 < d2min)
+              if (d2 < d2min)
               {
                 d2min = d2;
                 iiHit = ii + k;
@@ -243,16 +243,16 @@ namespace lb_library
 
           double fuzzyBG = 1.0;
 
-          if(d2min < epsilon)
-            fuzzyBG = d2min/epsilon;
+          if (d2min < epsilon)
+            fuzzyBG = d2min / epsilon;
 
           // Update SOM
 
           double alphamax = alpha*exp(FUZZYEXP*fuzzyBG);
 
-          for(int l = (jjHit - m_offset); l <= (jjHit + m_offset); l++)
+          for (int l = (jjHit - m_offset); l <= (jjHit + m_offset); l++)
           {
-            for(int k = (iiHit - m_offset); k <= (iiHit + m_offset); k++)
+            for (int k = (iiHit - m_offset); k <= (iiHit + m_offset); k++)
             {
               a = alphamax * m_ppW[l - jjHit + m_offset][k - iiHit + m_offset];
 
@@ -261,20 +261,20 @@ namespace lb_library
               double d;
 
               d = srcR - m_ppSOM[l][k].Red;
-              if(d*d > DBL_MIN)
+              if (d*d > DBL_MIN)
                 m_ppSOM[l][k].Red += a*d;
 
               d = srcG - m_ppSOM[l][k].Green;
-              if(d*d > DBL_MIN)
+              if (d*d > DBL_MIN)
                 m_ppSOM[l][k].Green += a*d;
 
               d = srcB - m_ppSOM[l][k].Blue;
-              if(d*d > DBL_MIN)
+              if (d*d > DBL_MIN)
                 m_ppSOM[l][k].Blue += a*d;
             }
           }
 
-          if(fuzzyBG >= FUZZYTHRESH)
+          if (fuzzyBG >= FUZZYTHRESH)
           {
             // Set foreground image
             prgbFG[j][i].Red = prgbFG[j][i].Green = prgbFG[j][i].Blue = 255;
@@ -284,7 +284,7 @@ namespace lb_library
             // Set background image
             prgbBG[j][i].Red = m_ppSOM[jjHit][iiHit].Red;
             prgbBG[j][i].Green = m_ppSOM[jjHit][iiHit].Green;
-            prgbBG[j][i].Blue =  m_ppSOM[jjHit][iiHit].Blue;
+            prgbBG[j][i].Blue = m_ppSOM[jjHit][iiHit].Blue;
 
             // Set foreground image
             prgbFG[j][i].Red = prgbFG[j][i].Green = prgbFG[j][i].Blue = 0;
@@ -295,4 +295,4 @@ namespace lb_library
       return;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/package_bgs/lb/BGModelFuzzySom.h b/package_bgs/lb/BGModelFuzzySom.h
index 2f21d3e01368863f6fa2188117b7527a520f82c4..ed0bf210e236a8acf02685c1e802be698ed4814d 100644
--- a/package_bgs/lb/BGModelFuzzySom.h
+++ b/package_bgs/lb/BGModelFuzzySom.h
@@ -14,7 +14,7 @@ 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/>.
 */
-/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments  
+/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments
 BGModelFuzzySom.h
 
 Copyright (C) 2011 Laurence Bender <lbender@untref.edu.ar>
@@ -33,9 +33,7 @@ You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-
-#ifndef BGMODELFUZZYSOM_H
-#define BGMODELFUZZYSOM_H
+#pragma once
 
 #include "BGModel.h"
 
@@ -47,9 +45,9 @@ namespace lb_library
 
     const int M = 3;				// width SOM (per pixel)
     const int N = 3;				// height SOM (per pixel)
-    const int KERNEL = 3; 	// size Gaussian kernel 
+    const int KERNEL = 3; 	// size Gaussian kernel
 
-    const bool SPAN_NEIGHBORS = false; // true if update neighborhood spans different pixels			// 
+    const bool SPAN_NEIGHBORS = false; // true if update neighborhood spans different pixels			//
     const int TRAINING_STEPS = 100;			// number of training steps
 
     const double EPS1 = 100.0; // model match distance during training
@@ -84,12 +82,10 @@ namespace lb_library
       double m_alpha2;
 
       DBLRGB** m_ppSOM;					// SOM grid
-      double** m_ppW;						// Weights 
+      double** m_ppW;						// Weights
 
       void Init();
       void Update();
     };
   }
 }
-
-#endif
diff --git a/package_bgs/lb/BGModelGauss.cpp b/package_bgs/lb/BGModelGauss.cpp
index 6892d13b9b9820f8f61734b2bde3d37ce8c74c5d..28a8b9379606f6a34600ec9d677e74343ad0a522 100644
--- a/package_bgs/lb/BGModelGauss.cpp
+++ b/package_bgs/lb/BGModelGauss.cpp
@@ -14,7 +14,7 @@ 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/>.
 */
-/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments  
+/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments
 BGModelGauss.cpp
 
 Copyright (C) 2011 Laurence Bender <lbender@untref.edu.ar>
@@ -40,7 +40,7 @@ namespace lb_library
 {
   namespace SimpleGaussian
   {
-    BGModelGauss::BGModelGauss(int width, int height) : BGModel(width,height)
+    BGModelGauss::BGModelGauss(int width, int height) : BGModel(width, height)
     {
       m_alpha = ALPHAGAUSS;
       m_threshold = THRESHGAUSS*THRESHGAUSS;
@@ -52,7 +52,7 @@ namespace lb_library
       DBLRGB *pMu = m_pMu;
       DBLRGB *pVar = m_pVar;
 
-      for(int k = 0; k < (m_width * m_height); k++)
+      for (int k = 0; k < (m_width * m_height); k++)
       {
         pMu->Red = 0.0;
         pMu->Green = 0.0;
@@ -69,15 +69,15 @@ namespace lb_library
 
     BGModelGauss::~BGModelGauss()
     {
-      delete [] m_pMu;
-      delete [] m_pVar;
+      delete[] m_pMu;
+      delete[] m_pVar;
     }
 
     void BGModelGauss::setBGModelParameter(int id, int value)
     {
-      double dvalue = (double)value/255.0;
+      double dvalue = (double)value / 255.0;
 
-      switch(id)
+      switch (id)
       {
       case 0:
         m_threshold = 100.0*dvalue*dvalue;
@@ -87,7 +87,7 @@ namespace lb_library
         m_noise = 100.0*dvalue;
         break;
 
-      case 2: 
+      case 2:
         m_alpha = dvalue*dvalue*dvalue;
         break;
       }
@@ -102,9 +102,9 @@ namespace lb_library
 
       Image<BYTERGB> prgbSrc(m_SrcImage);
 
-      for(int i = 0; i < m_height; i++)
+      for (int i = 0; i < m_height; i++)
       {
-        for(int j = 0; j < m_width; j++)
+        for (int j = 0; j < m_width; j++)
         {
           pMu->Red = prgbSrc[i][j].Red;
           pMu->Green = prgbSrc[i][j].Green;
@@ -131,62 +131,62 @@ namespace lb_library
       Image<BYTERGB> prgbBG(m_BGImage);
       Image<BYTERGB> prgbFG(m_FGImage);
 
-      for(int i = 0; i < m_height; i++)
+      for (int i = 0; i < m_height; i++)
       {
-        for(int j = 0; j < m_width; j++)
+        for (int j = 0; j < m_width; j++)
         {
-          double srcR = (double) prgbSrc[i][j].Red;
-          double srcG = (double) prgbSrc[i][j].Green;
-          double srcB = (double) prgbSrc[i][j].Blue;
+          double srcR = (double)prgbSrc[i][j].Red;
+          double srcG = (double)prgbSrc[i][j].Green;
+          double srcB = (double)prgbSrc[i][j].Blue;
 
-          // Mahalanobis distance 
+          // Mahalanobis distance
 
           double dr = srcR - pMu->Red;
           double dg = srcG - pMu->Green;
           double db = srcB - pMu->Blue;
 
-          double d2 = dr*dr/pVar->Red + dg*dg/pVar->Green + db*db/pVar->Blue;
+          double d2 = dr*dr / pVar->Red + dg*dg / pVar->Green + db*db / pVar->Blue;
 
           // Classify
 
-          if(d2 < m_threshold)
-            prgbFG[i][j].Red = prgbFG[i][j].Green = prgbFG[i][j].Blue = 0;		
+          if (d2 < m_threshold)
+            prgbFG[i][j].Red = prgbFG[i][j].Green = prgbFG[i][j].Blue = 0;
           else
-            prgbFG[i][j].Red = prgbFG[i][j].Green = prgbFG[i][j].Blue = 255;		
+            prgbFG[i][j].Red = prgbFG[i][j].Green = prgbFG[i][j].Blue = 255;
 
           // Update parameters
 
-          if(dr*dr > DBL_MIN)
+          if (dr*dr > DBL_MIN)
             pMu->Red += m_alpha*dr;
 
-          if(dg*dg > DBL_MIN)
+          if (dg*dg > DBL_MIN)
             pMu->Green += m_alpha*dg;
 
-          if(db*db > DBL_MIN)
+          if (db*db > DBL_MIN)
             pMu->Blue += m_alpha*db;
 
           double d;
 
           d = (srcR - pMu->Red)*(srcR - pMu->Red) - pVar->Red;
-          if(d*d > DBL_MIN)
+          if (d*d > DBL_MIN)
             pVar->Red += m_alpha*d;
 
           d = (srcG - pMu->Green)*(srcG - pMu->Green) - pVar->Green;
-          if(d*d > DBL_MIN)
+          if (d*d > DBL_MIN)
             pVar->Green += m_alpha*d;
 
           d = (srcB - pMu->Blue)*(srcB - pMu->Blue) - pVar->Blue;
-          if(d*d > DBL_MIN)
+          if (d*d > DBL_MIN)
             pVar->Blue += m_alpha*d;
 
-          pVar->Red = (std::min)(pVar->Red,m_noise);
-          pVar->Green = (std::min)(pVar->Green,m_noise);
-          pVar->Blue = (std::min)(pVar->Blue,m_noise);
+          pVar->Red = (std::min)(pVar->Red, m_noise);
+          pVar->Green = (std::min)(pVar->Green, m_noise);
+          pVar->Blue = (std::min)(pVar->Blue, m_noise);
 
           // Set background
 
-          prgbBG[i][j].Red = (unsigned char)pMu->Red;			
-          prgbBG[i][j].Green = (unsigned char)pMu->Green;			
+          prgbBG[i][j].Red = (unsigned char)pMu->Red;
+          prgbBG[i][j].Green = (unsigned char)pMu->Green;
           prgbBG[i][j].Blue = (unsigned char)pMu->Blue;
 
           pMu++;
@@ -197,4 +197,4 @@ namespace lb_library
       return;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/package_bgs/lb/BGModelGauss.h b/package_bgs/lb/BGModelGauss.h
index d36a716ab4094acd9ea431b6c834dc563ecfacae..0af6efe7beb9207d185ff15fc1d18df8c3657f3f 100644
--- a/package_bgs/lb/BGModelGauss.h
+++ b/package_bgs/lb/BGModelGauss.h
@@ -14,7 +14,7 @@ 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/>.
 */
-/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments  
+/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments
 BGModelGauss.h
 
 Copyright (C) 2011 Laurence Bender <lbender@untref.edu.ar>
@@ -33,9 +33,7 @@ You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-
-#ifndef BGMODELGAUSS_H
-#define BGMODELGAUSS_H
+#pragma once
 
 #include "BGModel.h"
 
@@ -69,5 +67,3 @@ namespace lb_library
     };
   }
 }
-
-#endif
diff --git a/package_bgs/lb/BGModelMog.cpp b/package_bgs/lb/BGModelMog.cpp
index df6986c90327115f7fb56d5066f976b7e1f8b3f7..036feabf1aaa3a819d3f816f43b98d97772c0a1e 100644
--- a/package_bgs/lb/BGModelMog.cpp
+++ b/package_bgs/lb/BGModelMog.cpp
@@ -14,7 +14,7 @@ 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/>.
 */
-/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments  
+/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments
 BGModelMog.cpp
 
 Copyright (C) 2011 Laurence Bender <lbender@untref.edu.ar>
@@ -54,9 +54,9 @@ namespace lb_library
       MOGDATA *pMOG = m_pMOG;
       int *pK = m_pK;
 
-      for(int i = 0; i < (m_width * m_height); i++)
+      for (int i = 0; i < (m_width * m_height); i++)
       {
-        for(int k = 0; k < NUMBERGAUSSIANS; k++)
+        for (int k = 0; k < NUMBERGAUSSIANS; k++)
         {
           pMOG->mu.Red = 0.0;
           pMOG->mu.Green = 0.0;
@@ -72,27 +72,27 @@ namespace lb_library
           pMOG++;
         }
 
-        pK[i] = 0; 
+        pK[i] = 0;
       }
     }
 
     BGModelMog::~BGModelMog()
     {
-      delete [] m_pMOG;
-      delete [] m_pK;
+      delete[] m_pMOG;
+      delete[] m_pK;
     }
 
     void BGModelMog::setBGModelParameter(int id, int value)
     {
-      double dvalue = (double)value/255.0;
+      double dvalue = (double)value / 255.0;
 
-      switch(id)
+      switch (id)
       {
       case 0:
         m_threshold = 100.0*dvalue*dvalue;
         break;
 
-      case 1: 
+      case 1:
         m_T = dvalue;
         break;
 
@@ -100,7 +100,7 @@ namespace lb_library
         m_alpha = dvalue*dvalue*dvalue;
         break;
 
-      case 3: 
+      case 3:
         m_noise = 100.0*dvalue;;
         break;
       }
@@ -116,9 +116,9 @@ namespace lb_library
       Image<BYTERGB> prgbSrc(m_SrcImage);
 
       int n = 0;
-      for(int i = 0; i < m_height; i++)
+      for (int i = 0; i < m_height; i++)
       {
-        for(int j = 0; j < m_width; j++)
+        for (int j = 0; j < m_width; j++)
         {
           pMOG[0].mu.Red = prgbSrc[i][j].Red;
           pMOG[0].mu.Green = prgbSrc[i][j].Green;
@@ -129,7 +129,7 @@ namespace lb_library
           pMOG[0].var.Blue = m_noise;
 
           pMOG[0].w = 1.0;
-          pMOG[0].sortKey = pMOG[0].w/sqrt(pMOG[0].var.Red+pMOG[0].var.Green+pMOG[0].var.Blue);
+          pMOG[0].sortKey = pMOG[0].w / sqrt(pMOG[0].var.Red + pMOG[0].var.Green + pMOG[0].var.Blue);
 
           pK[n] = 1;
           n++;
@@ -153,27 +153,27 @@ namespace lb_library
       Image<BYTERGB> prgbFG(m_FGImage);
 
       int n = 0;
-      for(int i = 0; i < m_height; i++)
+      for (int i = 0; i < m_height; i++)
       {
-        for(int j = 0; j < m_width; j++)
+        for (int j = 0; j < m_width; j++)
         {
-          double srcR = (double) prgbSrc[i][j].Red;
-          double srcG = (double) prgbSrc[i][j].Green;
-          double srcB = (double) prgbSrc[i][j].Blue;
+          double srcR = (double)prgbSrc[i][j].Red;
+          double srcG = (double)prgbSrc[i][j].Green;
+          double srcB = (double)prgbSrc[i][j].Blue;
 
           // Find matching distribution
 
           int kHit = -1;
 
-          for(int k = 0; k < pK[n]; k++)
+          for (int k = 0; k < pK[n]; k++)
           {
             // Mahalanobis distance
             double dr = srcR - pMOG[k].mu.Red;
             double dg = srcG - pMOG[k].mu.Green;
             double db = srcB - pMOG[k].mu.Blue;
-            double d2 = dr*dr/pMOG[k].var.Red + dg*dg/pMOG[k].var.Green + db*db/pMOG[k].var.Blue;
+            double d2 = dr*dr / pMOG[k].var.Red + dg*dg / pMOG[k].var.Green + db*db / pMOG[k].var.Blue;
 
-            if(d2 < m_threshold)
+            if (d2 < m_threshold)
             {
               kHit = k;
               break;
@@ -183,43 +183,43 @@ namespace lb_library
           // Adjust parameters
 
           // matching distribution found
-          if(kHit != -1)
+          if (kHit != -1)
           {
-            for(int k = 0; k < pK[n]; k++)
+            for (int k = 0; k < pK[n]; k++)
             {
-              if(k == kHit)
+              if (k == kHit)
               {
                 pMOG[k].w = pMOG[k].w + m_alpha*(1.0f - pMOG[k].w);
 
                 double d;
 
                 d = srcR - pMOG[k].mu.Red;
-                if(d*d > DBL_MIN)
+                if (d*d > DBL_MIN)
                   pMOG[k].mu.Red += m_alpha*d;
 
                 d = srcG - pMOG[k].mu.Green;
-                if(d*d > DBL_MIN)
+                if (d*d > DBL_MIN)
                   pMOG[k].mu.Green += m_alpha*d;
 
                 d = srcB - pMOG[k].mu.Blue;
-                if(d*d > DBL_MIN)
+                if (d*d > DBL_MIN)
                   pMOG[k].mu.Blue += m_alpha*d;
 
                 d = (srcR - pMOG[k].mu.Red)*(srcR - pMOG[k].mu.Red) - pMOG[k].var.Red;
-                if(d*d > DBL_MIN)
+                if (d*d > DBL_MIN)
                   pMOG[k].var.Red += m_alpha*d;
 
                 d = (srcG - pMOG[k].mu.Green)*(srcG - pMOG[k].mu.Green) - pMOG[k].var.Green;
-                if(d*d > DBL_MIN)
+                if (d*d > DBL_MIN)
                   pMOG[k].var.Green += m_alpha*d;
 
                 d = (srcB - pMOG[k].mu.Blue)*(srcB - pMOG[k].mu.Blue) - pMOG[k].var.Blue;
-                if(d*d > DBL_MIN)
+                if (d*d > DBL_MIN)
                   pMOG[k].var.Blue += m_alpha*d;
 
-                pMOG[k].var.Red = (std::max)(pMOG[k].var.Red,m_noise);
-                pMOG[k].var.Green = (std::max)(pMOG[k].var.Green,m_noise);
-                pMOG[k].var.Blue = (std::max)(pMOG[k].var.Blue,m_noise);
+                pMOG[k].var.Red = (std::max)(pMOG[k].var.Red, m_noise);
+                pMOG[k].var.Green = (std::max)(pMOG[k].var.Green, m_noise);
+                pMOG[k].var.Blue = (std::max)(pMOG[k].var.Blue, m_noise);
               }
               else
                 pMOG[k].w = (1.0 - m_alpha)*pMOG[k].w;
@@ -228,12 +228,12 @@ namespace lb_library
           // no match found... create new one
           else
           {
-            if(pK[n] < NUMBERGAUSSIANS)
+            if (pK[n] < NUMBERGAUSSIANS)
               pK[n]++;
 
             kHit = pK[n] - 1;
 
-            if(pK[n] == 1)
+            if (pK[n] == 1)
               pMOG[kHit].w = 1.0;
             else
               pMOG[kHit].w = LEARNINGRATEMOG;
@@ -251,24 +251,24 @@ namespace lb_library
 
           double wsum = 0.0;
 
-          for(int k = 0; k < pK[n]; k++) 
+          for (int k = 0; k < pK[n]; k++)
             wsum += pMOG[k].w;
 
-          double wfactor = 1.0/wsum;
+          double wfactor = 1.0 / wsum;
 
-          for(int k = 0; k < pK[n]; k++)
+          for (int k = 0; k < pK[n]; k++)
           {
             pMOG[k].w *= wfactor;
-            pMOG[k].sortKey = pMOG[k].w/sqrt(pMOG[k].var.Red+pMOG[k].var.Green+pMOG[k].var.Blue);
+            pMOG[k].sortKey = pMOG[k].w / sqrt(pMOG[k].var.Red + pMOG[k].var.Green + pMOG[k].var.Blue);
           }
 
           // Sort distributions
 
           for (int k = 0; k < kHit; k++)
           {
-            if(pMOG[kHit].sortKey > pMOG[k].sortKey)
+            if (pMOG[kHit].sortKey > pMOG[k].sortKey)
             {
-              std::swap(pMOG[kHit],pMOG[k]);
+              std::swap(pMOG[kHit], pMOG[k]);
               break;
             }
           }
@@ -277,21 +277,21 @@ namespace lb_library
 
           wsum = 0.0;
 
-          for(int k = 0; k < pK[n]; k++)
+          for (int k = 0; k < pK[n]; k++)
           {
             wsum += pMOG[k].w;
 
-            if(wsum > m_T)
+            if (wsum > m_T)
             {
               kBG = k;
               break;
             }
           }
 
-          if(kHit > kBG)
-            prgbFG[i][j].Red = prgbFG[i][j].Green = prgbFG[i][j].Blue = 255;			
+          if (kHit > kBG)
+            prgbFG[i][j].Red = prgbFG[i][j].Green = prgbFG[i][j].Blue = 255;
           else
-            prgbFG[i][j].Red = prgbFG[i][j].Green = prgbFG[i][j].Blue = 0;			
+            prgbFG[i][j].Red = prgbFG[i][j].Green = prgbFG[i][j].Blue = 0;
 
           prgbBG[i][j].Red = (unsigned char)pMOG[0].mu.Red;
           prgbBG[i][j].Green = (unsigned char)pMOG[0].mu.Green;
@@ -306,4 +306,4 @@ namespace lb_library
       return;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/package_bgs/lb/BGModelMog.h b/package_bgs/lb/BGModelMog.h
index c4e51a4447722bb0d8719297e1bd2e6269a53968..c75d1fdee92df5ebba23358f3321fcd06114c661 100644
--- a/package_bgs/lb/BGModelMog.h
+++ b/package_bgs/lb/BGModelMog.h
@@ -14,7 +14,7 @@ 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/>.
 */
-/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments  
+/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments
 BGModelMog.h
 
 Copyright (C) 2011 Laurence Bender <lbender@untref.edu.ar>
@@ -33,9 +33,7 @@ You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-
-#ifndef BGMODELMOGRGB_H
-#define BGMODELMOGRGB_H
+#pragma once
 
 #include "BGModel.h"
 
@@ -79,5 +77,3 @@ namespace lb_library
     };
   }
 }
-
-#endif
diff --git a/package_bgs/lb/BGModelSom.cpp b/package_bgs/lb/BGModelSom.cpp
index 256d4855f62d71aab321be466098f754fa7597ed..735af6e014669e777f01dad8518ac63b6e66456e 100644
--- a/package_bgs/lb/BGModelSom.cpp
+++ b/package_bgs/lb/BGModelSom.cpp
@@ -14,7 +14,7 @@ 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/>.
 */
-/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments  
+/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments
 BGModelSom.cpp
 
 Copyright (C) 2011 Laurence Bender <lbender@untref.edu.ar>
@@ -40,28 +40,28 @@ namespace lb_library
 {
   namespace AdaptiveSOM
   {
-    BGModelSom::BGModelSom(int width, int height) : BGModel(width,height)
+    BGModelSom::BGModelSom(int width, int height) : BGModel(width, height)
     {
-      m_offset = (KERNEL - 1)/2;
+      m_offset = (KERNEL - 1) / 2;
 
-      if(SPAN_NEIGHBORS)
-        m_pad = 0;	
+      if (SPAN_NEIGHBORS)
+        m_pad = 0;
       else
         m_pad = m_offset;
 
       // SOM models
 
-      m_widthSOM = m_width*M + 2*m_offset + (m_width-1)*m_pad;
-      m_heightSOM = m_height*N + 2*m_offset + (m_height-1)*m_pad;
+      m_widthSOM = m_width*M + 2 * m_offset + (m_width - 1)*m_pad;
+      m_heightSOM = m_height*N + 2 * m_offset + (m_height - 1)*m_pad;
 
-      m_ppSOM = new DBLRGB*[m_heightSOM];	
-      for(int n = 0; n < m_heightSOM; n++)
+      m_ppSOM = new DBLRGB*[m_heightSOM];
+      for (int n = 0; n < m_heightSOM; n++)
         m_ppSOM[n] = new DBLRGB[m_widthSOM];
 
-      for(int j = 0; j < m_heightSOM; j++)
+      for (int j = 0; j < m_heightSOM; j++)
       {
-        for(int i = 0; i < m_widthSOM; i++)
-        {							
+        for (int i = 0; i < m_widthSOM; i++)
+        {
           m_ppSOM[j][i].Red = 0.0;
           m_ppSOM[j][i].Green = 0.0;
           m_ppSOM[j][i].Blue = 0.0;
@@ -71,7 +71,7 @@ namespace lb_library
       // Create weights
 
       m_ppW = new double*[KERNEL];
-      for(int n = 0; n < KERNEL; n++)
+      for (int n = 0; n < KERNEL; n++)
         m_ppW[n] = new double[KERNEL];
 
       // Construct Gaussian kernel using Pascal's triangle
@@ -81,16 +81,16 @@ namespace lb_library
       m_Wmax = DBL_MIN;
 
       cN = 1;
-      for(int j = 0; j < KERNEL; j++)
+      for (int j = 0; j < KERNEL; j++)
       {
-        cM = 1;		
+        cM = 1;
 
-        for(int i = 0; i < KERNEL; i++)
+        for (int i = 0; i < KERNEL; i++)
         {
           m_ppW[j][i] = cN*cM;
 
-          if(m_ppW[j][i] > m_Wmax)
-            m_Wmax = m_ppW[j][i]; 
+          if (m_ppW[j][i] > m_Wmax)
+            m_Wmax = m_ppW[j][i];
 
           cM = cM * (KERNEL - 1 - i) / (i + 1);
         }
@@ -103,8 +103,8 @@ namespace lb_library
       m_epsilon1 = EPS1*EPS1;
       m_epsilon2 = EPS2*EPS2;
 
-      m_alpha1 = C1/m_Wmax;
-      m_alpha2 = C2/m_Wmax;
+      m_alpha1 = C1 / m_Wmax;
+      m_alpha2 = C2 / m_Wmax;
 
       m_K = 0;
       m_TSteps = TRAINING_STEPS;
@@ -112,22 +112,22 @@ namespace lb_library
 
     BGModelSom::~BGModelSom()
     {
-      for(int n = 0; n < m_heightSOM; n++)
-        delete [] m_ppSOM[n];
+      for (int n = 0; n < m_heightSOM; n++)
+        delete[] m_ppSOM[n];
 
-      delete [] m_ppSOM;
+      delete[] m_ppSOM;
 
-      for(int n = 0; n < KERNEL; n++)
-        delete [] m_ppW[n];
+      for (int n = 0; n < KERNEL; n++)
+        delete[] m_ppW[n];
 
-      delete [] m_ppW;
+      delete[] m_ppW;
     }
 
     void BGModelSom::setBGModelParameter(int id, int value)
     {
-      double dvalue = (double)value/255.0;
+      double dvalue = (double)value / 255.0;
 
-      switch(id)
+      switch (id)
       {
       case 0:
         m_epsilon2 = 255.0*255.0*dvalue*dvalue*dvalue*dvalue;
@@ -138,11 +138,11 @@ namespace lb_library
         break;
 
       case 2:
-        m_alpha2 = dvalue*dvalue*dvalue/m_Wmax;
+        m_alpha2 = dvalue*dvalue*dvalue / m_Wmax;
         break;
 
       case 3:
-        m_alpha1 = dvalue*dvalue*dvalue/m_Wmax;
+        m_alpha1 = dvalue*dvalue*dvalue / m_Wmax;
         break;
 
       case 5:
@@ -157,21 +157,21 @@ namespace lb_library
     {
       Image<BYTERGB> prgbSrc(m_SrcImage);
 
-      for(int j = 0; j < m_height; j++)
+      for (int j = 0; j < m_height; j++)
       {
         int jj = m_offset + j*(N + m_pad);
 
-        for(int i = 0; i < m_width; i++)
+        for (int i = 0; i < m_width; i++)
         {
-          int ii = m_offset + i*(M + m_pad);		
+          int ii = m_offset + i*(M + m_pad);
 
-          for(int l = 0; l < N; l++)
+          for (int l = 0; l < N; l++)
           {
-            for(int k = 0; k < M; k++)
+            for (int k = 0; k < M; k++)
             {
-              m_ppSOM[jj+l][ii+k].Red = (double)prgbSrc[j][i].Red;
-              m_ppSOM[jj+l][ii+k].Green = (double)prgbSrc[j][i].Green;
-              m_ppSOM[jj+l][ii+k].Blue = (double)prgbSrc[j][i].Blue;
+              m_ppSOM[jj + l][ii + k].Red = (double)prgbSrc[j][i].Red;
+              m_ppSOM[jj + l][ii + k].Green = (double)prgbSrc[j][i].Green;
+              m_ppSOM[jj + l][ii + k].Blue = (double)prgbSrc[j][i].Blue;
             }
           }
         }
@@ -184,18 +184,18 @@ namespace lb_library
 
     void BGModelSom::Update()
     {
-      double alpha,a;
+      double alpha, a;
       double epsilon;
 
       // calibration phase
-      if(m_K <= m_TSteps)
-      {									
+      if (m_K <= m_TSteps)
+      {
         epsilon = m_epsilon1;
-        alpha = (m_alpha1-m_K*(m_alpha1-m_alpha2)/m_TSteps);
+        alpha = (m_alpha1 - m_K*(m_alpha1 - m_alpha2) / m_TSteps);
         m_K++;
       }
       else // online phase
-      {														
+      {
         epsilon = m_epsilon2;
         alpha = m_alpha2;
       }
@@ -204,11 +204,11 @@ namespace lb_library
       Image<BYTERGB> prgbBG(m_BGImage);
       Image<BYTERGB> prgbFG(m_FGImage);
 
-      for(int j = 0; j < m_height; j++)
+      for (int j = 0; j < m_height; j++)
       {
         int jj = m_offset + j*(N + m_pad);
 
-        for(int i = 0; i < m_width; i++)
+        for (int i = 0; i < m_width; i++)
         {
           int ii = m_offset + i*(M + m_pad);
 
@@ -222,17 +222,17 @@ namespace lb_library
           int iiHit = ii;
           int jjHit = jj;
 
-          for(int l = 0; l < N; l++)
+          for (int l = 0; l < N; l++)
           {
-            for(int k = 0; k < M; k++)
+            for (int k = 0; k < M; k++)
             {
-              double dr = srcR - m_ppSOM[jj+l][ii+k].Red;
-              double dg = srcG - m_ppSOM[jj+l][ii+k].Green;
-              double db = srcB - m_ppSOM[jj+l][ii+k].Blue;
+              double dr = srcR - m_ppSOM[jj + l][ii + k].Red;
+              double dg = srcG - m_ppSOM[jj + l][ii + k].Green;
+              double db = srcB - m_ppSOM[jj + l][ii + k].Blue;
 
               double d2 = dr*dr + dg*dg + db*db;
 
-              if(d2 < d2min)
+              if (d2 < d2min)
               {
                 d2min = d2;
                 iiHit = ii + k;
@@ -243,28 +243,28 @@ namespace lb_library
 
           // Update SOM
 
-          if(d2min <= epsilon) // matching model found 
+          if (d2min <= epsilon) // matching model found
           {
-            for(int l = (jjHit - m_offset); l <= (jjHit + m_offset); l++)
+            for (int l = (jjHit - m_offset); l <= (jjHit + m_offset); l++)
             {
-              for(int k = (iiHit - m_offset); k <= (iiHit + m_offset); k++)
+              for (int k = (iiHit - m_offset); k <= (iiHit + m_offset); k++)
               {
-                a = alpha*m_ppW[l-jjHit+m_offset][k-iiHit+m_offset];
+                a = alpha*m_ppW[l - jjHit + m_offset][k - iiHit + m_offset];
 
                 // speed hack.. avoid very small increment values. abs() is sloooow.
 
                 double d;
 
                 d = srcR - m_ppSOM[l][k].Red;
-                if(d*d > DBL_MIN)
+                if (d*d > DBL_MIN)
                   m_ppSOM[l][k].Red += a*d;
 
                 d = srcG - m_ppSOM[l][k].Green;
-                if(d*d > DBL_MIN)
+                if (d*d > DBL_MIN)
                   m_ppSOM[l][k].Green += a*d;
 
                 d = srcB - m_ppSOM[l][k].Blue;
-                if(d*d > DBL_MIN)
+                if (d*d > DBL_MIN)
                   m_ppSOM[l][k].Blue += a*d;
               }
             }
@@ -272,7 +272,7 @@ namespace lb_library
             // Set background image
             prgbBG[j][i].Red = m_ppSOM[jjHit][iiHit].Red;
             prgbBG[j][i].Green = m_ppSOM[jjHit][iiHit].Green;
-            prgbBG[j][i].Blue =  m_ppSOM[jjHit][iiHit].Blue;
+            prgbBG[j][i].Blue = m_ppSOM[jjHit][iiHit].Blue;
 
             // Set foreground image
             prgbFG[j][i].Red = prgbFG[j][i].Green = prgbFG[j][i].Blue = 0;
@@ -288,4 +288,4 @@ namespace lb_library
       return;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/package_bgs/lb/BGModelSom.h b/package_bgs/lb/BGModelSom.h
index dcd715819927d69ef0a3831637dea7f57264ca4e..0975b0b3e38d89a3e2b2e734e9c1d3c5bb4686ab 100644
--- a/package_bgs/lb/BGModelSom.h
+++ b/package_bgs/lb/BGModelSom.h
@@ -14,7 +14,7 @@ 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/>.
 */
-/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments  
+/*  Scene 1.0.1 -- Background subtraction and object tracking for complex environments
 BGModelSom.h
 
 Copyright (C) 2011 Laurence Bender <lbender@untref.edu.ar>
@@ -33,9 +33,7 @@ You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-
-#ifndef BGMODELSOM_H
-#define BGMODELSOM_H
+#pragma once
 
 #include "BGModel.h"
 
@@ -47,9 +45,9 @@ namespace lb_library
 
     const int M = 3;				// width SOM (per pixel)
     const int N = 3;				// height SOM (per pixel)
-    const int KERNEL = 3; 	// size Gaussian kernel 
+    const int KERNEL = 3; 	// size Gaussian kernel
 
-    const bool SPAN_NEIGHBORS = false; // true if update neighborhood spans different pixels			// 
+    const bool SPAN_NEIGHBORS = false; // true if update neighborhood spans different pixels			//
     const int TRAINING_STEPS = 100;			// number of training steps
 
     const float EPS1 = 100.0; // model match distance during training
@@ -81,12 +79,10 @@ namespace lb_library
       double m_alpha2;
 
       DBLRGB** m_ppSOM;					// SOM grid
-      double** m_ppW;						// Weights 
+      double** m_ppW;						// Weights
 
       void Init();
       void Update();
     };
   }
 }
-
-#endif
diff --git a/package_bgs/lb/Types.h b/package_bgs/lb/Types.h
index cb318a238b7ba97f0c455fbab3b4732f177d1031..bd59c41eaba01dc5f8642a7bf40c365f5c61758f 100644
--- a/package_bgs/lb/Types.h
+++ b/package_bgs/lb/Types.h
@@ -33,57 +33,55 @@ You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-
-#ifndef TYPES_H
-#define TYPES_H
+#pragma once
 
 #include <opencv2/opencv.hpp>
 
 namespace lb_library
 {
-  template<class T> class Image
-  {
-  private:
-    IplImage* imgp;
+template<class T> class Image
+{
+private:
+  IplImage* imgp;
 
-  public:
-    Image(IplImage* img=0) {imgp=img;}
-    ~Image(){imgp=0;}
+public:
+  Image(IplImage* img=0) {imgp=img;}
+  ~Image(){imgp=0;}
   
-    void operator=(IplImage* img) {imgp=img;}
+  void operator=(IplImage* img) {imgp=img;}
   
-    inline T* operator[](const int rowIndx)
-    {
-      return ((T *)(imgp->imageData + rowIndx*imgp->widthStep));
-    }
-  };
-
-  typedef struct{
-    unsigned char b,g,r;
-  } RgbPixel;
-
-  typedef struct{
-    unsigned char Blue,Green,Red;
-  } BYTERGB;
-
-  typedef struct{
-    unsigned int Blue,Green,Red;
-  } INTRGB;
-
-  typedef struct{
-    float b,g,r;
-  }RgbPixelFloat;
-
-  typedef struct{
-    double Blue,Green,Red;
-  } DBLRGB;
-
-  typedef Image<RgbPixel>       RgbImage;
-  typedef Image<RgbPixelFloat>  RgbImageFloat;
-  typedef Image<unsigned char>  BwImage;
-  typedef Image<float>          BwImageFloat;
-
-  /*
+  inline T* operator[](const int rowIndx)
+  {
+    return ((T *)(imgp->imageData + rowIndx*imgp->widthStep));
+  }
+};
+
+typedef struct{
+  unsigned char b,g,r;
+} RgbPixel;
+
+typedef struct{
+  unsigned char Blue,Green,Red;
+} BYTERGB;
+
+typedef struct{
+  unsigned int Blue,Green,Red;
+} INTRGB;
+
+typedef struct{
+  float b,g,r;
+}RgbPixelFloat;
+
+typedef struct{
+  double Blue,Green,Red;
+} DBLRGB;
+
+typedef Image<RgbPixel>       RgbImage;
+typedef Image<RgbPixelFloat>  RgbImageFloat;
+typedef Image<unsigned char>  BwImage;
+typedef Image<float>          BwImageFloat;
+
+/*
   IplImage* img = cvCreateImage(cvSize(640,480), IPL_DEPTH_32F, 3);
   RgbImageFloat imgA(img);
   for(int i = 0; i < m_height; i++)
@@ -93,7 +91,3 @@ namespace lb_library
       imgA[i][j].r = 111;
   */
 }
-
-//---------------------------------------------
-
-#endif
diff --git a/package_bgs/my/MyBGS.cpp b/package_bgs/my/MyBGS.cpp
deleted file mode 100644
index 07b51cde46b07c5da9e0ad19951d35aca191f771..0000000000000000000000000000000000000000
--- a/package_bgs/my/MyBGS.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-#include "MyBGS.h"
-
-MyBGS::MyBGS(){}
-MyBGS::~MyBGS(){}
-
-void MyBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
-{
-  if(img_input.empty())
-    return;
-
-  if(img_previous.empty())
-    img_input.copyTo(img_previous);
-
-  cv::Mat img_foreground;
-  cv::absdiff(img_previous, img_input, img_foreground);
-
-  if(img_foreground.channels() == 3)
-    cv::cvtColor(img_foreground, img_foreground, CV_BGR2GRAY);
-
-  cv::threshold(img_foreground, img_foreground, 15, 255, cv::THRESH_BINARY);
-
-  img_foreground.copyTo(img_output);
-  img_previous.copyTo(img_bgmodel);
-
-  img_input.copyTo(img_previous);
-}
diff --git a/package_bgs/my/MyBGS.h b/package_bgs/my/MyBGS.h
deleted file mode 100644
index fa27484aafd413343913720b7695695e916cd624..0000000000000000000000000000000000000000
--- a/package_bgs/my/MyBGS.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#pragma once
-
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-
-class MyBGS : public IBGS
-{
-private:
-  cv::Mat img_previous;
-  
-public:
-  MyBGS();
-  ~MyBGS();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig(){}
-  void loadConfig(){}
-};
\ No newline at end of file
diff --git a/package_bgs/pl/BackgroundSubtractorLBSP.cpp b/package_bgs/pl/BackgroundSubtractorLBSP.cpp
deleted file mode 100644
index 6752f76fa6cf94194d256c42c02c46ef7a4392b6..0000000000000000000000000000000000000000
--- a/package_bgs/pl/BackgroundSubtractorLBSP.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-#include "BackgroundSubtractorLBSP.h"
-#include "DistanceUtils.h"
-#include "RandUtils.h"
-#include <iostream>
-#include <opencv2/imgproc/imgproc.hpp>
-#include <opencv2/highgui/highgui.hpp>
-#include <iomanip>
-#include <exception>
-
-#ifndef SIZE_MAX
-# if __WORDSIZE == 64
-#  define SIZE_MAX		(18446744073709551615UL)
-# else
-#  define SIZE_MAX		(4294967295U)
-# endif
-#endif
-
-// local define used to determine the default median blur kernel size
-#define DEFAULT_MEDIAN_BLUR_KERNEL_SIZE (9)
-
-BackgroundSubtractorLBSP::BackgroundSubtractorLBSP(float fRelLBSPThreshold, size_t nLBSPThresholdOffset)
-	:	 m_nImgChannels(0)
-		,m_nImgType(0)
-		,m_nLBSPThresholdOffset(nLBSPThresholdOffset)
-		,m_fRelLBSPThreshold(fRelLBSPThreshold)
-		,m_nTotPxCount(0)
-		,m_nTotRelevantPxCount(0)
-		,m_nFrameIndex(SIZE_MAX)
-		,m_nFramesSinceLastReset(0)
-		,m_nModelResetCooldown(0)
-		,m_aPxIdxLUT(nullptr)
-		,m_aPxInfoLUT(nullptr)
-		,m_nDefaultMedianBlurKernelSize(DEFAULT_MEDIAN_BLUR_KERNEL_SIZE)
-		,m_bInitialized(false)
-		,m_bAutoModelResetEnabled(true)
-		,m_bUsingMovingCamera(false)
-		,nDebugCoordX(0),nDebugCoordY(0) {
-	CV_Assert(m_fRelLBSPThreshold>=0);
-}
-
-BackgroundSubtractorLBSP::~BackgroundSubtractorLBSP() {}
-
-void BackgroundSubtractorLBSP::initialize(const cv::Mat& oInitImg) {
-	this->initialize(oInitImg,cv::Mat());
-}
-
-/*cv::AlgorithmInfo* BackgroundSubtractorLBSP::info() const {
-	return nullptr;
-}*/
-
-cv::Mat BackgroundSubtractorLBSP::getROICopy() const {
-	return m_oROI.clone();
-}
-
-void BackgroundSubtractorLBSP::setROI(cv::Mat& oROI) {
-	LBSP::validateROI(oROI);
-	CV_Assert(cv::countNonZero(oROI)>0);
-	if(m_bInitialized) {
-		cv::Mat oLatestBackgroundImage;
-		getBackgroundImage(oLatestBackgroundImage);
-		initialize(oLatestBackgroundImage,oROI);
-	}
-	else
-		m_oROI = oROI.clone();
-}
-
-void BackgroundSubtractorLBSP::setAutomaticModelReset(bool bVal) {
-	m_bAutoModelResetEnabled = bVal;
-}
diff --git a/package_bgs/pl/BackgroundSubtractorLBSP.h b/package_bgs/pl/BackgroundSubtractorLBSP.h
deleted file mode 100644
index 5602d349f039da4ebdd4f581d1c2ee4e6e19a9a9..0000000000000000000000000000000000000000
--- a/package_bgs/pl/BackgroundSubtractorLBSP.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#pragma once
-
-#include <opencv2/features2d/features2d.hpp>
-#include <opencv2/video/background_segm.hpp>
-#include "LBSP.h"
-
-/*!
-	Local Binary Similarity Pattern (LBSP)-based change detection algorithm (abstract version/base class).
-
-	For more details on the different parameters, see P.-L. St-Charles and G.-A. Bilodeau, "Improving Background
-	Subtraction using Local Binary Similarity Patterns", in WACV 2014, or G.-A. Bilodeau et al, "Change Detection
-	in Feature Space Using Local Binary Similarity Patterns", in CRV 2013.
-
-	This algorithm is currently NOT thread-safe.
- */
-class BackgroundSubtractorLBSP : public cv::BackgroundSubtractor {
-public:
-	//! full constructor
-	BackgroundSubtractorLBSP(float fRelLBSPThreshold, size_t nLBSPThresholdOffset=0);
-	//! default destructor
-	virtual ~BackgroundSubtractorLBSP();
-	//! (re)initiaization method; needs to be called before starting background subtraction
-	virtual void initialize(const cv::Mat& oInitImg);
-	//! (re)initiaization method; needs to be called before starting background subtraction
-	virtual void initialize(const cv::Mat& oInitImg, const cv::Mat& oROI)=0;
-	//! primary model update function; the learning param is used to override the internal learning speed (ignored when <= 0)
-	virtual void operator()(cv::InputArray image, cv::OutputArray fgmask, double learningRate=0)=0;
-	//! unused, always returns nullptr
-	//virtual cv::AlgorithmInfo* info() const;
-	//! returns a copy of the ROI used for descriptor extraction
-	virtual cv::Mat getROICopy() const;
-	//! sets the ROI to be used for descriptor extraction (note: this function will reinit the model and return the usable ROI)
-	virtual void setROI(cv::Mat& oROI);
-	//! turns automatic model reset on or off
-	void setAutomaticModelReset(bool);
-
-protected:
-	struct PxInfoBase {
-		int nImgCoord_Y;
-		int nImgCoord_X;
-		size_t nModelIdx;
-	};
-	//! background model ROI used for LBSP descriptor extraction (specific to the input image size)
-	cv::Mat m_oROI;
-	//! input image size
-	cv::Size m_oImgSize;
-	//! input image channel size
-	size_t m_nImgChannels;
-	//! input image type
-	int m_nImgType;
-	//! LBSP internal threshold offset value, used to reduce texture noise in dark regions
-	const size_t m_nLBSPThresholdOffset;
-	//! LBSP relative internal threshold (kept here since we don't keep an LBSP object)
-	const float m_fRelLBSPThreshold;
-	//! total number of pixels (depends on the input frame size) & total number of relevant pixels
-	size_t m_nTotPxCount, m_nTotRelevantPxCount;
-	//! current frame index, frame count since last model reset & model reset cooldown counters
-	size_t m_nFrameIndex, m_nFramesSinceLastReset, m_nModelResetCooldown;
-	//! pre-allocated internal LBSP threshold values LUT for all possible 8-bit intensities
-	size_t m_anLBSPThreshold_8bitLUT[UCHAR_MAX+1];
-	//! internal pixel index LUT for all relevant analysis regions (based on the provided ROI)
-	size_t* m_aPxIdxLUT;
-	//! internal pixel info LUT for all possible pixel indexes
-	PxInfoBase* m_aPxInfoLUT;
-	//! default kernel size for median blur post-proc filtering
-	const int m_nDefaultMedianBlurKernelSize;
-	//! specifies whether the algorithm is fully initialized or not
-	bool m_bInitialized;
-	//! specifies whether automatic model resets are enabled or not
-	bool m_bAutoModelResetEnabled;
-	//! specifies whether the camera is considered moving or not
-	bool m_bUsingMovingCamera;
-	//! copy of latest pixel intensities (used when refreshing model)
-	cv::Mat m_oLastColorFrame;
-	//! copy of latest descriptors (used when refreshing model)
-	cv::Mat m_oLastDescFrame;
-	//! the foreground mask generated by the method at [t-1]
-	cv::Mat m_oLastFGMask;
-
-public:
-	// ######## DEBUG PURPOSES ONLY ##########
-	int nDebugCoordX, nDebugCoordY;
-	std::string sDebugName;
-};
-
diff --git a/package_bgs/pl/BackgroundSubtractorLOBSTER.cpp b/package_bgs/pl/BackgroundSubtractorLOBSTER.cpp
deleted file mode 100644
index 78938ad347805703f1c9a975c886e32b0467eaed..0000000000000000000000000000000000000000
--- a/package_bgs/pl/BackgroundSubtractorLOBSTER.cpp
+++ /dev/null
@@ -1,326 +0,0 @@
-#include "BackgroundSubtractorLOBSTER.h"
-#include "DistanceUtils.h"
-#include "RandUtils.h"
-#include <iostream>
-#include <opencv2/imgproc/imgproc.hpp>
-#include <opencv2/highgui/highgui.hpp>
-#include <iomanip>
-
-BackgroundSubtractorLOBSTER::BackgroundSubtractorLOBSTER(	 float fRelLBSPThreshold
-															,size_t nLBSPThresholdOffset
-															,size_t nDescDistThreshold
-															,size_t nColorDistThreshold
-															,size_t nBGSamples
-															,size_t nRequiredBGSamples)
-	:	 BackgroundSubtractorLBSP(fRelLBSPThreshold,nLBSPThresholdOffset)
-		,m_nColorDistThreshold(nColorDistThreshold)
-		,m_nDescDistThreshold(nDescDistThreshold)
-		,m_nBGSamples(nBGSamples)
-		,m_nRequiredBGSamples(nRequiredBGSamples) {
-	CV_Assert(m_nRequiredBGSamples<=m_nBGSamples);
-	m_bAutoModelResetEnabled = false; // @@@@@@ not supported here for now
-}
-
-BackgroundSubtractorLOBSTER::~BackgroundSubtractorLOBSTER() {
-	if(m_aPxIdxLUT)
-		delete[] m_aPxIdxLUT;
-	if(m_aPxInfoLUT)
-	    delete[] m_aPxInfoLUT;
-}
-
-void BackgroundSubtractorLOBSTER::initialize(const cv::Mat& oInitImg, const cv::Mat& oROI) {
-	CV_Assert(!oInitImg.empty() && oInitImg.cols>0 && oInitImg.rows>0);
-	CV_Assert(oInitImg.isContinuous());
-	CV_Assert(oInitImg.type()==CV_8UC1 || oInitImg.type()==CV_8UC3);
-	if(oInitImg.type()==CV_8UC3) {
-		std::vector<cv::Mat> voInitImgChannels;
-		cv::split(oInitImg,voInitImgChannels);
-		if(!cv::countNonZero((voInitImgChannels[0]!=voInitImgChannels[1])|(voInitImgChannels[2]!=voInitImgChannels[1])))
-			std::cout << std::endl << "\tBackgroundSubtractorLOBSTER : Warning, grayscale images should always be passed in CV_8UC1 format for optimal performance." << std::endl;
-	}
-	cv::Mat oNewBGROI;
-	if(oROI.empty() && (m_oROI.empty() || oROI.size()!=oInitImg.size())) {
-		oNewBGROI.create(oInitImg.size(),CV_8UC1);
-		oNewBGROI = cv::Scalar_<uchar>(UCHAR_MAX);
-	}
-	else if(oROI.empty())
-		oNewBGROI = m_oROI;
-	else {
-		CV_Assert(oROI.size()==oInitImg.size() && oROI.type()==CV_8UC1);
-		CV_Assert(cv::countNonZero((oROI<UCHAR_MAX)&(oROI>0))==0);
-		oNewBGROI = oROI.clone();
-	}
-	LBSP::validateROI(oNewBGROI);
-	const size_t nROIPxCount = (size_t)cv::countNonZero(oNewBGROI);
-	CV_Assert(nROIPxCount>0);
-	m_oROI = oNewBGROI;
-	m_oImgSize = oInitImg.size();
-	m_nImgType = oInitImg.type();
-	m_nImgChannels = oInitImg.channels();
-	m_nTotPxCount = m_oImgSize.area();
-	m_nTotRelevantPxCount = nROIPxCount;
-	m_nFrameIndex = 0;
-	m_nFramesSinceLastReset = 0;
-	m_nModelResetCooldown = 0;
-	m_oLastFGMask.create(m_oImgSize,CV_8UC1);
-	m_oLastFGMask = cv::Scalar_<uchar>(0);
-	m_oLastColorFrame.create(m_oImgSize,CV_8UC((int)m_nImgChannels));
-	m_oLastColorFrame = cv::Scalar_<uchar>::all(0);
-	m_oLastDescFrame.create(m_oImgSize,CV_16UC((int)m_nImgChannels));
-	m_oLastDescFrame = cv::Scalar_<ushort>::all(0);
-	m_voBGColorSamples.resize(m_nBGSamples);
-	m_voBGDescSamples.resize(m_nBGSamples);
-	for(size_t s=0; s<m_nBGSamples; ++s) {
-		m_voBGColorSamples[s].create(m_oImgSize,CV_8UC((int)m_nImgChannels));
-		m_voBGColorSamples[s] = cv::Scalar_<uchar>::all(0);
-		m_voBGDescSamples[s].create(m_oImgSize,CV_16UC((int)m_nImgChannels));
-		m_voBGDescSamples[s] = cv::Scalar_<ushort>::all(0);
-	}
-	if(m_aPxIdxLUT)
-		delete[] m_aPxIdxLUT;
-	if(m_aPxInfoLUT)
-	    delete[] m_aPxInfoLUT;
-	m_aPxIdxLUT = new size_t[m_nTotRelevantPxCount];
-	m_aPxInfoLUT = new PxInfoBase[m_nTotPxCount];
-	if(m_nImgChannels==1) {
-		CV_Assert(m_oLastColorFrame.step.p[0]==(size_t)m_oImgSize.width && m_oLastColorFrame.step.p[1]==1);
-		CV_Assert(m_oLastDescFrame.step.p[0]==m_oLastColorFrame.step.p[0]*2 && m_oLastDescFrame.step.p[1]==m_oLastColorFrame.step.p[1]*2);
-		for(size_t t=0; t<=UCHAR_MAX; ++t)
-			m_anLBSPThreshold_8bitLUT[t] = cv::saturate_cast<uchar>((t*m_fRelLBSPThreshold+m_nLBSPThresholdOffset)/2);
-		for(size_t nPxIter=0, nModelIter=0; nPxIter<m_nTotPxCount; ++nPxIter) {
-			if(m_oROI.data[nPxIter]) {
-				m_aPxIdxLUT[nModelIter] = nPxIter;
-				m_aPxInfoLUT[nPxIter].nImgCoord_Y = (int)nPxIter/m_oImgSize.width;
-				m_aPxInfoLUT[nPxIter].nImgCoord_X = (int)nPxIter%m_oImgSize.width;
-				m_aPxInfoLUT[nPxIter].nModelIdx = nModelIter;
-				m_oLastColorFrame.data[nPxIter] = oInitImg.data[nPxIter];
-				const size_t nDescIter = nPxIter*2;
-				LBSP::computeGrayscaleDescriptor(oInitImg,oInitImg.data[nPxIter],m_aPxInfoLUT[nPxIter].nImgCoord_X,m_aPxInfoLUT[nPxIter].nImgCoord_Y,m_anLBSPThreshold_8bitLUT[oInitImg.data[nPxIter]],*((ushort*)(m_oLastDescFrame.data+nDescIter)));
-				++nModelIter;
-			}
-		}
-	}
-	else { //m_nImgChannels==3
-		CV_Assert(m_oLastColorFrame.step.p[0]==(size_t)m_oImgSize.width*3 && m_oLastColorFrame.step.p[1]==3);
-		CV_Assert(m_oLastDescFrame.step.p[0]==m_oLastColorFrame.step.p[0]*2 && m_oLastDescFrame.step.p[1]==m_oLastColorFrame.step.p[1]*2);
-		for(size_t t=0; t<=UCHAR_MAX; ++t)
-			m_anLBSPThreshold_8bitLUT[t] = cv::saturate_cast<uchar>(t*m_fRelLBSPThreshold+m_nLBSPThresholdOffset);
-		for(size_t nPxIter=0, nModelIter=0; nPxIter<m_nTotPxCount; ++nPxIter) {
-			if(m_oROI.data[nPxIter]) {
-				m_aPxIdxLUT[nModelIter] = nPxIter;
-				m_aPxInfoLUT[nPxIter].nImgCoord_Y = (int)nPxIter/m_oImgSize.width;
-				m_aPxInfoLUT[nPxIter].nImgCoord_X = (int)nPxIter%m_oImgSize.width;
-				m_aPxInfoLUT[nPxIter].nModelIdx = nModelIter;
-				const size_t nPxRGBIter = nPxIter*3;
-				const size_t nDescRGBIter = nPxRGBIter*2;
-				for(size_t c=0; c<3; ++c) {
-					m_oLastColorFrame.data[nPxRGBIter+c] = oInitImg.data[nPxRGBIter+c];
-					LBSP::computeSingleRGBDescriptor(oInitImg,oInitImg.data[nPxRGBIter+c],m_aPxInfoLUT[nPxIter].nImgCoord_X,m_aPxInfoLUT[nPxIter].nImgCoord_Y,c,m_anLBSPThreshold_8bitLUT[oInitImg.data[nPxRGBIter+c]],((ushort*)(m_oLastDescFrame.data+nDescRGBIter))[c]);
-				}
-				++nModelIter;
-			}
-		}
-	}
-	m_bInitialized = true;
-	refreshModel(1.0f);
-}
-
-void BackgroundSubtractorLOBSTER::refreshModel(float fSamplesRefreshFrac, bool bForceFGUpdate) {
-	// == refresh
-	CV_Assert(m_bInitialized);
-	CV_Assert(fSamplesRefreshFrac>0.0f && fSamplesRefreshFrac<=1.0f);
-	const size_t nModelsToRefresh = fSamplesRefreshFrac<1.0f?(size_t)(fSamplesRefreshFrac*m_nBGSamples):m_nBGSamples;
-	const size_t nRefreshStartPos = fSamplesRefreshFrac<1.0f?rand()%m_nBGSamples:0;
-	if(m_nImgChannels==1) {
-		for(size_t nModelIter=0; nModelIter<m_nTotRelevantPxCount; ++nModelIter) {
-			const size_t nPxIter = m_aPxIdxLUT[nModelIter];
-			if(bForceFGUpdate || !m_oLastFGMask.data[nPxIter]) {
-				for(size_t nCurrModelIdx=nRefreshStartPos; nCurrModelIdx<nRefreshStartPos+nModelsToRefresh; ++nCurrModelIdx) {
-					int nSampleImgCoord_Y, nSampleImgCoord_X;
-					getRandSamplePosition(nSampleImgCoord_X,nSampleImgCoord_Y,m_aPxInfoLUT[nPxIter].nImgCoord_X,m_aPxInfoLUT[nPxIter].nImgCoord_Y,LBSP::PATCH_SIZE/2,m_oImgSize);
-					const size_t nSamplePxIdx = m_oImgSize.width*nSampleImgCoord_Y + nSampleImgCoord_X;
-					if(bForceFGUpdate || !m_oLastFGMask.data[nSamplePxIdx]) {
-						const size_t nCurrRealModelIdx = nCurrModelIdx%m_nBGSamples;
-						m_voBGColorSamples[nCurrRealModelIdx].data[nPxIter] = m_oLastColorFrame.data[nSamplePxIdx];
-						*((ushort*)(m_voBGDescSamples[nCurrRealModelIdx].data+nPxIter*2)) = *((ushort*)(m_oLastDescFrame.data+nSamplePxIdx*2));
-					}
-				}
-			}
-		}
-	}
-	else { //m_nImgChannels==3
-		for(size_t nModelIter=0; nModelIter<m_nTotRelevantPxCount; ++nModelIter) {
-			const size_t nPxIter = m_aPxIdxLUT[nModelIter];
-			if(bForceFGUpdate || !m_oLastFGMask.data[nPxIter]) {
-				for(size_t nCurrModelIdx=nRefreshStartPos; nCurrModelIdx<nRefreshStartPos+nModelsToRefresh; ++nCurrModelIdx) {
-					int nSampleImgCoord_Y, nSampleImgCoord_X;
-					getRandSamplePosition(nSampleImgCoord_X,nSampleImgCoord_Y,m_aPxInfoLUT[nPxIter].nImgCoord_X,m_aPxInfoLUT[nPxIter].nImgCoord_Y,LBSP::PATCH_SIZE/2,m_oImgSize);
-					const size_t nSamplePxIdx = m_oImgSize.width*nSampleImgCoord_Y + nSampleImgCoord_X;
-					if(bForceFGUpdate || !m_oLastFGMask.data[nSamplePxIdx]) {
-						const size_t nCurrRealModelIdx = nCurrModelIdx%m_nBGSamples;
-						for(size_t c=0; c<3; ++c) {
-							m_voBGColorSamples[nCurrRealModelIdx].data[nPxIter*3+c] = m_oLastColorFrame.data[nSamplePxIdx*3+c];
-							*((ushort*)(m_voBGDescSamples[nCurrRealModelIdx].data+(nPxIter*3+c)*2)) = *((ushort*)(m_oLastDescFrame.data+(nSamplePxIdx*3+c)*2));
-						}
-					}
-				}
-			}
-		}
-	}
-}
-
-void BackgroundSubtractorLOBSTER::operator()(cv::InputArray _image, cv::OutputArray _fgmask, double learningRate) {
-	CV_Assert(m_bInitialized);
-	CV_Assert(learningRate>0);
-	cv::Mat oInputImg = _image.getMat();
-	CV_Assert(oInputImg.type()==m_nImgType && oInputImg.size()==m_oImgSize);
-	CV_Assert(oInputImg.isContinuous());
-	_fgmask.create(m_oImgSize,CV_8UC1);
-	cv::Mat oCurrFGMask = _fgmask.getMat();
-	oCurrFGMask = cv::Scalar_<uchar>(0);
-	const size_t nLearningRate = (size_t)ceil(learningRate);
-	if(m_nImgChannels==1) {
-		for(size_t nModelIter=0; nModelIter<m_nTotRelevantPxCount; ++nModelIter) {
-			const size_t nPxIter = m_aPxIdxLUT[nModelIter];
-			const size_t nDescIter = nPxIter*2;
-			const int nCurrImgCoord_X = m_aPxInfoLUT[nPxIter].nImgCoord_X;
-			const int nCurrImgCoord_Y = m_aPxInfoLUT[nPxIter].nImgCoord_Y;
-			const uchar nCurrColor = oInputImg.data[nPxIter];
-			size_t nGoodSamplesCount=0, nModelIdx=0;
-			ushort nCurrInputDesc;
-			while(nGoodSamplesCount<m_nRequiredBGSamples && nModelIdx<m_nBGSamples) {
-				const uchar nBGColor = m_voBGColorSamples[nModelIdx].data[nPxIter];
-				{
-					const size_t nColorDist = L1dist(nCurrColor,nBGColor);
-					if(nColorDist>m_nColorDistThreshold/2)
-						goto failedcheck1ch;
-					LBSP::computeGrayscaleDescriptor(oInputImg,nBGColor,nCurrImgCoord_X,nCurrImgCoord_Y,m_anLBSPThreshold_8bitLUT[nBGColor],nCurrInputDesc);
-					const size_t nDescDist = hdist(nCurrInputDesc,*((ushort*)(m_voBGDescSamples[nModelIdx].data+nDescIter)));
-					if(nDescDist>m_nDescDistThreshold)
-						goto failedcheck1ch;
-					nGoodSamplesCount++;
-				}
-				failedcheck1ch:
-				nModelIdx++;
-			}
-			if(nGoodSamplesCount<m_nRequiredBGSamples)
-				oCurrFGMask.data[nPxIter] = UCHAR_MAX;
-			else {
-				if((rand()%nLearningRate)==0) {
-					const size_t nSampleModelIdx = rand()%m_nBGSamples;
-					ushort& nRandInputDesc = *((ushort*)(m_voBGDescSamples[nSampleModelIdx].data+nDescIter));
-					LBSP::computeGrayscaleDescriptor(oInputImg,nCurrColor,nCurrImgCoord_X,nCurrImgCoord_Y,m_anLBSPThreshold_8bitLUT[nCurrColor],nRandInputDesc);
-					m_voBGColorSamples[nSampleModelIdx].data[nPxIter] = nCurrColor;
-				}
-				if((rand()%nLearningRate)==0) {
-					int nSampleImgCoord_Y, nSampleImgCoord_X;
-					getRandNeighborPosition_3x3(nSampleImgCoord_X,nSampleImgCoord_Y,nCurrImgCoord_X,nCurrImgCoord_Y,LBSP::PATCH_SIZE/2,m_oImgSize);
-					const size_t nSampleModelIdx = rand()%m_nBGSamples;
-					ushort& nRandInputDesc = m_voBGDescSamples[nSampleModelIdx].at<ushort>(nSampleImgCoord_Y,nSampleImgCoord_X);
-					LBSP::computeGrayscaleDescriptor(oInputImg,nCurrColor,nCurrImgCoord_X,nCurrImgCoord_Y,m_anLBSPThreshold_8bitLUT[nCurrColor],nRandInputDesc);
-					m_voBGColorSamples[nSampleModelIdx].at<uchar>(nSampleImgCoord_Y,nSampleImgCoord_X) = nCurrColor;
-				}
-			}
-		}
-	}
-	else { //m_nImgChannels==3
-		const size_t nCurrDescDistThreshold = m_nDescDistThreshold*3;
-		const size_t nCurrColorDistThreshold = m_nColorDistThreshold*3;
-		const size_t nCurrSCDescDistThreshold = nCurrDescDistThreshold/2;
-		const size_t nCurrSCColorDistThreshold = nCurrColorDistThreshold/2;
-		const size_t desc_row_step = m_voBGDescSamples[0].step.p[0];
-		const size_t img_row_step = m_voBGColorSamples[0].step.p[0];
-		for(size_t nModelIter=0; nModelIter<m_nTotRelevantPxCount; ++nModelIter) {
-			const size_t nPxIter = m_aPxIdxLUT[nModelIter];
-			const int nCurrImgCoord_X = m_aPxInfoLUT[nPxIter].nImgCoord_X;
-			const int nCurrImgCoord_Y = m_aPxInfoLUT[nPxIter].nImgCoord_Y;
-			const size_t nPxIterRGB = nPxIter*3;
-			const size_t nDescIterRGB = nPxIterRGB*2;
-			const uchar* const anCurrColor = oInputImg.data+nPxIterRGB;
-			size_t nGoodSamplesCount=0, nModelIdx=0;
-			ushort anCurrInputDesc[3];
-			while(nGoodSamplesCount<m_nRequiredBGSamples && nModelIdx<m_nBGSamples) {
-				const ushort* const anBGDesc = (ushort*)(m_voBGDescSamples[nModelIdx].data+nDescIterRGB);
-				const uchar* const anBGColor = m_voBGColorSamples[nModelIdx].data+nPxIterRGB;
-				size_t nTotColorDist = 0;
-				size_t nTotDescDist = 0;
-				for(size_t c=0;c<3; ++c) {
-					const size_t nColorDist = L1dist(anCurrColor[c],anBGColor[c]);
-					if(nColorDist>nCurrSCColorDistThreshold)
-						goto failedcheck3ch;
-					LBSP::computeSingleRGBDescriptor(oInputImg,anBGColor[c],nCurrImgCoord_X,nCurrImgCoord_Y,c,m_anLBSPThreshold_8bitLUT[anBGColor[c]],anCurrInputDesc[c]);
-					const size_t nDescDist = hdist(anCurrInputDesc[c],anBGDesc[c]);
-					if(nDescDist>nCurrSCDescDistThreshold)
-						goto failedcheck3ch;
-					nTotColorDist += nColorDist;
-					nTotDescDist += nDescDist;
-				}
-				if(nTotDescDist<=nCurrDescDistThreshold && nTotColorDist<=nCurrColorDistThreshold)
-					nGoodSamplesCount++;
-				failedcheck3ch:
-				nModelIdx++;
-			}
-			if(nGoodSamplesCount<m_nRequiredBGSamples)
-				oCurrFGMask.data[nPxIter] = UCHAR_MAX;
-			else {
-				if((rand()%nLearningRate)==0) {
-					const size_t nSampleModelIdx = rand()%m_nBGSamples;
-					ushort* anRandInputDesc = ((ushort*)(m_voBGDescSamples[nSampleModelIdx].data+nDescIterRGB));
-					const size_t anCurrIntraLBSPThresholds[3] = {m_anLBSPThreshold_8bitLUT[anCurrColor[0]],m_anLBSPThreshold_8bitLUT[anCurrColor[1]],m_anLBSPThreshold_8bitLUT[anCurrColor[2]]};
-					LBSP::computeRGBDescriptor(oInputImg,anCurrColor,nCurrImgCoord_X,nCurrImgCoord_Y,anCurrIntraLBSPThresholds,anRandInputDesc);
-					for(size_t c=0; c<3; ++c)
-						*(m_voBGColorSamples[nSampleModelIdx].data+nPxIterRGB+c) = anCurrColor[c];
-				}
-				if((rand()%nLearningRate)==0) {
-					int nSampleImgCoord_Y, nSampleImgCoord_X;
-					getRandNeighborPosition_3x3(nSampleImgCoord_X,nSampleImgCoord_Y,nCurrImgCoord_X,nCurrImgCoord_Y,LBSP::PATCH_SIZE/2,m_oImgSize);
-					const size_t nSampleModelIdx = rand()%m_nBGSamples;
-					ushort* anRandInputDesc = ((ushort*)(m_voBGDescSamples[nSampleModelIdx].data + desc_row_step*nSampleImgCoord_Y + 6*nSampleImgCoord_X));
-					const size_t anCurrIntraLBSPThresholds[3] = {m_anLBSPThreshold_8bitLUT[anCurrColor[0]],m_anLBSPThreshold_8bitLUT[anCurrColor[1]],m_anLBSPThreshold_8bitLUT[anCurrColor[2]]};
-					LBSP::computeRGBDescriptor(oInputImg,anCurrColor,nCurrImgCoord_X,nCurrImgCoord_Y,anCurrIntraLBSPThresholds,anRandInputDesc);
-					for(size_t c=0; c<3; ++c)
-						*(m_voBGColorSamples[nSampleModelIdx].data + img_row_step*nSampleImgCoord_Y + 3*nSampleImgCoord_X + c) = anCurrColor[c];
-				}
-			}
-		}
-	}
-	cv::medianBlur(oCurrFGMask,m_oLastFGMask,m_nDefaultMedianBlurKernelSize);
-	m_oLastFGMask.copyTo(oCurrFGMask);
-}
-
-void BackgroundSubtractorLOBSTER::getBackgroundImage(cv::OutputArray backgroundImage) const {
-	CV_DbgAssert(m_bInitialized);
-	cv::Mat oAvgBGImg = cv::Mat::zeros(m_oImgSize,CV_32FC((int)m_nImgChannels));
-	for(size_t s=0; s<m_nBGSamples; ++s) {
-		for(int y=0; y<m_oImgSize.height; ++y) {
-			for(int x=0; x<m_oImgSize.width; ++x) {
-				const size_t idx_nimg = m_voBGColorSamples[s].step.p[0]*y + m_voBGColorSamples[s].step.p[1]*x;
-				const size_t idx_flt32 = idx_nimg*4;
-				float* oAvgBgImgPtr = (float*)(oAvgBGImg.data+idx_flt32);
-				const uchar* const oBGImgPtr = m_voBGColorSamples[s].data+idx_nimg;
-				for(size_t c=0; c<m_nImgChannels; ++c)
-					oAvgBgImgPtr[c] += ((float)oBGImgPtr[c])/m_nBGSamples;
-			}
-		}
-	}
-	oAvgBGImg.convertTo(backgroundImage,CV_8U);
-}
-
-void BackgroundSubtractorLOBSTER::getBackgroundDescriptorsImage(cv::OutputArray backgroundDescImage) const {
-	CV_Assert(LBSP::DESC_SIZE==2);
-	CV_Assert(m_bInitialized);
-	cv::Mat oAvgBGDesc = cv::Mat::zeros(m_oImgSize,CV_32FC((int)m_nImgChannels));
-	for(size_t n=0; n<m_voBGDescSamples.size(); ++n) {
-		for(int y=0; y<m_oImgSize.height; ++y) {
-			for(int x=0; x<m_oImgSize.width; ++x) {
-				const size_t idx_ndesc = m_voBGDescSamples[n].step.p[0]*y + m_voBGDescSamples[n].step.p[1]*x;
-				const size_t idx_flt32 = idx_ndesc*2;
-				float* oAvgBgDescPtr = (float*)(oAvgBGDesc.data+idx_flt32);
-				const ushort* const oBGDescPtr = (ushort*)(m_voBGDescSamples[n].data+idx_ndesc);
-				for(size_t c=0; c<m_nImgChannels; ++c)
-					oAvgBgDescPtr[c] += ((float)oBGDescPtr[c])/m_voBGDescSamples.size();
-			}
-		}
-	}
-	oAvgBGDesc.convertTo(backgroundDescImage,CV_16U);
-}
diff --git a/package_bgs/pl/BackgroundSubtractorLOBSTER.h b/package_bgs/pl/BackgroundSubtractorLOBSTER.h
deleted file mode 100644
index bedc55d1cedccba3a2993f40de48ac056b67a8d3..0000000000000000000000000000000000000000
--- a/package_bgs/pl/BackgroundSubtractorLOBSTER.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#pragma once
-
-#include "BackgroundSubtractorLBSP.h"
-
-//! defines the default value for BackgroundSubtractorLBSP::m_fRelLBSPThreshold
-#define BGSLOBSTER_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD (0.365f)
-//! defines the default value for BackgroundSubtractorLBSP::m_nLBSPThresholdOffset
-#define BGSLOBSTER_DEFAULT_LBSP_OFFSET_SIMILARITY_THRESHOLD (0)
-//! defines the default value for BackgroundSubtractorLOBSTER::m_nDescDistThreshold
-#define BGSLOBSTER_DEFAULT_DESC_DIST_THRESHOLD (4)
-//! defines the default value for BackgroundSubtractorLOBSTER::m_nColorDistThreshold
-#define BGSLOBSTER_DEFAULT_COLOR_DIST_THRESHOLD (30)
-//! defines the default value for BackgroundSubtractorLOBSTER::m_nBGSamples
-#define BGSLOBSTER_DEFAULT_NB_BG_SAMPLES (35)
-//! defines the default value for BackgroundSubtractorLOBSTER::m_nRequiredBGSamples
-#define BGSLOBSTER_DEFAULT_REQUIRED_NB_BG_SAMPLES (2)
-//! defines the default value for the learning rate passed to BackgroundSubtractorLOBSTER::operator()
-#define BGSLOBSTER_DEFAULT_LEARNING_RATE (16)
-
-/*!
-	LOcal Binary Similarity segmenTER (LOBSTER) change detection algorithm.
-
-	Note: both grayscale and RGB/BGR images may be used with this extractor (parameters are adjusted automatically).
-	For optimal grayscale results, use CV_8UC1 frames instead of CV_8UC3.
-
-	For more details on the different parameters or on the algorithm itself, see P.-L. St-Charles and
-	G.-A. Bilodeau, "Improving Background Subtraction using Local Binary Similarity Patterns", in WACV 2014.
-
-	This algorithm is currently NOT thread-safe.
- */
-class BackgroundSubtractorLOBSTER : public BackgroundSubtractorLBSP {
-public:
-	//! full constructor
-	BackgroundSubtractorLOBSTER(float fRelLBSPThreshold=BGSLOBSTER_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD,
-								size_t nLBSPThresholdOffset=BGSLOBSTER_DEFAULT_LBSP_OFFSET_SIMILARITY_THRESHOLD,
-								size_t nDescDistThreshold=BGSLOBSTER_DEFAULT_DESC_DIST_THRESHOLD,
-								size_t nColorDistThreshold=BGSLOBSTER_DEFAULT_COLOR_DIST_THRESHOLD,
-								size_t nBGSamples=BGSLOBSTER_DEFAULT_NB_BG_SAMPLES,
-								size_t nRequiredBGSamples=BGSLOBSTER_DEFAULT_REQUIRED_NB_BG_SAMPLES);
-	//! default destructor
-	virtual ~BackgroundSubtractorLOBSTER();
-	//! (re)initiaization method; needs to be called before starting background subtraction
-	virtual void initialize(const cv::Mat& oInitImg, const cv::Mat& oROI);
-	//! refreshes all samples based on the last analyzed frame
-	virtual void refreshModel(float fSamplesRefreshFrac, bool bForceFGUpdate=false);
-	//! primary model update function; the learning param is reinterpreted as an integer and should be > 0 (smaller values == faster adaptation)
-	virtual void operator()(cv::InputArray image, cv::OutputArray fgmask, double learningRate=BGSLOBSTER_DEFAULT_LEARNING_RATE);
-	//! returns a copy of the latest reconstructed background image
-	void getBackgroundImage(cv::OutputArray backgroundImage) const;
-	//! returns a copy of the latest reconstructed background descriptors image
-	virtual void getBackgroundDescriptorsImage(cv::OutputArray backgroundDescImage) const;
-
-protected:
-	//! absolute color distance threshold
-	const size_t m_nColorDistThreshold;
-	//! absolute descriptor distance threshold
-	const size_t m_nDescDistThreshold;
-	//! number of different samples per pixel/block to be taken from input frames to build the background model
-	const size_t m_nBGSamples;
-	//! number of similar samples needed to consider the current pixel/block as 'background'
-	const size_t m_nRequiredBGSamples;
-	//! background model pixel intensity samples
-	std::vector<cv::Mat> m_voBGColorSamples;
-	//! background model descriptors samples
-	std::vector<cv::Mat> m_voBGDescSamples;
-};
-
diff --git a/package_bgs/pl/BackgroundSubtractorSuBSENSE.cpp b/package_bgs/pl/BackgroundSubtractorSuBSENSE.cpp
deleted file mode 100644
index c7d5daca785550f6290f59e19e3427892908520c..0000000000000000000000000000000000000000
--- a/package_bgs/pl/BackgroundSubtractorSuBSENSE.cpp
+++ /dev/null
@@ -1,737 +0,0 @@
-#include "BackgroundSubtractorSuBSENSE.h"
-#include "DistanceUtils.h"
-#include "RandUtils.h"
-#include <iostream>
-#include <opencv2/imgproc/imgproc.hpp>
-#include <opencv2/highgui/highgui.hpp>
-#include <iomanip>
-
-/*
- *
- * Intrinsic parameters for our method are defined here; tuning these for better
- * performance should not be required in most cases -- although improvements in
- * very specific scenarios are always possible.
- *
- */
-//! defines the threshold value(s) used to detect long-term ghosting and trigger the fast edge-based absorption heuristic
-#define GHOSTDET_D_MAX (0.010f) // defines 'negligible' change here
-#define GHOSTDET_S_MIN (0.995f) // defines the required minimum local foreground saturation value
-//! parameter used to scale dynamic distance threshold adjustments ('R(x)')
-#define FEEDBACK_R_VAR (0.01f)
-//! parameters used to adjust the variation step size of 'v(x)'
-#define FEEDBACK_V_INCR  (1.000f)
-#define FEEDBACK_V_DECR  (0.100f)
-//! parameters used to scale dynamic learning rate adjustments  ('T(x)')
-#define FEEDBACK_T_DECR  (0.2500f)
-#define FEEDBACK_T_INCR  (0.5000f)
-#define FEEDBACK_T_LOWER (2.0000f)
-#define FEEDBACK_T_UPPER (256.00f)
-//! parameters used to define 'unstable' regions, based on segm noise/bg dynamics and local dist threshold values
-#define UNSTABLE_REG_RATIO_MIN (0.100f)
-#define UNSTABLE_REG_RDIST_MIN (3.000f)
-//! parameters used to scale the relative LBSP intensity threshold used for internal comparisons
-#define LBSPDESC_NONZERO_RATIO_MIN (0.100f)
-#define LBSPDESC_NONZERO_RATIO_MAX (0.500f)
-//! parameters used to define model reset/learning rate boosts in our frame-level component
-#define FRAMELEVEL_MIN_COLOR_DIFF_THRESHOLD  (m_nMinColorDistThreshold/2)
-#define FRAMELEVEL_ANALYSIS_DOWNSAMPLE_RATIO (8)
-
-// local define used to display debug information
-#define DISPLAY_SUBSENSE_DEBUG_INFO 0
-// local define used to specify the default frame size (320x240 = QVGA)
-#define DEFAULT_FRAME_SIZE cv::Size(320,240)
-// local define used to specify the color dist threshold offset used for unstable regions
-#define STAB_COLOR_DIST_OFFSET (m_nMinColorDistThreshold/5)
-// local define used to specify the desc dist threshold offset used for unstable regions
-#define UNSTAB_DESC_DIST_OFFSET (m_nDescDistThresholdOffset)
-
-static const size_t s_nColorMaxDataRange_1ch = UCHAR_MAX;
-static const size_t s_nDescMaxDataRange_1ch = LBSP::DESC_SIZE*8;
-static const size_t s_nColorMaxDataRange_3ch = s_nColorMaxDataRange_1ch*3;
-static const size_t s_nDescMaxDataRange_3ch = s_nDescMaxDataRange_1ch*3;
-
-BackgroundSubtractorSuBSENSE::BackgroundSubtractorSuBSENSE(	 float fRelLBSPThreshold
-															,size_t nDescDistThresholdOffset
-															,size_t nMinColorDistThreshold
-															,size_t nBGSamples
-															,size_t nRequiredBGSamples
-															,size_t nSamplesForMovingAvgs)
-	:	 BackgroundSubtractorLBSP(fRelLBSPThreshold)
-		,m_nMinColorDistThreshold(nMinColorDistThreshold)
-		,m_nDescDistThresholdOffset(nDescDistThresholdOffset)
-		,m_nBGSamples(nBGSamples)
-		,m_nRequiredBGSamples(nRequiredBGSamples)
-		,m_nSamplesForMovingAvgs(nSamplesForMovingAvgs)
-		,m_fLastNonZeroDescRatio(0.0f)
-		,m_bLearningRateScalingEnabled(true)
-		,m_fCurrLearningRateLowerCap(FEEDBACK_T_LOWER)
-		,m_fCurrLearningRateUpperCap(FEEDBACK_T_UPPER)
-		,m_nMedianBlurKernelSize(m_nDefaultMedianBlurKernelSize)
-		,m_bUse3x3Spread(true) {
-	CV_Assert(m_nBGSamples>0 && m_nRequiredBGSamples<=m_nBGSamples);
-	CV_Assert(m_nMinColorDistThreshold>=STAB_COLOR_DIST_OFFSET);
-}
-
-BackgroundSubtractorSuBSENSE::~BackgroundSubtractorSuBSENSE() {
-	if(m_aPxIdxLUT)
-		delete[] m_aPxIdxLUT;
-	if(m_aPxInfoLUT)
-	    delete[] m_aPxInfoLUT;
-}
-
-void BackgroundSubtractorSuBSENSE::initialize(const cv::Mat& oInitImg, const cv::Mat& oROI) {
-	// == init
-	CV_Assert(!oInitImg.empty() && oInitImg.cols>0 && oInitImg.rows>0);
-	CV_Assert(oInitImg.isContinuous());
-	CV_Assert(oInitImg.type()==CV_8UC3 || oInitImg.type()==CV_8UC1);
-	if(oInitImg.type()==CV_8UC3) {
-		std::vector<cv::Mat> voInitImgChannels;
-		cv::split(oInitImg,voInitImgChannels);
-		if(!cv::countNonZero((voInitImgChannels[0]!=voInitImgChannels[1])|(voInitImgChannels[2]!=voInitImgChannels[1])))
-			std::cout << std::endl << "\tBackgroundSubtractorSuBSENSE : Warning, grayscale images should always be passed in CV_8UC1 format for optimal performance." << std::endl;
-	}
-	cv::Mat oNewBGROI;
-	if(oROI.empty() && (m_oROI.empty() || oROI.size()!=oInitImg.size())) {
-		oNewBGROI.create(oInitImg.size(),CV_8UC1);
-		oNewBGROI = cv::Scalar_<uchar>(UCHAR_MAX);
-	}
-	else if(oROI.empty())
-		oNewBGROI = m_oROI;
-	else {
-		CV_Assert(oROI.size()==oInitImg.size() && oROI.type()==CV_8UC1);
-		CV_Assert(cv::countNonZero((oROI<UCHAR_MAX)&(oROI>0))==0);
-		oNewBGROI = oROI.clone();
-		cv::Mat oTempROI;
-		cv::dilate(oNewBGROI,oTempROI,cv::Mat(),cv::Point(-1,-1),LBSP::PATCH_SIZE/2);
-		cv::bitwise_or(oNewBGROI,oTempROI/2,oNewBGROI);
-	}
-	const size_t nOrigROIPxCount = (size_t)cv::countNonZero(oNewBGROI);
-	CV_Assert(nOrigROIPxCount>0);
-	LBSP::validateROI(oNewBGROI);
-	const size_t nFinalROIPxCount = (size_t)cv::countNonZero(oNewBGROI);
-	CV_Assert(nFinalROIPxCount>0);
-	m_oROI = oNewBGROI;
-	m_oImgSize = oInitImg.size();
-	m_nImgType = oInitImg.type();
-	m_nImgChannels = oInitImg.channels();
-	m_nTotPxCount = m_oImgSize.area();
-	m_nTotRelevantPxCount = nFinalROIPxCount;
-	m_nFrameIndex = 0;
-	m_nFramesSinceLastReset = 0;
-	m_nModelResetCooldown = 0;
-	m_fLastNonZeroDescRatio = 0.0f;
-	const int nTotImgPixels = m_oImgSize.height*m_oImgSize.width;
-	if(nOrigROIPxCount>=m_nTotPxCount/2 && (int)m_nTotPxCount>=DEFAULT_FRAME_SIZE.area()) {
-		m_bLearningRateScalingEnabled = true;
-		m_bAutoModelResetEnabled = true;
-		m_bUse3x3Spread = !(nTotImgPixels>DEFAULT_FRAME_SIZE.area()*2);
-		const int nRawMedianBlurKernelSize = std::min((int)floor((float)nTotImgPixels/DEFAULT_FRAME_SIZE.area()+0.5f)+m_nDefaultMedianBlurKernelSize,14);
-		m_nMedianBlurKernelSize = (nRawMedianBlurKernelSize%2)?nRawMedianBlurKernelSize:nRawMedianBlurKernelSize-1;
-		m_fCurrLearningRateLowerCap = FEEDBACK_T_LOWER;
-		m_fCurrLearningRateUpperCap = FEEDBACK_T_UPPER;
-	}
-	else {
-		m_bLearningRateScalingEnabled = false;
-		m_bAutoModelResetEnabled = false;
-		m_bUse3x3Spread = true;
-		m_nMedianBlurKernelSize = m_nDefaultMedianBlurKernelSize;
-		m_fCurrLearningRateLowerCap = FEEDBACK_T_LOWER*2;
-		m_fCurrLearningRateUpperCap = FEEDBACK_T_UPPER*2;
-	}
-	m_oUpdateRateFrame.create(m_oImgSize,CV_32FC1);
-	m_oUpdateRateFrame = cv::Scalar(m_fCurrLearningRateLowerCap);
-	m_oDistThresholdFrame.create(m_oImgSize,CV_32FC1);
-	m_oDistThresholdFrame = cv::Scalar(1.0f);
-	m_oVariationModulatorFrame.create(m_oImgSize,CV_32FC1);
-	m_oVariationModulatorFrame = cv::Scalar(10.0f); // should always be >= FEEDBACK_V_DECR
-	m_oMeanLastDistFrame.create(m_oImgSize,CV_32FC1);
-	m_oMeanLastDistFrame = cv::Scalar(0.0f);
-	m_oMeanMinDistFrame_LT.create(m_oImgSize,CV_32FC1);
-	m_oMeanMinDistFrame_LT = cv::Scalar(0.0f);
-	m_oMeanMinDistFrame_ST.create(m_oImgSize,CV_32FC1);
-	m_oMeanMinDistFrame_ST = cv::Scalar(0.0f);
-	m_oDownSampledFrameSize = cv::Size(m_oImgSize.width/FRAMELEVEL_ANALYSIS_DOWNSAMPLE_RATIO,m_oImgSize.height/FRAMELEVEL_ANALYSIS_DOWNSAMPLE_RATIO);
-	m_oMeanDownSampledLastDistFrame_LT.create(m_oDownSampledFrameSize,CV_32FC((int)m_nImgChannels));
-	m_oMeanDownSampledLastDistFrame_LT = cv::Scalar(0.0f);
-	m_oMeanDownSampledLastDistFrame_ST.create(m_oDownSampledFrameSize,CV_32FC((int)m_nImgChannels));
-	m_oMeanDownSampledLastDistFrame_ST = cv::Scalar(0.0f);
-	m_oMeanRawSegmResFrame_LT.create(m_oImgSize,CV_32FC1);
-	m_oMeanRawSegmResFrame_LT = cv::Scalar(0.0f);
-	m_oMeanRawSegmResFrame_ST.create(m_oImgSize,CV_32FC1);
-	m_oMeanRawSegmResFrame_ST = cv::Scalar(0.0f);
-	m_oMeanFinalSegmResFrame_LT.create(m_oImgSize,CV_32FC1);
-	m_oMeanFinalSegmResFrame_LT = cv::Scalar(0.0f);
-	m_oMeanFinalSegmResFrame_ST.create(m_oImgSize,CV_32FC1);
-	m_oMeanFinalSegmResFrame_ST = cv::Scalar(0.0f);
-	m_oUnstableRegionMask.create(m_oImgSize,CV_8UC1);
-	m_oUnstableRegionMask = cv::Scalar_<uchar>(0);
-	m_oBlinksFrame.create(m_oImgSize,CV_8UC1);
-	m_oBlinksFrame = cv::Scalar_<uchar>(0);
-	m_oDownSampledFrame_MotionAnalysis.create(m_oDownSampledFrameSize,CV_8UC((int)m_nImgChannels));
-	m_oDownSampledFrame_MotionAnalysis = cv::Scalar_<uchar>::all(0);
-	m_oLastColorFrame.create(m_oImgSize,CV_8UC((int)m_nImgChannels));
-	m_oLastColorFrame = cv::Scalar_<uchar>::all(0);
-	m_oLastDescFrame.create(m_oImgSize,CV_16UC((int)m_nImgChannels));
-	m_oLastDescFrame = cv::Scalar_<ushort>::all(0);
-	m_oLastRawFGMask.create(m_oImgSize,CV_8UC1);
-	m_oLastRawFGMask = cv::Scalar_<uchar>(0);
-	m_oLastFGMask.create(m_oImgSize,CV_8UC1);
-	m_oLastFGMask = cv::Scalar_<uchar>(0);
-	m_oLastFGMask_dilated.create(m_oImgSize,CV_8UC1);
-	m_oLastFGMask_dilated = cv::Scalar_<uchar>(0);
-	m_oLastFGMask_dilated_inverted.create(m_oImgSize,CV_8UC1);
-	m_oLastFGMask_dilated_inverted = cv::Scalar_<uchar>(0);
-	m_oFGMask_FloodedHoles.create(m_oImgSize,CV_8UC1);
-	m_oFGMask_FloodedHoles = cv::Scalar_<uchar>(0);
-	m_oFGMask_PreFlood.create(m_oImgSize,CV_8UC1);
-	m_oFGMask_PreFlood = cv::Scalar_<uchar>(0);
-	m_oCurrRawFGBlinkMask.create(m_oImgSize,CV_8UC1);
-	m_oCurrRawFGBlinkMask = cv::Scalar_<uchar>(0);
-	m_oLastRawFGBlinkMask.create(m_oImgSize,CV_8UC1);
-	m_oLastRawFGBlinkMask = cv::Scalar_<uchar>(0);
-	m_voBGColorSamples.resize(m_nBGSamples);
-	m_voBGDescSamples.resize(m_nBGSamples);
-	for(size_t s=0; s<m_nBGSamples; ++s) {
-		m_voBGColorSamples[s].create(m_oImgSize,CV_8UC((int)m_nImgChannels));
-		m_voBGColorSamples[s] = cv::Scalar_<uchar>::all(0);
-		m_voBGDescSamples[s].create(m_oImgSize,CV_16UC((int)m_nImgChannels));
-		m_voBGDescSamples[s] = cv::Scalar_<ushort>::all(0);
-	}
-	if(m_aPxIdxLUT)
-		delete[] m_aPxIdxLUT;
-	if(m_aPxInfoLUT)
-	    delete[] m_aPxInfoLUT;
-	m_aPxIdxLUT = new size_t[m_nTotRelevantPxCount];
-	m_aPxInfoLUT = new PxInfoBase[m_nTotPxCount];
-	if(m_nImgChannels==1) {
-		CV_Assert(m_oLastColorFrame.step.p[0]==(size_t)m_oImgSize.width && m_oLastColorFrame.step.p[1]==1);
-		CV_Assert(m_oLastDescFrame.step.p[0]==m_oLastColorFrame.step.p[0]*2 && m_oLastDescFrame.step.p[1]==m_oLastColorFrame.step.p[1]*2);
-		for(size_t t=0; t<=UCHAR_MAX; ++t)
-			m_anLBSPThreshold_8bitLUT[t] = cv::saturate_cast<uchar>((m_nLBSPThresholdOffset+t*m_fRelLBSPThreshold)/3);
-		for(size_t nPxIter=0, nModelIter=0; nPxIter<m_nTotPxCount; ++nPxIter) {
-			if(m_oROI.data[nPxIter]) {
-				m_aPxIdxLUT[nModelIter] = nPxIter;
-				m_aPxInfoLUT[nPxIter].nImgCoord_Y = (int)nPxIter/m_oImgSize.width;
-				m_aPxInfoLUT[nPxIter].nImgCoord_X = (int)nPxIter%m_oImgSize.width;
-				m_aPxInfoLUT[nPxIter].nModelIdx = nModelIter;
-				m_oLastColorFrame.data[nPxIter] = oInitImg.data[nPxIter];
-				const size_t nDescIter = nPxIter*2;
-				LBSP::computeGrayscaleDescriptor(oInitImg,oInitImg.data[nPxIter],m_aPxInfoLUT[nPxIter].nImgCoord_X,m_aPxInfoLUT[nPxIter].nImgCoord_Y,m_anLBSPThreshold_8bitLUT[oInitImg.data[nPxIter]],*((ushort*)(m_oLastDescFrame.data+nDescIter)));
-				++nModelIter;
-			}
-		}
-	}
-	else { //m_nImgChannels==3
-		CV_Assert(m_oLastColorFrame.step.p[0]==(size_t)m_oImgSize.width*3 && m_oLastColorFrame.step.p[1]==3);
-		CV_Assert(m_oLastDescFrame.step.p[0]==m_oLastColorFrame.step.p[0]*2 && m_oLastDescFrame.step.p[1]==m_oLastColorFrame.step.p[1]*2);
-		for(size_t t=0; t<=UCHAR_MAX; ++t)
-			m_anLBSPThreshold_8bitLUT[t] = cv::saturate_cast<uchar>(m_nLBSPThresholdOffset+t*m_fRelLBSPThreshold);
-		for(size_t nPxIter=0, nModelIter=0; nPxIter<m_nTotPxCount; ++nPxIter) {
-			if(m_oROI.data[nPxIter]) {
-				m_aPxIdxLUT[nModelIter] = nPxIter;
-				m_aPxInfoLUT[nPxIter].nImgCoord_Y = (int)nPxIter/m_oImgSize.width;
-				m_aPxInfoLUT[nPxIter].nImgCoord_X = (int)nPxIter%m_oImgSize.width;
-				m_aPxInfoLUT[nPxIter].nModelIdx = nModelIter;
-				const size_t nPxRGBIter = nPxIter*3;
-				const size_t nDescRGBIter = nPxRGBIter*2;
-				for(size_t c=0; c<3; ++c) {
-					m_oLastColorFrame.data[nPxRGBIter+c] = oInitImg.data[nPxRGBIter+c];
-					LBSP::computeSingleRGBDescriptor(oInitImg,oInitImg.data[nPxRGBIter+c],m_aPxInfoLUT[nPxIter].nImgCoord_X,m_aPxInfoLUT[nPxIter].nImgCoord_Y,c,m_anLBSPThreshold_8bitLUT[oInitImg.data[nPxRGBIter+c]],((ushort*)(m_oLastDescFrame.data+nDescRGBIter))[c]);
-				}
-				++nModelIter;
-			}
-		}
-	}
-	m_bInitialized = true;
-	refreshModel(1.0f);
-}
-
-void BackgroundSubtractorSuBSENSE::refreshModel(float fSamplesRefreshFrac, bool bForceFGUpdate) {
-	// == refresh
-	CV_Assert(m_bInitialized);
-	CV_Assert(fSamplesRefreshFrac>0.0f && fSamplesRefreshFrac<=1.0f);
-	const size_t nModelsToRefresh = fSamplesRefreshFrac<1.0f?(size_t)(fSamplesRefreshFrac*m_nBGSamples):m_nBGSamples;
-	const size_t nRefreshStartPos = fSamplesRefreshFrac<1.0f?rand()%m_nBGSamples:0;
-	if(m_nImgChannels==1) {
-		for(size_t nModelIter=0; nModelIter<m_nTotRelevantPxCount; ++nModelIter) {
-			const size_t nPxIter = m_aPxIdxLUT[nModelIter];
-			if(bForceFGUpdate || !m_oLastFGMask.data[nPxIter]) {
-				for(size_t nCurrModelIdx=nRefreshStartPos; nCurrModelIdx<nRefreshStartPos+nModelsToRefresh; ++nCurrModelIdx) {
-					int nSampleImgCoord_Y, nSampleImgCoord_X;
-					getRandSamplePosition(nSampleImgCoord_X,nSampleImgCoord_Y,m_aPxInfoLUT[nPxIter].nImgCoord_X,m_aPxInfoLUT[nPxIter].nImgCoord_Y,LBSP::PATCH_SIZE/2,m_oImgSize);
-					const size_t nSamplePxIdx = m_oImgSize.width*nSampleImgCoord_Y + nSampleImgCoord_X;
-					if(bForceFGUpdate || !m_oLastFGMask.data[nSamplePxIdx]) {
-						const size_t nCurrRealModelIdx = nCurrModelIdx%m_nBGSamples;
-						m_voBGColorSamples[nCurrRealModelIdx].data[nPxIter] = m_oLastColorFrame.data[nSamplePxIdx];
-						*((ushort*)(m_voBGDescSamples[nCurrRealModelIdx].data+nPxIter*2)) = *((ushort*)(m_oLastDescFrame.data+nSamplePxIdx*2));
-					}
-				}
-			}
-		}
-	}
-	else { //m_nImgChannels==3
-		for(size_t nModelIter=0; nModelIter<m_nTotRelevantPxCount; ++nModelIter) {
-			const size_t nPxIter = m_aPxIdxLUT[nModelIter];
-			if(bForceFGUpdate || !m_oLastFGMask.data[nPxIter]) {
-				for(size_t nCurrModelIdx=nRefreshStartPos; nCurrModelIdx<nRefreshStartPos+nModelsToRefresh; ++nCurrModelIdx) {
-					int nSampleImgCoord_Y, nSampleImgCoord_X;
-					getRandSamplePosition(nSampleImgCoord_X,nSampleImgCoord_Y,m_aPxInfoLUT[nPxIter].nImgCoord_X,m_aPxInfoLUT[nPxIter].nImgCoord_Y,LBSP::PATCH_SIZE/2,m_oImgSize);
-					const size_t nSamplePxIdx = m_oImgSize.width*nSampleImgCoord_Y + nSampleImgCoord_X;
-					if(bForceFGUpdate || !m_oLastFGMask.data[nSamplePxIdx]) {
-						const size_t nCurrRealModelIdx = nCurrModelIdx%m_nBGSamples;
-						for(size_t c=0; c<3; ++c) {
-							m_voBGColorSamples[nCurrRealModelIdx].data[nPxIter*3+c] = m_oLastColorFrame.data[nSamplePxIdx*3+c];
-							*((ushort*)(m_voBGDescSamples[nCurrRealModelIdx].data+(nPxIter*3+c)*2)) = *((ushort*)(m_oLastDescFrame.data+(nSamplePxIdx*3+c)*2));
-						}
-					}
-				}
-			}
-		}
-	}
-}
-
-void BackgroundSubtractorSuBSENSE::operator()(cv::InputArray _image, cv::OutputArray _fgmask, double learningRateOverride) {
-	// == process
-	CV_Assert(m_bInitialized);
-	cv::Mat oInputImg = _image.getMat();
-	CV_Assert(oInputImg.type()==m_nImgType && oInputImg.size()==m_oImgSize);
-	CV_Assert(oInputImg.isContinuous());
-	_fgmask.create(m_oImgSize,CV_8UC1);
-	cv::Mat oCurrFGMask = _fgmask.getMat();
-	memset(oCurrFGMask.data,0,oCurrFGMask.cols*oCurrFGMask.rows);
-	size_t nNonZeroDescCount = 0;
-	const float fRollAvgFactor_LT = 1.0f/std::min(++m_nFrameIndex,m_nSamplesForMovingAvgs);
-	const float fRollAvgFactor_ST = 1.0f/std::min(m_nFrameIndex,m_nSamplesForMovingAvgs/4);
-	if(m_nImgChannels==1) {
-		for(size_t nModelIter=0; nModelIter<m_nTotRelevantPxCount; ++nModelIter) {
-			const size_t nPxIter = m_aPxIdxLUT[nModelIter];
-			const size_t nDescIter = nPxIter*2;
-			const size_t nFloatIter = nPxIter*4;
-			const int nCurrImgCoord_X = m_aPxInfoLUT[nPxIter].nImgCoord_X;
-			const int nCurrImgCoord_Y = m_aPxInfoLUT[nPxIter].nImgCoord_Y;
-			const uchar nCurrColor = oInputImg.data[nPxIter];
-			size_t nMinDescDist = s_nDescMaxDataRange_1ch;
-			size_t nMinSumDist = s_nColorMaxDataRange_1ch;
-			float* pfCurrDistThresholdFactor = (float*)(m_oDistThresholdFrame.data+nFloatIter);
-			float* pfCurrVariationFactor = (float*)(m_oVariationModulatorFrame.data+nFloatIter);
-			float* pfCurrLearningRate = ((float*)(m_oUpdateRateFrame.data+nFloatIter));
-			float* pfCurrMeanLastDist = ((float*)(m_oMeanLastDistFrame.data+nFloatIter));
-			float* pfCurrMeanMinDist_LT = ((float*)(m_oMeanMinDistFrame_LT.data+nFloatIter));
-			float* pfCurrMeanMinDist_ST = ((float*)(m_oMeanMinDistFrame_ST.data+nFloatIter));
-			float* pfCurrMeanRawSegmRes_LT = ((float*)(m_oMeanRawSegmResFrame_LT.data+nFloatIter));
-			float* pfCurrMeanRawSegmRes_ST = ((float*)(m_oMeanRawSegmResFrame_ST.data+nFloatIter));
-			float* pfCurrMeanFinalSegmRes_LT = ((float*)(m_oMeanFinalSegmResFrame_LT.data+nFloatIter));
-			float* pfCurrMeanFinalSegmRes_ST = ((float*)(m_oMeanFinalSegmResFrame_ST.data+nFloatIter));
-			ushort& nLastIntraDesc = *((ushort*)(m_oLastDescFrame.data+nDescIter));
-			uchar& nLastColor = m_oLastColorFrame.data[nPxIter];
-			const size_t nCurrColorDistThreshold = (size_t)(((*pfCurrDistThresholdFactor)*m_nMinColorDistThreshold)-((!m_oUnstableRegionMask.data[nPxIter])*STAB_COLOR_DIST_OFFSET))/2;
-			const size_t nCurrDescDistThreshold = ((size_t)1<<((size_t)floor(*pfCurrDistThresholdFactor+0.5f)))+m_nDescDistThresholdOffset+(m_oUnstableRegionMask.data[nPxIter]*UNSTAB_DESC_DIST_OFFSET);
-			ushort nCurrInterDesc, nCurrIntraDesc;
-			LBSP::computeGrayscaleDescriptor(oInputImg,nCurrColor,nCurrImgCoord_X,nCurrImgCoord_Y,m_anLBSPThreshold_8bitLUT[nCurrColor],nCurrIntraDesc);
-			m_oUnstableRegionMask.data[nPxIter] = ((*pfCurrDistThresholdFactor)>UNSTABLE_REG_RDIST_MIN || (*pfCurrMeanRawSegmRes_LT-*pfCurrMeanFinalSegmRes_LT)>UNSTABLE_REG_RATIO_MIN || (*pfCurrMeanRawSegmRes_ST-*pfCurrMeanFinalSegmRes_ST)>UNSTABLE_REG_RATIO_MIN)?1:0;
-			size_t nGoodSamplesCount=0, nSampleIdx=0;
-			while(nGoodSamplesCount<m_nRequiredBGSamples && nSampleIdx<m_nBGSamples) {
-				const uchar& nBGColor = m_voBGColorSamples[nSampleIdx].data[nPxIter];
-				{
-					const size_t nColorDist = L1dist(nCurrColor,nBGColor);
-					if(nColorDist>nCurrColorDistThreshold)
-						goto failedcheck1ch;
-					const ushort& nBGIntraDesc = *((ushort*)(m_voBGDescSamples[nSampleIdx].data+nDescIter));
-					const size_t nIntraDescDist = hdist(nCurrIntraDesc,nBGIntraDesc);
-					LBSP::computeGrayscaleDescriptor(oInputImg,nBGColor,nCurrImgCoord_X,nCurrImgCoord_Y,m_anLBSPThreshold_8bitLUT[nBGColor],nCurrInterDesc);
-					const size_t nInterDescDist = hdist(nCurrInterDesc,nBGIntraDesc);
-					const size_t nDescDist = (nIntraDescDist+nInterDescDist)/2;
-					if(nDescDist>nCurrDescDistThreshold)
-						goto failedcheck1ch;
-					const size_t nSumDist = std::min((nDescDist/4)*(s_nColorMaxDataRange_1ch/s_nDescMaxDataRange_1ch)+nColorDist,s_nColorMaxDataRange_1ch);
-					if(nSumDist>nCurrColorDistThreshold)
-						goto failedcheck1ch;
-					if(nMinDescDist>nDescDist)
-						nMinDescDist = nDescDist;
-					if(nMinSumDist>nSumDist)
-						nMinSumDist = nSumDist;
-					nGoodSamplesCount++;
-				}
-				failedcheck1ch:
-				nSampleIdx++;
-			}
-			const float fNormalizedLastDist = ((float)L1dist(nLastColor,nCurrColor)/s_nColorMaxDataRange_1ch+(float)hdist(nLastIntraDesc,nCurrIntraDesc)/s_nDescMaxDataRange_1ch)/2;
-			*pfCurrMeanLastDist = (*pfCurrMeanLastDist)*(1.0f-fRollAvgFactor_ST) + fNormalizedLastDist*fRollAvgFactor_ST;
-			if(nGoodSamplesCount<m_nRequiredBGSamples) {
-				// == foreground
-				const float fNormalizedMinDist = std::min(1.0f,((float)nMinSumDist/s_nColorMaxDataRange_1ch+(float)nMinDescDist/s_nDescMaxDataRange_1ch)/2 + (float)(m_nRequiredBGSamples-nGoodSamplesCount)/m_nRequiredBGSamples);
-				*pfCurrMeanMinDist_LT = (*pfCurrMeanMinDist_LT)*(1.0f-fRollAvgFactor_LT) + fNormalizedMinDist*fRollAvgFactor_LT;
-				*pfCurrMeanMinDist_ST = (*pfCurrMeanMinDist_ST)*(1.0f-fRollAvgFactor_ST) + fNormalizedMinDist*fRollAvgFactor_ST;
-				*pfCurrMeanRawSegmRes_LT = (*pfCurrMeanRawSegmRes_LT)*(1.0f-fRollAvgFactor_LT) + fRollAvgFactor_LT;
-				*pfCurrMeanRawSegmRes_ST = (*pfCurrMeanRawSegmRes_ST)*(1.0f-fRollAvgFactor_ST) + fRollAvgFactor_ST;
-				oCurrFGMask.data[nPxIter] = UCHAR_MAX;
-				if(m_nModelResetCooldown && (rand()%(size_t)FEEDBACK_T_LOWER)==0) {
-					const size_t s_rand = rand()%m_nBGSamples;
-					*((ushort*)(m_voBGDescSamples[s_rand].data+nDescIter)) = nCurrIntraDesc;
-					m_voBGColorSamples[s_rand].data[nPxIter] = nCurrColor;
-				}
-			}
-			else {
-				// == background
-				const float fNormalizedMinDist = ((float)nMinSumDist/s_nColorMaxDataRange_1ch+(float)nMinDescDist/s_nDescMaxDataRange_1ch)/2;
-				*pfCurrMeanMinDist_LT = (*pfCurrMeanMinDist_LT)*(1.0f-fRollAvgFactor_LT) + fNormalizedMinDist*fRollAvgFactor_LT;
-				*pfCurrMeanMinDist_ST = (*pfCurrMeanMinDist_ST)*(1.0f-fRollAvgFactor_ST) + fNormalizedMinDist*fRollAvgFactor_ST;
-				*pfCurrMeanRawSegmRes_LT = (*pfCurrMeanRawSegmRes_LT)*(1.0f-fRollAvgFactor_LT);
-				*pfCurrMeanRawSegmRes_ST = (*pfCurrMeanRawSegmRes_ST)*(1.0f-fRollAvgFactor_ST);
-				const size_t nLearningRate = learningRateOverride>0?(size_t)ceil(learningRateOverride):(size_t)ceil(*pfCurrLearningRate);
-				if((rand()%nLearningRate)==0) {
-					const size_t s_rand = rand()%m_nBGSamples;
-					*((ushort*)(m_voBGDescSamples[s_rand].data+nDescIter)) = nCurrIntraDesc;
-					m_voBGColorSamples[s_rand].data[nPxIter] = nCurrColor;
-				}
-				int nSampleImgCoord_Y, nSampleImgCoord_X;
-				const bool bCurrUsing3x3Spread = m_bUse3x3Spread && !m_oUnstableRegionMask.data[nPxIter];
-				if(bCurrUsing3x3Spread)
-					getRandNeighborPosition_3x3(nSampleImgCoord_X,nSampleImgCoord_Y,nCurrImgCoord_X,nCurrImgCoord_Y,LBSP::PATCH_SIZE/2,m_oImgSize);
-				else
-					getRandNeighborPosition_5x5(nSampleImgCoord_X,nSampleImgCoord_Y,nCurrImgCoord_X,nCurrImgCoord_Y,LBSP::PATCH_SIZE/2,m_oImgSize);
-				const size_t n_rand = rand();
-				const size_t idx_rand_uchar = m_oImgSize.width*nSampleImgCoord_Y + nSampleImgCoord_X;
-				const size_t idx_rand_flt32 = idx_rand_uchar*4;
-				const float fRandMeanLastDist = *((float*)(m_oMeanLastDistFrame.data+idx_rand_flt32));
-				const float fRandMeanRawSegmRes = *((float*)(m_oMeanRawSegmResFrame_ST.data+idx_rand_flt32));
-				if((n_rand%(bCurrUsing3x3Spread?nLearningRate:(nLearningRate/2+1)))==0
-					|| (fRandMeanRawSegmRes>GHOSTDET_S_MIN && fRandMeanLastDist<GHOSTDET_D_MAX && (n_rand%((size_t)m_fCurrLearningRateLowerCap))==0)) {
-					const size_t idx_rand_ushrt = idx_rand_uchar*2;
-					const size_t s_rand = rand()%m_nBGSamples;
-					*((ushort*)(m_voBGDescSamples[s_rand].data+idx_rand_ushrt)) = nCurrIntraDesc;
-					m_voBGColorSamples[s_rand].data[idx_rand_uchar] = nCurrColor;
-				}
-			}
-			if(m_oLastFGMask.data[nPxIter] || (std::min(*pfCurrMeanMinDist_LT,*pfCurrMeanMinDist_ST)<UNSTABLE_REG_RATIO_MIN && oCurrFGMask.data[nPxIter])) {
-				if((*pfCurrLearningRate)<m_fCurrLearningRateUpperCap)
-					*pfCurrLearningRate += FEEDBACK_T_INCR/(std::max(*pfCurrMeanMinDist_LT,*pfCurrMeanMinDist_ST)*(*pfCurrVariationFactor));
-			}
-			else if((*pfCurrLearningRate)>m_fCurrLearningRateLowerCap)
-				*pfCurrLearningRate -= FEEDBACK_T_DECR*(*pfCurrVariationFactor)/std::max(*pfCurrMeanMinDist_LT,*pfCurrMeanMinDist_ST);
-			if((*pfCurrLearningRate)<m_fCurrLearningRateLowerCap)
-				*pfCurrLearningRate = m_fCurrLearningRateLowerCap;
-			else if((*pfCurrLearningRate)>m_fCurrLearningRateUpperCap)
-				*pfCurrLearningRate = m_fCurrLearningRateUpperCap;
-			if(std::max(*pfCurrMeanMinDist_LT,*pfCurrMeanMinDist_ST)>UNSTABLE_REG_RATIO_MIN && m_oBlinksFrame.data[nPxIter])
-				(*pfCurrVariationFactor) += FEEDBACK_V_INCR;
-			else if((*pfCurrVariationFactor)>FEEDBACK_V_DECR) {
-				(*pfCurrVariationFactor) -= m_oLastFGMask.data[nPxIter]?FEEDBACK_V_DECR/4:m_oUnstableRegionMask.data[nPxIter]?FEEDBACK_V_DECR/2:FEEDBACK_V_DECR;
-				if((*pfCurrVariationFactor)<FEEDBACK_V_DECR)
-					(*pfCurrVariationFactor) = FEEDBACK_V_DECR;
-			}
-			if((*pfCurrDistThresholdFactor)<std::pow(1.0f+std::min(*pfCurrMeanMinDist_LT,*pfCurrMeanMinDist_ST)*2,2))
-				(*pfCurrDistThresholdFactor) += FEEDBACK_R_VAR*(*pfCurrVariationFactor-FEEDBACK_V_DECR);
-			else {
-				(*pfCurrDistThresholdFactor) -= FEEDBACK_R_VAR/(*pfCurrVariationFactor);
-				if((*pfCurrDistThresholdFactor)<1.0f)
-					(*pfCurrDistThresholdFactor) = 1.0f;
-			}
-			if(popcount(nCurrIntraDesc)>=2)
-				++nNonZeroDescCount;
-			nLastIntraDesc = nCurrIntraDesc;
-			nLastColor = nCurrColor;
-		}
-	}
-	else { //m_nImgChannels==3
-		for(size_t nModelIter=0; nModelIter<m_nTotRelevantPxCount; ++nModelIter) {
-			const size_t nPxIter = m_aPxIdxLUT[nModelIter];
-			const int nCurrImgCoord_X = m_aPxInfoLUT[nPxIter].nImgCoord_X;
-			const int nCurrImgCoord_Y = m_aPxInfoLUT[nPxIter].nImgCoord_Y;
-			const size_t nPxIterRGB = nPxIter*3;
-			const size_t nDescIterRGB = nPxIterRGB*2;
-			const size_t nFloatIter = nPxIter*4;
-			const uchar* const anCurrColor = oInputImg.data+nPxIterRGB;
-			size_t nMinTotDescDist=s_nDescMaxDataRange_3ch;
-			size_t nMinTotSumDist=s_nColorMaxDataRange_3ch;
-			float* pfCurrDistThresholdFactor = (float*)(m_oDistThresholdFrame.data+nFloatIter);
-			float* pfCurrVariationFactor = (float*)(m_oVariationModulatorFrame.data+nFloatIter);
-			float* pfCurrLearningRate = ((float*)(m_oUpdateRateFrame.data+nFloatIter));
-			float* pfCurrMeanLastDist = ((float*)(m_oMeanLastDistFrame.data+nFloatIter));
-			float* pfCurrMeanMinDist_LT = ((float*)(m_oMeanMinDistFrame_LT.data+nFloatIter));
-			float* pfCurrMeanMinDist_ST = ((float*)(m_oMeanMinDistFrame_ST.data+nFloatIter));
-			float* pfCurrMeanRawSegmRes_LT = ((float*)(m_oMeanRawSegmResFrame_LT.data+nFloatIter));
-			float* pfCurrMeanRawSegmRes_ST = ((float*)(m_oMeanRawSegmResFrame_ST.data+nFloatIter));
-			float* pfCurrMeanFinalSegmRes_LT = ((float*)(m_oMeanFinalSegmResFrame_LT.data+nFloatIter));
-			float* pfCurrMeanFinalSegmRes_ST = ((float*)(m_oMeanFinalSegmResFrame_ST.data+nFloatIter));
-			ushort* anLastIntraDesc = ((ushort*)(m_oLastDescFrame.data+nDescIterRGB));
-			uchar* anLastColor = m_oLastColorFrame.data+nPxIterRGB;
-			const size_t nCurrColorDistThreshold = (size_t)(((*pfCurrDistThresholdFactor)*m_nMinColorDistThreshold)-((!m_oUnstableRegionMask.data[nPxIter])*STAB_COLOR_DIST_OFFSET));
-			const size_t nCurrDescDistThreshold = ((size_t)1<<((size_t)floor(*pfCurrDistThresholdFactor+0.5f)))+m_nDescDistThresholdOffset+(m_oUnstableRegionMask.data[nPxIter]*UNSTAB_DESC_DIST_OFFSET);
-			const size_t nCurrTotColorDistThreshold = nCurrColorDistThreshold*3;
-			const size_t nCurrTotDescDistThreshold = nCurrDescDistThreshold*3;
-			const size_t nCurrSCColorDistThreshold = nCurrTotColorDistThreshold/2;
-			ushort anCurrInterDesc[3], anCurrIntraDesc[3];
-			const size_t anCurrIntraLBSPThresholds[3] = {m_anLBSPThreshold_8bitLUT[anCurrColor[0]],m_anLBSPThreshold_8bitLUT[anCurrColor[1]],m_anLBSPThreshold_8bitLUT[anCurrColor[2]]};
-			LBSP::computeRGBDescriptor(oInputImg,anCurrColor,nCurrImgCoord_X,nCurrImgCoord_Y,anCurrIntraLBSPThresholds,anCurrIntraDesc);
-			m_oUnstableRegionMask.data[nPxIter] = ((*pfCurrDistThresholdFactor)>UNSTABLE_REG_RDIST_MIN || (*pfCurrMeanRawSegmRes_LT-*pfCurrMeanFinalSegmRes_LT)>UNSTABLE_REG_RATIO_MIN || (*pfCurrMeanRawSegmRes_ST-*pfCurrMeanFinalSegmRes_ST)>UNSTABLE_REG_RATIO_MIN)?1:0;
-			size_t nGoodSamplesCount=0, nSampleIdx=0;
-			while(nGoodSamplesCount<m_nRequiredBGSamples && nSampleIdx<m_nBGSamples) {
-				const ushort* const anBGIntraDesc = (ushort*)(m_voBGDescSamples[nSampleIdx].data+nDescIterRGB);
-				const uchar* const anBGColor = m_voBGColorSamples[nSampleIdx].data+nPxIterRGB;
-				size_t nTotDescDist = 0;
-				size_t nTotSumDist = 0;
-				for(size_t c=0;c<3; ++c) {
-					const size_t nColorDist = L1dist(anCurrColor[c],anBGColor[c]);
-					if(nColorDist>nCurrSCColorDistThreshold)
-						goto failedcheck3ch;
-					const size_t nIntraDescDist = hdist(anCurrIntraDesc[c],anBGIntraDesc[c]);
-					LBSP::computeSingleRGBDescriptor(oInputImg,anBGColor[c],nCurrImgCoord_X,nCurrImgCoord_Y,c,m_anLBSPThreshold_8bitLUT[anBGColor[c]],anCurrInterDesc[c]);
-					const size_t nInterDescDist = hdist(anCurrInterDesc[c],anBGIntraDesc[c]);
-					const size_t nDescDist = (nIntraDescDist+nInterDescDist)/2;
-					const size_t nSumDist = std::min((nDescDist/2)*(s_nColorMaxDataRange_1ch/s_nDescMaxDataRange_1ch)+nColorDist,s_nColorMaxDataRange_1ch);
-					if(nSumDist>nCurrSCColorDistThreshold)
-						goto failedcheck3ch;
-					nTotDescDist += nDescDist;
-					nTotSumDist += nSumDist;
-				}
-				if(nTotDescDist>nCurrTotDescDistThreshold || nTotSumDist>nCurrTotColorDistThreshold)
-					goto failedcheck3ch;
-				if(nMinTotDescDist>nTotDescDist)
-					nMinTotDescDist = nTotDescDist;
-				if(nMinTotSumDist>nTotSumDist)
-					nMinTotSumDist = nTotSumDist;
-				nGoodSamplesCount++;
-				failedcheck3ch:
-				nSampleIdx++;
-			}
-			const float fNormalizedLastDist = ((float)L1dist<3>(anLastColor,anCurrColor)/s_nColorMaxDataRange_3ch+(float)hdist<3>(anLastIntraDesc,anCurrIntraDesc)/s_nDescMaxDataRange_3ch)/2;
-			*pfCurrMeanLastDist = (*pfCurrMeanLastDist)*(1.0f-fRollAvgFactor_ST) + fNormalizedLastDist*fRollAvgFactor_ST;
-			if(nGoodSamplesCount<m_nRequiredBGSamples) {
-				// == foreground
-				const float fNormalizedMinDist = std::min(1.0f,((float)nMinTotSumDist/s_nColorMaxDataRange_3ch+(float)nMinTotDescDist/s_nDescMaxDataRange_3ch)/2 + (float)(m_nRequiredBGSamples-nGoodSamplesCount)/m_nRequiredBGSamples);
-				*pfCurrMeanMinDist_LT = (*pfCurrMeanMinDist_LT)*(1.0f-fRollAvgFactor_LT) + fNormalizedMinDist*fRollAvgFactor_LT;
-				*pfCurrMeanMinDist_ST = (*pfCurrMeanMinDist_ST)*(1.0f-fRollAvgFactor_ST) + fNormalizedMinDist*fRollAvgFactor_ST;
-				*pfCurrMeanRawSegmRes_LT = (*pfCurrMeanRawSegmRes_LT)*(1.0f-fRollAvgFactor_LT) + fRollAvgFactor_LT;
-				*pfCurrMeanRawSegmRes_ST = (*pfCurrMeanRawSegmRes_ST)*(1.0f-fRollAvgFactor_ST) + fRollAvgFactor_ST;
-				oCurrFGMask.data[nPxIter] = UCHAR_MAX;
-				if(m_nModelResetCooldown && (rand()%(size_t)FEEDBACK_T_LOWER)==0) {
-					const size_t s_rand = rand()%m_nBGSamples;
-					for(size_t c=0; c<3; ++c) {
-						*((ushort*)(m_voBGDescSamples[s_rand].data+nDescIterRGB+2*c)) = anCurrIntraDesc[c];
-						*(m_voBGColorSamples[s_rand].data+nPxIterRGB+c) = anCurrColor[c];
-					}
-				}
-			}
-			else {
-				// == background
-				const float fNormalizedMinDist = ((float)nMinTotSumDist/s_nColorMaxDataRange_3ch+(float)nMinTotDescDist/s_nDescMaxDataRange_3ch)/2;
-				*pfCurrMeanMinDist_LT = (*pfCurrMeanMinDist_LT)*(1.0f-fRollAvgFactor_LT) + fNormalizedMinDist*fRollAvgFactor_LT;
-				*pfCurrMeanMinDist_ST = (*pfCurrMeanMinDist_ST)*(1.0f-fRollAvgFactor_ST) + fNormalizedMinDist*fRollAvgFactor_ST;
-				*pfCurrMeanRawSegmRes_LT = (*pfCurrMeanRawSegmRes_LT)*(1.0f-fRollAvgFactor_LT);
-				*pfCurrMeanRawSegmRes_ST = (*pfCurrMeanRawSegmRes_ST)*(1.0f-fRollAvgFactor_ST);
-				const size_t nLearningRate = learningRateOverride>0?(size_t)ceil(learningRateOverride):(size_t)ceil(*pfCurrLearningRate);
-				if((rand()%nLearningRate)==0) {
-					const size_t s_rand = rand()%m_nBGSamples;
-					for(size_t c=0; c<3; ++c) {
-						*((ushort*)(m_voBGDescSamples[s_rand].data+nDescIterRGB+2*c)) = anCurrIntraDesc[c];
-						*(m_voBGColorSamples[s_rand].data+nPxIterRGB+c) = anCurrColor[c];
-					}
-				}
-				int nSampleImgCoord_Y, nSampleImgCoord_X;
-				const bool bCurrUsing3x3Spread = m_bUse3x3Spread && !m_oUnstableRegionMask.data[nPxIter];
-				if(bCurrUsing3x3Spread)
-					getRandNeighborPosition_3x3(nSampleImgCoord_X,nSampleImgCoord_Y,nCurrImgCoord_X,nCurrImgCoord_Y,LBSP::PATCH_SIZE/2,m_oImgSize);
-				else
-					getRandNeighborPosition_5x5(nSampleImgCoord_X,nSampleImgCoord_Y,nCurrImgCoord_X,nCurrImgCoord_Y,LBSP::PATCH_SIZE/2,m_oImgSize);
-				const size_t n_rand = rand();
-				const size_t idx_rand_uchar = m_oImgSize.width*nSampleImgCoord_Y + nSampleImgCoord_X;
-				const size_t idx_rand_flt32 = idx_rand_uchar*4;
-				const float fRandMeanLastDist = *((float*)(m_oMeanLastDistFrame.data+idx_rand_flt32));
-				const float fRandMeanRawSegmRes = *((float*)(m_oMeanRawSegmResFrame_ST.data+idx_rand_flt32));
-				if((n_rand%(bCurrUsing3x3Spread?nLearningRate:(nLearningRate/2+1)))==0
-					|| (fRandMeanRawSegmRes>GHOSTDET_S_MIN && fRandMeanLastDist<GHOSTDET_D_MAX && (n_rand%((size_t)m_fCurrLearningRateLowerCap))==0)) {
-					const size_t idx_rand_uchar_rgb = idx_rand_uchar*3;
-					const size_t idx_rand_ushrt_rgb = idx_rand_uchar_rgb*2;
-					const size_t s_rand = rand()%m_nBGSamples;
-					for(size_t c=0; c<3; ++c) {
-						*((ushort*)(m_voBGDescSamples[s_rand].data+idx_rand_ushrt_rgb+2*c)) = anCurrIntraDesc[c];
-						*(m_voBGColorSamples[s_rand].data+idx_rand_uchar_rgb+c) = anCurrColor[c];
-					}
-				}
-			}
-			if(m_oLastFGMask.data[nPxIter] || (std::min(*pfCurrMeanMinDist_LT,*pfCurrMeanMinDist_ST)<UNSTABLE_REG_RATIO_MIN && oCurrFGMask.data[nPxIter])) {
-				if((*pfCurrLearningRate)<m_fCurrLearningRateUpperCap)
-					*pfCurrLearningRate += FEEDBACK_T_INCR/(std::max(*pfCurrMeanMinDist_LT,*pfCurrMeanMinDist_ST)*(*pfCurrVariationFactor));
-			}
-			else if((*pfCurrLearningRate)>m_fCurrLearningRateLowerCap)
-				*pfCurrLearningRate -= FEEDBACK_T_DECR*(*pfCurrVariationFactor)/std::max(*pfCurrMeanMinDist_LT,*pfCurrMeanMinDist_ST);
-			if((*pfCurrLearningRate)<m_fCurrLearningRateLowerCap)
-				*pfCurrLearningRate = m_fCurrLearningRateLowerCap;
-			else if((*pfCurrLearningRate)>m_fCurrLearningRateUpperCap)
-				*pfCurrLearningRate = m_fCurrLearningRateUpperCap;
-			if(std::max(*pfCurrMeanMinDist_LT,*pfCurrMeanMinDist_ST)>UNSTABLE_REG_RATIO_MIN && m_oBlinksFrame.data[nPxIter])
-				(*pfCurrVariationFactor) += FEEDBACK_V_INCR;
-			else if((*pfCurrVariationFactor)>FEEDBACK_V_DECR) {
-				(*pfCurrVariationFactor) -= m_oLastFGMask.data[nPxIter]?FEEDBACK_V_DECR/4:m_oUnstableRegionMask.data[nPxIter]?FEEDBACK_V_DECR/2:FEEDBACK_V_DECR;
-				if((*pfCurrVariationFactor)<FEEDBACK_V_DECR)
-					(*pfCurrVariationFactor) = FEEDBACK_V_DECR;
-			}
-			if((*pfCurrDistThresholdFactor)<std::pow(1.0f+std::min(*pfCurrMeanMinDist_LT,*pfCurrMeanMinDist_ST)*2,2))
-				(*pfCurrDistThresholdFactor) += FEEDBACK_R_VAR*(*pfCurrVariationFactor-FEEDBACK_V_DECR);
-			else {
-				(*pfCurrDistThresholdFactor) -= FEEDBACK_R_VAR/(*pfCurrVariationFactor);
-				if((*pfCurrDistThresholdFactor)<1.0f)
-					(*pfCurrDistThresholdFactor) = 1.0f;
-			}
-			if(popcount<3>(anCurrIntraDesc)>=4)
-				++nNonZeroDescCount;
-			for(size_t c=0; c<3; ++c) {
-				anLastIntraDesc[c] = anCurrIntraDesc[c];
-				anLastColor[c] = anCurrColor[c];
-			}
-		}
-	}
-#if DISPLAY_SUBSENSE_DEBUG_INFO
-	std::cout << std::endl;
-	cv::Point dbgpt(nDebugCoordX,nDebugCoordY);
-	cv::Mat oMeanMinDistFrameNormalized; m_oMeanMinDistFrame_ST.copyTo(oMeanMinDistFrameNormalized);
-	cv::circle(oMeanMinDistFrameNormalized,dbgpt,5,cv::Scalar(1.0f));
-	cv::resize(oMeanMinDistFrameNormalized,oMeanMinDistFrameNormalized,DEFAULT_FRAME_SIZE);
-	cv::imshow("d_min(x)",oMeanMinDistFrameNormalized);
-	std::cout << std::fixed << std::setprecision(5) << "  d_min(" << dbgpt << ") = " << m_oMeanMinDistFrame_ST.at<float>(dbgpt) << std::endl;
-	cv::Mat oMeanLastDistFrameNormalized; m_oMeanLastDistFrame.copyTo(oMeanLastDistFrameNormalized);
-	cv::circle(oMeanLastDistFrameNormalized,dbgpt,5,cv::Scalar(1.0f));
-	cv::resize(oMeanLastDistFrameNormalized,oMeanLastDistFrameNormalized,DEFAULT_FRAME_SIZE);
-	cv::imshow("d_last(x)",oMeanLastDistFrameNormalized);
-	std::cout << std::fixed << std::setprecision(5) << " d_last(" << dbgpt << ") = " << m_oMeanLastDistFrame.at<float>(dbgpt) << std::endl;
-	cv::Mat oMeanRawSegmResFrameNormalized; m_oMeanRawSegmResFrame_ST.copyTo(oMeanRawSegmResFrameNormalized);
-	cv::circle(oMeanRawSegmResFrameNormalized,dbgpt,5,cv::Scalar(1.0f));
-	cv::resize(oMeanRawSegmResFrameNormalized,oMeanRawSegmResFrameNormalized,DEFAULT_FRAME_SIZE);
-	cv::imshow("s_avg(x)",oMeanRawSegmResFrameNormalized);
-	std::cout << std::fixed << std::setprecision(5) << "  s_avg(" << dbgpt << ") = " << m_oMeanRawSegmResFrame_ST.at<float>(dbgpt) << std::endl;
-	cv::Mat oMeanFinalSegmResFrameNormalized; m_oMeanFinalSegmResFrame_ST.copyTo(oMeanFinalSegmResFrameNormalized);
-	cv::circle(oMeanFinalSegmResFrameNormalized,dbgpt,5,cv::Scalar(1.0f));
-	cv::resize(oMeanFinalSegmResFrameNormalized,oMeanFinalSegmResFrameNormalized,DEFAULT_FRAME_SIZE);
-	cv::imshow("z_avg(x)",oMeanFinalSegmResFrameNormalized);
-	std::cout << std::fixed << std::setprecision(5) << "  z_avg(" << dbgpt << ") = " << m_oMeanFinalSegmResFrame_ST.at<float>(dbgpt) << std::endl;
-	cv::Mat oDistThresholdFrameNormalized; m_oDistThresholdFrame.convertTo(oDistThresholdFrameNormalized,CV_32FC1,0.25f,-0.25f);
-	cv::circle(oDistThresholdFrameNormalized,dbgpt,5,cv::Scalar(1.0f));
-	cv::resize(oDistThresholdFrameNormalized,oDistThresholdFrameNormalized,DEFAULT_FRAME_SIZE);
-	cv::imshow("r(x)",oDistThresholdFrameNormalized);
-	std::cout << std::fixed << std::setprecision(5) << "      r(" << dbgpt << ") = " << m_oDistThresholdFrame.at<float>(dbgpt) << std::endl;
-	cv::Mat oVariationModulatorFrameNormalized; cv::normalize(m_oVariationModulatorFrame,oVariationModulatorFrameNormalized,0,255,cv::NORM_MINMAX,CV_8UC1);
-	cv::circle(oVariationModulatorFrameNormalized,dbgpt,5,cv::Scalar(255));
-	cv::resize(oVariationModulatorFrameNormalized,oVariationModulatorFrameNormalized,DEFAULT_FRAME_SIZE);
-	cv::imshow("v(x)",oVariationModulatorFrameNormalized);
-	std::cout << std::fixed << std::setprecision(5) << "      v(" << dbgpt << ") = " << m_oVariationModulatorFrame.at<float>(dbgpt) << std::endl;
-	cv::Mat oUpdateRateFrameNormalized; m_oUpdateRateFrame.convertTo(oUpdateRateFrameNormalized,CV_32FC1,1.0f/FEEDBACK_T_UPPER,-FEEDBACK_T_LOWER/FEEDBACK_T_UPPER);
-	cv::circle(oUpdateRateFrameNormalized,dbgpt,5,cv::Scalar(1.0f));
-	cv::resize(oUpdateRateFrameNormalized,oUpdateRateFrameNormalized,DEFAULT_FRAME_SIZE);
-	cv::imshow("t(x)",oUpdateRateFrameNormalized);
-	std::cout << std::fixed << std::setprecision(5) << "      t(" << dbgpt << ") = " << m_oUpdateRateFrame.at<float>(dbgpt) << std::endl;
-#endif //DISPLAY_SUBSENSE_DEBUG_INFO
-	cv::bitwise_xor(oCurrFGMask,m_oLastRawFGMask,m_oCurrRawFGBlinkMask);
-	cv::bitwise_or(m_oCurrRawFGBlinkMask,m_oLastRawFGBlinkMask,m_oBlinksFrame);
-	m_oCurrRawFGBlinkMask.copyTo(m_oLastRawFGBlinkMask);
-	oCurrFGMask.copyTo(m_oLastRawFGMask);
-	cv::morphologyEx(oCurrFGMask,m_oFGMask_PreFlood,cv::MORPH_CLOSE,cv::Mat());
-	m_oFGMask_PreFlood.copyTo(m_oFGMask_FloodedHoles);
-	cv::floodFill(m_oFGMask_FloodedHoles,cv::Point(0,0),UCHAR_MAX);
-	cv::bitwise_not(m_oFGMask_FloodedHoles,m_oFGMask_FloodedHoles);
-	cv::erode(m_oFGMask_PreFlood,m_oFGMask_PreFlood,cv::Mat(),cv::Point(-1,-1),3);
-	cv::bitwise_or(oCurrFGMask,m_oFGMask_FloodedHoles,oCurrFGMask);
-	cv::bitwise_or(oCurrFGMask,m_oFGMask_PreFlood,oCurrFGMask);
-	cv::medianBlur(oCurrFGMask,m_oLastFGMask,m_nMedianBlurKernelSize);
-	cv::dilate(m_oLastFGMask,m_oLastFGMask_dilated,cv::Mat(),cv::Point(-1,-1),3);
-	cv::bitwise_and(m_oBlinksFrame,m_oLastFGMask_dilated_inverted,m_oBlinksFrame);
-	cv::bitwise_not(m_oLastFGMask_dilated,m_oLastFGMask_dilated_inverted);
-	cv::bitwise_and(m_oBlinksFrame,m_oLastFGMask_dilated_inverted,m_oBlinksFrame);
-	m_oLastFGMask.copyTo(oCurrFGMask);
-	cv::addWeighted(m_oMeanFinalSegmResFrame_LT,(1.0f-fRollAvgFactor_LT),m_oLastFGMask,(1.0/UCHAR_MAX)*fRollAvgFactor_LT,0,m_oMeanFinalSegmResFrame_LT,CV_32F);
-	cv::addWeighted(m_oMeanFinalSegmResFrame_ST,(1.0f-fRollAvgFactor_ST),m_oLastFGMask,(1.0/UCHAR_MAX)*fRollAvgFactor_ST,0,m_oMeanFinalSegmResFrame_ST,CV_32F);
-	const float fCurrNonZeroDescRatio = (float)nNonZeroDescCount/m_nTotRelevantPxCount;
-	if(fCurrNonZeroDescRatio<LBSPDESC_NONZERO_RATIO_MIN && m_fLastNonZeroDescRatio<LBSPDESC_NONZERO_RATIO_MIN) {
-	    for(size_t t=0; t<=UCHAR_MAX; ++t)
-	        if(m_anLBSPThreshold_8bitLUT[t]>cv::saturate_cast<uchar>(m_nLBSPThresholdOffset+ceil(t*m_fRelLBSPThreshold/4)))
-	            --m_anLBSPThreshold_8bitLUT[t];
-	}
-	else if(fCurrNonZeroDescRatio>LBSPDESC_NONZERO_RATIO_MAX && m_fLastNonZeroDescRatio>LBSPDESC_NONZERO_RATIO_MAX) {
-	    for(size_t t=0; t<=UCHAR_MAX; ++t)
-	        if(m_anLBSPThreshold_8bitLUT[t]<cv::saturate_cast<uchar>(m_nLBSPThresholdOffset+UCHAR_MAX*m_fRelLBSPThreshold))
-	            ++m_anLBSPThreshold_8bitLUT[t];
-	}
-	m_fLastNonZeroDescRatio = fCurrNonZeroDescRatio;
-	if(m_bLearningRateScalingEnabled) {
-		cv::resize(oInputImg,m_oDownSampledFrame_MotionAnalysis,m_oDownSampledFrameSize,0,0,cv::INTER_AREA);
-		cv::accumulateWeighted(m_oDownSampledFrame_MotionAnalysis,m_oMeanDownSampledLastDistFrame_LT,fRollAvgFactor_LT);
-		cv::accumulateWeighted(m_oDownSampledFrame_MotionAnalysis,m_oMeanDownSampledLastDistFrame_ST,fRollAvgFactor_ST);
-		size_t nTotColorDiff = 0;
-		for(int i=0; i<m_oMeanDownSampledLastDistFrame_ST.rows; ++i) {
-			const size_t idx1 = m_oMeanDownSampledLastDistFrame_ST.step.p[0]*i;
-			for(int j=0; j<m_oMeanDownSampledLastDistFrame_ST.cols; ++j) {
-				const size_t idx2 = idx1+m_oMeanDownSampledLastDistFrame_ST.step.p[1]*j;
-				nTotColorDiff += (m_nImgChannels==1)?
-					(size_t)fabs((*(float*)(m_oMeanDownSampledLastDistFrame_ST.data+idx2))-(*(float*)(m_oMeanDownSampledLastDistFrame_LT.data+idx2)))/2
-							:  //(m_nImgChannels==3)
-						std::max((size_t)fabs((*(float*)(m_oMeanDownSampledLastDistFrame_ST.data+idx2))-(*(float*)(m_oMeanDownSampledLastDistFrame_LT.data+idx2))),
-							std::max((size_t)fabs((*(float*)(m_oMeanDownSampledLastDistFrame_ST.data+idx2+4))-(*(float*)(m_oMeanDownSampledLastDistFrame_LT.data+idx2+4))),
-										(size_t)fabs((*(float*)(m_oMeanDownSampledLastDistFrame_ST.data+idx2+8))-(*(float*)(m_oMeanDownSampledLastDistFrame_LT.data+idx2+8)))));
-			}
-		}
-		const float fCurrColorDiffRatio = (float)nTotColorDiff/(m_oMeanDownSampledLastDistFrame_ST.rows*m_oMeanDownSampledLastDistFrame_ST.cols);
-		if(m_bAutoModelResetEnabled) {
-			if(m_nFramesSinceLastReset>1000)
-				m_bAutoModelResetEnabled = false;
-			else if(fCurrColorDiffRatio>=FRAMELEVEL_MIN_COLOR_DIFF_THRESHOLD && m_nModelResetCooldown==0) {
-				m_nFramesSinceLastReset = 0;
-				refreshModel(0.1f); // reset 10% of the bg model
-				m_nModelResetCooldown = m_nSamplesForMovingAvgs/4;
-				m_oUpdateRateFrame = cv::Scalar(1.0f);
-			}
-			else
-				++m_nFramesSinceLastReset;
-		}
-		else if(fCurrColorDiffRatio>=FRAMELEVEL_MIN_COLOR_DIFF_THRESHOLD*2) {
-			m_nFramesSinceLastReset = 0;
-			m_bAutoModelResetEnabled = true;
-		}
-		if(fCurrColorDiffRatio>=FRAMELEVEL_MIN_COLOR_DIFF_THRESHOLD/2) {
-			m_fCurrLearningRateLowerCap = (float)std::max((int)FEEDBACK_T_LOWER>>(int)(fCurrColorDiffRatio/2),1);
-			m_fCurrLearningRateUpperCap = (float)std::max((int)FEEDBACK_T_UPPER>>(int)(fCurrColorDiffRatio/2),1);
-		}
-		else {
-			m_fCurrLearningRateLowerCap = FEEDBACK_T_LOWER;
-			m_fCurrLearningRateUpperCap = FEEDBACK_T_UPPER;
-		}
-		if(m_nModelResetCooldown>0)
-			--m_nModelResetCooldown;
-	}
-}
-
-void BackgroundSubtractorSuBSENSE::getBackgroundImage(cv::OutputArray backgroundImage) const {
-	CV_Assert(m_bInitialized);
-	cv::Mat oAvgBGImg = cv::Mat::zeros(m_oImgSize,CV_32FC((int)m_nImgChannels));
-	for(size_t s=0; s<m_nBGSamples; ++s) {
-		for(int y=0; y<m_oImgSize.height; ++y) {
-			for(int x=0; x<m_oImgSize.width; ++x) {
-				const size_t idx_nimg = m_voBGColorSamples[s].step.p[0]*y + m_voBGColorSamples[s].step.p[1]*x;
-				const size_t nFloatIter = idx_nimg*4;
-				float* oAvgBgImgPtr = (float*)(oAvgBGImg.data+nFloatIter);
-				const uchar* const oBGImgPtr = m_voBGColorSamples[s].data+idx_nimg;
-				for(size_t c=0; c<m_nImgChannels; ++c)
-					oAvgBgImgPtr[c] += ((float)oBGImgPtr[c])/m_nBGSamples;
-			}
-		}
-	}
-	oAvgBGImg.convertTo(backgroundImage,CV_8U);
-}
-
-void BackgroundSubtractorSuBSENSE::getBackgroundDescriptorsImage(cv::OutputArray backgroundDescImage) const {
-	CV_Assert(LBSP::DESC_SIZE==2);
-	CV_Assert(m_bInitialized);
-	cv::Mat oAvgBGDesc = cv::Mat::zeros(m_oImgSize,CV_32FC((int)m_nImgChannels));
-	for(size_t n=0; n<m_voBGDescSamples.size(); ++n) {
-		for(int y=0; y<m_oImgSize.height; ++y) {
-			for(int x=0; x<m_oImgSize.width; ++x) {
-				const size_t idx_ndesc = m_voBGDescSamples[n].step.p[0]*y + m_voBGDescSamples[n].step.p[1]*x;
-				const size_t nFloatIter = idx_ndesc*2;
-				float* oAvgBgDescPtr = (float*)(oAvgBGDesc.data+nFloatIter);
-				const ushort* const oBGDescPtr = (ushort*)(m_voBGDescSamples[n].data+idx_ndesc);
-				for(size_t c=0; c<m_nImgChannels; ++c)
-					oAvgBgDescPtr[c] += ((float)oBGDescPtr[c])/m_voBGDescSamples.size();
-			}
-		}
-	}
-	oAvgBGDesc.convertTo(backgroundDescImage,CV_16U);
-}
diff --git a/package_bgs/pl/BackgroundSubtractorSuBSENSE.h b/package_bgs/pl/BackgroundSubtractorSuBSENSE.h
deleted file mode 100644
index f8424ad1761219c8f833e598d6b2cf1e0051c57f..0000000000000000000000000000000000000000
--- a/package_bgs/pl/BackgroundSubtractorSuBSENSE.h
+++ /dev/null
@@ -1,113 +0,0 @@
-#pragma once
-
-#include "BackgroundSubtractorLBSP.h"
-
-//! defines the default value for BackgroundSubtractorLBSP::m_fRelLBSPThreshold
-#define BGSSUBSENSE_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD (0.333f)
-//! defines the default value for BackgroundSubtractorSuBSENSE::m_nDescDistThresholdOffset
-#define BGSSUBSENSE_DEFAULT_DESC_DIST_THRESHOLD_OFFSET (3)
-//! defines the default value for BackgroundSubtractorSuBSENSE::m_nMinColorDistThreshold
-#define BGSSUBSENSE_DEFAULT_MIN_COLOR_DIST_THRESHOLD (30)
-//! defines the default value for BackgroundSubtractorSuBSENSE::m_nBGSamples
-#define BGSSUBSENSE_DEFAULT_NB_BG_SAMPLES (50)
-//! defines the default value for BackgroundSubtractorSuBSENSE::m_nRequiredBGSamples
-#define BGSSUBSENSE_DEFAULT_REQUIRED_NB_BG_SAMPLES (2)
-//! defines the default value for BackgroundSubtractorSuBSENSE::m_nSamplesForMovingAvgs
-#define BGSSUBSENSE_DEFAULT_N_SAMPLES_FOR_MV_AVGS (100)
-
-/*!
-	Self-Balanced Sensitivity segmenTER (SuBSENSE) change detection algorithm.
-
-	Note: both grayscale and RGB/BGR images may be used with this extractor (parameters are adjusted automatically).
-	For optimal grayscale results, use CV_8UC1 frames instead of CV_8UC3.
-
-	For more details on the different parameters or on the algorithm itself, see P.-L. St-Charles et al.,
-	"Flexible Background Subtraction With Self-Balanced Local Sensitivity", in CVPRW 2014.
-
-	This algorithm is currently NOT thread-safe.
- */
-class BackgroundSubtractorSuBSENSE : public BackgroundSubtractorLBSP {
-public:
-	//! full constructor
-	BackgroundSubtractorSuBSENSE(	float fRelLBSPThreshold=BGSSUBSENSE_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD,
-									size_t nDescDistThresholdOffset=BGSSUBSENSE_DEFAULT_DESC_DIST_THRESHOLD_OFFSET,
-									size_t nMinColorDistThreshold=BGSSUBSENSE_DEFAULT_MIN_COLOR_DIST_THRESHOLD,
-									size_t nBGSamples=BGSSUBSENSE_DEFAULT_NB_BG_SAMPLES,
-									size_t nRequiredBGSamples=BGSSUBSENSE_DEFAULT_REQUIRED_NB_BG_SAMPLES,
-									size_t nSamplesForMovingAvgs=BGSSUBSENSE_DEFAULT_N_SAMPLES_FOR_MV_AVGS);
-	//! default destructor
-	virtual ~BackgroundSubtractorSuBSENSE();
-	//! (re)initiaization method; needs to be called before starting background subtraction
-	virtual void initialize(const cv::Mat& oInitImg, const cv::Mat& oROI);
-	//! refreshes all samples based on the last analyzed frame
-	virtual void refreshModel(float fSamplesRefreshFrac, bool bForceFGUpdate=false);
-	//! primary model update function; the learning param is used to override the internal learning thresholds (ignored when <= 0)
-	virtual void operator()(cv::InputArray image, cv::OutputArray fgmask, double learningRateOverride=0);
-	//! returns a copy of the latest reconstructed background image
-	void getBackgroundImage(cv::OutputArray backgroundImage) const;
-	//! returns a copy of the latest reconstructed background descriptors image
-	void getBackgroundDescriptorsImage(cv::OutputArray backgroundDescImage) const;
-
-protected:
-	//! absolute minimal color distance threshold ('R' or 'radius' in the original ViBe paper, used as the default/initial 'R(x)' value here)
-	const size_t m_nMinColorDistThreshold;
-	//! absolute descriptor distance threshold offset
-	const size_t m_nDescDistThresholdOffset;
-	//! number of different samples per pixel/block to be taken from input frames to build the background model (same as 'N' in ViBe/PBAS)
-	const size_t m_nBGSamples;
-	//! number of similar samples needed to consider the current pixel/block as 'background' (same as '#_min' in ViBe/PBAS)
-	const size_t m_nRequiredBGSamples;
-	//! number of samples to use to compute the learning rate of moving averages
-	const size_t m_nSamplesForMovingAvgs;
-	//! last calculated non-zero desc ratio
-	float m_fLastNonZeroDescRatio;
-	//! specifies whether Tmin/Tmax scaling is enabled or not
-	bool m_bLearningRateScalingEnabled;
-	//! current learning rate caps
-	float m_fCurrLearningRateLowerCap, m_fCurrLearningRateUpperCap;
-	//! current kernel size for median blur post-proc filtering
-	int m_nMedianBlurKernelSize;
-	//! specifies the px update spread range
-	bool m_bUse3x3Spread;
-	//! specifies the downsampled frame size used for cam motion analysis
-	cv::Size m_oDownSampledFrameSize;
-
-	//! background model pixel color intensity samples (equivalent to 'B(x)' in PBAS)
-	std::vector<cv::Mat> m_voBGColorSamples;
-	//! background model descriptors samples
-	std::vector<cv::Mat> m_voBGDescSamples;
-
-	//! per-pixel update rates ('T(x)' in PBAS, which contains pixel-level 'sigmas', as referred to in ViBe)
-	cv::Mat m_oUpdateRateFrame;
-	//! per-pixel distance thresholds (equivalent to 'R(x)' in PBAS, but used as a relative value to determine both intensity and descriptor variation thresholds)
-	cv::Mat m_oDistThresholdFrame;
-	//! per-pixel distance variation modulators ('v(x)', relative value used to modulate 'R(x)' and 'T(x)' variations)
-	cv::Mat m_oVariationModulatorFrame;
-	//! per-pixel mean distances between consecutive frames ('D_last(x)', used to detect ghosts and high variation regions in the sequence)
-	cv::Mat m_oMeanLastDistFrame;
-	//! per-pixel mean minimal distances from the model ('D_min(x)' in PBAS, used to control variation magnitude and direction of 'T(x)' and 'R(x)')
-	cv::Mat m_oMeanMinDistFrame_LT, m_oMeanMinDistFrame_ST;
-	//! per-pixel mean downsampled distances between consecutive frames (used to analyze camera movement and control max learning rates globally)
-	cv::Mat m_oMeanDownSampledLastDistFrame_LT, m_oMeanDownSampledLastDistFrame_ST;
-	//! per-pixel mean raw segmentation results (used to detect unstable segmentation regions)
-	cv::Mat m_oMeanRawSegmResFrame_LT, m_oMeanRawSegmResFrame_ST;
-	//! per-pixel mean raw segmentation results (used to detect unstable segmentation regions)
-	cv::Mat m_oMeanFinalSegmResFrame_LT, m_oMeanFinalSegmResFrame_ST;
-	//! a lookup map used to keep track of unstable regions (based on segm. noise & local dist. thresholds)
-	cv::Mat m_oUnstableRegionMask;
-	//! per-pixel blink detection map ('Z(x)')
-	cv::Mat m_oBlinksFrame;
-	//! pre-allocated matrix used to downsample the input frame when needed
-	cv::Mat m_oDownSampledFrame_MotionAnalysis;
-	//! the foreground mask generated by the method at [t-1] (without post-proc, used for blinking px detection)
-	cv::Mat m_oLastRawFGMask;
-
-	//! pre-allocated CV_8UC1 matrices used to speed up morph ops
-	cv::Mat m_oFGMask_PreFlood;
-	cv::Mat m_oFGMask_FloodedHoles;
-	cv::Mat m_oLastFGMask_dilated;
-	cv::Mat m_oLastFGMask_dilated_inverted;
-	cv::Mat m_oCurrRawFGBlinkMask;
-	cv::Mat m_oLastRawFGBlinkMask;
-};
-
diff --git a/package_bgs/pl/DistanceUtils.h b/package_bgs/pl/DistanceUtils.h
deleted file mode 100644
index 54d1cecd933b45a036c8222bed594d0b2305ef89..0000000000000000000000000000000000000000
--- a/package_bgs/pl/DistanceUtils.h
+++ /dev/null
@@ -1,316 +0,0 @@
-#pragma once
-
-#include <opencv2/core/types_c.h>
-
-//! computes the L1 distance between two integer values
-template<typename T> static inline typename std::enable_if<std::is_integral<T>::value,size_t>::type L1dist(T a, T b) {
-	return (size_t)abs((int)a-b);
-}
-
-//! computes the L1 distance between two float values
-template<typename T> static inline typename std::enable_if<std::is_floating_point<T>::value,float>::type L1dist(T a, T b) {
-	return fabs((float)a-(float)b);
-}
-
-//! computes the L1 distance between two generic arrays
-template<size_t nChannels, typename T> static inline auto L1dist(const T* a, const T* b) -> decltype(L1dist(*a,*b)) {
-	decltype(L1dist(*a,*b)) oResult = 0;
-	for(size_t c=0; c<nChannels; ++c)
-		oResult += L1dist(a[c],b[c]);
-	return oResult;
-}
-
-//! computes the L1 distance between two generic arrays
-template<size_t nChannels, typename T> static inline auto L1dist(const T* a, const T* b, size_t nElements, const uchar* m=NULL) -> decltype(L1dist<nChannels>(a,b)) {
-	decltype(L1dist<nChannels>(a,b)) oResult = 0;
-	size_t nTotElements = nElements*nChannels;
-	if(m) {
-		for(size_t n=0,i=0; n<nTotElements; n+=nChannels,++i)
-			if(m[i])
-				oResult += L1dist<nChannels>(a+n,b+n);
-	}
-	else {
-		for(size_t n=0; n<nTotElements; n+=nChannels)
-			oResult += L1dist<nChannels>(a+n,b+n);
-	}
-	return oResult;
-}
-
-//! computes the L1 distance between two generic arrays
-template<typename T> static inline auto L1dist(const T* a, const T* b, size_t nElements, size_t nChannels, const uchar* m=NULL) -> decltype(L1dist<3>(a,b,nElements,m)) {
-	CV_Assert(nChannels>0 && nChannels<=4);
-	switch(nChannels) {
-		case 1: return L1dist<1>(a,b,nElements,m);
-		case 2: return L1dist<2>(a,b,nElements,m);
-		case 3: return L1dist<3>(a,b,nElements,m);
-		case 4: return L1dist<4>(a,b,nElements,m);
-		default: return 0;
-	}
-}
-
-//! computes the L1 distance between two opencv vectors
-template<size_t nChannels, typename T> static inline auto L1dist_(const cv::Vec<T,nChannels>& a, const cv::Vec<T,nChannels>& b) -> decltype(L1dist<nChannels,T>((T*)(0),(T*)(0))) {
-	T a_array[nChannels], b_array[nChannels];
-	for(size_t c=0; c<nChannels; ++c) {
-		a_array[c] = a[(int)c];
-		b_array[c] = b[(int)c];
-	}
-	return L1dist<nChannels>(a_array,b_array);
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-//! computes the squared L2 distance between two generic variables
-template<typename T> static inline auto L2sqrdist(T a, T b) -> decltype(L1dist(a,b)) {
-	auto oResult = L1dist(a,b);
-	return oResult*oResult;
-}
-
-//! computes the squared L2 distance between two generic arrays
-template<size_t nChannels, typename T> static inline auto L2sqrdist(const T* a, const T* b) -> decltype(L2sqrdist(*a,*b)) {
-	decltype(L2sqrdist(*a,*b)) oResult = 0;
-	for(size_t c=0; c<nChannels; ++c)
-		oResult += L2sqrdist(a[c],b[c]);
-	return oResult;
-}
-
-//! computes the squared L2 distance between two generic arrays
-template<size_t nChannels, typename T> static inline auto L2sqrdist(const T* a, const T* b, size_t nElements, const uchar* m=NULL) -> decltype(L2sqrdist<nChannels>(a,b)) {
-	decltype(L2sqrdist<nChannels>(a,b)) oResult = 0;
-	size_t nTotElements = nElements*nChannels;
-	if(m) {
-		for(size_t n=0,i=0; n<nTotElements; n+=nChannels,++i)
-			if(m[i])
-				oResult += L2sqrdist<nChannels>(a+n,b+n);
-	}
-	else {
-		for(size_t n=0; n<nTotElements; n+=nChannels)
-			oResult += L2sqrdist<nChannels>(a+n,b+n);
-	}
-	return oResult;
-}
-
-//! computes the squared L2 distance between two generic arrays
-template<typename T> static inline auto L2sqrdist(const T* a, const T* b, size_t nElements, size_t nChannels, const uchar* m=NULL) -> decltype(L2sqrdist<3>(a,b,nElements,m)) {
-	CV_Assert(nChannels>0 && nChannels<=4);
-	switch(nChannels) {
-		case 1: return L2sqrdist<1>(a,b,nElements,m);
-		case 2: return L2sqrdist<2>(a,b,nElements,m);
-		case 3: return L2sqrdist<3>(a,b,nElements,m);
-		case 4: return L2sqrdist<4>(a,b,nElements,m);
-		default: return 0;
-	}
-}
-
-//! computes the squared L2 distance between two opencv vectors
-template<size_t nChannels, typename T> static inline auto L2sqrdist_(const cv::Vec<T,nChannels>& a, const cv::Vec<T,nChannels>& b) -> decltype(L2sqrdist<nChannels,T>((T*)(0),(T*)(0))) {
-	T a_array[nChannels], b_array[nChannels];
-	for(size_t c=0; c<nChannels; ++c) {
-		a_array[c] = a[(int)c];
-		b_array[c] = b[(int)c];
-	}
-	return L2sqrdist<nChannels>(a_array,b_array);
-}
-
-//! computes the L2 distance between two generic arrays
-template<size_t nChannels, typename T> static inline float L2dist(const T* a, const T* b) {
-	decltype(L2sqrdist(*a,*b)) oResult = 0;
-	for(size_t c=0; c<nChannels; ++c)
-		oResult += L2sqrdist(a[c],b[c]);
-	return sqrt((float)oResult);
-}
-
-//! computes the L2 distance between two generic arrays
-template<size_t nChannels, typename T> static inline float L2dist(const T* a, const T* b, size_t nElements, const uchar* m=NULL) {
-	decltype(L2sqrdist<nChannels>(a,b)) oResult = 0;
-	size_t nTotElements = nElements*nChannels;
-	if(m) {
-		for(size_t n=0,i=0; n<nTotElements; n+=nChannels,++i)
-			if(m[i])
-				oResult += L2sqrdist<nChannels>(a+n,b+n);
-	}
-	else {
-		for(size_t n=0; n<nTotElements; n+=nChannels)
-			oResult += L2sqrdist<nChannels>(a+n,b+n);
-	}
-	return sqrt((float)oResult);
-}
-
-//! computes the squared L2 distance between two generic arrays
-template<typename T> static inline float L2dist(const T* a, const T* b, size_t nElements, size_t nChannels, const uchar* m=NULL) {
-	CV_Assert(nChannels>0 && nChannels<=4);
-	switch(nChannels) {
-		case 1: return L2dist<1>(a,b,nElements,m);
-		case 2: return L2dist<2>(a,b,nElements,m);
-		case 3: return L2dist<3>(a,b,nElements,m);
-		case 4: return L2dist<4>(a,b,nElements,m);
-		default: return 0;
-	}
-}
-
-//! computes the L2 distance between two opencv vectors
-template<size_t nChannels, typename T> static inline float L2dist_(const cv::Vec<T,nChannels>& a, const cv::Vec<T,nChannels>& b) {
-	T a_array[nChannels], b_array[nChannels];
-	for(size_t c=0; c<nChannels; ++c) {
-		a_array[c] = a[(int)c];
-		b_array[c] = b[(int)c];
-	}
-	return L2dist<nChannels>(a_array,b_array);
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-//! computes the color distortion between two integer arrays
-template<size_t nChannels, typename T> static inline typename std::enable_if<std::is_integral<T>::value,size_t>::type cdist(const T* curr, const T* bg) {
-	static_assert(nChannels>1,"cdist: requires more than one channel");
-	size_t curr_sqr = 0;
-	bool bSkip = true;
-	for(size_t c=0; c<nChannels; ++c) {
-		curr_sqr += curr[c]*curr[c];
-		bSkip = bSkip&(bg[c]<=0);
-	}
-	if(bSkip)
-		return (size_t)sqrt((float)curr_sqr);
-	size_t bg_sqr = 0;
-	size_t mix = 0;
-	for(size_t c=0; c<nChannels; ++c) {
-		bg_sqr += bg[c]*bg[c];
-		mix += curr[c]*bg[c];
-	}
-	return (size_t)sqrt(curr_sqr-((float)(mix*mix)/bg_sqr));
-}
-
-//! computes the color distortion between two float arrays
-template<size_t nChannels, typename T> static inline typename std::enable_if<std::is_floating_point<T>::value,float>::type cdist(const T* curr, const T* bg) {
-	static_assert(nChannels>1,"cdist: requires more than one channel");
-	float curr_sqr = 0;
-	bool bSkip = true;
-	for(size_t c=0; c<nChannels; ++c) {
-		curr_sqr += (float)curr[c]*curr[c];
-		bSkip = bSkip&(bg[c]<=0);
-	}
-	if(bSkip)
-		return sqrt(curr_sqr);
-	float bg_sqr = 0;
-	float mix = 0;
-	for(size_t c=0; c<nChannels; ++c) {
-		bg_sqr += (float)bg[c]*bg[c];
-		mix += (float)curr[c]*bg[c];
-	}
-	return sqrt(curr_sqr-((mix*mix)/bg_sqr));
-}
-
-//! computes the color distortion between two generic arrays
-template<size_t nChannels, typename T> static inline auto cdist(const T* a, const T* b, size_t nElements, const uchar* m=NULL) -> decltype(cdist<nChannels>(a,b)) {
-	decltype(cdist<nChannels>(a,b)) oResult = 0;
-	size_t nTotElements = nElements*nChannels;
-	if(m) {
-		for(size_t n=0,i=0; n<nTotElements; n+=nChannels,++i)
-			if(m[i])
-				oResult += cdist<nChannels>(a+n,b+n);
-	}
-	else {
-		for(size_t n=0; n<nTotElements; n+=nChannels)
-			oResult += cdist<nChannels>(a+n,b+n);
-	}
-	return oResult;
-}
-
-//! computes the color distortion between two generic arrays
-template<typename T> static inline auto cdist(const T* a, const T* b, size_t nElements, size_t nChannels, const uchar* m=NULL) -> decltype(cdist<3>(a,b,nElements,m)) {
-	CV_Assert(nChannels>1 && nChannels<=4);
-	switch(nChannels) {
-		case 2: return cdist<2>(a,b,nElements,m);
-		case 3: return cdist<3>(a,b,nElements,m);
-		case 4: return cdist<4>(a,b,nElements,m);
-		default: return 0;
-	}
-}
-
-//! computes the color distortion between two opencv vectors
-template<size_t nChannels, typename T> static inline auto cdist_(const cv::Vec<T,nChannels>& a, const cv::Vec<T,nChannels>& b) -> decltype(cdist<nChannels,T>((T*)(0),(T*)(0))) {
-	T a_array[nChannels], b_array[nChannels];
-	for(size_t c=0; c<nChannels; ++c) {
-		a_array[c] = a[(int)c];
-		b_array[c] = b[(int)c];
-	}
-	return cdist<nChannels>(a_array,b_array);
-}
-
-//! computes a color distortion-distance mix using two generic distances
-template<typename T> static inline T cmixdist(T oL1Distance, T oCDistortion) {
-	return (oL1Distance/2+oCDistortion*4);
-}
-
-//! computes a color distoirtion-distance mix using two generic arrays
-template<size_t nChannels, typename T> static inline typename std::enable_if<std::is_integral<T>::value,size_t>::type cmixdist(const T* curr, const T* bg) {
-	return cmixdist(L1dist<nChannels>(curr,bg),cdist<nChannels>(curr,bg));
-}
-
-template<size_t nChannels, typename T> static inline typename std::enable_if<std::is_floating_point<T>::value,float>::type cmixdist(const T* curr, const T* bg) {
-	return cmixdist(L1dist<nChannels>(curr,bg),cdist<nChannels>(curr,bg));
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-//! popcount LUT for 8-bit vectors
-static const uchar popcount_LUT8[256] = {
-	0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
-	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
-	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
-	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
-	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
-	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
-	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
-	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
-	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
-	4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
-};
-
-//! computes the population count of an N-byte vector using an 8-bit popcount LUT
-template<typename T> static inline size_t popcount(T x) {
-	size_t nBytes = sizeof(T);
-	size_t nResult = 0;
-	for(size_t l=0; l<nBytes; ++l)
-		nResult += popcount_LUT8[(uchar)(x>>l*8)];
-	return nResult;
-}
-
-//! computes the hamming distance between two N-byte vectors using an 8-bit popcount LUT
-template<typename T> static inline size_t hdist(T a, T b) {
-	return popcount(a^b);
-}
-
-//! computes the gradient magnitude distance between two N-byte vectors using an 8-bit popcount LUT
-template<typename T> static inline size_t gdist(T a, T b) {
-	return L1dist(popcount(a),popcount(b));
-}
-
-//! computes the population count of a (nChannels*N)-byte vector using an 8-bit popcount LUT
-template<size_t nChannels, typename T> static inline size_t popcount(const T* x) {
-	size_t nBytes = sizeof(T);
-	size_t nResult = 0;
-	for(size_t c=0; c<nChannels; ++c)
-		for(size_t l=0; l<nBytes; ++l)
-			nResult += popcount_LUT8[(uchar)(*(x+c)>>l*8)];
-	return nResult;
-}
-
-//! computes the hamming distance between two (nChannels*N)-byte vectors using an 8-bit popcount LUT
-template<size_t nChannels, typename T> static inline size_t hdist(const T* a, const T* b) {
-	T xor_array[nChannels];
-	for(size_t c=0; c<nChannels; ++c)
-		xor_array[c] = a[c]^b[c];
-	return popcount<nChannels>(xor_array);
-}
-
-//! computes the gradient magnitude distance between two (nChannels*N)-byte vectors using an 8-bit popcount LUT
-template<size_t nChannels, typename T> static inline size_t gdist(const T* a, const T* b) {
-	return L1dist(popcount<nChannels>(a),popcount<nChannels>(b));
-}
diff --git a/package_bgs/pl/LBSP.cpp b/package_bgs/pl/LBSP.cpp
deleted file mode 100644
index de35f1a09bd8b4d0b762b390475c111916e0be11..0000000000000000000000000000000000000000
--- a/package_bgs/pl/LBSP.cpp
+++ /dev/null
@@ -1,318 +0,0 @@
-#include "LBSP.h"
-
-LBSP::LBSP(size_t nThreshold)
-	:	 m_bOnlyUsingAbsThreshold(true)
-		,m_fRelThreshold(0) // unused
-		,m_nThreshold(nThreshold)
-		,m_oRefImage() {}
-
-LBSP::LBSP(float fRelThreshold, size_t nThresholdOffset)
-	:	 m_bOnlyUsingAbsThreshold(false)
-		,m_fRelThreshold(fRelThreshold)
-		,m_nThreshold(nThresholdOffset)
-		,m_oRefImage() {
-	CV_Assert(m_fRelThreshold>=0);
-}
-
-LBSP::~LBSP() {}
-
-void LBSP::read(const cv::FileNode& /*fn*/) {
-    // ... = fn["..."];
-}
-
-void LBSP::write(cv::FileStorage& /*fs*/) const {
-    //fs << "..." << ...;
-}
-
-void LBSP::setReference(const cv::Mat& img) {
-	CV_DbgAssert(img.empty() || img.type()==CV_8UC1 || img.type()==CV_8UC3);
-	m_oRefImage = img;
-}
-
-int LBSP::descriptorSize() const {
-	return DESC_SIZE;
-}
-
-int LBSP::descriptorType() const {
-	return CV_16U;
-}
-
-bool LBSP::isUsingRelThreshold() const {
-	return !m_bOnlyUsingAbsThreshold;
-}
-
-float LBSP::getRelThreshold() const {
-	return m_fRelThreshold;
-}
-
-size_t LBSP::getAbsThreshold() const {
-	return m_nThreshold;
-}
-
-static inline void lbsp_computeImpl(	const cv::Mat& oInputImg,
-										const cv::Mat& oRefImg,
-										const std::vector<cv::KeyPoint>& voKeyPoints,
-										cv::Mat& oDesc,
-										size_t _t) {
-	CV_DbgAssert(oRefImg.empty() || (oRefImg.size==oInputImg.size && oRefImg.type()==oInputImg.type()));
-	CV_DbgAssert(oInputImg.type()==CV_8UC1 || oInputImg.type()==CV_8UC3);
-	CV_DbgAssert(LBSP::DESC_SIZE==2); // @@@ also relies on a constant desc size
-	const size_t nChannels = (size_t)oInputImg.channels();
-	const size_t _step_row = oInputImg.step.p[0];
-	const uchar* _data = oInputImg.data;
-	const uchar* _refdata = oRefImg.empty()?oInputImg.data:oRefImg.data;
-	const size_t nKeyPoints = voKeyPoints.size();
-	if(nChannels==1) {
-		oDesc.create((int)nKeyPoints,1,CV_16UC1);
-		for(size_t k=0; k<nKeyPoints; ++k) {
-			const int _x = (int)voKeyPoints[k].pt.x;
-			const int _y = (int)voKeyPoints[k].pt.y;
-			const uchar _ref = _refdata[_step_row*(_y)+_x];
-			ushort& _res = oDesc.at<ushort>((int)k);
-			#include "LBSP_16bits_dbcross_1ch.i"
-		}
-	}
-	else { //nChannels==3
-		oDesc.create((int)nKeyPoints,1,CV_16UC3);
-		for(size_t k=0; k<nKeyPoints; ++k) {
-			const int _x = (int)voKeyPoints[k].pt.x;
-			const int _y = (int)voKeyPoints[k].pt.y;
-			const uchar* _ref = _refdata+_step_row*(_y)+3*(_x);
-			ushort* _res = ((ushort*)(oDesc.data + oDesc.step.p[0]*k));
-			#include "LBSP_16bits_dbcross_3ch1t.i"
-		}
-	}
-}
-
-static inline void lbsp_computeImpl(	const cv::Mat& oInputImg,
-										const cv::Mat& oRefImg,
-										const std::vector<cv::KeyPoint>& voKeyPoints,
-										cv::Mat& oDesc,
-										float fThreshold,
-										size_t nThresholdOffset) {
-	CV_DbgAssert(oRefImg.empty() || (oRefImg.size==oInputImg.size && oRefImg.type()==oInputImg.type()));
-	CV_DbgAssert(oInputImg.type()==CV_8UC1 || oInputImg.type()==CV_8UC3);
-	CV_DbgAssert(LBSP::DESC_SIZE==2); // @@@ also relies on a constant desc size
-	CV_DbgAssert(fThreshold>=0);
-	const size_t nChannels = (size_t)oInputImg.channels();
-	const size_t _step_row = oInputImg.step.p[0];
-	const uchar* _data = oInputImg.data;
-	const uchar* _refdata = oRefImg.empty()?oInputImg.data:oRefImg.data;
-	const size_t nKeyPoints = voKeyPoints.size();
-	if(nChannels==1) {
-		oDesc.create((int)nKeyPoints,1,CV_16UC1);
-		for(size_t k=0; k<nKeyPoints; ++k) {
-			const int _x = (int)voKeyPoints[k].pt.x;
-			const int _y = (int)voKeyPoints[k].pt.y;
-			const uchar _ref = _refdata[_step_row*(_y)+_x];
-			ushort& _res = oDesc.at<ushort>((int)k);
-			const size_t _t = (size_t)(_ref*fThreshold)+nThresholdOffset;
-			#include "LBSP_16bits_dbcross_1ch.i"
-		}
-	}
-	else { //nChannels==3
-		oDesc.create((int)nKeyPoints,1,CV_16UC3);
-		for(size_t k=0; k<nKeyPoints; ++k) {
-			const int _x = (int)voKeyPoints[k].pt.x;
-			const int _y = (int)voKeyPoints[k].pt.y;
-			const uchar* _ref = _refdata+_step_row*(_y)+3*(_x);
-			ushort* _res = ((ushort*)(oDesc.data + oDesc.step.p[0]*k));
-			const size_t _t[3] = {(size_t)(_ref[0]*fThreshold)+nThresholdOffset,(size_t)(_ref[1]*fThreshold)+nThresholdOffset,(size_t)(_ref[2]*fThreshold)+nThresholdOffset};
-			#include "LBSP_16bits_dbcross_3ch3t.i"
-		}
-	}
-}
-
-static inline void lbsp_computeImpl2(	const cv::Mat& oInputImg,
-										const cv::Mat& oRefImg,
-										const std::vector<cv::KeyPoint>& voKeyPoints,
-										cv::Mat& oDesc,
-										size_t _t) {
-	CV_DbgAssert(oRefImg.empty() || (oRefImg.size==oInputImg.size && oRefImg.type()==oInputImg.type()));
-	CV_DbgAssert(oInputImg.type()==CV_8UC1 || oInputImg.type()==CV_8UC3);
-	CV_DbgAssert(LBSP::DESC_SIZE==2); // @@@ also relies on a constant desc size
-	const size_t nChannels = (size_t)oInputImg.channels();
-	const size_t _step_row = oInputImg.step.p[0];
-	const uchar* _data = oInputImg.data;
-	const uchar* _refdata = oRefImg.empty()?oInputImg.data:oRefImg.data;
-	const size_t nKeyPoints = voKeyPoints.size();
-	if(nChannels==1) {
-		oDesc.create(oInputImg.size(),CV_16UC1);
-		for(size_t k=0; k<nKeyPoints; ++k) {
-			const int _x = (int)voKeyPoints[k].pt.x;
-			const int _y = (int)voKeyPoints[k].pt.y;
-			const uchar _ref = _refdata[_step_row*(_y)+_x];
-			ushort& _res = oDesc.at<ushort>(_y,_x);
-			#include "LBSP_16bits_dbcross_1ch.i"
-		}
-	}
-	else { //nChannels==3
-		oDesc.create(oInputImg.size(),CV_16UC3);
-		for(size_t k=0; k<nKeyPoints; ++k) {
-			const int _x = (int)voKeyPoints[k].pt.x;
-			const int _y = (int)voKeyPoints[k].pt.y;
-			const uchar* _ref = _refdata+_step_row*(_y)+3*(_x);
-			ushort* _res = ((ushort*)(oDesc.data + oDesc.step.p[0]*_y + oDesc.step.p[1]*_x));
-			#include "LBSP_16bits_dbcross_3ch1t.i"
-		}
-	}
-}
-
-static inline void lbsp_computeImpl2(	const cv::Mat& oInputImg,
-										const cv::Mat& oRefImg,
-										const std::vector<cv::KeyPoint>& voKeyPoints,
-										cv::Mat& oDesc,
-										float fThreshold,
-										size_t nThresholdOffset) {
-	CV_DbgAssert(oRefImg.empty() || (oRefImg.size==oInputImg.size && oRefImg.type()==oInputImg.type()));
-	CV_DbgAssert(oInputImg.type()==CV_8UC1 || oInputImg.type()==CV_8UC3);
-	CV_DbgAssert(LBSP::DESC_SIZE==2); // @@@ also relies on a constant desc size
-	CV_DbgAssert(fThreshold>=0);
-	const size_t nChannels = (size_t)oInputImg.channels();
-	const size_t _step_row = oInputImg.step.p[0];
-	const uchar* _data = oInputImg.data;
-	const uchar* _refdata = oRefImg.empty()?oInputImg.data:oRefImg.data;
-	const size_t nKeyPoints = voKeyPoints.size();
-	if(nChannels==1) {
-		oDesc.create(oInputImg.size(),CV_16UC1);
-		for(size_t k=0; k<nKeyPoints; ++k) {
-			const int _x = (int)voKeyPoints[k].pt.x;
-			const int _y = (int)voKeyPoints[k].pt.y;
-			const uchar _ref = _refdata[_step_row*(_y)+_x];
-			ushort& _res = oDesc.at<ushort>(_y,_x);
-			const size_t _t = (size_t)(_ref*fThreshold)+nThresholdOffset;
-			#include "LBSP_16bits_dbcross_1ch.i"
-		}
-	}
-	else { //nChannels==3
-		oDesc.create(oInputImg.size(),CV_16UC3);
-		for(size_t k=0; k<nKeyPoints; ++k) {
-			const int _x = (int)voKeyPoints[k].pt.x;
-			const int _y = (int)voKeyPoints[k].pt.y;
-			const uchar* _ref = _refdata+_step_row*(_y)+3*(_x);
-			ushort* _res = ((ushort*)(oDesc.data + oDesc.step.p[0]*_y + oDesc.step.p[1]*_x));
-			const size_t _t[3] = {(size_t)(_ref[0]*fThreshold)+nThresholdOffset,(size_t)(_ref[1]*fThreshold)+nThresholdOffset,(size_t)(_ref[2]*fThreshold)+nThresholdOffset};
-			#include "LBSP_16bits_dbcross_3ch3t.i"
-		}
-	}
-}
-
-void LBSP::compute2(const cv::Mat& oImage, std::vector<cv::KeyPoint>& voKeypoints, cv::Mat& oDescriptors) const {
-	CV_Assert(!oImage.empty());
-    cv::KeyPointsFilter::runByImageBorder(voKeypoints,oImage.size(),PATCH_SIZE/2);
-    cv::KeyPointsFilter::runByKeypointSize(voKeypoints,std::numeric_limits<float>::epsilon());
-    if(voKeypoints.empty()) {
-        oDescriptors.release();
-        return;
-    }
-	if(m_bOnlyUsingAbsThreshold)
-		lbsp_computeImpl2(oImage,m_oRefImage,voKeypoints,oDescriptors,m_nThreshold);
-	else
-		lbsp_computeImpl2(oImage,m_oRefImage,voKeypoints,oDescriptors,m_fRelThreshold,m_nThreshold);
-}
-
-void LBSP::compute2(const std::vector<cv::Mat>& voImageCollection, std::vector<std::vector<cv::KeyPoint> >& vvoPointCollection, std::vector<cv::Mat>& voDescCollection) const {
-    CV_Assert(voImageCollection.size() == vvoPointCollection.size());
-    voDescCollection.resize(voImageCollection.size());
-    for(size_t i=0; i<voImageCollection.size(); i++)
-        compute2(voImageCollection[i], vvoPointCollection[i], voDescCollection[i]);
-}
-
-void LBSP::computeImpl(const cv::Mat& oImage, std::vector<cv::KeyPoint>& voKeypoints, cv::Mat& oDescriptors) const {
-	CV_Assert(!oImage.empty());
-	cv::KeyPointsFilter::runByImageBorder(voKeypoints,oImage.size(),PATCH_SIZE/2);
-	cv::KeyPointsFilter::runByKeypointSize(voKeypoints,std::numeric_limits<float>::epsilon());
-	if(voKeypoints.empty()) {
-		oDescriptors.release();
-		return;
-	}
-	if(m_bOnlyUsingAbsThreshold)
-		lbsp_computeImpl(oImage,m_oRefImage,voKeypoints,oDescriptors,m_nThreshold);
-	else
-		lbsp_computeImpl(oImage,m_oRefImage,voKeypoints,oDescriptors,m_fRelThreshold,m_nThreshold);
-}
-
-void LBSP::reshapeDesc(cv::Size oSize, const std::vector<cv::KeyPoint>& voKeypoints, const cv::Mat& oDescriptors, cv::Mat& oOutput) {
-	CV_DbgAssert(!voKeypoints.empty());
-	CV_DbgAssert(!oDescriptors.empty() && oDescriptors.cols==1);
-	CV_DbgAssert(oSize.width>0 && oSize.height>0);
-	CV_DbgAssert(DESC_SIZE==2); // @@@ also relies on a constant desc size
-	CV_DbgAssert(oDescriptors.type()==CV_16UC1 || oDescriptors.type()==CV_16UC3);
-	const size_t nChannels = (size_t)oDescriptors.channels();
-	const size_t nKeyPoints = voKeypoints.size();
-	if(nChannels==1) {
-		oOutput.create(oSize,CV_16UC1);
-		oOutput = cv::Scalar_<ushort>(0);
-		for(size_t k=0; k<nKeyPoints; ++k)
-			oOutput.at<ushort>(voKeypoints[k].pt) = oDescriptors.at<ushort>((int)k);
-	}
-	else { //nChannels==3
-		oOutput.create(oSize,CV_16UC3);
-		oOutput = cv::Scalar_<ushort>(0,0,0);
-		for(size_t k=0; k<nKeyPoints; ++k) {
-			ushort* output_ptr = (ushort*)(oOutput.data + oOutput.step.p[0]*(int)voKeypoints[k].pt.y);
-			const ushort* const desc_ptr = (ushort*)(oDescriptors.data + oDescriptors.step.p[0]*k);
-			const size_t idx = 3*(int)voKeypoints[k].pt.x;
-			for(size_t n=0; n<3; ++n)
-				output_ptr[idx+n] = desc_ptr[n];
-		}
-	}
-}
-
-void LBSP::calcDescImgDiff(const cv::Mat& oDesc1, const cv::Mat& oDesc2, cv::Mat& oOutput, bool bForceMergeChannels) {
-	CV_DbgAssert(oDesc1.size()==oDesc2.size() && oDesc1.type()==oDesc2.type());
-	CV_DbgAssert(DESC_SIZE==2); // @@@ also relies on a constant desc size
-	CV_DbgAssert(oDesc1.type()==CV_16UC1 || oDesc1.type()==CV_16UC3);
-	CV_DbgAssert(CV_MAT_DEPTH(oDesc1.type())==CV_16U);
-	CV_DbgAssert(DESC_SIZE*8<=UCHAR_MAX);
-	CV_DbgAssert(oDesc1.step.p[0]==oDesc2.step.p[0] && oDesc1.step.p[1]==oDesc2.step.p[1]);
-	const float fScaleFactor = (float)UCHAR_MAX/(DESC_SIZE*8);
-	const size_t nChannels = CV_MAT_CN(oDesc1.type());
-	const size_t _step_row = oDesc1.step.p[0];
-	if(nChannels==1) {
-		oOutput.create(oDesc1.size(),CV_8UC1);
-		oOutput = cv::Scalar(0);
-		for(int i=0; i<oDesc1.rows; ++i) {
-			const size_t idx = _step_row*i;
-			const ushort* const desc1_ptr = (ushort*)(oDesc1.data+idx);
-			const ushort* const desc2_ptr = (ushort*)(oDesc2.data+idx);
-			for(int j=0; j<oDesc1.cols; ++j)
-				oOutput.at<uchar>(i,j) = (uchar)(fScaleFactor*hdist(desc1_ptr[j],desc2_ptr[j]));
-		}
-	}
-	else { //nChannels==3
-		if(bForceMergeChannels)
-			oOutput.create(oDesc1.size(),CV_8UC1);
-		else
-			oOutput.create(oDesc1.size(),CV_8UC3);
-		oOutput = cv::Scalar::all(0);
-		for(int i=0; i<oDesc1.rows; ++i) {
-			const size_t idx =  _step_row*i;
-			const ushort* const desc1_ptr = (ushort*)(oDesc1.data+idx);
-			const ushort* const desc2_ptr = (ushort*)(oDesc2.data+idx);
-			uchar* output_ptr = oOutput.data + oOutput.step.p[0]*i;
-			for(int j=0; j<oDesc1.cols; ++j) {
-				for(size_t n=0;n<3; ++n) {
-					const size_t idx2 = 3*j+n;
-					if(bForceMergeChannels)
-						output_ptr[j] += (uchar)((fScaleFactor*hdist(desc1_ptr[idx2],desc2_ptr[idx2]))/3);
-					else
-						output_ptr[idx2] = (uchar)(fScaleFactor*hdist(desc1_ptr[idx2],desc2_ptr[idx2]));
-				}
-			}
-		}
-	}
-}
-
-void LBSP::validateKeyPoints(std::vector<cv::KeyPoint>& voKeypoints, cv::Size oImgSize) {
-	cv::KeyPointsFilter::runByImageBorder(voKeypoints,oImgSize,PATCH_SIZE/2);
-}
-
-void LBSP::validateROI(cv::Mat& oROI) {
-	CV_Assert(!oROI.empty() && oROI.type()==CV_8UC1);
-	cv::Mat oROI_new(oROI.size(),CV_8UC1,cv::Scalar_<uchar>(0));
-	const size_t nBorderSize = PATCH_SIZE/2;
-	const cv::Rect nROI_inner(nBorderSize,nBorderSize,oROI.cols-nBorderSize*2,oROI.rows-nBorderSize*2);
-	cv::Mat(oROI,nROI_inner).copyTo(cv::Mat(oROI_new,nROI_inner));
-	oROI = oROI_new;
-}
diff --git a/package_bgs/pl/LBSP.h b/package_bgs/pl/LBSP.h
deleted file mode 100644
index 1ca17a0125baae1a18e00b0d31fa673c1c34a903..0000000000000000000000000000000000000000
--- a/package_bgs/pl/LBSP.h
+++ /dev/null
@@ -1,118 +0,0 @@
-#pragma once
-
-#include <opencv2/core/core.hpp>
-#include <opencv2/imgproc/imgproc.hpp>
-#include <opencv2/features2d/features2d.hpp>
-#include "DistanceUtils.h"
-
-/*!
-	Local Binary Similarity Pattern (LBSP) feature extractor
-
-	Note 1: both grayscale and RGB/BGR images may be used with this extractor.
-	Note 2: using LBSP::compute2(...) is logically equivalent to using LBSP::compute(...) followed by LBSP::reshapeDesc(...).
-
-	For more details on the different parameters, see G.-A. Bilodeau et al, "Change Detection in Feature Space Using Local
-	Binary Similarity Patterns", in CRV 2013.
-
-	This algorithm is currently NOT thread-safe.
- */
-class LBSP : public cv::DescriptorExtractor {
-public:
-	//! constructor 1, threshold = absolute intensity 'similarity' threshold used when computing comparisons
-	LBSP(size_t nThreshold);
-	//! constructor 2, threshold = relative intensity 'similarity' threshold used when computing comparisons
-	LBSP(float fRelThreshold, size_t nThresholdOffset=0);
-	//! default destructor
-	virtual ~LBSP();
-	//! loads extractor params from the specified file node @@@@ not impl
-	virtual void read(const cv::FileNode&);
-	//! writes extractor params to the specified file storage @@@@ not impl
-	virtual void write(cv::FileStorage&) const;
-	//! sets the 'reference' image to be used for inter-frame comparisons (note: if no image is set or if the image is empty, the algorithm will default back to intra-frame comparisons)
-	virtual void setReference(const cv::Mat&);
-	//! returns the current descriptor size, in bytes
-	virtual int descriptorSize() const;
-	//! returns the current descriptor data type
-	virtual int descriptorType() const;
-	//! returns whether this extractor is using a relative threshold or not
-	virtual bool isUsingRelThreshold() const;
-	//! returns the current relative threshold used for comparisons (-1 = invalid/not used)
-	virtual float getRelThreshold() const;
-	//! returns the current absolute threshold used for comparisons (-1 = invalid/not used)
-	virtual size_t getAbsThreshold() const;
-
-	//! similar to DescriptorExtractor::compute(const cv::Mat& image, ...), but in this case, the descriptors matrix has the same shape as the input matrix (possibly slower, but the result can be displayed)
-	void compute2(const cv::Mat& oImage, std::vector<cv::KeyPoint>& voKeypoints, cv::Mat& oDescriptors) const;
-	//! batch version of LBSP::compute2(const cv::Mat& image, ...), also similar to DescriptorExtractor::compute(const std::vector<cv::Mat>& imageCollection, ...)
-	void compute2(const std::vector<cv::Mat>& voImageCollection, std::vector<std::vector<cv::KeyPoint> >& vvoPointCollection, std::vector<cv::Mat>& voDescCollection) const;
-
-	//! utility function, shortcut/lightweight/direct single-point LBSP computation function for extra flexibility (1-channel version)
-	inline static void computeGrayscaleDescriptor(const cv::Mat& oInputImg, const uchar _ref, const int _x, const int _y, const size_t _t, ushort& _res) {
-		CV_DbgAssert(!oInputImg.empty());
-		CV_DbgAssert(oInputImg.type()==CV_8UC1);
-		CV_DbgAssert(LBSP::DESC_SIZE==2); // @@@ also relies on a constant desc size
-		CV_DbgAssert(_x>=(int)LBSP::PATCH_SIZE/2 && _y>=(int)LBSP::PATCH_SIZE/2);
-		CV_DbgAssert(_x<oInputImg.cols-(int)LBSP::PATCH_SIZE/2 && _y<oInputImg.rows-(int)LBSP::PATCH_SIZE/2);
-		const size_t _step_row = oInputImg.step.p[0];
-		const uchar* const _data = oInputImg.data;
-		#include "LBSP_16bits_dbcross_1ch.i"
-	}
-
-	//! utility function, shortcut/lightweight/direct single-point LBSP computation function for extra flexibility (3-channels version)
-	inline static void computeRGBDescriptor(const cv::Mat& oInputImg, const uchar* const _ref,  const int _x, const int _y, const size_t* const _t, ushort* _res) {
-		CV_DbgAssert(!oInputImg.empty());
-		CV_DbgAssert(oInputImg.type()==CV_8UC3);
-		CV_DbgAssert(LBSP::DESC_SIZE==2); // @@@ also relies on a constant desc size
-		CV_DbgAssert(_x>=(int)LBSP::PATCH_SIZE/2 && _y>=(int)LBSP::PATCH_SIZE/2);
-		CV_DbgAssert(_x<oInputImg.cols-(int)LBSP::PATCH_SIZE/2 && _y<oInputImg.rows-(int)LBSP::PATCH_SIZE/2);
-		const size_t _step_row = oInputImg.step.p[0];
-		const uchar* const _data = oInputImg.data;
-		#include "LBSP_16bits_dbcross_3ch3t.i"
-	}
-
-	//! utility function, shortcut/lightweight/direct single-point LBSP computation function for extra flexibility (3-channels version)
-	inline static void computeRGBDescriptor(const cv::Mat& oInputImg, const uchar* const _ref,  const int _x, const int _y, const size_t _t, ushort* _res) {
-		CV_DbgAssert(!oInputImg.empty());
-		CV_DbgAssert(oInputImg.type()==CV_8UC3);
-		CV_DbgAssert(LBSP::DESC_SIZE==2); // @@@ also relies on a constant desc size
-		CV_DbgAssert(_x>=(int)LBSP::PATCH_SIZE/2 && _y>=(int)LBSP::PATCH_SIZE/2);
-		CV_DbgAssert(_x<oInputImg.cols-(int)LBSP::PATCH_SIZE/2 && _y<oInputImg.rows-(int)LBSP::PATCH_SIZE/2);
-		const size_t _step_row = oInputImg.step.p[0];
-		const uchar* const _data = oInputImg.data;
-		#include "LBSP_16bits_dbcross_3ch1t.i"
-	}
-
-	//! utility function, shortcut/lightweight/direct single-point LBSP computation function for extra flexibility (1-channel-RGB version)
-	inline static void computeSingleRGBDescriptor(const cv::Mat& oInputImg, const uchar _ref, const int _x, const int _y, const size_t _c, const size_t _t, ushort& _res) {
-		CV_DbgAssert(!oInputImg.empty());
-		CV_DbgAssert(oInputImg.type()==CV_8UC3 && _c<3);
-		CV_DbgAssert(LBSP::DESC_SIZE==2); // @@@ also relies on a constant desc size
-		CV_DbgAssert(_x>=(int)LBSP::PATCH_SIZE/2 && _y>=(int)LBSP::PATCH_SIZE/2);
-		CV_DbgAssert(_x<oInputImg.cols-(int)LBSP::PATCH_SIZE/2 && _y<oInputImg.rows-(int)LBSP::PATCH_SIZE/2);
-		const size_t _step_row = oInputImg.step.p[0];
-		const uchar* const _data = oInputImg.data;
-		#include "LBSP_16bits_dbcross_s3ch.i"
-	}
-
-	//! utility function, used to reshape a descriptors matrix to its input image size via their keypoint locations
-	static void reshapeDesc(cv::Size oSize, const std::vector<cv::KeyPoint>& voKeypoints, const cv::Mat& oDescriptors, cv::Mat& oOutput);
-	//! utility function, used to illustrate the difference between two descriptor images
-	static void calcDescImgDiff(const cv::Mat& oDesc1, const cv::Mat& oDesc2, cv::Mat& oOutput, bool bForceMergeChannels=false);
-	//! utility function, used to filter out bad keypoints that would trigger out of bounds error because they're too close to the image border
-	static void validateKeyPoints(std::vector<cv::KeyPoint>& voKeypoints, cv::Size oImgSize);
-	//! utility function, used to filter out bad pixels in a ROI that would trigger out of bounds error because they're too close to the image border
-	static void validateROI(cv::Mat& oROI);
-	//! utility, specifies the pixel size of the pattern used (width and height)
-	static const size_t PATCH_SIZE = 5;
-	//! utility, specifies the number of bytes per descriptor (should be the same as calling 'descriptorSize()')
-	static const size_t DESC_SIZE = 2;
-
-protected:
-	//! classic 'compute' implementation, based on the regular DescriptorExtractor::computeImpl arguments & expected output
-	virtual void computeImpl(const cv::Mat& oImage, std::vector<cv::KeyPoint>& voKeypoints, cv::Mat& oDescriptors) const;
-
-	const bool m_bOnlyUsingAbsThreshold;
-	const float m_fRelThreshold;
-	const size_t m_nThreshold;
-	cv::Mat m_oRefImage;
-};
diff --git a/package_bgs/pl/LOBSTER.cpp b/package_bgs/pl/LOBSTER.cpp
deleted file mode 100644
index f4e9bf62a7433f693f2309c712da197c7fd614b4..0000000000000000000000000000000000000000
--- a/package_bgs/pl/LOBSTER.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-#include "LOBSTER.h"
-#include "BackgroundSubtractorLOBSTER.h"
-
-
-LOBSTERBGS::LOBSTERBGS() :
-pLOBSTER(0), firstTime(true), showOutput(true),
-fRelLBSPThreshold 			(BGSLOBSTER_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD),
-nLBSPThresholdOffset 		(BGSLOBSTER_DEFAULT_LBSP_OFFSET_SIMILARITY_THRESHOLD),
-nDescDistThreshold 			(BGSLOBSTER_DEFAULT_DESC_DIST_THRESHOLD),
-nColorDistThreshold 		(BGSLOBSTER_DEFAULT_COLOR_DIST_THRESHOLD),
-nBGSamples 					(BGSLOBSTER_DEFAULT_NB_BG_SAMPLES),
-nRequiredBGSamples 			(BGSLOBSTER_DEFAULT_REQUIRED_NB_BG_SAMPLES)
-{
-}
-
-LOBSTERBGS::~LOBSTERBGS() {
-	if (pLOBSTER)
-		delete pLOBSTER;
-}
-
-void LOBSTERBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
-{
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if (firstTime) {
-    saveConfig();
-    pLOBSTER = new BackgroundSubtractorLOBSTER(
-    		fRelLBSPThreshold, nLBSPThresholdOffset, nDescDistThreshold,
-    		nColorDistThreshold, nBGSamples, nRequiredBGSamples);
-
-    pLOBSTER->initialize(img_input, cv::Mat (img_input.size(), CV_8UC1, cv::Scalar_<uchar>(255)));
-    firstTime = false;
-  }
-
-  (*pLOBSTER)(img_input, img_output);
-  pLOBSTER->getBackgroundImage(img_bgmodel);
-
-  if(showOutput) {
-	  imshow("LOBSTER FG", img_output);
-	  imshow("LOBSTER BG", img_bgmodel);
-  }
-}
-
-void LOBSTERBGS::saveConfig()
-{
-	CvFileStorage* fs = cvOpenFileStorage("./config/LOBSTERBGS.xml", 0, CV_STORAGE_WRITE);
-
-	cvWriteReal(fs, "fRelLBSPThreshold", fRelLBSPThreshold);
-	cvWriteInt(fs, "nLBSPThresholdOffset", nLBSPThresholdOffset);
-	cvWriteInt(fs, "nDescDistThreshold", nDescDistThreshold);
-	cvWriteInt(fs, "nColorDistThreshold", nColorDistThreshold);
-	cvWriteInt(fs, "nBGSamples", nBGSamples);
-  cvWriteInt(fs, "nRequiredBGSamples", nRequiredBGSamples);
-  cvWriteInt(fs, "showOutput", showOutput);
-
-	cvReleaseFileStorage(&fs);
-}
-
-void LOBSTERBGS::loadConfig()
-{
-	CvFileStorage* fs = cvOpenFileStorage("./config/LOBSTERBGS.xml", 0, CV_STORAGE_READ);
-
-	fRelLBSPThreshold = cvReadRealByName(fs, 0, "fRelLBSPThreshold", BGSLOBSTER_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD);
-	nLBSPThresholdOffset = cvReadIntByName(fs, 0, "nLBSPThresholdOffset", BGSLOBSTER_DEFAULT_LBSP_OFFSET_SIMILARITY_THRESHOLD);
-	nDescDistThreshold = cvReadIntByName(fs, 0, "nDescDistThreshold", BGSLOBSTER_DEFAULT_DESC_DIST_THRESHOLD);
-	nColorDistThreshold = cvReadIntByName(fs, 0, "nColorDistThreshold", BGSLOBSTER_DEFAULT_COLOR_DIST_THRESHOLD);
-	nBGSamples = cvReadIntByName(fs, 0, "nBGSamples", BGSLOBSTER_DEFAULT_NB_BG_SAMPLES);
-	nRequiredBGSamples = cvReadIntByName(fs, 0, "nRequiredBGSamples", BGSLOBSTER_DEFAULT_REQUIRED_NB_BG_SAMPLES);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
-
-	cvReleaseFileStorage(&fs);
-}
diff --git a/package_bgs/pl/LOBSTER.h b/package_bgs/pl/LOBSTER.h
deleted file mode 100644
index f5954ca2ebe814d176f47936e790668959e6089c..0000000000000000000000000000000000000000
--- a/package_bgs/pl/LOBSTER.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#pragma once
-
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-
-class BackgroundSubtractorLOBSTER;
-
-class LOBSTERBGS : public IBGS
-{
-private:
-	BackgroundSubtractorLOBSTER* pLOBSTER;
-	bool firstTime;
-	bool showOutput;
-
-	float fRelLBSPThreshold;
-	size_t nLBSPThresholdOffset;
-	size_t nDescDistThreshold;
-	size_t nColorDistThreshold;
-	size_t nBGSamples;
-	size_t nRequiredBGSamples;
-  
-public:
-  LOBSTERBGS();
-  ~LOBSTERBGS();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
diff --git a/package_bgs/pl/RandUtils.h b/package_bgs/pl/RandUtils.h
deleted file mode 100644
index 24ca5f683d86970c89d4822efdcae1ffce1ca4ae..0000000000000000000000000000000000000000
--- a/package_bgs/pl/RandUtils.h
+++ /dev/null
@@ -1,96 +0,0 @@
-#pragma once
-
-/*// gaussian 3x3 pattern, based on 'floor(fspecial('gaussian', 3, 1)*256)'
-static const int s_nSamplesInitPatternWidth = 3;
-static const int s_nSamplesInitPatternHeight = 3;
-static const int s_nSamplesInitPatternTot = 256;
-static const int s_anSamplesInitPattern[s_nSamplesInitPatternHeight][s_nSamplesInitPatternWidth] = {
-    {19,    32,    19,},
-    {32,    52,    32,},
-    {19,    32,    19,},
-};*/
-
-// gaussian 7x7 pattern, based on 'floor(fspecial('gaussian',7,2)*512)'
-static const int s_nSamplesInitPatternWidth = 7;
-static const int s_nSamplesInitPatternHeight = 7;
-static const int s_nSamplesInitPatternTot = 512;
-static const int s_anSamplesInitPattern[s_nSamplesInitPatternHeight][s_nSamplesInitPatternWidth] = {
-    {2,     4,     6,     7,     6,     4,     2,},
-    {4,     8,    12,    14,    12,     8,     4,},
-    {6,    12,    21,    25,    21,    12,     6,},
-    {7,    14,    25,    28,    25,    14,     7,},
-    {6,    12,    21,    25,    21,    12,     6,},
-    {4,     8,    12,    14,    12,     8,     4,},
-    {2,     4,     6,     7,     6,     4,     2,},
-};
-
-//! returns a random init/sampling position for the specified pixel position; also guards against out-of-bounds values via image/border size check.
-static inline void getRandSamplePosition(int& x_sample, int& y_sample, const int x_orig, const int y_orig, const int border, const cv::Size& imgsize) {
-    int r = 1+rand()%s_nSamplesInitPatternTot;
-    for(x_sample=0; x_sample<s_nSamplesInitPatternWidth; ++x_sample) {
-        for(y_sample=0; y_sample<s_nSamplesInitPatternHeight; ++y_sample) {
-            r -= s_anSamplesInitPattern[y_sample][x_sample];
-            if(r<=0)
-                goto stop;
-        }
-    }
-    stop:
-    x_sample += x_orig-s_nSamplesInitPatternWidth/2;
-    y_sample += y_orig-s_nSamplesInitPatternHeight/2;
-    if(x_sample<border)
-        x_sample = border;
-    else if(x_sample>=imgsize.width-border)
-        x_sample = imgsize.width-border-1;
-    if(y_sample<border)
-        y_sample = border;
-    else if(y_sample>=imgsize.height-border)
-        y_sample = imgsize.height-border-1;
-}
-
-// simple 8-connected (3x3) neighbors pattern
-static const int s_anNeighborPatternSize_3x3 = 8;
-static const int s_anNeighborPattern_3x3[8][2] = {
-    {-1, 1},  { 0, 1},  { 1, 1},
-    {-1, 0},            { 1, 0},
-    {-1,-1},  { 0,-1},  { 1,-1},
-};
-
-//! returns a random neighbor position for the specified pixel position; also guards against out-of-bounds values via image/border size check.
-static inline void getRandNeighborPosition_3x3(int& x_neighbor, int& y_neighbor, const int x_orig, const int y_orig, const int border, const cv::Size& imgsize) {
-    int r = rand()%s_anNeighborPatternSize_3x3;
-    x_neighbor = x_orig+s_anNeighborPattern_3x3[r][0];
-    y_neighbor = y_orig+s_anNeighborPattern_3x3[r][1];
-    if(x_neighbor<border)
-        x_neighbor = border;
-    else if(x_neighbor>=imgsize.width-border)
-        x_neighbor = imgsize.width-border-1;
-    if(y_neighbor<border)
-        y_neighbor = border;
-    else if(y_neighbor>=imgsize.height-border)
-        y_neighbor = imgsize.height-border-1;
-}
-
-// 5x5 neighbors pattern
-static const int s_anNeighborPatternSize_5x5 = 24;
-static const int s_anNeighborPattern_5x5[24][2] = {
-    {-2, 2},  {-1, 2},  { 0, 2},  { 1, 2},  { 2, 2},
-    {-2, 1},  {-1, 1},  { 0, 1},  { 1, 1},  { 2, 1},
-    {-2, 0},  {-1, 0},            { 1, 0},  { 2, 0},
-    {-2,-1},  {-1,-1},  { 0,-1},  { 1,-1},  { 2,-1},
-    {-2,-2},  {-1,-2},  { 0,-2},  { 1,-2},  { 2,-2},
-};
-
-//! returns a random neighbor position for the specified pixel position; also guards against out-of-bounds values via image/border size check.
-static inline void getRandNeighborPosition_5x5(int& x_neighbor, int& y_neighbor, const int x_orig, const int y_orig, const int border, const cv::Size& imgsize) {
-    int r = rand()%s_anNeighborPatternSize_5x5;
-    x_neighbor = x_orig+s_anNeighborPattern_5x5[r][0];
-    y_neighbor = y_orig+s_anNeighborPattern_5x5[r][1];
-    if(x_neighbor<border)
-        x_neighbor = border;
-    else if(x_neighbor>=imgsize.width-border)
-        x_neighbor = imgsize.width-border-1;
-    if(y_neighbor<border)
-        y_neighbor = border;
-    else if(y_neighbor>=imgsize.height-border)
-        y_neighbor = imgsize.height-border-1;
-}
diff --git a/package_bgs/pl/SuBSENSE.cpp b/package_bgs/pl/SuBSENSE.cpp
deleted file mode 100644
index a4aab0c1c5a3423ddfc793fd6577e0a4d49b07f2..0000000000000000000000000000000000000000
--- a/package_bgs/pl/SuBSENSE.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-#include "SuBSENSE.h"
-#include "BackgroundSubtractorSuBSENSE.h"
-
-
-SuBSENSEBGS::SuBSENSEBGS() :
-pSubsense(0), firstTime(true), showOutput(true),
-fRelLBSPThreshold 			(BGSSUBSENSE_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD),
-nDescDistThresholdOffset 	(BGSSUBSENSE_DEFAULT_DESC_DIST_THRESHOLD_OFFSET),
-nMinColorDistThreshold 		(BGSSUBSENSE_DEFAULT_MIN_COLOR_DIST_THRESHOLD),
-nBGSamples 					(BGSSUBSENSE_DEFAULT_NB_BG_SAMPLES),
-nRequiredBGSamples 			(BGSSUBSENSE_DEFAULT_REQUIRED_NB_BG_SAMPLES),
-nSamplesForMovingAvgs 		(BGSSUBSENSE_DEFAULT_N_SAMPLES_FOR_MV_AVGS)
-{
-}
-
-SuBSENSEBGS::~SuBSENSEBGS() {
-	if (pSubsense)
-		delete pSubsense;
-}
-
-void SuBSENSEBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
-{
-  if(img_input.empty())
-    return;
-
-  loadConfig();
-
-  if (firstTime) {
-    saveConfig();
-    pSubsense = new BackgroundSubtractorSuBSENSE(
-    		fRelLBSPThreshold, nDescDistThresholdOffset, nMinColorDistThreshold,
-    		nBGSamples, nRequiredBGSamples, nSamplesForMovingAvgs);
-
-    pSubsense->initialize(img_input, cv::Mat (img_input.size(), CV_8UC1, cv::Scalar_<uchar>(255)));
-    firstTime = false;
-  }
-
-  (*pSubsense)(img_input, img_output);
-  pSubsense->getBackgroundImage(img_bgmodel);
-
-  if(showOutput) {
-	  imshow("SuBSENSE FG", img_output);
-	  imshow("SuBSENSE BG", img_bgmodel);
-  }
-}
-
-void SuBSENSEBGS::saveConfig()
-{
-	CvFileStorage* fs = cvOpenFileStorage("./config/SuBSENSEBGS.xml", 0, CV_STORAGE_WRITE);
-
-	cvWriteReal(fs, "fRelLBSPThreshold", fRelLBSPThreshold);
-	cvWriteInt(fs, "nDescDistThresholdOffset", nDescDistThresholdOffset);
-	cvWriteInt(fs, "nMinColorDistThreshold", nMinColorDistThreshold);
-	cvWriteInt(fs, "nBGSamples", nBGSamples);
-	cvWriteInt(fs, "nRequiredBGSamples", nRequiredBGSamples);
-	cvWriteInt(fs, "nSamplesForMovingAvgs", nSamplesForMovingAvgs);
-  cvWriteInt(fs, "showOutput", showOutput);
-
-	cvReleaseFileStorage(&fs);
-}
-
-void SuBSENSEBGS::loadConfig()
-{
-	CvFileStorage* fs = cvOpenFileStorage("./config/SuBSENSEBGS.xml", 0, CV_STORAGE_READ);
-
-	fRelLBSPThreshold = cvReadRealByName(fs, 0, "fRelLBSPThreshold", BGSSUBSENSE_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD);
-	nDescDistThresholdOffset = cvReadIntByName(fs, 0, "nDescDistThresholdOffset", BGSSUBSENSE_DEFAULT_DESC_DIST_THRESHOLD_OFFSET);
-	nMinColorDistThreshold = cvReadIntByName(fs, 0, "nMinColorDistThreshold", BGSSUBSENSE_DEFAULT_MIN_COLOR_DIST_THRESHOLD);
-	nBGSamples = cvReadIntByName(fs, 0, "nBGSamples", BGSSUBSENSE_DEFAULT_NB_BG_SAMPLES);
-	nRequiredBGSamples = cvReadIntByName(fs, 0, "nRequiredBGSamples", BGSSUBSENSE_DEFAULT_REQUIRED_NB_BG_SAMPLES);
-	nSamplesForMovingAvgs = cvReadIntByName(fs, 0, "nSamplesForMovingAvgs", BGSSUBSENSE_DEFAULT_N_SAMPLES_FOR_MV_AVGS);
-  showOutput = cvReadIntByName(fs, 0, "showOutput", true);
-
-	cvReleaseFileStorage(&fs);
-}
diff --git a/package_bgs/pl/SuBSENSE.h b/package_bgs/pl/SuBSENSE.h
deleted file mode 100644
index b527c2711682814d0cac39681e6b841008c1195f..0000000000000000000000000000000000000000
--- a/package_bgs/pl/SuBSENSE.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-
-#include <opencv2/opencv.hpp>
-
-#include "../IBGS.h"
-
-class BackgroundSubtractorSuBSENSE;
-
-class SuBSENSEBGS: public IBGS {
-private:
-	BackgroundSubtractorSuBSENSE* pSubsense;
-	bool firstTime;
-	bool showOutput;
-
-	float fRelLBSPThreshold;
-	size_t nDescDistThresholdOffset;
-	size_t nMinColorDistThreshold;
-	size_t nBGSamples;
-	size_t nRequiredBGSamples;
-	size_t nSamplesForMovingAvgs;
-
-public:
-	SuBSENSEBGS();
-	~SuBSENSEBGS();
-
-	void process(const cv::Mat &img_input, cv::Mat &img_output,
-			cv::Mat &img_bgmodel);
-
-private:
-	void saveConfig();
-	void loadConfig();
-};
diff --git a/package_bgs/sjn/SJN_MultiCueBGS.h b/package_bgs/sjn/SJN_MultiCueBGS.h
deleted file mode 100644
index 0891c08c16d9d319a6f12290df3d5dd2d7884a29..0000000000000000000000000000000000000000
--- a/package_bgs/sjn/SJN_MultiCueBGS.h
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
-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
-
-#define MIN3(x,y,z)  ((y) <= (z) ? ((x) <= (y) ? (x) : (y)) : ((x) <= (z) ? (x) : (z)))
-#define MAX3(x,y,z)  ((y) >= (z) ? ((x) >= (y) ? (x) : (y)) : ((x) >= (z) ? (x) : (z)))
-
-#ifndef PI
-  #define PI 3.14159
-#endif
-
-typedef int BOOL;
-
-#ifndef FALSE
-  #define FALSE 0
-#endif
-
-#ifndef TRUE
-  #define TRUE 1
-#endif
-
-#if !defined(__APPLE__)
-#include <malloc.h>
-#endif
-#include "math.h"
-
-#include <vector>
-using std::vector;
-
-#include <algorithm>
-using std::sort;
-
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-
-//------------------------------------Structure Lists-------------------------------------//
-struct point{
-	short m_nX;
-	short m_nY;
-};
-
-struct neighbor_pos{
-	short m_nX;
-	short m_nY;
-};
-//1) Bounding Box Structure
-struct BoundingBoxInfo{
-	int m_iBoundBoxNum;										//# of bounding boxes for all foreground and false-positive blobs
-	int m_iArraySize;										//the size of the below arrays to store bounding box information
-
-	short *m_aLeft, *m_aRight, *m_aUpper, *m_aBottom;		//arrays to store bounding box information for (the original frame size)
-	short *m_aRLeft, *m_aRRight, *m_aRUpper, *m_aRBottom;	//arrays to store bounding box information for (the reduced frame size)
-	BOOL* m_ValidBox;										//If this value is true, the corresponding bounding box is for a foreground blob.
-															//Else, it is for a false-positive blob
-};
-
-//2) Texture Model Structure
-struct TextureCodeword{
-	int m_iMNRL;											//the maximum negative run-length
-	int m_iT_first_time;									//the first access time
-	int m_iT_last_time;										//the last access time
-
-	//��� MTLBP��
-	float m_fLowThre;										//a low threshold for the matching 
-	float m_fHighThre;										//a high threshold for the matching
-	float m_fMean;											//mean of the codeword
-};
-
-struct TextureModel{
-	TextureCodeword** m_Codewords;							//the texture-codeword Array
-
-	int m_iTotal;											//# of learned samples after the last clear process
-	int m_iElementArraySize;								//the array size of m_Codewords
-	int m_iNumEntries;										//# of codewords
-
-	BOOL m_bID;												//id=1 --> background model, id=0 --> cachebook
-};
-
-//3) Color Model Structure
-struct ColorCodeword{	
-	int m_iMNRL;											//the maximum negative run-length
-	int m_iT_first_time;									//the first access time
-	int m_iT_last_time;										//the last access time
-
-	double m_dMean[3];										//mean vector of the codeword
-
-};
-
-struct ColorModel{
-	ColorCodeword** m_Codewords;							//the color-codeword Array
-
-	int m_iTotal;											//# of learned samples after the last clear process
-	int m_iElementArraySize;								//the array size of m_Codewords
-	int m_iNumEntries;										//# of codewords
-
-	BOOL m_bID;												//id=1 --> background model, id=0 --> cachebookk
-};
-
-
-class SJN_MultiCueBGS : public IBGS
-{
-private:
-  bool firstTime;
-  bool showOutput;
-  void saveConfig();
-  void loadConfig();
-
-public:
-	SJN_MultiCueBGS();
-	~SJN_MultiCueBGS(void);
-
-public:
-	//----------------------------------------------------
-	//		APIs and User-Adjustable Parameters
-	//----------------------------------------------------
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);			//the main function to background modeling and subtraction
-  
-  void GetForegroundMap(IplImage* return_image, IplImage* input_frame=NULL);					//the function returning a foreground binary-map
-	void Destroy();																				//the function to release allocated memories
-
-	int g_iTrainingPeriod;										//the training period								(The parameter t in the paper)
-	int g_iT_ModelThreshold;									//the threshold for texture-model based BGS.		(The parameter tau_T in the paper)
-	int g_iC_ModelThreshold;									//the threshold for appearance based verification.  (The parameter tau_A in the paper)
-
-	float g_fLearningRate;										//the learning rate for background models.			(The parameter alpha in the paper)
-
-	short g_nTextureTrainVolRange;								//the codebook size factor for texture models.		(The parameter k in the paper)
-	short g_nColorTrainVolRange;								//the codebook size factor for color models.		(The parameter eta_1 in the paper)
-
-public:
-	//----------------------------------------------------
-	//	Implemented Function Lists
-	//----------------------------------------------------
-
-	//--1) General Functions
-	void Initialize(IplImage* frame);
-
-	void PreProcessing(IplImage* frame);
-	void ReduceImageSize(IplImage* SrcImage, IplImage* DstImage);
-	void GaussianFiltering(IplImage* frame, uchar*** aFilteredFrame);
-	void BGR2HSVxyz_Par(uchar*** aBGR, uchar*** aXYZ);
-
-	void BackgroundModeling_Par(IplImage* frame);
-	void ForegroundExtraction(IplImage* frame);
-	void CreateLandmarkArray_Par(float fConfThre, short nTrainVolRange, float**aConfMap, int iNehborNum, uchar*** aXYZ, 
-		point*** aNeiDir, TextureModel**** TModel, ColorModel*** CModel, uchar**aLandmarkArr);
-
-	void PostProcessing(IplImage* frame);
-	void MorphologicalOpearions(uchar** aInput, uchar** aOutput, double dThresholdRatio, int iMaskSize, int iWidth, int iHeight);
-	void Labeling(uchar** aBinaryArray, int* pLabelCount, int** aLabelTable);
-	void SetBoundingBox(int iLabelCount, int** aLabelTable);
-	void BoundBoxVerification(IplImage* frame, uchar** aResForeMap, BoundingBoxInfo* BoundBoxInfo);
-	void EvaluateBoxSize( BoundingBoxInfo* BoundBoxInfo);
-	void EvaluateOverlapRegionSize(BoundingBoxInfo* SrcBoxInfo);
-	void EvaluateGhostRegion(IplImage* frame, uchar** aResForeMap, BoundingBoxInfo* BoundBoxInfo);
-	double CalculateHausdorffDist(IplImage* input_image, IplImage* model_image);
-	void RemovingInvalidForeRegions(uchar** aResForeMap, BoundingBoxInfo* BoundBoxInfo);
-	
-	void UpdateModel_Par();
-	void GetEnlargedMap(float** aOriginMap, float** aEnlargedMap);
-
-	//--2) Texture Model Related Functions
-	void T_AllocateTextureModelRelatedMemory();
-	void T_ReleaseTextureModelRelatedMemory();
-	void T_SetNeighborDirection(point*** aNeighborPos);
-	void T_ModelConstruction(short nTrainVolRange,float fLearningRate, uchar*** aXYZ,point center, point* aNei, TextureModel** aModel);
-	void T_ClearNonEssentialEntries(short nClearNum, TextureModel** aModel);
-	void T_ClearNonEssentialEntriesForCachebook(uchar bLandmark, short* nReferredIdxArr, short nClearNum, TextureModel** pCachebook);
-	void T_GetConfidenceMap_Par(uchar*** aXYZ, float** aTextureMap, point*** aNeiDirArr, TextureModel**** aModel);
-	void T_Absorption(int iAbsorbCnt, point pos, short*** aContinuCnt, short*** aRefferedIndex, TextureModel** pModel, TextureModel** pCache);
-
-	//--3) Color Model Related Functions
-	void C_AllocateColorModelRelatedMemory();
-	void C_ReleaseColorModelRelatedMemory();
-	void C_CodebookConstruction(uchar* aP,int iPosX, int iPosY, short nTrainVolRange, float fLearningRate, ColorModel* pC);
-	void C_ClearNonEssentialEntries(short nClearNum, ColorModel* pModel);
-	void C_ClearNonEssentialEntriesForCachebook(uchar bLandmark, short nReferredIdx, short nClearNum, ColorModel* pCachebook);
-	void C_Absorption(int iAbsorbCnt, point pos , short** aContinuCnt, short** aRefferedIndex, ColorModel* pModel, ColorModel* pCache);
-public: 
-	//----------------------------------------------------
-	//	Implemented Variable Lists
-	//----------------------------------------------------
-	
-	//--1) General Variables
-	int g_iFrameCount;							//the counter of processed frames
-
-	int g_iBackClearPeriod;						//the period to clear background models
-	int g_iCacheClearPeriod;					//the period to clear cache-book models
-
-	int g_iAbsortionPeriod;						//the period to absorb static ghost regions 
-	BOOL g_bAbsorptionEnable;					//If True, procedures for ghost region absorption are activated.
-
-	BOOL g_bModelMemAllocated;					//To handle memory..
-	BOOL g_bNonModelMemAllocated;				//To handle memory..
-
-	float g_fConfidenceThre;					//the final decision threshold
-
-	int g_iWidth, g_iHeight;					//width and height of input frames
-	int g_iRWidth, g_iRHeight;					//width and height of reduced frames (For efficiency, the reduced size of frames are processed) 
-	int g_iForegroundNum;						//# of detected foreground regions
-	BOOL g_bForegroundMapEnable;				//TRUE only when BGS is successful
-
-	IplImage* g_ResizedFrame;					//reduced size of frame (For efficiency, the reduced size of frames are processed) 
-	uchar*** g_aGaussFilteredFrame;				
-	uchar*** g_aXYZFrame;						
-	uchar** g_aLandmarkArray;					//the landmark map
-	uchar** g_aResizedForeMap;					//the resized foreground map
-	uchar** g_aForegroundMap;					//the final foreground map
-	BOOL** g_aUpdateMap;						//the location map of update candidate pixels
-
-	BoundingBoxInfo* g_BoundBoxInfo;			//the array of bounding boxes of each foreground blob
-
-	//--2) Texture Model Related
-	TextureModel**** g_TextureModel;			//the texture background model
-	TextureModel**** g_TCacheBook;				//the texture cache-book
-	short*** g_aTReferredIndex;					//To handle cache-book
-	short*** g_aTContinuousCnt;					//To handle cache-book
-	point*** g_aNeighborDirection;				
-	float**g_aTextureConfMap;					//the texture confidence map
-
-	short g_nNeighborNum;						//# of neighborhoods
-	short g_nRadius;							
-	short g_nBoundarySize;						
-	
-	//--3) Texture Model Related
-	ColorModel*** g_ColorModel;					//the color background model
-	ColorModel*** g_CCacheBook;					//the color cache-book
-	short** g_aCReferredIndex;					//To handle cache-book
-	short** g_aCContinuousCnt;					//To handle cache-book
-};
-
-
diff --git a/package_bgs/tb/FuzzyChoquetIntegral.h b/package_bgs/tb/FuzzyChoquetIntegral.h
deleted file mode 100644
index 76ba15829bf493a19f75e5f7a77e87e3ca5dcdf7..0000000000000000000000000000000000000000
--- a/package_bgs/tb/FuzzyChoquetIntegral.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-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
-
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-
-#include "FuzzyUtils.h"
-
-class FuzzyChoquetIntegral : public IBGS
-{
-private:
-  bool firstTime;
-  long frameNumber;
-  bool showOutput;
-  
-  int framesToLearn;
-  double alphaLearn;
-  double alphaUpdate;
-  int colorSpace;
-  int option;
-  bool smooth;
-  double threshold;
-
-  FuzzyUtils fu;
-  cv::Mat img_background_f3;
-
-public:
-  FuzzyChoquetIntegral();
-  ~FuzzyChoquetIntegral();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
-
diff --git a/package_bgs/tb/FuzzySugenoIntegral.h b/package_bgs/tb/FuzzySugenoIntegral.h
deleted file mode 100644
index cfa91b7bb07dd4eeb2feba10a0f7832ef590a6d1..0000000000000000000000000000000000000000
--- a/package_bgs/tb/FuzzySugenoIntegral.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-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
-
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-
-#include "FuzzyUtils.h"
-
-class FuzzySugenoIntegral : public IBGS
-{
-private:
-  bool firstTime;
-  long long frameNumber;
-  bool showOutput;
-  
-  int framesToLearn;
-  double alphaLearn;
-  double alphaUpdate;
-  int colorSpace;
-  int option;
-  bool smooth;
-  double threshold;
-
-  FuzzyUtils fu;
-  cv::Mat img_background_f3;
-  
-public:
-  FuzzySugenoIntegral();
-  ~FuzzySugenoIntegral();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
-
diff --git a/package_bgs/tb/FuzzyUtils.cpp b/package_bgs/tb/FuzzyUtils.cpp
deleted file mode 100644
index fcb1972b3d21438c92333762b522c49a7e043800..0000000000000000000000000000000000000000
--- a/package_bgs/tb/FuzzyUtils.cpp
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
-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 "FuzzyUtils.h"
-
-FuzzyUtils::FuzzyUtils(void){}
-
-FuzzyUtils::~FuzzyUtils(void){}
-
-void FuzzyUtils::LBP(IplImage* InputImage, IplImage* LBPimage)
-{
-  PixelUtils p;
-
-  float* neighberPixel = (float*) malloc(9*sizeof(float));   
-  float* BinaryValue = (float*) malloc(9*sizeof(float));
-  float* CarreExp = (float*) malloc(9*sizeof(float));
-  float* valLBP = (float*) malloc(1*sizeof(float));
-
-  *valLBP = 0;
-
-  int x = 0, y = 0;
-
-  // on implemente les 8 valeurs puissance de 2 qui correspondent aux 8 elem. d'image voisins au elem. d'image central
-  *(CarreExp+0)=1.0;
-  *(CarreExp+1)=2.0;
-  *(CarreExp+2)=4.0;
-  *(CarreExp+3)=8.0;
-  *(CarreExp+4)=0.0;
-  *(CarreExp+5)=16.0;
-  *(CarreExp+6)=32.0;
-  *(CarreExp+7)=64.0;
-  *(CarreExp+8)=128.0;
-
-  //le calcule de LBP
-  //pour les 4 coins
-  /* 1.*/
-  if(x==0 && y==0)
-  {
-    p.getNeighberhoodGrayPixel(InputImage, x,y,neighberPixel);
-    getBinValue(neighberPixel,BinaryValue,4,0);
-    *valLBP=*valLBP+((*(BinaryValue+1))*(*(CarreExp+1))+(*(BinaryValue+2))*(*(CarreExp+2))+(*(BinaryValue+3))*(*(CarreExp+3)))/255.0;
-    p.PutGrayPixel(LBPimage,x,y,*valLBP);	
-  }
-
-  /* 2.*/
-  if(x==0 && y==InputImage->width)
-  {
-    *valLBP=0;
-    p.getNeighberhoodGrayPixel(InputImage, x,y,neighberPixel);
-    getBinValue(neighberPixel,BinaryValue,4,1);
-    *valLBP=*valLBP+((*(BinaryValue))*(*(CarreExp))+(*(BinaryValue+2))*(*(CarreExp+2))+(*(BinaryValue+3))*(*(CarreExp+3)))/255.0;
-    p.PutGrayPixel(LBPimage,x,y,*valLBP);	
-  }
-
-  /* 3.*/
-  if(x==InputImage->height && y==0)
-  {
-    *valLBP=0;
-    p.getNeighberhoodGrayPixel(InputImage, x,y,neighberPixel);
-    getBinValue(neighberPixel,BinaryValue,4,2);
-    *valLBP=*valLBP+((*(BinaryValue))*(*(CarreExp))+(*(BinaryValue+1))*(*(CarreExp+1))+(*(BinaryValue+3))*(*(CarreExp+3)))/255.0;
-    p.PutGrayPixel(LBPimage,x,y,*valLBP);	
-  }
-
-  /* 4.*/
-  if(x==InputImage->height && y==InputImage->width)
-  {
-    *valLBP=0;
-    p.getNeighberhoodGrayPixel(InputImage, x,y,neighberPixel);
-    getBinValue(neighberPixel,BinaryValue,4,3);
-    *valLBP=*valLBP+((*(BinaryValue))*(*(CarreExp))+(*(BinaryValue+1))*(*(CarreExp+1))+(*(BinaryValue+2))*(*(CarreExp+2)))/255.0;
-    p.PutGrayPixel(LBPimage,x,y,*valLBP);	
-  }
-
-  //le calcul de LBP pour la premi�re ligne : L(0)
-  if(x==0 && (y!=0 && y!=InputImage->width))
-  {
-    for(int y = 1; y < InputImage->width-1; y++)
-    {
-      p.getNeighberhoodGrayPixel(InputImage, x,y,neighberPixel);
-      getBinValue(neighberPixel,BinaryValue,6,4);
-      *valLBP=0;
-      *valLBP=*valLBP+((*(BinaryValue))*(*(CarreExp))+(*(BinaryValue+1))*(*(CarreExp+1))+(*(BinaryValue+2))*(*(CarreExp+2))+(*(BinaryValue+3))*(*(CarreExp+3))+(*(BinaryValue+5))*(*(CarreExp+5)))/255.0;
-      p.PutGrayPixel(LBPimage,x,y,*valLBP);
-    }
-  }
-
-  //le calcul de LBP pour la derni�re colonne : C(w)
-  if((x!=0 && x!=InputImage->height) && y==InputImage->width) 
-  {
-    for(int x = 1; x < InputImage->height-1; x++)
-    {
-      p.getNeighberhoodGrayPixel(InputImage, x,y,neighberPixel);
-      getBinValue(neighberPixel,BinaryValue,6,4);
-      *valLBP=0;
-      *valLBP=*valLBP+((*(BinaryValue))*(*(CarreExp))+(*(BinaryValue+1))*(*(CarreExp+1))+(*(BinaryValue+2))*(*(CarreExp+2))+(*(BinaryValue+3))*(*(CarreExp+3))+(*(BinaryValue+5))*(*(CarreExp+5)))/255.0;
-      p.PutGrayPixel(LBPimage,x,y,*valLBP);
-    }
-  }
-
-  //le calcul de LBP pour la derni�re ligne : L(h)
-  if(x==InputImage->height && (y!=0 && y!=InputImage->width))
-  {
-    for(int y = 1; y < InputImage->width-1; y++)
-    {
-      p.getNeighberhoodGrayPixel(InputImage, x,y,neighberPixel);
-      getBinValue(neighberPixel,BinaryValue,6,1);
-      *valLBP=0;
-      *valLBP=*valLBP+((*(BinaryValue))*(*(CarreExp))+(*(BinaryValue+2))*(*(CarreExp+2))+(*(BinaryValue+3))*(*(CarreExp+3))+(*(BinaryValue+4))*(*(CarreExp+4))+(*(BinaryValue+5))*(*(CarreExp+5)))/255.0;
-      p.PutGrayPixel(LBPimage,x,y,*valLBP);
-    }
-  }
-
-  //le calcul de LBP pour la premi�re colonne : C(0)
-  if((x!=0 && x!=InputImage->height) && y==0)
-  {
-    for(int x = 1; x <InputImage->height-1; x++)
-    {
-      p.getNeighberhoodGrayPixel(InputImage, x,y,neighberPixel);
-      getBinValue(neighberPixel,BinaryValue,6,2);
-      *valLBP=0;
-      *valLBP=*valLBP+((*(BinaryValue))*(*(CarreExp+5))+(*(BinaryValue+1))*(*(CarreExp+6))+(*(BinaryValue+3))*(*(CarreExp+3))+(*(BinaryValue+4))*(*(CarreExp))+(*(BinaryValue+5))*(*(CarreExp+1)))/255.0;
-      p.PutGrayPixel(LBPimage,x,y,*valLBP);
-    }
-  }
-
-  //pour le reste des elements d'image
-  for(int y = 1; y < InputImage->height-1; y++)
-  {
-    for(int x = 1; x < InputImage->width-1; x++)
-    {
-      p.getNeighberhoodGrayPixel(InputImage, x,y,neighberPixel);
-      getBinValue(neighberPixel,BinaryValue,9,4);
-      //le calcul de la valeur du LBP pour chaque elem. d'im.
-      *valLBP=0;
-      for(int l = 0; l < 9; l++)
-        *valLBP = *valLBP + ((*(BinaryValue+l)) * (*(CarreExp+l))) / 255.0;
-      //printf("\nvalLBP(%d,%d)=%f",x,y,*valLBP);
-      p.PutGrayPixel(LBPimage,x,y,*valLBP);	
-    }
-  }
-
-  free(neighberPixel);
-  free(BinaryValue);
-  free(CarreExp);
-  free(valLBP);
-}
-
-void FuzzyUtils::getBinValue(float* neighberGrayPixel, float* BinaryValue, int m, int n)
-{
-  // la comparaison entre la valeur d'elem d'image central et les valeurs des elem. d'im. voisins
-  // m = le numero des elements (4, 6 ou 9);
-  // n = la position de l'element central; 
-
-  int h = 0;
-  for(int k = 0; k < m; k++)
-  {
-    if(*(neighberGrayPixel+k) >= *(neighberGrayPixel+n))
-    {
-      *(BinaryValue+h)=1;
-      h++;
-    }
-    else
-    {
-      *(BinaryValue+h)=0;
-      h++;
-    }	
-  }
-}
-
-void FuzzyUtils::SimilarityDegreesImage(IplImage* CurrentImage, IplImage* BGImage, IplImage* DeltaImage, int n, int color_space)
-{
-  PixelUtils p;
-  int i, j;
-
-  if(n == 1)
-  {
-    float* CurrentGrayPixel = (float*) malloc (1*(sizeof(float)));
-    float* BGGrayPixel = (float*) malloc (1*(sizeof(float)));
-    float* DeltaGrayPixel = (float*) malloc (1*(sizeof(float)));
-
-    for(i = 0; i < CurrentImage->width; i++)
-    {
-      for(j = 0; j < CurrentImage->height; j++)
-      {
-        p.GetGrayPixel(CurrentImage,i,j,CurrentGrayPixel);
-        p.GetGrayPixel(BGImage,i,j,BGGrayPixel);
-        RatioPixels(CurrentGrayPixel,BGGrayPixel,DeltaGrayPixel,1);
-        p.PutGrayPixel(DeltaImage,i,j,*DeltaGrayPixel);
-      }
-    }
-
-    free(CurrentGrayPixel);
-    free(BGGrayPixel);
-    free(DeltaGrayPixel);
-  }
-
-  if(n != 1)
-  {   
-    IplImage* ConvertedCurrentImage = cvCreateImage(cvSize(CurrentImage->width, CurrentImage->height), IPL_DEPTH_32F, 3);
-    IplImage* ConvertedBGImage = cvCreateImage(cvSize(CurrentImage->width, CurrentImage->height), IPL_DEPTH_32F, 3);
-
-    float* ConvertedCurrentPixel = (float*) malloc(3*(sizeof(float)));
-    float* ConvertedBGPixel = (float*) malloc(3*(sizeof(float)));
-    float* DeltaConvertedPixel = (float*) malloc(3*(sizeof(float)));
-
-    p.ColorConversion(CurrentImage,ConvertedCurrentImage,color_space);
-    p.ColorConversion(BGImage,ConvertedBGImage,color_space);
-
-    for(i = 0; i < CurrentImage->width; i++)
-    {
-      for(j = 0; j < CurrentImage->height; j++)
-      {
-        p.GetPixel(ConvertedCurrentImage,i,j,ConvertedCurrentPixel);
-        p.GetPixel(ConvertedBGImage,i,j,ConvertedBGPixel);
-        RatioPixels(ConvertedCurrentPixel,ConvertedBGPixel,DeltaConvertedPixel,3);
-        p.PutPixel(DeltaImage,i,j,DeltaConvertedPixel);
-      }
-    }
-
-    free(ConvertedCurrentPixel);
-    free(ConvertedBGPixel);
-    free(DeltaConvertedPixel);
-
-    cvReleaseImage(&ConvertedCurrentImage);
-    cvReleaseImage(&ConvertedBGImage);
-  }
-}
-
-void FuzzyUtils::RatioPixels(float* CurrentPixel, float* BGPixel, float* DeltaPixel, int n)
-{
-  if(n == 1)
-  {
-    if(*CurrentPixel < *BGPixel)
-      *DeltaPixel = *CurrentPixel / *BGPixel;
-
-    if(*CurrentPixel > *BGPixel)
-      *DeltaPixel = *BGPixel / *CurrentPixel;
-
-    if(*CurrentPixel == *BGPixel)
-      *DeltaPixel = 1.0;
-  }
-
-  if(n == 3)
-    for(int i = 0; i < 3; i++)
-    {
-      if(*(CurrentPixel+i) < *(BGPixel+i))
-        *(DeltaPixel+i) = *(CurrentPixel+i) / *(BGPixel+i);
-
-      if(*(CurrentPixel+i) > *(BGPixel+i))
-        *(DeltaPixel+i) = *(BGPixel+i) / *(CurrentPixel+i);
-
-      if(*(CurrentPixel+i) == *(BGPixel+i))
-        *(DeltaPixel+i) = 1.0;			
-    }
-}
-
-void FuzzyUtils::getFuzzyIntegralSugeno(IplImage* H, IplImage* Delta, int n, float *MeasureG, IplImage* OutputImage)
-{
-  // MeasureG : est un vecteur contenant 3 mesure g (g1,g2,g3) tel que : g1+g2+g3=1
-  // n : =2 cad aggreger les 2 images "H" et "Delta" 
-  //	   =1 cad aggreger uniquement les valeurs des composantes couleurs de l'image "Delta"
-
-  PixelUtils p;
-
-  float* HTexturePixel = (float*) malloc(1*sizeof(float));   
-  float* DeltaOhtaPixel = (float*) malloc(3*(sizeof(float)));
-  int *Indice = (int*) malloc(3*(sizeof(int)));
-  float *HI = (float*) malloc(3*(sizeof(float)));
-  float *Integral = (float*) malloc(3*(sizeof(float)));
-  float* X = (float*) malloc(1*sizeof(float));
-  float* XiXj = (float*) malloc(1*sizeof(float));
-  float IntegralFlou;
-
-  *Indice = 0;
-  *(Indice+1) = 1;
-  *(Indice+2) = 2;
-  *X = 1.0;
-
-  for(int i = 0; i < H->width; i++)
-  {
-    for(int j = 0; j < H->height; j++)
-    {	
-      p.GetGrayPixel(H,i,j,HTexturePixel);
-      p.GetPixel(Delta,i,j,DeltaOhtaPixel);
-
-      *(HI+0) = *(HTexturePixel+0);
-      *(HI+1) = *(DeltaOhtaPixel+0);
-      *(HI+2) = *(DeltaOhtaPixel+1);
-
-      Trier(HI,3,Indice);
-
-      *XiXj = *(MeasureG + (*(Indice+1))) + (*(MeasureG + (*(Indice+2))));			
-
-      *(Integral+0) = min((HI + (*(Indice+0))), X);
-      *(Integral+1) = min((HI + (*(Indice+1))), XiXj);
-      *(Integral+2) = min((HI + (*(Indice+2))), ((MeasureG+(*(Indice+2)))));
-
-      IntegralFlou = max(Integral,3);
-      p.PutGrayPixel(OutputImage,i,j,IntegralFlou);
-    }
-  }
-
-  free(HTexturePixel);
-  free(DeltaOhtaPixel);
-  free(Indice);
-  free(HI);
-  free(X);
-  free(XiXj);
-  free(Integral);
-}
-
-void FuzzyUtils::getFuzzyIntegralChoquet(IplImage* H, IplImage* Delta, int n, float *MeasureG, IplImage* OutputImage)
-{
-  // MeasureG : est un vecteur contenant 3 mesure g (g1,g2,g3) tel que : g1+g2+g3=1
-  // n : =2 cad aggreger les 2 images "H" et "Delta" 
-  //	   =1 cad aggreger uniquement les valeurs des composantes couleurs de l'image "Delta"
-
-  PixelUtils p;
-
-  float* HTexturePixel = (float*) malloc(1*sizeof(float));   
-  float* DeltaOhtaPixel = (float*) malloc(3*(sizeof(float)));
-  int *Indice = (int*) malloc(3*(sizeof(int)));
-  float *HI = (float*) malloc(3*(sizeof(float)));
-  float *Integral = (float*) malloc(3*(sizeof(float)));
-  float* X = (float*) malloc(1*sizeof(float));
-  float* XiXj = (float*) malloc(1*sizeof(float));
-  float IntegralFlou;
-
-  *Indice = 0;
-  *(Indice+1) = 1;
-  *(Indice+2) = 2;
-  *X = 1.0;
-
-  for(int i = 0; i < Delta->width; i++)
-  {
-    for(int j = 0; j < Delta->height; j++)
-    {
-      if(n == 2)
-      {
-        p.GetGrayPixel(H,i,j,HTexturePixel);
-        p.GetPixel(Delta,i,j,DeltaOhtaPixel);
-
-        *(HI+0) = *(HTexturePixel+0);
-        *(HI+1) = *(DeltaOhtaPixel+0);
-        *(HI+2) = *(DeltaOhtaPixel+1);
-      }
-
-      if(n==1)
-      {
-        //remplir HI par les valeurs des 3 composantes couleurs uniquement
-        p.GetPixel(Delta,i,j,DeltaOhtaPixel);
-
-        *(HI+0) = *(DeltaOhtaPixel+0);
-        //*(HI+0) = *(DeltaOhtaPixel+2);
-        *(HI+1) = *(DeltaOhtaPixel+1);
-        *(HI+2) = *(DeltaOhtaPixel+2);
-      }
-
-      Trier(HI,3,Indice);
-      *XiXj = *(MeasureG + (*(Indice+1))) + (*(MeasureG + (*(Indice+2))));
-
-      *(Integral+0) = *(HI+(*(Indice+0)))* (*X-*XiXj);
-      *(Integral+1) = *(HI+(*(Indice+1)))* (*XiXj-*(MeasureG+(*(Indice+2))));
-      *(Integral+2) = *(HI+(*(Indice+2)))* (*(MeasureG+(*(Indice+2))));
-
-      IntegralFlou = *(Integral+0) + *(Integral+1) + *(Integral+2);
-      p.PutGrayPixel(OutputImage,i,j,IntegralFlou);
-    }
-  }
-
-  free(HTexturePixel);
-  free(DeltaOhtaPixel);
-  free(Indice);
-  free(HI);
-  free(X);
-  free(XiXj);
-  free(Integral);
-}
-
-void FuzzyUtils::FuzzyMeasureG(float g1, float g2, float g3, float *G)
-{
-  *(G+0) = g1;
-  *(G+1) = g2;
-  *(G+2) = g3;
-}
-
-void FuzzyUtils::Trier(float* g,int n,int* index)
-{
-  // Cette fonction trie un vecteur g par ordre croissant et 
-  // sort egalement l'indice des elements selon le trie dans le vecteur "index" suppos� initialis� par des valeurs de 1 a n
-
-  float t;	
-  int r,a,b;
-
-  for(a = 1; a <= n; a++)
-  {
-    for(b = n-1; b >= a; b--)
-      if(*(g + b-1) < (*(g + b))) 
-      {
-        // ordre croissant des �lements
-        t = *(g + b-1);
-        *(g + b-1) = *(g + b);
-        *(g + b) = t;
-
-        // ordre des indices des �lements du vecteur g
-        r = *(index + b-1);
-        *(index + b-1) = *(index + b);
-        *(index + b) = r;
-      }		
-  }
-}
-
-float FuzzyUtils::min(float *a,float *b)
-{
-  float min = 0;
-
-  if(*a >= (*b)) 
-    min = *b;
-  else
-    min = *a;
-
-  return min;
-}
-
-float FuzzyUtils::max(float* g , int n)
-{
-  float max = 0;
-
-  for(int i = 0; i < n; i++)
-  {
-    if(*(g+i) >= max)
-      max = *(g+i);
-  }
-  
-  return max;
-}
-
-void FuzzyUtils::gDeDeux(float* a, float* b, float* lambda)
-{
-  float* c = (float*) malloc(1*sizeof(float));
-  *c = *a + (*b) + (*lambda) * (*a) * (*b);
-}
-
-void FuzzyUtils::getLambda(float* g)
-{
-  float a,b;
-  float* lambda = (float*) malloc(1*sizeof(float)); 
-
-  a = (*(g+0) * (*(g+1)) + (*(g+1)) * (*(g+2)) + (*(g+0)) * (*(g+2)));
-  *lambda = -(*(g+0) * (*(g+1)) + (*(g+1)) * (*(g+2)) + (*(g+0)) * (*(g+2))) / (*(g+0) * (*(g+1)) * (*(g+2)));
-  b = (*(g+0) * (*(g+1)) * (*(g+2)));
-  
-  //printf("\na:%f",a);
-  //printf("\nb:%f",b);
-  //printf("\nlambda:%f", *lambda);
-
-  free(lambda);
-}
-
-void FuzzyUtils::AdaptativeSelectiveBackgroundModelUpdate(IplImage* CurrentImage, IplImage* BGImage, IplImage* OutputImage, IplImage* Integral, float seuil, float alpha)
-{
-  PixelUtils p;
-
-  float beta = 0.0;
-  float* CurentImagePixel = (float*) malloc(3*sizeof(float));
-  float* BGImagePixel = (float*) malloc(3*sizeof(float));
-  float* OutputImagePixel = (float*) malloc(3*sizeof(float));
-  float* IntegralImagePixel = (float*) malloc(1*sizeof(float));
-  float *Maximum = (float*) malloc(1*sizeof(float));
-  float *Minimum = (float*) malloc(1*sizeof(float));
-
-  p.ForegroundMaximum(Integral, Maximum, 1);
-  p.ForegroundMinimum(Integral, Minimum, 1);
-
-  for(int i = 0; i < CurrentImage->width; i++)
-  {
-    for(int j = 0; j < CurrentImage->height; j++)
-    {
-      p.GetPixel(CurrentImage, i, j, CurentImagePixel);
-      p.GetPixel(BGImage, i, j, BGImagePixel);
-      p.GetGrayPixel(Integral, i, j, IntegralImagePixel);
-      
-      beta = 1 - ((*IntegralImagePixel) - ((*Minimum / (*Minimum - *Maximum)) * (*IntegralImagePixel) - (*Minimum * (*Maximum) / (*Minimum - *Maximum))));
-      
-      for(int k = 0; k < 3; k++)
-        *(OutputImagePixel + k) = beta * (*(BGImagePixel + k)) + (1 - beta) * (alpha * (*(CurentImagePixel+k)) + (1-alpha) * (*(BGImagePixel+k)));
-      
-      p.PutPixel(OutputImage, i, j, OutputImagePixel);
-    }
-  }
-
-  free(CurentImagePixel);
-  free(BGImagePixel);
-  free(OutputImagePixel);
-  free(IntegralImagePixel);
-  free(Maximum);
-  free(Minimum);
-}
diff --git a/package_bgs/tb/PixelUtils.cpp b/package_bgs/tb/PixelUtils.cpp
deleted file mode 100644
index d647e05089369117ec38dcec215d532b72825715..0000000000000000000000000000000000000000
--- a/package_bgs/tb/PixelUtils.cpp
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
-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 "PixelUtils.h"
-
-PixelUtils::PixelUtils(void){}
-PixelUtils::~PixelUtils(void){}
-
-void PixelUtils::ColorConversion(IplImage* RGBImage, IplImage* ConvertedImage, int color_space)
-{
-  // Space Color RGB - Nothing to do!
-  if(color_space == 1)
-    cvCopy(RGBImage, ConvertedImage);
-
-  // Space Color Ohta
-  if(color_space == 2) 
-    cvttoOTHA(RGBImage, ConvertedImage);
-
-  // Space Color HSV - V Intensity - (H,S) Chromaticity
-  if(color_space == 3)
-    cvCvtColor(RGBImage, ConvertedImage, CV_BGR2HSV);
-
-  // Space Color YCrCb - Y Intensity - (Cr,Cb) Chromaticity
-  if(color_space == 4)
-    cvCvtColor(RGBImage,ConvertedImage,CV_BGR2YCrCb);
-}
-
-void PixelUtils::cvttoOTHA(IplImage* RGBImage, IplImage* OthaImage)
-{
-  float* OhtaPixel = (float*) malloc(3*(sizeof(float)));
-  float* RGBPixel = (float*) malloc(3*(sizeof(float)));
-
-  for(int i = 0; i < RGBImage->width; i++)
-  {
-    for(int j = 0;j < RGBImage->height; j++)
-    {
-      GetPixel(RGBImage, i, j, RGBPixel);
-
-      // I1 = (R + G + B) / 3
-      *OhtaPixel = (*(RGBPixel) + (*(RGBPixel + 1)) + (*(RGBPixel + 2))) / 3.0;
-
-      // I2 = (R - B) / 2
-      *(OhtaPixel+1) = (*RGBPixel - (*(RGBPixel + 2))) / 2.0;
-
-      // I3 = (2G - R - B) / 4
-      *(OhtaPixel+2) = (2 * (*(RGBPixel + 1)) - (*RGBPixel) - (*(RGBPixel + 2))) / 4.0;		
-      
-      PutPixel(OthaImage, i, j, OhtaPixel);
-    }
-  }
-
-  free(OhtaPixel);
-  free(RGBPixel);
-}
-
-void PixelUtils::PostProcessing(IplImage *InputImage)
-{
-  IplImage *ResultImage = cvCreateImage(cvSize(InputImage->width, InputImage->height), IPL_DEPTH_32F, 3);
-
-  cvErode(InputImage, ResultImage, NULL, 1);
-  cvDilate(ResultImage, InputImage, NULL, 0);
-
-  cvReleaseImage(&ResultImage);
-}	
-
-void PixelUtils::GetPixel(IplImage *image, int m, int n, unsigned char *pixelcourant)
-{	
-  for(int k = 0; k < 3; k++)
-    pixelcourant[k] = ((unsigned char*)(image->imageData + image->widthStep*n))[m*3 + k];
-}
-
-void PixelUtils::GetGrayPixel(IplImage *image, int m, int n, unsigned char *pixelcourant)
-{	
-  *pixelcourant = ((unsigned char*)(image->imageData + image->widthStep*n))[m];
-}
-
-void PixelUtils::PutPixel(IplImage *image,int p,int q,unsigned char *pixelcourant)
-{	
-  for(int r = 0; r < 3; r++)
-    ((unsigned char*)(image->imageData + image->widthStep*q))[p*3 + r] = pixelcourant[r];
-}
-
-void PixelUtils::PutGrayPixel(IplImage *image, int p, int q, unsigned char pixelcourant)
-{	
-  ((unsigned char*)(image->imageData + image->widthStep*q))[p] = pixelcourant; 
-}
-
-void PixelUtils::GetPixel(IplImage *image, int m, int n, float *pixelcourant)
-{	
-  for(int k = 0; k < 3; k++)
-    pixelcourant[k] = ((float*)(image->imageData + image->widthStep*n))[m*3 + k];
-}
-
-void PixelUtils::GetGrayPixel(IplImage *image, int m, int n, float *pixelcourant)
-{	
-  *pixelcourant = ((float*)(image->imageData + image->widthStep*n))[m];
-}
-
-void PixelUtils::PutPixel(IplImage *image, int p, int q, float *pixelcourant)
-{	
-  for(int r = 0; r < 3; r++)
-    ((float*)(image->imageData + image->widthStep*q))[p*3 + r] = pixelcourant[r];
-}
-
-void PixelUtils::PutGrayPixel(IplImage *image,int p,int q,float pixelcourant)
-{	
-  ((float*)(image->imageData + image->widthStep*q))[p] = pixelcourant;
-}
-
-void PixelUtils::getNeighberhoodGrayPixel(IplImage* InputImage, int x, int y, float* neighberPixel)
-{
-  int i,j,k;
-  
-  float* pixelCourant = (float*) malloc(1*(sizeof(float)));
-  
-  //le calcul de voisinage pour les 4 coins;
-  /* 1.*/
-  if(x==0 && y==0)
-  {
-    k = 0;
-    for(i = x; i < x+2; i++)
-      for(j = y; j < y+2; j++)
-      {  
-        GetGrayPixel(InputImage,i,j,pixelCourant);
-        *(neighberPixel+k) = *pixelCourant;
-        k++;
-      }
-  }
-
-  /* 2.*/
-  if(x==0 && y==InputImage->width)
-  {
-    k = 0;
-    for(i = x; i < x+2; i++)
-      for(j = y-1; j < y+1; j++)
-      {  
-        GetGrayPixel(InputImage,i,j,pixelCourant);
-        *(neighberPixel+k) = *pixelCourant;
-        k++;
-      }
-  }
-
-  /* 3.*/
-  if(x==InputImage->height && y==0)
-  {
-    k = 0;
-    for(i = x-1; i < x+1; i++)
-      for(j = y; j < y+2; j++)
-      {  
-        GetGrayPixel(InputImage,i,j,pixelCourant);
-        *(neighberPixel+k) = *pixelCourant;
-        k++;
-      }
-  }	
-
-  /* 4.*/
-  if(x==InputImage->height && y==InputImage->width)
-  {
-    k = 0;
-    for(i = x-1; i <x+1; i++)
-      for(j = y-1; j < y+1; j++)
-      {  
-        GetGrayPixel(InputImage,i,j,pixelCourant);
-        *(neighberPixel+k) = *pixelCourant;
-        k++;
-      }
-  }	
-
-  // Voisinage de la premiere ligne : L(0) 
-  if(x==0 && (y!=0 && y!=InputImage->width)) 
-  {
-    k = 0;
-    for(i = x+1; i >= x; i--)
-      for(j = y-1; j < y+2; j++)
-      {
-        GetGrayPixel(InputImage,i,j,pixelCourant);
-        *(neighberPixel+k) = *pixelCourant;
-        k++;
-      }
-  }
-
-  // Voisinage de la derni�re colonne : C(w)
-  if((x!=0 && x!=InputImage->height) && y==InputImage->width) 
-  {
-    k = 0;
-    for(i = x+1; i > x-2; i--)
-      for(j = y-1; j < y+1; j++)
-      {  
-        GetGrayPixel(InputImage,i,j,pixelCourant);
-        *(neighberPixel+k) = *pixelCourant;
-        k++;
-      }
-  }
-
-  // Voisinage de la derni�re ligne : L(h)    
-  if(x==InputImage->height && (y!=0 && y!=InputImage->width)) 
-  {
-    k = 0;
-    for(i = x; i > x-2; i--)
-      for(j = y-1; j < y+2; j++)
-      {  
-        GetGrayPixel(InputImage,i,j,pixelCourant);
-        *(neighberPixel+k) = *pixelCourant;
-        k++;
-      }
-  }
-
-  // Voisinage de la premiere colonne : C(0) 
-  if((x!=0 && x!=InputImage->height) && y==0) 
-  {
-    k = 0;
-    for(i = x-1; i < x+2; i++)
-      for(j = y; j < y+2; j++)
-      {  
-        GetGrayPixel(InputImage,i,j,pixelCourant);
-        *(neighberPixel+k) = *pixelCourant;
-        k++;
-      }
-  }  
-
-  //le calcul du voisinage pour le reste des elementes d'image
-  if((x!=0 && x!=InputImage->height)&&(y!=0 && y!=InputImage->width))
-  {
-    k = 0; 
-    for(i = x+1;i > x-2; i--)
-      for(j = y-1; j < y+2; j++)
-      {  
-        GetGrayPixel(InputImage,i,j,pixelCourant);
-        *(neighberPixel+k) = *pixelCourant;
-        k++;
-      }
-  }
-
-  free(pixelCourant);
-}
-
-void PixelUtils::ForegroundMinimum(IplImage *Foreground, float *Minimum, int n)
-{
-  int i,j,k;
-  float *pixelcourant;
-  
-  pixelcourant = (float *) malloc(n*sizeof(float));
-  
-  for(k = 0; k < n; k++)
-    *(Minimum + k) = 255;
-
-  for(i = 0; i < Foreground->width; i++)
-    for(j = 0; j < Foreground->height; j++)
-    {
-      if(n == 3)
-      {
-        GetPixel(Foreground,i,j,pixelcourant);
-
-        for(k = 0; k < n; k++)
-          if(*(pixelcourant + k) < *(Minimum + k))
-            *(Minimum + k) = *(pixelcourant + k);
-      }
-
-      if(n==1)
-      {
-        GetGrayPixel(Foreground,i,j,pixelcourant);
-
-        if(*pixelcourant < *Minimum)
-          *Minimum = *pixelcourant;
-      }
-    }
-
-    free(pixelcourant);
-}
-
-void PixelUtils::ForegroundMaximum(IplImage *Foreground, float *Maximum, int n)
-{
-  int i,j,k;
-  float *pixelcourant;
-  
-  pixelcourant = (float *) malloc(n*sizeof(float));
-  
-  for(k = 0; k < n; k++)
-    *(Maximum + k) = 0;
-  
-  for(i = 0; i < Foreground->width; i++)
-    for(j = 0; j < Foreground->height; j++)
-    {
-      if(n == 3)
-      {
-        GetPixel(Foreground,i,j,pixelcourant);
-
-        for(k = 0; k < n; k++)
-          if(*(pixelcourant + k) > *(Maximum + k))
-            *(Maximum + k) = *(pixelcourant + k);
-      }
-
-      if(n == 1)
-      {
-        GetGrayPixel(Foreground,i,j,pixelcourant);
-
-        if(*pixelcourant > *Maximum)
-          *Maximum = *pixelcourant;
-      }
-    }
-
-    free(pixelcourant);
-}
-
-void PixelUtils::ComplementaryAlphaImageCreation(IplImage *AlphaImage, IplImage *ComplementaryAlphaImage, int n)
-{
-  int i,j,k;
-  float *pixelcourant, *pixelcourant1;
-  
-  pixelcourant = (float *) malloc(n * sizeof(float));
-  pixelcourant1 = (float *) malloc(n * sizeof(float));
-
-  for(i = 0; i < AlphaImage->width; i++)
-    for(j = 0; j < AlphaImage->height; j++)
-    {
-      if(n == 1)
-      {
-        GetGrayPixel(AlphaImage,i,j,pixelcourant);
-        *pixelcourant1 = 1 - *(pixelcourant);
-        PutGrayPixel(ComplementaryAlphaImage,i,j,*pixelcourant1);
-      }
-
-      if(n == 3)
-      {
-        GetPixel(AlphaImage,i,j,pixelcourant);
-        for(k = 0; k < 3; k++)
-        {
-          *pixelcourant1 = 1.0 - *(pixelcourant);
-          *(pixelcourant1+1) = 1.0 - *(pixelcourant+1);
-          *(pixelcourant1+2) = 1.0 - *(pixelcourant+2);
-        }
-        PutPixel(ComplementaryAlphaImage,i,j,pixelcourant1);
-      }
-    }
-
-    free(pixelcourant);
-    free(pixelcourant1);
-}
diff --git a/package_bgs/tb/T2FMRF_UM.h b/package_bgs/tb/T2FMRF_UM.h
deleted file mode 100644
index fd0da7b1c2b68850d6b624ca489d38abdba462cf..0000000000000000000000000000000000000000
--- a/package_bgs/tb/T2FMRF_UM.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-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
-
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-#include "MRF.h"
-
-using namespace Algorithms::BackgroundSubtraction;
-
-class T2FMRF_UM : public IBGS
-{
-private:
-  bool firstTime;
-  long frameNumber;
-  IplImage *frame;
-  RgbImage frame_data;
-
-  IplImage *old_labeling;
-  IplImage *old;
-
-  T2FMRFParams params;
-  T2FMRF bgs;
-  BwImage lowThresholdMask;
-  BwImage highThresholdMask;
-
-  double threshold;
-  double alpha;
-  float km;
-  float kv;
-  int gaussians;
-  bool showOutput;
-
-  MRF_TC mrf;
-  GMM *gmm;
-  HMM *hmm;
-
-public:
-  T2FMRF_UM();
-  ~T2FMRF_UM();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
diff --git a/package_bgs/tb/T2FMRF_UV.h b/package_bgs/tb/T2FMRF_UV.h
deleted file mode 100644
index 28fcb679c9c698ce5bde59b54d4e8fb5577cc411..0000000000000000000000000000000000000000
--- a/package_bgs/tb/T2FMRF_UV.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-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
-
-#include <iostream>
-#include <opencv2/opencv.hpp>
-
-
-#include "../IBGS.h"
-#include "MRF.h"
-
-using namespace Algorithms::BackgroundSubtraction;
-
-class T2FMRF_UV : public IBGS
-{
-private:
-  bool firstTime;
-  long frameNumber;
-  IplImage *frame;
-  RgbImage frame_data;
-
-  IplImage *old_labeling;
-  IplImage *old;
-
-  T2FMRFParams params;
-  T2FMRF bgs;
-  BwImage lowThresholdMask;
-  BwImage highThresholdMask;
-
-  double threshold;
-  double alpha;
-  float km;
-  float kv;
-  int gaussians;
-  bool showOutput;
-
-  MRF_TC mrf;
-  GMM *gmm;
-  HMM *hmm;
-
-public:
-  T2FMRF_UV();
-  ~T2FMRF_UV();
-
-  void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
-
-private:
-  void saveConfig();
-  void loadConfig();
-};
diff --git a/vs2010/.gitignore b/vs2010/.gitignore
deleted file mode 100644
index affde9233a4b8ff7958593971e21d20c09b0cd72..0000000000000000000000000000000000000000
--- a/vs2010/.gitignore
+++ /dev/null
@@ -1,16 +0,0 @@
-# Ignore everything in this directory
-*
-# Except these files
-!.gitignore
-!README.txt
-!bgslibrary.sln
-!bgslibrary.suo
-!bgslibrary.vcxproj
-!bgslibrary.vcxproj.filters
-!bgslibrary.vcxproj.user
-!bgslibrary_demo.vcxproj
-!bgslibrary_demo.vcxproj.filters
-!bgslibrary_demo.vcxproj.user
-!bgslibrary_demo2.vcxproj
-!bgslibrary_demo2.vcxproj.filters
-!bgslibrary_demo2.vcxproj.user
diff --git a/vs2010/README.txt b/vs2010/README.txt
deleted file mode 100644
index 7b0a5cf1796fc0df235fa1b1f050ef6f4e4cfbf3..0000000000000000000000000000000000000000
--- a/vs2010/README.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-VISUAL STUDIO 2010 TEMPLATE PROJECT
------------------------------------
-Change to [Release][Win32]
-
-Tested with:
-  VISUAL STUDIO 2010
-  VISUAL STUDIO 2012
-  VISUAL STUDIO 2013
-  VISUAL STUDIO 2015
-
-You need to install OpenCV at:
-  C:\OpenCV2.4.10
-or change the project settings.
-
-Build and run! ;)
\ No newline at end of file
diff --git a/vs2010/bgslibrary.sln b/vs2010/bgslibrary.sln
deleted file mode 100644
index ab59be309d10a090953faf2a36022849609195b0..0000000000000000000000000000000000000000
--- a/vs2010/bgslibrary.sln
+++ /dev/null
@@ -1,27 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.24720.0
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bgslibrary", "bgslibrary.vcxproj", "{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bgslibrary_demo", "bgslibrary_demo.vcxproj", "{EBE7FE0E-9FE6-41D2-B744-D43E7446D50C}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bgslibrary_demo2", "bgslibrary_demo2.vcxproj", "{EAA15CCC-270A-460B-A61C-2DB864D67718}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Release|Win32 = Release|Win32
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.Release|Win32.ActiveCfg = Release|Win32
-		{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.Release|Win32.Build.0 = Release|Win32
-		{EBE7FE0E-9FE6-41D2-B744-D43E7446D50C}.Release|Win32.ActiveCfg = Release|Win32
-		{EBE7FE0E-9FE6-41D2-B744-D43E7446D50C}.Release|Win32.Build.0 = Release|Win32
-		{EAA15CCC-270A-460B-A61C-2DB864D67718}.Release|Win32.ActiveCfg = Release|Win32
-		{EAA15CCC-270A-460B-A61C-2DB864D67718}.Release|Win32.Build.0 = Release|Win32
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
diff --git a/vs2010/bgslibrary.suo b/vs2010/bgslibrary.suo
deleted file mode 100644
index 3dc8e43797f0d1ee8f60b5d84b6328c180a83479..0000000000000000000000000000000000000000
Binary files a/vs2010/bgslibrary.suo and /dev/null differ
diff --git a/vs2010/bgslibrary.vcxproj b/vs2010/bgslibrary.vcxproj
deleted file mode 100644
index 248586584484775df8bc7a2d1a7699e80d25c648..0000000000000000000000000000000000000000
--- a/vs2010/bgslibrary.vcxproj
+++ /dev/null
@@ -1,279 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>bgslibrary</RootNamespace>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>..\build</OutDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>C:\OpenCV2.4.10\build\include;C:\OpenCV2.4.10\build\include\opencv;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>C:\OpenCV2.4.10\build\x86\vc10\staticlib\*.lib;comctl32.lib;VFW32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClCompile Include="..\Demo.cpp">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
-    </ClCompile>
-    <ClCompile Include="..\Demo2.cpp">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
-    </ClCompile>
-    <ClCompile Include="..\FrameProcessor.cpp">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-    </ClCompile>
-    <ClCompile Include="..\Main.cpp">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-    </ClCompile>
-    <ClCompile Include="..\package_analysis\ForegroundMaskAnalysis.cpp" />
-    <ClCompile Include="..\package_bgs\AdaptiveBackgroundLearning.cpp" />
-    <ClCompile Include="..\package_bgs\AdaptiveSelectiveBackgroundLearning.cpp" />
-    <ClCompile Include="..\package_bgs\ae\KDE.cpp" />
-    <ClCompile Include="..\package_bgs\ae\KernelTable.cpp" />
-    <ClCompile Include="..\package_bgs\ae\NPBGmodel.cpp" />
-    <ClCompile Include="..\package_bgs\ae\NPBGSubtractor.cpp" />
-    <ClCompile Include="..\package_bgs\av\TBackground.cpp" />
-    <ClCompile Include="..\package_bgs\av\TBackgroundVuMeter.cpp" />
-    <ClCompile Include="..\package_bgs\av\VuMeter.cpp" />
-    <ClCompile Include="..\package_bgs\bl\sdLaMa091.cpp" />
-    <ClCompile Include="..\package_bgs\bl\SigmaDeltaBGS.cpp" />
-    <ClCompile Include="..\package_bgs\ck\graph.cpp" />
-    <ClCompile Include="..\package_bgs\ck\LbpMrf.cpp" />
-    <ClCompile Include="..\package_bgs\ck\maxflow.cpp" />
-    <ClCompile Include="..\package_bgs\ck\MEDefs.cpp" />
-    <ClCompile Include="..\package_bgs\ck\MEHistogram.cpp" />
-    <ClCompile Include="..\package_bgs\ck\MEImage.cpp" />
-    <ClCompile Include="..\package_bgs\ck\MotionDetection.cpp" />
-    <ClCompile Include="..\package_bgs\db\imbs.cpp" />
-    <ClCompile Include="..\package_bgs\db\IndependentMultimodalBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\AdaptiveMedianBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPAdaptiveMedianBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPEigenbackgroundBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPGrimsonGMMBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPMeanBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPPratiMediodBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPTextureBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPWrenGABGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPZivkovicAGMMBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\Eigenbackground.cpp" />
-    <ClCompile Include="..\package_bgs\dp\Error.cpp" />
-    <ClCompile Include="..\package_bgs\dp\GrimsonGMM.cpp" />
-    <ClCompile Include="..\package_bgs\dp\Image.cpp" />
-    <ClCompile Include="..\package_bgs\dp\MeanBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\PratiMediodBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\TextureBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\WrenGA.cpp" />
-    <ClCompile Include="..\package_bgs\dp\ZivkovicAGMM.cpp" />
-    <ClCompile Include="..\package_bgs\FrameDifferenceBGS.cpp" />
-    <ClCompile Include="..\package_bgs\GMG.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\blob.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\BlobExtraction.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\BlobResult.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\CMultiLayerBGS.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\LocalBinaryPattern.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\MultiLayerBGS.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModel.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelFuzzyGauss.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelFuzzySom.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelGauss.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelMog.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelSom.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBAdaptiveSOM.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBFuzzyAdaptiveSOM.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBFuzzyGaussian.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBMixtureOfGaussians.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBSimpleGaussian.cpp" />
-    <ClCompile Include="..\package_bgs\MixtureOfGaussianV1BGS.cpp" />
-    <ClCompile Include="..\package_bgs\MixtureOfGaussianV2BGS.cpp" />
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorLBSP.cpp" />
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorLOBSTER.cpp" />
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorSuBSENSE.cpp" />
-    <ClCompile Include="..\package_bgs\pl\LBSP.cpp" />
-    <ClCompile Include="..\package_bgs\pl\LOBSTER.cpp" />
-    <ClCompile Include="..\package_bgs\pl\SuBSENSE.cpp" />
-    <ClCompile Include="..\package_bgs\sjn\SJN_MultiCueBGS.cpp" />
-    <ClCompile Include="..\package_bgs\StaticFrameDifferenceBGS.cpp" />
-    <ClCompile Include="..\package_bgs\tb\FuzzyChoquetIntegral.cpp" />
-    <ClCompile Include="..\package_bgs\tb\FuzzySugenoIntegral.cpp" />
-    <ClCompile Include="..\package_bgs\tb\FuzzyUtils.cpp" />
-    <ClCompile Include="..\package_bgs\tb\MRF.cpp" />
-    <ClCompile Include="..\package_bgs\tb\PerformanceUtils.cpp" />
-    <ClCompile Include="..\package_bgs\tb\PixelUtils.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FGMM.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FGMM_UM.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FGMM_UV.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FMRF.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FMRF_UM.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FMRF_UV.cpp" />
-    <ClCompile Include="..\package_bgs\WeightedMovingMeanBGS.cpp" />
-    <ClCompile Include="..\package_bgs\WeightedMovingVarianceBGS.cpp" />
-    <ClCompile Include="..\PreProcessor.cpp">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-    </ClCompile>
-    <ClCompile Include="..\VideoAnalysis.cpp">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-    </ClCompile>
-    <ClCompile Include="..\VideoCapture.cpp">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\Config.h">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-    </ClInclude>
-    <ClInclude Include="..\FrameProcessor.h">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-    </ClInclude>
-    <ClInclude Include="..\IFrameProcessor.h">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-    </ClInclude>
-    <ClInclude Include="..\package_analysis\ForegroundMaskAnalysis.h" />
-    <ClInclude Include="..\package_bgs\AdaptiveBackgroundLearning.h" />
-    <ClInclude Include="..\package_bgs\AdaptiveSelectiveBackgroundLearning.h" />
-    <ClInclude Include="..\package_bgs\ae\KDE.h" />
-    <ClInclude Include="..\package_bgs\ae\KernelTable.h" />
-    <ClInclude Include="..\package_bgs\ae\NPBGmodel.h" />
-    <ClInclude Include="..\package_bgs\ae\NPBGSubtractor.h" />
-    <ClInclude Include="..\package_bgs\av\TBackground.h" />
-    <ClInclude Include="..\package_bgs\av\TBackgroundVuMeter.h" />
-    <ClInclude Include="..\package_bgs\av\VuMeter.h" />
-    <ClInclude Include="..\package_bgs\bl\sdLaMa091.h" />
-    <ClInclude Include="..\package_bgs\bl\SigmaDeltaBGS.h" />
-    <ClInclude Include="..\package_bgs\bl\stdbool.h" />
-    <ClInclude Include="..\package_bgs\ck\block.h" />
-    <ClInclude Include="..\package_bgs\ck\graph.h" />
-    <ClInclude Include="..\package_bgs\ck\LbpMrf.h" />
-    <ClInclude Include="..\package_bgs\ck\MEDefs.hpp" />
-    <ClInclude Include="..\package_bgs\ck\MEHistogram.hpp" />
-    <ClInclude Include="..\package_bgs\ck\MEImage.hpp" />
-    <ClInclude Include="..\package_bgs\ck\MotionDetection.hpp" />
-    <ClInclude Include="..\package_bgs\db\imbs.hpp" />
-    <ClInclude Include="..\package_bgs\db\IndependentMultimodalBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\AdaptiveMedianBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\Bgs.h" />
-    <ClInclude Include="..\package_bgs\dp\BgsParams.h" />
-    <ClInclude Include="..\package_bgs\dp\DPAdaptiveMedianBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPEigenbackgroundBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPGrimsonGMMBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPMeanBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPPratiMediodBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPTextureBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPWrenGABGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPZivkovicAGMMBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\Eigenbackground.h" />
-    <ClInclude Include="..\package_bgs\dp\Error.h" />
-    <ClInclude Include="..\package_bgs\dp\GrimsonGMM.h" />
-    <ClInclude Include="..\package_bgs\dp\Image.h" />
-    <ClInclude Include="..\package_bgs\dp\MeanBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\PratiMediodBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\TextureBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\WrenGA.h" />
-    <ClInclude Include="..\package_bgs\dp\ZivkovicAGMM.h" />
-    <ClInclude Include="..\package_bgs\FrameDifferenceBGS.h" />
-    <ClInclude Include="..\package_bgs\GMG.h" />
-    <ClInclude Include="..\package_bgs\IBGS.h" />
-    <ClInclude Include="..\package_bgs\jmo\BackgroundSubtractionAPI.h" />
-    <ClInclude Include="..\package_bgs\jmo\BGS.h" />
-    <ClInclude Include="..\package_bgs\jmo\blob.h" />
-    <ClInclude Include="..\package_bgs\jmo\BlobExtraction.h" />
-    <ClInclude Include="..\package_bgs\jmo\BlobLibraryConfiguration.h" />
-    <ClInclude Include="..\package_bgs\jmo\BlobResult.h" />
-    <ClInclude Include="..\package_bgs\jmo\CMultiLayerBGS.h" />
-    <ClInclude Include="..\package_bgs\jmo\LocalBinaryPattern.h" />
-    <ClInclude Include="..\package_bgs\jmo\MultiLayerBGS.h" />
-    <ClInclude Include="..\package_bgs\jmo\OpenCvDataConversion.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModel.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelFuzzyGauss.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelFuzzySom.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelGauss.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelMog.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelSom.h" />
-    <ClInclude Include="..\package_bgs\lb\LBAdaptiveSOM.h" />
-    <ClInclude Include="..\package_bgs\lb\LBFuzzyAdaptiveSOM.h" />
-    <ClInclude Include="..\package_bgs\lb\LBFuzzyGaussian.h" />
-    <ClInclude Include="..\package_bgs\lb\LBMixtureOfGaussians.h" />
-    <ClInclude Include="..\package_bgs\lb\LBSimpleGaussian.h" />
-    <ClInclude Include="..\package_bgs\lb\Types.h" />
-    <ClInclude Include="..\package_bgs\MixtureOfGaussianV1BGS.h" />
-    <ClInclude Include="..\package_bgs\MixtureOfGaussianV2BGS.h" />
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorLBSP.h" />
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorLOBSTER.h" />
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorSuBSENSE.h" />
-    <ClInclude Include="..\package_bgs\pl\DistanceUtils.h" />
-    <ClInclude Include="..\package_bgs\pl\LBSP.h" />
-    <ClInclude Include="..\package_bgs\pl\LOBSTER.h" />
-    <ClInclude Include="..\package_bgs\pl\RandUtils.h" />
-    <ClInclude Include="..\package_bgs\pl\SuBSENSE.h" />
-    <ClInclude Include="..\package_bgs\sjn\SJN_MultiCueBGS.h" />
-    <ClInclude Include="..\package_bgs\StaticFrameDifferenceBGS.h" />
-    <ClInclude Include="..\package_bgs\tb\FuzzyChoquetIntegral.h" />
-    <ClInclude Include="..\package_bgs\tb\FuzzySugenoIntegral.h" />
-    <ClInclude Include="..\package_bgs\tb\FuzzyUtils.h" />
-    <ClInclude Include="..\package_bgs\tb\MRF.h" />
-    <ClInclude Include="..\package_bgs\tb\PerformanceUtils.h" />
-    <ClInclude Include="..\package_bgs\tb\PixelUtils.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FGMM.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FGMM_UM.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FGMM_UV.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FMRF.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FMRF_UM.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FMRF_UV.h" />
-    <ClInclude Include="..\package_bgs\WeightedMovingMeanBGS.h" />
-    <ClInclude Include="..\package_bgs\WeightedMovingVarianceBGS.h" />
-    <ClInclude Include="..\PreProcessor.h">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-    </ClInclude>
-    <ClInclude Include="..\VideoAnalysis.h">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-    </ClInclude>
-    <ClInclude Include="..\VideoCapture.h">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_1ch.i" />
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_3ch1t.i" />
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_3ch3t.i" />
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_s3ch.i" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>
\ No newline at end of file
diff --git a/vs2010/bgslibrary.vcxproj.filters b/vs2010/bgslibrary.vcxproj.filters
deleted file mode 100644
index ab0fbf0265b52c559040cc089240d8247c1cae67..0000000000000000000000000000000000000000
--- a/vs2010/bgslibrary.vcxproj.filters
+++ /dev/null
@@ -1,644 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-    <Filter Include="Header Files\package_bgs">
-      <UniqueIdentifier>{8cb396e6-81b6-4db9-a1b0-5c2b7c122bd9}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\ae">
-      <UniqueIdentifier>{e1ab6d45-3486-42fa-8f51-69a300c0c173}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\av">
-      <UniqueIdentifier>{7992fa8c-e616-4e72-b249-6ede4f4291b4}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\db">
-      <UniqueIdentifier>{667f4048-d125-4453-9f0c-42f9abd4ed3a}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\dp">
-      <UniqueIdentifier>{89c4b817-936b-483c-abed-3e7e7c1fc427}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\jmo">
-      <UniqueIdentifier>{c5e0f44c-6120-4906-917d-c8c8af3eafec}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\lb">
-      <UniqueIdentifier>{728fbe82-1489-4878-89ea-a62ba0932204}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\pt">
-      <UniqueIdentifier>{6b017402-c47a-49a4-8f57-b5db863e1bde}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\sjn">
-      <UniqueIdentifier>{e25c1e03-530d-4c7a-b776-26bf17595213}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\tb">
-      <UniqueIdentifier>{53f2c4fb-9468-44ce-b76e-e25ea018c084}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\demo">
-      <UniqueIdentifier>{23f1cd4a-e9b2-4338-a5e7-128f451d3c89}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_analysis">
-      <UniqueIdentifier>{52a9f254-d817-4577-96c2-0b3b0a9527b7}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\bl">
-      <UniqueIdentifier>{0494c5d4-b4bb-421c-b032-176903ba8e1b}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\ck">
-      <UniqueIdentifier>{87961eee-b843-45bd-b642-9dcd9d78b661}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\pl">
-      <UniqueIdentifier>{cd33a41f-6151-46a5-95b6-b79022786144}</UniqueIdentifier>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\package_bgs\AdaptiveBackgroundLearning.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\AdaptiveSelectiveBackgroundLearning.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\FrameDifferenceBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\GMG.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\MixtureOfGaussianV1BGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\MixtureOfGaussianV2BGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\StaticFrameDifferenceBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\WeightedMovingMeanBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\WeightedMovingVarianceBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ae\KDE.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ae\KernelTable.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ae\NPBGmodel.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ae\NPBGSubtractor.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\av\TBackground.cpp">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\av\TBackgroundVuMeter.cpp">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\av\VuMeter.cpp">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\db\imbs.cpp">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\db\IndependentMultimodalBGS.cpp">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\AdaptiveMedianBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPAdaptiveMedianBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPEigenbackgroundBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPGrimsonGMMBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPMeanBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPPratiMediodBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPTextureBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPWrenGABGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPZivkovicAGMMBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\Eigenbackground.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\Error.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\GrimsonGMM.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\Image.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\MeanBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\PratiMediodBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\TextureBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\WrenGA.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\ZivkovicAGMM.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\blob.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\BlobExtraction.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\BlobResult.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\CMultiLayerBGS.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\LocalBinaryPattern.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\MultiLayerBGS.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModel.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelFuzzyGauss.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelFuzzySom.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelGauss.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelMog.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelSom.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBAdaptiveSOM.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBFuzzyAdaptiveSOM.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBFuzzyGaussian.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBMixtureOfGaussians.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBSimpleGaussian.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\sjn\SJN_MultiCueBGS.cpp">
-      <Filter>Header Files\package_bgs\sjn</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\FuzzyChoquetIntegral.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\FuzzySugenoIntegral.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\FuzzyUtils.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\MRF.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\PerformanceUtils.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\PixelUtils.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FGMM.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FGMM_UM.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FGMM_UV.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FMRF.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FMRF_UM.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FMRF_UV.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\FrameProcessor.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\Main.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\PreProcessor.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\VideoAnalysis.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\VideoCapture.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\Demo.cpp">
-      <Filter>Source Files\demo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_analysis\ForegroundMaskAnalysis.cpp">
-      <Filter>Header Files\package_analysis</Filter>
-    </ClCompile>
-    <ClCompile Include="..\Demo2.cpp">
-      <Filter>Source Files\demo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\bl\SigmaDeltaBGS.cpp">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\bl\sdLaMa091.cpp">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\graph.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\LbpMrf.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\maxflow.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\MEDefs.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\MEHistogram.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\MEImage.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\MotionDetection.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorLBSP.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorLOBSTER.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorSuBSENSE.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\LBSP.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\LOBSTER.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\SuBSENSE.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\package_bgs\AdaptiveBackgroundLearning.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\AdaptiveSelectiveBackgroundLearning.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\FrameDifferenceBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\GMG.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\IBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\MixtureOfGaussianV1BGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\MixtureOfGaussianV2BGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\StaticFrameDifferenceBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\WeightedMovingMeanBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\WeightedMovingVarianceBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ae\KDE.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ae\KernelTable.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ae\NPBGmodel.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ae\NPBGSubtractor.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\av\TBackground.h">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\av\TBackgroundVuMeter.h">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\av\VuMeter.h">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\db\imbs.hpp">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\db\IndependentMultimodalBGS.h">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\AdaptiveMedianBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\Bgs.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\BgsParams.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPAdaptiveMedianBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPEigenbackgroundBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPGrimsonGMMBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPMeanBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPPratiMediodBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPTextureBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPWrenGABGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPZivkovicAGMMBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\Eigenbackground.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\Error.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\GrimsonGMM.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\Image.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\MeanBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\PratiMediodBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\TextureBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\WrenGA.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\ZivkovicAGMM.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BackgroundSubtractionAPI.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BGS.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\blob.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BlobExtraction.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BlobLibraryConfiguration.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BlobResult.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\CMultiLayerBGS.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\LocalBinaryPattern.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\MultiLayerBGS.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\OpenCvDataConversion.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModel.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelFuzzyGauss.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelFuzzySom.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelGauss.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelMog.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelSom.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBAdaptiveSOM.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBFuzzyAdaptiveSOM.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBFuzzyGaussian.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBMixtureOfGaussians.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBSimpleGaussian.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\Types.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\sjn\SJN_MultiCueBGS.h">
-      <Filter>Header Files\package_bgs\sjn</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\FuzzyChoquetIntegral.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\FuzzySugenoIntegral.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\FuzzyUtils.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\MRF.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\PerformanceUtils.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\PixelUtils.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FGMM.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FGMM_UM.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FGMM_UV.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FMRF.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FMRF_UM.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FMRF_UV.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\Config.h">
-      <Filter>Source Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\FrameProcessor.h">
-      <Filter>Source Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\IFrameProcessor.h">
-      <Filter>Source Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\PreProcessor.h">
-      <Filter>Source Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\VideoAnalysis.h">
-      <Filter>Source Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\VideoCapture.h">
-      <Filter>Source Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_analysis\ForegroundMaskAnalysis.h">
-      <Filter>Header Files\package_analysis</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\bl\sdLaMa091.h">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\bl\SigmaDeltaBGS.h">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\bl\stdbool.h">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\block.h">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\graph.h">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\LbpMrf.h">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\MEDefs.hpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\MEHistogram.hpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\MEImage.hpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\MotionDetection.hpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorLBSP.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorLOBSTER.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorSuBSENSE.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\DistanceUtils.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\LBSP.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\LOBSTER.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\RandUtils.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\SuBSENSE.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_1ch.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_3ch1t.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_3ch3t.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_s3ch.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-  </ItemGroup>
-</Project>
\ No newline at end of file
diff --git a/vs2010/bgslibrary.vcxproj.user b/vs2010/bgslibrary.vcxproj.user
deleted file mode 100644
index ebebb3be3c8c323f20cee48d5f72f973ac3afb4d..0000000000000000000000000000000000000000
--- a/vs2010/bgslibrary.vcxproj.user
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LocalDebuggerWorkingDirectory>../</LocalDebuggerWorkingDirectory>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-    <LocalDebuggerCommandArguments>-uf -fn=dataset/video.avi</LocalDebuggerCommandArguments>
-  </PropertyGroup>
-</Project>
\ No newline at end of file
diff --git a/vs2010/bgslibrary_demo.vcxproj b/vs2010/bgslibrary_demo.vcxproj
deleted file mode 100644
index 966d57be2f68c5f0fd0989367754731893850ff2..0000000000000000000000000000000000000000
--- a/vs2010/bgslibrary_demo.vcxproj
+++ /dev/null
@@ -1,241 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{EBE7FE0E-9FE6-41D2-B744-D43E7446D50C}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>bgslibrary</RootNamespace>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>..\build</OutDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>C:\OpenCV2.4.10\build\include;C:\OpenCV2.4.10\build\include\opencv;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>C:\OpenCV2.4.10\build\x86\vc10\staticlib\*.lib;comctl32.lib;VFW32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClCompile Include="..\Demo.cpp">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\AdaptiveBackgroundLearning.cpp" />
-    <ClCompile Include="..\package_bgs\AdaptiveSelectiveBackgroundLearning.cpp" />
-    <ClCompile Include="..\package_bgs\ae\KDE.cpp" />
-    <ClCompile Include="..\package_bgs\ae\KernelTable.cpp" />
-    <ClCompile Include="..\package_bgs\ae\NPBGmodel.cpp" />
-    <ClCompile Include="..\package_bgs\ae\NPBGSubtractor.cpp" />
-    <ClCompile Include="..\package_bgs\av\TBackground.cpp" />
-    <ClCompile Include="..\package_bgs\av\TBackgroundVuMeter.cpp" />
-    <ClCompile Include="..\package_bgs\av\VuMeter.cpp" />
-    <ClCompile Include="..\package_bgs\bl\sdLaMa091.cpp" />
-    <ClCompile Include="..\package_bgs\bl\SigmaDeltaBGS.cpp" />
-    <ClCompile Include="..\package_bgs\ck\graph.cpp" />
-    <ClCompile Include="..\package_bgs\ck\LbpMrf.cpp" />
-    <ClCompile Include="..\package_bgs\ck\maxflow.cpp" />
-    <ClCompile Include="..\package_bgs\ck\MEDefs.cpp" />
-    <ClCompile Include="..\package_bgs\ck\MEHistogram.cpp" />
-    <ClCompile Include="..\package_bgs\ck\MEImage.cpp" />
-    <ClCompile Include="..\package_bgs\ck\MotionDetection.cpp" />
-    <ClCompile Include="..\package_bgs\db\imbs.cpp" />
-    <ClCompile Include="..\package_bgs\db\IndependentMultimodalBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\AdaptiveMedianBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPAdaptiveMedianBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPEigenbackgroundBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPGrimsonGMMBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPMeanBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPPratiMediodBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPTextureBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPWrenGABGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPZivkovicAGMMBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\Eigenbackground.cpp" />
-    <ClCompile Include="..\package_bgs\dp\Error.cpp" />
-    <ClCompile Include="..\package_bgs\dp\GrimsonGMM.cpp" />
-    <ClCompile Include="..\package_bgs\dp\Image.cpp" />
-    <ClCompile Include="..\package_bgs\dp\MeanBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\PratiMediodBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\TextureBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\WrenGA.cpp" />
-    <ClCompile Include="..\package_bgs\dp\ZivkovicAGMM.cpp" />
-    <ClCompile Include="..\package_bgs\FrameDifferenceBGS.cpp" />
-    <ClCompile Include="..\package_bgs\GMG.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\blob.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\BlobExtraction.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\BlobResult.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\CMultiLayerBGS.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\LocalBinaryPattern.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\MultiLayerBGS.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModel.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelFuzzyGauss.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelFuzzySom.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelGauss.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelMog.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelSom.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBAdaptiveSOM.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBFuzzyAdaptiveSOM.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBFuzzyGaussian.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBMixtureOfGaussians.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBSimpleGaussian.cpp" />
-    <ClCompile Include="..\package_bgs\MixtureOfGaussianV1BGS.cpp" />
-    <ClCompile Include="..\package_bgs\MixtureOfGaussianV2BGS.cpp" />
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorLBSP.cpp" />
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorLOBSTER.cpp" />
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorSuBSENSE.cpp" />
-    <ClCompile Include="..\package_bgs\pl\LBSP.cpp" />
-    <ClCompile Include="..\package_bgs\pl\LOBSTER.cpp" />
-    <ClCompile Include="..\package_bgs\pl\SuBSENSE.cpp" />
-    <ClCompile Include="..\package_bgs\sjn\SJN_MultiCueBGS.cpp" />
-    <ClCompile Include="..\package_bgs\StaticFrameDifferenceBGS.cpp" />
-    <ClCompile Include="..\package_bgs\tb\FuzzyChoquetIntegral.cpp" />
-    <ClCompile Include="..\package_bgs\tb\FuzzySugenoIntegral.cpp" />
-    <ClCompile Include="..\package_bgs\tb\FuzzyUtils.cpp" />
-    <ClCompile Include="..\package_bgs\tb\MRF.cpp" />
-    <ClCompile Include="..\package_bgs\tb\PerformanceUtils.cpp" />
-    <ClCompile Include="..\package_bgs\tb\PixelUtils.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FGMM.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FGMM_UM.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FGMM_UV.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FMRF.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FMRF_UM.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FMRF_UV.cpp" />
-    <ClCompile Include="..\package_bgs\WeightedMovingMeanBGS.cpp" />
-    <ClCompile Include="..\package_bgs\WeightedMovingVarianceBGS.cpp" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\package_bgs\AdaptiveBackgroundLearning.h" />
-    <ClInclude Include="..\package_bgs\AdaptiveSelectiveBackgroundLearning.h" />
-    <ClInclude Include="..\package_bgs\ae\KDE.h" />
-    <ClInclude Include="..\package_bgs\ae\KernelTable.h" />
-    <ClInclude Include="..\package_bgs\ae\NPBGmodel.h" />
-    <ClInclude Include="..\package_bgs\ae\NPBGSubtractor.h" />
-    <ClInclude Include="..\package_bgs\av\TBackground.h" />
-    <ClInclude Include="..\package_bgs\av\TBackgroundVuMeter.h" />
-    <ClInclude Include="..\package_bgs\av\VuMeter.h" />
-    <ClInclude Include="..\package_bgs\bl\sdLaMa091.h" />
-    <ClInclude Include="..\package_bgs\bl\SigmaDeltaBGS.h" />
-    <ClInclude Include="..\package_bgs\bl\stdbool.h" />
-    <ClInclude Include="..\package_bgs\ck\block.h" />
-    <ClInclude Include="..\package_bgs\ck\graph.h" />
-    <ClInclude Include="..\package_bgs\ck\LbpMrf.h" />
-    <ClInclude Include="..\package_bgs\ck\MEDefs.hpp" />
-    <ClInclude Include="..\package_bgs\ck\MEHistogram.hpp" />
-    <ClInclude Include="..\package_bgs\ck\MEImage.hpp" />
-    <ClInclude Include="..\package_bgs\ck\MotionDetection.hpp" />
-    <ClInclude Include="..\package_bgs\db\imbs.hpp" />
-    <ClInclude Include="..\package_bgs\db\IndependentMultimodalBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\AdaptiveMedianBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\Bgs.h" />
-    <ClInclude Include="..\package_bgs\dp\BgsParams.h" />
-    <ClInclude Include="..\package_bgs\dp\DPAdaptiveMedianBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPEigenbackgroundBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPGrimsonGMMBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPMeanBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPPratiMediodBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPTextureBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPWrenGABGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPZivkovicAGMMBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\Eigenbackground.h" />
-    <ClInclude Include="..\package_bgs\dp\Error.h" />
-    <ClInclude Include="..\package_bgs\dp\GrimsonGMM.h" />
-    <ClInclude Include="..\package_bgs\dp\Image.h" />
-    <ClInclude Include="..\package_bgs\dp\MeanBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\PratiMediodBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\TextureBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\WrenGA.h" />
-    <ClInclude Include="..\package_bgs\dp\ZivkovicAGMM.h" />
-    <ClInclude Include="..\package_bgs\FrameDifferenceBGS.h" />
-    <ClInclude Include="..\package_bgs\GMG.h" />
-    <ClInclude Include="..\package_bgs\IBGS.h" />
-    <ClInclude Include="..\package_bgs\jmo\BackgroundSubtractionAPI.h" />
-    <ClInclude Include="..\package_bgs\jmo\BGS.h" />
-    <ClInclude Include="..\package_bgs\jmo\blob.h" />
-    <ClInclude Include="..\package_bgs\jmo\BlobExtraction.h" />
-    <ClInclude Include="..\package_bgs\jmo\BlobLibraryConfiguration.h" />
-    <ClInclude Include="..\package_bgs\jmo\BlobResult.h" />
-    <ClInclude Include="..\package_bgs\jmo\CMultiLayerBGS.h" />
-    <ClInclude Include="..\package_bgs\jmo\LocalBinaryPattern.h" />
-    <ClInclude Include="..\package_bgs\jmo\MultiLayerBGS.h" />
-    <ClInclude Include="..\package_bgs\jmo\OpenCvDataConversion.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModel.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelFuzzyGauss.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelFuzzySom.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelGauss.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelMog.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelSom.h" />
-    <ClInclude Include="..\package_bgs\lb\LBAdaptiveSOM.h" />
-    <ClInclude Include="..\package_bgs\lb\LBFuzzyAdaptiveSOM.h" />
-    <ClInclude Include="..\package_bgs\lb\LBFuzzyGaussian.h" />
-    <ClInclude Include="..\package_bgs\lb\LBMixtureOfGaussians.h" />
-    <ClInclude Include="..\package_bgs\lb\LBSimpleGaussian.h" />
-    <ClInclude Include="..\package_bgs\lb\Types.h" />
-    <ClInclude Include="..\package_bgs\MixtureOfGaussianV1BGS.h" />
-    <ClInclude Include="..\package_bgs\MixtureOfGaussianV2BGS.h" />
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorLBSP.h" />
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorLOBSTER.h" />
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorSuBSENSE.h" />
-    <ClInclude Include="..\package_bgs\pl\DistanceUtils.h" />
-    <ClInclude Include="..\package_bgs\pl\LBSP.h" />
-    <ClInclude Include="..\package_bgs\pl\LOBSTER.h" />
-    <ClInclude Include="..\package_bgs\pl\RandUtils.h" />
-    <ClInclude Include="..\package_bgs\pl\SuBSENSE.h" />
-    <ClInclude Include="..\package_bgs\sjn\SJN_MultiCueBGS.h" />
-    <ClInclude Include="..\package_bgs\StaticFrameDifferenceBGS.h" />
-    <ClInclude Include="..\package_bgs\tb\FuzzyChoquetIntegral.h" />
-    <ClInclude Include="..\package_bgs\tb\FuzzySugenoIntegral.h" />
-    <ClInclude Include="..\package_bgs\tb\FuzzyUtils.h" />
-    <ClInclude Include="..\package_bgs\tb\MRF.h" />
-    <ClInclude Include="..\package_bgs\tb\PerformanceUtils.h" />
-    <ClInclude Include="..\package_bgs\tb\PixelUtils.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FGMM.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FGMM_UM.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FGMM_UV.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FMRF.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FMRF_UM.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FMRF_UV.h" />
-    <ClInclude Include="..\package_bgs\WeightedMovingMeanBGS.h" />
-    <ClInclude Include="..\package_bgs\WeightedMovingVarianceBGS.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_1ch.i" />
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_3ch1t.i" />
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_3ch3t.i" />
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_s3ch.i" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>
\ No newline at end of file
diff --git a/vs2010/bgslibrary_demo.vcxproj.filters b/vs2010/bgslibrary_demo.vcxproj.filters
deleted file mode 100644
index d9f3aa8224c2cec49c0148d8ebcc7e55987957a4..0000000000000000000000000000000000000000
--- a/vs2010/bgslibrary_demo.vcxproj.filters
+++ /dev/null
@@ -1,596 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-    <Filter Include="Header Files\package_bgs">
-      <UniqueIdentifier>{8cb396e6-81b6-4db9-a1b0-5c2b7c122bd9}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\ae">
-      <UniqueIdentifier>{e1ab6d45-3486-42fa-8f51-69a300c0c173}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\av">
-      <UniqueIdentifier>{7992fa8c-e616-4e72-b249-6ede4f4291b4}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\db">
-      <UniqueIdentifier>{667f4048-d125-4453-9f0c-42f9abd4ed3a}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\dp">
-      <UniqueIdentifier>{89c4b817-936b-483c-abed-3e7e7c1fc427}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\jmo">
-      <UniqueIdentifier>{c5e0f44c-6120-4906-917d-c8c8af3eafec}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\lb">
-      <UniqueIdentifier>{728fbe82-1489-4878-89ea-a62ba0932204}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\pt">
-      <UniqueIdentifier>{6b017402-c47a-49a4-8f57-b5db863e1bde}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\sjn">
-      <UniqueIdentifier>{e25c1e03-530d-4c7a-b776-26bf17595213}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\tb">
-      <UniqueIdentifier>{53f2c4fb-9468-44ce-b76e-e25ea018c084}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\bl">
-      <UniqueIdentifier>{0494c5d4-b4bb-421c-b032-176903ba8e1b}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\ck">
-      <UniqueIdentifier>{87961eee-b843-45bd-b642-9dcd9d78b661}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\pl">
-      <UniqueIdentifier>{cd33a41f-6151-46a5-95b6-b79022786144}</UniqueIdentifier>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\package_bgs\AdaptiveBackgroundLearning.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\AdaptiveSelectiveBackgroundLearning.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\FrameDifferenceBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\GMG.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\MixtureOfGaussianV1BGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\MixtureOfGaussianV2BGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\StaticFrameDifferenceBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\WeightedMovingMeanBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\WeightedMovingVarianceBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ae\KDE.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ae\KernelTable.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ae\NPBGmodel.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ae\NPBGSubtractor.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\av\TBackground.cpp">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\av\TBackgroundVuMeter.cpp">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\av\VuMeter.cpp">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\db\imbs.cpp">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\db\IndependentMultimodalBGS.cpp">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\AdaptiveMedianBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPAdaptiveMedianBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPEigenbackgroundBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPGrimsonGMMBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPMeanBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPPratiMediodBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPTextureBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPWrenGABGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPZivkovicAGMMBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\Eigenbackground.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\Error.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\GrimsonGMM.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\Image.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\MeanBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\PratiMediodBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\TextureBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\WrenGA.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\ZivkovicAGMM.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\blob.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\BlobExtraction.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\BlobResult.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\CMultiLayerBGS.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\LocalBinaryPattern.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\MultiLayerBGS.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModel.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelFuzzyGauss.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelFuzzySom.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelGauss.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelMog.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelSom.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBAdaptiveSOM.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBFuzzyAdaptiveSOM.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBFuzzyGaussian.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBMixtureOfGaussians.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBSimpleGaussian.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\sjn\SJN_MultiCueBGS.cpp">
-      <Filter>Header Files\package_bgs\sjn</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\FuzzyChoquetIntegral.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\FuzzySugenoIntegral.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\FuzzyUtils.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\MRF.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\PerformanceUtils.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\PixelUtils.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FGMM.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FGMM_UM.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FGMM_UV.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FMRF.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FMRF_UM.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FMRF_UV.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\bl\SigmaDeltaBGS.cpp">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\bl\sdLaMa091.cpp">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\graph.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\LbpMrf.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\maxflow.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\MEDefs.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\MEHistogram.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\MEImage.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\MotionDetection.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorLBSP.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorLOBSTER.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorSuBSENSE.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\LBSP.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\LOBSTER.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\SuBSENSE.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\Demo.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\package_bgs\AdaptiveBackgroundLearning.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\AdaptiveSelectiveBackgroundLearning.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\FrameDifferenceBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\GMG.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\IBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\MixtureOfGaussianV1BGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\MixtureOfGaussianV2BGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\StaticFrameDifferenceBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\WeightedMovingMeanBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\WeightedMovingVarianceBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ae\KDE.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ae\KernelTable.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ae\NPBGmodel.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ae\NPBGSubtractor.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\av\TBackground.h">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\av\TBackgroundVuMeter.h">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\av\VuMeter.h">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\db\imbs.hpp">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\db\IndependentMultimodalBGS.h">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\AdaptiveMedianBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\Bgs.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\BgsParams.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPAdaptiveMedianBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPEigenbackgroundBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPGrimsonGMMBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPMeanBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPPratiMediodBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPTextureBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPWrenGABGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPZivkovicAGMMBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\Eigenbackground.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\Error.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\GrimsonGMM.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\Image.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\MeanBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\PratiMediodBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\TextureBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\WrenGA.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\ZivkovicAGMM.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BackgroundSubtractionAPI.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BGS.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\blob.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BlobExtraction.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BlobLibraryConfiguration.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BlobResult.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\CMultiLayerBGS.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\LocalBinaryPattern.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\MultiLayerBGS.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\OpenCvDataConversion.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModel.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelFuzzyGauss.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelFuzzySom.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelGauss.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelMog.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelSom.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBAdaptiveSOM.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBFuzzyAdaptiveSOM.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBFuzzyGaussian.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBMixtureOfGaussians.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBSimpleGaussian.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\Types.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\sjn\SJN_MultiCueBGS.h">
-      <Filter>Header Files\package_bgs\sjn</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\FuzzyChoquetIntegral.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\FuzzySugenoIntegral.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\FuzzyUtils.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\MRF.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\PerformanceUtils.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\PixelUtils.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FGMM.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FGMM_UM.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FGMM_UV.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FMRF.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FMRF_UM.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FMRF_UV.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\bl\sdLaMa091.h">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\bl\SigmaDeltaBGS.h">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\bl\stdbool.h">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\block.h">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\graph.h">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\LbpMrf.h">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\MEDefs.hpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\MEHistogram.hpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\MEImage.hpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\MotionDetection.hpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorLBSP.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorLOBSTER.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorSuBSENSE.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\DistanceUtils.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\LBSP.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\LOBSTER.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\RandUtils.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\SuBSENSE.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_1ch.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_3ch1t.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_3ch3t.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_s3ch.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-  </ItemGroup>
-</Project>
\ No newline at end of file
diff --git a/vs2010/bgslibrary_demo.vcxproj.user b/vs2010/bgslibrary_demo.vcxproj.user
deleted file mode 100644
index abe8dd8961e3b66a88605bd7083dad32ef27bee9..0000000000000000000000000000000000000000
--- a/vs2010/bgslibrary_demo.vcxproj.user
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup />
-</Project>
\ No newline at end of file
diff --git a/vs2010/bgslibrary_demo2.vcxproj b/vs2010/bgslibrary_demo2.vcxproj
deleted file mode 100644
index ad0f4c4885039f583f88c26a5176e25810b762a3..0000000000000000000000000000000000000000
--- a/vs2010/bgslibrary_demo2.vcxproj
+++ /dev/null
@@ -1,241 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{EAA15CCC-270A-460B-A61C-2DB864D67718}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>bgslibrary</RootNamespace>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>..\build</OutDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>C:\OpenCV2.4.10\build\include;C:\OpenCV2.4.10\build\include\opencv;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>C:\OpenCV2.4.10\build\x86\vc10\staticlib\*.lib;comctl32.lib;VFW32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClCompile Include="..\Demo2.cpp">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\AdaptiveBackgroundLearning.cpp" />
-    <ClCompile Include="..\package_bgs\AdaptiveSelectiveBackgroundLearning.cpp" />
-    <ClCompile Include="..\package_bgs\ae\KDE.cpp" />
-    <ClCompile Include="..\package_bgs\ae\KernelTable.cpp" />
-    <ClCompile Include="..\package_bgs\ae\NPBGmodel.cpp" />
-    <ClCompile Include="..\package_bgs\ae\NPBGSubtractor.cpp" />
-    <ClCompile Include="..\package_bgs\av\TBackground.cpp" />
-    <ClCompile Include="..\package_bgs\av\TBackgroundVuMeter.cpp" />
-    <ClCompile Include="..\package_bgs\av\VuMeter.cpp" />
-    <ClCompile Include="..\package_bgs\bl\sdLaMa091.cpp" />
-    <ClCompile Include="..\package_bgs\bl\SigmaDeltaBGS.cpp" />
-    <ClCompile Include="..\package_bgs\ck\graph.cpp" />
-    <ClCompile Include="..\package_bgs\ck\LbpMrf.cpp" />
-    <ClCompile Include="..\package_bgs\ck\maxflow.cpp" />
-    <ClCompile Include="..\package_bgs\ck\MEDefs.cpp" />
-    <ClCompile Include="..\package_bgs\ck\MEHistogram.cpp" />
-    <ClCompile Include="..\package_bgs\ck\MEImage.cpp" />
-    <ClCompile Include="..\package_bgs\ck\MotionDetection.cpp" />
-    <ClCompile Include="..\package_bgs\db\imbs.cpp" />
-    <ClCompile Include="..\package_bgs\db\IndependentMultimodalBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\AdaptiveMedianBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPAdaptiveMedianBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPEigenbackgroundBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPGrimsonGMMBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPMeanBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPPratiMediodBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPTextureBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPWrenGABGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPZivkovicAGMMBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\Eigenbackground.cpp" />
-    <ClCompile Include="..\package_bgs\dp\Error.cpp" />
-    <ClCompile Include="..\package_bgs\dp\GrimsonGMM.cpp" />
-    <ClCompile Include="..\package_bgs\dp\Image.cpp" />
-    <ClCompile Include="..\package_bgs\dp\MeanBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\PratiMediodBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\TextureBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\WrenGA.cpp" />
-    <ClCompile Include="..\package_bgs\dp\ZivkovicAGMM.cpp" />
-    <ClCompile Include="..\package_bgs\FrameDifferenceBGS.cpp" />
-    <ClCompile Include="..\package_bgs\GMG.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\blob.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\BlobExtraction.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\BlobResult.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\CMultiLayerBGS.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\LocalBinaryPattern.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\MultiLayerBGS.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModel.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelFuzzyGauss.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelFuzzySom.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelGauss.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelMog.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelSom.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBAdaptiveSOM.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBFuzzyAdaptiveSOM.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBFuzzyGaussian.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBMixtureOfGaussians.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBSimpleGaussian.cpp" />
-    <ClCompile Include="..\package_bgs\MixtureOfGaussianV1BGS.cpp" />
-    <ClCompile Include="..\package_bgs\MixtureOfGaussianV2BGS.cpp" />
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorLBSP.cpp" />
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorLOBSTER.cpp" />
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorSuBSENSE.cpp" />
-    <ClCompile Include="..\package_bgs\pl\LBSP.cpp" />
-    <ClCompile Include="..\package_bgs\pl\LOBSTER.cpp" />
-    <ClCompile Include="..\package_bgs\pl\SuBSENSE.cpp" />
-    <ClCompile Include="..\package_bgs\sjn\SJN_MultiCueBGS.cpp" />
-    <ClCompile Include="..\package_bgs\StaticFrameDifferenceBGS.cpp" />
-    <ClCompile Include="..\package_bgs\tb\FuzzyChoquetIntegral.cpp" />
-    <ClCompile Include="..\package_bgs\tb\FuzzySugenoIntegral.cpp" />
-    <ClCompile Include="..\package_bgs\tb\FuzzyUtils.cpp" />
-    <ClCompile Include="..\package_bgs\tb\MRF.cpp" />
-    <ClCompile Include="..\package_bgs\tb\PerformanceUtils.cpp" />
-    <ClCompile Include="..\package_bgs\tb\PixelUtils.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FGMM.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FGMM_UM.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FGMM_UV.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FMRF.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FMRF_UM.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FMRF_UV.cpp" />
-    <ClCompile Include="..\package_bgs\WeightedMovingMeanBGS.cpp" />
-    <ClCompile Include="..\package_bgs\WeightedMovingVarianceBGS.cpp" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\package_bgs\AdaptiveBackgroundLearning.h" />
-    <ClInclude Include="..\package_bgs\AdaptiveSelectiveBackgroundLearning.h" />
-    <ClInclude Include="..\package_bgs\ae\KDE.h" />
-    <ClInclude Include="..\package_bgs\ae\KernelTable.h" />
-    <ClInclude Include="..\package_bgs\ae\NPBGmodel.h" />
-    <ClInclude Include="..\package_bgs\ae\NPBGSubtractor.h" />
-    <ClInclude Include="..\package_bgs\av\TBackground.h" />
-    <ClInclude Include="..\package_bgs\av\TBackgroundVuMeter.h" />
-    <ClInclude Include="..\package_bgs\av\VuMeter.h" />
-    <ClInclude Include="..\package_bgs\bl\sdLaMa091.h" />
-    <ClInclude Include="..\package_bgs\bl\SigmaDeltaBGS.h" />
-    <ClInclude Include="..\package_bgs\bl\stdbool.h" />
-    <ClInclude Include="..\package_bgs\ck\block.h" />
-    <ClInclude Include="..\package_bgs\ck\graph.h" />
-    <ClInclude Include="..\package_bgs\ck\LbpMrf.h" />
-    <ClInclude Include="..\package_bgs\ck\MEDefs.hpp" />
-    <ClInclude Include="..\package_bgs\ck\MEHistogram.hpp" />
-    <ClInclude Include="..\package_bgs\ck\MEImage.hpp" />
-    <ClInclude Include="..\package_bgs\ck\MotionDetection.hpp" />
-    <ClInclude Include="..\package_bgs\db\imbs.hpp" />
-    <ClInclude Include="..\package_bgs\db\IndependentMultimodalBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\AdaptiveMedianBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\Bgs.h" />
-    <ClInclude Include="..\package_bgs\dp\BgsParams.h" />
-    <ClInclude Include="..\package_bgs\dp\DPAdaptiveMedianBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPEigenbackgroundBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPGrimsonGMMBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPMeanBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPPratiMediodBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPTextureBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPWrenGABGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPZivkovicAGMMBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\Eigenbackground.h" />
-    <ClInclude Include="..\package_bgs\dp\Error.h" />
-    <ClInclude Include="..\package_bgs\dp\GrimsonGMM.h" />
-    <ClInclude Include="..\package_bgs\dp\Image.h" />
-    <ClInclude Include="..\package_bgs\dp\MeanBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\PratiMediodBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\TextureBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\WrenGA.h" />
-    <ClInclude Include="..\package_bgs\dp\ZivkovicAGMM.h" />
-    <ClInclude Include="..\package_bgs\FrameDifferenceBGS.h" />
-    <ClInclude Include="..\package_bgs\GMG.h" />
-    <ClInclude Include="..\package_bgs\IBGS.h" />
-    <ClInclude Include="..\package_bgs\jmo\BackgroundSubtractionAPI.h" />
-    <ClInclude Include="..\package_bgs\jmo\BGS.h" />
-    <ClInclude Include="..\package_bgs\jmo\blob.h" />
-    <ClInclude Include="..\package_bgs\jmo\BlobExtraction.h" />
-    <ClInclude Include="..\package_bgs\jmo\BlobLibraryConfiguration.h" />
-    <ClInclude Include="..\package_bgs\jmo\BlobResult.h" />
-    <ClInclude Include="..\package_bgs\jmo\CMultiLayerBGS.h" />
-    <ClInclude Include="..\package_bgs\jmo\LocalBinaryPattern.h" />
-    <ClInclude Include="..\package_bgs\jmo\MultiLayerBGS.h" />
-    <ClInclude Include="..\package_bgs\jmo\OpenCvDataConversion.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModel.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelFuzzyGauss.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelFuzzySom.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelGauss.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelMog.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelSom.h" />
-    <ClInclude Include="..\package_bgs\lb\LBAdaptiveSOM.h" />
-    <ClInclude Include="..\package_bgs\lb\LBFuzzyAdaptiveSOM.h" />
-    <ClInclude Include="..\package_bgs\lb\LBFuzzyGaussian.h" />
-    <ClInclude Include="..\package_bgs\lb\LBMixtureOfGaussians.h" />
-    <ClInclude Include="..\package_bgs\lb\LBSimpleGaussian.h" />
-    <ClInclude Include="..\package_bgs\lb\Types.h" />
-    <ClInclude Include="..\package_bgs\MixtureOfGaussianV1BGS.h" />
-    <ClInclude Include="..\package_bgs\MixtureOfGaussianV2BGS.h" />
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorLBSP.h" />
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorLOBSTER.h" />
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorSuBSENSE.h" />
-    <ClInclude Include="..\package_bgs\pl\DistanceUtils.h" />
-    <ClInclude Include="..\package_bgs\pl\LBSP.h" />
-    <ClInclude Include="..\package_bgs\pl\LOBSTER.h" />
-    <ClInclude Include="..\package_bgs\pl\RandUtils.h" />
-    <ClInclude Include="..\package_bgs\pl\SuBSENSE.h" />
-    <ClInclude Include="..\package_bgs\sjn\SJN_MultiCueBGS.h" />
-    <ClInclude Include="..\package_bgs\StaticFrameDifferenceBGS.h" />
-    <ClInclude Include="..\package_bgs\tb\FuzzyChoquetIntegral.h" />
-    <ClInclude Include="..\package_bgs\tb\FuzzySugenoIntegral.h" />
-    <ClInclude Include="..\package_bgs\tb\FuzzyUtils.h" />
-    <ClInclude Include="..\package_bgs\tb\MRF.h" />
-    <ClInclude Include="..\package_bgs\tb\PerformanceUtils.h" />
-    <ClInclude Include="..\package_bgs\tb\PixelUtils.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FGMM.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FGMM_UM.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FGMM_UV.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FMRF.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FMRF_UM.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FMRF_UV.h" />
-    <ClInclude Include="..\package_bgs\WeightedMovingMeanBGS.h" />
-    <ClInclude Include="..\package_bgs\WeightedMovingVarianceBGS.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_1ch.i" />
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_3ch1t.i" />
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_3ch3t.i" />
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_s3ch.i" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>
\ No newline at end of file
diff --git a/vs2010/bgslibrary_demo2.vcxproj.filters b/vs2010/bgslibrary_demo2.vcxproj.filters
deleted file mode 100644
index 45de1b6de367d51a75864819fb19ca2483e28e1c..0000000000000000000000000000000000000000
--- a/vs2010/bgslibrary_demo2.vcxproj.filters
+++ /dev/null
@@ -1,596 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-    <Filter Include="Header Files\package_bgs">
-      <UniqueIdentifier>{8cb396e6-81b6-4db9-a1b0-5c2b7c122bd9}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\ae">
-      <UniqueIdentifier>{e1ab6d45-3486-42fa-8f51-69a300c0c173}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\av">
-      <UniqueIdentifier>{7992fa8c-e616-4e72-b249-6ede4f4291b4}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\db">
-      <UniqueIdentifier>{667f4048-d125-4453-9f0c-42f9abd4ed3a}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\dp">
-      <UniqueIdentifier>{89c4b817-936b-483c-abed-3e7e7c1fc427}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\jmo">
-      <UniqueIdentifier>{c5e0f44c-6120-4906-917d-c8c8af3eafec}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\lb">
-      <UniqueIdentifier>{728fbe82-1489-4878-89ea-a62ba0932204}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\pt">
-      <UniqueIdentifier>{6b017402-c47a-49a4-8f57-b5db863e1bde}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\sjn">
-      <UniqueIdentifier>{e25c1e03-530d-4c7a-b776-26bf17595213}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\tb">
-      <UniqueIdentifier>{53f2c4fb-9468-44ce-b76e-e25ea018c084}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\bl">
-      <UniqueIdentifier>{0494c5d4-b4bb-421c-b032-176903ba8e1b}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\ck">
-      <UniqueIdentifier>{87961eee-b843-45bd-b642-9dcd9d78b661}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\pl">
-      <UniqueIdentifier>{cd33a41f-6151-46a5-95b6-b79022786144}</UniqueIdentifier>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\package_bgs\AdaptiveBackgroundLearning.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\AdaptiveSelectiveBackgroundLearning.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\FrameDifferenceBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\GMG.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\MixtureOfGaussianV1BGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\MixtureOfGaussianV2BGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\StaticFrameDifferenceBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\WeightedMovingMeanBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\WeightedMovingVarianceBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ae\KDE.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ae\KernelTable.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ae\NPBGmodel.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ae\NPBGSubtractor.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\av\TBackground.cpp">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\av\TBackgroundVuMeter.cpp">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\av\VuMeter.cpp">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\db\imbs.cpp">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\db\IndependentMultimodalBGS.cpp">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\AdaptiveMedianBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPAdaptiveMedianBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPEigenbackgroundBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPGrimsonGMMBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPMeanBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPPratiMediodBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPTextureBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPWrenGABGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPZivkovicAGMMBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\Eigenbackground.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\Error.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\GrimsonGMM.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\Image.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\MeanBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\PratiMediodBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\TextureBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\WrenGA.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\ZivkovicAGMM.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\blob.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\BlobExtraction.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\BlobResult.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\CMultiLayerBGS.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\LocalBinaryPattern.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\MultiLayerBGS.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModel.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelFuzzyGauss.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelFuzzySom.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelGauss.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelMog.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelSom.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBAdaptiveSOM.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBFuzzyAdaptiveSOM.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBFuzzyGaussian.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBMixtureOfGaussians.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBSimpleGaussian.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\sjn\SJN_MultiCueBGS.cpp">
-      <Filter>Header Files\package_bgs\sjn</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\FuzzyChoquetIntegral.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\FuzzySugenoIntegral.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\FuzzyUtils.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\MRF.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\PerformanceUtils.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\PixelUtils.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FGMM.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FGMM_UM.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FGMM_UV.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FMRF.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FMRF_UM.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FMRF_UV.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\bl\SigmaDeltaBGS.cpp">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\bl\sdLaMa091.cpp">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\graph.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\LbpMrf.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\maxflow.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\MEDefs.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\MEHistogram.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\MEImage.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\MotionDetection.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorLBSP.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorLOBSTER.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorSuBSENSE.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\LBSP.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\LOBSTER.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\SuBSENSE.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\Demo2.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\package_bgs\AdaptiveBackgroundLearning.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\AdaptiveSelectiveBackgroundLearning.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\FrameDifferenceBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\GMG.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\IBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\MixtureOfGaussianV1BGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\MixtureOfGaussianV2BGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\StaticFrameDifferenceBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\WeightedMovingMeanBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\WeightedMovingVarianceBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ae\KDE.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ae\KernelTable.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ae\NPBGmodel.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ae\NPBGSubtractor.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\av\TBackground.h">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\av\TBackgroundVuMeter.h">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\av\VuMeter.h">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\db\imbs.hpp">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\db\IndependentMultimodalBGS.h">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\AdaptiveMedianBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\Bgs.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\BgsParams.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPAdaptiveMedianBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPEigenbackgroundBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPGrimsonGMMBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPMeanBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPPratiMediodBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPTextureBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPWrenGABGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPZivkovicAGMMBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\Eigenbackground.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\Error.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\GrimsonGMM.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\Image.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\MeanBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\PratiMediodBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\TextureBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\WrenGA.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\ZivkovicAGMM.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BackgroundSubtractionAPI.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BGS.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\blob.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BlobExtraction.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BlobLibraryConfiguration.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BlobResult.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\CMultiLayerBGS.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\LocalBinaryPattern.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\MultiLayerBGS.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\OpenCvDataConversion.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModel.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelFuzzyGauss.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelFuzzySom.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelGauss.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelMog.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelSom.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBAdaptiveSOM.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBFuzzyAdaptiveSOM.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBFuzzyGaussian.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBMixtureOfGaussians.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBSimpleGaussian.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\Types.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\sjn\SJN_MultiCueBGS.h">
-      <Filter>Header Files\package_bgs\sjn</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\FuzzyChoquetIntegral.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\FuzzySugenoIntegral.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\FuzzyUtils.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\MRF.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\PerformanceUtils.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\PixelUtils.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FGMM.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FGMM_UM.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FGMM_UV.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FMRF.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FMRF_UM.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FMRF_UV.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\bl\sdLaMa091.h">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\bl\SigmaDeltaBGS.h">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\bl\stdbool.h">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\block.h">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\graph.h">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\LbpMrf.h">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\MEDefs.hpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\MEHistogram.hpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\MEImage.hpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\MotionDetection.hpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorLBSP.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorLOBSTER.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorSuBSENSE.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\DistanceUtils.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\LBSP.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\LOBSTER.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\RandUtils.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\SuBSENSE.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_1ch.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_3ch1t.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_3ch3t.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_s3ch.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-  </ItemGroup>
-</Project>
\ No newline at end of file
diff --git a/vs2010/bgslibrary_demo2.vcxproj.user b/vs2010/bgslibrary_demo2.vcxproj.user
deleted file mode 100644
index abe8dd8961e3b66a88605bd7083dad32ef27bee9..0000000000000000000000000000000000000000
--- a/vs2010/bgslibrary_demo2.vcxproj.user
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup />
-</Project>
\ No newline at end of file
diff --git a/vs2010mfc/outputs/background/KEEP_THIS_FOLDER b/vs2010mfc/outputs/background/KEEP_THIS_FOLDER
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/vs2010mfc/outputs/foreground/KEEP_THIS_FOLDER b/vs2010mfc/outputs/foreground/KEEP_THIS_FOLDER
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/vs2010mfc/outputs/input/KEEP_THIS_FOLDER b/vs2010mfc/outputs/input/KEEP_THIS_FOLDER
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/vs2010mfc/src/ReadMe.txt b/vs2010mfc/src/ReadMe.txt
deleted file mode 100644
index 6c7fde03e015240ce34101fd9d65e3e2fa76f3f6..0000000000000000000000000000000000000000
--- a/vs2010mfc/src/ReadMe.txt
+++ /dev/null
@@ -1,100 +0,0 @@
-================================================================================
-    MICROSOFT FOUNDATION CLASS LIBRARY : bgslibrary_vs2010_mfc Project Overview
-===============================================================================
-
-The application wizard has created this bgslibrary_vs2010_mfc application for
-you.  This application not only demonstrates the basics of using the Microsoft
-Foundation Classes but is also a starting point for writing your application.
-
-This file contains a summary of what you will find in each of the files that
-make up your bgslibrary_vs2010_mfc application.
-
-bgslibrary_vs2010_mfc.vcxproj
-    This is the main project file for VC++ projects generated using an application wizard.
-    It contains information about the version of Visual C++ that generated the file, and
-    information about the platforms, configurations, and project features selected with the
-    application wizard.
-
-bgslibrary_vs2010_mfc.vcxproj.filters
-    This is the filters file for VC++ projects generated using an Application Wizard. 
-    It contains information about the association between the files in your project 
-    and the filters. This association is used in the IDE to show grouping of files with
-    similar extensions under a specific node (for e.g. ".cpp" files are associated with the
-    "Source Files" filter).
-
-bgslibrary_vs2010_mfc.h
-    This is the main header file for the application.  It includes other
-    project specific headers (including Resource.h) and declares the
-    CApp application class.
-
-bgslibrary_vs2010_mfc.cpp
-    This is the main application source file that contains the application
-    class CApp.
-
-bgslibrary_vs2010_mfc.rc
-    This is a listing of all of the Microsoft Windows resources that the
-    program uses.  It includes the icons, bitmaps, and cursors that are stored
-    in the RES subdirectory.  This file can be directly edited in Microsoft
-    Visual C++. Your project resources are in 1033.
-
-res\bgslibrary_vs2010_mfc.ico
-    This is an icon file, which is used as the application's icon.  This
-    icon is included by the main resource file bgslibrary_vs2010_mfc.rc.
-
-res\bgslibrary_vs2010_mfc.rc2
-    This file contains resources that are not edited by Microsoft
-    Visual C++. You should place all resources not editable by
-    the resource editor in this file.
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-The application wizard creates one dialog class:
-
-Dlg.h, Dlg.cpp - the dialog
-    These files contain your CDlg class.  This class defines
-    the behavior of your application's main dialog.  The dialog's template is
-    in bgslibrary_vs2010_mfc.rc, which can be edited in Microsoft Visual C++.
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-Other Features:
-
-ActiveX Controls
-    The application includes support to use ActiveX controls.
-
-/////////////////////////////////////////////////////////////////////////////
-
-Other standard files:
-
-StdAfx.h, StdAfx.cpp
-    These files are used to build a precompiled header (PCH) file
-    named bgslibrary_vs2010_mfc.pch and a precompiled types file named StdAfx.obj.
-
-Resource.h
-    This is the standard header file, which defines new resource IDs.
-    Microsoft Visual C++ reads and updates this file.
-
-bgslibrary_vs2010_mfc.manifest
-	Application manifest files are used by Windows XP to describe an applications
-	dependency on specific versions of Side-by-Side assemblies. The loader uses this
-	information to load the appropriate assembly from the assembly cache or private
-	from the application. The Application manifest  maybe included for redistribution
-	as an external .manifest file that is installed in the same folder as the application
-	executable or it may be included in the executable in the form of a resource.
-/////////////////////////////////////////////////////////////////////////////
-
-Other notes:
-
-The application wizard uses "TODO:" to indicate parts of the source code you
-should add to or customize.
-
-If your application uses MFC in a shared DLL, you will need
-to redistribute the MFC DLLs. If your application is in a language
-other than the operating system's locale, you will also have to
-redistribute the corresponding localized resources MFC100XXX.DLL.
-For more information on both of these topics, please see the section on
-redistributing Visual C++ applications in MSDN documentation.
-
-/////////////////////////////////////////////////////////////////////////////
diff --git a/vs2010mfc/src/bgslibrary_vs2010_mfc.rc b/vs2010mfc/src/bgslibrary_vs2010_mfc.rc
deleted file mode 100644
index 7251658acf1cfb47e9ec6c5f95ae0d54e0237ed3..0000000000000000000000000000000000000000
Binary files a/vs2010mfc/src/bgslibrary_vs2010_mfc.rc and /dev/null differ
diff --git a/vs2010mfc/src/bgslibrary_vs2010_mfc.sln b/vs2010mfc/src/bgslibrary_vs2010_mfc.sln
deleted file mode 100644
index f082581f1fd0405b195a65ebb6f6c52e847782c3..0000000000000000000000000000000000000000
--- a/vs2010mfc/src/bgslibrary_vs2010_mfc.sln
+++ /dev/null
@@ -1,20 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bgslibrary_vs2010_mfc", "bgslibrary_vs2010_mfc.vcxproj", "{236E77EE-00D6-4B4E-80C7-C38847B1B60E}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Release|Win32 = Release|Win32
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{236E77EE-00D6-4B4E-80C7-C38847B1B60E}.Debug|Win32.ActiveCfg = Debug|Win32
-		{236E77EE-00D6-4B4E-80C7-C38847B1B60E}.Debug|Win32.Build.0 = Debug|Win32
-		{236E77EE-00D6-4B4E-80C7-C38847B1B60E}.Release|Win32.ActiveCfg = Release|Win32
-		{236E77EE-00D6-4B4E-80C7-C38847B1B60E}.Release|Win32.Build.0 = Release|Win32
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
diff --git a/vs2010mfc/src/bgslibrary_vs2010_mfc.v12.suo b/vs2010mfc/src/bgslibrary_vs2010_mfc.v12.suo
deleted file mode 100644
index dde25911dbe9553c86ec3483e9f01294bcef873b..0000000000000000000000000000000000000000
Binary files a/vs2010mfc/src/bgslibrary_vs2010_mfc.v12.suo and /dev/null differ
diff --git a/vs2010mfc/src/bgslibrary_vs2010_mfc.vcxproj b/vs2010mfc/src/bgslibrary_vs2010_mfc.vcxproj
deleted file mode 100644
index 1ed007d81a93f2a9df418151d5ca8fa2aeea5ab6..0000000000000000000000000000000000000000
--- a/vs2010mfc/src/bgslibrary_vs2010_mfc.vcxproj
+++ /dev/null
@@ -1,296 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{236E77EE-00D6-4B4E-80C7-C38847B1B60E}</ProjectGuid>
-    <RootNamespace>bgslibrary_vs2010_mfc</RootNamespace>
-    <Keyword>MFCProj</Keyword>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <UseOfMfc>Static</UseOfMfc>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <UseOfMfc>Static</UseOfMfc>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LinkIncremental>true</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <OutDir>../</OutDir>
-    <TargetName>mfc_bgslibrary</TargetName>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <Midl>
-      <MkTypLibCompatible>false</MkTypLibCompatible>
-      <ValidateAllParameters>true</ValidateAllParameters>
-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </Midl>
-    <ResourceCompile>
-      <Culture>0x0409</Culture>
-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-    </ResourceCompile>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>C:\OpenCV2.4.10\build\include;C:\OpenCV2.4.10\build\include\opencv;C:\boost_1_55_0;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>C:\OpenCV2.4.10\build\x86\vc10\staticlib\*.lib;C:\boost_1_55_0\stage32\lib\vc10\*.lib;comctl32.lib;VFW32.lib;uafxcw.lib;LIBCMT.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <ShowProgress>NotSet</ShowProgress>
-      <IgnoreSpecificDefaultLibraries>uafxcw.lib;LIBCMT.lib</IgnoreSpecificDefaultLibraries>
-    </Link>
-    <Midl>
-      <MkTypLibCompatible>false</MkTypLibCompatible>
-      <ValidateAllParameters>true</ValidateAllParameters>
-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </Midl>
-    <ResourceCompile>
-      <Culture>0x0409</Culture>
-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-    </ResourceCompile>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <None Include="..\..\package_bgs\pl\LBSP_16bits_dbcross_1ch.i" />
-    <None Include="..\..\package_bgs\pl\LBSP_16bits_dbcross_3ch1t.i" />
-    <None Include="..\..\package_bgs\pl\LBSP_16bits_dbcross_3ch3t.i" />
-    <None Include="..\..\package_bgs\pl\LBSP_16bits_dbcross_s3ch.i" />
-    <None Include="ReadMe.txt" />
-    <None Include="res\bgslibrary_vs2010_mfc.ico" />
-    <None Include="res\bgslibrary_vs2010_mfc.rc2" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\package_bgs\pl\BackgroundSubtractorLBSP.h" />
-    <ClInclude Include="..\..\package_bgs\pl\BackgroundSubtractorLOBSTER.h" />
-    <ClInclude Include="..\..\package_bgs\pl\BackgroundSubtractorSuBSENSE.h" />
-    <ClInclude Include="..\..\package_bgs\pl\DistanceUtils.h" />
-    <ClInclude Include="..\..\package_bgs\pl\LBSP.h" />
-    <ClInclude Include="..\..\package_bgs\pl\LOBSTER.h" />
-    <ClInclude Include="..\..\package_bgs\pl\RandUtils.h" />
-    <ClInclude Include="..\..\package_bgs\pl\SuBSENSE.h" />
-    <ClInclude Include="App.h" />
-    <ClInclude Include="Dlg.h" />
-    <ClInclude Include="..\..\package_bgs\AdaptiveBackgroundLearning.h" />
-    <ClInclude Include="..\..\package_bgs\AdaptiveSelectiveBackgroundLearning.h" />
-    <ClInclude Include="..\..\package_bgs\ae\KDE.h" />
-    <ClInclude Include="..\..\package_bgs\ae\KernelTable.h" />
-    <ClInclude Include="..\..\package_bgs\ae\NPBGmodel.h" />
-    <ClInclude Include="..\..\package_bgs\ae\NPBGSubtractor.h" />
-    <ClInclude Include="..\..\package_bgs\av\TBackground.h" />
-    <ClInclude Include="..\..\package_bgs\av\TBackgroundVuMeter.h" />
-    <ClInclude Include="..\..\package_bgs\av\VuMeter.h" />
-    <ClInclude Include="..\..\package_bgs\bl\sdLaMa091.h" />
-    <ClInclude Include="..\..\package_bgs\bl\SigmaDeltaBGS.h" />
-    <ClInclude Include="..\..\package_bgs\bl\stdbool.h" />
-    <ClInclude Include="..\..\package_bgs\db\imbs.hpp" />
-    <ClInclude Include="..\..\package_bgs\db\IndependentMultimodalBGS.h" />
-    <ClInclude Include="..\..\package_bgs\dp\AdaptiveMedianBGS.h" />
-    <ClInclude Include="..\..\package_bgs\dp\Bgs.h" />
-    <ClInclude Include="..\..\package_bgs\dp\BgsParams.h" />
-    <ClInclude Include="..\..\package_bgs\dp\DPAdaptiveMedianBGS.h" />
-    <ClInclude Include="..\..\package_bgs\dp\DPEigenbackgroundBGS.h" />
-    <ClInclude Include="..\..\package_bgs\dp\DPGrimsonGMMBGS.h" />
-    <ClInclude Include="..\..\package_bgs\dp\DPMeanBGS.h" />
-    <ClInclude Include="..\..\package_bgs\dp\DPPratiMediodBGS.h" />
-    <ClInclude Include="..\..\package_bgs\dp\DPTextureBGS.h" />
-    <ClInclude Include="..\..\package_bgs\dp\DPWrenGABGS.h" />
-    <ClInclude Include="..\..\package_bgs\dp\DPZivkovicAGMMBGS.h" />
-    <ClInclude Include="..\..\package_bgs\dp\Eigenbackground.h" />
-    <ClInclude Include="..\..\package_bgs\dp\Error.h" />
-    <ClInclude Include="..\..\package_bgs\dp\GrimsonGMM.h" />
-    <ClInclude Include="..\..\package_bgs\dp\Image.h" />
-    <ClInclude Include="..\..\package_bgs\dp\MeanBGS.h" />
-    <ClInclude Include="..\..\package_bgs\dp\PratiMediodBGS.h" />
-    <ClInclude Include="..\..\package_bgs\dp\TextureBGS.h" />
-    <ClInclude Include="..\..\package_bgs\dp\WrenGA.h" />
-    <ClInclude Include="..\..\package_bgs\dp\ZivkovicAGMM.h" />
-    <ClInclude Include="..\..\package_bgs\FrameDifferenceBGS.h" />
-    <ClInclude Include="..\..\package_bgs\GMG.h" />
-    <ClInclude Include="..\..\package_bgs\IBGS.h" />
-    <ClInclude Include="..\..\package_bgs\jmo\BackgroundSubtractionAPI.h" />
-    <ClInclude Include="..\..\package_bgs\jmo\BGS.h" />
-    <ClInclude Include="..\..\package_bgs\jmo\blob.h" />
-    <ClInclude Include="..\..\package_bgs\jmo\BlobExtraction.h" />
-    <ClInclude Include="..\..\package_bgs\jmo\BlobLibraryConfiguration.h" />
-    <ClInclude Include="..\..\package_bgs\jmo\BlobResult.h" />
-    <ClInclude Include="..\..\package_bgs\jmo\CMultiLayerBGS.h" />
-    <ClInclude Include="..\..\package_bgs\jmo\LocalBinaryPattern.h" />
-    <ClInclude Include="..\..\package_bgs\jmo\MultiLayerBGS.h" />
-    <ClInclude Include="..\..\package_bgs\jmo\OpenCvDataConversion.h" />
-    <ClInclude Include="..\..\package_bgs\lb\BGModel.h" />
-    <ClInclude Include="..\..\package_bgs\lb\BGModelFuzzyGauss.h" />
-    <ClInclude Include="..\..\package_bgs\lb\BGModelFuzzySom.h" />
-    <ClInclude Include="..\..\package_bgs\lb\BGModelGauss.h" />
-    <ClInclude Include="..\..\package_bgs\lb\BGModelMog.h" />
-    <ClInclude Include="..\..\package_bgs\lb\BGModelSom.h" />
-    <ClInclude Include="..\..\package_bgs\lb\LBAdaptiveSOM.h" />
-    <ClInclude Include="..\..\package_bgs\lb\LBFuzzyAdaptiveSOM.h" />
-    <ClInclude Include="..\..\package_bgs\lb\LBFuzzyGaussian.h" />
-    <ClInclude Include="..\..\package_bgs\lb\LBMixtureOfGaussians.h" />
-    <ClInclude Include="..\..\package_bgs\lb\LBSimpleGaussian.h" />
-    <ClInclude Include="..\..\package_bgs\lb\Types.h" />
-    <ClInclude Include="..\..\package_bgs\MixtureOfGaussianV1BGS.h" />
-    <ClInclude Include="..\..\package_bgs\MixtureOfGaussianV2BGS.h" />
-    <ClInclude Include="..\..\package_bgs\sjn\SJN_MultiCueBGS.h" />
-    <ClInclude Include="..\..\package_bgs\StaticFrameDifferenceBGS.h" />
-    <ClInclude Include="..\..\package_bgs\tb\FuzzyChoquetIntegral.h" />
-    <ClInclude Include="..\..\package_bgs\tb\FuzzySugenoIntegral.h" />
-    <ClInclude Include="..\..\package_bgs\tb\FuzzyUtils.h" />
-    <ClInclude Include="..\..\package_bgs\tb\MRF.h" />
-    <ClInclude Include="..\..\package_bgs\tb\PerformanceUtils.h" />
-    <ClInclude Include="..\..\package_bgs\tb\PixelUtils.h" />
-    <ClInclude Include="..\..\package_bgs\tb\T2FGMM.h" />
-    <ClInclude Include="..\..\package_bgs\tb\T2FGMM_UM.h" />
-    <ClInclude Include="..\..\package_bgs\tb\T2FGMM_UV.h" />
-    <ClInclude Include="..\..\package_bgs\tb\T2FMRF.h" />
-    <ClInclude Include="..\..\package_bgs\tb\T2FMRF_UM.h" />
-    <ClInclude Include="..\..\package_bgs\tb\T2FMRF_UV.h" />
-    <ClInclude Include="..\..\package_bgs\WeightedMovingMeanBGS.h" />
-    <ClInclude Include="..\..\package_bgs\WeightedMovingVarianceBGS.h" />
-    <ClInclude Include="Resource.h" />
-    <ClInclude Include="stdafx.h" />
-    <ClInclude Include="targetver.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\package_bgs\pl\BackgroundSubtractorLBSP.cpp" />
-    <ClCompile Include="..\..\package_bgs\pl\BackgroundSubtractorLOBSTER.cpp" />
-    <ClCompile Include="..\..\package_bgs\pl\BackgroundSubtractorSuBSENSE.cpp" />
-    <ClCompile Include="..\..\package_bgs\pl\LBSP.cpp" />
-    <ClCompile Include="..\..\package_bgs\pl\LOBSTER.cpp" />
-    <ClCompile Include="..\..\package_bgs\pl\SuBSENSE.cpp" />
-    <ClCompile Include="App.cpp" />
-    <ClCompile Include="Dlg.cpp" />
-    <ClCompile Include="..\..\package_bgs\AdaptiveBackgroundLearning.cpp" />
-    <ClCompile Include="..\..\package_bgs\AdaptiveSelectiveBackgroundLearning.cpp" />
-    <ClCompile Include="..\..\package_bgs\ae\KDE.cpp" />
-    <ClCompile Include="..\..\package_bgs\ae\KernelTable.cpp" />
-    <ClCompile Include="..\..\package_bgs\ae\NPBGmodel.cpp" />
-    <ClCompile Include="..\..\package_bgs\ae\NPBGSubtractor.cpp" />
-    <ClCompile Include="..\..\package_bgs\av\TBackground.cpp" />
-    <ClCompile Include="..\..\package_bgs\av\TBackgroundVuMeter.cpp" />
-    <ClCompile Include="..\..\package_bgs\av\VuMeter.cpp" />
-    <ClCompile Include="..\..\package_bgs\bl\sdLaMa091.cpp" />
-    <ClCompile Include="..\..\package_bgs\bl\SigmaDeltaBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\db\imbs.cpp" />
-    <ClCompile Include="..\..\package_bgs\db\IndependentMultimodalBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\dp\AdaptiveMedianBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\dp\DPAdaptiveMedianBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\dp\DPEigenbackgroundBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\dp\DPGrimsonGMMBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\dp\DPMeanBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\dp\DPPratiMediodBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\dp\DPTextureBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\dp\DPWrenGABGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\dp\DPZivkovicAGMMBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\dp\Eigenbackground.cpp" />
-    <ClCompile Include="..\..\package_bgs\dp\Error.cpp" />
-    <ClCompile Include="..\..\package_bgs\dp\GrimsonGMM.cpp" />
-    <ClCompile Include="..\..\package_bgs\dp\Image.cpp" />
-    <ClCompile Include="..\..\package_bgs\dp\MeanBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\dp\PratiMediodBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\dp\TextureBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\dp\WrenGA.cpp" />
-    <ClCompile Include="..\..\package_bgs\dp\ZivkovicAGMM.cpp" />
-    <ClCompile Include="..\..\package_bgs\FrameDifferenceBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\GMG.cpp" />
-    <ClCompile Include="..\..\package_bgs\jmo\blob.cpp" />
-    <ClCompile Include="..\..\package_bgs\jmo\BlobExtraction.cpp" />
-    <ClCompile Include="..\..\package_bgs\jmo\BlobResult.cpp" />
-    <ClCompile Include="..\..\package_bgs\jmo\CMultiLayerBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\jmo\LocalBinaryPattern.cpp" />
-    <ClCompile Include="..\..\package_bgs\jmo\MultiLayerBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\lb\BGModel.cpp" />
-    <ClCompile Include="..\..\package_bgs\lb\BGModelFuzzyGauss.cpp" />
-    <ClCompile Include="..\..\package_bgs\lb\BGModelFuzzySom.cpp" />
-    <ClCompile Include="..\..\package_bgs\lb\BGModelGauss.cpp" />
-    <ClCompile Include="..\..\package_bgs\lb\BGModelMog.cpp" />
-    <ClCompile Include="..\..\package_bgs\lb\BGModelSom.cpp" />
-    <ClCompile Include="..\..\package_bgs\lb\LBAdaptiveSOM.cpp" />
-    <ClCompile Include="..\..\package_bgs\lb\LBFuzzyAdaptiveSOM.cpp" />
-    <ClCompile Include="..\..\package_bgs\lb\LBFuzzyGaussian.cpp" />
-    <ClCompile Include="..\..\package_bgs\lb\LBMixtureOfGaussians.cpp" />
-    <ClCompile Include="..\..\package_bgs\lb\LBSimpleGaussian.cpp" />
-    <ClCompile Include="..\..\package_bgs\MixtureOfGaussianV1BGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\MixtureOfGaussianV2BGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\sjn\SJN_MultiCueBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\StaticFrameDifferenceBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\tb\FuzzyChoquetIntegral.cpp" />
-    <ClCompile Include="..\..\package_bgs\tb\FuzzySugenoIntegral.cpp" />
-    <ClCompile Include="..\..\package_bgs\tb\FuzzyUtils.cpp" />
-    <ClCompile Include="..\..\package_bgs\tb\MRF.cpp" />
-    <ClCompile Include="..\..\package_bgs\tb\PerformanceUtils.cpp" />
-    <ClCompile Include="..\..\package_bgs\tb\PixelUtils.cpp" />
-    <ClCompile Include="..\..\package_bgs\tb\T2FGMM.cpp" />
-    <ClCompile Include="..\..\package_bgs\tb\T2FGMM_UM.cpp" />
-    <ClCompile Include="..\..\package_bgs\tb\T2FGMM_UV.cpp" />
-    <ClCompile Include="..\..\package_bgs\tb\T2FMRF.cpp" />
-    <ClCompile Include="..\..\package_bgs\tb\T2FMRF_UM.cpp" />
-    <ClCompile Include="..\..\package_bgs\tb\T2FMRF_UV.cpp" />
-    <ClCompile Include="..\..\package_bgs\WeightedMovingMeanBGS.cpp" />
-    <ClCompile Include="..\..\package_bgs\WeightedMovingVarianceBGS.cpp" />
-    <ClCompile Include="stdafx.cpp">
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ResourceCompile Include="bgslibrary_vs2010_mfc.rc" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-  <ProjectExtensions>
-    <VisualStudio>
-      <UserProperties RESOURCE_FILE="bgslibrary_vs2010_mfc.rc" />
-    </VisualStudio>
-  </ProjectExtensions>
-</Project>
\ No newline at end of file
diff --git a/vs2010mfc/src/bgslibrary_vs2010_mfc.vcxproj.filters b/vs2010mfc/src/bgslibrary_vs2010_mfc.vcxproj.filters
deleted file mode 100644
index 28d979dd3d0204fa3d2b913eb231e03c20dc1944..0000000000000000000000000000000000000000
--- a/vs2010mfc/src/bgslibrary_vs2010_mfc.vcxproj.filters
+++ /dev/null
@@ -1,581 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-    <Filter Include="Header Files\package_bgs">
-      <UniqueIdentifier>{be6b45b0-e96c-4347-a65e-a72506b4195f}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\av">
-      <UniqueIdentifier>{c4756493-26d9-46f4-93d6-024b4d1ca61a}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\dp">
-      <UniqueIdentifier>{a3dff805-136a-4fc5-a8e9-a7eadebcd6f2}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\jmo">
-      <UniqueIdentifier>{d9c40f02-d18f-46bb-a956-522e83a8a2e7}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\lb">
-      <UniqueIdentifier>{77576fcd-de50-4205-8072-cb25a1aab145}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\tb">
-      <UniqueIdentifier>{50f16e47-ef1d-46b0-a0cb-f7c07599cd21}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\ae">
-      <UniqueIdentifier>{704bbcb4-9bbe-4fe1-8a80-78ee8d7f49c5}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\sjn">
-      <UniqueIdentifier>{d365878b-8639-4bfd-8008-adb158c9cd8b}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\db">
-      <UniqueIdentifier>{f7961eef-2755-4712-a9b7-1b840b7936b1}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\bl">
-      <UniqueIdentifier>{e23418b4-562b-41ae-bd15-e9ad45ece1d1}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\pl">
-      <UniqueIdentifier>{2a0f8129-33e2-4829-a112-edba4c8f5ef6}</UniqueIdentifier>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="ReadMe.txt" />
-    <None Include="res\bgslibrary_vs2010_mfc.rc2">
-      <Filter>Resource Files</Filter>
-    </None>
-    <None Include="res\bgslibrary_vs2010_mfc.ico">
-      <Filter>Resource Files</Filter>
-    </None>
-    <None Include="..\..\package_bgs\pl\LBSP_16bits_dbcross_1ch.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-    <None Include="..\..\package_bgs\pl\LBSP_16bits_dbcross_3ch1t.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-    <None Include="..\..\package_bgs\pl\LBSP_16bits_dbcross_3ch3t.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-    <None Include="..\..\package_bgs\pl\LBSP_16bits_dbcross_s3ch.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="Dlg.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="stdafx.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="targetver.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Resource.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="App.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\AdaptiveBackgroundLearning.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\FrameDifferenceBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\GMG.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\IBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\MixtureOfGaussianV1BGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\MixtureOfGaussianV2BGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\StaticFrameDifferenceBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\WeightedMovingMeanBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\WeightedMovingVarianceBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\av\TBackground.h">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\av\TBackgroundVuMeter.h">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\av\VuMeter.h">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\jmo\BackgroundSubtractionAPI.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\jmo\BGS.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\jmo\blob.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\jmo\BlobExtraction.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\jmo\BlobLibraryConfiguration.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\jmo\BlobResult.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\jmo\CMultiLayerBGS.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\jmo\LocalBinaryPattern.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\jmo\MultiLayerBGS.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\jmo\OpenCvDataConversion.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\lb\BGModel.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\lb\BGModelFuzzyGauss.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\lb\BGModelFuzzySom.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\lb\BGModelGauss.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\lb\BGModelMog.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\lb\BGModelSom.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\lb\LBAdaptiveSOM.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\lb\LBFuzzyAdaptiveSOM.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\lb\LBFuzzyGaussian.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\lb\LBMixtureOfGaussians.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\lb\LBSimpleGaussian.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\lb\Types.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\tb\FuzzyChoquetIntegral.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\tb\FuzzySugenoIntegral.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\tb\FuzzyUtils.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\tb\MRF.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\tb\PerformanceUtils.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\tb\PixelUtils.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\tb\T2FGMM.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\tb\T2FGMM_UM.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\tb\T2FGMM_UV.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\tb\T2FMRF.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\tb\T2FMRF_UM.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\tb\T2FMRF_UV.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\ae\KDE.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\ae\KernelTable.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\ae\NPBGmodel.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\ae\NPBGSubtractor.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\AdaptiveMedianBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\Bgs.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\BgsParams.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\DPAdaptiveMedianBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\DPEigenbackgroundBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\DPGrimsonGMMBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\DPMeanBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\DPPratiMediodBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\DPTextureBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\DPWrenGABGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\DPZivkovicAGMMBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\Eigenbackground.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\Error.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\GrimsonGMM.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\Image.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\MeanBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\PratiMediodBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\TextureBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\WrenGA.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\dp\ZivkovicAGMM.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\sjn\SJN_MultiCueBGS.h">
-      <Filter>Header Files\package_bgs\sjn</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\db\imbs.hpp">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\db\IndependentMultimodalBGS.h">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\AdaptiveSelectiveBackgroundLearning.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\bl\sdLaMa091.h">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\bl\SigmaDeltaBGS.h">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\bl\stdbool.h">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\pl\BackgroundSubtractorLBSP.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\pl\BackgroundSubtractorLOBSTER.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\pl\BackgroundSubtractorSuBSENSE.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\pl\DistanceUtils.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\pl\LBSP.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\pl\LOBSTER.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\pl\RandUtils.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\package_bgs\pl\SuBSENSE.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="Dlg.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="stdafx.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="App.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\AdaptiveBackgroundLearning.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\FrameDifferenceBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\GMG.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\MixtureOfGaussianV1BGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\MixtureOfGaussianV2BGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\StaticFrameDifferenceBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\WeightedMovingMeanBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\WeightedMovingVarianceBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\av\TBackground.cpp">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\av\TBackgroundVuMeter.cpp">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\av\VuMeter.cpp">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\jmo\blob.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\jmo\BlobExtraction.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\jmo\BlobResult.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\jmo\CMultiLayerBGS.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\jmo\LocalBinaryPattern.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\jmo\MultiLayerBGS.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\lb\BGModel.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\lb\BGModelFuzzyGauss.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\lb\BGModelFuzzySom.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\lb\BGModelGauss.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\lb\BGModelMog.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\lb\BGModelSom.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\lb\LBAdaptiveSOM.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\lb\LBFuzzyAdaptiveSOM.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\lb\LBFuzzyGaussian.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\lb\LBMixtureOfGaussians.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\lb\LBSimpleGaussian.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\tb\FuzzyChoquetIntegral.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\tb\FuzzySugenoIntegral.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\tb\FuzzyUtils.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\tb\MRF.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\tb\PerformanceUtils.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\tb\PixelUtils.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\tb\T2FGMM.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\tb\T2FGMM_UM.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\tb\T2FGMM_UV.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\tb\T2FMRF.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\tb\T2FMRF_UM.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\tb\T2FMRF_UV.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\ae\KDE.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\ae\KernelTable.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\ae\NPBGmodel.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\ae\NPBGSubtractor.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\dp\AdaptiveMedianBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\dp\DPAdaptiveMedianBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\dp\DPEigenbackgroundBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\dp\DPGrimsonGMMBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\dp\DPMeanBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\dp\DPPratiMediodBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\dp\DPTextureBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\dp\DPWrenGABGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\dp\DPZivkovicAGMMBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\dp\Eigenbackground.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\dp\Error.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\dp\GrimsonGMM.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\dp\Image.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\dp\MeanBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\dp\PratiMediodBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\dp\TextureBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\dp\WrenGA.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\dp\ZivkovicAGMM.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\sjn\SJN_MultiCueBGS.cpp">
-      <Filter>Header Files\package_bgs\sjn</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\db\imbs.cpp">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\db\IndependentMultimodalBGS.cpp">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\AdaptiveSelectiveBackgroundLearning.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\bl\sdLaMa091.cpp">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\bl\SigmaDeltaBGS.cpp">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\pl\BackgroundSubtractorLBSP.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\pl\BackgroundSubtractorLOBSTER.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\pl\BackgroundSubtractorSuBSENSE.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\pl\LBSP.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\pl\LOBSTER.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\package_bgs\pl\SuBSENSE.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ResourceCompile Include="bgslibrary_vs2010_mfc.rc">
-      <Filter>Resource Files</Filter>
-    </ResourceCompile>
-  </ItemGroup>
-</Project>
\ No newline at end of file
diff --git a/vs2010mfc/src/bgslibrary_vs2010_mfc.vcxproj.user b/vs2010mfc/src/bgslibrary_vs2010_mfc.vcxproj.user
deleted file mode 100644
index 882b48c8d7ec68d8f657f496796212ce80d27ea7..0000000000000000000000000000000000000000
--- a/vs2010mfc/src/bgslibrary_vs2010_mfc.vcxproj.user
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LocalDebuggerWorkingDirectory>../</LocalDebuggerWorkingDirectory>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
-</Project>
\ No newline at end of file
diff --git a/vs2010mfc/src/res/bgslibrary_vs2010_mfc.ico b/vs2010mfc/src/res/bgslibrary_vs2010_mfc.ico
deleted file mode 100644
index d56fbcdfdf6eac0f4727c34770c26689271d96af..0000000000000000000000000000000000000000
Binary files a/vs2010mfc/src/res/bgslibrary_vs2010_mfc.ico and /dev/null differ
diff --git a/vs2010mfc/src/res/bgslibrary_vs2010_mfc.rc2 b/vs2010mfc/src/res/bgslibrary_vs2010_mfc.rc2
deleted file mode 100644
index e327fa85913f2210efffc3a01eb0194aadda29e2..0000000000000000000000000000000000000000
Binary files a/vs2010mfc/src/res/bgslibrary_vs2010_mfc.rc2 and /dev/null differ
diff --git a/vs2013/.gitignore b/vs2013/.gitignore
deleted file mode 100644
index e289c9527e1cc7770a2991e1087affd94f960243..0000000000000000000000000000000000000000
--- a/vs2013/.gitignore
+++ /dev/null
@@ -1,10 +0,0 @@
-# Ignore everything in this directory
-*
-# Except these files
-!.gitignore
-!bgslibrary.sln
-!bgslibrary.suo
-!bgslibrary.vcxproj
-!bgslibrary.vcxproj.filters
-!bgslibrary.vcxproj.user
-!README.txt
\ No newline at end of file
diff --git a/vs2013/README.txt b/vs2013/README.txt
deleted file mode 100644
index e090e339c1145cffcfd5efb5ff8076bd36febd6f..0000000000000000000000000000000000000000
--- a/vs2013/README.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-VISUAL STUDIO 2013 TEMPLATE PROJECT
------------------------------------
-Select [Release][Win32] or [Release][x64]
-
-YOU NEEDS TO INSTALL OPENCV AT:
-  C:\OpenCV2.4.10
-
-BUILD AND RUN!
\ No newline at end of file
diff --git a/vs2013/bgslibrary.sln b/vs2013/bgslibrary.sln
deleted file mode 100644
index 8013b8e1af2ed99ead4d54d55b9f1efb336b6393..0000000000000000000000000000000000000000
--- a/vs2013/bgslibrary.sln
+++ /dev/null
@@ -1,40 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.31101.0
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bgslibrary", "bgslibrary.vcxproj", "{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Debug|x64 = Debug|x64
-		Release|Win32 = Release|Win32
-		Release|x64 = Release|x64
-		ReleaseDemo|Win32 = ReleaseDemo|Win32
-		ReleaseDemo|x64 = ReleaseDemo|x64
-		ReleaseDemo2|Win32 = ReleaseDemo2|Win32
-		ReleaseDemo2|x64 = ReleaseDemo2|x64
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.Debug|Win32.ActiveCfg = Debug|Win32
-		{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.Debug|Win32.Build.0 = Debug|Win32
-		{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.Debug|x64.ActiveCfg = Debug|x64
-		{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.Debug|x64.Build.0 = Debug|x64
-		{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.Release|Win32.ActiveCfg = Release|Win32
-		{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.Release|Win32.Build.0 = Release|Win32
-		{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.Release|x64.ActiveCfg = Release|x64
-		{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.Release|x64.Build.0 = Release|x64
-		{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.ReleaseDemo|Win32.ActiveCfg = ReleaseDemo|Win32
-		{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.ReleaseDemo|Win32.Build.0 = ReleaseDemo|Win32
-		{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.ReleaseDemo|x64.ActiveCfg = ReleaseDemo|x64
-		{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.ReleaseDemo|x64.Build.0 = ReleaseDemo|x64
-		{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.ReleaseDemo2|Win32.ActiveCfg = ReleaseDemo2|Win32
-		{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.ReleaseDemo2|Win32.Build.0 = ReleaseDemo2|Win32
-		{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.ReleaseDemo2|x64.ActiveCfg = ReleaseDemo2|x64
-		{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.ReleaseDemo2|x64.Build.0 = ReleaseDemo2|x64
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
diff --git a/vs2013/bgslibrary.suo b/vs2013/bgslibrary.suo
deleted file mode 100644
index 3dc8e43797f0d1ee8f60b5d84b6328c180a83479..0000000000000000000000000000000000000000
Binary files a/vs2013/bgslibrary.suo and /dev/null differ
diff --git a/vs2013/bgslibrary.vcxproj b/vs2013/bgslibrary.vcxproj
deleted file mode 100644
index de8e328ef22c18303faf5140fea7ae68a0481ec6..0000000000000000000000000000000000000000
--- a/vs2013/bgslibrary.vcxproj
+++ /dev/null
@@ -1,600 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="ReleaseDemo2|Win32">
-      <Configuration>ReleaseDemo2</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="ReleaseDemo2|x64">
-      <Configuration>ReleaseDemo2</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="ReleaseDemo|Win32">
-      <Configuration>ReleaseDemo</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="ReleaseDemo|x64">
-      <Configuration>ReleaseDemo</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>bgslibrary</RootNamespace>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LinkIncremental>true</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <LinkIncremental>true</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>..\</OutDir>
-    <IntDir>$(Platform)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>../</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>..\</OutDir>
-    <TargetName>Demo</TargetName>
-    <IntDir>$(Platform)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|x64'">
-    <TargetName>Demo</TargetName>
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>../</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>..\</OutDir>
-    <TargetName>Demo2</TargetName>
-    <IntDir>$(Platform)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|x64'">
-    <TargetName>Demo2</TargetName>
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>../</OutDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>C:\OpenCV2.4.10\build\include;C:\OpenCV2.4.10\build\include\opencv;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>C:\OpenCV2.4.10\build\x86\vc12\staticlib\*.lib;comctl32.lib;VFW32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>C:\OpenCV2.4.10\build\include;C:\OpenCV2.4.10\build\include\opencv;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>C:\OpenCV2.4.10\build\x64\vc12\staticlib\*.lib;comctl32.lib;VFW32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>C:\OpenCV2.4.10\build\include;C:\OpenCV2.4.10\build\include\opencv;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>C:\OpenCV2.4.10\build\x86\vc12\staticlib\*.lib;comctl32.lib;VFW32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>C:\OpenCV2.4.10\build\include;C:\OpenCV2.4.10\build\include\opencv;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>C:\OpenCV2.4.10\build\x64\vc12\staticlib\*.lib;comctl32.lib;VFW32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>C:\OpenCV2.4.10\build\include;C:\OpenCV2.4.10\build\include\opencv;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>C:\OpenCV2.4.10\build\x86\vc12\staticlib\*.lib;comctl32.lib;VFW32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>C:\OpenCV2.4.10\build\include;C:\OpenCV2.4.10\build\include\opencv;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>C:\OpenCV2.4.10\build\x64\vc12\staticlib\*.lib;comctl32.lib;VFW32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClCompile Include="..\Demo.cpp">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">true</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|x64'">true</ExcludedFromBuild>
-    </ClCompile>
-    <ClCompile Include="..\Demo2.cpp">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">true</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|x64'">true</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|x64'">false</ExcludedFromBuild>
-    </ClCompile>
-    <ClCompile Include="..\FrameProcessor.cpp">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|x64'">false</ExcludedFromBuild>
-    </ClCompile>
-    <ClCompile Include="..\Main.cpp">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">true</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|x64'">true</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">true</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|x64'">true</ExcludedFromBuild>
-    </ClCompile>
-    <ClCompile Include="..\package_analysis\ForegroundMaskAnalysis.cpp" />
-    <ClCompile Include="..\package_bgs\AdaptiveBackgroundLearning.cpp" />
-    <ClCompile Include="..\package_bgs\AdaptiveSelectiveBackgroundLearning.cpp" />
-    <ClCompile Include="..\package_bgs\ae\KDE.cpp" />
-    <ClCompile Include="..\package_bgs\ae\KernelTable.cpp" />
-    <ClCompile Include="..\package_bgs\ae\NPBGmodel.cpp" />
-    <ClCompile Include="..\package_bgs\ae\NPBGSubtractor.cpp" />
-    <ClCompile Include="..\package_bgs\av\TBackground.cpp" />
-    <ClCompile Include="..\package_bgs\av\TBackgroundVuMeter.cpp" />
-    <ClCompile Include="..\package_bgs\av\VuMeter.cpp" />
-    <ClCompile Include="..\package_bgs\bl\sdLaMa091.cpp" />
-    <ClCompile Include="..\package_bgs\bl\SigmaDeltaBGS.cpp" />
-    <ClCompile Include="..\package_bgs\ck\graph.cpp" />
-    <ClCompile Include="..\package_bgs\ck\LbpMrf.cpp" />
-    <ClCompile Include="..\package_bgs\ck\maxflow.cpp" />
-    <ClCompile Include="..\package_bgs\ck\MEDefs.cpp" />
-    <ClCompile Include="..\package_bgs\ck\MEHistogram.cpp" />
-    <ClCompile Include="..\package_bgs\ck\MEImage.cpp" />
-    <ClCompile Include="..\package_bgs\ck\MotionDetection.cpp" />
-    <ClCompile Include="..\package_bgs\db\imbs.cpp" />
-    <ClCompile Include="..\package_bgs\db\IndependentMultimodalBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\AdaptiveMedianBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPAdaptiveMedianBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPEigenbackgroundBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPGrimsonGMMBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPMeanBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPPratiMediodBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPTextureBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPWrenGABGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\DPZivkovicAGMMBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\Eigenbackground.cpp" />
-    <ClCompile Include="..\package_bgs\dp\Error.cpp" />
-    <ClCompile Include="..\package_bgs\dp\GrimsonGMM.cpp" />
-    <ClCompile Include="..\package_bgs\dp\Image.cpp" />
-    <ClCompile Include="..\package_bgs\dp\MeanBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\PratiMediodBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\TextureBGS.cpp" />
-    <ClCompile Include="..\package_bgs\dp\WrenGA.cpp" />
-    <ClCompile Include="..\package_bgs\dp\ZivkovicAGMM.cpp" />
-    <ClCompile Include="..\package_bgs\FrameDifferenceBGS.cpp" />
-    <ClCompile Include="..\package_bgs\GMG.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\blob.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\BlobExtraction.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\BlobResult.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\CMultiLayerBGS.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\LocalBinaryPattern.cpp" />
-    <ClCompile Include="..\package_bgs\jmo\MultiLayerBGS.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModel.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelFuzzyGauss.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelFuzzySom.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelGauss.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelMog.cpp" />
-    <ClCompile Include="..\package_bgs\lb\BGModelSom.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBAdaptiveSOM.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBFuzzyAdaptiveSOM.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBFuzzyGaussian.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBMixtureOfGaussians.cpp" />
-    <ClCompile Include="..\package_bgs\lb\LBSimpleGaussian.cpp" />
-    <ClCompile Include="..\package_bgs\MixtureOfGaussianV1BGS.cpp" />
-    <ClCompile Include="..\package_bgs\MixtureOfGaussianV2BGS.cpp" />
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorLBSP.cpp" />
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorLOBSTER.cpp" />
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorSuBSENSE.cpp" />
-    <ClCompile Include="..\package_bgs\pl\LBSP.cpp" />
-    <ClCompile Include="..\package_bgs\pl\LOBSTER.cpp" />
-    <ClCompile Include="..\package_bgs\pl\SuBSENSE.cpp" />
-    <ClCompile Include="..\package_bgs\sjn\SJN_MultiCueBGS.cpp" />
-    <ClCompile Include="..\package_bgs\StaticFrameDifferenceBGS.cpp" />
-    <ClCompile Include="..\package_bgs\tb\FuzzyChoquetIntegral.cpp" />
-    <ClCompile Include="..\package_bgs\tb\FuzzySugenoIntegral.cpp" />
-    <ClCompile Include="..\package_bgs\tb\FuzzyUtils.cpp" />
-    <ClCompile Include="..\package_bgs\tb\MRF.cpp" />
-    <ClCompile Include="..\package_bgs\tb\PerformanceUtils.cpp" />
-    <ClCompile Include="..\package_bgs\tb\PixelUtils.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FGMM.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FGMM_UM.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FGMM_UV.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FMRF.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FMRF_UM.cpp" />
-    <ClCompile Include="..\package_bgs\tb\T2FMRF_UV.cpp" />
-    <ClCompile Include="..\package_bgs\WeightedMovingMeanBGS.cpp" />
-    <ClCompile Include="..\package_bgs\WeightedMovingVarianceBGS.cpp" />
-    <ClCompile Include="..\PreProcessor.cpp">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|x64'">false</ExcludedFromBuild>
-    </ClCompile>
-    <ClCompile Include="..\VideoAnalysis.cpp">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|x64'">false</ExcludedFromBuild>
-    </ClCompile>
-    <ClCompile Include="..\VideoCapture.cpp">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|x64'">false</ExcludedFromBuild>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\Config.h">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|x64'">false</ExcludedFromBuild>
-    </ClInclude>
-    <ClInclude Include="..\FrameProcessor.h">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|x64'">false</ExcludedFromBuild>
-    </ClInclude>
-    <ClInclude Include="..\IFrameProcessor.h">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|x64'">false</ExcludedFromBuild>
-    </ClInclude>
-    <ClInclude Include="..\package_analysis\ForegroundMaskAnalysis.h" />
-    <ClInclude Include="..\package_bgs\AdaptiveBackgroundLearning.h" />
-    <ClInclude Include="..\package_bgs\AdaptiveSelectiveBackgroundLearning.h" />
-    <ClInclude Include="..\package_bgs\ae\KDE.h" />
-    <ClInclude Include="..\package_bgs\ae\KernelTable.h" />
-    <ClInclude Include="..\package_bgs\ae\NPBGmodel.h" />
-    <ClInclude Include="..\package_bgs\ae\NPBGSubtractor.h" />
-    <ClInclude Include="..\package_bgs\av\TBackground.h" />
-    <ClInclude Include="..\package_bgs\av\TBackgroundVuMeter.h" />
-    <ClInclude Include="..\package_bgs\av\VuMeter.h" />
-    <ClInclude Include="..\package_bgs\bl\sdLaMa091.h" />
-    <ClInclude Include="..\package_bgs\bl\SigmaDeltaBGS.h" />
-    <ClInclude Include="..\package_bgs\bl\stdbool.h" />
-    <ClInclude Include="..\package_bgs\ck\block.h" />
-    <ClInclude Include="..\package_bgs\ck\graph.h" />
-    <ClInclude Include="..\package_bgs\ck\LbpMrf.h" />
-    <ClInclude Include="..\package_bgs\ck\MEDefs.hpp" />
-    <ClInclude Include="..\package_bgs\ck\MEHistogram.hpp" />
-    <ClInclude Include="..\package_bgs\ck\MEImage.hpp" />
-    <ClInclude Include="..\package_bgs\ck\MotionDetection.hpp" />
-    <ClInclude Include="..\package_bgs\db\imbs.hpp" />
-    <ClInclude Include="..\package_bgs\db\IndependentMultimodalBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\AdaptiveMedianBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\Bgs.h" />
-    <ClInclude Include="..\package_bgs\dp\BgsParams.h" />
-    <ClInclude Include="..\package_bgs\dp\DPAdaptiveMedianBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPEigenbackgroundBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPGrimsonGMMBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPMeanBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPPratiMediodBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPTextureBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPWrenGABGS.h" />
-    <ClInclude Include="..\package_bgs\dp\DPZivkovicAGMMBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\Eigenbackground.h" />
-    <ClInclude Include="..\package_bgs\dp\Error.h" />
-    <ClInclude Include="..\package_bgs\dp\GrimsonGMM.h" />
-    <ClInclude Include="..\package_bgs\dp\Image.h" />
-    <ClInclude Include="..\package_bgs\dp\MeanBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\PratiMediodBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\TextureBGS.h" />
-    <ClInclude Include="..\package_bgs\dp\WrenGA.h" />
-    <ClInclude Include="..\package_bgs\dp\ZivkovicAGMM.h" />
-    <ClInclude Include="..\package_bgs\FrameDifferenceBGS.h" />
-    <ClInclude Include="..\package_bgs\GMG.h" />
-    <ClInclude Include="..\package_bgs\IBGS.h" />
-    <ClInclude Include="..\package_bgs\jmo\BackgroundSubtractionAPI.h" />
-    <ClInclude Include="..\package_bgs\jmo\BGS.h" />
-    <ClInclude Include="..\package_bgs\jmo\blob.h" />
-    <ClInclude Include="..\package_bgs\jmo\BlobExtraction.h" />
-    <ClInclude Include="..\package_bgs\jmo\BlobLibraryConfiguration.h" />
-    <ClInclude Include="..\package_bgs\jmo\BlobResult.h" />
-    <ClInclude Include="..\package_bgs\jmo\CMultiLayerBGS.h" />
-    <ClInclude Include="..\package_bgs\jmo\LocalBinaryPattern.h" />
-    <ClInclude Include="..\package_bgs\jmo\MultiLayerBGS.h" />
-    <ClInclude Include="..\package_bgs\jmo\OpenCvDataConversion.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModel.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelFuzzyGauss.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelFuzzySom.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelGauss.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelMog.h" />
-    <ClInclude Include="..\package_bgs\lb\BGModelSom.h" />
-    <ClInclude Include="..\package_bgs\lb\LBAdaptiveSOM.h" />
-    <ClInclude Include="..\package_bgs\lb\LBFuzzyAdaptiveSOM.h" />
-    <ClInclude Include="..\package_bgs\lb\LBFuzzyGaussian.h" />
-    <ClInclude Include="..\package_bgs\lb\LBMixtureOfGaussians.h" />
-    <ClInclude Include="..\package_bgs\lb\LBSimpleGaussian.h" />
-    <ClInclude Include="..\package_bgs\lb\Types.h" />
-    <ClInclude Include="..\package_bgs\MixtureOfGaussianV1BGS.h" />
-    <ClInclude Include="..\package_bgs\MixtureOfGaussianV2BGS.h" />
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorLBSP.h" />
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorLOBSTER.h" />
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorSuBSENSE.h" />
-    <ClInclude Include="..\package_bgs\pl\DistanceUtils.h" />
-    <ClInclude Include="..\package_bgs\pl\LBSP.h" />
-    <ClInclude Include="..\package_bgs\pl\LOBSTER.h" />
-    <ClInclude Include="..\package_bgs\pl\RandUtils.h" />
-    <ClInclude Include="..\package_bgs\pl\SuBSENSE.h" />
-    <ClInclude Include="..\package_bgs\sjn\SJN_MultiCueBGS.h" />
-    <ClInclude Include="..\package_bgs\StaticFrameDifferenceBGS.h" />
-    <ClInclude Include="..\package_bgs\tb\FuzzyChoquetIntegral.h" />
-    <ClInclude Include="..\package_bgs\tb\FuzzySugenoIntegral.h" />
-    <ClInclude Include="..\package_bgs\tb\FuzzyUtils.h" />
-    <ClInclude Include="..\package_bgs\tb\MRF.h" />
-    <ClInclude Include="..\package_bgs\tb\PerformanceUtils.h" />
-    <ClInclude Include="..\package_bgs\tb\PixelUtils.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FGMM.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FGMM_UM.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FGMM_UV.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FMRF.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FMRF_UM.h" />
-    <ClInclude Include="..\package_bgs\tb\T2FMRF_UV.h" />
-    <ClInclude Include="..\package_bgs\WeightedMovingMeanBGS.h" />
-    <ClInclude Include="..\package_bgs\WeightedMovingVarianceBGS.h" />
-    <ClInclude Include="..\PreProcessor.h">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|x64'">false</ExcludedFromBuild>
-    </ClInclude>
-    <ClInclude Include="..\VideoAnalysis.h">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|x64'">false</ExcludedFromBuild>
-    </ClInclude>
-    <ClInclude Include="..\VideoCapture.h">
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|x64'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|x64'">false</ExcludedFromBuild>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_1ch.i" />
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_3ch1t.i" />
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_3ch3t.i" />
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_s3ch.i" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>
\ No newline at end of file
diff --git a/vs2013/bgslibrary.vcxproj.filters b/vs2013/bgslibrary.vcxproj.filters
deleted file mode 100644
index ab0fbf0265b52c559040cc089240d8247c1cae67..0000000000000000000000000000000000000000
--- a/vs2013/bgslibrary.vcxproj.filters
+++ /dev/null
@@ -1,644 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-    <Filter Include="Header Files\package_bgs">
-      <UniqueIdentifier>{8cb396e6-81b6-4db9-a1b0-5c2b7c122bd9}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\ae">
-      <UniqueIdentifier>{e1ab6d45-3486-42fa-8f51-69a300c0c173}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\av">
-      <UniqueIdentifier>{7992fa8c-e616-4e72-b249-6ede4f4291b4}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\db">
-      <UniqueIdentifier>{667f4048-d125-4453-9f0c-42f9abd4ed3a}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\dp">
-      <UniqueIdentifier>{89c4b817-936b-483c-abed-3e7e7c1fc427}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\jmo">
-      <UniqueIdentifier>{c5e0f44c-6120-4906-917d-c8c8af3eafec}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\lb">
-      <UniqueIdentifier>{728fbe82-1489-4878-89ea-a62ba0932204}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\pt">
-      <UniqueIdentifier>{6b017402-c47a-49a4-8f57-b5db863e1bde}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\sjn">
-      <UniqueIdentifier>{e25c1e03-530d-4c7a-b776-26bf17595213}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\tb">
-      <UniqueIdentifier>{53f2c4fb-9468-44ce-b76e-e25ea018c084}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\demo">
-      <UniqueIdentifier>{23f1cd4a-e9b2-4338-a5e7-128f451d3c89}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_analysis">
-      <UniqueIdentifier>{52a9f254-d817-4577-96c2-0b3b0a9527b7}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\bl">
-      <UniqueIdentifier>{0494c5d4-b4bb-421c-b032-176903ba8e1b}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\ck">
-      <UniqueIdentifier>{87961eee-b843-45bd-b642-9dcd9d78b661}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\package_bgs\pl">
-      <UniqueIdentifier>{cd33a41f-6151-46a5-95b6-b79022786144}</UniqueIdentifier>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\package_bgs\AdaptiveBackgroundLearning.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\AdaptiveSelectiveBackgroundLearning.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\FrameDifferenceBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\GMG.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\MixtureOfGaussianV1BGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\MixtureOfGaussianV2BGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\StaticFrameDifferenceBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\WeightedMovingMeanBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\WeightedMovingVarianceBGS.cpp">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ae\KDE.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ae\KernelTable.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ae\NPBGmodel.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ae\NPBGSubtractor.cpp">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\av\TBackground.cpp">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\av\TBackgroundVuMeter.cpp">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\av\VuMeter.cpp">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\db\imbs.cpp">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\db\IndependentMultimodalBGS.cpp">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\AdaptiveMedianBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPAdaptiveMedianBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPEigenbackgroundBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPGrimsonGMMBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPMeanBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPPratiMediodBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPTextureBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPWrenGABGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\DPZivkovicAGMMBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\Eigenbackground.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\Error.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\GrimsonGMM.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\Image.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\MeanBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\PratiMediodBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\TextureBGS.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\WrenGA.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\dp\ZivkovicAGMM.cpp">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\blob.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\BlobExtraction.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\BlobResult.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\CMultiLayerBGS.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\LocalBinaryPattern.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\jmo\MultiLayerBGS.cpp">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModel.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelFuzzyGauss.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelFuzzySom.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelGauss.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelMog.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\BGModelSom.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBAdaptiveSOM.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBFuzzyAdaptiveSOM.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBFuzzyGaussian.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBMixtureOfGaussians.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\lb\LBSimpleGaussian.cpp">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\sjn\SJN_MultiCueBGS.cpp">
-      <Filter>Header Files\package_bgs\sjn</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\FuzzyChoquetIntegral.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\FuzzySugenoIntegral.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\FuzzyUtils.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\MRF.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\PerformanceUtils.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\PixelUtils.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FGMM.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FGMM_UM.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FGMM_UV.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FMRF.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FMRF_UM.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\tb\T2FMRF_UV.cpp">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClCompile>
-    <ClCompile Include="..\FrameProcessor.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\Main.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\PreProcessor.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\VideoAnalysis.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\VideoCapture.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\Demo.cpp">
-      <Filter>Source Files\demo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_analysis\ForegroundMaskAnalysis.cpp">
-      <Filter>Header Files\package_analysis</Filter>
-    </ClCompile>
-    <ClCompile Include="..\Demo2.cpp">
-      <Filter>Source Files\demo</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\bl\SigmaDeltaBGS.cpp">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\bl\sdLaMa091.cpp">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\graph.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\LbpMrf.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\maxflow.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\MEDefs.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\MEHistogram.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\MEImage.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\ck\MotionDetection.cpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorLBSP.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorLOBSTER.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\BackgroundSubtractorSuBSENSE.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\LBSP.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\LOBSTER.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-    <ClCompile Include="..\package_bgs\pl\SuBSENSE.cpp">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\package_bgs\AdaptiveBackgroundLearning.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\AdaptiveSelectiveBackgroundLearning.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\FrameDifferenceBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\GMG.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\IBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\MixtureOfGaussianV1BGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\MixtureOfGaussianV2BGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\StaticFrameDifferenceBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\WeightedMovingMeanBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\WeightedMovingVarianceBGS.h">
-      <Filter>Header Files\package_bgs</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ae\KDE.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ae\KernelTable.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ae\NPBGmodel.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ae\NPBGSubtractor.h">
-      <Filter>Header Files\package_bgs\ae</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\av\TBackground.h">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\av\TBackgroundVuMeter.h">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\av\VuMeter.h">
-      <Filter>Header Files\package_bgs\av</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\db\imbs.hpp">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\db\IndependentMultimodalBGS.h">
-      <Filter>Header Files\package_bgs\db</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\AdaptiveMedianBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\Bgs.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\BgsParams.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPAdaptiveMedianBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPEigenbackgroundBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPGrimsonGMMBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPMeanBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPPratiMediodBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPTextureBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPWrenGABGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\DPZivkovicAGMMBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\Eigenbackground.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\Error.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\GrimsonGMM.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\Image.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\MeanBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\PratiMediodBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\TextureBGS.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\WrenGA.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\dp\ZivkovicAGMM.h">
-      <Filter>Header Files\package_bgs\dp</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BackgroundSubtractionAPI.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BGS.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\blob.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BlobExtraction.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BlobLibraryConfiguration.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\BlobResult.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\CMultiLayerBGS.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\LocalBinaryPattern.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\MultiLayerBGS.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\jmo\OpenCvDataConversion.h">
-      <Filter>Header Files\package_bgs\jmo</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModel.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelFuzzyGauss.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelFuzzySom.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelGauss.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelMog.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\BGModelSom.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBAdaptiveSOM.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBFuzzyAdaptiveSOM.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBFuzzyGaussian.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBMixtureOfGaussians.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\LBSimpleGaussian.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\lb\Types.h">
-      <Filter>Header Files\package_bgs\lb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\sjn\SJN_MultiCueBGS.h">
-      <Filter>Header Files\package_bgs\sjn</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\FuzzyChoquetIntegral.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\FuzzySugenoIntegral.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\FuzzyUtils.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\MRF.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\PerformanceUtils.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\PixelUtils.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FGMM.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FGMM_UM.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FGMM_UV.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FMRF.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FMRF_UM.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\tb\T2FMRF_UV.h">
-      <Filter>Header Files\package_bgs\tb</Filter>
-    </ClInclude>
-    <ClInclude Include="..\Config.h">
-      <Filter>Source Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\FrameProcessor.h">
-      <Filter>Source Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\IFrameProcessor.h">
-      <Filter>Source Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\PreProcessor.h">
-      <Filter>Source Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\VideoAnalysis.h">
-      <Filter>Source Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\VideoCapture.h">
-      <Filter>Source Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_analysis\ForegroundMaskAnalysis.h">
-      <Filter>Header Files\package_analysis</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\bl\sdLaMa091.h">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\bl\SigmaDeltaBGS.h">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\bl\stdbool.h">
-      <Filter>Header Files\package_bgs\bl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\block.h">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\graph.h">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\LbpMrf.h">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\MEDefs.hpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\MEHistogram.hpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\MEImage.hpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\ck\MotionDetection.hpp">
-      <Filter>Header Files\package_bgs\ck</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorLBSP.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorLOBSTER.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\BackgroundSubtractorSuBSENSE.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\DistanceUtils.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\LBSP.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\LOBSTER.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\RandUtils.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-    <ClInclude Include="..\package_bgs\pl\SuBSENSE.h">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_1ch.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_3ch1t.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_3ch3t.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-    <None Include="..\package_bgs\pl\LBSP_16bits_dbcross_s3ch.i">
-      <Filter>Header Files\package_bgs\pl</Filter>
-    </None>
-  </ItemGroup>
-</Project>
\ No newline at end of file
diff --git a/vs2013/bgslibrary.vcxproj.user b/vs2013/bgslibrary.vcxproj.user
deleted file mode 100644
index 02146ba90de0d9e1d260428f869f3a15a1ae1909..0000000000000000000000000000000000000000
--- a/vs2013/bgslibrary.vcxproj.user
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LocalDebuggerWorkingDirectory>../</LocalDebuggerWorkingDirectory>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-    <LocalDebuggerCommandArguments>-uf=true -fn=dataset/video.avi</LocalDebuggerCommandArguments>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <LocalDebuggerWorkingDirectory>../</LocalDebuggerWorkingDirectory>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-    <LocalDebuggerCommandArguments>-uf=true -fn=dataset/video.avi</LocalDebuggerCommandArguments>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">
-    <LocalDebuggerWorkingDirectory>../</LocalDebuggerWorkingDirectory>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-    <LocalDebuggerCommandArguments>
-    </LocalDebuggerCommandArguments>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|x64'">
-    <LocalDebuggerWorkingDirectory>../</LocalDebuggerWorkingDirectory>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-    <LocalDebuggerCommandArguments />
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">
-    <LocalDebuggerWorkingDirectory>../</LocalDebuggerWorkingDirectory>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-    <LocalDebuggerCommandArguments />
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|x64'">
-    <LocalDebuggerWorkingDirectory>../</LocalDebuggerWorkingDirectory>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-    <LocalDebuggerCommandArguments />
-  </PropertyGroup>
-</Project>
\ No newline at end of file
diff --git a/vs2013mfc/.gitignore b/vs2013mfc/.gitignore
deleted file mode 100644
index fc99052718c029dc8927b7fb705ddc2ad093f0c7..0000000000000000000000000000000000000000
--- a/vs2013mfc/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-*.exe
-*.pdb
-*.dll
\ No newline at end of file
diff --git a/vs2013mfc/config/AdaptiveBackgroundLearning.xml b/vs2013mfc/config/AdaptiveBackgroundLearning.xml
deleted file mode 100644
index 313e1d4ed8e2e952599137b18753bf15811d2ec9..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/AdaptiveBackgroundLearning.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<alpha>5.0000000000000003e-002</alpha>
-<limit>-1</limit>
-<enableThreshold>1</enableThreshold>
-<threshold>15</threshold>
-<showForeground>0</showForeground>
-<showBackground>0</showBackground>
-</opencv_storage>
diff --git a/vs2013mfc/config/AdaptiveSelectiveBackgroundLearning.xml b/vs2013mfc/config/AdaptiveSelectiveBackgroundLearning.xml
deleted file mode 100644
index f175558a53932aac23393b3dd71588289a0f8ee4..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/AdaptiveSelectiveBackgroundLearning.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<learningFrames>90</learningFrames>
-<alphaLearn>5.0000000000000003e-002</alphaLearn>
-<alphaDetection>5.0000000000000003e-002</alphaDetection>
-<threshold>25</threshold>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/DPAdaptiveMedianBGS.xml b/vs2013mfc/config/DPAdaptiveMedianBGS.xml
deleted file mode 100644
index 8d09e859cf6b75c2a5432515ad56c2d87b558c8f..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/DPAdaptiveMedianBGS.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<threshold>40</threshold>
-<samplingRate>7</samplingRate>
-<learningFrames>30</learningFrames>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/DPEigenbackgroundBGS.xml b/vs2013mfc/config/DPEigenbackgroundBGS.xml
deleted file mode 100644
index d610426deba5bf4cc874695b1498b63390e0edf8..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/DPEigenbackgroundBGS.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<threshold>225</threshold>
-<historySize>20</historySize>
-<embeddedDim>10</embeddedDim>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/DPGrimsonGMMBGS.xml b/vs2013mfc/config/DPGrimsonGMMBGS.xml
deleted file mode 100644
index 8ade44f22824afdef676e1a7e80c93ffba82ac98..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/DPGrimsonGMMBGS.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<threshold>9.</threshold>
-<alpha>1.0000000000000000e-002</alpha>
-<gaussians>3</gaussians>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/DPMeanBGS.xml b/vs2013mfc/config/DPMeanBGS.xml
deleted file mode 100644
index 9bd59a84a2fc903366207bea2023eb0af22e30bb..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/DPMeanBGS.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<threshold>2700</threshold>
-<alpha>9.9999999747524271e-007</alpha>
-<learningFrames>30</learningFrames>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/DPPratiMediodBGS.xml b/vs2013mfc/config/DPPratiMediodBGS.xml
deleted file mode 100644
index fdf20b4efdecf362ef6de51abb5246ac60d59166..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/DPPratiMediodBGS.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<threshold>30</threshold>
-<samplingRate>5</samplingRate>
-<historySize>16</historySize>
-<weight>5</weight>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/DPTextureBGS.xml b/vs2013mfc/config/DPTextureBGS.xml
deleted file mode 100644
index 0d63e78ca0ddbea78b29206d4e652e0f3398b3c0..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/DPTextureBGS.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/DPWrenGABGS.xml b/vs2013mfc/config/DPWrenGABGS.xml
deleted file mode 100644
index 7eaa78ba47d02d4547ca1d3af118417e857f8048..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/DPWrenGABGS.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<threshold>1.2250000000000000e+001</threshold>
-<alpha>4.9999998882412910e-003</alpha>
-<learningFrames>30</learningFrames>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/DPZivkovicAGMMBGS.xml b/vs2013mfc/config/DPZivkovicAGMMBGS.xml
deleted file mode 100644
index 98ee82aaf9cd25da3cc38e2747da86db4822d9f2..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/DPZivkovicAGMMBGS.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<threshold>25.</threshold>
-<alpha>1.0000000474974513e-003</alpha>
-<gaussians>3</gaussians>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/FrameDifferenceBGS.xml b/vs2013mfc/config/FrameDifferenceBGS.xml
deleted file mode 100644
index 943a6c91f4eb5c48a786cd59ee1b73456090d365..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/FrameDifferenceBGS.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<enableThreshold>1</enableThreshold>
-<threshold>15</threshold>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/FuzzyChoquetIntegral.xml b/vs2013mfc/config/FuzzyChoquetIntegral.xml
deleted file mode 100644
index 22074aa90bffddb80527f40cbf4406b41ff47a48..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/FuzzyChoquetIntegral.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<showOutput>0</showOutput>
-<framesToLearn>10</framesToLearn>
-<alphaLearn>1.0000000000000001e-001</alphaLearn>
-<alphaUpdate>1.0000000000000000e-002</alphaUpdate>
-<colorSpace>1</colorSpace>
-<option>2</option>
-<smooth>1</smooth>
-<threshold>6.7000000000000004e-001</threshold>
-</opencv_storage>
diff --git a/vs2013mfc/config/FuzzySugenoIntegral.xml b/vs2013mfc/config/FuzzySugenoIntegral.xml
deleted file mode 100644
index 22074aa90bffddb80527f40cbf4406b41ff47a48..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/FuzzySugenoIntegral.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<showOutput>0</showOutput>
-<framesToLearn>10</framesToLearn>
-<alphaLearn>1.0000000000000001e-001</alphaLearn>
-<alphaUpdate>1.0000000000000000e-002</alphaUpdate>
-<colorSpace>1</colorSpace>
-<option>2</option>
-<smooth>1</smooth>
-<threshold>6.7000000000000004e-001</threshold>
-</opencv_storage>
diff --git a/vs2013mfc/config/GMG.xml b/vs2013mfc/config/GMG.xml
deleted file mode 100644
index e3ebdc736e92d8f096ffaacb9b491b111e353ebf..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/GMG.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<initializationFrames>20</initializationFrames>
-<decisionThreshold>6.9999999999999996e-001</decisionThreshold>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/IndependentMultimodalBGS.xml b/vs2013mfc/config/IndependentMultimodalBGS.xml
deleted file mode 100644
index 0d63e78ca0ddbea78b29206d4e652e0f3398b3c0..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/IndependentMultimodalBGS.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/KDE.xml b/vs2013mfc/config/KDE.xml
deleted file mode 100644
index c9b74025011e4f19d1752e8955c3b6ae0cf0f30a..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/KDE.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<framesToLearn>10</framesToLearn>
-<SequenceLength>50</SequenceLength>
-<TimeWindowSize>100</TimeWindowSize>
-<SDEstimationFlag>1</SDEstimationFlag>
-<lUseColorRatiosFlag>1</lUseColorRatiosFlag>
-<th>9.9999999999999995e-008</th>
-<alpha>2.9999999999999999e-001</alpha>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/LBAdaptiveSOM.xml b/vs2013mfc/config/LBAdaptiveSOM.xml
deleted file mode 100644
index 94b257021cfcf7c730ed2af03281086623339fb2..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/LBAdaptiveSOM.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<sensitivity>75</sensitivity>
-<trainingSensitivity>245</trainingSensitivity>
-<learningRate>62</learningRate>
-<trainingLearningRate>255</trainingLearningRate>
-<trainingSteps>55</trainingSteps>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/LBFuzzyAdaptiveSOM.xml b/vs2013mfc/config/LBFuzzyAdaptiveSOM.xml
deleted file mode 100644
index 7168563f6a032ac019e3facff2bf5b34bda5a779..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/LBFuzzyAdaptiveSOM.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<sensitivity>90</sensitivity>
-<trainingSensitivity>240</trainingSensitivity>
-<learningRate>38</learningRate>
-<trainingLearningRate>255</trainingLearningRate>
-<trainingSteps>81</trainingSteps>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/LBFuzzyGaussian.xml b/vs2013mfc/config/LBFuzzyGaussian.xml
deleted file mode 100644
index 18635a1248e632d25f4d623c7e011a71d18ac74d..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/LBFuzzyGaussian.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<sensitivity>72</sensitivity>
-<bgThreshold>162</bgThreshold>
-<learningRate>49</learningRate>
-<noiseVariance>195</noiseVariance>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/LBMixtureOfGaussians.xml b/vs2013mfc/config/LBMixtureOfGaussians.xml
deleted file mode 100644
index 22737201df64764ae51248cfb40eef752bb36500..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/LBMixtureOfGaussians.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<sensitivity>81</sensitivity>
-<bgThreshold>83</bgThreshold>
-<learningRate>59</learningRate>
-<noiseVariance>206</noiseVariance>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/LBSimpleGaussian.xml b/vs2013mfc/config/LBSimpleGaussian.xml
deleted file mode 100644
index a803f3f120523af3bbe4fa721bff4a645148ef73..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/LBSimpleGaussian.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<sensitivity>66</sensitivity>
-<noiseVariance>162</noiseVariance>
-<learningRate>18</learningRate>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/LOBSTERBGS.xml b/vs2013mfc/config/LOBSTERBGS.xml
deleted file mode 100644
index c17b5510fc48a0142fe8bf2c4afad7024d78625f..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/LOBSTERBGS.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<fRelLBSPThreshold>3.6500000953674316e-001</fRelLBSPThreshold>
-<nLBSPThresholdOffset>0</nLBSPThresholdOffset>
-<nDescDistThreshold>4</nDescDistThreshold>
-<nColorDistThreshold>30</nColorDistThreshold>
-<nBGSamples>35</nBGSamples>
-<nRequiredBGSamples>2</nRequiredBGSamples>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/MixtureOfGaussianV1BGS.xml b/vs2013mfc/config/MixtureOfGaussianV1BGS.xml
deleted file mode 100644
index 1e09ceb40082f60946afc3cb09e7ad6189af2e09..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/MixtureOfGaussianV1BGS.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<alpha>5.0000000000000003e-002</alpha>
-<enableThreshold>1</enableThreshold>
-<threshold>15</threshold>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/MixtureOfGaussianV2BGS.xml b/vs2013mfc/config/MixtureOfGaussianV2BGS.xml
deleted file mode 100644
index 1e09ceb40082f60946afc3cb09e7ad6189af2e09..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/MixtureOfGaussianV2BGS.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<alpha>5.0000000000000003e-002</alpha>
-<enableThreshold>1</enableThreshold>
-<threshold>15</threshold>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/MultiCueBGS.xml b/vs2013mfc/config/MultiCueBGS.xml
deleted file mode 100644
index 0d63e78ca0ddbea78b29206d4e652e0f3398b3c0..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/MultiCueBGS.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/MultiLayerBGS.xml b/vs2013mfc/config/MultiLayerBGS.xml
deleted file mode 100644
index 9b803db7ec73435625fb1fc3f0f5458f77b71a11..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/MultiLayerBGS.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<preloadModel>"./models/MultiLayerBGSModel.yml"</preloadModel>
-<saveModel>0</saveModel>
-<detectAfter>0</detectAfter>
-<disableDetectMode>1</disableDetectMode>
-<disableLearningInDetecMode>0</disableLearningInDetecMode>
-<loadDefaultParams>1</loadDefaultParams>
-<max_mode_num>5</max_mode_num>
-<weight_updating_constant>5.</weight_updating_constant>
-<texture_weight>5.0000000000000000e-001</texture_weight>
-<bg_mode_percent>6.0000002384185791e-001</bg_mode_percent>
-<pattern_neig_half_size>4</pattern_neig_half_size>
-<pattern_neig_gaus_sigma>3.</pattern_neig_gaus_sigma>
-<bg_prob_threshold>2.0000000298023224e-001</bg_prob_threshold>
-<bg_prob_updating_threshold>2.0000000298023224e-001</bg_prob_updating_threshold>
-<robust_LBP_constant>3</robust_LBP_constant>
-<min_noised_angle>1.7453293502330780e-001</min_noised_angle>
-<shadow_rate>6.0000002384185791e-001</shadow_rate>
-<highlight_rate>1.2000000476837158e+000</highlight_rate>
-<bilater_filter_sigma_s>3.</bilater_filter_sigma_s>
-<bilater_filter_sigma_r>1.0000000149011612e-001</bilater_filter_sigma_r>
-<frame_duration>1.0000000149011612e-001</frame_duration>
-<learn_mode_learn_rate_per_second>5.0000000000000000e-001</learn_mode_learn_rate_per_second>
-<learn_weight_learn_rate_per_second>5.0000000000000000e-001</learn_weight_learn_rate_per_second>
-<learn_init_mode_weight>5.0000000745058060e-002</learn_init_mode_weight>
-<detect_mode_learn_rate_per_second>9.9999997764825821e-003</detect_mode_learn_rate_per_second>
-<detect_weight_learn_rate_per_second>9.9999997764825821e-003</detect_weight_learn_rate_per_second>
-<detect_init_mode_weight>1.0000000474974513e-003</detect_init_mode_weight>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/SigmaDeltaBGS.xml b/vs2013mfc/config/SigmaDeltaBGS.xml
deleted file mode 100644
index f1b2b2f54d8a9dd555297315cbb96217efb2d533..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/SigmaDeltaBGS.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<ampFactor>1</ampFactor>
-<minVar>15</minVar>
-<maxVar>255</maxVar>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/StaticFrameDifferenceBGS.xml b/vs2013mfc/config/StaticFrameDifferenceBGS.xml
deleted file mode 100644
index 943a6c91f4eb5c48a786cd59ee1b73456090d365..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/StaticFrameDifferenceBGS.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<enableThreshold>1</enableThreshold>
-<threshold>15</threshold>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/SuBSENSEBGS.xml b/vs2013mfc/config/SuBSENSEBGS.xml
deleted file mode 100644
index 05509c15a8c0cf70db253d9ad5a90f3bfe819942..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/SuBSENSEBGS.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<fRelLBSPThreshold>3.3300000429153442e-001</fRelLBSPThreshold>
-<nDescDistThresholdOffset>3</nDescDistThresholdOffset>
-<nMinColorDistThreshold>30</nMinColorDistThreshold>
-<nBGSamples>50</nBGSamples>
-<nRequiredBGSamples>2</nRequiredBGSamples>
-<nSamplesForMovingAvgs>100</nSamplesForMovingAvgs>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/T2FGMM_UM.xml b/vs2013mfc/config/T2FGMM_UM.xml
deleted file mode 100644
index d2f1054e0517b8df10af55e715c94e9add632edc..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/T2FGMM_UM.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<threshold>9.</threshold>
-<alpha>1.0000000000000000e-002</alpha>
-<km>1.5000000000000000e+000</km>
-<kv>6.0000002384185791e-001</kv>
-<gaussians>3</gaussians>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/T2FGMM_UV.xml b/vs2013mfc/config/T2FGMM_UV.xml
deleted file mode 100644
index d2f1054e0517b8df10af55e715c94e9add632edc..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/T2FGMM_UV.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<threshold>9.</threshold>
-<alpha>1.0000000000000000e-002</alpha>
-<km>1.5000000000000000e+000</km>
-<kv>6.0000002384185791e-001</kv>
-<gaussians>3</gaussians>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/T2FMRF_UM.xml b/vs2013mfc/config/T2FMRF_UM.xml
deleted file mode 100644
index 9a65c57ca90f63d5223752d84191c7e439ff8882..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/T2FMRF_UM.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<threshold>9.</threshold>
-<alpha>1.0000000000000000e-002</alpha>
-<km>2.</km>
-<kv>8.9999997615814209e-001</kv>
-<gaussians>3</gaussians>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/T2FMRF_UV.xml b/vs2013mfc/config/T2FMRF_UV.xml
deleted file mode 100644
index 9a65c57ca90f63d5223752d84191c7e439ff8882..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/T2FMRF_UV.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<threshold>9.</threshold>
-<alpha>1.0000000000000000e-002</alpha>
-<km>2.</km>
-<kv>8.9999997615814209e-001</kv>
-<gaussians>3</gaussians>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/VuMeter.xml b/vs2013mfc/config/VuMeter.xml
deleted file mode 100644
index d28fda7ae34e3840df1b0695eea314fd7078756b..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/VuMeter.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<enableFilter>1</enableFilter>
-<binSize>8</binSize>
-<alpha>9.9500000000000000e-001</alpha>
-<threshold>2.9999999999999999e-002</threshold>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/config/WeightedMovingMeanBGS.xml b/vs2013mfc/config/WeightedMovingMeanBGS.xml
deleted file mode 100644
index 008ad741b9f0d140beac4eea74daf2c397b70a3c..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/WeightedMovingMeanBGS.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<enableWeight>1</enableWeight>
-<enableThreshold>1</enableThreshold>
-<threshold>15</threshold>
-<showOutput>0</showOutput>
-<showBackground>0</showBackground>
-</opencv_storage>
diff --git a/vs2013mfc/config/WeightedMovingVarianceBGS.xml b/vs2013mfc/config/WeightedMovingVarianceBGS.xml
deleted file mode 100644
index d9de1d4f8cd0978018e56d86f536a85ed8e98435..0000000000000000000000000000000000000000
--- a/vs2013mfc/config/WeightedMovingVarianceBGS.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0"?>
-<opencv_storage>
-<enableWeight>1</enableWeight>
-<enableThreshold>1</enableThreshold>
-<threshold>15</threshold>
-<showOutput>0</showOutput>
-</opencv_storage>
diff --git a/vs2013mfc/dataset/video.avi b/vs2013mfc/dataset/video.avi
deleted file mode 100644
index a29f00658be7d05b10344859e6bee9a501a7a2b1..0000000000000000000000000000000000000000
Binary files a/vs2013mfc/dataset/video.avi and /dev/null differ
diff --git a/vs2013mfc/src/.gitignore b/vs2013mfc/src/.gitignore
deleted file mode 100644
index 4ad092eb1e2981311d46fee0774589cf43dcb17a..0000000000000000000000000000000000000000
--- a/vs2013mfc/src/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-Release/
-ipch/
-*.exe
-*.pdb
-*.sdf
-*.opensdf
\ No newline at end of file
diff --git a/vs2013mfc/src/App.cpp b/vs2013mfc/src/App.cpp
deleted file mode 100644
index a6f45c78da8e675b92213074239b23c9907a1738..0000000000000000000000000000000000000000
--- a/vs2013mfc/src/App.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-
-// App.cpp : Defines the class behaviors for the application.
-//
-
-#include "stdafx.h"
-#include "App.h"
-#include "Dlg.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#endif
-
-
-// CApp
-
-BEGIN_MESSAGE_MAP(CApp, CWinApp)
-	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
-END_MESSAGE_MAP()
-
-
-// CApp construction
-
-CApp::CApp()
-{
-	// support Restart Manager
-	m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
-
-	// TODO: add construction code here,
-	// Place all significant initialization in InitInstance
-}
-
-
-// The one and only CApp object
-
-CApp theApp;
-
-
-// CApp initialization
-
-BOOL CApp::InitInstance()
-{
-	// InitCommonControlsEx() is required on Windows XP if an application
-	// manifest specifies use of ComCtl32.dll version 6 or later to enable
-	// visual styles.  Otherwise, any window creation will fail.
-	INITCOMMONCONTROLSEX InitCtrls;
-	InitCtrls.dwSize = sizeof(InitCtrls);
-	// Set this to include all the common control classes you want to use
-	// in your application.
-	InitCtrls.dwICC = ICC_WIN95_CLASSES;
-	InitCommonControlsEx(&InitCtrls);
-
-	CWinApp::InitInstance();
-
-
-	AfxEnableControlContainer();
-
-	// Create the shell manager, in case the dialog contains
-	// any shell tree view or shell list view controls.
-	CShellManager *pShellManager = new CShellManager;
-
-	// Standard initialization
-	// If you are not using these features and wish to reduce the size
-	// of your final executable, you should remove from the following
-	// the specific initialization routines you do not need
-	// Change the registry key under which our settings are stored
-	// TODO: You should modify this string to be something appropriate
-	// such as the name of your company or organization
-	SetRegistryKey(_T("Local AppWizard-Generated Applications"));
-
-	CDlg dlg;
-	m_pMainWnd = &dlg;
-	INT_PTR nResponse = dlg.DoModal();
-	if (nResponse == IDOK)
-	{
-		// TODO: Place code here to handle when the dialog is
-		//  dismissed with OK
-	}
-	else if (nResponse == IDCANCEL)
-	{
-		// TODO: Place code here to handle when the dialog is
-		//  dismissed with Cancel
-	}
-
-	// Delete the shell manager created above.
-	if (pShellManager != NULL)
-	{
-		delete pShellManager;
-	}
-
-	// Since the dialog has been closed, return FALSE so that we exit the
-	//  application, rather than start the application's message pump.
-	return FALSE;
-}
-
diff --git a/vs2013mfc/src/App.h b/vs2013mfc/src/App.h
deleted file mode 100644
index 5ef9764a331791f71d688154f7af484024a9ca7f..0000000000000000000000000000000000000000
--- a/vs2013mfc/src/App.h
+++ /dev/null
@@ -1,32 +0,0 @@
-
-// App.h : main header file for the application
-//
-
-#pragma once
-
-#ifndef __AFXWIN_H__
-	#error "include 'stdafx.h' before including this file for PCH"
-#endif
-
-#include "resource.h"		// main symbols
-
-
-// CApp:
-// See App.cpp for the implementation of this class
-//
-
-class CApp : public CWinApp
-{
-public:
-	CApp();
-
-// Overrides
-public:
-	virtual BOOL InitInstance();
-
-// Implementation
-
-	DECLARE_MESSAGE_MAP()
-};
-
-extern CApp theApp;
\ No newline at end of file
diff --git a/vs2013mfc/src/Dlg.cpp b/vs2013mfc/src/Dlg.cpp
deleted file mode 100644
index f39249eb3c7c450e55cb335666b94e7f910928e2..0000000000000000000000000000000000000000
--- a/vs2013mfc/src/Dlg.cpp
+++ /dev/null
@@ -1,709 +0,0 @@
-
-// Dlg.cpp : implementation file
-//
-
-#include "stdafx.h"
-#include "App.h"
-#include "Dlg.h"
-#include "afxdialogex.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#endif
-
-
-// CAboutDlg dialog used for App About
-
-class CAboutDlg : public CDialogEx
-{
-public:
-  CAboutDlg();
-
-// Dialog Data
-  enum { IDD = IDD_ABOUTBOX };
-
-  protected:
-  virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
-
-// Implementation
-protected:
-  DECLARE_MESSAGE_MAP()
-};
-
-CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
-{
-}
-
-void CAboutDlg::DoDataExchange(CDataExchange* pDX)
-{
-  CDialogEx::DoDataExchange(pDX);
-}
-
-BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
-END_MESSAGE_MAP()
-
-
-// CDlg dialog
-
-
-
-
-CDlg::CDlg(CWnd* pParent /*=NULL*/)
-  : CDialogEx(CDlg::IDD, pParent)
-{
-  m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
-}
-
-void CDlg::DoDataExchange(CDataExchange* pDX)
-{
-  CDialogEx::DoDataExchange(pDX);
-  DDX_Control(pDX, IDC_COMBO_BGSLIST, m_bgslist);
-  DDX_Control(pDX, IDC_LOG, m_log);
-  DDX_Control(pDX, IDC_INPUT_VIDEO, m_inputVideo);
-  DDX_Control(pDX, IDC_USE_WEBCAM, m_useWebCam);
-  DDX_Control(pDX, IDC_SPIN_WEBCAM_INDEX, m_spinWebCamIndex);
-  DDX_Control(pDX, IDC_EDIT_WEBCAM_INDEX, m_webCamIndex);
-  DDX_Control(pDX, IDC_FRAME_NUMBER, m_frameNumber);
-  DDX_Control(pDX, IDC_SAVE_FRAME, m_saveFrame);
-  DDX_Control(pDX, IDC_SAVE_MASK, m_saveMask);
-  DDX_Control(pDX, IDC_SAVE_BKG, m_saveBkg);
-  DDX_Control(pDX, IDC_IMG_SEQ, m_isImgSeq);
-  DDX_Control(pDX, IDC_EDIT_START_IDX, m_startIdx);
-  DDX_Control(pDX, IDC_EDIT_STOP_IDX, m_stopIdx);
-  DDX_Control(pDX, IDC_COMBO_FILE_TYPE, m_fileTypeList);
-  DDX_Control(pDX, IDC_SPIN_START_IDX, m_spinStartIdx);
-  DDX_Control(pDX, IDC_SPIN_STOP_IDX, m_spinStopIdx);
-  DDX_Control(pDX, IDC_EDIT_DELAY, m_delay);
-  DDX_Control(pDX, IDC_EXEC_TIME, m_execTime);
-  DDX_Control(pDX, IDC_MEDIAN_FILTER, m_medianFilter);
-}
-
-BEGIN_MESSAGE_MAP(CDlg, CDialogEx)
-  ON_WM_SYSCOMMAND()
-  ON_WM_PAINT()
-  ON_WM_QUERYDRAGICON()
-  ON_BN_CLICKED(IDSTART, &CDlg::OnBnClickedStart)
-  ON_BN_CLICKED(IDSTOP, &CDlg::OnBnClickedStop)
-  ON_BN_CLICKED(IDC_USE_WEBCAM, &CDlg::OnBnClickedUseWebcam)
-  ON_BN_CLICKED(IDC_IMG_SEQ, &CDlg::OnBnClickedImgSeq)
-  ON_BN_CLICKED(IDSAVE, &CDlg::OnBnClickedSave)
-END_MESSAGE_MAP()
-
-
-// CDlg message handlers
-
-BOOL CDlg::OnInitDialog()
-{
-  CDialogEx::OnInitDialog();
-
-  // Add "About..." menu item to system menu.
-
-  // IDM_ABOUTBOX must be in the system command range.
-  ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
-  ASSERT(IDM_ABOUTBOX < 0xF000);
-
-  CMenu* pSysMenu = GetSystemMenu(FALSE);
-  if (pSysMenu != NULL)
-  {
-    BOOL bNameValid;
-    CString strAboutMenu;
-    bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
-    ASSERT(bNameValid);
-    if (!strAboutMenu.IsEmpty())
-    {
-      pSysMenu->AppendMenu(MF_SEPARATOR);
-      pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
-    }
-  }
-
-  // Set the icon for this dialog.  The framework does this automatically
-  //  when the application's main window is not a dialog
-  SetIcon(m_hIcon, TRUE);			// Set big icon
-  SetIcon(m_hIcon, FALSE);		// Set small icon
-
-  // TODO: Add extra initialization here
-  methodName = L"";
-  useWebCam = false;
-  useImgSeq = false;
-  filePath = L"";
-  bgs = NULL;
-  webCamIndex = 0;
-  m_spinWebCamIndex.SetRange(0, 9); 
-  m_spinStartIdx.SetRange(0, 999999);
-  m_spinStopIdx.SetRange(0, 999999);
-  m_frameNumber.SetWindowTextW(L"0");
-  
-  addBgsList();
-  m_fileTypeList.AddString(L"PNG");
-  m_fileTypeList.AddString(L"JPG");
-  m_fileTypeList.AddString(L"JPEG");
-  m_fileTypeList.AddString(L"JPE");
-  m_fileTypeList.AddString(L"JP2");
-  m_fileTypeList.AddString(L"BMP");
-  m_fileTypeList.AddString(L"DIB");
-  m_fileTypeList.AddString(L"PBM");
-  m_fileTypeList.AddString(L"PGM");
-  m_fileTypeList.AddString(L"PPM");
-  m_fileTypeList.AddString(L"SR");
-  m_fileTypeList.AddString(L"RAS");
-  m_fileTypeList.AddString(L"TIFF");
-  m_fileTypeList.AddString(L"TIF");
-  m_fileTypeList.SelectString(0,L"PNG");
-  m_inputVideo.SetWindowTextW(L"dataset/video.avi");
-  m_delay.SetWindowTextW(L"1");
-  m_execTime.SetWindowTextW(L"0");
-  
-  started = false;
-  if(started == false)
-  {
-    cv::namedWindow("INPUT", 1);
-    HWND hWnd = (HWND) cvGetWindowHandle("INPUT");
-    HWND hParent = ::GetParent(hWnd);
-    ::SetParent(hWnd, GetDlgItem(IDC_FRAME_INPUT)->m_hWnd);
-    ::ShowWindow(hParent, SW_HIDE);
-  }
-
-  if(started == false)
-  {
-    cv::namedWindow("MASK", 1);
-    HWND hWnd = (HWND) cvGetWindowHandle("MASK");
-    HWND hParent = ::GetParent(hWnd);
-    ::SetParent(hWnd, GetDlgItem(IDC_FRAME_MASK)->m_hWnd);
-    ::ShowWindow(hParent, SW_HIDE);
-  }
-
-  if(started == false)
-  {
-    cv::namedWindow("BKG", 1);
-    HWND hWnd = (HWND) cvGetWindowHandle("BKG");
-    HWND hParent = ::GetParent(hWnd);
-    ::SetParent(hWnd, GetDlgItem(IDC_FRAME_BKG)->m_hWnd);
-    ::ShowWindow(hParent, SW_HIDE);
-  }
-
-  return TRUE;  // return TRUE  unless you set the focus to a control
-}
-
-void CDlg::OnSysCommand(UINT nID, LPARAM lParam)
-{
-  if ((nID & 0xFFF0) == IDM_ABOUTBOX)
-  {
-    CAboutDlg dlgAbout;
-    dlgAbout.DoModal();
-  }
-  else
-  {
-    CDialogEx::OnSysCommand(nID, lParam);
-  }
-}
-
-// If you add a minimize button to your dialog, you will need the code below
-//  to draw the icon.  For MFC applications using the document/view model,
-//  this is automatically done for you by the framework.
-
-void CDlg::OnPaint()
-{
-  if (IsIconic())
-  {
-    CPaintDC dc(this); // device context for painting
-
-    SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
-
-    // Center icon in client rectangle
-    int cxIcon = GetSystemMetrics(SM_CXICON);
-    int cyIcon = GetSystemMetrics(SM_CYICON);
-    CRect rect;
-    GetClientRect(&rect);
-    int x = (rect.Width() - cxIcon + 1) / 2;
-    int y = (rect.Height() - cyIcon + 1) / 2;
-
-    // Draw the icon
-    dc.DrawIcon(x, y, m_hIcon);
-  }
-  else
-  {
-    CDialogEx::OnPaint();
-  }
-}
-
-// The system calls this function to obtain the cursor to display while the user drags
-//  the minimized window.
-HCURSOR CDlg::OnQueryDragIcon()
-{
-  return static_cast<HCURSOR>(m_hIcon);
-}
-
-void CDlg::addBgsList()
-{
-  // 37 algorithms
-  m_bgslist.AddString(L"FrameDifferenceBGS");
-  m_bgslist.AddString(L"StaticFrameDifferenceBGS");
-  m_bgslist.AddString(L"WeightedMovingMeanBGS");
-  m_bgslist.AddString(L"WeightedMovingVarianceBGS");
-  m_bgslist.AddString(L"MixtureOfGaussianV1BGS");
-  m_bgslist.AddString(L"MixtureOfGaussianV2BGS");
-  m_bgslist.AddString(L"AdaptiveBackgroundLearning");
-  m_bgslist.AddString(L"AdaptiveSelectiveBackgroundLearning");
-  m_bgslist.AddString(L"GMG");
-  m_bgslist.AddString(L"DPAdaptiveMedianBGS");
-  m_bgslist.AddString(L"DPGrimsonGMMBGS");
-  m_bgslist.AddString(L"DPZivkovicAGMMBGS");
-  m_bgslist.AddString(L"DPMeanBGS");
-  m_bgslist.AddString(L"DPWrenGABGS");
-  m_bgslist.AddString(L"DPPratiMediodBGS");
-  m_bgslist.AddString(L"DPEigenbackgroundBGS");
-  m_bgslist.AddString(L"DPTextureBGS");
-  m_bgslist.AddString(L"T2FGMM_UM");
-  m_bgslist.AddString(L"T2FGMM_UV");
-  m_bgslist.AddString(L"T2FMRF_UM");
-  m_bgslist.AddString(L"T2FMRF_UV");
-  m_bgslist.AddString(L"FuzzySugenoIntegral");
-  m_bgslist.AddString(L"FuzzyChoquetIntegral");
-  m_bgslist.AddString(L"LBSimpleGaussian");
-  m_bgslist.AddString(L"LBFuzzyGaussian");
-  m_bgslist.AddString(L"LBMixtureOfGaussians");
-  m_bgslist.AddString(L"LBAdaptiveSOM");
-  m_bgslist.AddString(L"LBFuzzyAdaptiveSOM");
-  m_bgslist.AddString(L"MultiLayerBGS");
-  //m_bgslist.AddString(L"PBAS");
-  m_bgslist.AddString(L"VuMeter");
-  m_bgslist.AddString(L"KDE");
-  m_bgslist.AddString(L"IndependentMultimodalBGS");
-  m_bgslist.AddString(L"SJN_MultiCueBGS");
-  m_bgslist.AddString(L"SigmaDeltaBGS");
-  m_bgslist.AddString(L"SuBSENSEBGS");
-  m_bgslist.AddString(L"LOBSTERBGS");
-}
-
-bool CDlg::getBgsMethodName()
-{
-  int nIndex = m_bgslist.GetCurSel();
-  if(nIndex != CB_ERR)
-  {
-    m_bgslist.GetLBText(nIndex, methodName);
-    return true;
-  }
-  else
-  {
-    AfxMessageBox(L"Please, select one background subtraction method!");
-    return false;
-  }
-}
-
-bool CDlg::getFileType()
-{
-  int nIndex = m_fileTypeList.GetCurSel();
-  if(nIndex != CB_ERR)
-  {
-    m_fileTypeList.GetLBText(nIndex, fileType);
-    return true;
-  }
-  else
-  {
-    AfxMessageBox(L"Please, select one file type or extension!");
-    return false;
-  }
-}
-
-bool CDlg::getInputVideoFilePath()
-{
-  m_inputVideo.GetWindowTextW(filePath);
-
-  if(filePath.GetLength() > 0)
-    return true;
-  else
-  {
-    AfxMessageBox(L"Please, select one video file or image sequence folder!");
-    return false;
-  }
-}
-
-void CDlg::OnBnClickedStart()
-{
-  if(started == false)
-  {
-    m_log.SetWindowTextW(L"Checking...");
-
-    if(!getBgsMethodName())
-    {
-      m_log.SetWindowTextW(L"Stopped...");
-      return;
-    }
-    
-    useWebCam = false;
-    if(m_useWebCam.GetCheck() == BST_CHECKED)
-      useWebCam = true;
-    
-    useImgSeq = false;
-    if(m_isImgSeq.GetCheck() == BST_CHECKED)
-    {
-      useImgSeq = true;
-
-      if(!getFileType())
-      {
-        m_log.SetWindowTextW(L"Stopped...");
-        return;
-      }
-    }
-
-    if(useWebCam == false)
-      if(!getInputVideoFilePath())
-      {
-        m_log.SetWindowTextW(L"Stopped...");
-        return;
-      }
-  
-    m_log.SetWindowTextW(L"Starting...");
-    thread = AfxBeginThread((AFX_THREADPROC) CDlg::Thread, (LPVOID) this);
-  }
-  else
-  {
-    AfxMessageBox(L"Thread is already initialized!");
-    return;
-  }
-}
-
-DWORD CDlg::Thread(LPVOID *lpvParam)
-{
-  CDlg *thr = (CDlg*) lpvParam;
-  thr->ThreadProcess();
-  return NULL;
-}
-
-void CDlg::ThreadProcess()
-{
-  CString csStartIdx;
-  m_startIdx.GetWindowTextW(csStartIdx);
-  startIdx = _tstoi(csStartIdx);
-
-  CString csStopIdx;
-  m_stopIdx.GetWindowTextW(csStopIdx);
-  stopIdx = _tstoi(csStopIdx);
-
-  if(useImgSeq == false)
-  {
-    if(useWebCam)
-    {
-      CString strIndex;
-      m_webCamIndex.GetWindowTextW(strIndex);
-      webCamIndex = _tstoi(strIndex);
-      capture = cvCaptureFromCAM(webCamIndex);
-    }
-    else
-    {
-      CStringA file_path_aux(filePath);
-      capture = cvCaptureFromFile((const char *) file_path_aux);
-    }
-  
-    if(!capture)
-    {
-      AfxMessageBox(L"ERROR: Cannot initialize video!");
-      m_log.SetWindowTextW(L"Stopped...");
-      return;
-    }
-  }
-  else
-  {
-    if(stopIdx == 0)
-    {
-      AfxMessageBox(L"Stop index not defined!");
-      return;
-    }
-
-    if(startIdx > stopIdx)
-    {
-      AfxMessageBox(L"Start index is higher than stop index!");
-      return;
-    }
-  }
-
-  /* Background Subtraction Methods */
-  
-  if(methodName == "FrameDifferenceBGS")
-    bgs = new FrameDifferenceBGS;
-  if(methodName == "StaticFrameDifferenceBGS")
-    bgs = new StaticFrameDifferenceBGS;
-  if(methodName == "WeightedMovingMeanBGS")
-    bgs = new WeightedMovingMeanBGS;
-  if(methodName == "WeightedMovingVarianceBGS")
-    bgs = new WeightedMovingVarianceBGS;
-  if(methodName == "MixtureOfGaussianV1BGS")
-    bgs = new MixtureOfGaussianV1BGS;
-  if(methodName == "MixtureOfGaussianV2BGS")
-    bgs = new MixtureOfGaussianV2BGS;
-  if(methodName == "AdaptiveBackgroundLearning")
-    bgs = new AdaptiveBackgroundLearning;
-  if(methodName == "AdaptiveSelectiveBackgroundLearning")
-    bgs = new AdaptiveSelectiveBackgroundLearning;
-  if(methodName == "GMG")
-    bgs = new GMG;
-  
-  if(methodName == "DPAdaptiveMedianBGS")
-    bgs = new DPAdaptiveMedianBGS;
-  if(methodName == "DPGrimsonGMMBGS")
-    bgs = new DPGrimsonGMMBGS;
-  if(methodName == "DPZivkovicAGMMBGS")
-    bgs = new DPZivkovicAGMMBGS;
-  if(methodName == "DPMeanBGS")
-    bgs = new DPMeanBGS;
-  if(methodName == "DPWrenGABGS")
-    bgs = new DPWrenGABGS;
-  if(methodName == "DPPratiMediodBGS")
-    bgs = new DPPratiMediodBGS;
-  if(methodName == "DPEigenbackgroundBGS")
-    bgs = new DPEigenbackgroundBGS;
-  if(methodName == "DPTextureBGS")
-    bgs = new DPTextureBGS;
-
-  if(methodName == "T2FGMM_UM")
-    bgs = new T2FGMM_UM;
-  if(methodName == "T2FGMM_UV")
-    bgs = new T2FGMM_UV;
-  if(methodName == "T2FMRF_UM")
-    bgs = new T2FMRF_UM;
-  if(methodName == "T2FMRF_UV")
-    bgs = new T2FMRF_UV;
-  if(methodName == "FuzzySugenoIntegral")
-    bgs = new FuzzySugenoIntegral;
-  if(methodName == "FuzzyChoquetIntegral")
-    bgs = new FuzzyChoquetIntegral;
-
-  if(methodName == "LBSimpleGaussian")
-    bgs = new LBSimpleGaussian;
-  if(methodName == "LBFuzzyGaussian")
-    bgs = new LBFuzzyGaussian;
-  if(methodName == "LBMixtureOfGaussians")
-    bgs = new LBMixtureOfGaussians;
-  if(methodName == "LBAdaptiveSOM")
-    bgs = new LBAdaptiveSOM;
-  if(methodName == "LBFuzzyAdaptiveSOM")
-    bgs = new LBFuzzyAdaptiveSOM;
-  if(methodName == "MultiLayerBGS")
-    bgs = new MultiLayerBGS;
-  //if(methodName == "PBAS")
-    //bgs = new PixelBasedAdaptiveSegmenter;
-  if(methodName == "VuMeter")
-    bgs = new VuMeter;
-  if(methodName == "KDE")
-    bgs = new KDE;
-  if(methodName == "IndependentMultimodalBGS")
-    bgs = new IndependentMultimodalBGS;
-  if(methodName == "SJN_MultiCueBGS")
-    bgs = new SJN_MultiCueBGS;
-  if (methodName == "SigmaDeltaBGS")
-    bgs = new SigmaDeltaBGS;
-  if (methodName == "SuBSENSEBGS")
-    bgs = new SuBSENSEBGS;
-  if (methodName == "LOBSTERBGS")
-    bgs = new LOBSTERBGS;
-
-  if(bgs == NULL)
-  {
-    AfxMessageBox(L"BGS object not defined!");
-    return;
-  }
-
-  started = true;
-  int i = 0;
-  if(useImgSeq == true && startIdx > 0)
-       i = startIdx - 1;
-  CString strFrameNumber;
-  CString strExecTime;
-  cv::Size default_size;
-  default_size.width = 235;
-  default_size.height = 189;
-  IplImage* frame;
-  std::string input_filename;
-  cv::Mat img_input;
-  // Convert a TCHAR string to a LPCSTR
-  CT2CA fileType2(fileType);
-  CT2CA filePath2(filePath);
-  // construct a std::string using the LPCSTR input
-  std::string str_fileType(fileType2);
-  std::string str_filePath(filePath2);
-  // delay
-  CString csDelay;
-  m_delay.GetWindowTextW(csDelay);
-  int delay = _tstoi(csDelay);
-  
-  do
-  {
-    m_log.SetWindowTextW(L"Running...");
-
-    i++;
-    //::Sleep(1);
-
-    if(useImgSeq == true && i == (stopIdx + 1))
-      break;
-
-    if(useImgSeq)
-    {
-      input_filename = str_filePath + "\\" + boost::lexical_cast<std::string>(i) + "." + str_fileType;
-      img_input = cv::imread(input_filename);
-
-      CString input_filename2(input_filename.c_str());
-      m_log.SetWindowTextW(input_filename2);
-
-      strFrameNumber.Format(L"%d",i);
-      m_frameNumber.SetWindowTextW(strFrameNumber);
-
-      if(img_input.data == NULL)
-      {
-        AfxMessageBox(L"File can not be read!");
-        break;
-      }
-    }
-    else
-    {
-      if(useWebCam == false && stopIdx >= 2 && i > stopIdx)
-        break;
-
-      frame = cvQueryFrame(capture);
-      if(!frame)
-        break;
-      
-      if(useWebCam == false && startIdx >= 2 && i < startIdx)
-        continue;
-
-      img_input = cv::Mat(frame,true);
-    }
-
-    cv::Mat img_mask;
-    cv::Mat img_bkg;
-    Clock::time_point t0 = Clock::now();
-    bgs->process(img_input, img_mask, img_bkg);
-    Clock::time_point t1 = Clock::now();
-    auto d = boost::chrono::duration_cast<milliseconds>(t1 - t0);
-    //std::cout << "\nElapsed time: " << d.count() << "ms" << std::endl;
-    
-    cv::Mat img_input_aux;
-    cv::resize(img_input, img_input_aux, default_size);
-
-    cv::Mat img_mask_aux;
-    if(img_mask.empty())
-      img_mask = cv::Mat::zeros(cv::Size(img_input.size().width, img_input.size().height), img_input.type());
-    if(m_medianFilter.GetCheck() == BST_CHECKED)
-      cv::medianBlur(img_mask, img_mask, 5);
-    cv::resize(img_mask, img_mask_aux, default_size);
-
-    cv::Mat img_bgk_aux;
-    if(img_bkg.empty())
-      img_bkg = cv::Mat::zeros(cv::Size(img_input.size().width, img_input.size().height), img_input.type());
-    cv::resize(img_bkg, img_bgk_aux, default_size);
-    
-    cv::imshow("INPUT", img_input_aux);
-    cv::imshow("MASK", img_mask_aux);
-    cv::imshow("BKG", img_bgk_aux);
-
-    extern_input_filename = "outputs/input/" + boost::lexical_cast<std::string>(i)+".png";
-    img_input.copyTo(extern_input_img);
-    if(m_saveFrame.GetCheck() == BST_CHECKED)
-      cv::imwrite(extern_input_filename, img_input);
-    
-    extern_fg_filename = "outputs/foreground/" + boost::lexical_cast<std::string>(i)+".png";
-    img_mask.copyTo(extern_fg_img);
-    if(m_saveMask.GetCheck() == BST_CHECKED)
-      cv::imwrite(extern_fg_filename, img_mask);
-    
-    extern_bg_filename = "outputs/background/" + boost::lexical_cast<std::string>(i)+".png";
-    img_bkg.copyTo(extern_bg_img);
-    if(m_saveBkg.GetCheck() == BST_CHECKED)
-      cv::imwrite(extern_bg_filename, img_bkg);
-    
-    strFrameNumber.Format(L"%d",i);
-    m_frameNumber.SetWindowTextW(strFrameNumber);
-
-    //strExecTime.Format(_T("%.2f"), d.count());
-    strExecTime.Format(_T("%d"), d.count());
-    m_execTime.SetWindowTextW(strExecTime);
-
-    ::Sleep(delay);
-
-  }while(1);
-  
-  delete bgs;
-  
-  if(!useImgSeq)
-    cvReleaseCapture(&capture);
-
-  //AfxMessageBox(L"Thread is finished!");
-  m_log.SetWindowTextW(L"Finished!");
-  started = false;
-}
-
-
-void CDlg::OnBnClickedStop()
-{
-  if(started)
-  {
-    m_log.SetWindowTextW(L"Stopping...");
-  
-    StopThread();
-
-    if(!useImgSeq)
-      if(capture)
-        cvReleaseCapture(&capture);
-
-    delete bgs;
-    bgs = NULL;
-
-    m_log.SetWindowTextW(L"Stopped!");
-    started = false;
-  }
-}
-
-void CDlg::StopThread()
-{
-  DWORD exit_code = NULL;
-
-  if(thread != NULL)
-  {
-    GetExitCodeThread(thread->m_hThread, &exit_code);
-    
-    if(exit_code == STILL_ACTIVE)
-    {
-      ::TerminateThread(thread->m_hThread, 0);
-      CloseHandle(thread->m_hThread);
-    }
-
-    thread->m_hThread = NULL;
-    thread = NULL;
-  }
-}
-
-void CDlg::OnBnClickedUseWebcam()
-{
-  if(m_useWebCam.GetCheck() == BST_CHECKED)
-    m_isImgSeq.SetCheck(BST_UNCHECKED);
-  
-  m_inputVideo.EnableFileBrowseButton();
-}
-
-void CDlg::OnBnClickedImgSeq()
-{
-  if(m_isImgSeq.GetCheck() == BST_CHECKED)
-  {
-    m_inputVideo.EnableFolderBrowseButton();
-    m_useWebCam.SetCheck(BST_UNCHECKED);
-  }
-  else
-  {
-    m_startIdx.SetWindowTextW(L"0");
-    m_stopIdx.SetWindowTextW(L"0");
-    m_inputVideo.EnableFileBrowseButton();
-  }
-}
-
-void CDlg::OnBnClickedSave()
-{
-  if(m_saveFrame.GetCheck() == BST_CHECKED)
-    cv::imwrite(extern_input_filename, extern_input_img);
-
-  if(m_saveMask.GetCheck() == BST_CHECKED)
-    cv::imwrite(extern_fg_filename, extern_fg_img);
-
-  if(m_saveBkg.GetCheck() == BST_CHECKED)
-    cv::imwrite(extern_bg_filename, extern_bg_img);
-
-  m_log.SetWindowTextW(L"OK! Saved!");
-}
diff --git a/vs2013mfc/src/Dlg.h b/vs2013mfc/src/Dlg.h
deleted file mode 100644
index 479d7271be837a490bf17915279e371f41461e85..0000000000000000000000000000000000000000
--- a/vs2013mfc/src/Dlg.h
+++ /dev/null
@@ -1,92 +0,0 @@
-
-// Dlg.h : header file
-//
-
-#pragma once
-#include "stdafx.h"
-#include "afxwin.h"
-#include "afxcmn.h"
-
-// CDlg dialog
-class CDlg : public CDialogEx
-{
-// Construction
-public:
-  CDlg(CWnd* pParent = NULL);	// standard constructor
-
-// Dialog Data
-  enum { IDD = IDD_APP };
-
-  protected:
-  virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
-
-
-// Implementation
-protected:
-  HICON m_hIcon;
-
-  // Generated message map functions
-  virtual BOOL OnInitDialog();
-  afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
-  afx_msg void OnPaint();
-  afx_msg HCURSOR OnQueryDragIcon();
-  DECLARE_MESSAGE_MAP()
-
-private:
-  bool started;
-  CWinThread* thread;
-  CvCapture* capture;
-  IBGS* bgs;
-  CString methodName;
-  CString fileType;
-  bool useWebCam;
-  bool useImgSeq;
-  int webCamIndex;
-  int startIdx;
-  int stopIdx;
-  int extern_i;
-  std::string extern_input_filename;
-  cv::Mat extern_input_img;
-  std::string extern_fg_filename;
-  cv::Mat extern_fg_img;
-  std::string extern_bg_filename;
-  cv::Mat extern_bg_img;
-
-  CString filePath;
-
-public:
-  afx_msg void ThreadProcess();
-  static DWORD Thread(LPVOID *x);
-  afx_msg void StopThread();
-  afx_msg bool ipDraw(HDC hdc, IplImage* img, int xoffset=0, int yoffset=0);
-
-public:
-  void addBgsList();
-  bool getBgsMethodName();
-  CComboBox m_bgslist;
-  afx_msg void OnBnClickedStart();
-  CStatic m_log;
-  CMFCEditBrowseCtrl m_inputVideo;
-  bool getInputVideoFilePath();
-  CButton m_useWebCam;
-  afx_msg void OnBnClickedStop();
-  CSpinButtonCtrl m_spinWebCamIndex;
-  CEdit m_webCamIndex;
-  CStatic m_frameNumber;
-  CButton m_saveFrame;
-  CButton m_saveMask;
-  CButton m_saveBkg;
-  CButton m_isImgSeq;
-  CEdit m_startIdx;
-  CEdit m_stopIdx;
-  CComboBox m_fileTypeList;
-  bool getFileType();
-  CSpinButtonCtrl m_spinStartIdx;
-  CSpinButtonCtrl m_spinStopIdx;
-  afx_msg void OnBnClickedUseWebcam();
-  afx_msg void OnBnClickedImgSeq();
-  CEdit m_delay;
-  CStatic m_execTime;
-  CButton m_medianFilter;
-  afx_msg void OnBnClickedSave();
-};
diff --git a/vs2013mfc/src/resource.h b/vs2013mfc/src/resource.h
deleted file mode 100644
index 606dd8c2eebd167158db80652c82fc50419d8ec6..0000000000000000000000000000000000000000
Binary files a/vs2013mfc/src/resource.h and /dev/null differ
diff --git a/vs2013mfc/src/stdafx.cpp b/vs2013mfc/src/stdafx.cpp
deleted file mode 100644
index 9e260e7224cab759fbfae5b285437dcdec4e40db..0000000000000000000000000000000000000000
--- a/vs2013mfc/src/stdafx.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-
-// stdafx.cpp : source file that includes just the standard includes
-// bgslibrary_vs2010_mfc.pch will be the pre-compiled header
-// stdafx.obj will contain the pre-compiled type information
-
-#include "stdafx.h"
-
-
diff --git a/vs2013mfc/src/stdafx.h b/vs2013mfc/src/stdafx.h
deleted file mode 100644
index 4d734a9e557b27d0ff404d1ae85769b66c6e890e..0000000000000000000000000000000000000000
--- a/vs2013mfc/src/stdafx.h
+++ /dev/null
@@ -1,104 +0,0 @@
-
-// stdafx.h : include file for standard system include files,
-// or project specific include files that are used frequently,
-// but are changed infrequently
-
-#pragma once
-
-#ifndef _SECURE_ATL
-#define _SECURE_ATL 1
-#endif
-
-#ifndef VC_EXTRALEAN
-#define VC_EXTRALEAN            // Exclude rarely-used stuff from Windows headers
-#endif
-
-#include "targetver.h"
-
-#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // some CString constructors will be explicit
-
-// turns off MFC's hiding of some common and often safely ignored warning messages
-#define _AFX_ALL_WARNINGS
-
-#include <afxwin.h>         // MFC core and standard components
-#include <afxext.h>         // MFC extensions
-
-
-#include <afxdisp.h>        // MFC Automation classes
-
-
-
-#ifndef _AFX_NO_OLE_SUPPORT
-#include <afxdtctl.h>           // MFC support for Internet Explorer 4 Common Controls
-#endif
-#ifndef _AFX_NO_AFXCMN_SUPPORT
-#include <afxcmn.h>             // MFC support for Windows Common Controls
-#endif // _AFX_NO_AFXCMN_SUPPORT
-
-#include <afxcontrolbars.h>     // MFC support for ribbons and control bars
-
-#ifdef _UNICODE
-#if defined _M_IX86
-#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
-#elif defined _M_X64
-#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
-#else
-#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
-#endif
-#endif
-
-#include <boost/lexical_cast.hpp>
-#include <boost/chrono.hpp>
-typedef boost::chrono::high_resolution_clock Clock;
-typedef boost::chrono::milliseconds milliseconds;
-typedef boost::chrono::microseconds microseconds;
-
-#include <iostream>
-
-#include <cv.h>
-#include <highgui.h>
-
-// BGSLibrary algorithms
-
-#include "../../package_bgs/FrameDifferenceBGS.h"
-#include "../../package_bgs/StaticFrameDifferenceBGS.h"
-#include "../../package_bgs/WeightedMovingMeanBGS.h"
-#include "../../package_bgs/WeightedMovingVarianceBGS.h"
-#include "../../package_bgs/MixtureOfGaussianV1BGS.h"
-#include "../../package_bgs/MixtureOfGaussianV2BGS.h"
-#include "../../package_bgs/AdaptiveBackgroundLearning.h"
-#include "../../package_bgs/AdaptiveSelectiveBackgroundLearning.h"
-#include "../../package_bgs/GMG.h"
-
-#include "../../package_bgs/dp/DPAdaptiveMedianBGS.h"
-#include "../../package_bgs/dp/DPGrimsonGMMBGS.h"
-#include "../../package_bgs/dp/DPZivkovicAGMMBGS.h"
-#include "../../package_bgs/dp/DPMeanBGS.h"
-#include "../../package_bgs/dp/DPWrenGABGS.h"
-#include "../../package_bgs/dp/DPPratiMediodBGS.h"
-#include "../../package_bgs/dp/DPEigenbackgroundBGS.h"
-#include "../../package_bgs/dp/DPTextureBGS.h"
-
-#include "../../package_bgs/tb/T2FGMM_UM.h"
-#include "../../package_bgs/tb/T2FGMM_UV.h"
-#include "../../package_bgs/tb/T2FMRF_UM.h"
-#include "../../package_bgs/tb/T2FMRF_UV.h"
-#include "../../package_bgs/tb/FuzzySugenoIntegral.h"
-#include "../../package_bgs/tb/FuzzyChoquetIntegral.h"
-
-#include "../../package_bgs/lb/LBSimpleGaussian.h"
-#include "../../package_bgs/lb/LBFuzzyGaussian.h"
-#include "../../package_bgs/lb/LBMixtureOfGaussians.h"
-#include "../../package_bgs/lb/LBAdaptiveSOM.h"
-#include "../../package_bgs/lb/LBFuzzyAdaptiveSOM.h"
-
-#include "../../package_bgs/jmo/MultiLayerBGS.h"
-//#include "../../package_bgs/pt/PixelBasedAdaptiveSegmenter.h"
-#include "../../package_bgs/av/VuMeter.h"
-#include "../../package_bgs/ae/KDE.h"
-#include "../../package_bgs/db/IndependentMultimodalBGS.h"
-#include "../../package_bgs/sjn/SJN_MultiCueBGS.h"
-#include "../../package_bgs/bl/SigmaDeltaBGS.h"
-
-#include "../../package_bgs/pl/SuBSENSE.h"
-#include "../../package_bgs/pl/LOBSTER.h"
diff --git a/vs2013mfc/src/targetver.h b/vs2013mfc/src/targetver.h
deleted file mode 100644
index 87c0086de751bac3d47208b77d76b82d78f26702..0000000000000000000000000000000000000000
--- a/vs2013mfc/src/targetver.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-
-// Including SDKDDKVer.h defines the highest available Windows platform.
-
-// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
-// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
-
-#include <SDKDDKVer.h>
diff --git a/wrapper_matlab/.gitignore b/wrapper_matlab/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..1c363bf8e10adc1abae7940599fcf0292c8ec151
--- /dev/null
+++ b/wrapper_matlab/.gitignore
@@ -0,0 +1 @@
+*.mex*
diff --git a/wrapper_matlab/backgroundSubtractor.m b/wrapper_matlab/backgroundSubtractor.m
new file mode 100644
index 0000000000000000000000000000000000000000..e4317664f7d8580f8ce4740dc4b6c51b8835b268
--- /dev/null
+++ b/wrapper_matlab/backgroundSubtractor.m
@@ -0,0 +1,81 @@
+%{
+/*
+ * 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/>.
+ */
+%}
+classdef backgroundSubtractor
+  %backgroundSubtractor Wrapper class for BGSLibrary
+  %   obj = backgroundSubtractor(algorithm)
+  %   creates an object with properties
+  %
+  %   Properties:
+  %   algorithm      - Algorithm name (e.g. "FrameDifference").
+  %
+  %   fgMask = getForegroundMask(obj, img) computes foreground mask on
+  %   input image, img, for the object defined by obj.
+  %
+  %   reset(obj) resets object.
+  %
+  %   release(obj) releases object memory.
+  
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  %  Properties
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  properties
+    % See the full list of available algorithms in the BGSLibrary website.
+    algorithm = 'FrameDifference';
+  end
+  
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  %  Public methods
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  methods
+    % Constructor
+    function obj = backgroundSubtractor(algorithm)
+      if(nargin > 0)
+        obj.algorithm = algorithm;
+      else
+        obj.algorithm = 'FrameDifference';
+      end
+      disp(['Selected algorithm: ' obj.algorithm]);
+      params = struct('algorithm', obj.algorithm);
+      backgroundSubtractor_wrapper('construct', params);
+    end
+    
+    % Get foreground mask and background model
+    function [fgMask, bgModel] = getForegroundMask(~, img)
+      [fgMask, bgModel] = backgroundSubtractor_wrapper('compute', img);
+    end
+    
+    % Reset object states
+    function reset(obj)
+      % Reset the background model with default parameters
+      % This is done in two steps. First free the persistent
+      % memory and then reconstruct the model with original
+      % parameters
+      backgroundSubtractor_wrapper('destroy');
+      params = struct('algorithm', obj.algorithm);
+      backgroundSubtractor_wrapper('construct', params);
+    end
+    
+    % Release object memory
+    function release(~)
+      % free persistent memory for model
+      backgroundSubtractor_wrapper('destroy');
+    end
+    
+  end
+end
\ No newline at end of file
diff --git a/wrapper_matlab/backgroundSubtractor_wrapper.cpp b/wrapper_matlab/backgroundSubtractor_wrapper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..547012070adb5a3318282452faa650bf5aa3f6a7
--- /dev/null
+++ b/wrapper_matlab/backgroundSubtractor_wrapper.cpp
@@ -0,0 +1,395 @@
+/*
+ * 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 "opencvmex.hpp"
+ // On some platforms, the following include is needed for "placement new".
+ // For more information see: http://en.wikipedia.org/wiki/Placement_syntax
+#include <memory>
+
+#include <typeinfo>
+#include "mxarray.h"
+
+#include "IBGS.h"
+#include "FrameDifference.h"
+#include "StaticFrameDifference.h"
+#include "WeightedMovingMean.h"
+#include "WeightedMovingVariance.h"
+#include "MixtureOfGaussianV1.h"
+#include "MixtureOfGaussianV2.h"
+#include "AdaptiveBackgroundLearning.h"
+#include "AdaptiveSelectiveBackgroundLearning.h"
+#include "GMG.h"
+#include "KNN.h"
+#include "DPAdaptiveMedian.h"
+#include "DPGrimsonGMM.h"
+#include "DPZivkovicAGMM.h"
+#include "DPMean.h"
+#include "DPWrenGA.h"
+#include "DPPratiMediod.h"
+#include "DPEigenbackground.h"
+#include "DPTexture.h"
+#include "T2FGMM_UM.h"
+#include "T2FGMM_UV.h"
+#include "T2FMRF_UM.h"
+#include "T2FMRF_UV.h"
+#include "FuzzySugenoIntegral.h"
+#include "FuzzyChoquetIntegral.h"
+#include "LBSimpleGaussian.h"
+#include "LBFuzzyGaussian.h"
+#include "LBMixtureOfGaussians.h"
+#include "LBAdaptiveSOM.h"
+#include "LBFuzzyAdaptiveSOM.h"
+#include "LBP_MRF.h"
+#include "MultiLayer.h"
+#include "PixelBasedAdaptiveSegmenter.h"
+#include "VuMeter.h"
+#include "KDE.h"
+#include "IndependentMultimodal.h"
+#include "MultiCue.h"
+#include "SigmaDelta.h"
+#include "SuBSENSE.h"
+#include "LOBSTER.h"
+#include "PAWCS.h"
+#include "TwoPoints.h"
+#include "ViBe.h"
+
+using namespace bgslibrary::algorithms;
+
+static IBGS *ptrBGS = NULL;
+
+namespace bgslibrary
+{
+  IBGS* init_alg(std::string alg_name)
+  {
+    if (alg_name.compare("FrameDifference") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(FrameDifference));
+    if (alg_name.compare("StaticFrameDifference") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(StaticFrameDifference));
+    if (alg_name.compare("WeightedMovingMean") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(WeightedMovingMean));
+    if (alg_name.compare("WeightedMovingVariance") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(WeightedMovingVariance));
+#if CV_MAJOR_VERSION == 2
+    if (alg_name.compare("MixtureOfGaussianV1") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(MixtureOfGaussianV1)); // only for OpenCV 2.x
+#endif
+    if (alg_name.compare("MixtureOfGaussianV2") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(MixtureOfGaussianV2));
+    if (alg_name.compare("AdaptiveBackgroundLearning") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(AdaptiveBackgroundLearning));
+    if (alg_name.compare("AdaptiveSelectiveBackgroundLearning") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(AdaptiveSelectiveBackgroundLearning));
+#if CV_MAJOR_VERSION == 2 && CV_MINOR_VERSION >= 4 && CV_SUBMINOR_VERSION >= 3
+    if (alg_name.compare("GMG") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(GMG)); // only for OpenCV >= 2.4.3
+#endif
+#if CV_MAJOR_VERSION == 3
+    if (alg_name.compare("KNN") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(KNN)); // only for OpenCV 3.x
+#endif
+    if (alg_name.compare("DPAdaptiveMedian") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(DPAdaptiveMedian));
+    if (alg_name.compare("DPGrimsonGMM") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(DPGrimsonGMM));
+    if (alg_name.compare("DPZivkovicAGMM") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(DPZivkovicAGMM));
+    if (alg_name.compare("DPMean") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(DPMean));
+    if (alg_name.compare("DPWrenGA") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(DPWrenGA));
+    if (alg_name.compare("DPPratiMediod") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(DPPratiMediod));
+    if (alg_name.compare("DPEigenbackground") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(DPEigenbackground));
+    if (alg_name.compare("DPTexture") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(DPTexture));
+    if (alg_name.compare("T2FGMM_UM") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(T2FGMM_UM));
+    if (alg_name.compare("T2FGMM_UV") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(T2FGMM_UV));
+    if (alg_name.compare("T2FMRF_UM") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(T2FMRF_UM));
+    if (alg_name.compare("T2FMRF_UV") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(T2FMRF_UV));
+    if (alg_name.compare("FuzzySugenoIntegral") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(FuzzySugenoIntegral));
+    if (alg_name.compare("FuzzyChoquetIntegral") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(FuzzyChoquetIntegral));
+    if (alg_name.compare("LBSimpleGaussian") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(LBSimpleGaussian));
+    if (alg_name.compare("LBFuzzyGaussian") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(LBFuzzyGaussian));
+    if (alg_name.compare("LBMixtureOfGaussians") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(LBMixtureOfGaussians));
+    if (alg_name.compare("LBAdaptiveSOM") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(LBAdaptiveSOM));
+    if (alg_name.compare("LBFuzzyAdaptiveSOM") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(LBFuzzyAdaptiveSOM));
+    if (alg_name.compare("LBP_MRF") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(LBP_MRF));
+    if (alg_name.compare("MultiLayer") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(MultiLayer));
+    if (alg_name.compare("PixelBasedAdaptiveSegmenter") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(PixelBasedAdaptiveSegmenter));
+    if (alg_name.compare("VuMeter") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(VuMeter));
+    if (alg_name.compare("KDE") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(KDE));
+    if (alg_name.compare("IndependentMultimodal") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(IndependentMultimodal));
+    if (alg_name.compare("MultiCue") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(MultiCue));
+    if (alg_name.compare("SigmaDelta") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(SigmaDelta));
+    if (alg_name.compare("SuBSENSE") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(SuBSENSE));
+    if (alg_name.compare("LOBSTER") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(LOBSTER));
+    if (alg_name.compare("PAWCS") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(PAWCS));
+    if (alg_name.compare("TwoPoints") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(TwoPoints));
+    if (alg_name.compare("ViBe") == 0)
+      return (IBGS *)mxCalloc(1, sizeof(ViBe));
+    return NULL;
+  }
+
+  IBGS* get_alg(std::string alg_name)
+  {
+    if (alg_name.compare("FrameDifference") == 0)
+      return new (ptrBGS) FrameDifference();
+    if (alg_name.compare("StaticFrameDifference") == 0)
+      return new (ptrBGS) StaticFrameDifference();
+    if (alg_name.compare("WeightedMovingMean") == 0)
+      return new (ptrBGS) WeightedMovingMean();
+    if (alg_name.compare("WeightedMovingVariance") == 0)
+      return new (ptrBGS) WeightedMovingVariance();
+#if CV_MAJOR_VERSION == 2
+    if (alg_name.compare("MixtureOfGaussianV1") == 0)
+      return new (ptrBGS) MixtureOfGaussianV1(); // only for OpenCV 2.x
+#endif
+    if (alg_name.compare("MixtureOfGaussianV2") == 0)
+      return new (ptrBGS) MixtureOfGaussianV2();
+    if (alg_name.compare("AdaptiveBackgroundLearning") == 0)
+      return new (ptrBGS) AdaptiveBackgroundLearning();
+    if (alg_name.compare("AdaptiveSelectiveBackgroundLearning") == 0)
+      return new (ptrBGS) AdaptiveSelectiveBackgroundLearning();
+#if CV_MAJOR_VERSION == 2 && CV_MINOR_VERSION >= 4 && CV_SUBMINOR_VERSION >= 3
+    if (alg_name.compare("GMG") == 0)
+      return new (ptrBGS) GMG(); // only for OpenCV >= 2.4.3
+#endif
+#if CV_MAJOR_VERSION == 3
+    if (alg_name.compare("KNN") == 0)
+      return new (ptrBGS) KNN(); // only on OpenCV 3.x
+#endif
+    if (alg_name.compare("DPAdaptiveMedian") == 0)
+      return new (ptrBGS) DPAdaptiveMedian();
+    if (alg_name.compare("DPGrimsonGMM") == 0)
+      return new (ptrBGS) DPGrimsonGMM();
+    if (alg_name.compare("DPZivkovicAGMM") == 0)
+      return new (ptrBGS) DPZivkovicAGMM();
+    if (alg_name.compare("DPMean") == 0)
+      return new (ptrBGS) DPMean();
+    if (alg_name.compare("DPWrenGA") == 0)
+      return new (ptrBGS) DPWrenGA();
+    if (alg_name.compare("DPPratiMediod") == 0)
+      return new (ptrBGS) DPPratiMediod();
+    if (alg_name.compare("DPEigenbackground") == 0)
+      return new (ptrBGS) DPEigenbackground();
+    if (alg_name.compare("DPTexture") == 0)
+      return new (ptrBGS) DPTexture();
+    if (alg_name.compare("T2FGMM_UM") == 0)
+      return new (ptrBGS) T2FGMM_UM();
+    if (alg_name.compare("T2FGMM_UV") == 0)
+      return new (ptrBGS) T2FGMM_UV();
+    if (alg_name.compare("T2FMRF_UM") == 0)
+      return new (ptrBGS) T2FMRF_UM();
+    if (alg_name.compare("T2FMRF_UV") == 0)
+      return new (ptrBGS) T2FMRF_UV();
+    if (alg_name.compare("FuzzySugenoIntegral") == 0)
+      return new (ptrBGS) FuzzySugenoIntegral();
+    if (alg_name.compare("FuzzyChoquetIntegral") == 0)
+      return new (ptrBGS) FuzzyChoquetIntegral();
+    if (alg_name.compare("LBSimpleGaussian") == 0)
+      return new (ptrBGS) LBSimpleGaussian();
+    if (alg_name.compare("LBFuzzyGaussian") == 0)
+      return new (ptrBGS) LBFuzzyGaussian();
+    if (alg_name.compare("LBMixtureOfGaussians") == 0)
+      return new (ptrBGS) LBMixtureOfGaussians();
+    if (alg_name.compare("LBAdaptiveSOM") == 0)
+      return new (ptrBGS) LBAdaptiveSOM();
+    if (alg_name.compare("LBFuzzyAdaptiveSOM") == 0)
+      return new (ptrBGS) LBFuzzyAdaptiveSOM();
+    if (alg_name.compare("LBP_MRF") == 0)
+      return new (ptrBGS) LBP_MRF();
+    if (alg_name.compare("MultiLayer") == 0)
+      return new (ptrBGS) MultiLayer();
+    if (alg_name.compare("PixelBasedAdaptiveSegmenter") == 0)
+      return new (ptrBGS) PixelBasedAdaptiveSegmenter();
+    if (alg_name.compare("VuMeter") == 0)
+      return new (ptrBGS) VuMeter();
+    if (alg_name.compare("KDE") == 0)
+      return new (ptrBGS) KDE();
+    if (alg_name.compare("IndependentMultimodal") == 0)
+      return new (ptrBGS) IndependentMultimodal();
+    if (alg_name.compare("MultiCue") == 0)
+      return new (ptrBGS) MultiCue();
+    if (alg_name.compare("SigmaDelta") == 0)
+      return new (ptrBGS) SigmaDelta();
+    if (alg_name.compare("SuBSENSE") == 0)
+      return new (ptrBGS) SuBSENSE();
+    if (alg_name.compare("LOBSTER") == 0)
+      return new (ptrBGS) LOBSTER();
+    if (alg_name.compare("PAWCS") == 0)
+      return new (ptrBGS) PAWCS();
+    if (alg_name.compare("TwoPoints") == 0)
+      return new (ptrBGS) TwoPoints();
+    if (alg_name.compare("ViBe") == 0)
+      return new (ptrBGS) ViBe();
+    return NULL;
+  }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Check inputs
+//////////////////////////////////////////////////////////////////////////////
+void checkInputs(int nrhs, const mxArray *prhs[])
+{
+  //mexPrintf("checkInputs()\n");
+  if ((nrhs < 1) || (nrhs > 2))
+    mexErrMsgTxt("Incorrect number of inputs. Function expects 1 or 2 inputs.");
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Get MEX function inputs
+//////////////////////////////////////////////////////////////////////////////
+void getParams(std::string &algorithm, const mxArray* mxParams)
+{
+  //mexPrintf("getParams()\n");
+  const mxArray* mxfield;
+  mxfield = mxGetField(mxParams, 0, "algorithm");
+  algorithm = mexplus::MxArray::to<std::string>(mxfield);
+  //mexPrintf(algorithm.c_str());
+  //mexPrintf("\n");
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Exit function for freeing persistent memory
+//////////////////////////////////////////////////////////////////////////////
+void exitFcn()
+{
+  //mexPrintf("exitFcn()\n");
+  if (ptrBGS != NULL)
+  {
+    // explicitly call destructor for "placement new"
+    ptrBGS->~IBGS();
+    mxFree(ptrBGS);
+    ptrBGS = NULL;
+  }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Construct object
+//////////////////////////////////////////////////////////////////////////////
+void constructObject(const mxArray *prhs[])
+{
+  //mexPrintf("constructObject()\n");
+  std::string algorithm;
+
+  // second input must be struct
+  if (mxIsStruct(prhs[1]))
+    getParams(algorithm, prhs[1]);
+
+  if (ptrBGS != NULL) exitFcn();
+
+  // Allocate memory for background subtractor model
+  //ptrBGS = (IBGS *)mxCalloc(1, sizeof(IBGS));
+  ptrBGS = bgslibrary::init_alg(algorithm);
+  if (ptrBGS != NULL)
+  {
+    // Make memory allocated by MATLAB software persist after MEX-function completes.
+    // This lets us use the updated background subtractor model for the next frame.
+    mexMakeMemoryPersistent(ptrBGS);
+
+    // Use "placement new" to construct an object on memory that was
+    // already allocated using mxCalloc
+    ptrBGS = bgslibrary::get_alg(algorithm);
+    if (ptrBGS == NULL)
+      mexErrMsgTxt("Failed to construct an object on memory. Algorithm not initialized.");
+  }
+  else
+    mexErrMsgTxt("Failed to allocate memory. Algorithm not found?");
+
+  // Register a function that gets called when the MEX-function is cleared.
+  // This function is responsible for freeing persistent memory
+  mexAtExit(exitFcn);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Compute foreground mask
+//////////////////////////////////////////////////////////////////////////////
+void computeForegroundMask(mxArray *plhs[], const mxArray *prhs[])
+{
+  //mexPrintf("computeForegroundMask()\n");
+  if (ptrBGS != NULL)
+  {
+    cv::Ptr<cv::Mat> img = ocvMxArrayToImage_uint8(prhs[1], true);
+    cv::Mat fgmask, bgmodel;
+
+    ptrBGS->process(*img, fgmask, bgmodel);
+
+    if (fgmask.empty())
+      fgmask = cv::Mat::zeros((*img).size(), CV_8UC1);
+    if (bgmodel.empty())
+      bgmodel = cv::Mat::zeros((*img).size(), CV_8UC3); // (*img).type()
+
+    // https://fr.mathworks.com/help/vision/ref/ocvmxarrayfromimage_datatype.html
+    plhs[0] = ocvMxArrayFromImage_uint8(fgmask);
+    plhs[1] = ocvMxArrayFromImage_uint8(bgmodel);
+
+    //if(!fgmask.empty())
+    fgmask.release();
+    //if(!bgmodel.empty())
+    bgmodel.release();
+  }
+  else
+    mexErrMsgTxt("Algorithm not initialized.");
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// The main MEX function entry point
+//////////////////////////////////////////////////////////////////////////////
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
+{
+  //mexPrintf("mexFunction()\n");
+  checkInputs(nrhs, prhs);
+  const char *str = mxIsChar(prhs[0]) ? mxArrayToString(prhs[0]) : NULL;
+
+  if (str != NULL)
+  {
+    //mexPrintf("%s\n",str);
+    if (strcmp(str, "construct") == 0)
+      constructObject(prhs);
+    else if (strcmp(str, "compute") == 0)
+      computeForegroundMask(plhs, prhs);
+    else if (strcmp(str, "destroy") == 0)
+      exitFcn();
+
+    // Free memory allocated by mxArrayToString
+    mxFree((void *)str);
+  }
+}
diff --git a/wrapper_matlab/compile.m b/wrapper_matlab/compile.m
new file mode 100644
index 0000000000000000000000000000000000000000..314ada17de002e4a63f565b4178cc886a1c2f406
--- /dev/null
+++ b/wrapper_matlab/compile.m
@@ -0,0 +1,94 @@
+%% Compile
+clc;
+mexOpenCV -v -DMEX_COMPILE_FLAG -I"..\package_bgs" backgroundSubtractor_wrapper.cpp ...
+  "..\package_bgs\FrameDifference.cpp" ...
+  "..\package_bgs\StaticFrameDifference.cpp" ...
+  "..\package_bgs\WeightedMovingMean.cpp" ...
+  "..\package_bgs\WeightedMovingVariance.cpp" ...
+  "..\package_bgs\MixtureOfGaussianV1.cpp" ...
+  "..\package_bgs\MixtureOfGaussianV2.cpp" ...
+  "..\package_bgs\AdaptiveBackgroundLearning.cpp" ...
+  "..\package_bgs\AdaptiveSelectiveBackgroundLearning.cpp" ...
+  "..\package_bgs\GMG.cpp" ...
+  "..\package_bgs\KNN.cpp" ...
+  "..\package_bgs\DPAdaptiveMedian.cpp" ...
+  "..\package_bgs\DPGrimsonGMM.cpp" ...
+  "..\package_bgs\DPZivkovicAGMM.cpp" ...
+  "..\package_bgs\DPMean.cpp" ...
+  "..\package_bgs\DPWrenGA.cpp" ...
+  "..\package_bgs\DPPratiMediod.cpp" ...
+  "..\package_bgs\DPEigenbackground.cpp" ...
+  "..\package_bgs\DPTexture.cpp" ...
+  "..\package_bgs\dp\AdaptiveMedianBGS.cpp" ...
+  "..\package_bgs\dp\Image.cpp" ...
+  "..\package_bgs\dp\Error.cpp" ...
+  "..\package_bgs\dp\GrimsonGMM.cpp" ...
+  "..\package_bgs\dp\ZivkovicAGMM.cpp" ...
+  "..\package_bgs\dp\MeanBGS.cpp" ...
+  "..\package_bgs\dp\WrenGA.cpp"  ...
+  "..\package_bgs\dp\PratiMediodBGS.cpp" ...
+  "..\package_bgs\dp\Eigenbackground.cpp" ...
+  "..\package_bgs\dp\TextureBGS.cpp" ...
+  "..\package_bgs\T2FGMM_UM.cpp" ...
+  "..\package_bgs\T2FGMM_UV.cpp" ...
+  "..\package_bgs\T2FMRF_UM.cpp" ...
+  "..\package_bgs\T2FMRF_UV.cpp" ...
+  "..\package_bgs\FuzzyChoquetIntegral.cpp" ...
+  "..\package_bgs\FuzzySugenoIntegral.cpp" ...
+  "..\package_bgs\T2F\T2FGMM.cpp" ...
+  "..\package_bgs\T2F\T2FMRF.cpp" ...
+  "..\package_bgs\T2F\MRF.cpp" ...
+  "..\package_bgs\T2F\FuzzyUtils.cpp" ...
+  "..\package_analysis\PixelUtils.cpp" ...
+  "..\package_bgs\MultiLayer.cpp" ...
+  "..\package_bgs\MultiLayer\CMultiLayerBGS.cpp" ...
+  "..\package_bgs\MultiLayer\LocalBinaryPattern.cpp" ...
+  "..\package_bgs\MultiLayer\BlobResult.cpp" ...
+  "..\package_bgs\MultiLayer\BlobExtraction.cpp" ...
+  "..\package_bgs\MultiLayer\blob.cpp" ...
+  "..\package_bgs\LBSimpleGaussian.cpp" ...
+  "..\package_bgs\LBFuzzyGaussian.cpp" ...
+  "..\package_bgs\LBMixtureOfGaussians.cpp" ...
+  "..\package_bgs\LBAdaptiveSOM.cpp" ...
+  "..\package_bgs\LBFuzzyAdaptiveSOM.cpp" ...
+  "..\package_bgs\lb\BGModel.cpp" ...
+  "..\package_bgs\lb\BGModelFuzzyGauss.cpp" ...
+  "..\package_bgs\lb\BGModelFuzzySom.cpp" ...
+  "..\package_bgs\lb\BGModelGauss.cpp" ...
+  "..\package_bgs\lb\BGModelMog.cpp" ...
+  "..\package_bgs\lb\BGModelSom.cpp" ...
+  "..\package_bgs\LBP_MRF.cpp" ...
+  "..\package_bgs\LBP_MRF\MotionDetection.cpp" ...
+  "..\package_bgs\LBP_MRF\MEImage.cpp" ...
+  "..\package_bgs\LBP_MRF\MEHistogram.cpp" ...
+  "..\package_bgs\LBP_MRF\MEDefs.cpp" ...
+  "..\package_bgs\LBP_MRF\maxflow.cpp" ...
+  "..\package_bgs\LBP_MRF\graph.cpp" ...
+  "..\package_bgs\PixelBasedAdaptiveSegmenter.cpp" ...
+  "..\package_bgs\PBAS\PBAS.cpp" ...
+  "..\package_bgs\VuMeter.cpp" ...
+  "..\package_bgs\VuMeter\TBackgroundVuMeter.cpp" ...
+  "..\package_bgs\VuMeter\TBackground.cpp" ...
+  "..\package_bgs\KDE.cpp" ...
+  "..\package_bgs\KDE\NPBGSubtractor.cpp" ...
+  "..\package_bgs\KDE\NPBGmodel.cpp" ...
+  "..\package_bgs\KDE\KernelTable.cpp" ...
+  "..\package_bgs\IndependentMultimodal.cpp" ...
+  "..\package_bgs\IMBS\IMBS.cpp" ...
+  "..\package_bgs\MultiCue.cpp" ...
+  "..\package_bgs\SigmaDelta.cpp" ...
+  "..\package_bgs\SigmaDelta\sdLaMa091.cpp" ...
+  "..\package_bgs\SuBSENSE.cpp" ...
+  "..\package_bgs\LOBSTER.cpp" ...
+  "..\package_bgs\PAWCS.cpp" ...
+  "..\package_bgs\LBSP\LBSP.cpp" ...
+  "..\package_bgs\LBSP\LBSP_.cpp" ...
+  "..\package_bgs\LBSP\BackgroundSubtractorLBSP.cpp" ...
+  "..\package_bgs\LBSP\BackgroundSubtractorLBSP_.cpp" ...
+  "..\package_bgs\LBSP\BackgroundSubtractorLOBSTER.cpp" ...
+  "..\package_bgs\LBSP\BackgroundSubtractorPAWCS.cpp" ...
+  "..\package_bgs\LBSP\BackgroundSubtractorSuBSENSE.cpp" ...
+  "..\package_bgs\ViBe.cpp" ...
+  "..\package_bgs\ViBe\vibe-background-sequential.cpp" ...
+  "..\package_bgs\TwoPoints.cpp" ...
+  "..\package_bgs\TwoPoints\two_points.cpp"
diff --git a/wrapper_matlab/config/.gitignore b/wrapper_matlab/config/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4e2a98bb114355ae964e78a929c12d44f75815de
--- /dev/null
+++ b/wrapper_matlab/config/.gitignore
@@ -0,0 +1,4 @@
+# Ignore everything in this directory
+*
+# Except these files
+!.gitignore
diff --git a/wrapper_matlab/demo.m b/wrapper_matlab/demo.m
new file mode 100644
index 0000000000000000000000000000000000000000..942e457fb227cc4f11104f276f0a498d40eb0181
--- /dev/null
+++ b/wrapper_matlab/demo.m
@@ -0,0 +1,65 @@
+%{
+/*
+ * 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/>.
+ */
+%}
+% Example:
+% demo('FrameDifference')
+% demo('StaticFrameDifference')
+% See the full list of available algorithms in the BGSLibrary website.
+function demo(algorithm)
+if(nargin < 1)
+  algorithm = 'FrameDifference';
+end
+
+% Create video reader object
+%filename = 'visiontraffic.avi';
+filename = '../dataset/demo.avi';
+hsrc = vision.VideoFileReader(filename, ...
+                              'ImageColorSpace', 'RGB', ...
+                              'VideoOutputDataType', 'uint8');
+
+% Create background/foreground segmentation object
+hfg = backgroundSubtractor(algorithm);
+
+disp('Starting...');
+frameCnt = 1;
+while ~isDone(hsrc), %disp(frameCnt)
+  % Read frame
+  frame = step(hsrc);
+  
+  % Compute foreground mask and background model
+  [fgMask, bgModel] = getForegroundMask(hfg, frame);
+  
+  % View results
+  subplot(1,3,1), imshow(frame,'InitialMagnification','fit');
+  subplot(1,3,2), imshow(fgMask,'InitialMagnification','fit');
+  subplot(1,3,3), imshow(bgModel,'InitialMagnification','fit');
+  pause(0.01);
+  
+  % Reset background model
+  % This step just demonstrates how to use reset method
+  if (frameCnt==15)
+    %reset(hfg);
+    %break;
+  end
+  
+  frameCnt = frameCnt + 1;
+end
+disp('Finished!');
+
+release(hfg);
+release(hsrc);
diff --git a/wrapper_matlab/mxarray.h b/wrapper_matlab/mxarray.h
new file mode 100644
index 0000000000000000000000000000000000000000..6a9afe96bba0bb96065c75f48e1077e08673a05a
--- /dev/null
+++ b/wrapper_matlab/mxarray.h
@@ -0,0 +1,1555 @@
+/** MxArray data conversion library.
+ *
+ * Copyright 2014 Kota Yamaguchi.
+ *
+ * The library provides mexplus::MxArray class for data conversion between
+ * mxArray* and C++ types. The static API's are the core of the high-level
+ * conversions.
+ *
+ *    int value = MxArray::to<int>(prhs[0]);
+ *    string value = MxArray::to<string>(prhs[0]);
+ *    vector<double> value = MxArray::to<vector<double> >(prhs[0]);
+ *
+ *    plhs[0] = MxArray::from(20);
+ *    plhs[0] = MxArray::from("text value.");
+ *    plhs[0] = MxArray::from(vector<double>(20, 0));
+ *
+ * Additionally, object API's are there to wrap around a complicated data
+ * access.
+ *
+ * ### Read access
+ *
+ *    MxArray cell(prhs[0]);   // Assumes cell array in prhs[0].
+ *    int x = cell.at<int>(0);
+ *    vector<double> y = cell.at<vector<double> >(1);
+ *
+ *    MxArray numeric(prhs[0]);   // Assumes numeric array in prhs[0].
+ *    double x = numeric.at<double>(0);
+ *    int y = numeric.at<int>(1);
+ *
+ * ### Write access
+ *
+ *    MxArray cell(MxArray::Cell(1, 3));
+ *    cell.set(0, 12);
+ *    cell.set(1, "text value.");
+ *    cell.set(2, vector<double>(4, 0));
+ *    plhs[0] = cell.release();
+ *
+ *    MxArray numeric(MxArray::Numeric<double>(2, 2));
+ *    numeric.set(0, 0, 1);
+ *    numeric.set(0, 1, 2);
+ *    numeric.set(1, 0, 3);
+ *    numeric.set(1, 1, 4);
+ *    plhs[0] = numeric.release();
+ *
+ * To add your own data conversion, define in namespace mexplus a template
+ * specialization of MxArray::from() and MxArray::to().
+ *
+ */
+
+#ifndef INCLUDE_MEXPLUS_MXARRAY_H_
+#define INCLUDE_MEXPLUS_MXARRAY_H_
+
+#include <mex.h>
+#include <algorithm>
+#include <cstdint>
+#include <set>
+#include <string>
+#include <typeinfo>
+#include <vector>
+#include "mxtypes.h"
+
+#pragma warning(once : 4244)
+
+/** Macro definitions.
+ */
+#define MEXPLUS_CHECK_NOTNULL(pointer) \
+    if (!(pointer)) \
+      mexErrMsgIdAndTxt("mexplus:error", \
+                        "Null pointer exception: %s:%d:%s `" #pointer "`.", \
+                        __FILE__, \
+                        __LINE__, \
+                        __FUNCTION__)
+
+#define MEXPLUS_ERROR(...) mexErrMsgIdAndTxt("mexplus:error", __VA_ARGS__)
+#define MEXPLUS_WARNING(...) mexWarnMsgIdAndTxt("mexplus:warning", __VA_ARGS__)
+#define MEXPLUS_ASSERT(condition, ...) \
+    if (!(condition)) mexErrMsgIdAndTxt("mexplus:error", __VA_ARGS__)
+
+namespace mexplus {
+
+/** mxArray object wrapper for data conversion and manipulation.
+ *
+ * The class is similar to a combination of unique_ptr and wrapper around
+ * Matlab's matrix API. An MxArray object created from a mutable mxArray*
+ * pointer automatically frees its internal memory unless explicitly
+ * released. When MxArray is created from a const mxArray*, the object does not
+ * manage memory but still provides the same matrix API.
+ */
+class MxArray {
+ public:
+  /** Empty MxArray constructor. Use reset() to set a pointer.
+   */
+  MxArray() : array_(NULL), owner_(false) {}
+  /** NULL assignment.
+   */
+  MxArray& operator= (std::nullptr_t) {
+    reset();
+    return *this;
+  }
+  /** Move constructor.
+   */
+  MxArray(MxArray&& array) : array_(NULL), owner_(false) {
+    *this = std::move(array);
+  }
+  /** Move assignment.
+   */
+  MxArray& operator= (MxArray&& rhs) {
+    if (this != &rhs) {
+      array_ = rhs.array_;
+      owner_ = rhs.owner_;
+      rhs.array_ = NULL;
+      rhs.owner_ = false;
+    }
+    return *this;
+  }
+  /** MxArray constructor from const mxArray*. MxArray will not manage memory.
+   * @param array mxArray pointer given by mexFunction.
+   */
+  explicit MxArray(const mxArray* array) :
+      array_(const_cast<mxArray*>(array)),
+      owner_(false) {}
+  /** MxArray constructor from mutable mxArray*. MxArray will manage memory.
+   * @param array mxArray pointer.
+   */
+  explicit MxArray(mxArray* array) : array_(array), owner_(array != NULL) {}
+  /** Assignment from const mxArray*. MxArray will not manage memory.
+   */
+  MxArray& operator= (const mxArray* rhs) {
+    reset(rhs);
+    return *this;
+  }
+  /** Assignment from mutable mxArray*. MxArray will manage memory.
+   */
+  MxArray& operator= (mxArray* rhs) {
+    reset(rhs);
+    return *this;
+  }
+  /** MxArray constructor from scalar.
+   */
+  template <typename T>
+  explicit MxArray(const T& value) : array_(from(value)), owner_(true) {}
+  /** Destructor. Unreleased pointers will be destroyed.
+   */
+  virtual ~MxArray() {
+    if (array_ && owner_)
+      mxDestroyArray(array_);
+  }
+  /** Swap operation.
+   */
+  void swap(MxArray& rhs) {
+    if (this != &rhs) {
+      mxArray* array = rhs.array_;
+      bool owner = rhs.owner_;
+      rhs.array_ = array_;
+      rhs.owner_ = owner_;
+      array_ = array;
+      owner_ = owner;
+    }
+  }
+  /** Reset an mxArray to a const mxArray*.
+   *
+   * Caller must be VERY careful with this, as the behavior is undefined when
+   * the original mxArray* is destroyed. For example, the following will crash.
+   * @code
+   *     MxArray foo;
+   *     {
+   *       MxArray bar(1);
+   *       foo.reset(bar.get());
+   *     }
+   *     foo.toInt(); // Error!
+   * @endcode
+   */
+  void reset(const mxArray* array = NULL) {
+    if (array_ && owner_)
+      mxDestroyArray(array_);
+    array_ = const_cast<mxArray*>(array);
+    owner_ = false;
+  }
+  /** Reset an mxArray.
+   */
+  void reset(mxArray* array) {
+    if (array_ && owner_)
+      mxDestroyArray(array_);
+    array_ = array;
+    owner_ = (array != NULL);
+  }
+  /** Release managed mxArray* pointer, or clone if not owner.
+   * @return Unmanaged mxArray*. Always caller must destroy.
+   */
+  mxArray* release()  {
+    MEXPLUS_CHECK_NOTNULL(array_);
+    mxArray* array = (owner_) ? array_ : clone();
+    array_ = NULL;
+    owner_ = false;
+    return array;
+  }
+  /** Clone mxArray. This always allocates new mxArray*.
+   * @return Unmanaged mxArray*. Always caller must destroy.
+   */
+  mxArray* clone() const {
+    MEXPLUS_CHECK_NOTNULL(array_);
+    mxArray* array = mxDuplicateArray(array_);
+    MEXPLUS_CHECK_NOTNULL(array);
+    return array;
+  }
+  /** Conversion to const mxArray*.
+   * @return const mxArray* pointer.
+   */
+  inline const mxArray* get() const { return array_; }
+  /** Get raw mxArray*.
+   * @return mxArray* pointer.
+   */
+  inline mxArray* getMutable() { return array_; }
+  /** Return true if the array is not NULL.
+   */
+  operator bool() const { return array_ != NULL; }
+  /** Return true if owner.
+   */
+  inline bool isOwner() const { return owner_; }
+  /** Create a new numeric (real or complex) matrix.
+   * @param rows Number of rows.
+   * @param columns Number of cols.
+   */
+  template <typename T>
+  static mxArray* Numeric(int rows = 1, int columns = 1);
+  /** Create a new numeric (real or complex) matrix.
+   * @param ndim Number of dimensions.
+   * @param dims Dimensions array. Each element in the dimensions array
+   *             contains the size of the array in that dimension.
+   */
+  template <typename T>
+  static mxArray* Numeric(std::vector<std::size_t> dims);
+  /** Create a new logical matrix.
+   * @param rows Number of rows.
+   * @param columns Number of cols.
+   */
+  static mxArray* Logical(int rows = 1, int columns = 1) {
+    mxArray* logical_array = mxCreateLogicalMatrix(rows, columns);
+    MEXPLUS_CHECK_NOTNULL(logical_array);
+    return logical_array;
+  }
+  /** Create a new cell matrix.
+   * @param rows Number of rows.
+   * @param columns Number of cols.
+   *
+   * Example:
+   * @code
+   *     MxArray cell_array = MxArray::Cell(1, 2);
+   *     cell_array.set(0, 1);
+   *     cell_array.set(1, "another value");
+   *     plhs[0] = cell_array.release();
+   * @endcode
+   */
+  static mxArray* Cell(int rows = 1, int columns = 1) {
+    mxArray* cell_array = mxCreateCellMatrix(rows, columns);
+    MEXPLUS_CHECK_NOTNULL(cell_array);
+    return cell_array;
+  }
+  /** Generic constructor for a struct matrix.
+   * @param fields field names.
+   * @param nfields number of field names.
+   * @param rows size of the first dimension.
+   * @param columns size of the second dimension.
+   *
+   * Example:
+   * @code
+   *     const char* fields[] = {"field1", "field2"};
+   *     MxArray struct_array(MxArray::Struct(2, fields));
+   *     struct_array.set("field1", 1);
+   *     struct_array.set("field2", "field2 value");
+   *     plhs[0] = struct_array.release();
+   * @endcode
+   */
+  static mxArray* Struct(int nfields = 0,
+                         const char** fields = NULL,
+                         int rows = 1,
+                         int columns = 1) {
+    mxArray* struct_array = mxCreateStructMatrix(rows,
+                                                 columns,
+                                                 nfields,
+                                                 fields);
+    MEXPLUS_CHECK_NOTNULL(struct_array);
+    return struct_array;
+  }
+  /** mxArray* importer methods.
+   */
+  template <typename T>
+  static mxArray* from(const T& value) { return fromInternal<T>(value); }
+  static mxArray* from(const char* value) {
+    mxArray* array = mxCreateString(value);
+    MEXPLUS_CHECK_NOTNULL(array);
+    return array;
+  }
+  static mxArray* from(int32_t value) {
+    mxArray* array = mxCreateNumericMatrix(1, 1, mxINT32_CLASS, mxREAL);
+    MEXPLUS_CHECK_NOTNULL(array);
+    *reinterpret_cast<int32_t*>(mxGetData(array)) = value;
+    return array;
+  }
+  /** mxArray* exporter methods.
+   */
+  template <typename T>
+  static void to(const mxArray* array, T* value) {
+    toInternal<T>(array, value);
+  }
+  template <typename T>
+  static T to(const mxArray* array) {
+    T value;
+    toInternal<T>(array, &value);
+    return value;
+  }
+  /** mxArray* element reader methods.
+   */
+  template <typename T>
+  static T at(const mxArray* array, mwIndex index) {
+    T value;
+    atInternal<T>(array, index, &value);
+    return value;
+  }
+  template <typename T>
+  static void at(const mxArray* array, mwIndex index, T* value) {
+    atInternal<T>(array, index, value);
+  }
+  static const mxArray* at(const mxArray* array, mwIndex index) {
+    MEXPLUS_CHECK_NOTNULL(array);
+    MEXPLUS_ASSERT(mxIsCell(array), "Expected a cell array.");
+    return mxGetCell(array, index);
+  }
+  template <typename T>
+  static void at(const mxArray* array,
+                 const std::string& field,
+                 T* value,
+                 mwIndex index = 0) {
+    atInternal<T>(array, field, index, value);
+  }
+  static const mxArray* at(const mxArray* array,
+                           const std::string& field,
+                           mwIndex index = 0)  {
+    MEXPLUS_CHECK_NOTNULL(array);
+    MEXPLUS_ASSERT(mxIsStruct(array), "Expected a struct array.");
+    return mxGetField(array, index, field.c_str());
+  }
+  /** mxArray* element writer methods.
+   */
+  template <typename T>
+  static void set(mxArray* array, mwIndex index, const T& value) {
+    setInternal<T>(array, index, value);
+  }
+  static void set(mxArray* array, mwIndex index, mxArray* value) {
+    MEXPLUS_CHECK_NOTNULL(array);
+    MEXPLUS_CHECK_NOTNULL(value);
+    MEXPLUS_ASSERT(mxIsCell(array), "Expected a cell array.");
+    MEXPLUS_ASSERT(static_cast<size_t>(index) < mxGetNumberOfElements(array),
+                   "Index out of range: %u.",
+                   index);
+    mxDestroyArray(mxGetCell(array, index));
+    mxSetCell(array, index, value);
+  }
+  template <typename T>
+  static void set(mxArray* array,
+                  const std::string& field,
+                  const T& value,
+                  mwIndex index = 0) {
+    setInternal<T>(array, field, index, value);
+  }
+  static void set(mxArray* array,
+                  const std::string& field,
+                  mxArray* value,
+                  mwIndex index = 0) {
+    MEXPLUS_CHECK_NOTNULL(array);
+    MEXPLUS_CHECK_NOTNULL(value);
+    MEXPLUS_ASSERT(mxIsStruct(array), "Expected a struct array.");
+    MEXPLUS_ASSERT(static_cast<size_t>(index) < mxGetNumberOfElements(array),
+                   "Index out of range: %u.",
+                   index);
+    int field_number = mxGetFieldNumber(array, field.c_str());
+    if (field_number < 0) {
+      field_number = mxAddField(array, field.c_str());
+      MEXPLUS_ASSERT(field_number >= 0,
+                     "Failed to create a field '%s'",
+                     field.c_str());
+    }
+    mxDestroyArray(mxGetFieldByNumber(array, index, field_number));
+    mxSetFieldByNumber(array, index, field_number, value);
+  }
+
+  /** Convert MxArray to a specified type.
+   */
+  template <typename T>
+  T to() const {
+    T value;
+    toInternal<T>(array_, &value);
+    return value;
+  }
+  template <typename T>
+  void to(T* value) const { toInternal<T>(array_, value); }
+  /** Template for element accessor.
+   * @param index index of the array element.
+   * @return value of the element at index.
+   *
+   *
+   * Example:
+   * @code
+   *     MxArray array(prhs[0]);
+   *     double value = array.at<double>(0);
+   * @endcode
+   */
+  template <typename T>
+  T at(mwIndex index) const {
+    T value;
+    atInternal<T>(array_, index, &value);
+    return value;
+  }
+  template <typename T>
+  void at(mwIndex index, T* value) const {
+    atInternal<T>(array_, index, value);
+  }
+  const mxArray* at(mwIndex index) const {
+    return at(array_, index);
+  }
+  /** Template for element accessor.
+   * @param row index of the first dimension.
+   * @param column index of the second dimension.
+   * @return value of the element at (row, column).
+   */
+  template <typename T>
+  T at(mwIndex row, mwIndex column) const;
+  /** Template for element accessor.
+   * @param subscripts subscript indexes of elements.
+   * @return value of the element at subscript index.
+   */
+  template <typename T>
+  T at(const std::vector<mwIndex>& subscripts) const;
+  /** Struct element accessor.
+   * @param field field name of the struct array.
+   * @param index index of the struct array.
+   * @return value of the element at the specified field.
+   */
+  template <typename T>
+  T at(const std::string& field, mwIndex index = 0) const {
+    T value;
+    atInternal<T>(array_, field, index, &value);
+    return value;
+  }
+  template <typename T>
+  void at(const std::string& field, T* value, mwIndex index = 0) const {
+    atInternal<T>(array_, field, index, value);
+  }
+  const mxArray* at(const std::string& field, mwIndex index = 0) const {
+    return at(array_, field, index);
+  }
+
+  /** Template for element write accessor.
+   * @param index offset of the array element.
+   * @param value value of the field.
+   */
+  template <typename T>
+  void set(mwIndex index, const T& value) {
+    setInternal<T>(array_, index, value);
+  }
+  /** Template for element write accessor.
+   * @param row index of the first dimension of the array element.
+   * @param column index of the first dimension of the array element.
+   * @param value value of the field.
+   */
+  template <typename T>
+  void set(mwIndex row, mwIndex column, const T& value);
+  /** Template for element write accessor.
+   * @param subscripts subscript index of the element.
+   * @param value value of the field.
+   */
+  template <typename T>
+  void set(const std::vector<mwIndex>& subscripts, const T& value);
+  /** Cell element write accessor.
+   * @param index index of the element.
+   * @param value cell element to be inserted.
+   */
+  void set(mwIndex index, mxArray* value) {
+    MEXPLUS_ASSERT(isOwner(), "Must be an owner to set.");
+    set(array_, index, value);
+  }
+  /** Cell element write accessor.
+   * @param row index of the first dimension of the array element.
+   * @param column index of the first dimension of the array element.
+   * @param value cell element to be inserted.
+   */
+  void set(mwIndex row, mwIndex column, mxArray* value) {
+    MEXPLUS_ASSERT(isOwner(), "Must be an owner to set.");
+    set(array_, subscriptIndex(row, column), value);
+  }
+  /** Cell element write accessor.
+   * @param subscripts subscript index of the element.
+   * @param value value of the field.
+   */
+  void set(const std::vector<mwIndex>& subscripts, mxArray* value) {
+    MEXPLUS_ASSERT(isOwner(), "Must be an owner to set.");
+    set(array_, subscriptIndex(subscripts), value);
+  }
+  /** Struct element write accessor.
+   * @param field field name of the struct array.
+   * @param value value of the field.
+   * @param index linear index of the struct array element.
+   */
+  template <typename T>
+  void set(const std::string& field, const T& value, mwIndex index = 0) {
+    MEXPLUS_ASSERT(isOwner(), "Must be an owner to set.");
+    setInternal<T>(array_, field, index, value);
+  }
+  /** Struct element write accessor.
+   * @param field field name of the struct array.
+   * @param value value of the field to be inserted.
+   * @param index linear index of the struct array element.
+   */
+  void set(const std::string& field, mxArray* value, mwIndex index = 0) {
+    MEXPLUS_ASSERT(isOwner(), "Must be an owner to set.");
+    set(array_, field, value, index);
+  }
+  /** Get raw data pointer.
+   * @return pointer T*. If MxArray is not compatible, return NULL.
+   */
+  template <typename T>
+  T* getData() const;
+  /** Get raw data pointer to imaginary part.
+   * @return pointer T*. If MxArray is not compatible, return NULL.
+   */
+  template <typename T>
+  T* getImagData() const;
+  mxLogical* getLogicals() const {
+    MEXPLUS_CHECK_NOTNULL(array_);
+    MEXPLUS_ASSERT(isLogical(),
+                   "Expected a logical array but %s.",
+                   className().c_str());
+    return mxGetLogicals(array_);
+  }
+  mxChar* getChars() const {
+    MEXPLUS_CHECK_NOTNULL(array_);
+    MEXPLUS_ASSERT(isChar(),
+                   "Expected a char array but %s.",
+                   className().c_str());
+    return mxGetChars(array_);
+  }
+  /** Class ID of mxArray.
+   */
+  inline mxClassID classID() const { return mxGetClassID(array_); }
+  /** Class name of mxArray.
+   */
+  inline const std::string className() const {
+    return std::string(mxGetClassName(array_));
+  }
+  /** Number of elements in an array.
+   */
+  inline mwSize size() const {
+    return static_cast<mwSize>(mxGetNumberOfElements(array_));
+  }
+  /** Number of dimensions.
+   */
+  inline mwSize dimensionSize() const {
+    return mxGetNumberOfDimensions(array_);
+  }
+  /** Array of each dimension.
+   */
+  inline std::vector<mwSize> dimensions() const {
+    const mwSize* dimensions = mxGetDimensions(array_);
+    return std::vector<mwSize>(dimensions, dimensions + dimensionSize());
+  }
+  /** Number of rows in an array.
+   */
+  inline mwSize rows() const { return static_cast<mwSize>(mxGetM(array_)); }
+  /** Number of columns in an array.
+   */
+  inline mwSize cols() const { return static_cast<mwSize>(mxGetN(array_)); }
+  /** Number of fields in a struct array.
+   */
+  inline int fieldSize() const { return mxGetNumberOfFields(array_); }
+  /** Get field name of a struct array.
+   * @param index index of the struct array.
+   * @return std::string.
+   */
+  std::string fieldName(int index) const {
+    const char* field = mxGetFieldNameByNumber(array_, index);
+    MEXPLUS_ASSERT(field, "Failed to get field name at %d.", index);
+    return std::string(field);
+  }
+  /** Get field names of a struct array.
+   * @return std::vector<std::string> of struct field names.
+   */
+  std::vector<std::string> fieldNames() const {
+    MEXPLUS_ASSERT(isStruct(), "Expected a struct array.");
+    std::vector<std::string> fields(fieldSize());
+    for (size_t i = 0; i < fields.size(); ++i)
+      fields[i] = fieldName(i);
+    return fields;
+  }
+  /** Number of elements in IR, PR, and PI arrays.
+   */
+  inline mwSize nonZeroMax() const { return mxGetNzmax(array_); }
+  /** Offset from first element to desired element.
+   * @param row index of the first dimension of the array.
+   * @param column index of the second dimension of the array.
+   * @return linear offset of the specified subscript index.
+   */
+  mwIndex subscriptIndex(mwIndex row, mwIndex column) const {
+    MEXPLUS_ASSERT(row < rows() && column < cols(),
+                   "Subscript is out of range.");
+    mwIndex subscripts[] = {row, column};
+    return mxCalcSingleSubscript(array_, 2, subscripts);
+  }
+  /** Offset from first element to desired element.
+   * @param subscripts subscript indexes of the array.
+   * @return linear offset of the specified subscript index.
+   */
+  mwIndex subscriptIndex(const std::vector<mwIndex>& subscripts) const {
+    return mxCalcSingleSubscript(array_,
+                                 static_cast<mwSize>(subscripts.size()),
+                                 const_cast<mwIndex*>(&subscripts[0]));
+  }
+  /** Determine whether input is cell array.
+   */
+  inline bool isCell() const { return mxIsCell(array_); }
+  /** Determine whether input is string array.
+   */
+  inline bool isChar() const { return mxIsChar(array_); }
+  /** Determine whether input is vector array.
+   */
+  inline bool isVector() const {
+    return mxGetNumberOfDimensions(array_) == 2 &&
+        (mxGetM(array_) == 1 || mxGetN(array_) == 1);
+  }
+  /** Determine whether array is integral type.
+   */
+  inline bool isIntegral(const char* name) const {
+    return mxIsNumeric(array_) && !mxIsDouble(array_);
+  }
+  /** Determine whether array is member of specified class.
+   */
+  inline bool isClass(const char* name) const {
+    return mxIsClass(array_, name);
+  }
+  /** Determine whether data is complex.
+   */
+  inline bool isComplex() const { return mxIsComplex(array_); }
+  /** Determine whether mxArray represents data as double-precision,
+   * floating-point numbers.
+   */
+  inline bool isDouble() const { return mxIsDouble(array_); }
+  /** Determine whether array is empty.
+   */
+  inline bool isEmpty() const { return mxIsEmpty(array_); }
+  /** Determine whether input is finite.
+   */
+  static inline bool IsFinite(double value) { return mxIsFinite(value); }
+  /** Determine whether array was copied from MATLAB global workspace.
+   */
+  inline bool isFromGlobalWS() const { return mxIsFromGlobalWS(array_); }
+  /** Determine whether input is infinite.
+   */
+  static inline bool IsInf(double value) { return mxIsInf(value); }
+  /** Determine whether array represents data as signed 8-bit integers.
+   */
+  inline bool isInt8() const { return mxIsInt8(array_); }
+  /** Determine whether array represents data as signed 16-bit integers.
+   */
+  inline bool isInt16() const { return mxIsInt16(array_); }
+  /** Determine whether array represents data as signed 32-bit integers.
+   */
+  inline bool isInt32() const { return mxIsInt32(array_); }
+  /** Determine whether array represents data as signed 64-bit integers.
+   */
+  inline bool isInt64() const { return mxIsInt64(array_); }
+  /** Determine whether array is of type mxLogical.
+   */
+  inline bool isLogical() const { return mxIsLogical(array_); }
+  /** Determine whether scalar array is of type mxLogical.
+   */
+  inline bool isLogicalScalar() const { return mxIsLogicalScalar(array_); }
+  /** Determine whether scalar array of type mxLogical is true.
+   */
+  inline bool isLogicalScalarTrue() const {
+    return mxIsLogicalScalarTrue(array_);
+  }
+  /** Determine whether array is numeric.
+   */
+  inline bool isNumeric() const { return mxIsNumeric(array_); }
+  /** Determine whether array represents data as single-precision,
+   * floating-point numbers.
+   */
+  inline bool isSingle() const { return mxIsSingle(array_); }
+  /** Determine whether input is sparse array.
+   */
+  inline bool isSparse() const { return mxIsSparse(array_); }
+  /** Determine whether input is structure array.
+   */
+  inline bool isStruct() const { return mxIsStruct(array_); }
+  /** Determine whether array represents data as unsigned 8-bit integers.
+   */
+  inline bool isUint8() const { return mxIsUint8(array_); }
+  /** Determine whether array represents data as unsigned 16-bit integers.
+   */
+  inline bool isUint16() const { return mxIsUint16(array_); }
+  /** Determine whether array represents data as unsigned 32-bit integers.
+   */
+  inline bool isUint32() const { return mxIsUint32(array_); }
+  /** Determine whether array represents data as unsigned 64-bit integers.
+   */
+  inline bool isUint64() const { return mxIsUint64(array_); }
+  /** Determine whether a struct array has a specified field.
+   */
+  bool hasField(const std::string& field_name, mwIndex index = 0) const {
+    return isStruct() &&
+        mxGetField(array_, index, field_name.c_str()) != NULL;
+  }
+  /** Element size.
+   */
+  int elementSize() const {
+    return static_cast<int>(mxGetElementSize(array_));
+  }
+  /** Determine whether input is NaN (Not-a-Number).
+   */
+  static inline bool IsNaN(double value) { return mxIsNaN(value); }
+  /** Value of infinity.
+   */
+  static inline double Inf() { return mxGetInf(); }
+  /** Value of NaN (Not-a-Number).
+   */
+  static inline double NaN() { return mxGetNaN(); }
+  /** Value of EPS.
+   */
+  static inline double Eps() { return mxGetEps(); }
+
+ private:
+  /** Copy constructor is prohibited except internally.
+   */
+  MxArray(const MxArray& array);
+  // MxArray(const MxArray& array) = delete;
+  /** Copy assignment operator is prohibited.
+   */
+  MxArray& operator=(const MxArray& rhs);
+  // MxArray& operator=(const MxArray& rhs) = delete;
+
+  /*************************************************************/
+  /**             Templated mxArray importers                 **/
+  /*************************************************************/
+
+  /** Fundamental numerics.
+   */
+  template <typename T>
+  static mxArray* fromInternal(const typename std::enable_if<
+      MxArithmeticType<T>::value, T>::type& value);
+  /** Complex types, complex<float> or complex<double>.
+   */
+  template <typename T>
+  static mxArray* fromInternal(const typename std::enable_if<
+      MxComplexType<T>::value, T>::type& value);
+  /** Container with fundamental numerics, i.e. vector<double>.
+   */
+  template <typename Container>
+  static mxArray* fromInternal(const typename std::enable_if<
+      MxArithmeticCompound<Container>::value,
+      Container>::type& value);
+  /** Container with complex numbers, i.e. vector<complex<double>>.
+   */
+  template <typename Container>
+  static mxArray* fromInternal(const typename std::enable_if<
+      MxComplexCompound<Container>::value, Container>::type& value);
+  /** Char type */
+  template <typename T>
+  static mxArray* fromInternal(const typename std::enable_if<
+      MxCharType<T>::value, T>::type& value);
+  /** Containter with signed char.
+   */
+  template <typename Container>
+  static mxArray* fromInternal(const typename std::enable_if<
+      (MxCharCompound<Container>::value) &&
+      (std::is_signed<typename Container::value_type>::value),
+      Container>::type& value);
+  /** Container with unsigned char.
+   */
+  template <typename Container>
+  static mxArray* fromInternal(const typename std::enable_if<
+      (MxCharCompound<Container>::value) &&
+      !(std::is_signed<typename Container::value_type>::value),
+      Container>::type& value);
+  /** Logicals.
+   */
+  template <typename T>
+  static mxArray* fromInternal(const typename std::enable_if<
+      MxLogicalType<T>::value, T>::type& value);
+  /** Container with logicals.
+   */
+  template <typename Container>
+  static mxArray* fromInternal(const typename std::enable_if<
+      MxLogicalCompound<Container>::value, Container>::type& value);
+  /** Container with cell type content.
+   */
+  template <typename Container>
+  static mxArray* fromInternal(const typename std::enable_if<
+      MxCellCompound<Container>::value, Container>::type& value);
+
+  /*************************************************************/
+  /**             Templated mxArray exporters                 **/
+  /*************************************************************/
+
+  /** Singleton types.
+   */
+  template <typename T>
+  static void toInternal(const mxArray* array,
+                         typename std::enable_if<
+                           MxArithmeticType<T>::value ||
+                           MxComplexType<T>::value ||
+                           MxLogicalType<T>::value ||
+                           MxCharType<T>::value,
+                           T
+                         >::type* value) {
+    atInternal<T>(array, 0, value);
+  }
+  /** Vector types.
+   */
+  template <typename T>
+  static void toInternal(const mxArray* array,
+                         typename std::enable_if<
+                           MxComplexOrArithmeticCompound<T>::value ||
+                           MxLogicalCompound<T>::value ||
+                           MxCharCompound<T>::value,
+                           T
+                         >::type* value);
+  /** Nested types (leads into recursive deduction).
+   */
+  template <typename T>
+  static void toInternal(const mxArray* array,
+                         typename std::enable_if<
+                           MxCellType<T>::value &&
+                           (!std::is_compound<T>::value ||
+                            MxCellType<typename T::value_type>::value),
+                           T
+                         >::type* value);
+
+  /*************************************************************/
+  /**             Templated mxArray getters                   **/
+  /*************************************************************/
+
+  /** Fundamental numeric types.
+   */
+  template <typename T>
+  static void atInternal(const mxArray* array, mwIndex index,
+                         typename std::enable_if<
+                           MxComplexOrArithmeticType<T>::value ||
+                           MxLogicalType<T>::value ||
+                           MxCharType<T>::value,
+                         T>::type* value);
+  /** Converter for nested types.
+   */
+  template <typename T>
+  static void atInternal(const mxArray* array, mwIndex index,
+                         typename std::enable_if<
+                           std::is_compound<T>::value &&
+                           !MxComplexType<T>::value,
+                           T
+                         >::type* value);
+  /** Structure access.
+   */
+  template <typename T>
+  static void atInternal(const mxArray* array,
+                         const std::string& field,
+                         mwIndex index, T* value);
+
+  /*************************************************************/
+  /**           Templated mxArray element setters             **/
+  /*************************************************************/
+
+  /** Fundamental numeric and complex types.
+   */
+  template <typename T>
+  static void setInternal(mxArray* array, mwIndex index,
+                          const typename std::enable_if<
+                            !std::is_compound<T>::value ||
+                            MxComplexType<T>::value,
+                            T
+                          >::type& value);
+  /** Container types.
+   */
+  template <typename T>
+  static void setInternal(mxArray* array,  mwIndex index,
+                          const typename std::enable_if<
+                            MxCellType<T>::value,
+                            T
+                          >::type& value);
+  /** Structure access.
+   */
+  template <typename T>
+  static void setInternal(mxArray* array, const std::string& field,
+                          mwIndex index, const T& value);
+
+  /*************************************************************/
+  /**    Assignment helpers (for MxArray.to<type>(value))     **/
+  /*************************************************************/
+
+  /** Explicit integer element assignment.
+   */
+  template <typename T, typename R>
+  static void assignTo(const mxArray* array,
+                       mwIndex index, typename std::enable_if<
+                         std::is_integral<R>::value,
+                         R
+                       >::type* value) {
+    MEXPLUS_ASSERT(!mxIsComplex(array), "Non-complex array expected!");
+    *value = (R)*(reinterpret_cast<T*>(mxGetData(array)) + index);
+  }
+  /** Explicit floating point element assignment.
+   */
+  template <typename T, typename R>
+  static void assignTo(const mxArray* array,
+                       mwIndex index,
+                       typename std::enable_if<
+                         std::is_floating_point<R>::value,
+                         R
+                       >::type* value) {
+    if (mxIsComplex(array)) {
+      T real_part = *(reinterpret_cast<T*>(mxGetPr(array)) + index);
+      T imag_part = *(reinterpret_cast<T*>(mxGetPi(array)) + index);
+      *value = std::abs(std::complex<R>(real_part, imag_part));
+    } else {
+      *value = *(reinterpret_cast<T*>(mxGetData(array)) + index);
+    }
+  }
+  /** Explicit complex element assignment.
+   */
+  template <typename T, typename R>
+  static void assignTo(const mxArray* array,
+                       mwIndex index,
+                       typename std::enable_if<
+                         MxComplexType<R>::value,
+                         R
+                       >::type* value) {
+    typename R::value_type real_part, imag_part;
+    if (mxIsComplex(array)) {
+      real_part = *(reinterpret_cast<T*>(mxGetPr(array)) + index);
+      imag_part = *(reinterpret_cast<T*>(mxGetPi(array)) + index);
+    } else {
+      real_part = *(reinterpret_cast<T*>(mxGetData(array)) + index);
+      imag_part = 0.0;
+    }
+    *value = std::complex<typename R::value_type>(real_part, imag_part);
+  }
+  /** Explicit char (signed) element assignment.
+   */
+  template <typename R>
+  static void assignCharTo(const mxArray* array,
+                           mwIndex index,
+                           typename std::enable_if<
+                             std::is_signed<R>::value,
+                             R
+                           >::type* value) {
+    typedef typename std::make_signed<mxChar>::type SignedMxChar;
+    *value = *(reinterpret_cast<SignedMxChar*>(mxGetChars(array)) + index);
+  }
+  /** Explicit char (unsigned) element assignment.
+   */
+  template <typename R>
+  static void assignCharTo(const mxArray* array,
+                           mwIndex index,
+                           typename std::enable_if<
+                             !std::is_signed<R>::value,
+                             R
+                           >::type* value) {
+    *value = *(mxGetChars(array) + index);
+  }
+  /** Explicit cell element assignment.
+   */
+  template <typename T>
+  static void assignCellTo(const mxArray* array, mwIndex index, T* value) {
+    const mxArray* element = mxGetCell(array, index);
+    MEXPLUS_CHECK_NOTNULL(element);
+    toInternal<T>(element, value);  // Recursion for nested types.
+  }
+  /** Explicit numeric array assignment.
+   */
+  template <typename T, typename R>
+  static void assignTo(const mxArray* array,
+                       typename std::enable_if<
+                         MxArithmeticCompound<R>::value ||
+                         MxLogicalCompound<R>::value ||
+                         MxCharCompound<R>::value,
+                         R
+                       >::type* value) {
+    mwSize array_size = static_cast<mwSize>(mxGetNumberOfElements(array));
+    if (!mxIsComplex(array)) {
+      T* data_pointer = reinterpret_cast<T*>(mxGetData(array));
+      value->assign(data_pointer, data_pointer + array_size);
+    } else {
+      T* real_part = reinterpret_cast<T*>(mxGetPr(array));
+      T* imag_part = reinterpret_cast<T*>(mxGetPi(array));
+      value->resize(array_size);
+      for (mwSize i = 0; i < array_size; ++i) {
+        double mag = std::abs(std::complex<double>(
+            static_cast<double>(*(real_part++)),
+            static_cast<double>(*(imag_part++))));
+        (*value)[i] = static_cast<T>(mag);
+      }
+    }
+  }
+  /** Explicit complex array assigment.
+   */
+  template <typename T, typename R>
+  static void assignTo(const mxArray* array,
+                       typename std::enable_if<
+                         MxComplexCompound<R>::value,
+                         R
+                       >::type* value) {
+    mwSize array_size = mxGetNumberOfElements(array);
+    value->resize(array_size);
+    if (!mxIsComplex(array)) {
+      T* data_pointer = reinterpret_cast<T*>(mxGetData(array));
+      for (mwSize i = 0; i < array_size; ++i) {
+        (*value)[i] = typename R::value_type(*(data_pointer++), 0.0f);
+      }
+    } else {
+      T* real_part = reinterpret_cast<T*>(mxGetPr(array));
+      T* imag_part = reinterpret_cast<T*>(mxGetPi(array));
+      for (mwSize i = 0; i < array_size; ++i) {
+        (*value)[i] = typename R::value_type(*(real_part++), *(imag_part++));
+      }
+    }
+  }
+  /** Explicit char (signed) array assignment.
+   */
+  template <typename R>
+  static void assignStringTo(const mxArray* array,
+                             typename std::enable_if<
+                               std::is_signed<typename R::value_type>::value,
+                               R
+                             >::type* value) {
+    typedef typename std::make_signed<mxChar>::type SignedMxChar;
+    SignedMxChar* data_pointer = reinterpret_cast<SignedMxChar*>(
+        mxGetChars(array));
+    value->assign(data_pointer, data_pointer + mxGetNumberOfElements(array));
+  }
+  /** Explicit char (unsigned) array assignment.
+   */
+  template <typename R>
+  static void assignStringTo(const mxArray* array,
+                             typename std::enable_if<
+                               !std::is_signed<typename R::value_type>::value,
+      R>::type* value) {
+    mxChar* data_pointer = mxGetChars(array);
+    value->assign(data_pointer, data_pointer + mxGetNumberOfElements(array));
+  }
+  /** Explicit cell array assignment.
+   */
+  template <typename T>
+  static void assignCellTo(const mxArray* array, T* value) {
+    mwSize array_size = static_cast<mwSize>(mxGetNumberOfElements(array));
+    value->resize(array_size);
+    for (size_t i = 0; i < array_size; ++i) {
+      const mxArray* element = mxGetCell(array, i);
+      MEXPLUS_CHECK_NOTNULL(element);
+      (*value)[i] = to<typename T::value_type>(element);
+    }
+  }
+
+  /*************************************************************/
+  /**  Assignment helpers (for MxArray.set<type>(i, value))  **/
+  /*************************************************************/
+
+  /** Explicit numeric element assignment.
+   */
+  template <typename R, typename T>
+  static void assignFrom(mxArray* array,
+                         mwIndex index,
+                         const typename std::enable_if<
+                           MxArithmeticType<T>::value || MxCharType<T>::value,
+                           T
+                         >::type& value) {
+    if (mxIsComplex(array)) {
+      *(reinterpret_cast<R*>(mxGetPr(array)) + index) = value;
+      *(reinterpret_cast<R*>(mxGetPi(array)) + index) = 0.0;
+    } else {
+      *(reinterpret_cast<R*>(mxGetData(array)) + index) = value;
+    }
+  }
+  /** Explicit complex element assignment.
+   */
+  template <typename R, typename T>
+  static void assignFrom(mxArray* array,
+                         mwIndex index,
+                         const typename std::enable_if<
+                           MxComplexType<T>::value,
+                           T
+                         >::type& value) {
+    if (mxIsComplex(array)) {
+      *(reinterpret_cast<R*>(mxGetPr(array)) + index) = value.real();
+      *(reinterpret_cast<R*>(mxGetPi(array)) + index) = value.imag();
+    } else {
+      *(reinterpret_cast<R*>(mxGetData(array)) + index) = std::abs(value);
+    }
+  }
+  template <typename T>
+  static void assignCharFrom(mxArray* array,
+                             mwIndex index,
+                             const typename std::enable_if<
+                               std::is_floating_point<T>::value,
+                               T
+                             >::type& value) {
+    *(mxGetChars(array) + index) = value;  // whoever needs this...
+  }
+  template <typename T>
+  static void assignCharFrom(mxArray* array,
+                             mwIndex index,
+                             const typename std::enable_if<
+                               std::is_integral<T>::value &&
+                               std::is_signed<T>::value,
+                               T
+                             >::type& value) {
+    *(mxGetChars(array) + index) = reinterpret_cast<const typename
+        std::make_unsigned<T>::type&>(value);
+  }
+  template <typename T>
+  static void assignCharFrom(mxArray* array,
+                             mwIndex index,
+                             const typename std::enable_if<
+                               std::is_integral<T>::value &&
+                               !std::is_signed<T>::value,
+                               T
+                             >::type& value) {
+    *(mxGetChars(array) + index) = value;
+  }
+
+  template <typename T>
+  static void assignCharFrom(mxArray* array,
+                             mwIndex index,
+                             const typename std::enable_if<
+                               MxComplexType<T>::value,
+                               T
+                             >::type& value) {
+    *(mxGetChars(array) + index) = std::abs(value);  // whoever needs it...
+  }
+
+  /** Pointer to the mxArray C object.
+   */
+  mxArray* array_;
+  /** Flag to enable resource management.
+   */
+  bool owner_;
+};
+
+/*************************************************************/
+/**             Templated mxArray importers                 **/
+/*************************************************************/
+
+/** Fundamental numeric type.
+ */
+template <typename T>
+mxArray* MxArray::fromInternal(const typename std::enable_if<
+    MxArithmeticType<T>::value, T>::type& value) {
+  mxArray* array = mxCreateNumericMatrix(1,
+                                         1,
+                                         MxTypes<T>::class_id,
+                                         MxTypes<T>::complexity);
+  MEXPLUS_CHECK_NOTNULL(array);
+  *reinterpret_cast<T*>(mxGetData(array)) = value;
+  return array;
+}
+
+/** Complex type, complex<float> or complex<double>.
+ */
+template <typename T>
+mxArray* MxArray::fromInternal(const typename std::enable_if<
+    MxComplexType<T>::value, T>::type& value) {
+  mxArray* array = mxCreateNumericMatrix(1, 1,
+                                         MxTypes<T>::class_id,
+                                         MxTypes<T>::complexity);
+  MEXPLUS_CHECK_NOTNULL(array);
+  *reinterpret_cast<typename T::value_type*>(mxGetPr(array)) = value.real();
+  *reinterpret_cast<typename T::value_type*>(mxGetPi(array)) = value.imag();
+
+  return array;
+}
+
+/** Container with fundamental numerics, i.e. vector<double>.
+ */
+template <typename Container>
+mxArray* MxArray::fromInternal(const typename std::enable_if<
+    MxArithmeticCompound<Container>::value, Container>::type& value) {
+  typedef typename Container::value_type ValueType;
+  mxArray* array = mxCreateNumericMatrix(1,
+                                         value.size(),
+                                         MxTypes<ValueType>::class_id,
+                                         MxTypes<ValueType>::complexity);
+  MEXPLUS_CHECK_NOTNULL(array);
+  std::copy(value.begin(),
+            value.end(),
+            reinterpret_cast<ValueType*>(mxGetData(array)));
+  return array;
+}
+
+/** Container with complex numbers, i.e. vector<complex<double>>.
+ */
+template <typename Container>
+mxArray* MxArray::fromInternal(const typename std::enable_if<
+      MxComplexCompound<Container>::value, Container>::type& value) {
+  typedef typename Container::value_type ContainerValueType;
+  typedef typename ContainerValueType::value_type ValueType;
+  mxArray* array = mxCreateNumericMatrix(1,
+                                         value.size(),
+                                         MxTypes<ContainerValueType>::class_id,
+                                         mxCOMPLEX);
+  MEXPLUS_CHECK_NOTNULL(array);
+  ValueType* real = reinterpret_cast<ValueType*>(mxGetPr(array));
+  ValueType* imag = reinterpret_cast<ValueType*>(mxGetPi(array));
+  typename Container::const_iterator it;
+  for (it = value.begin(); it != value.end(); it++) {
+      *real++ = (*it).real();
+      *imag++ = (*it).imag();
+  }
+  return array;
+}
+
+template <typename T>
+mxArray* MxArray::fromInternal(const typename std::enable_if<
+    MxCharType<T>::value, T>::type& value) {
+  const char char_array[] = {static_cast<char>(value), 0};
+  mxArray* array = mxCreateString(char_array);
+  MEXPLUS_CHECK_NOTNULL(array);
+  return array;
+}
+
+template <typename Container>
+mxArray* MxArray::fromInternal(const typename std::enable_if<
+    (MxCharCompound<Container>::value) &&
+    (std::is_signed<typename Container::value_type>::value),
+    Container>::type& value) {
+  typedef typename std::make_unsigned<typename Container::value_type>::type
+                   UnsignedValue;
+  const mwSize dimensions[] = {1, static_cast<mwSize>(value.size())};
+  mxArray* array = mxCreateCharArray(2, dimensions);
+  MEXPLUS_CHECK_NOTNULL(array);
+  mxChar* array_data = mxGetChars(array);
+  for (typename Container::const_iterator it = value.begin();
+       it != value.end();
+       ++it) {
+    *(array_data++) = reinterpret_cast<const UnsignedValue&>(*it);
+  }
+  return array;
+}
+
+template <typename Container>
+mxArray* MxArray::fromInternal(const typename std::enable_if<
+    (MxCharCompound<Container>::value) &&
+    !(std::is_signed<typename Container::value_type>::value),
+    Container>::type& value) {
+  const mwSize dimensions[] = {1, static_cast<mwSize>(value.size())};
+  mxArray* array = mxCreateCharArray(2, dimensions);
+  MEXPLUS_CHECK_NOTNULL(array);
+  std::copy(value.begin(), value.end(), mxGetChars(array));
+  return array;
+}
+
+template <typename T>
+mxArray* MxArray::fromInternal(const typename std::enable_if<
+    MxLogicalType<T>::value, T>::type& value) {
+  mxArray* array = mxCreateLogicalScalar(value);
+  MEXPLUS_CHECK_NOTNULL(array);
+  return array;
+}
+
+template <typename Container>
+mxArray* MxArray::fromInternal(const typename std::enable_if<
+    MxLogicalCompound<Container>::value, Container>::type& value) {
+  mxArray* array = mxCreateLogicalMatrix(1, value.size());
+  MEXPLUS_CHECK_NOTNULL(array);
+  std::copy(value.begin(), value.end(), mxGetLogicals(array));
+  return array;
+}
+
+template <typename Container>
+mxArray* MxArray::fromInternal(const typename std::enable_if<
+    MxCellCompound<Container>::value, Container>::type& value) {
+  mxArray* array = mxCreateCellMatrix(1, value.size());
+  MEXPLUS_CHECK_NOTNULL(array);
+  mwIndex index = 0;
+  for (typename Container::const_iterator it = value.begin();
+       it != value.end();
+       ++it) {
+    mxArray* new_item = from(*it);  // Safe in case if from() fails.
+    mxDestroyArray(mxGetCell(array, index));
+    mxSetCell(array, index++, new_item);
+  }
+  return array;
+}
+
+/*************************************************************/
+/**             Templated mxArray exporters                 **/
+/*************************************************************/
+
+/** Converter from numeric matrix to container.
+ */
+template <typename T>
+void MxArray::toInternal(const mxArray* array, typename std::enable_if<
+                           MxComplexOrArithmeticCompound<T>::value ||
+                           MxLogicalCompound<T>::value ||
+                           MxCharCompound<T>::value, T>::type* value) {
+  MEXPLUS_CHECK_NOTNULL(array);
+  MEXPLUS_CHECK_NOTNULL(value);
+  switch (mxGetClassID(array)) {
+    case mxINT8_CLASS:    assignTo<int8_t, T>(array, value); break;
+    case mxUINT8_CLASS:   assignTo<uint8_t, T>(array, value); break;
+    case mxINT16_CLASS:   assignTo<int16_t, T>(array, value); break;
+    case mxUINT16_CLASS:  assignTo<uint16_t, T>(array, value); break;
+    case mxINT32_CLASS:   assignTo<int32_t, T>(array, value); break;
+    case mxUINT32_CLASS:  assignTo<uint32_t, T>(array, value); break;
+    case mxINT64_CLASS:   assignTo<int64_t, T>(array, value); break;
+    case mxUINT64_CLASS:  assignTo<uint64_t, T>(array, value); break;
+    case mxSINGLE_CLASS:  assignTo<float, T>(array, value); break;
+    case mxDOUBLE_CLASS:  assignTo<double, T>(array, value); break;
+    case mxLOGICAL_CLASS: assignTo<mxLogical, T>(array, value); break;
+    case mxCHAR_CLASS:    assignStringTo<T>(array, value); break;
+    case mxCELL_CLASS:    assignCellTo<T>(array, value); break;
+    // case mxSPARSE_CLASS:
+    default:
+      MEXPLUS_ERROR("Cannot convert %s.", mxGetClassName(array));
+  }
+}
+
+/** Converter from nested types to container.
+ */
+template <typename T>
+void MxArray::toInternal(const mxArray* array,
+                         typename std::enable_if<
+                           MxCellType<T>::value &&
+                           (!std::is_compound<T>::value ||
+                           MxCellType<typename T::value_type>::value),
+                           T
+                         >::type* value) {
+  MEXPLUS_CHECK_NOTNULL(value);
+  MEXPLUS_ASSERT(mxIsCell(array), "Expected a cell array.");
+  mwSize array_size = mxGetNumberOfElements(array);
+  value->resize(array_size);
+  for (size_t i = 0; i < array_size; ++i) {
+    const mxArray* element = mxGetCell(array, i);
+    (*value)[i] = to<typename T::value_type>(element);
+  }
+}
+
+/*************************************************************/
+/**             Templated mxArray getters                   **/
+/*************************************************************/
+
+/** Converter from fundamental numeric or complex types.
+ */
+template <typename T>
+void MxArray::atInternal(const mxArray* array, mwIndex index,
+                         typename std::enable_if<
+                         MxComplexOrArithmeticType<T>::value ||
+                         MxLogicalType<T>::value ||
+                         MxCharType<T>::value, T>::type* value) {
+  MEXPLUS_CHECK_NOTNULL(array);
+  MEXPLUS_CHECK_NOTNULL(value);
+  MEXPLUS_ASSERT(static_cast<size_t>(index) < mxGetNumberOfElements(array),
+                 "Index out of range: %u.",
+                 index);
+  switch (mxGetClassID(array)) {
+    case mxINT8_CLASS:    assignTo<int8_t, T>(array, index, value); break;
+    case mxUINT8_CLASS:   assignTo<uint8_t, T>(array, index, value); break;
+    case mxINT16_CLASS:   assignTo<int16_t, T>(array, index, value); break;
+    case mxUINT16_CLASS:  assignTo<uint16_t, T>(array, index, value); break;
+    case mxINT32_CLASS:   assignTo<int32_t, T>(array, index, value); break;
+    case mxUINT32_CLASS:  assignTo<uint32_t, T>(array, index, value); break;
+    case mxINT64_CLASS:   assignTo<int64_t, T>(array, index, value); break;
+    case mxUINT64_CLASS:  assignTo<uint64_t, T>(array, index, value); break;
+    case mxSINGLE_CLASS:  assignTo<float, T>(array, index, value); break;
+    case mxDOUBLE_CLASS:  assignTo<double, T>(array, index, value); break;
+    case mxLOGICAL_CLASS: assignTo<mxLogical, T>(array, index, value); break;
+    case mxCHAR_CLASS:    assignCharTo<T>(array, index, value); break;
+    case mxCELL_CLASS:    assignCellTo<T>(array, index, value); break;
+    // case mxSPARSE_CLASS:
+    default:
+      MEXPLUS_ASSERT(true, "Cannot convert %s", mxGetClassName(array));
+  }
+}
+
+template <typename T>
+void MxArray::atInternal(const mxArray* array, mwIndex index,
+                         typename std::enable_if<
+                           std::is_compound<T>::value &&
+                           !MxComplexType<T>::value, T>::type* value) {
+  MEXPLUS_CHECK_NOTNULL(array);
+  MEXPLUS_CHECK_NOTNULL(value);
+  MEXPLUS_ASSERT(static_cast<size_t>(index) < mxGetNumberOfElements(array),
+                 "Index out of range: %u.",
+                 index);
+  MEXPLUS_ASSERT(mxIsCell(array), "Expected a cell array.");
+  const mxArray* element = mxGetCell(array, index);
+  to<T>(element, value);
+}
+
+template <typename T>
+void MxArray::atInternal(const mxArray* array,
+                         const std::string& field,
+                         mwIndex index,
+                         T* value) {
+  MEXPLUS_CHECK_NOTNULL(array);
+  MEXPLUS_CHECK_NOTNULL(value);
+  MEXPLUS_ASSERT(static_cast<size_t>(index) < mxGetNumberOfElements(array),
+                 "Index out of range: %u.",
+                 index);
+  MEXPLUS_ASSERT(mxIsStruct(array), "Expected a struct array.");
+  const mxArray* element = mxGetField(array, index, field.c_str());
+  MEXPLUS_ASSERT(element, "Invalid field name %s.", field.c_str());
+  to<T>(element, value);
+}
+
+/*************************************************************/
+/**             Templated mxArray setters                   **/
+/*************************************************************/
+
+/** Converter from fundamental numeric or complex types.
+ */
+template <typename T>
+void MxArray::setInternal(mxArray* array,
+                          mwIndex index,
+                          const typename std::enable_if<
+                            !std::is_compound<T>::value ||
+              MxComplexType<T>::value, T>::type& value) {
+  MEXPLUS_CHECK_NOTNULL(array);
+  MEXPLUS_ASSERT(static_cast<size_t>(index) < mxGetNumberOfElements(array),
+                 "Index out of range: %u.",
+                 index);
+  switch (mxGetClassID(array)) {
+    case mxINT8_CLASS:    assignFrom<int8_t, T>(array, index, value); break;
+    case mxUINT8_CLASS:   assignFrom<uint8_t, T>(array, index, value); break;
+    case mxINT16_CLASS:   assignFrom<int16_t, T>(array, index, value); break;
+    case mxUINT16_CLASS:  assignFrom<uint16_t, T>(array, index, value); break;
+    case mxINT32_CLASS:   assignFrom<int32_t, T>(array, index, value); break;
+    case mxUINT32_CLASS:  assignFrom<uint32_t, T>(array, index, value); break;
+    case mxINT64_CLASS:   assignFrom<int64_t, T>(array, index, value); break;
+    case mxUINT64_CLASS:  assignFrom<uint64_t, T>(array, index, value); break;
+    case mxSINGLE_CLASS:  assignFrom<float, T>(array, index, value); break;
+    case mxDOUBLE_CLASS:  assignFrom<double, T>(array, index, value); break;
+    case mxCHAR_CLASS:    assignCharFrom<T>(array, index, value); break;
+    case mxLOGICAL_CLASS: assignFrom<mxLogical, T>(array, index, value); break;
+    case mxCELL_CLASS: {
+      mxArray* new_item = from(value);  // Safe in case if from() fails.
+
+      mxDestroyArray(mxGetCell(array, index));
+      mxSetCell(array, index, new_item);
+      break;
+    }
+    default:
+      MEXPLUS_ERROR("Cannot assign to %s array.", mxGetClassName(array));
+  }
+}
+
+/** Converter from fundamental numeric or complex types.
+ */
+template <typename T>
+void MxArray::setInternal(mxArray* array,
+                          mwIndex index,
+                          const typename std::enable_if<
+                            MxCellType<T>::value, T>::type& value) {
+  MEXPLUS_CHECK_NOTNULL(array);
+  MEXPLUS_ASSERT(static_cast<size_t>(index) < mxGetNumberOfElements(array),
+                 "Index out of range: %u.",
+                 index);
+  MEXPLUS_ASSERT(mxIsCell(array), "Expected a cell array.");
+  mxArray* new_item = from(value);  // Safe in case if from() fails.
+  mxDestroyArray(mxGetCell(array, index));
+  mxSetCell(array, index, new_item);
+}
+
+template <typename T>
+void MxArray::setInternal(mxArray* array,
+                          const std::string& field,
+                          mwIndex index,
+                          const T& value) {
+  MEXPLUS_CHECK_NOTNULL(array);
+  MEXPLUS_ASSERT(static_cast<size_t>(index) < mxGetNumberOfElements(array),
+                 "Index out of range: %u.",
+                 index);
+  MEXPLUS_ASSERT(mxIsStruct(array), "Expected a struct array.");
+  int field_number = mxGetFieldNumber(array, field.c_str());
+  if (field_number < 0) {
+    field_number = mxAddField(array, field.c_str());
+    MEXPLUS_ASSERT(field_number >= 0,
+                   "Failed to create a field '%s'",
+                   field.c_str());
+  }
+  mxArray* new_item = from(value);
+  mxDestroyArray(mxGetFieldByNumber(array, index, field_number));
+  mxSetFieldByNumber(array, index, field_number, new_item);
+}
+
+template <typename T>
+mxArray* MxArray::Numeric(int rows, int columns) {
+  typedef typename std::enable_if<
+      MxComplexOrArithmeticType<T>::value, T>::type Scalar;
+  mxArray* numeric = mxCreateNumericMatrix(rows,
+                                           columns,
+                                           MxTypes<Scalar>::class_id,
+                                           MxTypes<Scalar>::complexity);
+  MEXPLUS_CHECK_NOTNULL(numeric);
+  return numeric;
+}
+
+template <typename T>
+mxArray* MxArray::Numeric(std::vector<std::size_t> dims) {
+	typedef typename std::enable_if<
+		MxComplexOrArithmeticType<T>::value, T>::type Scalar;
+	mxArray* numeric = mxCreateNumericArray(dims.size(),
+                                          &dims[0],
+                                          MxTypes<Scalar>::class_id,
+                                          MxTypes<Scalar>::complexity);
+	MEXPLUS_CHECK_NOTNULL(numeric);
+	return numeric;
+}
+
+template <typename T>
+T* MxArray::getData() const {
+  MEXPLUS_CHECK_NOTNULL(array_);
+  MEXPLUS_ASSERT(MxTypes<T>::class_id == classID(),
+                 "Expected a %s array.",
+                 typeid(T).name());
+  return reinterpret_cast<T*>(mxGetData(array_));
+}
+
+template <typename T>
+T* MxArray::getImagData() const {
+  MEXPLUS_CHECK_NOTNULL(array_);
+  MEXPLUS_ASSERT(MxTypes<T>::class_id == classID(),
+                 "Expected a %s array.",
+                 typeid(T).name());
+  return reinterpret_cast<T*>(mxGetPi(array_));
+}
+
+template <typename T>
+T MxArray::at(mwIndex row, mwIndex column) const {
+  return at<T>(subscriptIndex(row, column));
+}
+
+template <typename T>
+T MxArray::at(const std::vector<mwIndex>& subscripts) const {
+  return at<T>(subscriptIndex(subscripts));
+}
+
+template <typename T>
+void MxArray::set(mwIndex row, mwIndex column, const T& value) {
+  set<T>(subscriptIndex(row, column), value);
+}
+
+template <typename T>
+void MxArray::set(const std::vector<mwIndex>& subscripts, const T& value) {
+  set<T>(subscriptIndex(subscripts), value);
+}
+
+}  // namespace mexplus
+
+#endif  // INCLUDE_MEXPLUS_MXARRAY_H_
diff --git a/wrapper_matlab/mxtypes.h b/wrapper_matlab/mxtypes.h
new file mode 100644
index 0000000000000000000000000000000000000000..bc8c1aa370f776d65b68ba67550b4c36dc014830
--- /dev/null
+++ b/wrapper_matlab/mxtypes.h
@@ -0,0 +1,345 @@
+/** MxTypes and other type traits for template.
+ *
+ * Copyright 2014 Kota Yamaguchi.
+ */
+
+#ifndef INCLUDE_MEXPLUS_MXTYPES_H_
+#define INCLUDE_MEXPLUS_MXTYPES_H_
+
+#include <mex.h>
+#include <complex>
+#include <type_traits>
+
+namespace mexplus {
+
+/************************************************************/
+/* Traits for fundamental datatypes.
+   Don't use with function templates due to type promotion!
+   (Ignore it and get PITA!)                                */
+/************************************************************/
+
+/** Traits for mxLogical-convertibles.
+ */
+template <typename T, typename U = T>
+struct MxLogicalTy : std::false_type {};
+
+template <typename T>
+struct MxLogicalTy<T, typename std::enable_if<
+    std::is_same<typename std::remove_cv<T>::type, bool>::value ||
+    std::is_same<typename std::remove_cv<T>::type, mxLogical>::value,
+    T>::type> : std::true_type {};
+
+/** Traits for mxChar-convertibles.
+ *
+ * Treat them as an integer types when they are specified signed or unsigned,
+ * because uint8_t is exactly unsigned char and there is no way to tell them
+ * apart.
+ */
+template <typename T, typename U = T>
+struct MxCharTy : std::false_type {};
+
+template <typename T>
+struct MxCharTy<T, typename std::enable_if<
+    std::is_same<typename std::remove_cv<T>::type, char>::value ||
+    // Visual Studio cannot distinguish these from uint.
+    // std::is_same<typename std::remove_cv<T>::type, char16_t>::value ||
+    // std::is_same<typename std::remove_cv<T>::type, char32_t>::value ||
+    std::is_same<typename std::remove_cv<T>::type, mxChar>::value ||
+    std::is_same<typename std::remove_cv<T>::type, wchar_t>::value,
+    T>::type> : std::true_type {};
+
+/** Traits for integer numerics.
+ */
+template <typename T, typename U = T>
+struct MxIntTy : std::false_type {};
+template <typename T>
+struct MxIntTy<T, typename std::enable_if<
+    std::is_integral<T>::value &&
+    !MxLogicalTy<T>::value &&
+    !MxCharTy<T>::value,
+    T>::type> : std::true_type {};
+/** Traits for arithmetic types.
+ */
+template <typename T, typename U = T>
+struct MxArithmeticTy : std::false_type {};
+template <typename T>
+struct MxArithmeticTy<T, typename std::enable_if<
+    (std::is_floating_point<T>::value) || (MxIntTy<T>::value),
+    T>::type> : std::true_type {};
+
+/**********************************************/
+/* Introducing traits for MATLAB array types. */
+/**********************************************/
+
+typedef struct mxNumeric_tag {} mxNumeric;
+typedef struct mxCell_tag    {} mxCell;
+typedef struct mxComplex_tag {} mxComplex;
+// mxLogical already defined in MATLAB (matrix.h).
+
+/** Traits for mxArray.
+ */
+template <typename T, typename U = T>
+struct MxTypes {
+  typedef T type;
+  typedef mxCell array_type;
+  static const mxClassID class_id = mxUNKNOWN_CLASS;
+  static const mxComplexity complexity = mxREAL;
+};
+
+template <typename T>
+struct MxTypes<T, typename std::enable_if<MxCharTy<T>::value, T>::type> {
+  typedef T type;
+  typedef mxChar array_type;
+  static const mxClassID class_id = mxCHAR_CLASS;
+  static const mxComplexity complexity = mxREAL;
+};
+
+template <typename T>
+struct MxTypes<T, typename std::enable_if<MxLogicalTy<T>::value, T>::type> {
+  typedef T type;
+  typedef mxLogical array_type;
+  static const mxClassID class_id = mxLOGICAL_CLASS;
+  static const mxComplexity complexity = mxREAL;
+};
+
+template <typename T>
+struct MxTypes<T, typename std::enable_if<std::is_signed<T>::value &&
+                                          MxIntTy<T>::value &&
+                                          sizeof(T) == 1, T>::type> {
+  typedef T type;
+  typedef mxNumeric array_type;
+  static const mxClassID class_id = mxINT8_CLASS;
+  static const mxComplexity complexity = mxREAL;
+};
+
+template <typename T>
+struct MxTypes<T, typename std::enable_if<std::is_unsigned<T>::value &&
+                                          MxIntTy<T>::value &&
+                                          sizeof(T) == 1, T>::type> {
+  typedef T type;
+  typedef mxNumeric array_type;
+  static const mxClassID class_id = mxUINT8_CLASS;
+  static const mxComplexity complexity = mxREAL;
+};
+
+template <typename T>
+struct MxTypes<T, typename std::enable_if<std::is_signed<T>::value &&
+                                          MxIntTy<T>::value &&
+                                          sizeof(T) == 2, T>::type> {
+  typedef T type;
+  typedef mxNumeric array_type;
+  static const mxClassID class_id = mxINT16_CLASS;
+  static const mxComplexity complexity = mxREAL;
+};
+
+template <typename T>
+struct MxTypes<T, typename std::enable_if<std::is_unsigned<T>::value &&
+                                          MxIntTy<T>::value &&
+                                          sizeof(T) == 2, T>::type> {
+  typedef T type;
+  typedef mxNumeric array_type;
+  static const mxClassID class_id = mxUINT16_CLASS;
+  static const mxComplexity complexity = mxREAL;
+};
+
+template <typename T>
+struct MxTypes<T, typename std::enable_if<std::is_signed<T>::value &&
+                                          MxIntTy<T>::value &&
+                                          sizeof(T) == 4, T>::type> {
+  typedef T type;
+  typedef mxNumeric array_type;
+  static const mxClassID class_id = mxINT32_CLASS;
+  static const mxComplexity complexity = mxREAL;
+};
+
+template <typename T>
+struct MxTypes<T, typename std::enable_if<std::is_unsigned<T>::value &&
+                                          MxIntTy<T>::value &&
+                                          sizeof(T) == 4, T>::type> {
+  typedef T type;
+  typedef mxNumeric array_type;
+  static const mxClassID class_id = mxUINT32_CLASS;
+  static const mxComplexity complexity = mxREAL;
+};
+
+template <typename T>
+struct MxTypes<T, typename std::enable_if<std::is_signed<T>::value &&
+                                          MxIntTy<T>::value &&
+                                          sizeof(T) == 8, T>::type> {
+  typedef T type;
+  typedef mxNumeric array_type;
+  static const mxClassID class_id = mxINT64_CLASS;
+  static const mxComplexity complexity = mxREAL;
+};
+
+template <typename T>
+struct MxTypes<T, typename std::enable_if<std::is_unsigned<T>::value &&
+                                          MxIntTy<T>::value &&
+                                          sizeof(T) == 8, T>::type> {
+  typedef T type;
+  typedef mxNumeric array_type;
+  static const mxClassID class_id = mxUINT64_CLASS;
+  static const mxComplexity complexity = mxREAL;
+};
+
+template <typename T>
+struct MxTypes<T, typename std::enable_if<std::is_floating_point<T>::value &&
+                                          sizeof(T) == 4, T>::type> {
+  typedef T type;
+  typedef mxNumeric array_type;
+  static const mxClassID class_id = mxSINGLE_CLASS;
+  static const mxComplexity complexity = mxREAL;
+};
+
+template <typename T>
+struct MxTypes<T, typename std::enable_if<std::is_floating_point<T>::value &&
+                                          sizeof(T) == 8, T>::type> {
+  typedef T type;
+  typedef mxNumeric array_type;
+  static const mxClassID class_id = mxDOUBLE_CLASS;
+  static const mxComplexity complexity = mxREAL;
+};
+
+template <typename T>
+struct MxTypes<T, typename std::enable_if<
+    std::is_same<typename std::remove_cv<T>::type,
+                 std::complex<float>>::value,
+                 T>::type> {
+  typedef T type;
+  typedef mxComplex array_type;
+  static const mxClassID class_id = mxSINGLE_CLASS;
+  static const mxComplexity complexity = mxCOMPLEX;
+};
+
+template <typename T>
+struct MxTypes<T, typename std::enable_if<
+    std::is_same<typename std::remove_cv<T>::type,
+                 std::complex<double>>::value,
+                 T>::type> {
+  typedef T type;
+  typedef mxComplex array_type;
+  static const mxClassID class_id = mxDOUBLE_CLASS;
+  static const mxComplexity complexity = mxCOMPLEX;
+};
+
+/********************************************/
+/* Type traits for function template usage. */
+/********************************************/
+
+/* Traits for logical types.
+ */
+template <typename T, typename U = T>
+struct MxLogicalType : std::false_type {};
+template<typename T>
+struct MxLogicalType<T, typename std::enable_if<
+    std::is_same<typename MxTypes<T>::array_type, mxLogical>::value,
+    T>::type> : std::true_type {};
+
+/* Traits for char types.
+ */
+template <typename T, typename U = T>
+struct MxCharType : std::false_type {};
+template<typename T>
+struct MxCharType<T, typename std::enable_if<
+    std::is_same<typename MxTypes<T>::array_type, mxChar>::value,
+    T>::type> : std::true_type {};
+
+/* Traits for arithmetic types.
+ */
+template <typename T, typename U = T>
+struct MxArithmeticType : std::false_type {};
+template<typename T>
+struct MxArithmeticType<T, typename std::enable_if<
+    std::is_same<typename MxTypes<T>::array_type, mxNumeric>::value,
+    T>::type> : std::true_type {};
+
+/* Traits for complex types.
+ */
+template <typename T, typename U = T>
+struct MxComplexType : std::false_type {};
+template<typename T>
+struct MxComplexType<T, typename std::enable_if<
+    std::is_same<typename MxTypes<T>::array_type, mxComplex>::value,
+    T>::type> : std::true_type {};
+
+/* Traits for complex or arithmetic types.
+ */
+template <typename T, typename U = T>
+struct MxComplexOrArithmeticType : std::false_type {};
+template <typename T>
+struct MxComplexOrArithmeticType<T, typename std::enable_if<
+    MxComplexType<T>::value,
+    T>::type> : std::true_type {};
+template <typename T>
+struct MxComplexOrArithmeticType<T, typename std::enable_if<
+    MxArithmeticTy<T>::value,
+    T>::type> : std::true_type {};
+
+/* Traits for cell types.
+ */
+template <typename T, typename U = T>
+struct MxCellType : std::false_type {};
+template <typename T>
+struct MxCellType<T, typename std::enable_if<
+    std::is_same<typename MxTypes<T>::array_type, mxCell>::value,
+    T>::type> : std::true_type {};
+
+/* Traits for logical type compounds.
+ */
+template <typename T, typename U = T>
+struct MxLogicalCompound : std::false_type {};
+template <typename T>
+struct MxLogicalCompound<T, typename std::enable_if<
+    MxLogicalType<typename T::value_type>::value,
+    T>::type> : std::true_type {};
+
+/* Traits for char type compounds.
+ */
+template <typename T, typename U = T>
+struct MxCharCompound : std::false_type {};
+template <typename T>
+struct MxCharCompound<T, typename std::enable_if<
+    MxCharType<typename T::value_type>::value,
+    T>::type> : std::true_type {};
+
+/* Traits for arithmetic type compounds.
+ */
+template <typename T, typename U = T>
+struct MxArithmeticCompound : std::false_type {};
+template <typename T>
+struct MxArithmeticCompound<T, typename std::enable_if<
+    (MxArithmeticType<typename T::value_type>::value) &&
+    !(MxComplexType<T>::value),
+    T>::type> : std::true_type {};
+
+/* Traits for complex type compounds.
+ */
+template <typename T, typename U = T>
+struct MxComplexCompound : std::false_type {};
+template <typename T>
+struct MxComplexCompound<T, typename std::enable_if<
+    MxComplexType<typename T::value_type>::value,
+    T>::type> : std::true_type {};
+
+/* Traits for complex or arithmetic type compounds.
+ */
+template <typename T, typename U = T>
+struct MxComplexOrArithmeticCompound : std::false_type {};
+template <typename T>
+struct MxComplexOrArithmeticCompound<T, typename std::enable_if<
+    MxComplexCompound<T>::value ||
+    MxArithmeticCompound<T>::value,
+    T>::type> : std::true_type {};
+
+/* Traits for cell compounds.
+ */
+template <typename T, typename U = T>
+struct MxCellCompound : std::false_type {};
+template <typename T>
+struct MxCellCompound<T, typename std::enable_if<
+    MxCellType<typename T::value_type>::value,
+    T>::type> : std::true_type {};
+
+}  // namespace mexplus
+
+#endif  // INCLUDE_MEXPLUS_MXTYPES_H_
diff --git a/wrapper_matlab/run_demo.m b/wrapper_matlab/run_demo.m
new file mode 100644
index 0000000000000000000000000000000000000000..e27174dfa82de5f47c9b8d68efeb5fb6ddcb3e16
--- /dev/null
+++ b/wrapper_matlab/run_demo.m
@@ -0,0 +1,49 @@
+%% Compile the BGSLibrary wrapper
+compile;
+
+%% Run demo
+demo;
+
+%% Run a specific algorithm
+demo('FrameDifference')
+% demo('StaticFrameDifference')
+% demo('WeightedMovingMean')
+% demo('WeightedMovingVariance')
+% demo('MixtureOfGaussianV1') % only for OpenCV 2.x
+% demo('MixtureOfGaussianV2')
+% demo('AdaptiveBackgroundLearning')
+% demo('AdaptiveSelectiveBackgroundLearning')
+% demo('GMG') % only on OpenCV >= 2.4.3
+% demo('KNN') % only on OpenCV 3.x
+% demo('DPAdaptiveMedian')
+% demo('DPGrimsonGMM')
+% demo('DPZivkovicAGMM')
+% demo('DPMean')
+% demo('DPWrenGA')
+% demo('DPPratiMediod')
+% demo('DPEigenbackground')
+% demo('DPTexture')
+% demo('T2FGMM_UM')
+% demo('T2FGMM_UV')
+% demo('T2FMRF_UM')
+% demo('T2FMRF_UV')
+% demo('FuzzySugenoIntegral')
+% demo('FuzzyChoquetIntegral')
+% demo('LBSimpleGaussian')
+% demo('LBFuzzyGaussian')
+% demo('LBMixtureOfGaussians')
+% demo('LBAdaptiveSOM')
+% demo('LBFuzzyAdaptiveSOM')
+% demo('LBP_MRF')
+% demo('MultiLayer')
+% demo('PixelBasedAdaptiveSegmenter')
+% demo('VuMeter')
+% demo('KDE')
+% demo('IndependentMultimodal')
+% demo('MultiCue')
+% demo('SigmaDelta')
+% demo('SuBSENSE')
+% demo('LOBSTER')
+% demo('PAWCS')
+% demo('TwoPoints')
+% demo('ViBe')
\ No newline at end of file
diff --git a/wrapper_python/bgslibrary_module.cpp b/wrapper_python/bgslibrary_module.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..edb75a8552bbc29d4e27ef72485d7859e38851c8
--- /dev/null
+++ b/wrapper_python/bgslibrary_module.cpp
@@ -0,0 +1,265 @@
+/*
+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 <boost/python.hpp>
+#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
+#include <exception>
+
+#include <opencv2/opencv.hpp>
+#include "np_opencv_converter.h"
+
+#include "../package_bgs/bgslibrary.h"
+
+namespace py = boost::python;
+
+cv::Mat test_transpose(const cv::Mat& in)
+{
+	std::cerr << "Input size: " << in.size() << std::endl;
+	std::cerr << "Returning transpose" << std::endl;
+	return in.t();
+}
+
+namespace fs 
+{ 
+	namespace python 
+	{
+		BOOST_PYTHON_MODULE(libbgs)
+		{
+			// Main types export
+			fs::python::init_and_export_converters();
+			py::scope scope = py::scope();
+			
+			// Basic test
+			py::def("test_transpose", &test_transpose);
+			
+			py::class_<FrameDifference>("FrameDifference")
+			.def("apply", &FrameDifference::apply)
+			.def("getBackgroundModel", &FrameDifference::getBackgroundModel)
+			;
+
+			py::class_<StaticFrameDifference>("StaticFrameDifference")
+				.def("apply", &StaticFrameDifference::apply)
+				.def("getBackgroundModel", &StaticFrameDifference::getBackgroundModel)
+				;
+
+			py::class_<AdaptiveBackgroundLearning>("AdaptiveBackgroundLearning")
+				.def("apply", &AdaptiveBackgroundLearning::apply)
+				.def("getBackgroundModel", &AdaptiveBackgroundLearning::getBackgroundModel)
+				;
+
+			py::class_<AdaptiveSelectiveBackgroundLearning>("AdaptiveSelectiveBackgroundLearning")
+				.def("apply", &AdaptiveSelectiveBackgroundLearning::apply)
+				.def("getBackgroundModel", &AdaptiveSelectiveBackgroundLearning::getBackgroundModel)
+				;
+
+			py::class_<DPAdaptiveMedian>("DPAdaptiveMedian")
+				.def("apply", &DPAdaptiveMedian::apply)
+				.def("getBackgroundModel", &DPAdaptiveMedian::getBackgroundModel)
+				;
+
+			py::class_<DPEigenbackground>("DPEigenbackground")
+				.def("apply", &DPEigenbackground::apply)
+				.def("getBackgroundModel", &DPEigenbackground::getBackgroundModel)
+				;
+
+			py::class_<DPGrimsonGMM>("DPGrimsonGMM")
+				.def("apply", &DPGrimsonGMM::apply)
+				.def("getBackgroundModel", &DPGrimsonGMM::getBackgroundModel)
+				;
+
+			py::class_<DPMean>("DPMean")
+				.def("apply", &DPMean::apply)
+				.def("getBackgroundModel", &DPMean::getBackgroundModel)
+				;
+
+			py::class_<DPPratiMediod>("DPPratiMediod")
+				.def("apply", &DPPratiMediod::apply)
+				.def("getBackgroundModel", &DPPratiMediod::getBackgroundModel)
+				;
+
+			py::class_<DPTexture>("DPTexture")
+				.def("apply", &DPTexture::apply)
+				.def("getBackgroundModel", &DPTexture::getBackgroundModel)
+				;
+
+			py::class_<DPWrenGA>("DPWrenGA")
+				.def("apply", &DPWrenGA::apply)
+				.def("getBackgroundModel", &DPWrenGA::getBackgroundModel)
+				;
+
+			py::class_<DPZivkovicAGMM>("DPZivkovicAGMM")
+				.def("apply", &DPZivkovicAGMM::apply)
+				.def("getBackgroundModel", &DPZivkovicAGMM::getBackgroundModel)
+				;
+
+			py::class_<FuzzyChoquetIntegral>("FuzzyChoquetIntegral")
+				.def("apply", &FuzzyChoquetIntegral::apply)
+				.def("getBackgroundModel", &FuzzyChoquetIntegral::getBackgroundModel)
+				;
+
+			py::class_<FuzzySugenoIntegral>("FuzzySugenoIntegral")
+				.def("apply", &FuzzySugenoIntegral::apply)
+				.def("getBackgroundModel", &FuzzySugenoIntegral::getBackgroundModel)
+				;
+
+#if CV_MAJOR_VERSION == 2
+			py::class_<GMG>("GMG")
+				.def("apply", &GMG::apply)
+				.def("getBackgroundModel", &GMG::getBackgroundModel)
+				;
+#endif
+
+			py::class_<IndependentMultimodal>("IndependentMultimodal")
+				.def("apply", &IndependentMultimodal::apply)
+				.def("getBackgroundModel", &IndependentMultimodal::getBackgroundModel)
+				;
+
+			py::class_<KDE>("KDE")
+				.def("apply", &KDE::apply)
+				.def("getBackgroundModel", &KDE::getBackgroundModel)
+				;
+
+#if CV_MAJOR_VERSION == 3
+			py::class_<KNN>("KNN")
+				.def("apply", &KNN::apply)
+				.def("getBackgroundModel", &KNN::getBackgroundModel)
+				;
+#endif
+
+			py::class_<LBAdaptiveSOM>("LBAdaptiveSOM")
+				.def("apply", &LBAdaptiveSOM::apply)
+				.def("getBackgroundModel", &LBAdaptiveSOM::getBackgroundModel)
+				;
+
+			py::class_<LBFuzzyAdaptiveSOM>("LBFuzzyAdaptiveSOM")
+				.def("apply", &LBFuzzyAdaptiveSOM::apply)
+				.def("getBackgroundModel", &LBFuzzyAdaptiveSOM::getBackgroundModel)
+				;
+
+			py::class_<LBFuzzyGaussian>("LBFuzzyGaussian")
+				.def("apply", &LBFuzzyGaussian::apply)
+				.def("getBackgroundModel", &LBFuzzyGaussian::getBackgroundModel)
+				;
+
+			py::class_<LBMixtureOfGaussians>("LBMixtureOfGaussians")
+				.def("apply", &LBMixtureOfGaussians::apply)
+				.def("getBackgroundModel", &LBMixtureOfGaussians::getBackgroundModel)
+				;
+
+			py::class_<LBSimpleGaussian>("LBSimpleGaussian")
+				.def("apply", &LBSimpleGaussian::apply)
+				.def("getBackgroundModel", &LBSimpleGaussian::getBackgroundModel)
+				;
+
+			py::class_<LBP_MRF>("LBP_MRF")
+				.def("apply", &LBP_MRF::apply)
+				.def("getBackgroundModel", &LBP_MRF::getBackgroundModel)
+				;
+
+			py::class_<LOBSTER>("LOBSTER")
+				.def("apply", &LOBSTER::apply)
+				.def("getBackgroundModel", &LOBSTER::getBackgroundModel)
+				;
+
+#if CV_MAJOR_VERSION == 2
+			py::class_<MixtureOfGaussianV1>("MixtureOfGaussianV1")
+				.def("apply", &MixtureOfGaussianV1::apply)
+				.def("getBackgroundModel", &MixtureOfGaussianV1::getBackgroundModel)
+				;
+#endif
+
+			py::class_<MixtureOfGaussianV2>("MixtureOfGaussianV2")
+				.def("apply", &MixtureOfGaussianV2::apply)
+				.def("getBackgroundModel", &MixtureOfGaussianV2::getBackgroundModel)
+				;
+
+			py::class_<MultiCue>("MultiCue")
+				.def("apply", &MultiCue::apply)
+				.def("getBackgroundModel", &MultiCue::getBackgroundModel)
+				;
+
+			py::class_<MultiLayer>("MultiLayer")
+				.def("apply", &MultiLayer::apply)
+				.def("getBackgroundModel", &MultiLayer::getBackgroundModel)
+				;
+
+			py::class_<PAWCS>("PAWCS")
+				.def("apply", &PAWCS::apply)
+				.def("getBackgroundModel", &PAWCS::getBackgroundModel)
+				;
+
+			py::class_<PixelBasedAdaptiveSegmenter>("PixelBasedAdaptiveSegmenter")
+				.def("apply", &PixelBasedAdaptiveSegmenter::apply)
+				.def("getBackgroundModel", &PixelBasedAdaptiveSegmenter::getBackgroundModel)
+				;
+
+			py::class_<SigmaDelta>("SigmaDelta")
+				.def("apply", &SigmaDelta::apply)
+				.def("getBackgroundModel", &SigmaDelta::getBackgroundModel)
+				;
+
+			py::class_<SuBSENSE>("SuBSENSE")
+				.def("apply", &SuBSENSE::apply)
+				.def("getBackgroundModel", &SuBSENSE::getBackgroundModel)
+				;
+
+			py::class_<T2FGMM_UM>("T2FGMM_UM")
+				.def("apply", &T2FGMM_UM::apply)
+				.def("getBackgroundModel", &T2FGMM_UM::getBackgroundModel)
+				;
+
+			py::class_<T2FGMM_UV>("T2FGMM_UV")
+				.def("apply", &T2FGMM_UV::apply)
+				.def("getBackgroundModel", &T2FGMM_UV::getBackgroundModel)
+				;
+
+			py::class_<T2FMRF_UM>("T2FMRF_UM")
+				.def("apply", &T2FMRF_UM::apply)
+				.def("getBackgroundModel", &T2FMRF_UM::getBackgroundModel)
+				;
+
+			py::class_<T2FMRF_UV>("T2FMRF_UV")
+				.def("apply", &T2FMRF_UV::apply)
+				.def("getBackgroundModel", &T2FMRF_UV::getBackgroundModel)
+				;
+
+			py::class_<VuMeter>("VuMeter")
+				.def("apply", &VuMeter::apply)
+				.def("getBackgroundModel", &VuMeter::getBackgroundModel)
+				;
+
+			py::class_<WeightedMovingMean>("WeightedMovingMean")
+				.def("apply", &WeightedMovingMean::apply)
+				.def("getBackgroundModel", &WeightedMovingMean::getBackgroundModel)
+				;
+
+			py::class_<WeightedMovingVariance>("WeightedMovingVariance")
+				.def("apply", &WeightedMovingVariance::apply)
+				.def("getBackgroundModel", &WeightedMovingVariance::getBackgroundModel)
+				;
+
+			py::class_<TwoPoints>("TwoPoints")
+				.def("apply", &TwoPoints::apply)
+				.def("getBackgroundModel", &TwoPoints::getBackgroundModel)
+				;
+
+			py::class_<ViBe>("ViBe")
+				.def("apply", &ViBe::apply)
+				.def("getBackgroundModel", &ViBe::getBackgroundModel)
+				;
+		}
+	} // namespace fs
+} // namespace python
diff --git a/wrapper_python/np_opencv_converter.cpp b/wrapper_python/np_opencv_converter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6050f6b40e5815670d2f2f8383381642ee2fd413
--- /dev/null
+++ b/wrapper_python/np_opencv_converter.cpp
@@ -0,0 +1,103 @@
+/*
+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 "np_opencv_converter.h"
+
+namespace fs { namespace python {
+
+// Static PyInit
+static void py_init() {
+  Py_Initialize();
+  import_array();
+}
+
+// Singleton init and export converters
+static bool export_type_conversions_once = false;
+bool init_and_export_converters() {
+
+  if (export_type_conversions_once)
+    return false;
+  
+  std::cerr << "PYTHON TYPE CONVERTERS exported" << std::endl;
+  export_type_conversions_once = true;
+
+  // Py_Init and array import
+  py_init();
+  
+  // => py::list
+  expose_template_type<int>();
+  expose_template_type<float>();
+  expose_template_type<double>();
+
+  // std::vector => py::list
+  expose_template_type< std::vector<int> >();
+  expose_template_type< std::vector<float> >();
+  expose_template_type< std::vector<double> >();
+
+  expose_template_type< std::vector<cv::Point> >();
+  expose_template_type< std::vector<cv::Point2f> >();
+  expose_template_type< std::vector<cv::KeyPoint> >();
+  
+  expose_template_type< std::vector<cv::Mat> >();
+  expose_template_type< std::vector<cv::Mat1b > >();
+  expose_template_type< std::vector<cv::Mat1f > >();
+
+  // std::map => py::dict
+  expose_template_type<std::map<int, std::vector<int> > >();
+  expose_template_type<std::map<int, std::vector<float> > >();
+  expose_template_type<std::map<std::string, float> >();
+
+  // various converters to cv::Mat
+  py::to_python_converter<cv::Point, Point_to_mat>();
+  py::to_python_converter<cv::Point2f, Point2f_to_mat>();
+  py::to_python_converter<cv::Point3f, Point3f_to_mat>();
+  py::to_python_converter<cv::Vec3f, Vec3f_to_mat>();
+
+  // register the to-from-python converter for each of the types
+  Mat_PyObject_converter< cv::Mat >();
+  
+  // 1-channel
+  Mat_PyObject_converter< cv::Mat1b >();
+  Mat_PyObject_converter< cv::Mat1s >();
+  Mat_PyObject_converter< cv::Mat1w >();
+  Mat_PyObject_converter< cv::Mat1i >();
+  Mat_PyObject_converter< cv::Mat1f >();
+  Mat_PyObject_converter< cv::Mat1d >();
+
+  // 2-channel
+  Mat_PyObject_converter< cv::Mat2b >();
+  Mat_PyObject_converter< cv::Mat2s >();
+  Mat_PyObject_converter< cv::Mat2w >();
+  Mat_PyObject_converter< cv::Mat2i >();
+  Mat_PyObject_converter< cv::Mat2f >();
+  Mat_PyObject_converter< cv::Mat2d >();
+
+  // 3-channel
+  Mat_PyObject_converter< cv::Mat3b >();
+  Mat_PyObject_converter< cv::Mat3s >();
+  Mat_PyObject_converter< cv::Mat3w >();
+  Mat_PyObject_converter< cv::Mat3i >();
+  Mat_PyObject_converter< cv::Mat3f >();
+  Mat_PyObject_converter< cv::Mat3d >();
+
+  // add more if needed
+
+  return true;
+}
+
+} // namespace python
+} // namespace fs
+
diff --git a/wrapper_python/np_opencv_converter.h b/wrapper_python/np_opencv_converter.h
new file mode 100644
index 0000000000000000000000000000000000000000..68386f0f16c8855ff0c0b7c74dac2a58ea9b6438
--- /dev/null
+++ b/wrapper_python/np_opencv_converter.h
@@ -0,0 +1,122 @@
+/*
+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
+
+#include <boost/python.hpp>
+#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
+
+#include "utils/template.h"
+#include "utils/container.h"
+#include "utils/conversion.h"
+
+#include <opencv2/opencv.hpp>
+
+namespace fs { namespace python {
+
+// TODO: Template these
+// Vec3f => cv::Mat
+struct Vec3f_to_mat {
+  static PyObject* convert(const cv::Vec3f& v){
+    NDArrayConverter cvt;
+    PyObject* ret = cvt.toNDArray(cv::Mat(v));
+    return ret;
+  }
+};
+
+// cv::Point => cv::Mat
+struct Point_to_mat {
+  static PyObject* convert(const cv::Point& v){
+    NDArrayConverter cvt;
+    PyObject* ret = cvt.toNDArray(cv::Mat(v));
+    return ret;
+  }
+};
+
+// cv::Point2f => cv::Mat
+struct Point2f_to_mat {
+  static PyObject* convert(const cv::Point2f& v){
+    NDArrayConverter cvt;
+    PyObject* ret = cvt.toNDArray(cv::Mat(v));
+    return ret;
+  }
+};
+
+// cv::Point3f => cv::Mat
+struct Point3f_to_mat {
+  static PyObject* convert(const cv::Point3f& v){
+    NDArrayConverter cvt;
+    PyObject* ret = cvt.toNDArray(cv::Mat(v));
+    return ret;
+  }
+};
+
+// cv::Mat_<T> => Numpy PyObject
+template <typename T>
+struct Mat_to_PyObject {
+  static PyObject* convert(const T& mat){
+    NDArrayConverter cvt;
+    PyObject* ret = cvt.toNDArray(mat);
+    return ret;
+  }
+};
+
+// Generic templated cv::Mat <=> Numpy PyObject converter
+template <typename T>
+struct Mat_PyObject_converter
+{
+  // Register from converter
+  Mat_PyObject_converter() {
+    boost::python::converter::registry::push_back(
+        &convertible,
+        &construct,
+        boost::python::type_id<T>());
+
+    // Register to converter
+    py::to_python_converter<T, Mat_to_PyObject<T> >();
+  }
+
+  // Convert from type T to PyObject (numpy array)
+  // Assume obj_ptr can be converted in a cv::Mat
+  static void* convertible(PyObject* obj_ptr)
+  {
+    // Check validity? 
+    assert(obj_ptr != 0); 
+    return obj_ptr;
+  }
+
+  // Convert obj_ptr into a cv::Mat
+  static void construct(PyObject* obj_ptr,
+                        boost::python::converter::rvalue_from_python_stage1_data* data)
+  {
+    using namespace boost::python;
+    typedef converter::rvalue_from_python_storage< T > storage_t;
+
+    storage_t* the_storage = reinterpret_cast<storage_t*>( data );
+    void* memory_chunk = the_storage->storage.bytes;
+
+    NDArrayConverter cvt;
+    T* newvec = new (memory_chunk) T(cvt.toMat(obj_ptr));
+    data->convertible = memory_chunk;
+
+    return;
+  }
+};
+
+bool init_and_export_converters();
+
+} // namespace python
+} // namespace fs
diff --git a/wrapper_python/utils/container.h b/wrapper_python/utils/container.h
new file mode 100644
index 0000000000000000000000000000000000000000..3db5613a9e4a1f694fbbf008c2c0c6d0913eb730
--- /dev/null
+++ b/wrapper_python/utils/container.h
@@ -0,0 +1,208 @@
+/*
+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/>.
+*/
+// Author: Sudeep Pillai (spillai@csail.mit.edu)
+// Note: Stripped from pyxx project
+
+#pragma once
+
+#include <boost/python.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/module.hpp>
+#include <boost/foreach.hpp>
+
+#include <vector>
+#include <string>
+#include <stdexcept>
+#include <iostream>
+#include <map>
+#include <list>
+
+namespace py = boost::python;
+
+template<typename T>
+struct expose_template_type< std::vector<T> > :
+    public expose_template_type_base< std::vector<T> >
+{
+  typedef expose_template_type_base< std::vector<T> > base_type;
+  typedef expose_template_type< std::vector<T> > this_type;
+  typedef std::vector<T> wrapped_type;
+
+  expose_template_type()
+  {
+    ::expose_template_type<T>();
+    if( !base_type::wrapped() )
+    {
+      py::to_python_converter< wrapped_type, this_type >();
+      py::converter::registry::push_back(
+          this_type::convertible,
+          this_type::construct,
+          py::type_id< wrapped_type >() );
+ 
+    }
+  }
+
+  static PyObject * convert( const wrapped_type & container)
+  {
+    py::list l;
+    for(typename wrapped_type::const_iterator iter = container.begin(); iter != container.end(); iter++)
+    {
+      l.append( py::object( *iter ) );
+    }
+    Py_INCREF( l.ptr() );
+    return l.ptr();
+  }
+
+  static void * convertible( PyObject * py_obj)
+  {
+    // we are supposed to indicate whether or not we can convert this
+    // we don't really know, but we'll try any sequence
+    if( PySequence_Check(py_obj) )
+      return py_obj;
+    return 0;
+  }
+    
+  static void construct( PyObject * py_obj, py::converter::rvalue_from_python_stage1_data* data)
+  {
+    using namespace boost::python;
+    typedef converter::rvalue_from_python_storage< wrapped_type > storage_t;
+        
+    storage_t* the_storage = reinterpret_cast<storage_t*>( data );
+    void* memory_chunk = the_storage->storage.bytes;
+    wrapped_type * newvec = new (memory_chunk) wrapped_type;
+    data->convertible = memory_chunk;
+
+    object sequence(handle<>( borrowed( py_obj ) ) );
+
+    for(int idx = 0; idx < len(sequence);idx++)
+    {
+      newvec->push_back( extract<T>( sequence[idx] )() );
+    }
+
+  }
+
+};
+
+template<typename Key, typename Value>
+    struct expose_template_type< std::map<Key, Value> > :
+    public expose_template_type_base< std::map<Key, Value> >
+{
+  typedef std::map<Key, Value> wrapped_type;
+  typedef expose_template_type_base< wrapped_type > base_type;
+  typedef expose_template_type< wrapped_type > this_type;
+
+  expose_template_type()
+  {
+    if( !base_type::wrapped() )
+    {
+      py::to_python_converter< wrapped_type, this_type >();
+      py::converter::registry::push_back(
+          this_type::convertible,
+          this_type::construct,
+          py::type_id< wrapped_type >() );
+ 
+    }
+  }
+
+  static PyObject * convert( const wrapped_type & container)
+  {
+    py::dict d;
+    for(typename wrapped_type::const_iterator iter = container.begin(); iter != container.end(); iter++)
+    {
+      d[iter->first] = py::object(iter->second);
+    }
+    Py_INCREF( d.ptr() );
+    return d.ptr();
+  }
+
+  static void * convertible( PyObject * py_obj)
+  {
+    // we are supposed to indicate whether or not we can convert this
+    // we don't really know, but we'll try any sequence
+    if( PyMapping_Check(py_obj) )
+      return py_obj;
+    return 0;
+  }
+    
+  static void construct( PyObject * py_obj, py::converter::rvalue_from_python_stage1_data* data)
+  {
+    using namespace boost::python;
+    typedef converter::rvalue_from_python_storage< wrapped_type > storage_t;
+        
+    storage_t* the_storage = reinterpret_cast<storage_t*>( data );
+    void* memory_chunk = the_storage->storage.bytes;
+    wrapped_type * newvec = new (memory_chunk) wrapped_type;
+    data->convertible = memory_chunk;
+
+    object sequence(handle<>( borrowed( py_obj ) ) );
+    sequence = sequence.attr("items")();
+
+    for(int idx = 0; idx < len(sequence);idx++)
+    {
+      Key key = py::extract<Key>(sequence[idx][0])();
+      Value value = py::extract<Value>(sequence[idx][1])();
+      (*newvec)[key] = value;
+    }
+
+  }
+
+};
+
+template<typename Key, typename Value>
+    struct expose_template_type< typename std::pair<Key, Value> > :
+    public expose_template_type_base< std::pair<Key, Value> >
+{
+  typedef std::pair<Key, Value> wrapped_type;
+  typedef expose_template_type_base< wrapped_type > base_type;
+  typedef expose_template_type< wrapped_type > this_type;
+
+  expose_template_type()
+  {
+    if( !base_type::wrapped() )
+    {
+      py::converter::registry::push_back(
+          this_type::convertible,
+          this_type::construct,
+          py::type_id< wrapped_type >() );
+ 
+    }
+  }
+
+  static void * convertible( PyObject * py_obj)
+  {
+    // we are supposed to indicate whether or not we can convert this
+    // we don't really know, but we'll try any sequence
+    if( PyTuple_Check(py_obj) && PyTuple_Size(py_obj) == 2)
+      return py_obj;
+    return 0;
+  }
+    
+  static void construct( PyObject * py_obj, py::converter::rvalue_from_python_stage1_data* data)
+  {
+    using namespace boost::python;
+    typedef converter::rvalue_from_python_storage< wrapped_type > storage_t;
+        
+    storage_t* the_storage = reinterpret_cast<storage_t*>( data );
+    void* memory_chunk = the_storage->storage.bytes;
+    wrapped_type * newvec = new (memory_chunk) wrapped_type;
+    data->convertible = memory_chunk;
+
+    object sequence(handle<>( borrowed( py_obj ) ) );
+    newvec->first = extract<Key>(sequence[0])();
+    newvec->second = extract<Value>(sequence[1])();
+  }
+
+};
diff --git a/wrapper_python/utils/conversion.cpp b/wrapper_python/utils/conversion.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7ca21dd59b201947fb16ff6bf60c18a04073998e
--- /dev/null
+++ b/wrapper_python/utils/conversion.cpp
@@ -0,0 +1,349 @@
+/*
+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/>.
+*/
+// Author: Sudeep Pillai (spillai@csail.mit.edu)
+// Note: Stripped from Opencv (opencv/modules/python/src2/cv2.cpp)
+
+# include "conversion.h"
+/*
+ * The following conversion functions are taken/adapted from OpenCV's cv2.cpp file
+ * inside modules/python/src2 folder.
+ */
+
+static void init()
+{
+    import_array();
+}
+
+static int failmsg(const char *fmt, ...)
+{
+    char str[1000];
+
+    va_list ap;
+    va_start(ap, fmt);
+    vsnprintf(str, sizeof(str), fmt, ap);
+    va_end(ap);
+
+    PyErr_SetString(PyExc_TypeError, str);
+    return 0;
+}
+
+class PyAllowThreads
+{
+public:
+    PyAllowThreads() : _state(PyEval_SaveThread()) {}
+    ~PyAllowThreads()
+    {
+        PyEval_RestoreThread(_state);
+    }
+private:
+    PyThreadState* _state;
+};
+
+class PyEnsureGIL
+{
+public:
+    PyEnsureGIL() : _state(PyGILState_Ensure()) {}
+    ~PyEnsureGIL()
+    {
+        PyGILState_Release(_state);
+    }
+private:
+    PyGILState_STATE _state;
+};
+
+using namespace cv;
+static PyObject* failmsgp(const char *fmt, ...)
+{
+  char str[1000];
+
+  va_list ap;
+  va_start(ap, fmt);
+  vsnprintf(str, sizeof(str), fmt, ap);
+  va_end(ap);
+
+  PyErr_SetString(PyExc_TypeError, str);
+  return 0;
+}
+
+#define OPENCV_3 0
+#if OPENCV_3
+class NumpyAllocator : public MatAllocator
+{
+public:
+    NumpyAllocator() { stdAllocator = Mat::getStdAllocator(); }
+    ~NumpyAllocator() {}
+
+    UMatData* allocate(PyObject* o, int dims, const int* sizes, int type, size_t* step) const
+    {
+        UMatData* u = new UMatData(this);
+        u->data = u->origdata = (uchar*)PyArray_DATA((PyArrayObject*) o);
+        npy_intp* _strides = PyArray_STRIDES((PyArrayObject*) o);
+        for( int i = 0; i < dims - 1; i++ )
+            step[i] = (size_t)_strides[i];
+        step[dims-1] = CV_ELEM_SIZE(type);
+        u->size = sizes[0]*step[0];
+        u->userdata = o;
+        return u;
+    }
+
+    UMatData* allocate(int dims0, const int* sizes, int type, void* data, size_t* step, int flags) const
+    {
+        if( data != 0 )
+        {
+            CV_Error(Error::StsAssert, "The data should normally be NULL!");
+            // probably this is safe to do in such extreme case
+            return stdAllocator->allocate(dims0, sizes, type, data, step, flags);
+        }
+        PyEnsureGIL gil;
+
+        int depth = CV_MAT_DEPTH(type);
+        int cn = CV_MAT_CN(type);
+        const int f = (int)(sizeof(size_t)/8);
+        int typenum = depth == CV_8U ? NPY_UBYTE : depth == CV_8S ? NPY_BYTE :
+        depth == CV_16U ? NPY_USHORT : depth == CV_16S ? NPY_SHORT :
+        depth == CV_32S ? NPY_INT : depth == CV_32F ? NPY_FLOAT :
+        depth == CV_64F ? NPY_DOUBLE : f*NPY_ULONGLONG + (f^1)*NPY_UINT;
+        int i, dims = dims0;
+        cv::AutoBuffer<npy_intp> _sizes(dims + 1);
+        for( i = 0; i < dims; i++ )
+            _sizes[i] = sizes[i];
+        if( cn > 1 )
+            _sizes[dims++] = cn;
+        PyObject* o = PyArray_SimpleNew(dims, _sizes, typenum);
+        if(!o)
+            CV_Error_(Error::StsError, ("The numpy array of typenum=%d, ndims=%d can not be created", typenum, dims));
+        return allocate(o, dims0, sizes, type, step);
+    }
+
+    bool allocate(UMatData* u, int accessFlags) const
+    {
+        return stdAllocator->allocate(u, accessFlags);
+    }
+
+    void deallocate(UMatData* u) const
+    {
+        if(u)
+        {
+            PyEnsureGIL gil;
+            PyObject* o = (PyObject*)u->userdata;
+            Py_XDECREF(o);
+            delete u;
+        }
+    }
+ 
+    const MatAllocator* stdAllocator;
+};
+#else
+class NumpyAllocator : public MatAllocator
+{
+public:
+    NumpyAllocator() {}
+    ~NumpyAllocator() {}
+
+    void allocate(int dims, const int* sizes, int type, int*& refcount,
+                  uchar*& datastart, uchar*& data, size_t* step)
+    {
+        PyEnsureGIL gil;
+
+        int depth = CV_MAT_DEPTH(type);
+        int cn = CV_MAT_CN(type);
+        const int f = (int)(sizeof(size_t)/8);
+        int typenum = depth == CV_8U ? NPY_UBYTE : depth == CV_8S ? NPY_BYTE :
+                      depth == CV_16U ? NPY_USHORT : depth == CV_16S ? NPY_SHORT :
+                      depth == CV_32S ? NPY_INT : depth == CV_32F ? NPY_FLOAT :
+                      depth == CV_64F ? NPY_DOUBLE : f*NPY_ULONGLONG + (f^1)*NPY_UINT;
+        int i;
+        npy_intp _sizes[CV_MAX_DIM+1];
+        for( i = 0; i < dims; i++ )
+            _sizes[i] = sizes[i];
+        if( cn > 1 )
+        {
+            /*if( _sizes[dims-1] == 1 )
+                _sizes[dims-1] = cn;
+            else*/
+                _sizes[dims++] = cn;
+        }
+        PyObject* o = PyArray_SimpleNew(dims, _sizes, typenum);
+        if(!o)
+            CV_Error_(CV_StsError, ("The numpy array of typenum=%d, ndims=%d can not be created", typenum, dims));
+        refcount = refcountFromPyObject(o);
+        npy_intp* _strides = PyArray_STRIDES((PyArrayObject*) o);
+        for( i = 0; i < dims - (cn > 1); i++ )
+            step[i] = (size_t)_strides[i];
+        datastart = data = (uchar*)PyArray_DATA((PyArrayObject*) o);
+    }
+
+    void deallocate(int* refcount, uchar*, uchar*)
+    {
+        PyEnsureGIL gil;
+        if( !refcount )
+            return;
+        PyObject* o = pyObjectFromRefcount(refcount);
+        Py_INCREF(o);
+        Py_DECREF(o);
+    }
+};
+#endif
+  
+
+  
+NumpyAllocator g_numpyAllocator;
+
+NDArrayConverter::NDArrayConverter() { init(); }
+
+void NDArrayConverter::init()
+{
+    import_array();
+}
+
+cv::Mat NDArrayConverter::toMat(const PyObject *o)
+{
+    cv::Mat m;
+
+    if(!o || o == Py_None)
+    {
+        if( !m.data )
+            m.allocator = &g_numpyAllocator;
+    }
+
+    if( !PyArray_Check(o) )
+    {
+        failmsg("toMat: Object is not a numpy array");
+    }
+
+    int typenum = PyArray_TYPE(o);
+    int type = typenum == NPY_UBYTE ? CV_8U : typenum == NPY_BYTE ? CV_8S :
+               typenum == NPY_USHORT ? CV_16U : typenum == NPY_SHORT ? CV_16S :
+               typenum == NPY_INT || typenum == NPY_LONG ? CV_32S :
+               typenum == NPY_FLOAT ? CV_32F :
+               typenum == NPY_DOUBLE ? CV_64F : -1;
+
+    if( type < 0 )
+    {
+        failmsg("toMat: Data type = %d is not supported", typenum);
+    }
+
+    int ndims = PyArray_NDIM(o);
+
+    if(ndims >= CV_MAX_DIM)
+    {
+        failmsg("toMat: Dimensionality (=%d) is too high", ndims);
+    }
+
+    int size[CV_MAX_DIM+1];
+    size_t step[CV_MAX_DIM+1], elemsize = CV_ELEM_SIZE1(type);
+    const npy_intp* _sizes = PyArray_DIMS(o);
+    const npy_intp* _strides = PyArray_STRIDES(o);
+    bool transposed = false;
+    
+    for(int i = 0; i < ndims; i++)
+    {
+        size[i] = (int)_sizes[i];
+        step[i] = (size_t)_strides[i];
+    }
+
+    if( ndims == 0 || step[ndims-1] > elemsize ) {
+        size[ndims] = 1;
+        step[ndims] = elemsize;
+        ndims++;
+    }
+
+    if( ndims >= 2 && step[0] < step[1] )
+    {
+        std::swap(size[0], size[1]);
+        std::swap(step[0], step[1]);
+        transposed = true;
+    }
+
+    // std::cerr << " ndims: " << ndims
+    //           << " size: " << size
+    //           << " type: " << type
+    //           << " step: " << step 
+    //           << " size: " << size[2] << std::endl;
+
+    // TODO: Possible bug in multi-dimensional matrices
+#if 1
+    if( ndims == 3 && size[2] <= CV_CN_MAX && step[1] == elemsize*size[2] )
+    {
+        ndims--;
+        type |= CV_MAKETYPE(0, size[2]);
+    }
+#endif
+    
+    if( ndims > 2)
+    {
+        failmsg("toMat: Object has more than 2 dimensions");
+    }
+    
+    m = Mat(ndims, size, type, PyArray_DATA(o), step);
+    // m.u = g_numpyAllocator.allocate(o, ndims, size, type, step);
+    
+    if( m.data )
+    {
+#if OPENCV_3
+      m.addref();
+      Py_INCREF(o);
+#else
+        m.refcount = refcountFromPyObject(o);
+        m.addref(); // protect the original numpy array from deallocation
+                    // (since Mat destructor will decrement the reference counter)
+#endif
+    };
+    m.allocator = &g_numpyAllocator;
+
+    if( transposed )
+    {
+        Mat tmp;
+        tmp.allocator = &g_numpyAllocator;
+        transpose(m, tmp);
+        m = tmp;
+    }
+    return m;
+}
+
+PyObject* NDArrayConverter::toNDArray(const cv::Mat& m)
+{
+#if OPENCV_3
+  if( !m.data )
+        Py_RETURN_NONE;
+    Mat temp, *p = (Mat*)&m;
+    if(!p->u || p->allocator != &g_numpyAllocator)
+    {
+        temp.allocator = &g_numpyAllocator;
+        m.copyTo(temp);
+        p = &temp;
+    }
+    PyObject* o = (PyObject*)p->u->userdata;
+    Py_INCREF(o);
+    // p->addref();
+    // pyObjectFromRefcount(p->refcount);
+    return o; 
+#else
+    if( !m.data )
+      Py_RETURN_NONE;
+    Mat temp, *p = (Mat*)&m;
+    if(!p->refcount || p->allocator != &g_numpyAllocator)
+    {
+        temp.allocator = &g_numpyAllocator;
+        ERRWRAP2(m.copyTo(temp));
+        p = &temp;
+    }
+    p->addref();
+    return pyObjectFromRefcount(p->refcount);
+#endif
+
+}
diff --git a/wrapper_python/utils/conversion.h b/wrapper_python/utils/conversion.h
new file mode 100644
index 0000000000000000000000000000000000000000..8ce616dbcd540e9842de24d4ec04d780f0c04e80
--- /dev/null
+++ b/wrapper_python/utils/conversion.h
@@ -0,0 +1,75 @@
+/*
+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/>.
+*/
+// Author: Sudeep Pillai (spillai@csail.mit.edu)
+// Note: Stripped from Opencv (opencv/modules/python/src2/cv2.cpp)
+
+#pragma once
+
+#include <Python.h>
+#include <opencv2/opencv.hpp>
+#include <opencv2/core/core.hpp>
+#include <numpy/ndarrayobject.h>
+
+static PyObject* opencv_error = 0;
+
+static int failmsg(const char *fmt, ...);
+
+class PyAllowThreads;
+
+class PyEnsureGIL;
+
+#define ERRWRAP2(expr) \
+try \
+{ \
+    PyAllowThreads allowThreads; \
+    expr; \
+} \
+catch (const cv::Exception &e) \
+{ \
+    PyErr_SetString(opencv_error, e.what()); \
+    return 0; \
+}
+
+static PyObject* failmsgp(const char *fmt, ...);
+
+static size_t REFCOUNT_OFFSET = (size_t)&(((PyObject*)0)->ob_refcnt) +
+    (0x12345678 != *(const size_t*)"\x78\x56\x34\x12\0\0\0\0\0")*sizeof(int);
+
+static inline PyObject* pyObjectFromRefcount(const int* refcount)
+{
+    return (PyObject*)((size_t)refcount - REFCOUNT_OFFSET);
+}
+
+static inline int* refcountFromPyObject(const PyObject* obj)
+{
+    return (int*)((size_t)obj + REFCOUNT_OFFSET);
+}
+
+
+class NumpyAllocator;
+
+enum { ARG_NONE = 0, ARG_MAT = 1, ARG_SCALAR = 2 };
+
+class NDArrayConverter
+{
+private:
+    void init();
+public:
+    NDArrayConverter();
+    cv::Mat toMat(const PyObject* o);
+    PyObject* toNDArray(const cv::Mat& mat);
+};
diff --git a/wrapper_python/utils/template.h b/wrapper_python/utils/template.h
new file mode 100644
index 0000000000000000000000000000000000000000..3f0b535a8df7b92d645d63787787900644f77f56
--- /dev/null
+++ b/wrapper_python/utils/template.h
@@ -0,0 +1,44 @@
+/*
+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/>.
+*/
+// Author: Sudeep Pillai (spillai@csail.mit.edu)
+// Note: Stripped from pyxx project
+
+#pragma once
+
+#include <boost/python.hpp>
+/*
+ * Provides template support
+ */
+
+template<typename TemplateType>
+struct expose_template_type
+{
+   // do nothing! 
+};
+
+template<typename TemplateType>
+struct expose_template_type_base
+{
+    bool wrapped()
+    {
+        using namespace boost::python::converter;
+        using namespace boost::python;
+        registration const * p = registry::query( type_id<TemplateType>() );
+        return p && (p->m_class_object || p->m_to_python);
+    }
+
+};