added support for Ximea cameras (patch by Marian Zajko), fixed GCC warnings in MOG2...
authorVadim Pisarevsky <no@email>
Thu, 11 Aug 2011 17:59:30 +0000 (17:59 +0000)
committerVadim Pisarevsky <no@email>
Thu, 11 Aug 2011 17:59:30 +0000 (17:59 +0000)
CMakeLists.txt
OpenCVFindXimea.cmake [new file with mode: 0755]
cvconfig.h.cmake
modules/highgui/include/opencv2/highgui/highgui_c.h
modules/highgui/src/cap.cpp
modules/highgui/src/cap_ximea.cpp [new file with mode: 0755]
modules/highgui/src/precomp.hpp
modules/video/src/bgfg_gaussmix2.cpp

index f24b7ee..9e1347b 100644 (file)
@@ -428,6 +428,7 @@ set(WITH_EIGEN ON CACHE BOOL "Include Eigen2/Eigen3 support")
 set(WITH_CUDA ON CACHE BOOL "Include NVidia Cuda Runtime support")
 
 set(WITH_OPENNI OFF CACHE BOOL "Include OpenNI support")
+set(WITH_XIMEA OFF CACHE BOOL "Include XIMEA cameras support")
 
 # ===================================================
 # Macros that checks if module have been installed.
@@ -1025,6 +1026,17 @@ if(WITH_OPENNI)
     include(OpenCVFindOpenNI.cmake)
 endif()
 
+############################### XIMEA ################################
+set(HAVE_XIMEA FALSE)
+if(WITH_XIMEA)
+    include(OpenCVFindXimea.cmake)
+endif()
+
+if(XIMEA_FOUND)
+    set(HAVE_XIMEA TRUE)
+endif()
+
 ############################## Eigen ##############################
 
 if(WITH_EIGEN)
@@ -1632,6 +1644,7 @@ status("    OpenEXR:"   WITH_OPENEXR AND OPENEXR_FOUND     THEN YES
 status("    OpenNI:"    HAVE_OPENNI                        THEN YES             ELSE NO)
 status("    OpenNI PrimeSensor Modules:"
                         HAVE_OPENNI_PRIME_SENSOR_MODULE    THEN YES             ELSE NO)
+status("    XIMEA:"     HAVE_XIMEA  THEN YES ELSE NO)
 
 # video
 status("")
diff --git a/OpenCVFindXimea.cmake b/OpenCVFindXimea.cmake
new file mode 100755 (executable)
index 0000000..afc73e0
--- /dev/null
@@ -0,0 +1,35 @@
+# - Find XIMEA
+# This module finds if XIMEA Software package is installed
+# and determines where the binaries and header files are.
+# This code sets the following variables:
+#  
+#  XIMEA_FOUND          - True if XIMEA API found
+#  XIMEA_PATH:          - Path to the XIMEA API folder
+#  XIMEA_LIBRARY_DIRS   - XIMEA libraries folder
+#
+# Created: 5 Aug 2011 by Marian Zajko (marian.zajko@ximea.com)
+#
+
+set(XIMEA_FOUND)
+set(XIMEA_PATH)
+set(XIMEA_LIBRARY_DIR)
+
+# Try to find the XIMEA API path in registry.
+GET_FILENAME_COMPONENT(XIMEA_PATH "[HKEY_CURRENT_USER\\Software\\XIMEA\\CamSupport\\API;Path]" ABSOLUTE)                                                
+
+if(XIMEA_PATH)
+  set(XIMEA_FOUND 1)
+  
+  # set LIB folders
+  set(XIMEA_LIBRARY_DIR "${XIMEA_PATH}\\x86")
+  
+else()
+  set(XIMEA_FOUND 0)
+endif()                                            
+
+mark_as_advanced(FORCE XIMEA_FOUND)
+mark_as_advanced(FORCE XIMEA_PATH)
+mark_as_advanced(FORCE XIMEA_LIBRARY_DIR)
+  
+   
+   
\ No newline at end of file
index e61a226..4bd16dd 100644 (file)
 /* VideoInput library */
 #cmakedefine HAVE_VIDEOINPUT
 
+/* XIMEA camera support */
+#cmakedefine HAVE_XIMEA
index 7c030ae..52fa3a8 100644 (file)
@@ -287,7 +287,9 @@ enum
 
     CV_CAP_OPENNI   =900,   // OpenNI (for Kinect)
 
-    CV_CAP_ANDROID  =1000   // Android
+    CV_CAP_ANDROID  =1000,  // Android
+    
+    CV_CAP_XIAPI    =1100   // XIMEA Camera API
 };
 
 /* start capturing frames from camera: index = camera_index + domain_offset (CV_CAP_*) */
@@ -372,7 +374,30 @@ enum
     
     // Properties of cameras available through GStreamer interface
     CV_CAP_GSTREAMER_QUEUE_LENGTH   = 200, // default is 1
-    CV_CAP_PROP_PVAPI_MULTICASTIP   = 300  // ip for anable multicast master mode. 0 for disable multicast
+    CV_CAP_PROP_PVAPI_MULTICASTIP   = 300, // ip for anable multicast master mode. 0 for disable multicast
+    
+    // Properties of cameras available through XIMEA SDK interface
+    CV_CAP_PROP_XI_DOWNSAMPLING  = 400,      // Change image resolution by binning or skipping.  
+    CV_CAP_PROP_XI_DATA_FORMAT   = 401,       // Output data format.
+    CV_CAP_PROP_XI_OFFSET_X      = 402,      // Horizontal offset from the origin to the area of interest (in pixels).
+    CV_CAP_PROP_XI_OFFSET_Y      = 403,      // Vertical offset from the origin to the area of interest (in pixels).
+    CV_CAP_PROP_XI_TRG_SOURCE    = 404,      // Defines source of trigger.
+    CV_CAP_PROP_XI_TRG_SOFTWARE  = 405,      // Generates an internal trigger. PRM_TRG_SOURCE must be set to TRG_SOFTWARE.
+    CV_CAP_PROP_XI_GPI_SELECTOR  = 406,      // Selects general purpose input 
+    CV_CAP_PROP_XI_GPI_MODE      = 407,      // Set general purpose input mode
+    CV_CAP_PROP_XI_GPI_LEVEL     = 408,      // Get general purpose level
+    CV_CAP_PROP_XI_GPO_SELECTOR  = 409,      // Selects general purpose output 
+    CV_CAP_PROP_XI_GPO_MODE      = 410,      // Set general purpose output mode
+    CV_CAP_PROP_XI_LED_SELECTOR  = 411,      // Selects camera signalling LED 
+    CV_CAP_PROP_XI_LED_MODE      = 412,      // Define camera signalling LED functionality
+    CV_CAP_PROP_XI_MANUAL_WB     = 413,      // Calculates White Balance(must be called during acquisition)
+    CV_CAP_PROP_XI_AUTO_WB       = 414,      // Automatic white balance
+    CV_CAP_PROP_XI_AEAG          = 415,      // Automatic exposure/gain
+    CV_CAP_PROP_XI_EXP_PRIORITY  = 416,      // Exposure priority (0.5 - exposure 50%, gain 50%).
+    CV_CAP_PROP_XI_AE_MAX_LIMIT  = 417,      // Maximum limit of exposure in AEAG procedure
+    CV_CAP_PROP_XI_AG_MAX_LIMIT  = 418,      // Maximum limit of gain in AEAG procedure
+    CV_CAP_PROP_XI_AEAG_LEVEL    = 419,       // Average intensity of output signal AEAG should achieve(in %)
+    CV_CAP_PROP_XI_TIMEOUT       = 420       // Image capture timeout in milliseconds
 };
 
 enum
index 0df99b0..fa9f9f9 100644 (file)
@@ -133,6 +133,9 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
 #ifdef HAVE_ANDROID_NATIVE_CAMERA
         CV_CAP_ANDROID,
 #endif
+#ifdef HAVE_XIMEA
+        CV_CAP_XIAPI,
+#endif
         -1
     };
 
@@ -238,36 +241,43 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
 
         #ifdef HAVE_UNICAP
         case CV_CAP_UNICAP:
-        capture = cvCreateCameraCapture_Unicap (index);
-        if (capture)
-            return capture;
+            capture = cvCreateCameraCapture_Unicap (index);
+            if (capture)
+                return capture;
         break;
         #endif
         
         #ifdef HAVE_PVAPI
         case CV_CAP_PVAPI:
-        capture = cvCreateCameraCapture_PvAPI (index);
-        if (capture)
-            return capture;
+            capture = cvCreateCameraCapture_PvAPI (index);
+            if (capture)
+                return capture;
         break;
         #endif
 
         #ifdef HAVE_OPENNI
         case CV_CAP_OPENNI:
-        capture = cvCreateCameraCapture_OpenNI (index);
-        if (capture)
-            return capture;
+            capture = cvCreateCameraCapture_OpenNI (index);
+            if (capture)
+                return capture;
         break;
         #endif
 
-               #ifdef HAVE_ANDROID_NATIVE_CAMERA
+        #ifdef HAVE_ANDROID_NATIVE_CAMERA
         case CV_CAP_ANDROID:
-          capture = cvCreateCameraCapture_Android (index);
-        if (capture)
-            return capture;
+            capture = cvCreateCameraCapture_Android (index);
+            if (capture)
+                return capture;
+        break;
+        #endif
+        
+        #ifdef HAVE_XIMEA
+        case CV_CAP_XIAPI:
+            capture = cvCreateCameraCapture_Ximea (index);
+            if (capture)
+                return capture;
         break;
         #endif
-
         }
     }
 
