diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..777eb984792e57246be0169000d3efbae1ac2730
--- /dev/null
+++ b/samples/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 2.8)
+project( SubsBackground )
+find_package( OpenCV REQUIRED )
+add_executable( SubsBackground SubsBackground.cpp )
+target_link_libraries( SubsBackground ${OpenCV_LIBS} )
diff --git a/samples/SubsBackground.cpp b/samples/SubsBackground.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c91cd63e76ebef0f603e72ab1a1b3fa52ace93a3
--- /dev/null
+++ b/samples/SubsBackground.cpp
@@ -0,0 +1,222 @@
+/**
+ * @file bg_sub.cpp
+ * @brief Background subtraction tutorial sample code
+ * @author Domenico D. Bloisi
+ */
+
+//opencv
+#include <opencv2/core/core.hpp>
+#include <opencv2/highgui/highgui.hpp>
+#include <opencv2/video/background_segm.hpp>
+//C
+#include <stdio.h>
+//C++
+#include <iostream>
+#include <sstream>
+
+using namespace cv;
+using namespace std;
+
+// Global variables
+Mat frame; //current frame
+Mat fgMaskMOG; //fg mask generated by MOG method
+Mat fgMaskMOG2; //fg mask fg mask generated by MOG2 method
+Ptr<BackgroundSubtractor> pMOG; //MOG Background subtractor
+Ptr<BackgroundSubtractor> pMOG2; //MOG2 Background subtractor
+int keyboard; //input from keyboard
+
+/** Function Headers */
+void help();
+void processVideo(char* videoFilename);
+void processImages(char* firstFrameFilename);
+
+void help()
+{
+    cout
+    << "--------------------------------------------------------------------------" << endl
+    << "This program shows how to use background subtraction methods provided by "  << endl
+    << " OpenCV. You can process both videos (-vid) and images (-img)."             << endl
+                                                                                    << endl
+    << "Usage:"                                                                     << endl
+    << "./bs {-vid <video filename>|-img <image filename>}"                         << endl
+    << "for example: ./bs -vid video.avi"                                           << endl
+    << "or: ./bs -img /data/images/1.png"                                           << endl
+    << "--------------------------------------------------------------------------" << endl
+    << endl;
+}
+
+/**
+ * @function main
+ */
+int main(int argc, char* argv[])
+{
+    //print help information
+    help();
+
+    //check for the input parameter correctness
+    if(argc != 3) {
+        cerr <<"Incorret input list" << endl;
+        cerr <<"exiting..." << endl;
+        return EXIT_FAILURE;
+    }
+
+    //create GUI windows
+    namedWindow("Frame");
+    namedWindow("FG Mask MOG");
+    namedWindow("FG Mask MOG 2");
+
+    //create Background Subtractor objects
+    pMOG= new BackgroundSubtractorMOG(); //MOG approach
+    pMOG2 = new BackgroundSubtractorMOG2(); //MOG2 approach
+//    pMOG = createBackgroundSubtractorMOG(); //MOG approach
+//    pMOG2 = createBackgroundSubtractorMOG2(); //MOG2 approach
+
+    if(strcmp(argv[1], "-vid") == 0) {
+        //input data coming from a video
+        processVideo(argv[2]);
+    }
+    else if(strcmp(argv[1], "-img") == 0) {
+        //input data coming from a sequence of images
+        processImages(argv[2]);
+    }
+    else {
+        //error in reading input parameters
+        cerr <<"Please, check the input parameters." << endl;
+        cerr <<"Exiting..." << endl;
+        return EXIT_FAILURE;
+    }
+    //destroy GUI windows
+    destroyAllWindows();
+    return EXIT_SUCCESS;
+}
+
+/**
+ * @function processVideo
+ */
+void processVideo(char* videoFilename) {
+    //create the capture object
+    VideoCapture capture(videoFilename);
+    if(!capture.isOpened()){
+        //error in opening the video input
+        cerr << "Unable to open video file: " << videoFilename << endl;
+        exit(EXIT_FAILURE);
+    }
+    //read input data. ESC or 'q' for quitting
+    while( (char)keyboard != 'q' && (char)keyboard != 27 ){
+        //read the current frame
+        if(!capture.read(frame)) {
+            cerr << "Unable to read next frame." << endl;
+            cerr << "Exiting..." << endl;
+            exit(EXIT_FAILURE);
+        }
+        //update the background model
+        pMOG->operator()(frame, fgMaskMOG);
+        pMOG2->operator()(frame, fgMaskMOG2);
+//        pMOG->apply(frame, fgMaskMOG);
+//        pMOG2->apply(frame, fgMaskMOG2);
+        //get the frame number and write it on the current frame
+
+/*
+        stringstream ss;
+        rectangle(frame, cv::Point(10, 2), cv::Point(100,20),
+                  cv::Scalar(255,255,255), -1);
+        ss << capture.get(CAP_PROP_POS_FRAMES);
+        string frameNumberString = ss.str();
+        putText(frame, frameNumberString.c_str(), cv::Point(15, 15),
+                FONT_HERSHEY_SIMPLEX, 0.5 , cv::Scalar(0,0,0));
+*/
+
+        //show the current frame and the fg masks
+        imshow("Frame", frame);
+        imshow("FG Mask MOG", fgMaskMOG);
+        imshow("FG Mask MOG 2", fgMaskMOG2);
+        //get the input from the keyboard
+        keyboard = waitKey( 30 );
+    }
+    //delete capture object
+    capture.release();
+}
+
+/**
+ * @function processImages
+ */
+void processImages(char* fistFrameFilename) {
+    //read the first file of the sequence
+    frame = imread(fistFrameFilename);
+    if(!frame.data){
+        //error in opening the first image
+        cerr << "Unable to open first image frame: " << fistFrameFilename << endl;
+        exit(EXIT_FAILURE);
+    }
+    //current image filename
+    string fn(fistFrameFilename);
+    //read input data. ESC or 'q' for quitting
+    while( (char)keyboard != 'q' && (char)keyboard != 27 ){
+        //update the background model
+        pMOG->operator()(frame, fgMaskMOG);
+        pMOG2->operator()(frame, fgMaskMOG2);
+//        pMOG->apply(frame, fgMaskMOG);
+//        pMOG2->apply(frame, fgMaskMOG2);
+        //get the frame number and write it on the current frame
+        size_t index = fn.find_last_of("/");
+        if(index == string::npos) {
+            index = fn.find_last_of("\\");
+        }
+        size_t index2 = fn.find_last_of(".");
+        string prefix = fn.substr(0,index+1);
+        string suffix = fn.substr(index2);
+        string frameNumberString = fn.substr(index+1, index2-index-1);
+        istringstream iss(frameNumberString);
+        int frameNumber = 0;
+        iss >> frameNumber;
+        rectangle(frame, cv::Point(10, 2), cv::Point(100,20),
+                  cv::Scalar(255,255,255), -1);
+        putText(frame, frameNumberString.c_str(), cv::Point(15, 15),
+                FONT_HERSHEY_SIMPLEX, 0.5 , cv::Scalar(0,0,0));
+        //show the current frame and the fg masks
+        imshow("Frame", frame);
+        imshow("FG Mask MOG", fgMaskMOG);
+        imshow("FG Mask MOG 2", fgMaskMOG2);
+        //get the input from the keyboard
+        keyboard = waitKey( 30 );
+        //search for the next image in the sequence
+        ostringstream oss;
+        oss << (frameNumber + 1);
+        string nextFrameNumberString = oss.str();
+        string nextFrameFilename = prefix + nextFrameNumberString + suffix;
+        //read the next frame
+        frame = imread(nextFrameFilename);
+        if(!frame.data){
+            //error in opening the next image in the sequence
+            cerr << "Unable to open image frame: " << nextFrameFilename << endl;
+            exit(EXIT_FAILURE);
+        }
+        //update the path of the current frame
+        fn.assign(nextFrameFilename);
+    }
+}
+
+
+/*#include <opencv2/highgui/highgui.hpp>
+#include <iostream>
+
+using namespace cv;
+using namespace std;
+
+
+int main( int argc, char** argv ) {
+    cvNamedWindow("Example2", CV_WINDOW_AUTOSIZE );
+    CvCapture* capture = cvCreateFileCapture(argv[1]);
+    IplImage* frame;
+    while(1) {
+        frame = cvQueryFrame(capture);
+        if(!frame) break;
+        cvShowImage("Example2", frame );
+        char c = cvWaitKey(33);
+        if(c == 27) break;
+    }
+    cvReleaseCapture(&capture);
+    cvDestroyWindow("Example2");
+    return 0;
+}
+*/