diff --git a/modules/highgui/src/cap_ximea.cpp b/modules/highgui/src/cap_ximea.cpp
new file mode 100755 (executable)
index 0000000..a803414
--- /dev/null
@@ -0,0 +1,253 @@
+
+#include "precomp.hpp"
+
+#include "xiApi.h"
+#include "xiExt.h"
+
+/**********************************************************************************/
+
+class CvCaptureCAM_XIMEA : public CvCapture
+{
+public:
+    CvCaptureCAM_XIMEA() { init(); }
+    virtual ~CvCaptureCAM_XIMEA() { close(); }
+
+    virtual bool open( int index );
+    virtual void close();
+    virtual double getProperty(int);
+    virtual bool setProperty(int, double);
+    virtual bool grabFrame();
+    virtual IplImage* retrieveFrame(int);
+       virtual int getCaptureDomain() { return CV_CAP_XIAPI; } // Return the type of the capture object: CV_CAP_VFW, etc...
+
+protected:
+       void init();
+       void errMsg(char* msg, int errNum);
+    IplImage* frame;
+
+       HANDLE    hmv;
+       DWORD     numDevices;
+       XI_IMG    image;
+       int       width;
+       int       height;
+       int       format;
+       int       timeout;
+};
+
+/**********************************************************************************/
+
+CvCapture* cvCreateCameraCapture_XIMEA( int index )
+{
+     CvCaptureCAM_XIMEA* capture = new CvCaptureCAM_XIMEA;
+
+    if( capture->open( index ))
+        return capture;
+
+       delete capture;
+    return 0;
+}
+
+/**********************************************************************************/
+// Enumerate connected devices
+void CvCaptureCAM_XIMEA::init()
+{
+       xiGetNumberDevices( &numDevices);
+       hmv = NULL;
+}
+
+
+/**********************************************************************************/
+// Initialize camera input
+bool CvCaptureCAM_XIMEA::open( int wIndex )
+{
+       int mvret = XI_OK;
+
+       if(numDevices == 0)
+               return false;
+       
+       if((mvret = xiOpenDevice( wIndex, &hmv)) != XI_OK)
+  {
+               errMsg("Open XI_DEVICE failed", mvret);
+               return false;
+       }
+
+       // always use auto exposure/gain
+       xiSetParamInt( hmv, XI_PRM_AEAG, 1);
+
+       // always use auto white ballance
+       xiSetParamInt( hmv, XI_PRM_AUTO_WB, 1);
+
+       xiGetParamInt( hmv, XI_PRM_WIDTH, &width);
+       xiGetParamInt( hmv, XI_PRM_HEIGHT, &height);
+       
+       // default image format RGB24
+       xiSetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, XI_RGB24);
+       format = XI_RGB24;
+       // allocate frame buffer for RGB24 image
+       frame = cvCreateImage(cvSize( width, height), IPL_DEPTH_8U, 3); 
+
+       //default capture timeout 10s
+       timeout = 10000;
+
+       return true;
+}
+
+/**********************************************************************************/
+
+void CvCaptureCAM_XIMEA::close()
+{
+       xiCloseDevice(hmv);
+       hmv = NULL;
+}
+
+/**********************************************************************************/
+
+bool CvCaptureCAM_XIMEA::grabFrame()
+{
+       int mvret = XI_OK;
+       image.size = sizeof(XI_IMG);
+       if((mvret = xiGetImage( hmv, timeout, &image)) != XI_OK)
+  {
+               errMsg("Error during GetImage", mvret);
+               return false;
+       }
+    return true;
+}
+
+/**********************************************************************************/
+
+IplImage* CvCaptureCAM_XIMEA::retrieveFrame(int)
+{
+       // update cvImage after format has changed
+       if( image.width != width || image.height != height || image.frm != format)
+       {
+               cvReleaseImage(&frame);
+               switch( image.frm)
+               {
+               case XI_MONO8  : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_8U, 1); break;
+               case XI_MONO16 : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_16U, 1); break; 
+               case XI_RGB24  : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_8U, 3); break;
+               case XI_RGB32  : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_8U, 4); break;
+               }
+               // update global image format
+               format = image.frm;     
+               width = image.width;
+               height = image.height;
+       }
+
+       // copy pixel data
+       switch( image.frm)
+       {
+       case XI_MONO8  : memcpy( frame->imageData, image.bp, image.width*image.height); break;
+       case XI_MONO16 : memcpy( frame->imageData, image.bp, image.width*image.height*sizeof(WORD)); break;
+       case XI_RGB24  : memcpy( frame->imageData, image.bp, image.width*image.height*3); break;
+       case XI_RGB32  : memcpy( frame->imageData, image.bp, image.width*image.height*sizeof(DWORD)); break;
+       }
+       return frame;
+}
+
+/**********************************************************************************/
+
+double CvCaptureCAM_XIMEA::getProperty( int property_id )
+{
+       if(hmv == NULL)
+               return 0;
+
+       int ival = 0;
+       float fval = 0;
+
+       switch( property_id )
+  {
+       // OCV parameters
+  case CV_CAP_PROP_POS_FRAMES   : return (double) image.nframe;
+  case CV_CAP_PROP_FRAME_WIDTH  : xiGetParamInt( hmv, XI_PRM_WIDTH, &ival); return ival;
+  case CV_CAP_PROP_FRAME_HEIGHT : xiGetParamInt( hmv, XI_PRM_HEIGHT, &ival); return ival;
+  case CV_CAP_PROP_FPS          : xiGetParamFloat( hmv, XI_PRM_FRAMERATE, &fval); return fval;
+  case CV_CAP_PROP_GAIN         : xiGetParamFloat( hmv, XI_PRM_GAIN, &fval); return fval;
+  case CV_CAP_PROP_EXPOSURE     : xiGetParamInt( hmv, XI_PRM_EXPOSURE, &ival); return ival;
+
+       // XIMEA camera properties
+       case CV_CAP_PROP_XI_DOWNSAMPLING  : xiGetParamInt( hmv, XI_PRM_DOWNSAMPLING, &ival); return ival;
+       case CV_CAP_PROP_XI_DATA_FORMAT   : xiGetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, &ival); return ival;
+       case CV_CAP_PROP_XI_OFFSET_X      : xiGetParamInt( hmv, XI_PRM_OFFSET_X, &ival); return ival;
+       case CV_CAP_PROP_XI_OFFSET_Y      : xiGetParamInt( hmv, XI_PRM_OFFSET_Y, &ival); return ival;
+       case CV_CAP_PROP_XI_TRG_SOURCE    : xiGetParamInt( hmv, XI_PRM_TRG_SOURCE, &ival); return ival;
+       case CV_CAP_PROP_XI_GPI_SELECTOR  : xiGetParamInt( hmv, XI_PRM_GPI_SELECTOR, &ival); return ival;
+       case CV_CAP_PROP_XI_GPI_MODE      : xiGetParamInt( hmv, XI_PRM_GPI_MODE, &ival); return ival;
+       case CV_CAP_PROP_XI_GPI_LEVEL     : xiGetParamInt( hmv, XI_PRM_GPI_LEVEL, &ival); return ival;
+       case CV_CAP_PROP_XI_GPO_SELECTOR  : xiGetParamInt( hmv, XI_PRM_GPO_SELECTOR, &ival); return ival;
+       case CV_CAP_PROP_XI_GPO_MODE      : xiGetParamInt( hmv, XI_PRM_GPO_MODE, &ival); return ival;
+       case CV_CAP_PROP_XI_LED_SELECTOR  : xiGetParamInt( hmv, XI_PRM_LED_SELECTOR, &ival); return ival;
+       case CV_CAP_PROP_XI_LED_MODE      : xiGetParamInt( hmv, XI_PRM_LED_MODE, &ival); return ival;
+       case CV_CAP_PROP_XI_AUTO_WB       : xiGetParamInt( hmv, XI_PRM_AUTO_WB, &ival); return ival;
+       case CV_CAP_PROP_XI_AEAG          : xiGetParamInt( hmv, XI_PRM_AEAG, &ival); return ival;
+       case CV_CAP_PROP_XI_EXP_PRIORITY  : xiGetParamFloat( hmv, XI_PRM_EXP_PRIORITY, &fval); return fval;
+       case CV_CAP_PROP_XI_AE_MAX_LIMIT  : xiGetParamInt( hmv, XI_PRM_EXP_PRIORITY, &ival); return ival;
+       case CV_CAP_PROP_XI_AG_MAX_LIMIT  : xiGetParamFloat( hmv, XI_PRM_AG_MAX_LIMIT, &fval); return fval;
+       case CV_CAP_PROP_XI_AEAG_LEVEL    : xiGetParamInt( hmv, XI_PRM_AEAG_LEVEL, &ival); return ival;
+       case CV_CAP_PROP_XI_TIMEOUT       : return timeout;
+  }
+       return 0;
+}
+
+/**********************************************************************************/
+
+bool CvCaptureCAM_XIMEA::setProperty( int property_id, double value )
+{ 
+       int ival = (int) value; 
+       float fval = (float) value;
+       
+       int mvret = XI_OK;
+       
+       switch(property_id)
+       {
+       // OCV parameters
+    case CV_CAP_PROP_FRAME_WIDTH  : mvret = xiSetParamInt( hmv, XI_PRM_WIDTH, ival); break;
+    case CV_CAP_PROP_FRAME_HEIGHT : mvret = xiSetParamInt( hmv, XI_PRM_HEIGHT, ival); break;
+    case CV_CAP_PROP_FPS          : mvret = xiSetParamFloat( hmv, XI_PRM_FRAMERATE, fval); break;
+       case CV_CAP_PROP_GAIN         : mvret = xiSetParamFloat( hmv, XI_PRM_GAIN, fval); break;
+       case CV_CAP_PROP_EXPOSURE     : mvret = xiSetParamInt( hmv, XI_PRM_EXPOSURE, ival); break;
+       // XIMEA camera properties
+       case CV_CAP_PROP_XI_DOWNSAMPLING  :  mvret = xiSetParamInt( hmv, XI_PRM_DOWNSAMPLING, ival); break;
+       case CV_CAP_PROP_XI_DATA_FORMAT   : mvret = xiSetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, ival); break;
+       case CV_CAP_PROP_XI_OFFSET_X      : mvret = xiSetParamInt( hmv, XI_PRM_OFFSET_X, ival); break;
+       case CV_CAP_PROP_XI_OFFSET_Y      : mvret = xiSetParamInt( hmv, XI_PRM_OFFSET_Y, ival); break;
+       case CV_CAP_PROP_XI_TRG_SOURCE    : mvret = xiSetParamInt( hmv, XI_PRM_TRG_SOURCE, ival); break;
+       case CV_CAP_PROP_XI_GPI_SELECTOR  : mvret = xiSetParamInt( hmv, XI_PRM_GPI_SELECTOR, ival); break;
+       case CV_CAP_PROP_XI_TRG_SOFTWARE  : mvret = xiSetParamInt( hmv, XI_PRM_TRG_SOURCE, 1); break;           
+       case CV_CAP_PROP_XI_GPI_MODE      : mvret = xiSetParamInt( hmv, XI_PRM_GPI_MODE, ival); break; 
+       case CV_CAP_PROP_XI_GPI_LEVEL     : mvret = xiSetParamInt( hmv, XI_PRM_GPI_LEVEL, ival); break;
+       case CV_CAP_PROP_XI_GPO_SELECTOR  : mvret = xiSetParamInt( hmv, XI_PRM_GPO_SELECTOR, ival); break;
+       case CV_CAP_PROP_XI_GPO_MODE      : mvret = xiSetParamInt( hmv, XI_PRM_GPO_MODE, ival); break; 
+       case CV_CAP_PROP_XI_LED_SELECTOR  : mvret = xiSetParamInt( hmv, XI_PRM_LED_SELECTOR, ival); break;
+       case CV_CAP_PROP_XI_LED_MODE      : mvret = xiSetParamInt( hmv, XI_PRM_LED_MODE, ival); break; 
+       case CV_CAP_PROP_XI_AUTO_WB       : mvret = xiSetParamInt( hmv, XI_PRM_AUTO_WB, ival); break;
+       case CV_CAP_PROP_XI_MANUAL_WB     : mvret = xiSetParamInt( hmv, XI_PRM_LED_MODE, ival); break;
+       case CV_CAP_PROP_XI_AEAG          : mvret = xiSetParamInt( hmv, XI_PRM_AEAG, ival); break;
+       case CV_CAP_PROP_XI_EXP_PRIORITY  : mvret = xiSetParamFloat( hmv, XI_PRM_EXP_PRIORITY, fval); break; 
+       case CV_CAP_PROP_XI_AE_MAX_LIMIT  : mvret = xiSetParamInt( hmv, XI_PRM_EXP_PRIORITY, ival); break;
+       case CV_CAP_PROP_XI_AG_MAX_LIMIT  : mvret = xiSetParamFloat( hmv, XI_PRM_AG_MAX_LIMIT, fval); break;
+       case CV_CAP_PROP_XI_AEAG_LEVEL    : mvret = xiSetParamInt( hmv, XI_PRM_AEAG_LEVEL, ival); break; 
+       case CV_CAP_PROP_XI_TIMEOUT       : timeout = ival; break;
+       }
+
+       if(mvret != XI_OK)
+  {
+               errMsg("Set parameter error", mvret);
+               return false;
+       } 
+  else
+               return true; 
+               
+}
+
+/**********************************************************************************/
+
+void CvCaptureCAM_XIMEA::errMsg(char* msg, int errNum)
+{
+       char buf[512];
+       sprintf( buf, "%s : %d\n", msg, errNum);
+       OutputDebugString(buf);
+}
+
+/**********************************************************************************/
\ No newline at end of file
index bbdc1d7..b4980bf 100644 (file)
@@ -133,6 +133,7 @@ CvVideoWriter* cvCreateVideoWriter_VFW( const char* filename, int fourcc,
 CvCapture* cvCreateCameraCapture_DShow( int index );
 CvCapture* cvCreateCameraCapture_OpenNI( int index );
 CvCapture* cvCreateCameraCapture_Android( int index );
+CvCapture* cvCreateCameraCapture_XIMEA( int index );
 
 CVAPI(int) cvHaveImageReader(const char* filename);
 CVAPI(int) cvHaveImageWriter(const char* filename);
index 1d1f0c8..65d646c 100644 (file)
@@ -204,69 +204,68 @@ typedef struct CvGaussBGModel2
     CvGaussBGStatModel2Params params;
     CvGaussBGStatModel2Data   data;
     int                       countFrames;
-}
-CvGaussBGModel2;
+} CvGaussBGModel2;
 
 CVAPI(CvBGStatModel*) cvCreateGaussianBGModel2( IplImage* first_frame,
                                                 CvGaussBGStatModel2Params* params CV_DEFAULT(NULL) );
 //shadow detection performed per pixel
 // should work for rgb data, could be usefull for gray scale and depth data as well
-//     See: Prati,Mikic,Trivedi,Cucchiarra,"Detecting Moving Shadows...",IEEE PAMI,2003.
+//  See: Prati,Mikic,Trivedi,Cucchiarra,"Detecting Moving Shadows...",IEEE PAMI,2003.
 CV_INLINE int _icvRemoveShadowGMM(float* data, int nD,
-                                                               unsigned char nModes, 
-                                                               CvPBGMMGaussian* pGMM,
-                                                               float m_fTb,
-                                                               float m_fTB,    
-                                                               float m_fTau)
+                                unsigned char nModes, 
+                                CvPBGMMGaussian* pGMM,
+                                float m_fTb,
+                                float m_fTB,    
+                                float m_fTau)
 {
-       float tWeight = 0;
-       float numerator, denominator;
-       // check all the components  marked as background:
-       for (int iModes=0;iModes<nModes;iModes++)
-       {
-
-               CvPBGMMGaussian g=pGMM[iModes];
-
-               numerator = 0.0f;
-               denominator = 0.0f;
-               for (int iD=0;iD<nD;iD++)
-               {
-                               numerator   += data[iD]  * g.mean[iD];
-                               denominator += g.mean[iD]* g.mean[iD];
-               }
-
-               // no division by zero allowed
-               if (denominator == 0)
-               {
-                               return 0;
-               };
-               float a = numerator / denominator;
-
-               // if tau < a < 1 then also check the color distortion
-               if ((a <= 1) && (a >= m_fTau))
-               {
-
-                       float dist2a=0.0f;
-                       
-                       for (int iD=0;iD<nD;iD++)
-                       {
-                               float dD= a*g.mean[iD] - data[iD];
-                               dist2a += (dD*dD);
-                       }
-
-                       if (dist2a<m_fTb*g.variance*a*a)
-                       {
-                               return 2;
-                       }
-               };
-
-               tWeight += g.weight;
-               if (tWeight > m_fTB)
-               {
-                               return 0;
-               };
-       };
-       return 0;
+    float tWeight = 0;
+    float numerator, denominator;
+    // check all the components  marked as background:
+    for (int iModes=0;iModes<nModes;iModes++)
+    {
+
+        CvPBGMMGaussian g=pGMM[iModes];
+
+        numerator = 0.0f;
+        denominator = 0.0f;
+        for (int iD=0;iD<nD;iD++)
+        {
+                numerator   += data[iD]  * g.mean[iD];
+                denominator += g.mean[iD]* g.mean[iD];
+        }
+
+        // no division by zero allowed
+        if (denominator == 0)
+        {
+                return 0;
+        };
+        float a = numerator / denominator;
+
+        // if tau < a < 1 then also check the color distortion
+        if ((a <= 1) && (a >= m_fTau))
+        {
+
+            float dist2a=0.0f;
+            
+            for (int iD=0;iD<nD;iD++)
+            {
+                float dD= a*g.mean[iD] - data[iD];
+                dist2a += (dD*dD);
+            }
+
+            if (dist2a<m_fTb*g.variance*a*a)
+            {
+                return 2;
+            }
+        };
+
+        tWeight += g.weight;
+        if (tWeight > m_fTB)
+        {
+                return 0;
+        };
+    };
+    return 0;
 }
 
 //update GMM - the base update function performed per pixel
@@ -284,402 +283,402 @@ CV_INLINE int _icvRemoveShadowGMM(float* data, int nD,
 //http://www.zoranz.net/Publications/zivkovic2004PAMI.pdf
 
 CV_INLINE int _icvUpdateGMM(float* data, int nD,
-                                                               unsigned char* pModesUsed, 
-                                                               CvPBGMMGaussian* pGMM,
-                                                               int m_nM,
-                                                               float m_fAlphaT,
-                                                               float m_fTb,
-                                                               float m_fTB,    
-                                                               float m_fTg,
-                                                               float m_fVarInit,
-                                                               float m_fVarMax,
-                                                               float m_fVarMin,
-                                                               float m_fPrune)
+                                unsigned char* pModesUsed, 
+                                CvPBGMMGaussian* pGMM,
+                                int m_nM,
+                                float m_fAlphaT,
+                                float m_fTb,
+                                float m_fTB,    
+                                float m_fTg,
+                                float m_fVarInit,
+                                float m_fVarMax,
+                                float m_fVarMin,
+                                float m_fPrune)
 {
-       //calculate distances to the modes (+ sort)
-       //here we need to go in descending order!!!     
-       bool bBackground=0;//return value -> true - the pixel classified as background
-
-       //internal:
-       bool bFitsPDF=0;//if it remains zero a new GMM mode will be added       
-       float m_fOneMinAlpha=1-m_fAlphaT;
-       unsigned char nModes=*pModesUsed;//current number of modes in GMM
-       float totalWeight=0.0f;
-
-       //////
-       //go through all modes
-       int iMode=0;
-       CvPBGMMGaussian* pGauss=pGMM;
-       for (;iMode<nModes;iMode++,pGauss++)
-       {
-               float weight = pGauss->weight;//need only weight if fit is found
-               weight=m_fOneMinAlpha*weight+m_fPrune;
-
-               ////
-               //fit not found yet
-               if (!bFitsPDF)
-               {
-                       //check if it belongs to some of the remaining modes
-                       float var=pGauss->variance;
-
-                       //calculate difference and distance
-                       float dist2=0.0f;
+    //calculate distances to the modes (+ sort)
+    //here we need to go in descending order!!! 
+    bool bBackground=0;//return value -> true - the pixel classified as background
+
+    //internal:
+    bool bFitsPDF=0;//if it remains zero a new GMM mode will be added   
+    float m_fOneMinAlpha=1-m_fAlphaT;
+    unsigned char nModes=*pModesUsed;//current number of modes in GMM
+    float totalWeight=0.0f;
+
+    //////
+    //go through all modes
+    int iMode=0;
+    CvPBGMMGaussian* pGauss=pGMM;
+    for (;iMode<nModes;iMode++,pGauss++)
+    {
+        float weight = pGauss->weight;//need only weight if fit is found
+        weight=m_fOneMinAlpha*weight+m_fPrune;
+
+        ////
+        //fit not found yet
+        if (!bFitsPDF)
+        {
+            //check if it belongs to some of the remaining modes
+            float var=pGauss->variance;
+
+            //calculate difference and distance
+            float dist2=0.0f;
 #if (CV_BGFG_MOG2_NDMAX==1)
-                       float dData=pGauss->mean[0]-data[0];
-                       dist2=dData*dData;
-#else                  
-                       float dData[CV_BGFG_MOG2_NDMAX];
-
-                       for (int iD=0;iD<nD;iD++)
-                       {
-                               dData[iD]=pGauss->mean[iD]-data[iD];
-                               dist2+=dData[iD]*dData[iD];
-                       }
-#endif         
-                       //background? - m_fTb - usually larger than m_fTg
-                       if ((totalWeight<m_fTB)&&(dist2<m_fTb*var))
-                                       bBackground=1;
-
-                       //check fit
-                       if (dist2<m_fTg*var)
-                       {
-                               /////
-                               //belongs to the mode - bFitsPDF becomes 1
-                               bFitsPDF=1;
-
-                               //update distribution                           
-                               
-                               //update weight
-                               weight+=m_fAlphaT;
-
-                               float k = m_fAlphaT/weight;
-
-                               //update mean
+            float dData=pGauss->mean[0]-data[0];
+            dist2=dData*dData;
+#else           
+            float dData[CV_BGFG_MOG2_NDMAX];
+
+            for (int iD=0;iD<nD;iD++)
+            {
+                dData[iD]=pGauss->mean[iD]-data[iD];
+                dist2+=dData[iD]*dData[iD];
+            }
+#endif      
+            //background? - m_fTb - usually larger than m_fTg
+            if ((totalWeight<m_fTB)&&(dist2<m_fTb*var))
+                    bBackground=1;
+
+            //check fit
+            if (dist2<m_fTg*var)
+            {
+                /////
+                //belongs to the mode - bFitsPDF becomes 1
+                bFitsPDF=1;
+
+                //update distribution               
+                
+                //update weight
+                weight+=m_fAlphaT;
+
+                float k = m_fAlphaT/weight;
+
+                //update mean
 #if (CV_BGFG_MOG2_NDMAX==1)
-                               pGauss->mean[0]-=k*dData;
-#else                          
-                               for (int iD=0;iD<nD;iD++)
-                               {
-                                       pGauss->mean[iD]-=k*dData[iD];
-                               }
+                pGauss->mean[0]-=k*dData;
+#else               
+                for (int iD=0;iD<nD;iD++)
+                {
+                    pGauss->mean[iD]-=k*dData[iD];
+                }
 #endif
 
-                               //update variance
-                               float varnew = var + k*(dist2-var);
-                               //limit the variance                            
-                               pGauss->variance = MIN(m_fVarMax,MAX(varnew,m_fVarMin));
-
-                               //sort
-                               //all other weights are at the same place and 
-                               //only the matched (iModes) is higher -> just find the new place for it                         
-                               for (int iLocal = iMode;iLocal>0;iLocal--)
-                               {
-                                       //check one up
-                                       if (weight < (pGMM[iLocal-1].weight))
-                                       {
-                                               break;
-                                       }
-                                       else
-                                       {
-                                               //swap one up
-                                               CvPBGMMGaussian temp = pGMM[iLocal];
-                                               pGMM[iLocal] = pGMM[iLocal-1];
-                                               pGMM[iLocal-1] = temp;
-                                               pGauss--;
-                                       }
-                               }
-                               //belongs to the mode - bFitsPDF becomes 1
-                               /////
-                       }
-               }//!bFitsPDF)
-
-               //check prune
-               if (weight<-m_fPrune)
-               {
-                       weight=0.0;
-                       nModes--;
-               }
-
-               pGauss->weight=weight;//update weight by the calculated value
-               totalWeight+=weight;
-       }
-       //go through all modes
-       //////
-
-       //renormalize weights
-       for (iMode = 0; iMode < nModes; iMode++)
-       {
-               pGMM[iMode].weight = pGMM[iMode].weight/totalWeight;
-       }
-       
-       //make new mode if needed and exit
-       if (!bFitsPDF)
-       {
-               if (nModes==m_nM)
-               {
+                //update variance
+                float varnew = var + k*(dist2-var);
+                //limit the variance                
+                pGauss->variance = MIN(m_fVarMax,MAX(varnew,m_fVarMin));
+
+                //sort
+                //all other weights are at the same place and 
+                //only the matched (iModes) is higher -> just find the new place for it             
+                for (int iLocal = iMode;iLocal>0;iLocal--)
+                {
+                    //check one up
+                    if (weight < (pGMM[iLocal-1].weight))
+                    {
+                        break;
+                    }
+                    else
+                    {
+                        //swap one up
+                        CvPBGMMGaussian temp = pGMM[iLocal];
+                        pGMM[iLocal] = pGMM[iLocal-1];
+                        pGMM[iLocal-1] = temp;
+                        pGauss--;
+                    }
+                }
+                //belongs to the mode - bFitsPDF becomes 1
+                /////
+            }
+        }//!bFitsPDF)
+
+        //check prune
+        if (weight<-m_fPrune)
+        {
+            weight=0.0;
+            nModes--;
+        }
+
+        pGauss->weight=weight;//update weight by the calculated value
+        totalWeight+=weight;
+    }
+    //go through all modes
+    //////
+
+    //renormalize weights
+    for (iMode = 0; iMode < nModes; iMode++)
+    {
+        pGMM[iMode].weight = pGMM[iMode].weight/totalWeight;
+    }
+    
+    //make new mode if needed and exit
+    if (!bFitsPDF)
+    {
+        if (nModes==m_nM)
+        {
            //replace the weakest
-                       pGauss=pGMM+m_nM-1;
-               }
-               else
-               {
+            pGauss=pGMM+m_nM-1;
+        }
+        else
+        {
            //add a new one
-                       pGauss=pGMM+nModes;
-                       nModes++;
-               }
-
-       if (nModes==1)
-               {
-                       pGauss->weight=1;
-               }
-               else
-               {
-                       pGauss->weight=m_fAlphaT;
-
-                       //renormalize all weights
-                       for (iMode = 0; iMode < nModes-1; iMode++)
-                       {
-                               pGMM[iMode].weight *=m_fOneMinAlpha;
-                       }
-               }
-
-               //init 
-               memcpy(pGauss->mean,data,nD*sizeof(float));
-               pGauss->variance=m_fVarInit;
-
-               //sort
-               //find the new place for it
-               for (int iLocal = nModes-1;iLocal>0;iLocal--)
-               {
-                                       //check one up
-                                       if (m_fAlphaT < (pGMM[iLocal-1].weight))
-                                       {
-                                               break;
-                                       }
-                                       else
-                                       {
-                                               //swap one up
-                                               CvPBGMMGaussian temp = pGMM[iLocal];
-                                               pGMM[iLocal] = pGMM[iLocal-1];
-                                               pGMM[iLocal-1] = temp;
-                                       }
-               }
-       }
-
-       //set the number of modes
-       *pModesUsed=nModes;
+            pGauss=pGMM+nModes;
+            nModes++;
+        }
+
+        if (nModes==1)
+        {
+            pGauss->weight=1;
+        }
+        else
+        {
+            pGauss->weight=m_fAlphaT;
+
+            //renormalize all weights
+            for (iMode = 0; iMode < nModes-1; iMode++)
+            {
+                pGMM[iMode].weight *=m_fOneMinAlpha;
+            }
+        }
+
+        //init 
+        memcpy(pGauss->mean,data,nD*sizeof(float));
+        pGauss->variance=m_fVarInit;
+
+        //sort
+        //find the new place for it
+        for (int iLocal = nModes-1;iLocal>0;iLocal--)
+        {
+                    //check one up
+                    if (m_fAlphaT < (pGMM[iLocal-1].weight))
+                    {
+                        break;
+                    }
+                    else
+                    {
+                        //swap one up
+                        CvPBGMMGaussian temp = pGMM[iLocal];
+                        pGMM[iLocal] = pGMM[iLocal-1];
+                        pGMM[iLocal-1] = temp;
+                    }
+        }
+    }
+
+    //set the number of modes
+    *pModesUsed=nModes;
 
     return bBackground;
 }
 
 // a bit more efficient implementation for common case of 3 channel (rgb) images
 CV_INLINE int _icvUpdateGMM_C3(float r,float g, float b,
-                                                               unsigned char* pModesUsed, 
-                                                               CvPBGMMGaussian* pGMM,
-                                                               int m_nM,
-                                                               float m_fAlphaT,
-                                                               float m_fTb,
-                                                               float m_fTB,    
-                                                               float m_fTg,
-                                                               float m_fVarInit,
-                                                               float m_fVarMax,
-                                                               float m_fVarMin,
-                                                               float m_fPrune)
+                                unsigned char* pModesUsed, 
+                                CvPBGMMGaussian* pGMM,
+                                int m_nM,
+                                float m_fAlphaT,
+                                float m_fTb,
+                                float m_fTB,    
+                                float m_fTg,
+                                float m_fVarInit,
+                                float m_fVarMax,
+                                float m_fVarMin,
+                                float m_fPrune)
 {
-       //calculate distances to the modes (+ sort)
-       //here we need to go in descending order!!!     
-       bool bBackground=0;//return value -> true - the pixel classified as background
-
-       //internal:
-       bool bFitsPDF=0;//if it remains zero a new GMM mode will be added       
-       float m_fOneMinAlpha=1-m_fAlphaT;
-       unsigned char nModes=*pModesUsed;//current number of modes in GMM
-       float totalWeight=0.0f;
-
-       //////
-       //go through all modes
-       int iMode=0;
-       CvPBGMMGaussian* pGauss=pGMM;
-       for (;iMode<nModes;iMode++,pGauss++)
-       {
-               float weight = pGauss->weight;//need only weight if fit is found
-               weight=m_fOneMinAlpha*weight+m_fPrune;
-
-               ////
-               //fit not found yet
-               if (!bFitsPDF)
-               {
-                       //check if it belongs to some of the remaining modes
-                       float var=pGauss->variance;
-
-                       //calculate difference and distance
-                       float muR = pGauss->mean[0];
-                       float muG = pGauss->mean[1];
-                       float muB = pGauss->mean[2];
-               
-                       float dR=muR - r;
-                       float dG=muG - g;
-                       float dB=muB - b;
-
-                       float dist2=(dR*dR+dG*dG+dB*dB);                
-                       
-                       //background? - m_fTb - usually larger than m_fTg
-                       if ((totalWeight<m_fTB)&&(dist2<m_fTb*var))
-                                       bBackground=1;
-
-                       //check fit
-                       if (dist2<m_fTg*var)
-                       {
-                               /////
-                               //belongs to the mode - bFitsPDF becomes 1
-                               bFitsPDF=1;
-
-                               //update distribution                           
-                               
-                               //update weight
-                               weight+=m_fAlphaT;
-                               
-                               float k = m_fAlphaT/weight;
-
-                               //update mean
-                               pGauss->mean[0] = muR - k*(dR);
-                               pGauss->mean[1] = muG - k*(dG);
-                               pGauss->mean[2] = muB - k*(dB);
-
-                               //update variance
-                               float varnew = var + k*(dist2-var);
-                               //limit the variance                            
-                               pGauss->variance = MIN(m_fVarMax,MAX(varnew,m_fVarMin));
-
-                               //sort
-                               //all other weights are at the same place and 
-                               //only the matched (iModes) is higher -> just find the new place for it                         
-                               for (int iLocal = iMode;iLocal>0;iLocal--)
-                               {
-                                       //check one up
-                                       if (weight < (pGMM[iLocal-1].weight))
-                                       {
-                                               break;
-                                       }
-                                       else
-                                       {
-                                               //swap one up
-                                               CvPBGMMGaussian temp = pGMM[iLocal];
-                                               pGMM[iLocal] = pGMM[iLocal-1];
-                                               pGMM[iLocal-1] = temp;
-                                               pGauss--;
-                                       }
-                               }
-                               //belongs to the mode - bFitsPDF becomes 1
-                               /////
-                       }       
-
-               }//!bFitsPDF)
-               
-               //check prunning
-               if (weight<-m_fPrune)
-               {
-                                       weight=0.0;
-                                       nModes--;
-               }
-
-               pGauss->weight=weight;
-               totalWeight+=weight;
-       }
-       //go through all modes
-       //////
-
-       //renormalize weights
-       for (iMode = 0; iMode < nModes; iMode++)
-       {
-               pGMM[iMode].weight = pGMM[iMode].weight/totalWeight;
-       }
-       
-       //make new mode if needed and exit
-       if (!bFitsPDF)
-       {
-               if (nModes==m_nM)
-               {
+    //calculate distances to the modes (+ sort)
+    //here we need to go in descending order!!! 
+    bool bBackground=0;//return value -> true - the pixel classified as background
+
+    //internal:
+    bool bFitsPDF=0;//if it remains zero a new GMM mode will be added   
+    float m_fOneMinAlpha=1-m_fAlphaT;
+    unsigned char nModes=*pModesUsed;//current number of modes in GMM
+    float totalWeight=0.0f;
+
+    //////
+    //go through all modes
+    int iMode=0;
+    CvPBGMMGaussian* pGauss=pGMM;
+    for (;iMode<nModes;iMode++,pGauss++)
+    {
+        float weight = pGauss->weight;//need only weight if fit is found
+        weight=m_fOneMinAlpha*weight+m_fPrune;
+
+        ////
+        //fit not found yet
+        if (!bFitsPDF)
+        {
+            //check if it belongs to some of the remaining modes
+            float var=pGauss->variance;
+
+            //calculate difference and distance
+            float muR = pGauss->mean[0];
+            float muG = pGauss->mean[1];
+            float muB = pGauss->mean[2];
+        
+            float dR=muR - r;
+            float dG=muG - g;
+            float dB=muB - b;
+
+            float dist2=(dR*dR+dG*dG+dB*dB);        
+            
+            //background? - m_fTb - usually larger than m_fTg
+            if ((totalWeight<m_fTB)&&(dist2<m_fTb*var))
+                    bBackground=1;
+
+            //check fit
+            if (dist2<m_fTg*var)
+            {
+                /////
+                //belongs to the mode - bFitsPDF becomes 1
+                bFitsPDF=1;
+
+                //update distribution               
+                
+                //update weight
+                weight+=m_fAlphaT;
+                
+                float k = m_fAlphaT/weight;
+
+                //update mean
+                pGauss->mean[0] = muR - k*(dR);
+                pGauss->mean[1] = muG - k*(dG);
+                pGauss->mean[2] = muB - k*(dB);
+
+                //update variance
+                float varnew = var + k*(dist2-var);
+                //limit the variance                
+                pGauss->variance = MIN(m_fVarMax,MAX(varnew,m_fVarMin));
+
+                //sort
+                //all other weights are at the same place and 
+                //only the matched (iModes) is higher -> just find the new place for it             
+                for (int iLocal = iMode;iLocal>0;iLocal--)
+                {
+                    //check one up
+                    if (weight < (pGMM[iLocal-1].weight))
+                    {
+                        break;
+                    }
+                    else
+                    {
+                        //swap one up
+                        CvPBGMMGaussian temp = pGMM[iLocal];
+                        pGMM[iLocal] = pGMM[iLocal-1];
+                        pGMM[iLocal-1] = temp;
+                        pGauss--;
+                    }
+                }
+                //belongs to the mode - bFitsPDF becomes 1
+                /////
+            }   
+
+        }//!bFitsPDF)
+        
+        //check prunning
+        if (weight<-m_fPrune)
+        {
+                    weight=0.0;
+                    nModes--;
+        }
+
+        pGauss->weight=weight;
+        totalWeight+=weight;
+    }
+    //go through all modes
+    //////
+
+    //renormalize weights
+    for (iMode = 0; iMode < nModes; iMode++)
+    {
+        pGMM[iMode].weight = pGMM[iMode].weight/totalWeight;
+    }
+    
+    //make new mode if needed and exit
+    if (!bFitsPDF)
+    {
+        if (nModes==m_nM)
+        {
            //replace the weakest
-                       pGauss=pGMM+m_nM-1;
-               }
-               else
-               {
+            pGauss=pGMM+m_nM-1;
+        }
+        else
+        {
            //add a new one
-                       pGauss=pGMM+nModes;
-                       nModes++;
-               }
-
-       if (nModes==1)
-               {
-                       pGauss->weight=1;
-               }
-               else
-               {
-                       pGauss->weight=m_fAlphaT;
-
-                       //renormalize all weights
-                       for (iMode = 0; iMode < nModes-1; iMode++)
-                       {
-                               pGMM[iMode].weight *=m_fOneMinAlpha;
-                       }
-               }
-
-               //init 
-               pGauss->mean[0]=r;
-               pGauss->mean[1]=g;
-               pGauss->mean[2]=b;
-
-               pGauss->variance=m_fVarInit;
-
-               //sort
-               //find the new place for it
-               for (int iLocal = nModes-1;iLocal>0;iLocal--)
-               {
-                                       //check one up
-                                       if (m_fAlphaT < (pGMM[iLocal-1].weight))
-                                       {
-                                               break;
-                                       }
-                                       else
-                                       {
-                                               //swap one up
-                                               CvPBGMMGaussian temp = pGMM[iLocal];
-                                               pGMM[iLocal] = pGMM[iLocal-1];
-                                               pGMM[iLocal-1] = temp;
-                                       }
-               }
-       }
-
-       //set the number of modes
-       *pModesUsed=nModes;
+            pGauss=pGMM+nModes;
+            nModes++;
+        }
+
+        if (nModes==1)
+        {
+            pGauss->weight=1;
+        }
+        else
+        {
+            pGauss->weight=m_fAlphaT;
+
+            //renormalize all weights
+            for (iMode = 0; iMode < nModes-1; iMode++)
+            {
+                pGMM[iMode].weight *=m_fOneMinAlpha;
+            }
+        }
+
+        //init 
+        pGauss->mean[0]=r;
+        pGauss->mean[1]=g;
+        pGauss->mean[2]=b;
+
+        pGauss->variance=m_fVarInit;
+
+        //sort
+        //find the new place for it
+        for (int iLocal = nModes-1;iLocal>0;iLocal--)
+        {
+                    //check one up
+                    if (m_fAlphaT < (pGMM[iLocal-1].weight))
+                    {
+                        break;
+                    }
+                    else
+                    {
+                        //swap one up
+                        CvPBGMMGaussian temp = pGMM[iLocal];
+                        pGMM[iLocal] = pGMM[iLocal-1];
+                        pGMM[iLocal-1] = temp;
+                    }
+        }
+    }
+
+    //set the number of modes
+    *pModesUsed=nModes;
 
     return bBackground;
 }
 
 //the main function to update the background model
 void icvUpdatePixelBackgroundGMM2( const CvArr* srcarr, CvArr* dstarr ,
-                                                                                CvPBGMMGaussian *pGMM,
-                                                                                unsigned char *pUsedModes,
-                                                                                //CvGaussBGStatModel2Params* pGMMPar,
-                                                                                int nM,
-                                                                                float fTb, 
-                                                                                float fTB, 
-                                                                                float fTg, 
-                                                                                float fVarInit,
-                                                                                float fVarMax,
-                                                                                float fVarMin,
-                                                                                float fCT,
-                                                                                float fTau,
-                                                                                bool bShadowDetection,
-                                                                                unsigned char  nShadowDetection,
-                                                                                float alpha)
+                                         CvPBGMMGaussian *pGMM,
+                                         unsigned char *pUsedModes,
+                                         //CvGaussBGStatModel2Params* pGMMPar,
+                                         int nM,
+                                         float fTb, 
+                                         float fTB, 
+                                         float fTg, 
+                                         float fVarInit,
+                                         float fVarMax,
+                                         float fVarMin,
+                                         float fCT,
+                                         float fTau,
+                                         bool bShadowDetection,
+                                         unsigned char  nShadowDetection,
+                                         float alpha)
 {
-       CvMat sstub, *src = cvGetMat(srcarr, &sstub);
+    CvMat sstub, *src = cvGetMat(srcarr, &sstub);
     CvMat dstub, *dst = cvGetMat(dstarr, &dstub);
     CvSize size = cvGetMatSize(src);
-       int nD=CV_MAT_CN(src->type);
+    int nD=CV_MAT_CN(src->type);
 
-       //reshape if possible
+    //reshape if possible
     if( CV_IS_MAT_CONT(src->type & dst->type) )
     {
         size.width *= size.height;
@@ -687,258 +686,258 @@ void icvUpdatePixelBackgroundGMM2( const CvArr* srcarr, CvArr* dstarr ,
     }
 
     int x, y;
-       float data[CV_BGFG_MOG2_NDMAX];
-       float prune=-alpha*fCT;
-
-       //general nD
-
-       if (nD!=3)
-       {
-       switch (CV_MAT_DEPTH(src->type))
-       {
-       case CV_8U:
-               for( y = 0; y < size.height; y++ )
-               {
-                       uchar* sptr = src->data.ptr + src->step*y;
-                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
-                       for( x = 0; x < size.width; x++,
-                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
-                       {
-                               //convert data
-                               for (int iD=0;iD<nD;iD++) data[iD]=float(sptr[iD]);
-                               //update GMM model
-                               int result = _icvUpdateGMM(data,nD,pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
-                               //detect shadows in the foreground
-                               if (bShadowDetection)
-                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
-                               //generate output
-                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
-                       }
-               }
-               break;
-       case CV_16S:
-               for( y = 0; y < size.height; y++ )
-               {
-                       short* sptr = src->data.s + src->step*y;
-                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
-                       for( x = 0; x < size.width; x++,
-                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
-                       {
-                               //convert data
-                               for (int iD=0;iD<nD;iD++) data[iD]=float(sptr[iD]);
-                               //update GMM model
-                               int result = _icvUpdateGMM(data,nD,pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
-                               //detect shadows in the foreground
-                               if (bShadowDetection)
-                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
-                               //generate output
-                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
-                       }
-               }
-               break;
-       case CV_16U:
-               for( y = 0; y < size.height; y++ )
-               {
-                       unsigned short* sptr = (unsigned short*) (src->data.s + src->step*y);
-                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
-                       for( x = 0; x < size.width; x++,
-                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
-                       {
-                               //convert data
-                               for (int iD=0;iD<nD;iD++) data[iD]=float(sptr[iD]);
-                               //update GMM model
-                               int result = _icvUpdateGMM(data,nD,pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
-                               //detect shadows in the foreground
-                               if (bShadowDetection)
-                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
-                               //generate output
-                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
-                       }
-               }
-               break;
-       case CV_32S:
-               for( y = 0; y < size.height; y++ )
-               {
-                       int* sptr = src->data.i + src->step*y;
-                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
-                       for( x = 0; x < size.width; x++,
-                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
-                       {
-                               //convert data
-                               for (int iD=0;iD<nD;iD++) data[iD]=float(sptr[iD]);
-                               //update GMM model
-                               int result = _icvUpdateGMM(data,nD,pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
-                               //detect shadows in the foreground
-                               if (bShadowDetection)
-                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
-                               //generate output
-                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
-                       }
-               }
-               break;
-       case CV_32F:
-               for( y = 0; y < size.height; y++ )
-               {
-                       float* sptr = src->data.fl + src->step*y;
-                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
-                       for( x = 0; x < size.width; x++,
-                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
-                       {
-                               //update GMM model
-                               int result = _icvUpdateGMM(sptr,nD,pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
-                               //detect shadows in the foreground
-                               if (bShadowDetection)
-                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
-                               //generate output
-                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
-                       }
-               }
-               break;
-       case CV_64F:
-               for( y = 0; y < size.height; y++ )
-               {
-                       double* sptr = src->data.db + src->step*y;
-                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
-                       for( x = 0; x < size.width; x++,
-                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
-                       {
-                               //convert data
-                               for (int iD=0;iD<nD;iD++) data[iD]=float(sptr[iD]);
-                               //update GMM model
-                               int result = _icvUpdateGMM(data,nD,pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
-                               //detect shadows in the foreground
-                               if (bShadowDetection)
-                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
-                               //generate output
-                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
-                       }
-               }
-               break;
-       }
-       }else ///if (nD==3) - a bit faster
-       {
-       switch (CV_MAT_DEPTH(src->type))
-       {
-       case CV_8U:
-               for( y = 0; y < size.height; y++ )
-               {
-                       uchar* sptr = src->data.ptr + src->step*y;
-                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
-                       for( x = 0; x < size.width; x++,
-                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
-                       {
-                               //convert data
-                               data[0]=float(sptr[0]),data[1]=float(sptr[1]),data[2]=float(sptr[2]);
-                               //update GMM model
-                               int result = _icvUpdateGMM_C3(data[0],data[1],data[2],pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
-                               //detect shadows in the foreground
-                               if (bShadowDetection)
-                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
-                               //generate output
-                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
-                       }
-               }
-               break;
-       case CV_16S:
-               for( y = 0; y < size.height; y++ )
-               {
-                       short* sptr = src->data.s + src->step*y;
-                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
-                       for( x = 0; x < size.width; x++,
-                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
-                       {
-                               //convert data
-                               data[0]=float(sptr[0]),data[1]=float(sptr[1]),data[2]=float(sptr[2]);
-                               //update GMM model
-                               int result = _icvUpdateGMM_C3(data[0],data[1],data[2],pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
-                               //detect shadows in the foreground
-                               if (bShadowDetection)
-                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
-                               //generate output
-                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
-                       }
-               }
-               break;
-       case CV_16U:
-               for( y = 0; y < size.height; y++ )
-               {
-                       unsigned short* sptr = (unsigned short*) src->data.s + src->step*y;
-                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
-                       for( x = 0; x < size.width; x++,
-                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
-                       {
-                               //convert data
-                               data[0]=float(sptr[0]),data[1]=float(sptr[1]),data[2]=float(sptr[2]);
-                               //update GMM model
-                               int result = _icvUpdateGMM_C3(data[0],data[1],data[2],pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
-                               //detect shadows in the foreground
-                               if (bShadowDetection)
-                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
-                               //generate output
-                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
-                       }
-               }
-               break;
-       case CV_32S:
-               for( y = 0; y < size.height; y++ )
-               {
-                       int* sptr = src->data.i + src->step*y;
-                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
-                       for( x = 0; x < size.width; x++,
-                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
-                       {
-                               //convert data
-                               data[0]=float(sptr[0]),data[1]=float(sptr[1]),data[2]=float(sptr[2]);
-                               //update GMM model
-                               int result = _icvUpdateGMM_C3(data[0],data[1],data[2],pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
-                               //detect shadows in the foreground
-                               if (bShadowDetection)
-                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
-                               //generate output
-                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
-                       }
-               }
-               break;
-       case CV_32F:
-               for( y = 0; y < size.height; y++ )
-               {
-                       float* sptr = src->data.fl + src->step*y;
-                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
-                       for( x = 0; x < size.width; x++,
-                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
-                       {
-                               //update GMM model
-                               int result = _icvUpdateGMM_C3(sptr[0],sptr[1],sptr[2],pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
-                               //detect shadows in the foreground
-                               if (bShadowDetection)
-                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
-                               //generate output
-                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
-                       }
-               }
-               break;
-       case CV_64F:
-               for( y = 0; y < size.height; y++ )
-               {
-                       double* sptr = src->data.db + src->step*y;
-                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
-                       for( x = 0; x < size.width; x++,
-                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
-                       {
-                               //convert data
-                               data[0]=float(sptr[0]),data[1]=float(sptr[1]),data[2]=float(sptr[2]);
-                               //update GMM model
-                               int result = _icvUpdateGMM_C3(data[0],data[1],data[2],pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
-                               //detect shadows in the foreground
-                               if (bShadowDetection)
-                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
-                               //generate output
-                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
-                       }
-               }
-               break;
-       }
-       }//a bit faster for nD=3; 
+    float data[CV_BGFG_MOG2_NDMAX];
+    float prune=-alpha*fCT;
+
+    //general nD
+
+    if (nD!=3)
+    {
+    switch (CV_MAT_DEPTH(src->type))
+    {
+    case CV_8U:
+        for( y = 0; y < size.height; y++ )
+        {
+            uchar* sptr = src->data.ptr + src->step*y;
+            uchar* pDataOutput = dst->data.ptr + dst->step*y;
+            for( x = 0; x < size.width; x++,
+                pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+            {
+                //convert data
+                for (int iD=0;iD<nD;iD++) data[iD]=float(sptr[iD]);
+                //update GMM model
+                int result = _icvUpdateGMM(data,nD,pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                //detect shadows in the foreground
+                if (bShadowDetection)
+                    if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                //generate output
+                (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+            }
+        }
+        break;
+    case CV_16S:
+        for( y = 0; y < size.height; y++ )
+        {
+            short* sptr = src->data.s + src->step*y;
+            uchar* pDataOutput = dst->data.ptr + dst->step*y;
+            for( x = 0; x < size.width; x++,
+                pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+            {
+                //convert data
+                for (int iD=0;iD<nD;iD++) data[iD]=float(sptr[iD]);
+                //update GMM model
+                int result = _icvUpdateGMM(data,nD,pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                //detect shadows in the foreground
+                if (bShadowDetection)
+                    if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                //generate output
+                (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+            }
+        }
+        break;
+    case CV_16U:
+        for( y = 0; y < size.height; y++ )
+        {
+            unsigned short* sptr = (unsigned short*) (src->data.s + src->step*y);
+            uchar* pDataOutput = dst->data.ptr + dst->step*y;
+            for( x = 0; x < size.width; x++,
+                pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+            {
+                //convert data
+                for (int iD=0;iD<nD;iD++) data[iD]=float(sptr[iD]);
+                //update GMM model
+                int result = _icvUpdateGMM(data,nD,pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                //detect shadows in the foreground
+                if (bShadowDetection)
+                    if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                //generate output
+                (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+            }
+        }
+        break;
+    case CV_32S:
+        for( y = 0; y < size.height; y++ )
+        {
+            int* sptr = src->data.i + src->step*y;
+            uchar* pDataOutput = dst->data.ptr + dst->step*y;
+            for( x = 0; x < size.width; x++,
+                pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+            {
+                //convert data
+                for (int iD=0;iD<nD;iD++) data[iD]=float(sptr[iD]);
+                //update GMM model
+                int result = _icvUpdateGMM(data,nD,pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                //detect shadows in the foreground
+                if (bShadowDetection)
+                    if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                //generate output
+                (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+            }
+        }
+        break;
+    case CV_32F:
+        for( y = 0; y < size.height; y++ )
+        {
+            float* sptr = src->data.fl + src->step*y;
+            uchar* pDataOutput = dst->data.ptr + dst->step*y;
+            for( x = 0; x < size.width; x++,
+                pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+            {
+                //update GMM model
+                int result = _icvUpdateGMM(sptr,nD,pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                //detect shadows in the foreground
+                if (bShadowDetection)
+                    if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                //generate output
+                (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+            }
+        }
+        break;
+    case CV_64F:
+        for( y = 0; y < size.height; y++ )
+        {
+            double* sptr = src->data.db + src->step*y;
+            uchar* pDataOutput = dst->data.ptr + dst->step*y;
+            for( x = 0; x < size.width; x++,
+                pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+            {
+                //convert data
+                for (int iD=0;iD<nD;iD++) data[iD]=float(sptr[iD]);
+                //update GMM model
+                int result = _icvUpdateGMM(data,nD,pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                //detect shadows in the foreground
+                if (bShadowDetection)
+                    if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                //generate output
+                (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+            }
+        }
+        break;
+    }
+    }else ///if (nD==3) - a bit faster
+    {
+    switch (CV_MAT_DEPTH(src->type))
+    {
+    case CV_8U:
+        for( y = 0; y < size.height; y++ )
+        {
+            uchar* sptr = src->data.ptr + src->step*y;
+            uchar* pDataOutput = dst->data.ptr + dst->step*y;
+            for( x = 0; x < size.width; x++,
+                pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+            {
+                //convert data
+                data[0]=float(sptr[0]),data[1]=float(sptr[1]),data[2]=float(sptr[2]);
+                //update GMM model
+                int result = _icvUpdateGMM_C3(data[0],data[1],data[2],pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                //detect shadows in the foreground
+                if (bShadowDetection)
+                    if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                //generate output
+                (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+            }
+        }
+        break;
+    case CV_16S:
+        for( y = 0; y < size.height; y++ )
+        {
+            short* sptr = src->data.s + src->step*y;
+            uchar* pDataOutput = dst->data.ptr + dst->step*y;
+            for( x = 0; x < size.width; x++,
+                pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+            {
+                //convert data
+                data[0]=float(sptr[0]),data[1]=float(sptr[1]),data[2]=float(sptr[2]);
+                //update GMM model
+                int result = _icvUpdateGMM_C3(data[0],data[1],data[2],pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                //detect shadows in the foreground
+                if (bShadowDetection)
+                    if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                //generate output
+                (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+            }
+        }
+        break;
+    case CV_16U:
+        for( y = 0; y < size.height; y++ )
+        {
+            unsigned short* sptr = (unsigned short*) src->data.s + src->step*y;
+            uchar* pDataOutput = dst->data.ptr + dst->step*y;
+            for( x = 0; x < size.width; x++,
+                pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+            {
+                //convert data
+                data[0]=float(sptr[0]),data[1]=float(sptr[1]),data[2]=float(sptr[2]);
+                //update GMM model
+                int result = _icvUpdateGMM_C3(data[0],data[1],data[2],pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                //detect shadows in the foreground
+                if (bShadowDetection)
+                    if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                //generate output
+                (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+            }
+        }
+        break;
+    case CV_32S:
+        for( y = 0; y < size.height; y++ )
+        {
+            int* sptr = src->data.i + src->step*y;
+            uchar* pDataOutput = dst->data.ptr + dst->step*y;
+            for( x = 0; x < size.width; x++,
+                pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+            {
+                //convert data
+                data[0]=float(sptr[0]),data[1]=float(sptr[1]),data[2]=float(sptr[2]);
+                //update GMM model
+                int result = _icvUpdateGMM_C3(data[0],data[1],data[2],pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                //detect shadows in the foreground
+                if (bShadowDetection)
+                    if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                //generate output
+                (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+            }
+        }
+        break;
+    case CV_32F:
+        for( y = 0; y < size.height; y++ )
+        {
+            float* sptr = src->data.fl + src->step*y;
+            uchar* pDataOutput = dst->data.ptr + dst->step*y;
+            for( x = 0; x < size.width; x++,
+                pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+            {
+                //update GMM model
+                int result = _icvUpdateGMM_C3(sptr[0],sptr[1],sptr[2],pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                //detect shadows in the foreground
+                if (bShadowDetection)
+                    if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                //generate output
+                (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+            }
+        }
+        break;
+    case CV_64F:
+        for( y = 0; y < size.height; y++ )
+        {
+            double* sptr = src->data.db + src->step*y;
+            uchar* pDataOutput = dst->data.ptr + dst->step*y;
+            for( x = 0; x < size.width; x++,
+                pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+            {
+                //convert data
+                data[0]=float(sptr[0]),data[1]=float(sptr[1]),data[2]=float(sptr[2]);
+                //update GMM model
+                int result = _icvUpdateGMM_C3(data[0],data[1],data[2],pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                //detect shadows in the foreground
+                if (bShadowDetection)
+                    if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                //generate output
+                (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+            }
+        }
+        break;
+    }
+    }//a bit faster for nD=3; 
 }
 
 
@@ -953,93 +952,95 @@ CV_IMPL CvBGStatModel*
 cvCreateGaussianBGModel2( IplImage* first_frame, CvGaussBGStatModel2Params* parameters )
 {
     CvGaussBGModel2* bg_model = 0;
-       int w,h;
+    int w,h;
     
     CV_FUNCNAME( "cvCreateGaussianBGModel2" );
     
     __BEGIN__;
 
-       CvGaussBGStatModel2Params params;
+    CvGaussBGStatModel2Params params;
     
     if( !CV_IS_IMAGE(first_frame) )
         CV_ERROR( CV_StsBadArg, "Invalid or NULL first_frame parameter" );
 
-       if( first_frame->nChannels>CV_BGFG_MOG2_NDMAX )
+    if( first_frame->nChannels>CV_BGFG_MOG2_NDMAX )
         CV_ERROR( CV_StsBadArg, "Maxumum number of channels in the image is excedded (change CV_BGFG_MOG2_MAXBANDS constant)!" );
 
 
-       CV_CALL( bg_model = (CvGaussBGModel2*)cvAlloc( sizeof(*bg_model) ));
+    CV_CALL( bg_model = (CvGaussBGModel2*)cvAlloc( sizeof(*bg_model) ));
     memset( bg_model, 0, sizeof(*bg_model) );
     bg_model->type    = CV_BG_MODEL_MOG2;
     bg_model->release = (CvReleaseBGStatModel) icvReleaseGaussianBGModel2;
     bg_model->update  = (CvUpdateBGStatModel)  icvUpdateGaussianBGModel2;
 
-    //init parameters  
+    //init parameters   
     if( parameters == NULL )
-      {                        
-               /* These constants are defined in cvaux/include/cvaux.h: */
-               params.bShadowDetection = 1;
-               params.bPostFiltering=0;
-               params.minArea=CV_BGFG_MOG2_MINAREA;
-
-               //set parameters
-               // K - max number of Gaussians per pixel
-               params.nM = CV_BGFG_MOG2_NGAUSSIANS;//4;                        
-               // Tb - the threshold - n var
-               //pGMM->fTb = 4*4;
-               params.fTb = CV_BGFG_MOG2_STD_THRESHOLD*CV_BGFG_MOG2_STD_THRESHOLD;
-               // Tbf - the threshold
-               //pGMM->fTB = 0.9f;//1-cf from the paper 
-               params.fTB = CV_BGFG_MOG2_BACKGROUND_THRESHOLD;
-               // Tgenerate - the threshold
-               params.fTg = CV_BGFG_MOG2_STD_THRESHOLD_GENERATE*CV_BGFG_MOG2_STD_THRESHOLD_GENERATE;//update the mode or generate new
-               //pGMM->fSigma= 11.0f;//sigma for the new mode
-               params.fVarInit = CV_BGFG_MOG2_VAR_INIT;
-               params.fVarMax = CV_BGFG_MOG2_VAR_MAX;
-               params.fVarMin = CV_BGFG_MOG2_VAR_MIN;
-               // alpha - the learning factor
-               params.fAlphaT = 1.0f/CV_BGFG_MOG2_WINDOW_SIZE;//0.003f;
-               // complexity reduction prior constant
-               params.fCT = CV_BGFG_MOG2_CT;//0.05f;
-
-               //shadow
-               // Shadow detection
-               params.nShadowDetection = (unsigned char)CV_BGFG_MOG2_SHADOW_VALUE;//value 0 to turn off
-               params.fTau = CV_BGFG_MOG2_SHADOW_TAU;//0.5f;// Tau - shadow threshold
+    {                        
+        memset(&params, 0, sizeof(params));
+        
+        /* These constants are defined in cvaux/include/cvaux.h: */
+        params.bShadowDetection = 1;
+        params.bPostFiltering=0;
+        params.minArea=CV_BGFG_MOG2_MINAREA;
+
+        //set parameters
+        // K - max number of Gaussians per pixel
+        params.nM = CV_BGFG_MOG2_NGAUSSIANS;//4;            
+        // Tb - the threshold - n var
+        //pGMM->fTb = 4*4;
+        params.fTb = CV_BGFG_MOG2_STD_THRESHOLD*CV_BGFG_MOG2_STD_THRESHOLD;
+        // Tbf - the threshold
+        //pGMM->fTB = 0.9f;//1-cf from the paper 
+        params.fTB = CV_BGFG_MOG2_BACKGROUND_THRESHOLD;
+        // Tgenerate - the threshold
+        params.fTg = CV_BGFG_MOG2_STD_THRESHOLD_GENERATE*CV_BGFG_MOG2_STD_THRESHOLD_GENERATE;//update the mode or generate new
+        //pGMM->fSigma= 11.0f;//sigma for the new mode
+        params.fVarInit = CV_BGFG_MOG2_VAR_INIT;
+        params.fVarMax = CV_BGFG_MOG2_VAR_MAX;
+        params.fVarMin = CV_BGFG_MOG2_VAR_MIN;
+        // alpha - the learning factor
+        params.fAlphaT = 1.0f/CV_BGFG_MOG2_WINDOW_SIZE;//0.003f;
+        // complexity reduction prior constant
+        params.fCT = CV_BGFG_MOG2_CT;//0.05f;
+
+        //shadow
+        // Shadow detection
+        params.nShadowDetection = (unsigned char)CV_BGFG_MOG2_SHADOW_VALUE;//value 0 to turn off
+        params.fTau = CV_BGFG_MOG2_SHADOW_TAU;//0.5f;// Tau - shadow threshold
     }
     else
     {
         params = *parameters;
     }
 
-       bg_model->params = params;
+    bg_model->params = params;
 
-       //image data 
-       w = first_frame->width;
-       h = first_frame->height;
+    //image data 
+    w = first_frame->width;
+    h = first_frame->height;
 
-       bg_model->params.nWidth = w;
-       bg_model->params.nHeight = h;
+    bg_model->params.nWidth = w;
+    bg_model->params.nHeight = h;
 
-       bg_model->params.nND = first_frame->nChannels;
+    bg_model->params.nND = first_frame->nChannels;
 
 
-       //allocate GMM data
+    //allocate GMM data
 
-       //GMM for each pixel
-       bg_model->data.rGMM = (CvPBGMMGaussian*) malloc(w*h * params.nM * sizeof(CvPBGMMGaussian));
-       //used modes per pixel
-       bg_model->data.rnUsedModes = (unsigned char* ) malloc(w*h);
-       memset(bg_model->data.rnUsedModes,0,w*h);//no modes used
+    //GMM for each pixel
+    bg_model->data.rGMM = (CvPBGMMGaussian*) malloc(w*h * params.nM * sizeof(CvPBGMMGaussian));
+    //used modes per pixel
+    bg_model->data.rnUsedModes = (unsigned char* ) malloc(w*h);
+    memset(bg_model->data.rnUsedModes,0,w*h);//no modes used
   
     //prepare storages    
     CV_CALL( bg_model->background = cvCreateImage(cvSize(w,h), IPL_DEPTH_8U, first_frame->nChannels));
     CV_CALL( bg_model->foreground = cvCreateImage(cvSize(w,h), IPL_DEPTH_8U, 1));
     
-       //for eventual filtering
+    //for eventual filtering
     CV_CALL( bg_model->storage = cvCreateMemStorage());
-       
-       bg_model->countFrames = 0;
+    
+    bg_model->countFrames = 0;
 
     __END__;
     
@@ -1072,8 +1073,8 @@ icvReleaseGaussianBGModel2( CvGaussBGModel2** _bg_model )
     {
         CvGaussBGModel2* bg_model = *_bg_model;
 
-               free (bg_model->data.rGMM);
-               free (bg_model->data.rnUsedModes);
+        free (bg_model->data.rGMM);
+        free (bg_model->data.rnUsedModes);
 
         cvReleaseImage( &bg_model->background );
         cvReleaseImage( &bg_model->foreground );
@@ -1089,87 +1090,87 @@ icvReleaseGaussianBGModel2( CvGaussBGModel2** _bg_model )
 static int CV_CDECL
 icvUpdateGaussianBGModel2( IplImage* curr_frame, CvGaussBGModel2*  bg_model )
 { 
-       //checks        
-       if ((curr_frame->height!=bg_model->params.nHeight)||(curr_frame->width!=bg_model->params.nWidth)||(curr_frame->nChannels!=bg_model->params.nND))
-               CV_Error( CV_StsBadSize, "the image not the same size as the reserved GMM background model");
-
-       float alpha=bg_model->params.fAlphaT;
-       bg_model->countFrames++;
-       
-       //faster initial updates - increase value of alpha
-       if (bg_model->params.bInit){
-               float alphaInit=(1.0f/(2*bg_model->countFrames+1));
-               if (alphaInit>alpha)
-               {
-                       alpha = alphaInit;
-               }
-               else
-               {
-                       bg_model->params.bInit = 0;
-               }
-       }
-
-       //update background
-       //icvUpdatePixelBackgroundGMM2( curr_frame, bg_model->foreground, bg_model->data.rGMM,bg_model->data.rnUsedModes,&(bg_model->params),alpha);
-       icvUpdatePixelBackgroundGMM2( curr_frame, bg_model->foreground, bg_model->data.rGMM,bg_model->data.rnUsedModes,
-               bg_model->params.nM,
-               bg_model->params.fTb,
-               bg_model->params.fTB,
-               bg_model->params.fTg,
-               bg_model->params.fVarInit,
-               bg_model->params.fVarMax,
-               bg_model->params.fVarMin,
-               bg_model->params.fCT,
-               bg_model->params.fTau,
-               bg_model->params.bShadowDetection,
-               bg_model->params.nShadowDetection,
-               alpha);
-
-       //foreground filtering
-       if (bg_model->params.bPostFiltering==1)
-       {
-               int region_count = 0;
-               CvSeq *first_seq = NULL, *prev_seq = NULL, *seq = NULL;
-
-
-               //filter small regions
-               cvClearMemStorage(bg_model->storage);
-
-               cvMorphologyEx( bg_model->foreground, bg_model->foreground, 0, 0, CV_MOP_OPEN, 1 );
-               cvMorphologyEx( bg_model->foreground, bg_model->foreground, 0, 0, CV_MOP_CLOSE, 1 );
-
-               cvFindContours( bg_model->foreground, bg_model->storage, &first_seq, sizeof(CvContour), CV_RETR_LIST );
-               for( seq = first_seq; seq; seq = seq->h_next )
-               {
-                       CvContour* cnt = (CvContour*)seq;
-                       if( cnt->rect.width * cnt->rect.height < bg_model->params.minArea )
-                       {
-                               //delete small contour
-                               prev_seq = seq->h_prev;
-                               if( prev_seq )
-                               {
-                                       prev_seq->h_next = seq->h_next;
-                                       if( seq->h_next ) seq->h_next->h_prev = prev_seq;
-                               }
-                               else
-                               {
-                                       first_seq = seq->h_next;
-                                       if( seq->h_next ) seq->h_next->h_prev = NULL;
-                               }
-                       }
-                       else
-                       {
-                               region_count++;
-                       }
-               }
-               bg_model->foreground_regions = first_seq;
-               cvZero(bg_model->foreground);
-               cvDrawContours(bg_model->foreground, first_seq, CV_RGB(0, 0, 255), CV_RGB(0, 0, 255), 10, -1);
-
-               return region_count; 
-       }
-
-       return 1;
+    //checks    
+    if ((curr_frame->height!=bg_model->params.nHeight)||(curr_frame->width!=bg_model->params.nWidth)||(curr_frame->nChannels!=bg_model->params.nND))
+        CV_Error( CV_StsBadSize, "the image not the same size as the reserved GMM background model");
+
+    float alpha=bg_model->params.fAlphaT;
+    bg_model->countFrames++;
+    
+    //faster initial updates - increase value of alpha
+    if (bg_model->params.bInit){
+        float alphaInit=(1.0f/(2*bg_model->countFrames+1));
+        if (alphaInit>alpha)
+        {
+            alpha = alphaInit;
+        }
+        else
+        {
+            bg_model->params.bInit = 0;
+        }
+    }
+
+    //update background
+    //icvUpdatePixelBackgroundGMM2( curr_frame, bg_model->foreground, bg_model->data.rGMM,bg_model->data.rnUsedModes,&(bg_model->params),alpha);
+    icvUpdatePixelBackgroundGMM2( curr_frame, bg_model->foreground, bg_model->data.rGMM,bg_model->data.rnUsedModes,
+        bg_model->params.nM,
+        bg_model->params.fTb,
+        bg_model->params.fTB,
+        bg_model->params.fTg,
+        bg_model->params.fVarInit,
+        bg_model->params.fVarMax,
+        bg_model->params.fVarMin,
+        bg_model->params.fCT,
+        bg_model->params.fTau,
+        bg_model->params.bShadowDetection,
+        bg_model->params.nShadowDetection,
+        alpha);
+
+    //foreground filtering
+    if (bg_model->params.bPostFiltering==1)
+    {
+        int region_count = 0;
+        CvSeq *first_seq = NULL, *prev_seq = NULL, *seq = NULL;
+
+
+        //filter small regions
+        cvClearMemStorage(bg_model->storage);
+
+        cvMorphologyEx( bg_model->foreground, bg_model->foreground, 0, 0, CV_MOP_OPEN, 1 );
+        cvMorphologyEx( bg_model->foreground, bg_model->foreground, 0, 0, CV_MOP_CLOSE, 1 );
+
+        cvFindContours( bg_model->foreground, bg_model->storage, &first_seq, sizeof(CvContour), CV_RETR_LIST );
+        for( seq = first_seq; seq; seq = seq->h_next )
+        {
+            CvContour* cnt = (CvContour*)seq;
+            if( cnt->rect.width * cnt->rect.height < bg_model->params.minArea )
+            {
+                //delete small contour
+                prev_seq = seq->h_prev;
+                if( prev_seq )
+                {
+                    prev_seq->h_next = seq->h_next;
+                    if( seq->h_next ) seq->h_next->h_prev = prev_seq;
+                }
+                else
+                {
+                    first_seq = seq->h_next;
+                    if( seq->h_next ) seq->h_next->h_prev = NULL;
+                }
+            }
+            else
+            {
+                region_count++;
+            }
+        }
+        bg_model->foreground_regions = first_seq;
+        cvZero(bg_model->foreground);
+        cvDrawContours(bg_model->foreground, first_seq, CV_RGB(0, 0, 255), CV_RGB(0, 0, 255), 10, -1);
+
+        return region_count; 
+    }
+
+    return 1;
 }
 
 
@@ -1196,19 +1197,19 @@ BackgroundSubtractorMOG2::BackgroundSubtractorMOG2()
     
     nframes = 0;
     history = defaultHistory2;
-       varThreshold = defaultVarThreshold2;
-       bShadowDetection = 1;
-
-       nmixtures = defaultNMixtures2;   
-       backgroundRatio = defaultBackgroundRatio2;
-       fVarInit = defaultVarInit2;
-       fVarMax  = defaultVarMax2;
-       fVarMin = defaultVarMin2;
-
-       varThresholdGen = defaultVarThresholdGen2;
-       fCT = defaultfCT2;
-       nShadowDetection =  defaultnShadowDetection2;
-       fTau = defaultfTau;
+    varThreshold = defaultVarThreshold2;
+    bShadowDetection = 1;
+
+    nmixtures = defaultNMixtures2;   
+    backgroundRatio = defaultBackgroundRatio2;
+    fVarInit = defaultVarInit2;
+    fVarMax  = defaultVarMax2;
+    fVarMin = defaultVarMin2;
+
+    varThresholdGen = defaultVarThresholdGen2;
+    fCT = defaultfCT2;
+    nShadowDetection =  defaultnShadowDetection2;
+    fTau = defaultfTau;
 }
     
 BackgroundSubtractorMOG2::BackgroundSubtractorMOG2(int _history,  float _varThreshold, bool _bShadowDetection)
@@ -1218,19 +1219,19 @@ BackgroundSubtractorMOG2::BackgroundSubtractorMOG2(int _history,  float _varThre
     
     nframes = 0;
     history = _history > 0 ? _history : defaultHistory2;
-       varThreshold = (_varThreshold>0)? _varThreshold : defaultVarThreshold2;
-       bShadowDetection = _bShadowDetection;
-
-       nmixtures = defaultNMixtures2;   
-       backgroundRatio = defaultBackgroundRatio2;
-       fVarInit = defaultVarInit2;
-       fVarMax  = defaultVarMax2;
-       fVarMin = defaultVarMin2;
-
-       varThresholdGen = defaultVarThresholdGen2;
-       fCT = defaultfCT2;
-       nShadowDetection =  defaultnShadowDetection2;
-       fTau = defaultfTau;
+    varThreshold = (_varThreshold>0)? _varThreshold : defaultVarThreshold2;
+    bShadowDetection = _bShadowDetection;
+
+    nmixtures = defaultNMixtures2;   
+    backgroundRatio = defaultBackgroundRatio2;
+    fVarInit = defaultVarInit2;
+    fVarMax  = defaultVarMax2;
+    fVarMin = defaultVarMin2;
+
+    varThresholdGen = defaultVarThresholdGen2;
+    fCT = defaultfCT2;
+    nShadowDetection =  defaultnShadowDetection2;
+    fTau = defaultfTau;
 }
     
 BackgroundSubtractorMOG2::~BackgroundSubtractorMOG2()
@@ -1245,15 +1246,15 @@ void BackgroundSubtractorMOG2::initialize(Size _frameSize, int _frameType)
     nframes = 0;
     
     int nchannels = CV_MAT_CN(frameType);
-       CV_Assert( nchannels <= CV_BGFG_MOG2_NDMAX );
+    CV_Assert( nchannels <= CV_BGFG_MOG2_NDMAX );
     
     // for each gaussian mixture of each pixel bg model we store ...
     // the mixture weight (w),
     // the mean (nchannels values) and
     // the covariance
     bgmodel.create( 1, frameSize.height*frameSize.width*nmixtures*(2 + CV_BGFG_MOG2_NDMAX), CV_32F );
-       //make the array for keeping track of the used modes per pixel - all zeros at start
-       bgmodelUsedModes.create(frameSize,CV_8U);
+    //make the array for keeping track of the used modes per pixel - all zeros at start
+    bgmodelUsedModes.create(frameSize,CV_8U);
     bgmodelUsedModes = Scalar::all(0);
 }
 
@@ -1273,22 +1274,22 @@ void BackgroundSubtractorMOG2::operator()(InputArray _image, OutputArray _fgmask
     CV_Assert(learningRate >= 0);
     CvMat _cimage = image, _cfgmask = fgmask;
     
-       if (learningRate > 0) 
-               icvUpdatePixelBackgroundGMM2( &_cimage, &_cfgmask, 
-               (CvPBGMMGaussian*) bgmodel.data,
-               bgmodelUsedModes.data,
-               nmixtures,//nM
-               varThreshold,//fTb
-               backgroundRatio,//fTB
-               varThresholdGen,//fTg,
-               fVarInit,
-               fVarMax,
-               fVarMin,
-               fCT,
-               fTau,
-               bShadowDetection,
-               nShadowDetection,
-               float(learningRate));
+    if (learningRate > 0) 
+        icvUpdatePixelBackgroundGMM2( &_cimage, &_cfgmask, 
+        (CvPBGMMGaussian*) bgmodel.data,
+        bgmodelUsedModes.data,
+        nmixtures,//nM
+        varThreshold,//fTb
+        backgroundRatio,//fTB
+        varThresholdGen,//fTg,
+        fVarInit,
+        fVarMax,
+        fVarMin,
+        fCT,
+        fTau,
+        bShadowDetection,
+        nShadowDetection,
+        float(learningRate));
 }
 
 void BackgroundSubtractorMOG2::getBackgroundImage(OutputArray backgroundImage) const