Merge branch '2.4'
authorAndrey Kamaev <andrey.kamaev@itseez.com>
Fri, 5 Apr 2013 15:52:42 +0000 (19:52 +0400)
committerAndrey Kamaev <andrey.kamaev@itseez.com>
Fri, 5 Apr 2013 17:11:59 +0000 (21:11 +0400)
88 files changed:
1  2 
CMakeLists.txt
cmake/OpenCVFindLibsGrfmt.cmake
cmake/OpenCVFindLibsPerf.cmake
cmake/OpenCVFindLibsVideo.cmake
cmake/checks/win32uitest.cpp
cmake/templates/cvconfig.h.cmake
doc/tutorials/features2d/feature_description/feature_description.rst
doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.rst
doc/tutorials/introduction/linux_eclipse/linux_eclipse.rst
modules/calib3d/test/test_solvepnp_ransac.cpp
modules/calib3d/test/test_stereomatching.cpp
modules/contrib/doc/facerec/facerec_tutorial.rst
modules/contrib/include/opencv2/contrib/contrib.hpp
modules/contrib/src/ba.cpp
modules/core/doc/intro.rst
modules/core/include/opencv2/core/core.hpp
modules/core/include/opencv2/core/cvdef.h
modules/core/include/opencv2/core/mat.hpp
modules/core/include/opencv2/core/mat.inl.hpp
modules/core/src/lapack.cpp
modules/core/src/matop.cpp
modules/core/src/matrix.cpp
modules/core/test/test_arithm.cpp
modules/features2d/doc/feature_detection_and_description.rst
modules/features2d/src/keypoint.cpp
modules/flann/include/opencv2/flann/dist.h
modules/gpu/CMakeLists.txt
modules/gpu/perf/perf_video.cpp
modules/gpu/src/tvl1flow.cpp
modules/highgui/CMakeLists.txt
modules/highgui/include/opencv2/highgui/highgui_c.h
modules/highgui/perf/perf_precomp.hpp
modules/highgui/src/cap.cpp
modules/highgui/src/cap_dshow.cpp
modules/highgui/src/cap_ffmpeg.cpp
modules/highgui/src/cap_ffmpeg_impl.hpp
modules/highgui/src/precomp.hpp
modules/highgui/src/window.cpp
modules/highgui/test/test_ffmpeg.cpp
modules/highgui/test/test_gui.cpp
modules/highgui/test/test_precomp.hpp
modules/imgproc/src/imgwarp.cpp
modules/java/CMakeLists.txt
modules/java/android_test/src/org/opencv/test/features2d/BruteForceHammingDescriptorMatcherTest.java
modules/java/generator/src/java/core+MatOfDMatch.java
modules/legacy/src/calibfilter.cpp
modules/legacy/src/epilines.cpp
modules/nonfree/test/test_precomp.hpp
modules/ocl/CMakeLists.txt
modules/ocl/include/opencv2/ocl.hpp
modules/ocl/perf/main.cpp
modules/ocl/perf/precomp.cpp
modules/ocl/perf/precomp.hpp
modules/ocl/src/fft.cpp
modules/ocl/src/initialization.cpp
modules/ocl/src/mcwutil.cpp
modules/ocl/src/opencl/arithm_absdiff.cl
modules/ocl/src/opencl/arithm_addWeighted.cl
modules/ocl/src/opencl/arithm_add_scalar.cl
modules/ocl/src/opencl/arithm_add_scalar_mask.cl
modules/ocl/src/opencl/arithm_bitwise_and.cl
modules/ocl/src/opencl/arithm_bitwise_and_mask.cl
modules/ocl/src/opencl/arithm_bitwise_and_scalar.cl
modules/ocl/src/opencl/arithm_bitwise_and_scalar_mask.cl
modules/ocl/src/opencl/arithm_bitwise_not.cl
modules/ocl/src/opencl/arithm_bitwise_or.cl
modules/ocl/src/opencl/arithm_bitwise_or_mask.cl
modules/ocl/src/opencl/arithm_bitwise_or_scalar.cl
modules/ocl/src/opencl/arithm_bitwise_or_scalar_mask.cl
modules/ocl/src/opencl/arithm_bitwise_xor.cl
modules/ocl/src/opencl/arithm_bitwise_xor_mask.cl
modules/ocl/src/opencl/arithm_bitwise_xor_scalar.cl
modules/ocl/src/opencl/arithm_bitwise_xor_scalar_mask.cl
modules/ocl/src/opencl/arithm_compare_eq.cl
modules/ocl/src/opencl/arithm_compare_ne.cl
modules/ocl/src/opencl/arithm_div.cl
modules/ocl/src/opencl/arithm_flip.cl
modules/ocl/src/opencl/arithm_mul.cl
modules/ocl/src/opencl/stereobp.cl
modules/ocl/src/stereobp.cpp
modules/ocl/test/test_calib3d.cpp
modules/python/src2/cv2.cpp
modules/stitching/include/opencv2/stitching/detail/warpers.hpp
modules/stitching/src/matchers.cpp
modules/video/src/tvl1flow.cpp
samples/cpp/Qt_sample/main.cpp
samples/gpu/super_resolution.cpp
samples/python2/dft.py

diff --cc CMakeLists.txt
@@@ -118,10 -118,11 +118,11 @@@ OCV_OPTION(WITH_CUFFT          "Includ
  OCV_OPTION(WITH_CUBLAS         "Include NVidia Cuda Basic Linear Algebra Subprograms (BLAS) library support" OFF IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS) )
  OCV_OPTION(WITH_NVCUVID        "Include NVidia Video Decoding library support"                               OFF IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS AND NOT APPLE) )
  OCV_OPTION(WITH_EIGEN          "Include Eigen2/Eigen3 support"               ON)
+ OCV_OPTION(WITH_VFW            "Include Video for Windows support"           ON   IF WIN32 )
  OCV_OPTION(WITH_FFMPEG         "Include FFMPEG support"                      ON   IF (NOT ANDROID AND NOT IOS))
  OCV_OPTION(WITH_GSTREAMER      "Include Gstreamer support"                   ON   IF (UNIX AND NOT APPLE AND NOT ANDROID) )
 +OCV_OPTION(WITH_GSTREAMER_1_X  "Include Gstreamer 1.x support"               OFF)
  OCV_OPTION(WITH_GTK            "Include GTK support"                         ON   IF (UNIX AND NOT APPLE AND NOT ANDROID) )
 -OCV_OPTION(WITH_IMAGEIO        "ImageIO support for OS X"                    OFF  IF APPLE )
  OCV_OPTION(WITH_IPP            "Include Intel IPP support"                   OFF  IF (MSVC OR X86 OR X86_64) )
  OCV_OPTION(WITH_JASPER         "Include JPEG2K support"                      ON   IF (NOT IOS) )
  OCV_OPTION(WITH_JPEG           "Include JPEG support"                        ON)
@@@ -139,13 -140,13 +141,14 @@@ OCV_OPTION(WITH_CSTRIPES       "Includ
  OCV_OPTION(WITH_TIFF           "Include TIFF support"                        ON   IF (NOT IOS) )
  OCV_OPTION(WITH_UNICAP         "Include Unicap support (GPL)"                OFF  IF (UNIX AND NOT APPLE AND NOT ANDROID) )
  OCV_OPTION(WITH_V4L            "Include Video 4 Linux support"               ON   IF (UNIX AND NOT ANDROID) )
- OCV_OPTION(WITH_VIDEOINPUT     "Build HighGUI with DirectShow support"       ON   IF WIN32 )
+ OCV_OPTION(WITH_DSHOW          "Build HighGUI with DirectShow support"       ON   IF (WIN32 AND NOT ARM) )
+ OCV_OPTION(WITH_MSMF           "Build HighGUI with Media Foundation support" OFF  IF WIN32 )
  OCV_OPTION(WITH_XIMEA          "Include XIMEA cameras support"               OFF  IF (NOT ANDROID AND NOT APPLE) )
  OCV_OPTION(WITH_XINE           "Include Xine support (GPL)"                  OFF  IF (UNIX AND NOT APPLE AND NOT ANDROID) )
 -OCV_OPTION(WITH_OPENCL         "Include OpenCL Runtime support"              ON   IF (NOT ANDROID AND NOT IOS) )
 -OCV_OPTION(WITH_OPENCLAMDFFT   "Include AMD OpenCL FFT library support"      ON   IF (NOT ANDROID AND NOT IOS) )
 -OCV_OPTION(WITH_OPENCLAMDBLAS  "Include AMD OpenCL BLAS library support"     ON   IF (NOT ANDROID AND NOT IOS) )
 +OCV_OPTION(WITH_CLP            "Include Clp support (EPL)"                   OFF)
 +OCV_OPTION(WITH_OPENCL         "Include OpenCL Runtime support"              ON  IF (NOT ANDROID AND NOT IOS) )
 +OCV_OPTION(WITH_OPENCLAMDFFT   "Include AMD OpenCL FFT library support"      ON  IF (NOT ANDROID AND NOT IOS) )
 +OCV_OPTION(WITH_OPENCLAMDBLAS  "Include AMD OpenCL BLAS library support"     ON  IF (NOT ANDROID AND NOT IOS) )
  
  
  # OpenCV build components
Simple merge
Simple merge
@@@ -2,46 -2,26 +2,55 @@@
  #  Detect 3rd-party video IO libraries
  # ----------------------------------------------------------------------------
  
+ ocv_clear_vars(HAVE_VFW)
+ if (WITH_VFW)
+   TRY_COMPILE(HAVE_VFW
+     "${OPENCV_BINARY_DIR}/CMakeFiles/CMakeTmp"
+     "${OpenCV_SOURCE_DIR}/cmake/checks/vfwtest.cpp"
+     CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=vfw32"
+     OUTPUT_VARIABLE OUTPUT)
+  endif(WITH_VFW)
  # --- GStreamer ---
  ocv_clear_vars(HAVE_GSTREAMER)
 -if(WITH_GSTREAMER)
 -  CHECK_MODULE(gstreamer-base-0.10 HAVE_GSTREAMER)
 -  if(HAVE_GSTREAMER)
 -    CHECK_MODULE(gstreamer-app-0.10 HAVE_GSTREAMER)
 +# try to find gstreamer 0.10 first
 +if(WITH_GSTREAMER AND NOT WITH_GSTREAMER_1_X)
 +  CHECK_MODULE(gstreamer-base-0.10 HAVE_GSTREAMER_BASE)
 +  CHECK_MODULE(gstreamer-video-0.10 HAVE_GSTREAMER_VIDEO)
 +  CHECK_MODULE(gstreamer-app-0.10 HAVE_GSTREAMER_APP)
 +  CHECK_MODULE(gstreamer-riff-0.10 HAVE_GSTREAMER_RIFF)
 +  CHECK_MODULE(gstreamer-pbutils-0.10 HAVE_GSTREAMER_PBUTILS)
 +
 +  if(HAVE_GSTREAMER_BASE AND HAVE_GSTREAMER_VIDEO AND HAVE_GSTREAMER_APP AND HAVE_GSTREAMER_RIFF AND HAVE_GSTREAMER_PBUTILS)
 +      set(HAVE_GSTREAMER TRUE)
 +      set(GSTREAMER_BASE_VERSION ${ALIASOF_gstreamer-base-0.10_VERSION})
 +      set(GSTREAMER_VIDEO_VERSION ${ALIASOF_gstreamer-video-0.10_VERSION})
 +      set(GSTREAMER_APP_VERSION ${ALIASOF_gstreamer-app-0.10_VERSION})
 +      set(GSTREAMER_RIFF_VERSION ${ALIASOF_gstreamer-riff-0.10_VERSION})
 +      set(GSTREAMER_PBUTILS_VERSION ${ALIASOF_gstreamer-pbutils-0.10_VERSION})
    endif()
 -  if(HAVE_GSTREAMER)
 -    CHECK_MODULE(gstreamer-video-0.10 HAVE_GSTREAMER)
 +  
 +endif(WITH_GSTREAMER AND NOT WITH_GSTREAMER_1_X)
 +
 +# if gstreamer 0.10 was not found, or we specified we wanted 1.x, try to find it
 +if(WITH_GSTREAMER_1_X OR NOT HAVE_GSTREAMER)
 +  #check for 1.x
 +  CHECK_MODULE(gstreamer-base-1.0 HAVE_GSTREAMER_BASE)
 +  CHECK_MODULE(gstreamer-video-1.0 HAVE_GSTREAMER_VIDEO)
 +  CHECK_MODULE(gstreamer-app-1.0 HAVE_GSTREAMER_APP)
 +  CHECK_MODULE(gstreamer-riff-1.0 HAVE_GSTREAMER_RIFF)
 +  CHECK_MODULE(gstreamer-pbutils-1.0 HAVE_GSTREAMER_PBUTILS)
 +  
 +  if(HAVE_GSTREAMER_BASE AND HAVE_GSTREAMER_VIDEO AND HAVE_GSTREAMER_APP AND HAVE_GSTREAMER_RIFF AND HAVE_GSTREAMER_PBUTILS)
 +      set(HAVE_GSTREAMER TRUE)
 +      set(GSTREAMER_BASE_VERSION ${ALIASOF_gstreamer-base-1.0_VERSION})
 +      set(GSTREAMER_VIDEO_VERSION ${ALIASOF_gstreamer-video-1.0_VERSION})
 +      set(GSTREAMER_APP_VERSION ${ALIASOF_gstreamer-app-1.0_VERSION})
 +      set(GSTREAMER_RIFF_VERSION ${ALIASOF_gstreamer-riff-1.0_VERSION})
 +      set(GSTREAMER_PBUTILS_VERSION ${ALIASOF_gstreamer-pbutils-1.0_VERSION})
    endif()
 -endif(WITH_GSTREAMER)
 +  
 +endif(WITH_GSTREAMER_1_X OR NOT HAVE_GSTREAMER)
  
  # --- unicap ---
  ocv_clear_vars(HAVE_UNICAP)
index 0000000,6f13a09..f475e1c
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,11 +1,11 @@@
 -      CreateWindow(NULL /*lpClassName*/, NULL /*lpWindowName*/, 0 /*dwStyle*/, 0 /*x*/,
 -                               0 /*y*/, 0 /*nWidth*/, 0 /*nHeight*/, NULL /*hWndParent*/, NULL /*hMenu*/,
 -                              NULL /*hInstance*/,  NULL /*lpParam*/);
 -      DeleteDC(NULL);
+ #include <windows.h>
+ int main(int argc, char** argv)
+ {
 -      return 0;
++    CreateWindow(NULL /*lpClassName*/, NULL /*lpWindowName*/, 0 /*dwStyle*/, 0 /*x*/,
++                 0 /*y*/, 0 /*nWidth*/, 0 /*nHeight*/, NULL /*hWndParent*/, NULL /*hMenu*/,
++                NULL /*hInstance*/,  NULL /*lpParam*/);
++    DeleteDC(NULL);
++    return 0;
+ }
Simple merge
@@@ -48,21 -48,21 +48,21 @@@ Jav
  Application Development with Async Initialization
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
 -Using async initialization is a **recommended** way for application development. It uses the OpenCV 
 +Using async initialization is a **recommended** way for application development. It uses the OpenCV
  Manager to access OpenCV libraries externally installed in the target system.
  
 -#. Add OpenCV library project to your workspace. Use menu 
 +#. Add OpenCV library project to your workspace. Use menu
     :guilabel:`File -> Import -> Existing project in your workspace`.
  
 -   Press :guilabel:`Browse`  button and locate OpenCV4Android SDK 
 +   Press :guilabel:`Browse`  button and locate OpenCV4Android SDK
-    (:file:`OpenCV-2.4.4-android-sdk/sdk`).
+    (:file:`OpenCV-2.4.5-android-sdk/sdk`).
  
     .. image:: images/eclipse_opencv_dependency0.png
          :alt: Add dependency from OpenCV library
          :align: center
  
 -#. In application project add a reference to the OpenCV Java SDK in 
 +#. In application project add a reference to the OpenCV Java SDK in
-    :guilabel:`Project -> Properties -> Android -> Library -> Add` select ``OpenCV Library - 2.4.4``.
+    :guilabel:`Project -> Properties -> Android -> Library -> Add` select ``OpenCV Library - 2.4.5``.
  
     .. image:: images/eclipse_opencv_dependency1.png
          :alt: Add dependency from OpenCV library
@@@ -120,35 -120,35 +120,35 @@@ finalization method
  Application Development with Static Initialization
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
 -According to this approach all OpenCV binaries are included into your application package. It is 
 -designed mostly for development purposes. This approach is deprecated for the production code, 
 -release package is recommended to communicate with OpenCV Manager via the async initialization 
 +According to this approach all OpenCV binaries are included into your application package. It is
 +designed mostly for development purposes. This approach is deprecated for the production code,
 +release package is recommended to communicate with OpenCV Manager via the async initialization
  described above.
  
 -#. Add the OpenCV library project to your workspace the same way as for the async initialization 
 -   above. Use menu :guilabel:`File -> Import -> Existing project in your workspace`, 
 -   press :guilabel:`Browse` button and select OpenCV SDK path 
 +#. Add the OpenCV library project to your workspace the same way as for the async initialization
 +   above. Use menu :guilabel:`File -> Import -> Existing project in your workspace`,
 +   press :guilabel:`Browse` button and select OpenCV SDK path
-    (:file:`OpenCV-2.4.4-android-sdk/sdk`).
+    (:file:`OpenCV-2.4.5-android-sdk/sdk`).
  
     .. image:: images/eclipse_opencv_dependency0.png
          :alt: Add dependency from OpenCV library
          :align: center
  
 -#. In the application project add a reference to the OpenCV4Android SDK in 
 +#. In the application project add a reference to the OpenCV4Android SDK in
-    :guilabel:`Project -> Properties -> Android -> Library -> Add` select ``OpenCV Library - 2.4.4``;
+    :guilabel:`Project -> Properties -> Android -> Library -> Add` select ``OpenCV Library - 2.4.5``;
  
     .. image:: images/eclipse_opencv_dependency1.png
         :alt: Add dependency from OpenCV library
         :align: center
  
 -#. If your application project **doesn't have a JNI part**, just copy the corresponding OpenCV 
 +#. If your application project **doesn't have a JNI part**, just copy the corresponding OpenCV
-    native libs from :file:`<OpenCV-2.4.4-android-sdk>/sdk/native/libs/<target_arch>` to your
+    native libs from :file:`<OpenCV-2.4.5-android-sdk>/sdk/native/libs/<target_arch>` to your
     project directory to folder :file:`libs/<target_arch>`.
  
 -   In case of the application project **with a JNI part**, instead of manual libraries copying you 
 +   In case of the application project **with a JNI part**, instead of manual libraries copying you
     need to modify your ``Android.mk`` file:
 -   add the following two code lines after the ``"include $(CLEAR_VARS)"`` and before 
 +   add the following two code lines after the ``"include $(CLEAR_VARS)"`` and before
-    ``"include path_to_OpenCV-2.4.4-android-sdk/sdk/native/jni/OpenCV.mk"``
+    ``"include path_to_OpenCV-2.4.5-android-sdk/sdk/native/jni/OpenCV.mk"``
  
     .. code-block:: make
        :linenos:
  //
  //M*/
  
 -#ifndef __OPENCV_CONTRIB_HPP__
 -#define __OPENCV_CONTRIB_HPP__
 -
 -#include "opencv2/core/core.hpp"
 -#include "opencv2/imgproc/imgproc.hpp"
 -#include "opencv2/features2d/features2d.hpp"
 -#include "opencv2/objdetect/objdetect.hpp"
 -
 -#ifdef __cplusplus
 -
 -/****************************************************************************************\
 -*                                   Adaptive Skin Detector                               *
 -\****************************************************************************************/
 -
 -class CV_EXPORTS CvAdaptiveSkinDetector
 -{
 -private:
 -    enum {
 -        GSD_HUE_LT = 3,
 -        GSD_HUE_UT = 33,
 -        GSD_INTENSITY_LT = 15,
 -        GSD_INTENSITY_UT = 250
 -    };
 -
 -    class CV_EXPORTS Histogram
 -    {
 -    private:
 -        enum {
 -            HistogramSize = (GSD_HUE_UT - GSD_HUE_LT + 1)
 -        };
 -
 -    protected:
 -        int findCoverageIndex(double surfaceToCover, int defaultValue = 0);
 -
 -    public:
 -        CvHistogram *fHistogram;
 -        Histogram();
 -        virtual ~Histogram();
 -
 -        void findCurveThresholds(int &x1, int &x2, double percent = 0.05);
 -        void mergeWith(Histogram *source, double weight);
 -    };
 -
 -    int nStartCounter, nFrameCount, nSkinHueLowerBound, nSkinHueUpperBound, nMorphingMethod, nSamplingDivider;
 -    double fHistogramMergeFactor, fHuePercentCovered;
 -    Histogram histogramHueMotion, skinHueHistogram;
 -    IplImage *imgHueFrame, *imgSaturationFrame, *imgLastGrayFrame, *imgMotionFrame, *imgFilteredFrame;
 -    IplImage *imgShrinked, *imgTemp, *imgGrayFrame, *imgHSVFrame;
 -
 -protected:
 -    void initData(IplImage *src, int widthDivider, int heightDivider);
 -    void adaptiveFilter();
 -
 -public:
 -
 -    enum {
 -        MORPHING_METHOD_NONE = 0,
 -        MORPHING_METHOD_ERODE = 1,
 -        MORPHING_METHOD_ERODE_ERODE = 2,
 -        MORPHING_METHOD_ERODE_DILATE = 3
 -    };
 -
 -    CvAdaptiveSkinDetector(int samplingDivider = 1, int morphingMethod = MORPHING_METHOD_NONE);
 -    virtual ~CvAdaptiveSkinDetector();
 -
 -    virtual void process(IplImage *inputBGRImage, IplImage *outputHueMask);
 -};
 -
 -
 -/****************************************************************************************\
 - *                                  Fuzzy MeanShift Tracker                               *
 - \****************************************************************************************/
 -
 -class CV_EXPORTS CvFuzzyPoint {
 -public:
 -    double x, y, value;
 -
 -    CvFuzzyPoint(double _x, double _y);
 -};
 -
 -class CV_EXPORTS CvFuzzyCurve {
 -private:
 -    std::vector<CvFuzzyPoint> points;
 -    double value, centre;
 -
 -    bool between(double x, double x1, double x2);
 -
 -public:
 -    CvFuzzyCurve();
 -    ~CvFuzzyCurve();
 -
 -    void setCentre(double _centre);
 -    double getCentre();
 -    void clear();
 -    void addPoint(double x, double y);
 -    double calcValue(double param);
 -    double getValue();
 -    void setValue(double _value);
 -};
 -
 -class CV_EXPORTS CvFuzzyFunction {
 -public:
 -    std::vector<CvFuzzyCurve> curves;
 -
 -    CvFuzzyFunction();
 -    ~CvFuzzyFunction();
 -    void addCurve(CvFuzzyCurve *curve, double value = 0);
 -    void resetValues();
 -    double calcValue();
 -    CvFuzzyCurve *newCurve();
 -};
 -
 -class CV_EXPORTS CvFuzzyRule {
 -private:
 -    CvFuzzyCurve *fuzzyInput1, *fuzzyInput2;
 -    CvFuzzyCurve *fuzzyOutput;
 -public:
 -    CvFuzzyRule();
 -    ~CvFuzzyRule();
 -    void setRule(CvFuzzyCurve *c1, CvFuzzyCurve *c2, CvFuzzyCurve *o1);
 -    double calcValue(double param1, double param2);
 -    CvFuzzyCurve *getOutputCurve();
 -};
 -
 -class CV_EXPORTS CvFuzzyController {
 -private:
 -    std::vector<CvFuzzyRule*> rules;
 -public:
 -    CvFuzzyController();
 -    ~CvFuzzyController();
 -    void addRule(CvFuzzyCurve *c1, CvFuzzyCurve *c2, CvFuzzyCurve *o1);
 -    double calcOutput(double param1, double param2);
 -};
 -
 -class CV_EXPORTS CvFuzzyMeanShiftTracker
 -{
 -private:
 -    class FuzzyResizer
 -    {
 -    private:
 -        CvFuzzyFunction iInput, iOutput;
 -        CvFuzzyController fuzzyController;
 -    public:
 -        FuzzyResizer();
 -        int calcOutput(double edgeDensity, double density);
 -    };
 -
 -    class SearchWindow
 -    {
 -    public:
 -        FuzzyResizer *fuzzyResizer;
 -        int x, y;
 -        int width, height, maxWidth, maxHeight, ellipseHeight, ellipseWidth;
 -        int ldx, ldy, ldw, ldh, numShifts, numIters;
 -        int xGc, yGc;
 -        long m00, m01, m10, m11, m02, m20;
 -        double ellipseAngle;
 -        double density;
 -        unsigned int depthLow, depthHigh;
 -        int verticalEdgeLeft, verticalEdgeRight, horizontalEdgeTop, horizontalEdgeBottom;
 -
 -        SearchWindow();
 -        ~SearchWindow();
 -        void setSize(int _x, int _y, int _width, int _height);
 -        void initDepthValues(IplImage *maskImage, IplImage *depthMap);
 -        bool shift();
 -        void extractInfo(IplImage *maskImage, IplImage *depthMap, bool initDepth);
 -        void getResizeAttribsEdgeDensityLinear(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);
 -        void getResizeAttribsInnerDensity(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);
 -        void getResizeAttribsEdgeDensityFuzzy(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);
 -        bool meanShift(IplImage *maskImage, IplImage *depthMap, int maxIteration, bool initDepth);
 -    };
 -
 -public:
 -    enum TrackingState
 -    {
 -        tsNone          = 0,
 -        tsSearching     = 1,
 -        tsTracking      = 2,
 -        tsSetWindow     = 3,
 -        tsDisabled      = 10
 -    };
 -
 -    enum ResizeMethod {
 -        rmEdgeDensityLinear     = 0,
 -        rmEdgeDensityFuzzy      = 1,
 -        rmInnerDensity          = 2
 -    };
 -
 -    enum {
 -        MinKernelMass           = 1000
 -    };
 -
 -    SearchWindow kernel;
 -    int searchMode;
 -
 -private:
 -    enum
 -    {
 -        MaxMeanShiftIteration   = 5,
 -        MaxSetSizeIteration     = 5
 -    };
 -
 -    void findOptimumSearchWindow(SearchWindow &searchWindow, IplImage *maskImage, IplImage *depthMap, int maxIteration, int resizeMethod, bool initDepth);
 -
 -public:
 -    CvFuzzyMeanShiftTracker();
 -    ~CvFuzzyMeanShiftTracker();
 -
 -    void track(IplImage *maskImage, IplImage *depthMap, int resizeMethod, bool resetSearch, int minKernelMass = MinKernelMass);
 -};
 -
 -
 -namespace cv
 -{
 -
 -    class CV_EXPORTS Octree
 -    {
 -    public:
 -        struct Node
 -        {
 -            Node() {}
 -            int begin, end;
 -            float x_min, x_max, y_min, y_max, z_min, z_max;
 -            int maxLevels;
 -            bool isLeaf;
 -            int children[8];
 -        };
 -
 -        Octree();
 -        Octree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 );
 -        virtual ~Octree();
 -
 -        virtual void buildTree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 );
 -        virtual void getPointsWithinSphere( const Point3f& center, float radius,
 -                                           vector<Point3f>& points ) const;
 -        const vector<Node>& getNodes() const { return nodes; }
 -    private:
 -        int minPoints;
 -        vector<Point3f> points;
 -        vector<Node> nodes;
 -
 -        virtual void buildNext(size_t node_ind);
 -    };
 -
 -
 -    class CV_EXPORTS Mesh3D
 -    {
 -    public:
 -        struct EmptyMeshException {};
 -
 -        Mesh3D();
 -        Mesh3D(const vector<Point3f>& vtx);
 -        ~Mesh3D();
 -
 -        void buildOctree();
 -        void clearOctree();
 -        float estimateResolution(float tryRatio = 0.1f);
 -        void computeNormals(float normalRadius, int minNeighbors = 20);
 -        void computeNormals(const vector<int>& subset, float normalRadius, int minNeighbors = 20);
 -
 -        void writeAsVrml(const String& file, const vector<Scalar>& colors = vector<Scalar>()) const;
 -
 -        vector<Point3f> vtx;
 -        vector<Point3f> normals;
 -        float resolution;
 -        Octree octree;
 -
 -        const static Point3f allzero;
 -    };
 -
 -    class CV_EXPORTS SpinImageModel
 -    {
 -    public:
 -
 -        /* model parameters, leave unset for default or auto estimate */
 -        float normalRadius;
 -        int minNeighbors;
 -
 -        float binSize;
 -        int imageWidth;
 -
 -        float lambda;
 -        float gamma;
 -
 -        float T_GeometriccConsistency;
 -        float T_GroupingCorespondances;
 -
 -        /* public interface */
 -        SpinImageModel();
 -        explicit SpinImageModel(const Mesh3D& mesh);
 -        ~SpinImageModel();
 -
 -        void setLogger(std::ostream* log);
 -        void selectRandomSubset(float ratio);
 -        void setSubset(const vector<int>& subset);
 -        void compute();
 -
 -        void match(const SpinImageModel& scene, vector< vector<Vec2i> >& result);
 -
 -        Mat packRandomScaledSpins(bool separateScale = false, size_t xCount = 10, size_t yCount = 10) const;
 -
 -        size_t getSpinCount() const { return spinImages.rows; }
 -        Mat getSpinImage(size_t index) const { return spinImages.row((int)index); }
 -        const Point3f& getSpinVertex(size_t index) const { return mesh.vtx[subset[index]]; }
 -        const Point3f& getSpinNormal(size_t index) const { return mesh.normals[subset[index]]; }
 -
 -        const Mesh3D& getMesh() const { return mesh; }
 -        Mesh3D& getMesh() { return mesh; }
 -
 -        /* static utility functions */
 -        static bool spinCorrelation(const Mat& spin1, const Mat& spin2, float lambda, float& result);
 -
 -        static Point2f calcSpinMapCoo(const Point3f& point, const Point3f& vertex, const Point3f& normal);
 -
 -        static float geometricConsistency(const Point3f& pointScene1, const Point3f& normalScene1,
 -                                          const Point3f& pointModel1, const Point3f& normalModel1,
 -                                          const Point3f& pointScene2, const Point3f& normalScene2,
 -                                          const Point3f& pointModel2, const Point3f& normalModel2);
 -
 -        static float groupingCreteria(const Point3f& pointScene1, const Point3f& normalScene1,
 -                                      const Point3f& pointModel1, const Point3f& normalModel1,
 -                                      const Point3f& pointScene2, const Point3f& normalScene2,
 -                                      const Point3f& pointModel2, const Point3f& normalModel2,
 -                                      float gamma);
 -    protected:
 -        void defaultParams();
 -
 -        void matchSpinToModel(const Mat& spin, vector<int>& indeces,
 -                              vector<float>& corrCoeffs, bool useExtremeOutliers = true) const;
 -
 -        void repackSpinImages(const vector<uchar>& mask, Mat& spinImages, bool reAlloc = true) const;
 -
 -        vector<int> subset;
 -        Mesh3D mesh;
 -        Mat spinImages;
 -        std::ostream* out;
 -    };
 -
 -    class CV_EXPORTS TickMeter
 -    {
 -    public:
 -        TickMeter();
 -        void start();
 -        void stop();
 -
 -        int64 getTimeTicks() const;
 -        double getTimeMicro() const;
 -        double getTimeMilli() const;
 -        double getTimeSec()   const;
 -        int64 getCounter() const;
 -
 -        void reset();
 -    private:
 -        int64 counter;
 -        int64 sumTime;
 -        int64 startTime;
 -    };
 -
 -    CV_EXPORTS std::ostream& operator<<(std::ostream& out, const TickMeter& tm);
 -
 -    class CV_EXPORTS SelfSimDescriptor
 -    {
 -    public:
 -        SelfSimDescriptor();
 -        SelfSimDescriptor(int _ssize, int _lsize,
 -                          int _startDistanceBucket=DEFAULT_START_DISTANCE_BUCKET,
 -                          int _numberOfDistanceBuckets=DEFAULT_NUM_DISTANCE_BUCKETS,
 -                          int _nangles=DEFAULT_NUM_ANGLES);
 -        SelfSimDescriptor(const SelfSimDescriptor& ss);
 -        virtual ~SelfSimDescriptor();
 -        SelfSimDescriptor& operator = (const SelfSimDescriptor& ss);
 -
 -        size_t getDescriptorSize() const;
 -        Size getGridSize( Size imgsize, Size winStride ) const;
 -
 -        virtual void compute(const Mat& img, vector<float>& descriptors, Size winStride=Size(),
 -                             const vector<Point>& locations=vector<Point>()) const;
 -        virtual void computeLogPolarMapping(Mat& mappingMask) const;
 -        virtual void SSD(const Mat& img, Point pt, Mat& ssd) const;
 -
 -        int smallSize;
 -        int largeSize;
 -        int startDistanceBucket;
 -        int numberOfDistanceBuckets;
 -        int numberOfAngles;
 -
 -        enum { DEFAULT_SMALL_SIZE = 5, DEFAULT_LARGE_SIZE = 41,
 -            DEFAULT_NUM_ANGLES = 20, DEFAULT_START_DISTANCE_BUCKET = 3,
 -            DEFAULT_NUM_DISTANCE_BUCKETS = 7 };
 -    };
 -
 -
 -    typedef bool (*BundleAdjustCallback)(int iteration, double norm_error, void* user_data);
 -
 -    class CV_EXPORTS LevMarqSparse {
 -    public:
 -        LevMarqSparse();
 -        LevMarqSparse(int npoints, // number of points
 -                      int ncameras, // number of cameras
 -                      int nPointParams, // number of params per one point  (3 in case of 3D points)
 -                      int nCameraParams, // number of parameters per one camera
 -                      int nErrParams, // number of parameters in measurement vector
 -                      // for 1 point at one camera (2 in case of 2D projections)
 -                      Mat& visibility, // visibility matrix. rows correspond to points, columns correspond to cameras
 -                      // 1 - point is visible for the camera, 0 - invisible
 -                      Mat& P0, // starting vector of parameters, first cameras then points
 -                      Mat& X, // measurements, in order of visibility. non visible cases are skipped
 -                      TermCriteria criteria, // termination criteria
 -
 -                      // callback for estimation of Jacobian matrices
 -                      void (CV_CDECL * fjac)(int i, int j, Mat& point_params,
 -                                             Mat& cam_params, Mat& A, Mat& B, void* data),
 -                      // callback for estimation of backprojection errors
 -                      void (CV_CDECL * func)(int i, int j, Mat& point_params,
 -                                             Mat& cam_params, Mat& estim, void* data),
 -                      void* data, // user-specific data passed to the callbacks
 -                      BundleAdjustCallback cb, void* user_data
 -                      );
 -
 -        virtual ~LevMarqSparse();
 -
 -        virtual void run( int npoints, // number of points
 -                         int ncameras, // number of cameras
 -                         int nPointParams, // number of params per one point  (3 in case of 3D points)
 -                         int nCameraParams, // number of parameters per one camera
 -                         int nErrParams, // number of parameters in measurement vector
 -                         // for 1 point at one camera (2 in case of 2D projections)
 -                         Mat& visibility, // visibility matrix. rows correspond to points, columns correspond to cameras
 -                         // 1 - point is visible for the camera, 0 - invisible
 -                         Mat& P0, // starting vector of parameters, first cameras then points
 -                         Mat& X, // measurements, in order of visibility. non visible cases are skipped
 -                         TermCriteria criteria, // termination criteria
 -
 -                         // callback for estimation of Jacobian matrices
 -                         void (CV_CDECL * fjac)(int i, int j, Mat& point_params,
 -                                                Mat& cam_params, Mat& A, Mat& B, void* data),
 -                         // callback for estimation of backprojection errors
 -                         void (CV_CDECL * func)(int i, int j, Mat& point_params,
 -                                                Mat& cam_params, Mat& estim, void* data),
 -                         void* data // user-specific data passed to the callbacks
 -                         );
 -
 -        virtual void clear();
 -
 -        // useful function to do simple bundle adjustment tasks
 -        static void bundleAdjust(vector<Point3d>& points, // positions of points in global coordinate system (input and output)
 -                                 const vector<vector<Point2d> >& imagePoints, // projections of 3d points for every camera
 -                                 const vector<vector<int> >& visibility, // visibility of 3d points for every camera
 -                                 vector<Mat>& cameraMatrix, // intrinsic matrices of all cameras (input and output)
 -                                 vector<Mat>& R, // rotation matrices of all cameras (input and output)
 -                                 vector<Mat>& T, // translation vector of all cameras (input and output)
 -                                 vector<Mat>& distCoeffs, // distortion coefficients of all cameras (input and output)
 -                                 const TermCriteria& criteria=
 -                                 TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON),
 -                                 BundleAdjustCallback cb = 0, void* user_data = 0);
 -
 -    public:
 -        virtual void optimize(CvMat &_vis); //main function that runs minimization
 -
 -        //iteratively asks for measurement for visible camera-point pairs
 -        void ask_for_proj(CvMat &_vis,bool once=false);
 -        //iteratively asks for Jacobians for every camera_point pair
 -        void ask_for_projac(CvMat &_vis);
 -
 -        CvMat* err; //error X-hX
 -        double prevErrNorm, errNorm;
 -        double lambda;
 -        CvTermCriteria criteria;
 -        int iters;
 -
 -        CvMat** U; //size of array is equal to number of cameras
 -        CvMat** V; //size of array is equal to number of points
 -        CvMat** inv_V_star; //inverse of V*
 -
 -        CvMat** A;
 -        CvMat** B;
 -        CvMat** W;
 -
 -        CvMat* X; //measurement
 -        CvMat* hX; //current measurement extimation given new parameter vector
 -
 -        CvMat* prevP; //current already accepted parameter.
 -        CvMat* P; // parameters used to evaluate function with new params
 -        // this parameters may be rejected
 -
 -        CvMat* deltaP; //computed increase of parameters (result of normal system solution )
 -
 -        CvMat** ea; // sum_i  AijT * e_ij , used as right part of normal equation
 -        // length of array is j = number of cameras
 -        CvMat** eb; // sum_j  BijT * e_ij , used as right part of normal equation
 -        // length of array is i = number of points
 -
 -        CvMat** Yj; //length of array is i = num_points
 -
 -        CvMat* S; //big matrix of block Sjk  , each block has size num_cam_params x num_cam_params
 -
 -        CvMat* JtJ_diag; //diagonal of JtJ,  used to backup diagonal elements before augmentation
 -
 -        CvMat* Vis_index; // matrix which element is index of measurement for point i and camera j
 -
 -        int num_cams;
 -        int num_points;
 -        int num_err_param;
 -        int num_cam_param;
 -        int num_point_param;
 -
 -        //target function and jacobian pointers, which needs to be initialized
 -        void (*fjac)(int i, int j, Mat& point_params, Mat& cam_params, Mat& A, Mat& B, void* data);
 -        void (*func)(int i, int j, Mat& point_params, Mat& cam_params, Mat& estim, void* data);
 -
 -        void* data;
 -
 -        BundleAdjustCallback cb;
 -        void* user_data;
 -    };
 -
 -    CV_EXPORTS_W int chamerMatching( Mat& img, Mat& templ,
 -                                  CV_OUT vector<vector<Point> >& results, CV_OUT vector<float>& cost,
 -                                  double templScale=1, int maxMatches = 20,
 -                                  double minMatchDistance = 1.0, int padX = 3,
 -                                  int padY = 3, int scales = 5, double minScale = 0.6, double maxScale = 1.6,
 -                                  double orientationWeight = 0.5, double truncate = 20);
 -
 -
 -    class CV_EXPORTS_W StereoVar
 -    {
 -    public:
 -        // Flags
 -        enum {USE_INITIAL_DISPARITY = 1, USE_EQUALIZE_HIST = 2, USE_SMART_ID = 4, USE_AUTO_PARAMS = 8, USE_MEDIAN_FILTERING = 16};
 -        enum {CYCLE_O, CYCLE_V};
 -        enum {PENALIZATION_TICHONOV, PENALIZATION_CHARBONNIER, PENALIZATION_PERONA_MALIK};
 -
 -        //! the default constructor
 -        CV_WRAP StereoVar();
 -
 -        //! the full constructor taking all the necessary algorithm parameters
 -        CV_WRAP StereoVar(int levels, double pyrScale, int nIt, int minDisp, int maxDisp, int poly_n, double poly_sigma, float fi, float lambda, int penalization, int cycle, int flags);
 -
 -        //! the destructor
 -        virtual ~StereoVar();
 -
 -        //! the stereo correspondence operator that computes disparity map for the specified rectified stereo pair
 -        CV_WRAP_AS(compute) virtual void operator()(const Mat& left, const Mat& right, CV_OUT Mat& disp);
 -
 -        CV_PROP_RW int      levels;
 -        CV_PROP_RW double   pyrScale;
 -        CV_PROP_RW int      nIt;
 -        CV_PROP_RW int      minDisp;
 -        CV_PROP_RW int      maxDisp;
 -        CV_PROP_RW int      poly_n;
 -        CV_PROP_RW double   poly_sigma;
 -        CV_PROP_RW float    fi;
 -        CV_PROP_RW float    lambda;
 -        CV_PROP_RW int      penalization;
 -        CV_PROP_RW int      cycle;
 -        CV_PROP_RW int      flags;
 -
 -    private:
 -        void autoParams();
 -        void FMG(Mat &I1, Mat &I2, Mat &I2x, Mat &u, int level);
 -        void VCycle_MyFAS(Mat &I1_h, Mat &I2_h, Mat &I2x_h, Mat &u_h, int level);
 -        void VariationalSolver(Mat &I1_h, Mat &I2_h, Mat &I2x_h, Mat &u_h, int level);
 -    };
 -
 -    CV_EXPORTS void polyfit(const Mat& srcx, const Mat& srcy, Mat& dst, int order);
 -
 -    class CV_EXPORTS Directory
 -    {
 -        public:
 -            static std::vector<std::string> GetListFiles  ( const std::string& path, const std::string & exten = "*", bool addPath = true );
 -            static std::vector<std::string> GetListFilesR ( const std::string& path, const std::string & exten = "*", bool addPath = true );
 -            static std::vector<std::string> GetListFolders( const std::string& path, const std::string & exten = "*", bool addPath = true );
 -    };
 -
 -    /*
 -     * Generation of a set of different colors by the following way:
 -     * 1) generate more then need colors (in "factor" times) in RGB,
 -     * 2) convert them to Lab,
 -     * 3) choose the needed count of colors from the set that are more different from
 -     *    each other,
 -     * 4) convert the colors back to RGB
 -     */
 -    CV_EXPORTS void generateColors( std::vector<Scalar>& colors, size_t count, size_t factor=100 );
 -
 -
 -    /*
 -     *  Estimate the rigid body motion from frame0 to frame1. The method is based on the paper
 -     *  "Real-Time Visual Odometry from Dense RGB-D Images", F. Steinbucker, J. Strum, D. Cremers, ICCV, 2011.
 -     */
 -    enum { ROTATION          = 1,
 -           TRANSLATION       = 2,
 -           RIGID_BODY_MOTION = 4
 -         };
 -    CV_EXPORTS bool RGBDOdometry( Mat& Rt, const Mat& initRt,
 -                                  const Mat& image0, const Mat& depth0, const Mat& mask0,
 -                                  const Mat& image1, const Mat& depth1, const Mat& mask1,
 -                                  const Mat& cameraMatrix, float minDepth=0.f, float maxDepth=4.f, float maxDepthDiff=0.07f,
 -                                  const std::vector<int>& iterCounts=std::vector<int>(),
 -                                  const std::vector<float>& minGradientMagnitudes=std::vector<float>(),
 -                                  int transformType=RIGID_BODY_MOTION );
 -
 -    /**
 -    *Bilinear interpolation technique.
 -    *
 -    *The value of a desired cortical pixel is obtained through a bilinear interpolation of the values
 -    *of the four nearest neighbouring Cartesian pixels to the center of the RF.
 -    *The same principle is applied to the inverse transformation.
 -    *
 -    *More details can be found in http://dx.doi.org/10.1007/978-3-642-23968-7_5
 -    */
 -    class CV_EXPORTS LogPolar_Interp
 -    {
 -    public:
 -
 -        LogPolar_Interp() {}
 -
 -        /**
 -        *Constructor
 -        *\param w the width of the input image
 -        *\param h the height of the input image
 -        *\param center the transformation center: where the output precision is maximal
 -        *\param R the number of rings of the cortical image (default value 70 pixel)
 -        *\param ro0 the radius of the blind spot (default value 3 pixel)
 -        *\param full \a 1 (default value) means that the retinal image (the inverse transform) is computed within the circumscribing circle.
 -        *            \a 0 means that the retinal image is computed within the inscribed circle.
 -        *\param S the number of sectors of the cortical image (default value 70 pixel).
 -        *         Its value is usually internally computed to obtain a pixel aspect ratio equals to 1.
 -        *\param sp \a 1 (default value) means that the parameter \a S is internally computed.
 -        *          \a 0 means that the parameter \a S is provided by the user.
 -        */
 -        LogPolar_Interp(int w, int h, Point2i center, int R=70, double ro0=3.0,
 -                        int interp=INTER_LINEAR, int full=1, int S=117, int sp=1);
 -        /**
 -        *Transformation from Cartesian image to cortical (log-polar) image.
 -        *\param source the Cartesian image
 -        *\return the transformed image (cortical image)
 -        */
 -        const Mat to_cortical(const Mat &source);
 -        /**
 -        *Transformation from cortical image to retinal (inverse log-polar) image.
 -        *\param source the cortical image
 -        *\return the transformed image (retinal image)
 -        */
 -        const Mat to_cartesian(const Mat &source);
 -        /**
 -        *Destructor
 -        */
 -        ~LogPolar_Interp();
 -
 -    protected:
 -
 -        Mat Rsri;
 -        Mat Csri;
 -
 -        int S, R, M, N;
 -        int top, bottom,left,right;
 -        double ro0, romax, a, q;
 -        int interp;
 -
 -        Mat ETAyx;
 -        Mat CSIyx;
 -
 -        void create_map(int M, int N, int R, int S, double ro0);
 -    };
 -
 -    /**
 -    *Overlapping circular receptive fields technique
 -    *
 -    *The Cartesian plane is divided in two regions: the fovea and the periphery.
 -    *The fovea (oversampling) is handled by using the bilinear interpolation technique described above, whereas in
 -    *the periphery we use the overlapping Gaussian circular RFs.
 -    *
 -    *More details can be found in http://dx.doi.org/10.1007/978-3-642-23968-7_5
 -    */
 -    class CV_EXPORTS LogPolar_Overlapping
 -    {
 -    public:
 -        LogPolar_Overlapping() {}
 -
 -        /**
 -        *Constructor
 -        *\param w the width of the input image
 -        *\param h the height of the input image
 -        *\param center the transformation center: where the output precision is maximal
 -        *\param R the number of rings of the cortical image (default value 70 pixel)
 -        *\param ro0 the radius of the blind spot (default value 3 pixel)
 -        *\param full \a 1 (default value) means that the retinal image (the inverse transform) is computed within the circumscribing circle.
 -        *            \a 0 means that the retinal image is computed within the inscribed circle.
 -        *\param S the number of sectors of the cortical image (default value 70 pixel).
 -        *         Its value is usually internally computed to obtain a pixel aspect ratio equals to 1.
 -        *\param sp \a 1 (default value) means that the parameter \a S is internally computed.
 -        *          \a 0 means that the parameter \a S is provided by the user.
 -        */
 -        LogPolar_Overlapping(int w, int h, Point2i center, int R=70,
 -                             double ro0=3.0, int full=1, int S=117, int sp=1);
 -        /**
 -        *Transformation from Cartesian image to cortical (log-polar) image.
 -        *\param source the Cartesian image
 -        *\return the transformed image (cortical image)
 -        */
 -        const Mat to_cortical(const Mat &source);
 -        /**
 -        *Transformation from cortical image to retinal (inverse log-polar) image.
 -        *\param source the cortical image
 -        *\return the transformed image (retinal image)
 -        */
 -        const Mat to_cartesian(const Mat &source);
 -        /**
 -        *Destructor
 -        */
 -        ~LogPolar_Overlapping();
 -
 -    protected:
 -
 -        Mat Rsri;
 -        Mat Csri;
 -        vector<int> Rsr;
 -        vector<int> Csr;
 -        vector<double> Wsr;
 -
 -        int S, R, M, N, ind1;
 -        int top, bottom,left,right;
 -        double ro0, romax, a, q;
 -
 -        struct kernel
 -        {
 -            kernel() { w = 0; }
 -            vector<double> weights;
 -            int w;
 -        };
 -
 -        Mat ETAyx;
 -        Mat CSIyx;
 -        vector<kernel> w_ker_2D;
 -
 -        void create_map(int M, int N, int R, int S, double ro0);
 -    };
 -
 -    /**
 -    * Adjacent receptive fields technique
 -    *
 -    *All the Cartesian pixels, whose coordinates in the cortical domain share the same integer part, are assigned to the same RF.
 -    *The precision of the boundaries of the RF can be improved by breaking each pixel into subpixels and assigning each of them to the correct RF.
 -    *This technique is implemented from: Traver, V., Pla, F.: Log-polar mapping template design: From task-level requirements
 -    *to geometry parameters. Image Vision Comput. 26(10) (2008) 1354-1370
 -    *
 -    *More details can be found in http://dx.doi.org/10.1007/978-3-642-23968-7_5
 -    */
 -    class CV_EXPORTS LogPolar_Adjacent
 -    {
 -    public:
 -        LogPolar_Adjacent() {}
 -
 -        /**
 -         *Constructor
 -         *\param w the width of the input image
 -         *\param h the height of the input image
 -         *\param center the transformation center: where the output precision is maximal
 -         *\param R the number of rings of the cortical image (default value 70 pixel)
 -         *\param ro0 the radius of the blind spot (default value 3 pixel)
 -         *\param smin the size of the subpixel (default value 0.25 pixel)
 -         *\param full \a 1 (default value) means that the retinal image (the inverse transform) is computed within the circumscribing circle.
 -         *            \a 0 means that the retinal image is computed within the inscribed circle.
 -         *\param S the number of sectors of the cortical image (default value 70 pixel).
 -         *         Its value is usually internally computed to obtain a pixel aspect ratio equals to 1.
 -         *\param sp \a 1 (default value) means that the parameter \a S is internally computed.
 -         *          \a 0 means that the parameter \a S is provided by the user.
 -         */
 -        LogPolar_Adjacent(int w, int h, Point2i center, int R=70, double ro0=3.0, double smin=0.25, int full=1, int S=117, int sp=1);
 -        /**
 -         *Transformation from Cartesian image to cortical (log-polar) image.
 -         *\param source the Cartesian image
 -         *\return the transformed image (cortical image)
 -         */
 -        const Mat to_cortical(const Mat &source);
 -        /**
 -         *Transformation from cortical image to retinal (inverse log-polar) image.
 -         *\param source the cortical image
 -         *\return the transformed image (retinal image)
 -         */
 -        const Mat to_cartesian(const Mat &source);
 -        /**
 -         *Destructor
 -         */
 -        ~LogPolar_Adjacent();
 -
 -    protected:
 -        struct pixel
 -        {
 -            pixel() { u = v = 0; a = 0.; }
 -            int u;
 -            int v;
 -            double a;
 -        };
 -        int S, R, M, N;
 -        int top, bottom,left,right;
 -        double ro0, romax, a, q;
 -        vector<vector<pixel> > L;
 -        vector<double> A;
 -
 -        void subdivide_recursively(double x, double y, int i, int j, double length, double smin);
 -        bool get_uv(double x, double y, int&u, int&v);
 -        void create_map(int M, int N, int R, int S, double ro0, double smin);
 -    };
 -
 -    CV_EXPORTS Mat subspaceProject(InputArray W, InputArray mean, InputArray src);
 -    CV_EXPORTS Mat subspaceReconstruct(InputArray W, InputArray mean, InputArray src);
 -
 -    class CV_EXPORTS LDA
 -    {
 -    public:
 -        // Initializes a LDA with num_components (default 0) and specifies how
 -        // samples are aligned (default dataAsRow=true).
 -        LDA(int num_components = 0) :
 -            _num_components(num_components) {};
 -
 -        // Initializes and performs a Discriminant Analysis with Fisher's
 -        // Optimization Criterion on given data in src and corresponding labels
 -        // in labels. If 0 (or less) number of components are given, they are
 -        // automatically determined for given data in computation.
 -        LDA(const Mat& src, vector<int> labels,
 -                int num_components = 0) :
 -                    _num_components(num_components)
 -        {
 -            this->compute(src, labels); //! compute eigenvectors and eigenvalues
 -        }
 -
 -        // Initializes and performs a Discriminant Analysis with Fisher's
 -        // Optimization Criterion on given data in src and corresponding labels
 -        // in labels. If 0 (or less) number of components are given, they are
 -        // automatically determined for given data in computation.
 -        LDA(InputArrayOfArrays src, InputArray labels,
 -                int num_components = 0) :
 -                    _num_components(num_components)
 -        {
 -            this->compute(src, labels); //! compute eigenvectors and eigenvalues
 -        }
 -
 -        // Serializes this object to a given filename.
 -        void save(const string& filename) const;
 -
 -        // Deserializes this object from a given filename.
 -        void load(const string& filename);
 -
 -        // Serializes this object to a given cv::FileStorage.
 -        void save(FileStorage& fs) const;
 -
 -            // Deserializes this object from a given cv::FileStorage.
 -        void load(const FileStorage& node);
 -
 -        // Destructor.
 -        ~LDA() {}
 -
 -        //! Compute the discriminants for data in src and labels.
 -        void compute(InputArrayOfArrays src, InputArray labels);
 -
 -        // Projects samples into the LDA subspace.
 -        Mat project(InputArray src);
 -
 -        // Reconstructs projections from the LDA subspace.
 -        Mat reconstruct(InputArray src);
 -
 -        // Returns the eigenvectors of this LDA.
 -        Mat eigenvectors() const { return _eigenvectors; };
 -
 -        // Returns the eigenvalues of this LDA.
 -        Mat eigenvalues() const { return _eigenvalues; }
 -
 -    protected:
 -        bool _dataAsRow;
 -        int _num_components;
 -        Mat _eigenvectors;
 -        Mat _eigenvalues;
 -
 -        void lda(InputArrayOfArrays src, InputArray labels);
 -    };
 -
 -    class CV_EXPORTS_W FaceRecognizer : public Algorithm
 -    {
 -    public:
 -        //! virtual destructor
 -        virtual ~FaceRecognizer() {}
 -
 -        // Trains a FaceRecognizer.
 -        CV_WRAP virtual void train(InputArrayOfArrays src, InputArray labels) = 0;
 -
 -        // Updates a FaceRecognizer.
 -        CV_WRAP void update(InputArrayOfArrays src, InputArray labels);
 -
 -        // Gets a prediction from a FaceRecognizer.
 -        virtual int predict(InputArray src) const = 0;
 -
 -        // Predicts the label and confidence for a given sample.
 -        CV_WRAP virtual void predict(InputArray src, CV_OUT int &label, CV_OUT double &confidence) const = 0;
 -
 -        // Serializes this object to a given filename.
 -        CV_WRAP virtual void save(const string& filename) const;
 -
 -        // Deserializes this object from a given filename.
 -        CV_WRAP virtual void load(const string& filename);
 -
 -        // Serializes this object to a given cv::FileStorage.
 -        virtual void save(FileStorage& fs) const = 0;
 -
 -        // Deserializes this object from a given cv::FileStorage.
 -        virtual void load(const FileStorage& fs) = 0;
 -
 -    };
 -
 -    CV_EXPORTS_W Ptr<FaceRecognizer> createEigenFaceRecognizer(int num_components = 0, double threshold = DBL_MAX);
 -    CV_EXPORTS_W Ptr<FaceRecognizer> createFisherFaceRecognizer(int num_components = 0, double threshold = DBL_MAX);
 -    CV_EXPORTS_W Ptr<FaceRecognizer> createLBPHFaceRecognizer(int radius=1, int neighbors=8,
 -                                                            int grid_x=8, int grid_y=8, double threshold = DBL_MAX);
 -
 -    enum
 -    {
 -        COLORMAP_AUTUMN = 0,
 -        COLORMAP_BONE = 1,
 -        COLORMAP_JET = 2,
 -        COLORMAP_WINTER = 3,
 -        COLORMAP_RAINBOW = 4,
 -        COLORMAP_OCEAN = 5,
 -        COLORMAP_SUMMER = 6,
 -        COLORMAP_SPRING = 7,
 -        COLORMAP_COOL = 8,
 -        COLORMAP_HSV = 9,
 -        COLORMAP_PINK = 10,
 -        COLORMAP_HOT = 11
 -    };
 -
 -    CV_EXPORTS_W void applyColorMap(InputArray src, OutputArray dst, int colormap);
 -
 -    CV_EXPORTS bool initModule_contrib();
 -}
 -
 -#include "opencv2/contrib/retina.hpp"
 -
 -#include "opencv2/contrib/openfabmap.hpp"
 -
 -#endif
 -
 +#ifdef __OPENCV_BUILD
 +#error this is a compatibility header which should not be used inside the OpenCV library
  #endif
  
- #include "opencv2/contrib.hpp"
++#include "opencv2/contrib.hpp"
@@@ -1100,13 -1100,12 +1100,13 @@@ void LevMarqSparse::bundleAdjust( std::
    }
    //fill camera params
    //R.clear();T.clear();cameraMatrix.clear();
 +  Mat levmarP = cv::cvarrToMat(levmar.P);
    for( int i = 0; i < num_cameras; i++ ) {
      //rotation
 -    Mat rot_vec = Mat(levmar.P).rowRange(i*num_cam_param, i*num_cam_param+3);
 +    Mat rot_vec = levmarP.rowRange(i*num_cam_param, i*num_cam_param+3);
      Rodrigues( rot_vec, R[i] );
      //translation
-     T[i] = levmarP.rowRange(i*num_cam_param + 3, i*num_cam_param+6);
 -    Mat(levmar.P).rowRange(i*num_cam_param + 3, i*num_cam_param+6).copyTo(T[i]);
++    levmarP.rowRange(i*num_cam_param + 3, i*num_cam_param+6).copyTo(T[i]);
  
      //intrinsic camera matrix
      double* intr_data = (double*)cameraMatrix[i].data;
Simple merge
  //
  //M*/
  
 -#ifndef __OPENCV_CORE_HPP__
 -#define __OPENCV_CORE_HPP__
 -
 -#include "opencv2/core/types_c.h"
 -#include "opencv2/core/version.hpp"
 -
 -#ifdef __cplusplus
 -
 -#ifndef SKIP_INCLUDES
 -#include <limits.h>
 -#include <algorithm>
 -#include <cmath>
 -#include <cstddef>
 -#include <complex>
 -#include <map>
 -#include <new>
 -#include <string>
 -#include <vector>
 -#include <sstream>
 -#endif // SKIP_INCLUDES
 -
 -/*! \namespace cv
 -    Namespace where all the C++ OpenCV functionality resides
 -*/
 -namespace cv {
 -
 -#undef abs
 -#undef min
 -#undef max
 -#undef Complex
 -
 -using std::vector;
 -using std::string;
 -using std::ptrdiff_t;
 -
 -template<typename _Tp> class CV_EXPORTS Size_;
 -template<typename _Tp> class CV_EXPORTS Point_;
 -template<typename _Tp> class CV_EXPORTS Rect_;
 -template<typename _Tp, int cn> class CV_EXPORTS Vec;
 -template<typename _Tp, int m, int n> class CV_EXPORTS Matx;
 -
 -typedef std::string String;
 -
 -class Mat;
 -class SparseMat;
 -typedef Mat MatND;
 -
 -namespace ogl {
 -    class Buffer;
 -    class Texture2D;
 -    class Arrays;
 -}
 -
 -// < Deprecated
 -class GlBuffer;
 -class GlTexture;
 -class GlArrays;
 -class GlCamera;
 -// >
 -
 -namespace gpu {
 -    class GpuMat;
 -}
 -
 -class CV_EXPORTS MatExpr;
 -class CV_EXPORTS MatOp_Base;
 -class CV_EXPORTS MatArg;
 -class CV_EXPORTS MatConstIterator;
 -
 -template<typename _Tp> class CV_EXPORTS Mat_;
 -template<typename _Tp> class CV_EXPORTS MatIterator_;
 -template<typename _Tp> class CV_EXPORTS MatConstIterator_;
 -template<typename _Tp> class CV_EXPORTS MatCommaInitializer_;
 -
 -#if !defined(ANDROID) || (defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_WCHAR_T)
 -typedef std::basic_string<wchar_t> WString;
 -
 -CV_EXPORTS string fromUtf16(const WString& str);
 -CV_EXPORTS WString toUtf16(const string& str);
 -#endif
 -
 -CV_EXPORTS string format( const char* fmt, ... );
 -CV_EXPORTS string tempfile( const char* suffix CV_DEFAULT(0));
 -
 -// matrix decomposition types
 -enum { DECOMP_LU=0, DECOMP_SVD=1, DECOMP_EIG=2, DECOMP_CHOLESKY=3, DECOMP_QR=4, DECOMP_NORMAL=16 };
 -enum { NORM_INF=1, NORM_L1=2, NORM_L2=4, NORM_L2SQR=5, NORM_HAMMING=6, NORM_HAMMING2=7, NORM_TYPE_MASK=7, NORM_RELATIVE=8, NORM_MINMAX=32 };
 -enum { CMP_EQ=0, CMP_GT=1, CMP_GE=2, CMP_LT=3, CMP_LE=4, CMP_NE=5 };
 -enum { GEMM_1_T=1, GEMM_2_T=2, GEMM_3_T=4 };
 -enum { DFT_INVERSE=1, DFT_SCALE=2, DFT_ROWS=4, DFT_COMPLEX_OUTPUT=16, DFT_REAL_OUTPUT=32,
 -    DCT_INVERSE = DFT_INVERSE, DCT_ROWS=DFT_ROWS };
 -
 -
 -/*!
 - The standard OpenCV exception class.
 - Instances of the class are thrown by various functions and methods in the case of critical errors.
 - */
 -class CV_EXPORTS Exception : public std::exception
 -{
 -public:
 -    /*!
 -     Default constructor
 -     */
 -    Exception();
 -    /*!
 -     Full constructor. Normally the constuctor is not called explicitly.
 -     Instead, the macros CV_Error(), CV_Error_() and CV_Assert() are used.
 -    */
 -    Exception(int _code, const string& _err, const string& _func, const string& _file, int _line);
 -    virtual ~Exception() throw();
 -
 -    /*!
 -     \return the error description and the context as a text string.
 -    */
 -    virtual const char *what() const throw();
 -    void formatMessage();
 -
 -    string msg; ///< the formatted error message
 -
 -    int code; ///< error code @see CVStatus
 -    string err; ///< error description
 -    string func; ///< function name. Available only when the compiler supports __func__ macro
 -    string file; ///< source file name where the error has occured
 -    int line; ///< line number in the source file where the error has occured
 -};
 -
 -
 -//! Signals an error and raises the exception.
 -
 -/*!
 -  By default the function prints information about the error to stderr,
 -  then it either stops if setBreakOnError() had been called before or raises the exception.
 -  It is possible to alternate error processing by using redirectError().
 -
 -  \param exc the exception raisen.
 - */
 -CV_EXPORTS void error( const Exception& exc );
 -
 -//! Sets/resets the break-on-error mode.
 -
 -/*!
 -  When the break-on-error mode is set, the default error handler
 -  issues a hardware exception, which can make debugging more convenient.
 -
 -  \return the previous state
 - */
 -CV_EXPORTS bool setBreakOnError(bool flag);
 -
 -typedef int (CV_CDECL *ErrorCallback)( int status, const char* func_name,
 -                                       const char* err_msg, const char* file_name,
 -                                       int line, void* userdata );
 -
 -//! Sets the new error handler and the optional user data.
 -
 -/*!
 -  The function sets the new error handler, called from cv::error().
 -
 -  \param errCallback the new error handler. If NULL, the default error handler is used.
 -  \param userdata the optional user data pointer, passed to the callback.
 -  \param prevUserdata the optional output parameter where the previous user data pointer is stored
 -
 -  \return the previous error handler
 -*/
 -CV_EXPORTS ErrorCallback redirectError( ErrorCallback errCallback,
 -                                        void* userdata=0, void** prevUserdata=0);
 -
 -#ifdef __GNUC__
 -#define CV_Error( code, msg ) cv::error( cv::Exception(code, msg, __func__, __FILE__, __LINE__) )
 -#define CV_Error_( code, args ) cv::error( cv::Exception(code, cv::format args, __func__, __FILE__, __LINE__) )
 -#define CV_Assert( expr ) if(!!(expr)) ; else cv::error( cv::Exception(CV_StsAssert, #expr, __func__, __FILE__, __LINE__) )
 -#else
 -#define CV_Error( code, msg ) cv::error( cv::Exception(code, msg, "", __FILE__, __LINE__) )
 -#define CV_Error_( code, args ) cv::error( cv::Exception(code, cv::format args, "", __FILE__, __LINE__) )
 -#define CV_Assert( expr ) if(!!(expr)) ; else cv::error( cv::Exception(CV_StsAssert, #expr, "", __FILE__, __LINE__) )
 -#endif
 -
 -#ifdef _DEBUG
 -#define CV_DbgAssert(expr) CV_Assert(expr)
 -#else
 -#define CV_DbgAssert(expr)
 -#endif
 -
 -CV_EXPORTS void setNumThreads(int nthreads);
 -CV_EXPORTS int getNumThreads();
 -CV_EXPORTS int getThreadNum();
 -
 -CV_EXPORTS_W const string& getBuildInformation();
 -
 -//! Returns the number of ticks.
 -
 -/*!
 -  The function returns the number of ticks since the certain event (e.g. when the machine was turned on).
 -  It can be used to initialize cv::RNG or to measure a function execution time by reading the tick count
 -  before and after the function call. The granularity of ticks depends on the hardware and OS used. Use
 -  cv::getTickFrequency() to convert ticks to seconds.
 -*/
 -CV_EXPORTS_W int64 getTickCount();
 -
 -/*!
 -  Returns the number of ticks per seconds.
 -
 -  The function returns the number of ticks (as returned by cv::getTickCount()) per second.
 -  The following code computes the execution time in milliseconds:
 -
 -  \code
 -  double exec_time = (double)getTickCount();
 -  // do something ...
 -  exec_time = ((double)getTickCount() - exec_time)*1000./getTickFrequency();
 -  \endcode
 -*/
 -CV_EXPORTS_W double getTickFrequency();
 -
 -/*!
 -  Returns the number of CPU ticks.
 -
 -  On platforms where the feature is available, the function returns the number of CPU ticks
 -  since the certain event (normally, the system power-on moment). Using this function
 -  one can accurately measure the execution time of very small code fragments,
 -  for which cv::getTickCount() granularity is not enough.
 -*/
 -CV_EXPORTS_W int64 getCPUTickCount();
 -
 -/*!
 -  Returns SSE etc. support status
 -
 -  The function returns true if certain hardware features are available.
 -  Currently, the following features are recognized:
 -  - CV_CPU_MMX - MMX
 -  - CV_CPU_SSE - SSE
 -  - CV_CPU_SSE2 - SSE 2
 -  - CV_CPU_SSE3 - SSE 3
 -  - CV_CPU_SSSE3 - SSSE 3
 -  - CV_CPU_SSE4_1 - SSE 4.1
 -  - CV_CPU_SSE4_2 - SSE 4.2
 -  - CV_CPU_POPCNT - POPCOUNT
 -  - CV_CPU_AVX - AVX
 -
 -  \note {Note that the function output is not static. Once you called cv::useOptimized(false),
 -  most of the hardware acceleration is disabled and thus the function will returns false,
 -  until you call cv::useOptimized(true)}
 -*/
 -CV_EXPORTS_W bool checkHardwareSupport(int feature);
 -
 -//! returns the number of CPUs (including hyper-threading)
 -CV_EXPORTS_W int getNumberOfCPUs();
 -
 -/*!
 -  Allocates memory buffer
 -
 -  This is specialized OpenCV memory allocation function that returns properly aligned memory buffers.
 -  The usage is identical to malloc(). The allocated buffers must be freed with cv::fastFree().
 -  If there is not enough memory, the function calls cv::error(), which raises an exception.
 -
 -  \param bufSize buffer size in bytes
 -  \return the allocated memory buffer.
 -*/
 -CV_EXPORTS void* fastMalloc(size_t bufSize);
 -
 -/*!
 -  Frees the memory allocated with cv::fastMalloc
 -
 -  This is the corresponding deallocation function for cv::fastMalloc().
 -  When ptr==NULL, the function has no effect.
 -*/
 -CV_EXPORTS void fastFree(void* ptr);
 -
 -template<typename _Tp> static inline _Tp* allocate(size_t n)
 -{
 -    return new _Tp[n];
 -}
 -
 -template<typename _Tp> static inline void deallocate(_Tp* ptr, size_t)
 -{
 -    delete[] ptr;
 -}
 -
 -/*!
 -  Aligns pointer by the certain number of bytes
 -
 -  This small inline function aligns the pointer by the certian number of bytes by shifting
 -  it forward by 0 or a positive offset.
 -*/
 -template<typename _Tp> static inline _Tp* alignPtr(_Tp* ptr, int n=(int)sizeof(_Tp))
 -{
 -    return (_Tp*)(((size_t)ptr + n-1) & -n);
 -}
 -
 -/*!
 -  Aligns buffer size by the certain number of bytes
 -
 -  This small inline function aligns a buffer size by the certian number of bytes by enlarging it.
 -*/
 -static inline size_t alignSize(size_t sz, int n)
 -{
 -    return (sz + n-1) & -n;
 -}
 -
 -/*!
 -  Turns on/off available optimization
 -
 -  The function turns on or off the optimized code in OpenCV. Some optimization can not be enabled
 -  or disabled, but, for example, most of SSE code in OpenCV can be temporarily turned on or off this way.
 -
 -  \note{Since optimization may imply using special data structures, it may be unsafe
 -  to call this function anywhere in the code. Instead, call it somewhere at the top level.}
 -*/
 -CV_EXPORTS_W void setUseOptimized(bool onoff);
 -
 -/*!
 -  Returns the current optimization status
 -
 -  The function returns the current optimization status, which is controlled by cv::setUseOptimized().
 -*/
 -CV_EXPORTS_W bool useOptimized();
 -
 -/*!
 -  The STL-compilant memory Allocator based on cv::fastMalloc() and cv::fastFree()
 -*/
 -template<typename _Tp> class CV_EXPORTS Allocator
 -{
 -public:
 -    typedef _Tp value_type;
 -    typedef value_type* pointer;
 -    typedef const value_type* const_pointer;
 -    typedef value_type& reference;
 -    typedef const value_type& const_reference;
 -    typedef size_t size_type;
 -    typedef ptrdiff_t difference_type;
 -    template<typename U> class rebind { typedef Allocator<U> other; };
 -
 -    explicit Allocator() {}
 -    ~Allocator() {}
 -    explicit Allocator(Allocator const&) {}
 -    template<typename U>
 -    explicit Allocator(Allocator<U> const&) {}
 -
 -    // address
 -    pointer address(reference r) { return &r; }
 -    const_pointer address(const_reference r) { return &r; }
 -
 -    pointer allocate(size_type count, const void* =0)
 -    { return reinterpret_cast<pointer>(fastMalloc(count * sizeof (_Tp))); }
 -
 -    void deallocate(pointer p, size_type) {fastFree(p); }
 -
 -    size_type max_size() const
 -    { return max(static_cast<_Tp>(-1)/sizeof(_Tp), 1); }
 -
 -    void construct(pointer p, const _Tp& v) { new(static_cast<void*>(p)) _Tp(v); }
 -    void destroy(pointer p) { p->~_Tp(); }
 -};
 -
 -/////////////////////// Vec (used as element of multi-channel images /////////////////////
 -
 -/*!
 -  A helper class for cv::DataType
 -
 -  The class is specialized for each fundamental numerical data type supported by OpenCV.
 -  It provides DataDepth<T>::value constant.
 -*/
 -template<typename _Tp> class CV_EXPORTS DataDepth {};
 -
 -template<> class DataDepth<bool> { public: enum { value = CV_8U, fmt=(int)'u' }; };
 -template<> class DataDepth<uchar> { public: enum { value = CV_8U, fmt=(int)'u' }; };
 -template<> class DataDepth<schar> { public: enum { value = CV_8S, fmt=(int)'c' }; };
 -template<> class DataDepth<char> { public: enum { value = CV_8S, fmt=(int)'c' }; };
 -template<> class DataDepth<ushort> { public: enum { value = CV_16U, fmt=(int)'w' }; };
 -template<> class DataDepth<short> { public: enum { value = CV_16S, fmt=(int)'s' }; };
 -template<> class DataDepth<int> { public: enum { value = CV_32S, fmt=(int)'i' }; };
 -// this is temporary solution to support 32-bit unsigned integers
 -template<> class DataDepth<unsigned> { public: enum { value = CV_32S, fmt=(int)'i' }; };
 -template<> class DataDepth<float> { public: enum { value = CV_32F, fmt=(int)'f' }; };
 -template<> class DataDepth<double> { public: enum { value = CV_64F, fmt=(int)'d' }; };
 -template<typename _Tp> class DataDepth<_Tp*> { public: enum { value = CV_USRTYPE1, fmt=(int)'r' }; };
 -
 -
 -////////////////////////////// Small Matrix ///////////////////////////
 -
 -/*!
 - A short numerical vector.
 -
 - This template class represents short numerical vectors (of 1, 2, 3, 4 ... elements)
 - on which you can perform basic arithmetical operations, access individual elements using [] operator etc.
 - The vectors are allocated on stack, as opposite to std::valarray, std::vector, cv::Mat etc.,
 - which elements are dynamically allocated in the heap.
 -
 - The template takes 2 parameters:
 - -# _Tp element type
 - -# cn the number of elements
 -
 - In addition to the universal notation like Vec<float, 3>, you can use shorter aliases
 - for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec<float, 3>.
 - */
 -
 -struct CV_EXPORTS Matx_AddOp {};
 -struct CV_EXPORTS Matx_SubOp {};
 -struct CV_EXPORTS Matx_ScaleOp {};
 -struct CV_EXPORTS Matx_MulOp {};
 -struct CV_EXPORTS Matx_MatMulOp {};
 -struct CV_EXPORTS Matx_TOp {};
 -
 -template<typename _Tp, int m, int n> class CV_EXPORTS Matx
 -{
 -public:
 -    typedef _Tp value_type;
 -    typedef Matx<_Tp, (m < n ? m : n), 1> diag_type;
 -    typedef Matx<_Tp, m, n> mat_type;
 -    enum { depth = DataDepth<_Tp>::value, rows = m, cols = n, channels = rows*cols,
 -           type = CV_MAKETYPE(depth, channels) };
 -
 -    //! default constructor
 -    Matx();
 -
 -    Matx(_Tp v0); //!< 1x1 matrix
 -    Matx(_Tp v0, _Tp v1); //!< 1x2 or 2x1 matrix
 -    Matx(_Tp v0, _Tp v1, _Tp v2); //!< 1x3 or 3x1 matrix
 -    Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 1x4, 2x2 or 4x1 matrix
 -    Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 1x5 or 5x1 matrix
 -    Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 1x6, 2x3, 3x2 or 6x1 matrix
 -    Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 1x7 or 7x1 matrix
 -    Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 1x8, 2x4, 4x2 or 8x1 matrix
 -    Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 1x9, 3x3 or 9x1 matrix
 -    Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 1x10, 2x5 or 5x2 or 10x1 matrix
 -    Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
 -         _Tp v4, _Tp v5, _Tp v6, _Tp v7,
 -         _Tp v8, _Tp v9, _Tp v10, _Tp v11); //!< 1x12, 2x6, 3x4, 4x3, 6x2 or 12x1 matrix
 -    Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
 -         _Tp v4, _Tp v5, _Tp v6, _Tp v7,
 -         _Tp v8, _Tp v9, _Tp v10, _Tp v11,
 -         _Tp v12, _Tp v13, _Tp v14, _Tp v15); //!< 1x16, 4x4 or 16x1 matrix
 -    explicit Matx(const _Tp* vals); //!< initialize from a plain array
 -
 -    static Matx all(_Tp alpha);
 -    static Matx zeros();
 -    static Matx ones();
 -    static Matx eye();
 -    static Matx diag(const diag_type& d);
 -    static Matx randu(_Tp a, _Tp b);
 -    static Matx randn(_Tp a, _Tp b);
 -
 -    //! dot product computed with the default precision
 -    _Tp dot(const Matx<_Tp, m, n>& v) const;
 -
 -    //! dot product computed in double-precision arithmetics
 -    double ddot(const Matx<_Tp, m, n>& v) const;
 -
 -    //! convertion to another data type
 -    template<typename T2> operator Matx<T2, m, n>() const;
 -
 -    //! change the matrix shape
 -    template<int m1, int n1> Matx<_Tp, m1, n1> reshape() const;
 -
 -    //! extract part of the matrix
 -    template<int m1, int n1> Matx<_Tp, m1, n1> get_minor(int i, int j) const;
 -
 -    //! extract the matrix row
 -    Matx<_Tp, 1, n> row(int i) const;
 -
 -    //! extract the matrix column
 -    Matx<_Tp, m, 1> col(int i) const;
 -
 -    //! extract the matrix diagonal
 -    diag_type diag() const;
 -
 -    //! transpose the matrix
 -    Matx<_Tp, n, m> t() const;
 -
 -    //! invert matrix the matrix
 -    Matx<_Tp, n, m> inv(int method=DECOMP_LU) const;
 -
 -    //! solve linear system
 -    template<int l> Matx<_Tp, n, l> solve(const Matx<_Tp, m, l>& rhs, int flags=DECOMP_LU) const;
 -    Vec<_Tp, n> solve(const Vec<_Tp, m>& rhs, int method) const;
 -
 -    //! multiply two matrices element-wise
 -    Matx<_Tp, m, n> mul(const Matx<_Tp, m, n>& a) const;
 -
 -    //! element access
 -    const _Tp& operator ()(int i, int j) const;
 -    _Tp& operator ()(int i, int j);
 -
 -    //! 1D element access
 -    const _Tp& operator ()(int i) const;
 -    _Tp& operator ()(int i);
 -
 -    Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp);
 -    Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp);
 -    template<typename _T2> Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp);
 -    Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp);
 -    template<int l> Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp);
 -    Matx(const Matx<_Tp, n, m>& a, Matx_TOp);
 -
 -    _Tp val[m*n]; //< matrix elements
 -};
 -
 -
 -typedef Matx<float, 1, 2> Matx12f;
 -typedef Matx<double, 1, 2> Matx12d;
 -typedef Matx<float, 1, 3> Matx13f;
 -typedef Matx<double, 1, 3> Matx13d;
 -typedef Matx<float, 1, 4> Matx14f;
 -typedef Matx<double, 1, 4> Matx14d;
 -typedef Matx<float, 1, 6> Matx16f;
 -typedef Matx<double, 1, 6> Matx16d;
 -
 -typedef Matx<float, 2, 1> Matx21f;
 -typedef Matx<double, 2, 1> Matx21d;
 -typedef Matx<float, 3, 1> Matx31f;
 -typedef Matx<double, 3, 1> Matx31d;
 -typedef Matx<float, 4, 1> Matx41f;
 -typedef Matx<double, 4, 1> Matx41d;
 -typedef Matx<float, 6, 1> Matx61f;
 -typedef Matx<double, 6, 1> Matx61d;
 -
 -typedef Matx<float, 2, 2> Matx22f;
 -typedef Matx<double, 2, 2> Matx22d;
 -typedef Matx<float, 2, 3> Matx23f;
 -typedef Matx<double, 2, 3> Matx23d;
 -typedef Matx<float, 3, 2> Matx32f;
 -typedef Matx<double, 3, 2> Matx32d;
 -
 -typedef Matx<float, 3, 3> Matx33f;
 -typedef Matx<double, 3, 3> Matx33d;
 -
 -typedef Matx<float, 3, 4> Matx34f;
 -typedef Matx<double, 3, 4> Matx34d;
 -typedef Matx<float, 4, 3> Matx43f;
 -typedef Matx<double, 4, 3> Matx43d;
 -
 -typedef Matx<float, 4, 4> Matx44f;
 -typedef Matx<double, 4, 4> Matx44d;
 -typedef Matx<float, 6, 6> Matx66f;
 -typedef Matx<double, 6, 6> Matx66d;
 -
 -
 -/*!
 -  A short numerical vector.
 -
 -  This template class represents short numerical vectors (of 1, 2, 3, 4 ... elements)
 -  on which you can perform basic arithmetical operations, access individual elements using [] operator etc.
 -  The vectors are allocated on stack, as opposite to std::valarray, std::vector, cv::Mat etc.,
 -  which elements are dynamically allocated in the heap.
 -
 -  The template takes 2 parameters:
 -  -# _Tp element type
 -  -# cn the number of elements
 -
 -  In addition to the universal notation like Vec<float, 3>, you can use shorter aliases
 -  for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec<float, 3>.
 -*/
 -template<typename _Tp, int cn> class CV_EXPORTS Vec : public Matx<_Tp, cn, 1>
 -{
 -public:
 -    typedef _Tp value_type;
 -    enum { depth = DataDepth<_Tp>::value, channels = cn, type = CV_MAKETYPE(depth, channels) };
 -
 -    //! default constructor
 -    Vec();
 -
 -    Vec(_Tp v0); //!< 1-element vector constructor
 -    Vec(_Tp v0, _Tp v1); //!< 2-element vector constructor
 -    Vec(_Tp v0, _Tp v1, _Tp v2); //!< 3-element vector constructor
 -    Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 4-element vector constructor
 -    Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 5-element vector constructor
 -    Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 6-element vector constructor
 -    Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 7-element vector constructor
 -    Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 8-element vector constructor
 -    Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 9-element vector constructor
 -    Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 10-element vector constructor
 -    explicit Vec(const _Tp* values);
 -
 -    Vec(const Vec<_Tp, cn>& v);
 -
 -    static Vec all(_Tp alpha);
 -
 -    //! per-element multiplication
 -    Vec mul(const Vec<_Tp, cn>& v) const;
 -
 -    //! conjugation (makes sense for complex numbers and quaternions)
 -    Vec conj() const;
 -
 -    /*!
 -      cross product of the two 3D vectors.
 -
 -      For other dimensionalities the exception is raised
 -    */
 -    Vec cross(const Vec& v) const;
 -    //! convertion to another data type
 -    template<typename T2> operator Vec<T2, cn>() const;
 -    //! conversion to 4-element CvScalar.
 -    operator CvScalar() const;
 -
 -    /*! element access */
 -    const _Tp& operator [](int i) const;
 -    _Tp& operator[](int i);
 -    const _Tp& operator ()(int i) const;
 -    _Tp& operator ()(int i);
 -
 -    Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp);
 -    Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp);
 -    template<typename _T2> Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp);
 -};
 -
 -
 -/* \typedef
 -
 -   Shorter aliases for the most popular specializations of Vec<T,n>
 -*/
 -typedef Vec<uchar, 2> Vec2b;
 -typedef Vec<uchar, 3> Vec3b;
 -typedef Vec<uchar, 4> Vec4b;
 -
 -typedef Vec<short, 2> Vec2s;
 -typedef Vec<short, 3> Vec3s;
 -typedef Vec<short, 4> Vec4s;
 -
 -typedef Vec<ushort, 2> Vec2w;
 -typedef Vec<ushort, 3> Vec3w;
 -typedef Vec<ushort, 4> Vec4w;
 -
 -typedef Vec<int, 2> Vec2i;
 -typedef Vec<int, 3> Vec3i;
 -typedef Vec<int, 4> Vec4i;
 -typedef Vec<int, 6> Vec6i;
 -typedef Vec<int, 8> Vec8i;
 -
 -typedef Vec<float, 2> Vec2f;
 -typedef Vec<float, 3> Vec3f;
 -typedef Vec<float, 4> Vec4f;
 -typedef Vec<float, 6> Vec6f;
 -
 -typedef Vec<double, 2> Vec2d;
 -typedef Vec<double, 3> Vec3d;
 -typedef Vec<double, 4> Vec4d;
 -typedef Vec<double, 6> Vec6d;
 -
 -
 -//////////////////////////////// Complex //////////////////////////////
 -
 -/*!
 -  A complex number class.
 -
 -  The template class is similar and compatible with std::complex, however it provides slightly
 -  more convenient access to the real and imaginary parts using through the simple field access, as opposite
 -  to std::complex::real() and std::complex::imag().
 -*/
 -template<typename _Tp> class CV_EXPORTS Complex
 -{
 -public:
 -
 -    //! constructors
 -    Complex();
 -    Complex( _Tp _re, _Tp _im=0 );
 -    Complex( const std::complex<_Tp>& c );
 -
 -    //! conversion to another data type
 -    template<typename T2> operator Complex<T2>() const;
 -    //! conjugation
 -    Complex conj() const;
 -    //! conversion to std::complex
 -    operator std::complex<_Tp>() const;
 -
 -    _Tp re, im; //< the real and the imaginary parts
 -};
 -
 -
 -/*!
 -  \typedef
 -*/
 -typedef Complex<float> Complexf;
 -typedef Complex<double> Complexd;
 -
 -
 -//////////////////////////////// Point_ ////////////////////////////////
 -
 -/*!
 -  template 2D point class.
 -
 -  The class defines a point in 2D space. Data type of the point coordinates is specified
 -  as a template parameter. There are a few shorter aliases available for user convenience.
 -  See cv::Point, cv::Point2i, cv::Point2f and cv::Point2d.
 -*/
 -template<typename _Tp> class CV_EXPORTS Point_
 -{
 -public:
 -    typedef _Tp value_type;
 -
 -    // various constructors
 -    Point_();
 -    Point_(_Tp _x, _Tp _y);
 -    Point_(const Point_& pt);
 -    Point_(const CvPoint& pt);
 -    Point_(const CvPoint2D32f& pt);
 -    Point_(const Size_<_Tp>& sz);
 -    Point_(const Vec<_Tp, 2>& v);
 -
 -    Point_& operator = (const Point_& pt);
 -    //! conversion to another data type
 -    template<typename _Tp2> operator Point_<_Tp2>() const;
 -
 -    //! conversion to the old-style C structures
 -    operator CvPoint() const;
 -    operator CvPoint2D32f() const;
 -    operator Vec<_Tp, 2>() const;
 -
 -    //! dot product
 -    _Tp dot(const Point_& pt) const;
 -    //! dot product computed in double-precision arithmetics
 -    double ddot(const Point_& pt) const;
 -    //! cross-product
 -    double cross(const Point_& pt) const;
 -    //! checks whether the point is inside the specified rectangle
 -    bool inside(const Rect_<_Tp>& r) const;
 -
 -    _Tp x, y; //< the point coordinates
 -};
 -
 -/*!
 -  template 3D point class.
 -
 -  The class defines a point in 3D space. Data type of the point coordinates is specified
 -  as a template parameter.
 -
 -  \see cv::Point3i, cv::Point3f and cv::Point3d
 -*/
 -template<typename _Tp> class CV_EXPORTS Point3_
 -{
 -public:
 -    typedef _Tp value_type;
 -
 -    // various constructors
 -    Point3_();
 -    Point3_(_Tp _x, _Tp _y, _Tp _z);
 -    Point3_(const Point3_& pt);
 -    explicit Point3_(const Point_<_Tp>& pt);
 -    Point3_(const CvPoint3D32f& pt);
 -    Point3_(const Vec<_Tp, 3>& v);
 -
 -    Point3_& operator = (const Point3_& pt);
 -    //! conversion to another data type
 -    template<typename _Tp2> operator Point3_<_Tp2>() const;
 -    //! conversion to the old-style CvPoint...
 -    operator CvPoint3D32f() const;
 -    //! conversion to cv::Vec<>
 -    operator Vec<_Tp, 3>() const;
 -
 -    //! dot product
 -    _Tp dot(const Point3_& pt) const;
 -    //! dot product computed in double-precision arithmetics
 -    double ddot(const Point3_& pt) const;
 -    //! cross product of the 2 3D points
 -    Point3_ cross(const Point3_& pt) const;
 -
 -    _Tp x, y, z; //< the point coordinates
 -};
 -
 -//////////////////////////////// Size_ ////////////////////////////////
 -
 -/*!
 -  The 2D size class
 -
 -  The class represents the size of a 2D rectangle, image size, matrix size etc.
 -  Normally, cv::Size ~ cv::Size_<int> is used.
 -*/
 -template<typename _Tp> class CV_EXPORTS Size_
 -{
 -public:
 -    typedef _Tp value_type;
 -
 -    //! various constructors
 -    Size_();
 -    Size_(_Tp _width, _Tp _height);
 -    Size_(const Size_& sz);
 -    Size_(const CvSize& sz);
 -    Size_(const CvSize2D32f& sz);
 -    Size_(const Point_<_Tp>& pt);
 -
 -    Size_& operator = (const Size_& sz);
 -    //! the area (width*height)
 -    _Tp area() const;
 -
 -    //! conversion of another data type.
 -    template<typename _Tp2> operator Size_<_Tp2>() const;
 -
 -    //! conversion to the old-style OpenCV types
 -    operator CvSize() const;
 -    operator CvSize2D32f() const;
 -
 -    _Tp width, height; // the width and the height
 -};
 -
 -//////////////////////////////// Rect_ ////////////////////////////////
 -
 -/*!
 -  The 2D up-right rectangle class
 -
 -  The class represents a 2D rectangle with coordinates of the specified data type.
 -  Normally, cv::Rect ~ cv::Rect_<int> is used.
 -*/
 -template<typename _Tp> class CV_EXPORTS Rect_
 -{
 -public:
 -    typedef _Tp value_type;
 -
 -    //! various constructors
 -    Rect_();
 -    Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
 -    Rect_(const Rect_& r);
 -    Rect_(const CvRect& r);
 -    Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz);
 -    Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2);
 -
 -    Rect_& operator = ( const Rect_& r );
 -    //! the top-left corner
 -    Point_<_Tp> tl() const;
 -    //! the bottom-right corner
 -    Point_<_Tp> br() const;
 -
 -    //! size (width, height) of the rectangle
 -    Size_<_Tp> size() const;
 -    //! area (width*height) of the rectangle
 -    _Tp area() const;
 -
 -    //! conversion to another data type
 -    template<typename _Tp2> operator Rect_<_Tp2>() const;
 -    //! conversion to the old-style CvRect
 -    operator CvRect() const;
 -
 -    //! checks whether the rectangle contains the point
 -    bool contains(const Point_<_Tp>& pt) const;
 -
 -    _Tp x, y, width, height; //< the top-left corner, as well as width and height of the rectangle
 -};
 -
 -
 -/*!
 -  \typedef
 -
 -  shorter aliases for the most popular cv::Point_<>, cv::Size_<> and cv::Rect_<> specializations
 -*/
 -typedef Point_<int> Point2i;
 -typedef Point2i Point;
 -typedef Size_<int> Size2i;
 -typedef Size2i Size;
 -typedef Rect_<int> Rect;
 -typedef Point_<float> Point2f;
 -typedef Point_<double> Point2d;
 -typedef Size_<float> Size2f;
 -typedef Point3_<int> Point3i;
 -typedef Point3_<float> Point3f;
 -typedef Point3_<double> Point3d;
 -
 -
 -/*!
 -  The rotated 2D rectangle.
 -
 -  The class represents rotated (i.e. not up-right) rectangles on a plane.
 -  Each rectangle is described by the center point (mass center), length of each side
 -  (represented by cv::Size2f structure) and the rotation angle in degrees.
 -*/
 -class CV_EXPORTS RotatedRect
 -{
 -public:
 -    //! various constructors
 -    RotatedRect();
 -    RotatedRect(const Point2f& center, const Size2f& size, float angle);
 -    RotatedRect(const CvBox2D& box);
 -
 -    //! returns 4 vertices of the rectangle
 -    void points(Point2f pts[]) const;
 -    //! returns the minimal up-right rectangle containing the rotated rectangle
 -    Rect boundingRect() const;
 -    //! conversion to the old-style CvBox2D structure
 -    operator CvBox2D() const;
 -
 -    Point2f center; //< the rectangle mass center
 -    Size2f size;    //< width and height of the rectangle
 -    float angle;    //< the rotation angle. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle.
 -};
 -
 -//////////////////////////////// Scalar_ ///////////////////////////////
 -
 -/*!
 -   The template scalar class.
 -
 -   This is partially specialized cv::Vec class with the number of elements = 4, i.e. a short vector of four elements.
 -   Normally, cv::Scalar ~ cv::Scalar_<double> is used.
 -*/
 -template<typename _Tp> class CV_EXPORTS Scalar_ : public Vec<_Tp, 4>
 -{
 -public:
 -    //! various constructors
 -    Scalar_();
 -    Scalar_(_Tp v0, _Tp v1, _Tp v2=0, _Tp v3=0);
 -    Scalar_(const CvScalar& s);
 -    Scalar_(_Tp v0);
 -
 -    //! returns a scalar with all elements set to v0
 -    static Scalar_<_Tp> all(_Tp v0);
 -    //! conversion to the old-style CvScalar
 -    operator CvScalar() const;
 -
 -    //! conversion to another data type
 -    template<typename T2> operator Scalar_<T2>() const;
 -
 -    //! per-element product
 -    Scalar_<_Tp> mul(const Scalar_<_Tp>& t, double scale=1 ) const;
 -
 -    // returns (v0, -v1, -v2, -v3)
 -    Scalar_<_Tp> conj() const;
 -
 -    // returns true iff v1 == v2 == v3 == 0
 -    bool isReal() const;
 -};
 -
 -typedef Scalar_<double> Scalar;
 -
 -CV_EXPORTS void scalarToRawData(const Scalar& s, void* buf, int type, int unroll_to=0);
 -
 -//////////////////////////////// Range /////////////////////////////////
 -
 -/*!
 -   The 2D range class
 -
 -   This is the class used to specify a continuous subsequence, i.e. part of a contour, or a column span in a matrix.
 -*/
 -class CV_EXPORTS Range
 -{
 -public:
 -    Range();
 -    Range(int _start, int _end);
 -    Range(const CvSlice& slice);
 -    int size() const;
 -    bool empty() const;
 -    static Range all();
 -    operator CvSlice() const;
 -
 -    int start, end;
 -};
 -
 -/////////////////////////////// DataType ////////////////////////////////
 -
 -/*!
 -   Informative template class for OpenCV "scalars".
 -
 -   The class is specialized for each primitive numerical type supported by OpenCV (such as unsigned char or float),
 -   as well as for more complex types, like cv::Complex<>, std::complex<>, cv::Vec<> etc.
 -   The common property of all such types (called "scalars", do not confuse it with cv::Scalar_)
 -   is that each of them is basically a tuple of numbers of the same type. Each "scalar" can be represented
 -   by the depth id (CV_8U ... CV_64F) and the number of channels.
 -   OpenCV matrices, 2D or nD, dense or sparse, can store "scalars",
 -   as long as the number of channels does not exceed CV_CN_MAX.
 -*/
 -template<typename _Tp> class DataType
 -{
 -public:
 -    typedef _Tp value_type;
 -    typedef value_type work_type;
 -    typedef value_type channel_type;
 -    typedef value_type vec_type;
 -    enum { generic_type = 1, depth = -1, channels = 1, fmt=0,
 -        type = CV_MAKETYPE(depth, channels) };
 -};
 -
 -template<> class DataType<bool>
 -{
 -public:
 -    typedef bool value_type;
 -    typedef int work_type;
 -    typedef value_type channel_type;
 -    typedef value_type vec_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 1,
 -           fmt=DataDepth<channel_type>::fmt,
 -           type = CV_MAKETYPE(depth, channels) };
 -};
 -
 -template<> class DataType<uchar>
 -{
 -public:
 -    typedef uchar value_type;
 -    typedef int work_type;
 -    typedef value_type channel_type;
 -    typedef value_type vec_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 1,
 -           fmt=DataDepth<channel_type>::fmt,
 -           type = CV_MAKETYPE(depth, channels) };
 -};
 -
 -template<> class DataType<schar>
 -{
 -public:
 -    typedef schar value_type;
 -    typedef int work_type;
 -    typedef value_type channel_type;
 -    typedef value_type vec_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 1,
 -           fmt=DataDepth<channel_type>::fmt,
 -           type = CV_MAKETYPE(depth, channels) };
 -};
 -
 -template<> class DataType<char>
 -{
 -public:
 -    typedef schar value_type;
 -    typedef int work_type;
 -    typedef value_type channel_type;
 -    typedef value_type vec_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 1,
 -           fmt=DataDepth<channel_type>::fmt,
 -           type = CV_MAKETYPE(depth, channels) };
 -};
 -
 -template<> class DataType<ushort>
 -{
 -public:
 -    typedef ushort value_type;
 -    typedef int work_type;
 -    typedef value_type channel_type;
 -    typedef value_type vec_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 1,
 -           fmt=DataDepth<channel_type>::fmt,
 -           type = CV_MAKETYPE(depth, channels) };
 -};
 -
 -template<> class DataType<short>
 -{
 -public:
 -    typedef short value_type;
 -    typedef int work_type;
 -    typedef value_type channel_type;
 -    typedef value_type vec_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 1,
 -           fmt=DataDepth<channel_type>::fmt,
 -           type = CV_MAKETYPE(depth, channels) };
 -};
 -
 -template<> class DataType<int>
 -{
 -public:
 -    typedef int value_type;
 -    typedef value_type work_type;
 -    typedef value_type channel_type;
 -    typedef value_type vec_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 1,
 -           fmt=DataDepth<channel_type>::fmt,
 -           type = CV_MAKETYPE(depth, channels) };
 -};
 -
 -template<> class DataType<float>
 -{
 -public:
 -    typedef float value_type;
 -    typedef value_type work_type;
 -    typedef value_type channel_type;
 -    typedef value_type vec_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 1,
 -           fmt=DataDepth<channel_type>::fmt,
 -           type = CV_MAKETYPE(depth, channels) };
 -};
 -
 -template<> class DataType<double>
 -{
 -public:
 -    typedef double value_type;
 -    typedef value_type work_type;
 -    typedef value_type channel_type;
 -    typedef value_type vec_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 1,
 -           fmt=DataDepth<channel_type>::fmt,
 -           type = CV_MAKETYPE(depth, channels) };
 -};
 -
 -template<typename _Tp, int m, int n> class DataType<Matx<_Tp, m, n> >
 -{
 -public:
 -    typedef Matx<_Tp, m, n> value_type;
 -    typedef Matx<typename DataType<_Tp>::work_type, m, n> work_type;
 -    typedef _Tp channel_type;
 -    typedef value_type vec_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = m*n,
 -        fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
 -        type = CV_MAKETYPE(depth, channels) };
 -};
 -
 -template<typename _Tp, int cn> class DataType<Vec<_Tp, cn> >
 -{
 -public:
 -    typedef Vec<_Tp, cn> value_type;
 -    typedef Vec<typename DataType<_Tp>::work_type, cn> work_type;
 -    typedef _Tp channel_type;
 -    typedef value_type vec_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = cn,
 -           fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
 -           type = CV_MAKETYPE(depth, channels) };
 -};
 -
 -template<typename _Tp> class DataType<std::complex<_Tp> >
 -{
 -public:
 -    typedef std::complex<_Tp> value_type;
 -    typedef value_type work_type;
 -    typedef _Tp channel_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 2,
 -           fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
 -           type = CV_MAKETYPE(depth, channels) };
 -    typedef Vec<channel_type, channels> vec_type;
 -};
 -
 -template<typename _Tp> class DataType<Complex<_Tp> >
 -{
 -public:
 -    typedef Complex<_Tp> value_type;
 -    typedef value_type work_type;
 -    typedef _Tp channel_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 2,
 -           fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
 -           type = CV_MAKETYPE(depth, channels) };
 -    typedef Vec<channel_type, channels> vec_type;
 -};
 -
 -template<typename _Tp> class DataType<Point_<_Tp> >
 -{
 -public:
 -    typedef Point_<_Tp> value_type;
 -    typedef Point_<typename DataType<_Tp>::work_type> work_type;
 -    typedef _Tp channel_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 2,
 -           fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
 -           type = CV_MAKETYPE(depth, channels) };
 -    typedef Vec<channel_type, channels> vec_type;
 -};
 -
 -template<typename _Tp> class DataType<Point3_<_Tp> >
 -{
 -public:
 -    typedef Point3_<_Tp> value_type;
 -    typedef Point3_<typename DataType<_Tp>::work_type> work_type;
 -    typedef _Tp channel_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 3,
 -           fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
 -           type = CV_MAKETYPE(depth, channels) };
 -    typedef Vec<channel_type, channels> vec_type;
 -};
 -
 -template<typename _Tp> class DataType<Size_<_Tp> >
 -{
 -public:
 -    typedef Size_<_Tp> value_type;
 -    typedef Size_<typename DataType<_Tp>::work_type> work_type;
 -    typedef _Tp channel_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 2,
 -           fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
 -           type = CV_MAKETYPE(depth, channels) };
 -    typedef Vec<channel_type, channels> vec_type;
 -};
 -
 -template<typename _Tp> class DataType<Rect_<_Tp> >
 -{
 -public:
 -    typedef Rect_<_Tp> value_type;
 -    typedef Rect_<typename DataType<_Tp>::work_type> work_type;
 -    typedef _Tp channel_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 4,
 -           fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
 -           type = CV_MAKETYPE(depth, channels) };
 -    typedef Vec<channel_type, channels> vec_type;
 -};
 -
 -template<typename _Tp> class DataType<Scalar_<_Tp> >
 -{
 -public:
 -    typedef Scalar_<_Tp> value_type;
 -    typedef Scalar_<typename DataType<_Tp>::work_type> work_type;
 -    typedef _Tp channel_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 4,
 -           fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
 -           type = CV_MAKETYPE(depth, channels) };
 -    typedef Vec<channel_type, channels> vec_type;
 -};
 -
 -template<> class DataType<Range>
 -{
 -public:
 -    typedef Range value_type;
 -    typedef value_type work_type;
 -    typedef int channel_type;
 -    enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 2,
 -           fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
 -           type = CV_MAKETYPE(depth, channels) };
 -    typedef Vec<channel_type, channels> vec_type;
 -};
 -
 -//////////////////// generic_type ref-counting pointer class for C/C++ objects ////////////////////////
 -
 -/*!
 -  Smart pointer to dynamically allocated objects.
 -
 -  This is template pointer-wrapping class that stores the associated reference counter along with the
 -  object pointer. The class is similar to std::smart_ptr<> from the recent addons to the C++ standard,
 -  but is shorter to write :) and self-contained (i.e. does add any dependency on the compiler or an external library).
 -
 -  Basically, you can use "Ptr<MyObjectType> ptr" (or faster "const Ptr<MyObjectType>& ptr" for read-only access)
 -  everywhere instead of "MyObjectType* ptr", where MyObjectType is some C structure or a C++ class.
 -  To make it all work, you need to specialize Ptr<>::delete_obj(), like:
 -
 -  \code
 -  template<> void Ptr<MyObjectType>::delete_obj() { call_destructor_func(obj); }
 -  \endcode
 -
 -  \note{if MyObjectType is a C++ class with a destructor, you do not need to specialize delete_obj(),
 -  since the default implementation calls "delete obj;"}
 -
 -  \note{Another good property of the class is that the operations on the reference counter are atomic,
 -  i.e. it is safe to use the class in multi-threaded applications}
 -*/
 -template<typename _Tp> class CV_EXPORTS Ptr
 -{
 -public:
 -    //! empty constructor
 -    Ptr();
 -    //! take ownership of the pointer. The associated reference counter is allocated and set to 1
 -    Ptr(_Tp* _obj);
 -    //! calls release()
 -    ~Ptr();
 -    //! copy constructor. Copies the members and calls addref()
 -    Ptr(const Ptr& ptr);
 -    template<typename _Tp2> Ptr(const Ptr<_Tp2>& ptr);
 -    //! copy operator. Calls ptr.addref() and release() before copying the members
 -    Ptr& operator = (const Ptr& ptr);
 -    //! increments the reference counter
 -    void addref();
 -    //! decrements the reference counter. If it reaches 0, delete_obj() is called
 -    void release();
 -    //! deletes the object. Override if needed
 -    void delete_obj();
 -    //! returns true iff obj==NULL
 -    bool empty() const;
 -
 -    //! cast pointer to another type
 -    template<typename _Tp2> Ptr<_Tp2> ptr();
 -    template<typename _Tp2> const Ptr<_Tp2> ptr() const;
 -
 -    //! helper operators making "Ptr<T> ptr" use very similar to "T* ptr".
 -    _Tp* operator -> ();
 -    const _Tp* operator -> () const;
 -
 -    operator _Tp* ();
 -    operator const _Tp*() const;
 -
 -    _Tp* obj; //< the object pointer.
 -    int* refcount; //< the associated reference counter
 -};
 -
 -
 -//////////////////////// Input/Output Array Arguments /////////////////////////////////
 -
 -/*!
 - Proxy datatype for passing Mat's and vector<>'s as input parameters
 - */
 -class CV_EXPORTS _InputArray
 -{
 -public:
 -    enum {
 -        KIND_SHIFT = 16,
 -        FIXED_TYPE = 0x8000 << KIND_SHIFT,
 -        FIXED_SIZE = 0x4000 << KIND_SHIFT,
 -        KIND_MASK = ~(FIXED_TYPE|FIXED_SIZE) - (1 << KIND_SHIFT) + 1,
 -
 -        NONE              = 0 << KIND_SHIFT,
 -        MAT               = 1 << KIND_SHIFT,
 -        MATX              = 2 << KIND_SHIFT,
 -        STD_VECTOR        = 3 << KIND_SHIFT,
 -        STD_VECTOR_VECTOR = 4 << KIND_SHIFT,
 -        STD_VECTOR_MAT    = 5 << KIND_SHIFT,
 -        EXPR              = 6 << KIND_SHIFT,
 -        OPENGL_BUFFER     = 7 << KIND_SHIFT,
 -        OPENGL_TEXTURE    = 8 << KIND_SHIFT,
 -        GPU_MAT           = 9 << KIND_SHIFT
 -    };
 -    _InputArray();
 -
 -    _InputArray(const Mat& m);
 -    _InputArray(const MatExpr& expr);
 -    template<typename _Tp> _InputArray(const _Tp* vec, int n);
 -    template<typename _Tp> _InputArray(const vector<_Tp>& vec);
 -    template<typename _Tp> _InputArray(const vector<vector<_Tp> >& vec);
 -    _InputArray(const vector<Mat>& vec);
 -    template<typename _Tp> _InputArray(const vector<Mat_<_Tp> >& vec);
 -    template<typename _Tp> _InputArray(const Mat_<_Tp>& m);
 -    template<typename _Tp, int m, int n> _InputArray(const Matx<_Tp, m, n>& matx);
 -    _InputArray(const Scalar& s);
 -    _InputArray(const double& val);
 -    // < Deprecated
 -    _InputArray(const GlBuffer& buf);
 -    _InputArray(const GlTexture& tex);
 -    // >
 -    _InputArray(const gpu::GpuMat& d_mat);
 -    _InputArray(const ogl::Buffer& buf);
 -    _InputArray(const ogl::Texture2D& tex);
 -
 -    virtual Mat getMat(int i=-1) const;
 -    virtual void getMatVector(vector<Mat>& mv) const;
 -    // < Deprecated
 -    virtual GlBuffer getGlBuffer() const;
 -    virtual GlTexture getGlTexture() const;
 -    // >
 -    virtual gpu::GpuMat getGpuMat() const;
 -    /*virtual*/ ogl::Buffer getOGlBuffer() const;
 -    /*virtual*/ ogl::Texture2D getOGlTexture2D() const;
 -
 -    virtual int kind() const;
 -    virtual Size size(int i=-1) const;
 -    virtual size_t total(int i=-1) const;
 -    virtual int type(int i=-1) const;
 -    virtual int depth(int i=-1) const;
 -    virtual int channels(int i=-1) const;
 -    virtual bool empty() const;
 -
 -#ifdef OPENCV_CAN_BREAK_BINARY_COMPATIBILITY
 -    virtual ~_InputArray();
 -#endif
 -
 -    int flags;
 -    void* obj;
 -    Size sz;
 -};
 -
 -
 -enum
 -{
 -    DEPTH_MASK_8U = 1 << CV_8U,
 -    DEPTH_MASK_8S = 1 << CV_8S,
 -    DEPTH_MASK_16U = 1 << CV_16U,
 -    DEPTH_MASK_16S = 1 << CV_16S,
 -    DEPTH_MASK_32S = 1 << CV_32S,
 -    DEPTH_MASK_32F = 1 << CV_32F,
 -    DEPTH_MASK_64F = 1 << CV_64F,
 -    DEPTH_MASK_ALL = (DEPTH_MASK_64F<<1)-1,
 -    DEPTH_MASK_ALL_BUT_8S = DEPTH_MASK_ALL & ~DEPTH_MASK_8S,
 -    DEPTH_MASK_FLT = DEPTH_MASK_32F + DEPTH_MASK_64F
 -};
 -
 -
 -/*!
 - Proxy datatype for passing Mat's and vector<>'s as input parameters
 - */
 -class CV_EXPORTS _OutputArray : public _InputArray
 -{
 -public:
 -    _OutputArray();
 -
 -    _OutputArray(Mat& m);
 -    template<typename _Tp> _OutputArray(vector<_Tp>& vec);
 -    template<typename _Tp> _OutputArray(vector<vector<_Tp> >& vec);
 -    _OutputArray(vector<Mat>& vec);
 -    template<typename _Tp> _OutputArray(vector<Mat_<_Tp> >& vec);
 -    template<typename _Tp> _OutputArray(Mat_<_Tp>& m);
 -    template<typename _Tp, int m, int n> _OutputArray(Matx<_Tp, m, n>& matx);
 -    template<typename _Tp> _OutputArray(_Tp* vec, int n);
 -    _OutputArray(gpu::GpuMat& d_mat);
 -    _OutputArray(ogl::Buffer& buf);
 -    _OutputArray(ogl::Texture2D& tex);
 -
 -    _OutputArray(const Mat& m);
 -    template<typename _Tp> _OutputArray(const vector<_Tp>& vec);
 -    template<typename _Tp> _OutputArray(const vector<vector<_Tp> >& vec);
 -    _OutputArray(const vector<Mat>& vec);
 -    template<typename _Tp> _OutputArray(const vector<Mat_<_Tp> >& vec);
 -    template<typename _Tp> _OutputArray(const Mat_<_Tp>& m);
 -    template<typename _Tp, int m, int n> _OutputArray(const Matx<_Tp, m, n>& matx);
 -    template<typename _Tp> _OutputArray(const _Tp* vec, int n);
 -    _OutputArray(const gpu::GpuMat& d_mat);
 -    _OutputArray(const ogl::Buffer& buf);
 -    _OutputArray(const ogl::Texture2D& tex);
 -
 -    virtual bool fixedSize() const;
 -    virtual bool fixedType() const;
 -    virtual bool needed() const;
 -    virtual Mat& getMatRef(int i=-1) const;
 -    /*virtual*/ gpu::GpuMat& getGpuMatRef() const;
 -    /*virtual*/ ogl::Buffer& getOGlBufferRef() const;
 -    /*virtual*/ ogl::Texture2D& getOGlTexture2DRef() const;
 -    virtual void create(Size sz, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
 -    virtual void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
 -    virtual void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
 -    virtual void release() const;
 -    virtual void clear() const;
 -
 -#ifdef OPENCV_CAN_BREAK_BINARY_COMPATIBILITY
 -    virtual ~_OutputArray();
 +#ifdef __OPENCV_BUILD
 +#error this is a compatibility header which should not be used inside the OpenCV library
  #endif
 -};
 -
 -typedef const _InputArray& InputArray;
 -typedef InputArray InputArrayOfArrays;
 -typedef const _OutputArray& OutputArray;
 -typedef OutputArray OutputArrayOfArrays;
 -typedef OutputArray InputOutputArray;
 -typedef OutputArray InputOutputArrayOfArrays;
 -
 -CV_EXPORTS OutputArray noArray();
 -
 -/////////////////////////////////////// Mat ///////////////////////////////////////////
 -
 -enum { MAGIC_MASK=0xFFFF0000, TYPE_MASK=0x00000FFF, DEPTH_MASK=7 };
 -
 -static inline size_t getElemSize(int type) { return CV_ELEM_SIZE(type); }
 -
 -/*!
 -   Custom array allocator
 -
 -*/
 -class CV_EXPORTS MatAllocator
 -{
 -public:
 -    MatAllocator() {}
 -    virtual ~MatAllocator() {}
 -    virtual void allocate(int dims, const int* sizes, int type, int*& refcount,
 -                          uchar*& datastart, uchar*& data, size_t* step) = 0;
 -    virtual void deallocate(int* refcount, uchar* datastart, uchar* data) = 0;
 -};
 -
 -/*!
 -   The n-dimensional matrix class.
 -
 -   The class represents an n-dimensional dense numerical array that can act as
 -   a matrix, image, optical flow map, 3-focal tensor etc.
 -   It is very similar to CvMat and CvMatND types from earlier versions of OpenCV,
 -   and similarly to those types, the matrix can be multi-channel. It also fully supports ROI mechanism.
 -
 -   There are many different ways to create cv::Mat object. Here are the some popular ones:
 -   <ul>
 -   <li> using cv::Mat::create(nrows, ncols, type) method or
 -     the similar constructor cv::Mat::Mat(nrows, ncols, type[, fill_value]) constructor.
 -     A new matrix of the specified size and specifed type will be allocated.
 -     "type" has the same meaning as in cvCreateMat function,
 -     e.g. CV_8UC1 means 8-bit single-channel matrix, CV_32FC2 means 2-channel (i.e. complex)
 -     floating-point matrix etc:
 -
 -     \code
 -     // make 7x7 complex matrix filled with 1+3j.
 -     cv::Mat M(7,7,CV_32FC2,Scalar(1,3));
 -     // and now turn M to 100x60 15-channel 8-bit matrix.
 -     // The old content will be deallocated
 -     M.create(100,60,CV_8UC(15));
 -     \endcode
 -
 -     As noted in the introduction of this chapter, Mat::create()
 -     will only allocate a new matrix when the current matrix dimensionality
 -     or type are different from the specified.
 -
 -   <li> by using a copy constructor or assignment operator, where on the right side it can
 -     be a matrix or expression, see below. Again, as noted in the introduction,
 -     matrix assignment is O(1) operation because it only copies the header
 -     and increases the reference counter. cv::Mat::clone() method can be used to get a full
 -     (a.k.a. deep) copy of the matrix when you need it.
 -
 -   <li> by constructing a header for a part of another matrix. It can be a single row, single column,
 -     several rows, several columns, rectangular region in the matrix (called a minor in algebra) or
 -     a diagonal. Such operations are also O(1), because the new header will reference the same data.
 -     You can actually modify a part of the matrix using this feature, e.g.
 -
 -     \code
 -     // add 5-th row, multiplied by 3 to the 3rd row
 -     M.row(3) = M.row(3) + M.row(5)*3;
 -
 -     // now copy 7-th column to the 1-st column
 -     // M.col(1) = M.col(7); // this will not work
 -     Mat M1 = M.col(1);
 -     M.col(7).copyTo(M1);
 -
 -     // create new 320x240 image
 -     cv::Mat img(Size(320,240),CV_8UC3);
 -     // select a roi
 -     cv::Mat roi(img, Rect(10,10,100,100));
 -     // fill the ROI with (0,255,0) (which is green in RGB space);
 -     // the original 320x240 image will be modified
 -     roi = Scalar(0,255,0);
 -     \endcode
 -
 -     Thanks to the additional cv::Mat::datastart and cv::Mat::dataend members, it is possible to
 -     compute the relative sub-matrix position in the main "container" matrix using cv::Mat::locateROI():
 -
 -     \code
 -     Mat A = Mat::eye(10, 10, CV_32S);
 -     // extracts A columns, 1 (inclusive) to 3 (exclusive).
 -     Mat B = A(Range::all(), Range(1, 3));
 -     // extracts B rows, 5 (inclusive) to 9 (exclusive).
 -     // that is, C ~ A(Range(5, 9), Range(1, 3))
 -     Mat C = B(Range(5, 9), Range::all());
 -     Size size; Point ofs;
 -     C.locateROI(size, ofs);
 -     // size will be (width=10,height=10) and the ofs will be (x=1, y=5)
 -     \endcode
 -
 -     As in the case of whole matrices, if you need a deep copy, use cv::Mat::clone() method
 -     of the extracted sub-matrices.
 -
 -   <li> by making a header for user-allocated-data. It can be useful for
 -      <ol>
 -      <li> processing "foreign" data using OpenCV (e.g. when you implement
 -         a DirectShow filter or a processing module for gstreamer etc.), e.g.
 -
 -         \code
 -         void process_video_frame(const unsigned char* pixels,
 -                                  int width, int height, int step)
 -         {
 -            cv::Mat img(height, width, CV_8UC3, pixels, step);
 -            cv::GaussianBlur(img, img, cv::Size(7,7), 1.5, 1.5);
 -         }
 -         \endcode
 -
 -      <li> for quick initialization of small matrices and/or super-fast element access
 -
 -         \code
 -         double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}};
 -         cv::Mat M = cv::Mat(3, 3, CV_64F, m).inv();
 -         \endcode
 -      </ol>
 -
 -       partial yet very common cases of this "user-allocated data" case are conversions
 -       from CvMat and IplImage to cv::Mat. For this purpose there are special constructors
 -       taking pointers to CvMat or IplImage and the optional
 -       flag indicating whether to copy the data or not.
 -
 -       Backward conversion from cv::Mat to CvMat or IplImage is provided via cast operators
 -       cv::Mat::operator CvMat() an cv::Mat::operator IplImage().
 -       The operators do not copy the data.
 -
 -
 -       \code
 -       IplImage* img = cvLoadImage("greatwave.jpg", 1);
 -       Mat mtx(img); // convert IplImage* -> cv::Mat
 -       CvMat oldmat = mtx; // convert cv::Mat -> CvMat
 -       CV_Assert(oldmat.cols == img->width && oldmat.rows == img->height &&
 -           oldmat.data.ptr == (uchar*)img->imageData && oldmat.step == img->widthStep);
 -       \endcode
 -
 -   <li> by using MATLAB-style matrix initializers, cv::Mat::zeros(), cv::Mat::ones(), cv::Mat::eye(), e.g.:
 -
 -   \code
 -   // create a double-precision identity martix and add it to M.
 -   M += Mat::eye(M.rows, M.cols, CV_64F);
 -   \endcode
 -
 -   <li> by using comma-separated initializer:
 -
 -   \code
 -   // create 3x3 double-precision identity matrix
 -   Mat M = (Mat_<double>(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);
 -   \endcode
 -
 -   here we first call constructor of cv::Mat_ class (that we describe further) with the proper matrix,
 -   and then we just put "<<" operator followed by comma-separated values that can be constants,
 -   variables, expressions etc. Also, note the extra parentheses that are needed to avoid compiler errors.
 -
 -   </ul>
 -
 -   Once matrix is created, it will be automatically managed by using reference-counting mechanism
 -   (unless the matrix header is built on top of user-allocated data,
 -   in which case you should handle the data by yourself).
 -   The matrix data will be deallocated when no one points to it;
 -   if you want to release the data pointed by a matrix header before the matrix destructor is called,
 -   use cv::Mat::release().
 -
 -   The next important thing to learn about the matrix class is element access. Here is how the matrix is stored.
 -   The elements are stored in row-major order (row by row). The cv::Mat::data member points to the first element of the first row,
 -   cv::Mat::rows contains the number of matrix rows and cv::Mat::cols - the number of matrix columns. There is yet another member,
 -   cv::Mat::step that is used to actually compute address of a matrix element. cv::Mat::step is needed because the matrix can be
 -   a part of another matrix or because there can some padding space in the end of each row for a proper alignment.
 -
 -   \image html roi.png
 -
 -   Given these parameters, address of the matrix element M_{ij} is computed as following:
 -
 -   addr(M_{ij})=M.data + M.step*i + j*M.elemSize()
 -
 -   if you know the matrix element type, e.g. it is float, then you can use cv::Mat::at() method:
 -
 -   addr(M_{ij})=&M.at<float>(i,j)
 -
 -   (where & is used to convert the reference returned by cv::Mat::at() to a pointer).
 -   if you need to process a whole row of matrix, the most efficient way is to get
 -   the pointer to the row first, and then just use plain C operator []:
 -
 -   \code
 -   // compute sum of positive matrix elements
 -   // (assuming that M is double-precision matrix)
 -   double sum=0;
 -   for(int i = 0; i < M.rows; i++)
 -   {
 -       const double* Mi = M.ptr<double>(i);
 -       for(int j = 0; j < M.cols; j++)
 -           sum += std::max(Mi[j], 0.);
 -   }
 -   \endcode
 -
 -   Some operations, like the above one, do not actually depend on the matrix shape,
 -   they just process elements of a matrix one by one (or elements from multiple matrices
 -   that are sitting in the same place, e.g. matrix addition). Such operations are called
 -   element-wise and it makes sense to check whether all the input/output matrices are continuous,
 -   i.e. have no gaps in the end of each row, and if yes, process them as a single long row:
 -
 -   \code
 -   // compute sum of positive matrix elements, optimized variant
 -   double sum=0;
 -   int cols = M.cols, rows = M.rows;
 -   if(M.isContinuous())
 -   {
 -       cols *= rows;
 -       rows = 1;
 -   }
 -   for(int i = 0; i < rows; i++)
 -   {
 -       const double* Mi = M.ptr<double>(i);
 -       for(int j = 0; j < cols; j++)
 -           sum += std::max(Mi[j], 0.);
 -   }
 -   \endcode
 -   in the case of continuous matrix the outer loop body will be executed just once,
 -   so the overhead will be smaller, which will be especially noticeable in the case of small matrices.
 -
 -   Finally, there are STL-style iterators that are smart enough to skip gaps between successive rows:
 -   \code
 -   // compute sum of positive matrix elements, iterator-based variant
 -   double sum=0;
 -   MatConstIterator_<double> it = M.begin<double>(), it_end = M.end<double>();
 -   for(; it != it_end; ++it)
 -       sum += std::max(*it, 0.);
 -   \endcode
 -
 -   The matrix iterators are random-access iterators, so they can be passed
 -   to any STL algorithm, including std::sort().
 -*/
 -class CV_EXPORTS Mat
 -{
 -public:
 -    //! default constructor
 -    Mat();
 -    //! constructs 2D matrix of the specified size and type
 -    // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
 -    Mat(int rows, int cols, int type);
 -    Mat(Size size, int type);
 -    //! constucts 2D matrix and fills it with the specified value _s.
 -    Mat(int rows, int cols, int type, const Scalar& s);
 -    Mat(Size size, int type, const Scalar& s);
 -
 -    //! constructs n-dimensional matrix
 -    Mat(int ndims, const int* sizes, int type);
 -    Mat(int ndims, const int* sizes, int type, const Scalar& s);
 -
 -    //! copy constructor
 -    Mat(const Mat& m);
 -    //! constructor for matrix headers pointing to user-allocated data
 -    Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP);
 -    Mat(Size size, int type, void* data, size_t step=AUTO_STEP);
 -    Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0);
 -
 -    //! creates a matrix header for a part of the bigger matrix
 -    Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all());
 -    Mat(const Mat& m, const Rect& roi);
 -    Mat(const Mat& m, const Range* ranges);
 -    //! converts old-style CvMat to the new matrix; the data is not copied by default
 -    Mat(const CvMat* m, bool copyData=false);
 -    //! converts old-style CvMatND to the new matrix; the data is not copied by default
 -    Mat(const CvMatND* m, bool copyData=false);
 -    //! converts old-style IplImage to the new matrix; the data is not copied by default
 -    Mat(const IplImage* img, bool copyData=false);
 -    //! builds matrix from std::vector with or without copying the data
 -    template<typename _Tp> explicit Mat(const vector<_Tp>& vec, bool copyData=false);
 -    //! builds matrix from cv::Vec; the data is copied by default
 -    template<typename _Tp, int n> explicit Mat(const Vec<_Tp, n>& vec, bool copyData=true);
 -    //! builds matrix from cv::Matx; the data is copied by default
 -    template<typename _Tp, int m, int n> explicit Mat(const Matx<_Tp, m, n>& mtx, bool copyData=true);
 -    //! builds matrix from a 2D point
 -    template<typename _Tp> explicit Mat(const Point_<_Tp>& pt, bool copyData=true);
 -    //! builds matrix from a 3D point
 -    template<typename _Tp> explicit Mat(const Point3_<_Tp>& pt, bool copyData=true);
 -    //! builds matrix from comma initializer
 -    template<typename _Tp> explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer);
 -
 -    //! download data from GpuMat
 -    explicit Mat(const gpu::GpuMat& m);
 -
 -    //! destructor - calls release()
 -    ~Mat();
 -    //! assignment operators
 -    Mat& operator = (const Mat& m);
 -    Mat& operator = (const MatExpr& expr);
 -
 -    //! returns a new matrix header for the specified row
 -    Mat row(int y) const;
 -    //! returns a new matrix header for the specified column
 -    Mat col(int x) const;
 -    //! ... for the specified row span
 -    Mat rowRange(int startrow, int endrow) const;
 -    Mat rowRange(const Range& r) const;
 -    //! ... for the specified column span
 -    Mat colRange(int startcol, int endcol) const;
 -    Mat colRange(const Range& r) const;
 -    //! ... for the specified diagonal
 -    // (d=0 - the main diagonal,
 -    //  >0 - a diagonal from the lower half,
 -    //  <0 - a diagonal from the upper half)
 -    Mat diag(int d=0) const;
 -    //! constructs a square diagonal matrix which main diagonal is vector "d"
 -    static Mat diag(const Mat& d);
 -
 -    //! returns deep copy of the matrix, i.e. the data is copied
 -    Mat clone() const;
 -    //! copies the matrix content to "m".
 -    // It calls m.create(this->size(), this->type()).
 -    void copyTo( OutputArray m ) const;
 -    //! copies those matrix elements to "m" that are marked with non-zero mask elements.
 -    void copyTo( OutputArray m, InputArray mask ) const;
 -    //! converts matrix to another datatype with optional scalng. See cvConvertScale.
 -    void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;
 -
 -    void assignTo( Mat& m, int type=-1 ) const;
 -
 -    //! sets every matrix element to s
 -    Mat& operator = (const Scalar& s);
 -    //! sets some of the matrix elements to s, according to the mask
 -    Mat& setTo(InputArray value, InputArray mask=noArray());
 -    //! creates alternative matrix header for the same data, with different
 -    // number of channels and/or different number of rows. see cvReshape.
 -    Mat reshape(int cn, int rows=0) const;
 -    Mat reshape(int cn, int newndims, const int* newsz) const;
 -
 -    //! matrix transposition by means of matrix expressions
 -    MatExpr t() const;
 -    //! matrix inversion by means of matrix expressions
 -    MatExpr inv(int method=DECOMP_LU) const;
 -    //! per-element matrix multiplication by means of matrix expressions
 -    MatExpr mul(InputArray m, double scale=1) const;
 -
 -    //! computes cross-product of 2 3D vectors
 -    Mat cross(InputArray m) const;
 -    //! computes dot-product
 -    double dot(InputArray m) const;
 -
 -    //! Matlab-style matrix initialization
 -    static MatExpr zeros(int rows, int cols, int type);
 -    static MatExpr zeros(Size size, int type);
 -    static MatExpr zeros(int ndims, const int* sz, int type);
 -    static MatExpr ones(int rows, int cols, int type);
 -    static MatExpr ones(Size size, int type);
 -    static MatExpr ones(int ndims, const int* sz, int type);
 -    static MatExpr eye(int rows, int cols, int type);
 -    static MatExpr eye(Size size, int type);
 -
 -    //! allocates new matrix data unless the matrix already has specified size and type.
 -    // previous data is unreferenced if needed.
 -    void create(int rows, int cols, int type);
 -    void create(Size size, int type);
 -    void create(int ndims, const int* sizes, int type);
 -
 -    //! increases the reference counter; use with care to avoid memleaks
 -    void addref();
 -    //! decreases reference counter;
 -    // deallocates the data when reference counter reaches 0.
 -    void release();
 -
 -    //! deallocates the matrix data
 -    void deallocate();
 -    //! internal use function; properly re-allocates _size, _step arrays
 -    void copySize(const Mat& m);
 -
 -    //! reserves enough space to fit sz hyper-planes
 -    void reserve(size_t sz);
 -    //! resizes matrix to the specified number of hyper-planes
 -    void resize(size_t sz);
 -    //! resizes matrix to the specified number of hyper-planes; initializes the newly added elements
 -    void resize(size_t sz, const Scalar& s);
 -    //! internal function
 -    void push_back_(const void* elem);
 -    //! adds element to the end of 1d matrix (or possibly multiple elements when _Tp=Mat)
 -    template<typename _Tp> void push_back(const _Tp& elem);
 -    template<typename _Tp> void push_back(const Mat_<_Tp>& elem);
 -    void push_back(const Mat& m);
 -    //! removes several hyper-planes from bottom of the matrix
 -    void pop_back(size_t nelems=1);
 -
 -    //! locates matrix header within a parent matrix. See below
 -    void locateROI( Size& wholeSize, Point& ofs ) const;
 -    //! moves/resizes the current matrix ROI inside the parent matrix.
 -    Mat& adjustROI( int dtop, int dbottom, int dleft, int dright );
 -    //! extracts a rectangular sub-matrix
 -    // (this is a generalized form of row, rowRange etc.)
 -    Mat operator()( Range rowRange, Range colRange ) const;
 -    Mat operator()( const Rect& roi ) const;
 -    Mat operator()( const Range* ranges ) const;
 -
 -    //! converts header to CvMat; no data is copied
 -    operator CvMat() const;
 -    //! converts header to CvMatND; no data is copied
 -    operator CvMatND() const;
 -    //! converts header to IplImage; no data is copied
 -    operator IplImage() const;
 -
 -    template<typename _Tp> operator vector<_Tp>() const;
 -    template<typename _Tp, int n> operator Vec<_Tp, n>() const;
 -    template<typename _Tp, int m, int n> operator Matx<_Tp, m, n>() const;
 -
 -    //! returns true iff the matrix data is continuous
 -    // (i.e. when there are no gaps between successive rows).
 -    // similar to CV_IS_MAT_CONT(cvmat->type)
 -    bool isContinuous() const;
 -
 -    //! returns true if the matrix is a submatrix of another matrix
 -    bool isSubmatrix() const;
 -
 -    //! returns element size in bytes,
 -    // similar to CV_ELEM_SIZE(cvmat->type)
 -    size_t elemSize() const;
 -    //! returns the size of element channel in bytes.
 -    size_t elemSize1() const;
 -    //! returns element type, similar to CV_MAT_TYPE(cvmat->type)
 -    int type() const;
 -    //! returns element type, similar to CV_MAT_DEPTH(cvmat->type)
 -    int depth() const;
 -    //! returns element type, similar to CV_MAT_CN(cvmat->type)
 -    int channels() const;
 -    //! returns step/elemSize1()
 -    size_t step1(int i=0) const;
 -    //! returns true if matrix data is NULL
 -    bool empty() const;
 -    //! returns the total number of matrix elements
 -    size_t total() const;
 -
 -    //! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise
 -    int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const;
 -
 -    //! returns pointer to i0-th submatrix along the dimension #0
 -    uchar* ptr(int i0=0);
 -    const uchar* ptr(int i0=0) const;
 -
 -    //! returns pointer to (i0,i1) submatrix along the dimensions #0 and #1
 -    uchar* ptr(int i0, int i1);
 -    const uchar* ptr(int i0, int i1) const;
 -
 -    //! returns pointer to (i0,i1,i3) submatrix along the dimensions #0, #1, #2
 -    uchar* ptr(int i0, int i1, int i2);
 -    const uchar* ptr(int i0, int i1, int i2) const;
 -
 -    //! returns pointer to the matrix element
 -    uchar* ptr(const int* idx);
 -    //! returns read-only pointer to the matrix element
 -    const uchar* ptr(const int* idx) const;
 -
 -    template<int n> uchar* ptr(const Vec<int, n>& idx);
 -    template<int n> const uchar* ptr(const Vec<int, n>& idx) const;
 -
 -    //! template version of the above method
 -    template<typename _Tp> _Tp* ptr(int i0=0);
 -    template<typename _Tp> const _Tp* ptr(int i0=0) const;
 -
 -    template<typename _Tp> _Tp* ptr(int i0, int i1);
 -    template<typename _Tp> const _Tp* ptr(int i0, int i1) const;
 -
 -    template<typename _Tp> _Tp* ptr(int i0, int i1, int i2);
 -    template<typename _Tp> const _Tp* ptr(int i0, int i1, int i2) const;
 -
 -    template<typename _Tp> _Tp* ptr(const int* idx);
 -    template<typename _Tp> const _Tp* ptr(const int* idx) const;
 -
 -    template<typename _Tp, int n> _Tp* ptr(const Vec<int, n>& idx);
 -    template<typename _Tp, int n> const _Tp* ptr(const Vec<int, n>& idx) const;
 -
 -    //! the same as above, with the pointer dereferencing
 -    template<typename _Tp> _Tp& at(int i0=0);
 -    template<typename _Tp> const _Tp& at(int i0=0) const;
 -
 -    template<typename _Tp> _Tp& at(int i0, int i1);
 -    template<typename _Tp> const _Tp& at(int i0, int i1) const;
 -
 -    template<typename _Tp> _Tp& at(int i0, int i1, int i2);
 -    template<typename _Tp> const _Tp& at(int i0, int i1, int i2) const;
 -
 -    template<typename _Tp> _Tp& at(const int* idx);
 -    template<typename _Tp> const _Tp& at(const int* idx) const;
 -
 -    template<typename _Tp, int n> _Tp& at(const Vec<int, n>& idx);
 -    template<typename _Tp, int n> const _Tp& at(const Vec<int, n>& idx) const;
 -
 -    //! special versions for 2D arrays (especially convenient for referencing image pixels)
 -    template<typename _Tp> _Tp& at(Point pt);
 -    template<typename _Tp> const _Tp& at(Point pt) const;
 -
 -    //! template methods for iteration over matrix elements.
 -    // the iterators take care of skipping gaps in the end of rows (if any)
 -    template<typename _Tp> MatIterator_<_Tp> begin();
 -    template<typename _Tp> MatIterator_<_Tp> end();
 -    template<typename _Tp> MatConstIterator_<_Tp> begin() const;
 -    template<typename _Tp> MatConstIterator_<_Tp> end() const;
 -
 -    enum { MAGIC_VAL=0x42FF0000, AUTO_STEP=0, CONTINUOUS_FLAG=CV_MAT_CONT_FLAG, SUBMATRIX_FLAG=CV_SUBMAT_FLAG };
 -
 -    /*! includes several bit-fields:
 -         - the magic signature
 -         - continuity flag
 -         - depth
 -         - number of channels
 -     */
 -    int flags;
 -    //! the matrix dimensionality, >= 2
 -    int dims;
 -    //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
 -    int rows, cols;
 -    //! pointer to the data
 -    uchar* data;
 -
 -    //! pointer to the reference counter;
 -    // when matrix points to user-allocated data, the pointer is NULL
 -    int* refcount;
 -
 -    //! helper fields used in locateROI and adjustROI
 -    uchar* datastart;
 -    uchar* dataend;
 -    uchar* datalimit;
 -
 -    //! custom allocator
 -    MatAllocator* allocator;
 -
 -    struct CV_EXPORTS MSize
 -    {
 -        MSize(int* _p);
 -        Size operator()() const;
 -        const int& operator[](int i) const;
 -        int& operator[](int i);
 -        operator const int*() const;
 -        bool operator == (const MSize& sz) const;
 -        bool operator != (const MSize& sz) const;
 -
 -        int* p;
 -    };
 -
 -    struct CV_EXPORTS MStep
 -    {
 -        MStep();
 -        MStep(size_t s);
 -        const size_t& operator[](int i) const;
 -        size_t& operator[](int i);
 -        operator size_t() const;
 -        MStep& operator = (size_t s);
 -
 -        size_t* p;
 -        size_t buf[2];
 -    protected:
 -        MStep& operator = (const MStep&);
 -    };
 -
 -    MSize size;
 -    MStep step;
 -
 -protected:
 -    void initEmpty();
 -};
 -
 -
 -/*!
 -   Random Number Generator
 -
 -   The class implements RNG using Multiply-with-Carry algorithm
 -*/
 -class CV_EXPORTS RNG
 -{
 -public:
 -    enum { UNIFORM=0, NORMAL=1 };
 -
 -    RNG();
 -    RNG(uint64 state);
 -    //! updates the state and returns the next 32-bit unsigned integer random number
 -    unsigned next();
 -
 -    operator uchar();
 -    operator schar();
 -    operator ushort();
 -    operator short();
 -    operator unsigned();
 -    //! returns a random integer sampled uniformly from [0, N).
 -    unsigned operator ()(unsigned N);
 -    unsigned operator ()();
 -    operator int();
 -    operator float();
 -    operator double();
 -    //! returns uniformly distributed integer random number from [a,b) range
 -    int uniform(int a, int b);
 -    //! returns uniformly distributed floating-point random number from [a,b) range
 -    float uniform(float a, float b);
 -    //! returns uniformly distributed double-precision floating-point random number from [a,b) range
 -    double uniform(double a, double b);
 -    void fill( InputOutputArray mat, int distType, InputArray a, InputArray b, bool saturateRange=false );
 -    //! returns Gaussian random variate with mean zero.
 -    double gaussian(double sigma);
 -
 -    uint64 state;
 -};
 -
 -
 -/*!
 - Termination criteria in iterative algorithms
 - */
 -class CV_EXPORTS TermCriteria
 -{
 -public:
 -    enum
 -    {
 -        COUNT=1, //!< the maximum number of iterations or elements to compute
 -        MAX_ITER=COUNT, //!< ditto
 -        EPS=2 //!< the desired accuracy or change in parameters at which the iterative algorithm stops
 -    };
 -
 -    //! default constructor
 -    TermCriteria();
 -    //! full constructor
 -    TermCriteria(int type, int maxCount, double epsilon);
 -    //! conversion from CvTermCriteria
 -    TermCriteria(const CvTermCriteria& criteria);
 -    //! conversion to CvTermCriteria
 -    operator CvTermCriteria() const;
 -
 -    int type; //!< the type of termination criteria: COUNT, EPS or COUNT + EPS
 -    int maxCount; // the maximum number of iterations/elements
 -    double epsilon; // the desired accuracy
 -};
 -
 -
 -typedef void (*BinaryFunc)(const uchar* src1, size_t step1,
 -                           const uchar* src2, size_t step2,
 -                           uchar* dst, size_t step, Size sz,
 -                           void*);
 -
 -CV_EXPORTS BinaryFunc getConvertFunc(int sdepth, int ddepth);
 -CV_EXPORTS BinaryFunc getConvertScaleFunc(int sdepth, int ddepth);
 -CV_EXPORTS BinaryFunc getCopyMaskFunc(size_t esz);
 -
 -//! swaps two matrices
 -CV_EXPORTS void swap(Mat& a, Mat& b);
 -
 -//! converts array (CvMat or IplImage) to cv::Mat
 -CV_EXPORTS Mat cvarrToMat(const CvArr* arr, bool copyData=false,
 -                          bool allowND=true, int coiMode=0);
 -//! extracts Channel of Interest from CvMat or IplImage and makes cv::Mat out of it.
 -CV_EXPORTS void extractImageCOI(const CvArr* arr, OutputArray coiimg, int coi=-1);
 -//! inserts single-channel cv::Mat into a multi-channel CvMat or IplImage
 -CV_EXPORTS void insertImageCOI(InputArray coiimg, CvArr* arr, int coi=-1);
 -
 -//! adds one matrix to another (dst = src1 + src2)
 -CV_EXPORTS_W void add(InputArray src1, InputArray src2, OutputArray dst,
 -                      InputArray mask=noArray(), int dtype=-1);
 -//! subtracts one matrix from another (dst = src1 - src2)
 -CV_EXPORTS_W void subtract(InputArray src1, InputArray src2, OutputArray dst,
 -                           InputArray mask=noArray(), int dtype=-1);
 -
 -//! computes element-wise weighted product of the two arrays (dst = scale*src1*src2)
 -CV_EXPORTS_W void multiply(InputArray src1, InputArray src2,
 -                           OutputArray dst, double scale=1, int dtype=-1);
 -
 -//! computes element-wise weighted quotient of the two arrays (dst = scale*src1/src2)
 -CV_EXPORTS_W void divide(InputArray src1, InputArray src2, OutputArray dst,
 -                         double scale=1, int dtype=-1);
 -
 -//! computes element-wise weighted reciprocal of an array (dst = scale/src2)
 -CV_EXPORTS_W void divide(double scale, InputArray src2,
 -                         OutputArray dst, int dtype=-1);
 -
 -//! adds scaled array to another one (dst = alpha*src1 + src2)
 -CV_EXPORTS_W void scaleAdd(InputArray src1, double alpha, InputArray src2, OutputArray dst);
 -
 -//! computes weighted sum of two arrays (dst = alpha*src1 + beta*src2 + gamma)
 -CV_EXPORTS_W void addWeighted(InputArray src1, double alpha, InputArray src2,
 -                              double beta, double gamma, OutputArray dst, int dtype=-1);
 -
 -//! scales array elements, computes absolute values and converts the results to 8-bit unsigned integers: dst(i)=saturate_cast<uchar>abs(src(i)*alpha+beta)
 -CV_EXPORTS_W void convertScaleAbs(InputArray src, OutputArray dst,
 -                                  double alpha=1, double beta=0);
 -//! transforms array of numbers using a lookup table: dst(i)=lut(src(i))
 -CV_EXPORTS_W void LUT(InputArray src, InputArray lut, OutputArray dst,
 -                      int interpolation=0);
 -
 -//! computes sum of array elements
 -CV_EXPORTS_AS(sumElems) Scalar sum(InputArray src);
 -//! computes the number of nonzero array elements
 -CV_EXPORTS_W int countNonZero( InputArray src );
 -//! returns the list of locations of non-zero pixels
 -CV_EXPORTS_W void findNonZero( InputArray src, OutputArray idx );
 -
 -//! computes mean value of selected array elements
 -CV_EXPORTS_W Scalar mean(InputArray src, InputArray mask=noArray());
 -//! computes mean value and standard deviation of all or selected array elements
 -CV_EXPORTS_W void meanStdDev(InputArray src, OutputArray mean, OutputArray stddev,
 -                             InputArray mask=noArray());
 -//! computes norm of the selected array part
 -CV_EXPORTS_W double norm(InputArray src1, int normType=NORM_L2, InputArray mask=noArray());
 -//! computes norm of selected part of the difference between two arrays
 -CV_EXPORTS_W double norm(InputArray src1, InputArray src2,
 -                         int normType=NORM_L2, InputArray mask=noArray());
 -
 -//! naive nearest neighbor finder
 -CV_EXPORTS_W void batchDistance(InputArray src1, InputArray src2,
 -                                OutputArray dist, int dtype, OutputArray nidx,
 -                                int normType=NORM_L2, int K=0,
 -                                InputArray mask=noArray(), int update=0,
 -                                bool crosscheck=false);
 -
 -//! scales and shifts array elements so that either the specified norm (alpha) or the minimum (alpha) and maximum (beta) array values get the specified values
 -CV_EXPORTS_W void normalize( InputArray src, OutputArray dst, double alpha=1, double beta=0,
 -                             int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray());
 -
 -//! finds global minimum and maximum array elements and returns their values and their locations
 -CV_EXPORTS_W void minMaxLoc(InputArray src, CV_OUT double* minVal,
 -                           CV_OUT double* maxVal=0, CV_OUT Point* minLoc=0,
 -                           CV_OUT Point* maxLoc=0, InputArray mask=noArray());
 -CV_EXPORTS void minMaxIdx(InputArray src, double* minVal, double* maxVal,
 -                          int* minIdx=0, int* maxIdx=0, InputArray mask=noArray());
 -
 -//! transforms 2D matrix to 1D row or column vector by taking sum, minimum, maximum or mean value over all the rows
 -CV_EXPORTS_W void reduce(InputArray src, OutputArray dst, int dim, int rtype, int dtype=-1);
 -
 -//! makes multi-channel array out of several single-channel arrays
 -CV_EXPORTS void merge(const Mat* mv, size_t count, OutputArray dst);
 -CV_EXPORTS void merge(const vector<Mat>& mv, OutputArray dst );
 -
 -//! makes multi-channel array out of several single-channel arrays
 -CV_EXPORTS_W void merge(InputArrayOfArrays mv, OutputArray dst);
 -
 -//! copies each plane of a multi-channel array to a dedicated array
 -CV_EXPORTS void split(const Mat& src, Mat* mvbegin);
 -CV_EXPORTS void split(const Mat& m, vector<Mat>& mv );
 -
 -//! copies each plane of a multi-channel array to a dedicated array
 -CV_EXPORTS_W void split(InputArray m, OutputArrayOfArrays mv);
 -
 -//! copies selected channels from the input arrays to the selected channels of the output arrays
 -CV_EXPORTS void mixChannels(const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts,
 -                            const int* fromTo, size_t npairs);
 -CV_EXPORTS void mixChannels(const vector<Mat>& src, vector<Mat>& dst,
 -                            const int* fromTo, size_t npairs);
 -CV_EXPORTS_W void mixChannels(InputArrayOfArrays src, InputArrayOfArrays dst,
 -                              const vector<int>& fromTo);
 -
 -//! extracts a single channel from src (coi is 0-based index)
 -CV_EXPORTS_W void extractChannel(InputArray src, OutputArray dst, int coi);
 -
 -//! inserts a single channel to dst (coi is 0-based index)
 -CV_EXPORTS_W void insertChannel(InputArray src, InputOutputArray dst, int coi);
 -
 -//! reverses the order of the rows, columns or both in a matrix
 -CV_EXPORTS_W void flip(InputArray src, OutputArray dst, int flipCode);
 -
 -//! replicates the input matrix the specified number of times in the horizontal and/or vertical direction
 -CV_EXPORTS_W void repeat(InputArray src, int ny, int nx, OutputArray dst);
 -CV_EXPORTS Mat repeat(const Mat& src, int ny, int nx);
 -
 -CV_EXPORTS void hconcat(const Mat* src, size_t nsrc, OutputArray dst);
 -CV_EXPORTS void hconcat(InputArray src1, InputArray src2, OutputArray dst);
 -CV_EXPORTS_W void hconcat(InputArrayOfArrays src, OutputArray dst);
 -
 -CV_EXPORTS void vconcat(const Mat* src, size_t nsrc, OutputArray dst);
 -CV_EXPORTS void vconcat(InputArray src1, InputArray src2, OutputArray dst);
 -CV_EXPORTS_W void vconcat(InputArrayOfArrays src, OutputArray dst);
 -
 -//! computes bitwise conjunction of the two arrays (dst = src1 & src2)
 -CV_EXPORTS_W void bitwise_and(InputArray src1, InputArray src2,
 -                              OutputArray dst, InputArray mask=noArray());
 -//! computes bitwise disjunction of the two arrays (dst = src1 | src2)
 -CV_EXPORTS_W void bitwise_or(InputArray src1, InputArray src2,
 -                             OutputArray dst, InputArray mask=noArray());
 -//! computes bitwise exclusive-or of the two arrays (dst = src1 ^ src2)
 -CV_EXPORTS_W void bitwise_xor(InputArray src1, InputArray src2,
 -                              OutputArray dst, InputArray mask=noArray());
 -//! inverts each bit of array (dst = ~src)
 -CV_EXPORTS_W void bitwise_not(InputArray src, OutputArray dst,
 -                              InputArray mask=noArray());
 -//! computes element-wise absolute difference of two arrays (dst = abs(src1 - src2))
 -CV_EXPORTS_W void absdiff(InputArray src1, InputArray src2, OutputArray dst);
 -//! set mask elements for those array elements which are within the element-specific bounding box (dst = lowerb <= src && src < upperb)
 -CV_EXPORTS_W void inRange(InputArray src, InputArray lowerb,
 -                          InputArray upperb, OutputArray dst);
 -//! compares elements of two arrays (dst = src1 <cmpop> src2)
 -CV_EXPORTS_W void compare(InputArray src1, InputArray src2, OutputArray dst, int cmpop);
 -//! computes per-element minimum of two arrays (dst = min(src1, src2))
 -CV_EXPORTS_W void min(InputArray src1, InputArray src2, OutputArray dst);
 -//! computes per-element maximum of two arrays (dst = max(src1, src2))
 -CV_EXPORTS_W void max(InputArray src1, InputArray src2, OutputArray dst);
 -
 -//! computes per-element minimum of two arrays (dst = min(src1, src2))
 -CV_EXPORTS void min(const Mat& src1, const Mat& src2, Mat& dst);
 -//! computes per-element minimum of array and scalar (dst = min(src1, src2))
 -CV_EXPORTS void min(const Mat& src1, double src2, Mat& dst);
 -//! computes per-element maximum of two arrays (dst = max(src1, src2))
 -CV_EXPORTS void max(const Mat& src1, const Mat& src2, Mat& dst);
 -//! computes per-element maximum of array and scalar (dst = max(src1, src2))
 -CV_EXPORTS void max(const Mat& src1, double src2, Mat& dst);
 -
 -//! computes square root of each matrix element (dst = src**0.5)
 -CV_EXPORTS_W void sqrt(InputArray src, OutputArray dst);
 -//! raises the input matrix elements to the specified power (b = a**power)
 -CV_EXPORTS_W void pow(InputArray src, double power, OutputArray dst);
 -//! computes exponent of each matrix element (dst = e**src)
 -CV_EXPORTS_W void exp(InputArray src, OutputArray dst);
 -//! computes natural logarithm of absolute value of each matrix element: dst = log(abs(src))
 -CV_EXPORTS_W void log(InputArray src, OutputArray dst);
 -//! computes cube root of the argument
 -CV_EXPORTS_W float cubeRoot(float val);
 -//! computes the angle in degrees (0..360) of the vector (x,y)
 -CV_EXPORTS_W float fastAtan2(float y, float x);
 -
 -CV_EXPORTS void exp(const float* src, float* dst, int n);
 -CV_EXPORTS void log(const float* src, float* dst, int n);
 -CV_EXPORTS void fastAtan2(const float* y, const float* x, float* dst, int n, bool angleInDegrees);
 -CV_EXPORTS void magnitude(const float* x, const float* y, float* dst, int n);
 -
 -//! converts polar coordinates to Cartesian
 -CV_EXPORTS_W void polarToCart(InputArray magnitude, InputArray angle,
 -                              OutputArray x, OutputArray y, bool angleInDegrees=false);
 -//! converts Cartesian coordinates to polar
 -CV_EXPORTS_W void cartToPolar(InputArray x, InputArray y,
 -                              OutputArray magnitude, OutputArray angle,
 -                              bool angleInDegrees=false);
 -//! computes angle (angle(i)) of each (x(i), y(i)) vector
 -CV_EXPORTS_W void phase(InputArray x, InputArray y, OutputArray angle,
 -                        bool angleInDegrees=false);
 -//! computes magnitude (magnitude(i)) of each (x(i), y(i)) vector
 -CV_EXPORTS_W void magnitude(InputArray x, InputArray y, OutputArray magnitude);
 -//! checks that each matrix element is within the specified range.
 -CV_EXPORTS_W bool checkRange(InputArray a, bool quiet=true, CV_OUT Point* pos=0,
 -                            double minVal=-DBL_MAX, double maxVal=DBL_MAX);
 -//! converts NaN's to the given number
 -CV_EXPORTS_W void patchNaNs(InputOutputArray a, double val=0);
 -
 -//! implements generalized matrix product algorithm GEMM from BLAS
 -CV_EXPORTS_W void gemm(InputArray src1, InputArray src2, double alpha,
 -                       InputArray src3, double gamma, OutputArray dst, int flags=0);
 -//! multiplies matrix by its transposition from the left or from the right
 -CV_EXPORTS_W void mulTransposed( InputArray src, OutputArray dst, bool aTa,
 -                                 InputArray delta=noArray(),
 -                                 double scale=1, int dtype=-1 );
 -//! transposes the matrix
 -CV_EXPORTS_W void transpose(InputArray src, OutputArray dst);
 -//! performs affine transformation of each element of multi-channel input matrix
 -CV_EXPORTS_W void transform(InputArray src, OutputArray dst, InputArray m );
 -//! performs perspective transformation of each element of multi-channel input matrix
 -CV_EXPORTS_W void perspectiveTransform(InputArray src, OutputArray dst, InputArray m );
 -
 -//! extends the symmetrical matrix from the lower half or from the upper half
 -CV_EXPORTS_W void completeSymm(InputOutputArray mtx, bool lowerToUpper=false);
 -//! initializes scaled identity matrix
 -CV_EXPORTS_W void setIdentity(InputOutputArray mtx, const Scalar& s=Scalar(1));
 -//! computes determinant of a square matrix
 -CV_EXPORTS_W double determinant(InputArray mtx);
 -//! computes trace of a matrix
 -CV_EXPORTS_W Scalar trace(InputArray mtx);
 -//! computes inverse or pseudo-inverse matrix
 -CV_EXPORTS_W double invert(InputArray src, OutputArray dst, int flags=DECOMP_LU);
 -//! solves linear system or a least-square problem
 -CV_EXPORTS_W bool solve(InputArray src1, InputArray src2,
 -                        OutputArray dst, int flags=DECOMP_LU);
 -
 -enum
 -{
 -    SORT_EVERY_ROW=0,
 -    SORT_EVERY_COLUMN=1,
 -    SORT_ASCENDING=0,
 -    SORT_DESCENDING=16
 -};
 -
 -//! sorts independently each matrix row or each matrix column
 -CV_EXPORTS_W void sort(InputArray src, OutputArray dst, int flags);
 -//! sorts independently each matrix row or each matrix column
 -CV_EXPORTS_W void sortIdx(InputArray src, OutputArray dst, int flags);
 -//! finds real roots of a cubic polynomial
 -CV_EXPORTS_W int solveCubic(InputArray coeffs, OutputArray roots);
 -//! finds real and complex roots of a polynomial
 -CV_EXPORTS_W double solvePoly(InputArray coeffs, OutputArray roots, int maxIters=300);
 -//! finds eigenvalues of a symmetric matrix
 -CV_EXPORTS bool eigen(InputArray src, OutputArray eigenvalues, int lowindex=-1,
 -                      int highindex=-1);
 -//! finds eigenvalues and eigenvectors of a symmetric matrix
 -CV_EXPORTS bool eigen(InputArray src, OutputArray eigenvalues,
 -                      OutputArray eigenvectors,
 -                      int lowindex=-1, int highindex=-1);
 -CV_EXPORTS_W bool eigen(InputArray src, bool computeEigenvectors,
 -                        OutputArray eigenvalues, OutputArray eigenvectors);
 -
 -enum
 -{
 -    COVAR_SCRAMBLED=0,
 -    COVAR_NORMAL=1,
 -    COVAR_USE_AVG=2,
 -    COVAR_SCALE=4,
 -    COVAR_ROWS=8,
 -    COVAR_COLS=16
 -};
 -
 -//! computes covariation matrix of a set of samples
 -CV_EXPORTS void calcCovarMatrix( const Mat* samples, int nsamples, Mat& covar, Mat& mean,
 -                                 int flags, int ctype=CV_64F);
 -//! computes covariation matrix of a set of samples
 -CV_EXPORTS_W void calcCovarMatrix( InputArray samples, OutputArray covar,
 -                                   OutputArray mean, int flags, int ctype=CV_64F);
 -
 -/*!
 -    Principal Component Analysis
 -
 -    The class PCA is used to compute the special basis for a set of vectors.
 -    The basis will consist of eigenvectors of the covariance matrix computed
 -    from the input set of vectors. After PCA is performed, vectors can be transformed from
 -    the original high-dimensional space to the subspace formed by a few most
 -    prominent eigenvectors (called the principal components),
 -    corresponding to the largest eigenvalues of the covariation matrix.
 -    Thus the dimensionality of the vector and the correlation between the coordinates is reduced.
 -
 -    The following sample is the function that takes two matrices. The first one stores the set
 -    of vectors (a row per vector) that is used to compute PCA, the second one stores another
 -    "test" set of vectors (a row per vector) that are first compressed with PCA,
 -    then reconstructed back and then the reconstruction error norm is computed and printed for each vector.
 -
 -    \code
 -    using namespace cv;
 -
 -    PCA compressPCA(const Mat& pcaset, int maxComponents,
 -                    const Mat& testset, Mat& compressed)
 -    {
 -        PCA pca(pcaset, // pass the data
 -                Mat(), // we do not have a pre-computed mean vector,
 -                       // so let the PCA engine to compute it
 -                CV_PCA_DATA_AS_ROW, // indicate that the vectors
 -                                    // are stored as matrix rows
 -                                    // (use CV_PCA_DATA_AS_COL if the vectors are
 -                                    // the matrix columns)
 -                maxComponents // specify, how many principal components to retain
 -                );
 -        // if there is no test data, just return the computed basis, ready-to-use
 -        if( !testset.data )
 -            return pca;
 -        CV_Assert( testset.cols == pcaset.cols );
 -
 -        compressed.create(testset.rows, maxComponents, testset.type());
 -
 -        Mat reconstructed;
 -        for( int i = 0; i < testset.rows; i++ )
 -        {
 -            Mat vec = testset.row(i), coeffs = compressed.row(i), reconstructed;
 -            // compress the vector, the result will be stored
 -            // in the i-th row of the output matrix
 -            pca.project(vec, coeffs);
 -            // and then reconstruct it
 -            pca.backProject(coeffs, reconstructed);
 -            // and measure the error
 -            printf("%d. diff = %g\n", i, norm(vec, reconstructed, NORM_L2));
 -        }
 -        return pca;
 -    }
 -    \endcode
 -*/
 -class CV_EXPORTS PCA
 -{
 -public:
 -    //! default constructor
 -    PCA();
 -    //! the constructor that performs PCA
 -    PCA(InputArray data, InputArray mean, int flags, int maxComponents=0);
 -    PCA(InputArray data, InputArray mean, int flags, double retainedVariance);
 -    //! operator that performs PCA. The previously stored data, if any, is released
 -    PCA& operator()(InputArray data, InputArray mean, int flags, int maxComponents=0);
 -    PCA& computeVar(InputArray data, InputArray mean, int flags, double retainedVariance);
 -    //! projects vector from the original space to the principal components subspace
 -    Mat project(InputArray vec) const;
 -    //! projects vector from the original space to the principal components subspace
 -    void project(InputArray vec, OutputArray result) const;
 -    //! reconstructs the original vector from the projection
 -    Mat backProject(InputArray vec) const;
 -    //! reconstructs the original vector from the projection
 -    void backProject(InputArray vec, OutputArray result) const;
 -
 -    Mat eigenvectors; //!< eigenvectors of the covariation matrix
 -    Mat eigenvalues; //!< eigenvalues of the covariation matrix
 -    Mat mean; //!< mean value subtracted before the projection and added after the back projection
 -};
 -
 -CV_EXPORTS_W void PCACompute(InputArray data, CV_OUT InputOutputArray mean,
 -                             OutputArray eigenvectors, int maxComponents=0);
 -
 -CV_EXPORTS_W void PCAComputeVar(InputArray data, CV_OUT InputOutputArray mean,
 -                             OutputArray eigenvectors, double retainedVariance);
 -
 -CV_EXPORTS_W void PCAProject(InputArray data, InputArray mean,
 -                             InputArray eigenvectors, OutputArray result);
 -
 -CV_EXPORTS_W void PCABackProject(InputArray data, InputArray mean,
 -                                 InputArray eigenvectors, OutputArray result);
 -
 -
 -/*!
 -    Singular Value Decomposition class
 -
 -    The class is used to compute Singular Value Decomposition of a floating-point matrix and then
 -    use it to solve least-square problems, under-determined linear systems, invert matrices,
 -    compute condition numbers etc.
 -
 -    For a bit faster operation you can pass flags=SVD::MODIFY_A|... to modify the decomposed matrix
 -    when it is not necessarily to preserve it. If you want to compute condition number of a matrix
 -    or absolute value of its determinant - you do not need SVD::u or SVD::vt,
 -    so you can pass flags=SVD::NO_UV|... . Another flag SVD::FULL_UV indicates that the full-size SVD::u and SVD::vt
 -    must be computed, which is not necessary most of the time.
 -*/
 -class CV_EXPORTS SVD
 -{
 -public:
 -    enum { MODIFY_A=1, NO_UV=2, FULL_UV=4 };
 -    //! the default constructor
 -    SVD();
 -    //! the constructor that performs SVD
 -    SVD( InputArray src, int flags=0 );
 -    //! the operator that performs SVD. The previously allocated SVD::u, SVD::w are SVD::vt are released.
 -    SVD& operator ()( InputArray src, int flags=0 );
 -
 -    //! decomposes matrix and stores the results to user-provided matrices
 -    static void compute( InputArray src, OutputArray w,
 -                         OutputArray u, OutputArray vt, int flags=0 );
 -    //! computes singular values of a matrix
 -    static void compute( InputArray src, OutputArray w, int flags=0 );
 -    //! performs back substitution
 -    static void backSubst( InputArray w, InputArray u,
 -                           InputArray vt, InputArray rhs,
 -                           OutputArray dst );
 -
 -    template<typename _Tp, int m, int n, int nm> static void compute( const Matx<_Tp, m, n>& a,
 -        Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt );
 -    template<typename _Tp, int m, int n, int nm> static void compute( const Matx<_Tp, m, n>& a,
 -        Matx<_Tp, nm, 1>& w );
 -    template<typename _Tp, int m, int n, int nm, int nb> static void backSubst( const Matx<_Tp, nm, 1>& w,
 -        const Matx<_Tp, m, nm>& u, const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs, Matx<_Tp, n, nb>& dst );
 -
 -    //! finds dst = arg min_{|dst|=1} |m*dst|
 -    static void solveZ( InputArray src, OutputArray dst );
 -    //! performs back substitution, so that dst is the solution or pseudo-solution of m*dst = rhs, where m is the decomposed matrix
 -    void backSubst( InputArray rhs, OutputArray dst ) const;
 -
 -    Mat u, w, vt;
 -};
 -
 -//! computes SVD of src
 -CV_EXPORTS_W void SVDecomp( InputArray src, CV_OUT OutputArray w,
 -    CV_OUT OutputArray u, CV_OUT OutputArray vt, int flags=0 );
 -
 -//! performs back substitution for the previously computed SVD
 -CV_EXPORTS_W void SVBackSubst( InputArray w, InputArray u, InputArray vt,
 -                               InputArray rhs, CV_OUT OutputArray dst );
 -
 -//! computes Mahalanobis distance between two vectors: sqrt((v1-v2)'*icovar*(v1-v2)), where icovar is the inverse covariation matrix
 -CV_EXPORTS_W double Mahalanobis(InputArray v1, InputArray v2, InputArray icovar);
 -//! a synonym for Mahalanobis
 -CV_EXPORTS double Mahalonobis(InputArray v1, InputArray v2, InputArray icovar);
 -
 -//! performs forward or inverse 1D or 2D Discrete Fourier Transformation
 -CV_EXPORTS_W void dft(InputArray src, OutputArray dst, int flags=0, int nonzeroRows=0);
 -//! performs inverse 1D or 2D Discrete Fourier Transformation
 -CV_EXPORTS_W void idft(InputArray src, OutputArray dst, int flags=0, int nonzeroRows=0);
 -//! performs forward or inverse 1D or 2D Discrete Cosine Transformation
 -CV_EXPORTS_W void dct(InputArray src, OutputArray dst, int flags=0);
 -//! performs inverse 1D or 2D Discrete Cosine Transformation
 -CV_EXPORTS_W void idct(InputArray src, OutputArray dst, int flags=0);
 -//! computes element-wise product of the two Fourier spectrums. The second spectrum can optionally be conjugated before the multiplication
 -CV_EXPORTS_W void mulSpectrums(InputArray a, InputArray b, OutputArray c,
 -                               int flags, bool conjB=false);
 -//! computes the minimal vector size vecsize1 >= vecsize so that the dft() of the vector of length vecsize1 can be computed efficiently
 -CV_EXPORTS_W int getOptimalDFTSize(int vecsize);
 -
 -/*!
 - Various k-Means flags
 -*/
 -enum
 -{
 -    KMEANS_RANDOM_CENTERS=0, // Chooses random centers for k-Means initialization
 -    KMEANS_PP_CENTERS=2,     // Uses k-Means++ algorithm for initialization
 -    KMEANS_USE_INITIAL_LABELS=1 // Uses the user-provided labels for K-Means initialization
 -};
 -//! clusters the input data using k-Means algorithm
 -CV_EXPORTS_W double kmeans( InputArray data, int K, CV_OUT InputOutputArray bestLabels,
 -                            TermCriteria criteria, int attempts,
 -                            int flags, OutputArray centers=noArray() );
 -
 -//! returns the thread-local Random number generator
 -CV_EXPORTS RNG& theRNG();
 -
 -//! returns the next unifomly-distributed random number of the specified type
 -template<typename _Tp> static inline _Tp randu() { return (_Tp)theRNG(); }
 -
 -//! fills array with uniformly-distributed random numbers from the range [low, high)
 -CV_EXPORTS_W void randu(InputOutputArray dst, InputArray low, InputArray high);
 -
 -//! fills array with normally-distributed random numbers with the specified mean and the standard deviation
 -CV_EXPORTS_W void randn(InputOutputArray dst, InputArray mean, InputArray stddev);
 -
 -//! shuffles the input array elements
 -CV_EXPORTS void randShuffle(InputOutputArray dst, double iterFactor=1., RNG* rng=0);
 -CV_EXPORTS_AS(randShuffle) void randShuffle_(InputOutputArray dst, double iterFactor=1.);
 -
 -//! draws the line segment (pt1, pt2) in the image
 -CV_EXPORTS_W void line(CV_IN_OUT Mat& img, Point pt1, Point pt2, const Scalar& color,
 -                     int thickness=1, int lineType=8, int shift=0);
 -
 -//! draws the rectangle outline or a solid rectangle with the opposite corners pt1 and pt2 in the image
 -CV_EXPORTS_W void rectangle(CV_IN_OUT Mat& img, Point pt1, Point pt2,
 -                          const Scalar& color, int thickness=1,
 -                          int lineType=8, int shift=0);
 -
 -//! draws the rectangle outline or a solid rectangle covering rec in the image
 -CV_EXPORTS void rectangle(CV_IN_OUT Mat& img, Rect rec,
 -                          const Scalar& color, int thickness=1,
 -                          int lineType=8, int shift=0);
 -
 -//! draws the circle outline or a solid circle in the image
 -CV_EXPORTS_W void circle(CV_IN_OUT Mat& img, Point center, int radius,
 -                       const Scalar& color, int thickness=1,
 -                       int lineType=8, int shift=0);
 -
 -//! draws an elliptic arc, ellipse sector or a rotated ellipse in the image
 -CV_EXPORTS_W void ellipse(CV_IN_OUT Mat& img, Point center, Size axes,
 -                        double angle, double startAngle, double endAngle,
 -                        const Scalar& color, int thickness=1,
 -                        int lineType=8, int shift=0);
 -
 -//! draws a rotated ellipse in the image
 -CV_EXPORTS_W void ellipse(CV_IN_OUT Mat& img, const RotatedRect& box, const Scalar& color,
 -                        int thickness=1, int lineType=8);
 -
 -//! draws a filled convex polygon in the image
 -CV_EXPORTS void fillConvexPoly(Mat& img, const Point* pts, int npts,
 -                               const Scalar& color, int lineType=8,
 -                               int shift=0);
 -CV_EXPORTS_W void fillConvexPoly(InputOutputArray img, InputArray points,
 -                                 const Scalar& color, int lineType=8,
 -                                 int shift=0);
 -
 -//! fills an area bounded by one or more polygons
 -CV_EXPORTS void fillPoly(Mat& img, const Point** pts,
 -                         const int* npts, int ncontours,
 -                         const Scalar& color, int lineType=8, int shift=0,
 -                         Point offset=Point() );
 -
 -CV_EXPORTS_W void fillPoly(InputOutputArray img, InputArrayOfArrays pts,
 -                           const Scalar& color, int lineType=8, int shift=0,
 -                           Point offset=Point() );
 -
 -//! draws one or more polygonal curves
 -CV_EXPORTS void polylines(Mat& img, const Point** pts, const int* npts,
 -                          int ncontours, bool isClosed, const Scalar& color,
 -                          int thickness=1, int lineType=8, int shift=0 );
 -
 -CV_EXPORTS_W void polylines(InputOutputArray img, InputArrayOfArrays pts,
 -                            bool isClosed, const Scalar& color,
 -                            int thickness=1, int lineType=8, int shift=0 );
 -
 -//! clips the line segment by the rectangle Rect(0, 0, imgSize.width, imgSize.height)
 -CV_EXPORTS bool clipLine(Size imgSize, CV_IN_OUT Point& pt1, CV_IN_OUT Point& pt2);
 -
 -//! clips the line segment by the rectangle imgRect
 -CV_EXPORTS_W bool clipLine(Rect imgRect, CV_OUT CV_IN_OUT Point& pt1, CV_OUT CV_IN_OUT Point& pt2);
 -
 -/*!
 -   Line iterator class
 -
 -   The class is used to iterate over all the pixels on the raster line
 -   segment connecting two specified points.
 -*/
 -class CV_EXPORTS LineIterator
 -{
 -public:
 -    //! intializes the iterator
 -    LineIterator( const Mat& img, Point pt1, Point pt2,
 -                  int connectivity=8, bool leftToRight=false );
 -    //! returns pointer to the current pixel
 -    uchar* operator *();
 -    //! prefix increment operator (++it). shifts iterator to the next pixel
 -    LineIterator& operator ++();
 -    //! postfix increment operator (it++). shifts iterator to the next pixel
 -    LineIterator operator ++(int);
 -    //! returns coordinates of the current pixel
 -    Point pos() const;
 -
 -    uchar* ptr;
 -    const uchar* ptr0;
 -    int step, elemSize;
 -    int err, count;
 -    int minusDelta, plusDelta;
 -    int minusStep, plusStep;
 -};
 -
 -//! converts elliptic arc to a polygonal curve
 -CV_EXPORTS_W void ellipse2Poly( Point center, Size axes, int angle,
 -                                int arcStart, int arcEnd, int delta,
 -                                CV_OUT vector<Point>& pts );
 -
 -enum
 -{
 -    FONT_HERSHEY_SIMPLEX = 0,
 -    FONT_HERSHEY_PLAIN = 1,
 -    FONT_HERSHEY_DUPLEX = 2,
 -    FONT_HERSHEY_COMPLEX = 3,
 -    FONT_HERSHEY_TRIPLEX = 4,
 -    FONT_HERSHEY_COMPLEX_SMALL = 5,
 -    FONT_HERSHEY_SCRIPT_SIMPLEX = 6,
 -    FONT_HERSHEY_SCRIPT_COMPLEX = 7,
 -    FONT_ITALIC = 16
 -};
 -
 -//! renders text string in the image
 -CV_EXPORTS_W void putText( Mat& img, const string& text, Point org,
 -                         int fontFace, double fontScale, Scalar color,
 -                         int thickness=1, int lineType=8,
 -                         bool bottomLeftOrigin=false );
 -
 -//! returns bounding box of the text string
 -CV_EXPORTS_W Size getTextSize(const string& text, int fontFace,
 -                            double fontScale, int thickness,
 -                            CV_OUT int* baseLine);
 -
 -///////////////////////////////// Mat_<_Tp> ////////////////////////////////////
 -
 -/*!
 - Template matrix class derived from Mat
 -
 - The class Mat_ is a "thin" template wrapper on top of cv::Mat. It does not have any extra data fields,
 - nor it or cv::Mat have any virtual methods and thus references or pointers to these two classes
 - can be safely converted one to another. But do it with care, for example:
 -
 - \code
 - // create 100x100 8-bit matrix
 - Mat M(100,100,CV_8U);
 - // this will compile fine. no any data conversion will be done.
 - Mat_<float>& M1 = (Mat_<float>&)M;
 - // the program will likely crash at the statement below
 - M1(99,99) = 1.f;
 - \endcode
 -
 - While cv::Mat is sufficient in most cases, cv::Mat_ can be more convenient if you use a lot of element
 - access operations and if you know matrix type at compile time.
 - Note that cv::Mat::at<_Tp>(int y, int x) and cv::Mat_<_Tp>::operator ()(int y, int x) do absolutely the
 - same thing and run at the same speed, but the latter is certainly shorter:
 -
 - \code
 - Mat_<double> M(20,20);
 - for(int i = 0; i < M.rows; i++)
 -    for(int j = 0; j < M.cols; j++)
 -       M(i,j) = 1./(i+j+1);
 - Mat E, V;
 - eigen(M,E,V);
 - cout << E.at<double>(0,0)/E.at<double>(M.rows-1,0);
 - \endcode
 -
 - It is easy to use Mat_ for multi-channel images/matrices - just pass cv::Vec as cv::Mat_ template parameter:
 -
 - \code
 - // allocate 320x240 color image and fill it with green (in RGB space)
 - Mat_<Vec3b> img(240, 320, Vec3b(0,255,0));
 - // now draw a diagonal white line
 - for(int i = 0; i < 100; i++)
 -     img(i,i)=Vec3b(255,255,255);
 - // and now modify the 2nd (red) channel of each pixel
 - for(int i = 0; i < img.rows; i++)
 -    for(int j = 0; j < img.cols; j++)
 -       img(i,j)[2] ^= (uchar)(i ^ j); // img(y,x)[c] accesses c-th channel of the pixel (x,y)
 - \endcode
 -*/
 -template<typename _Tp> class CV_EXPORTS Mat_ : public Mat
 -{
 -public:
 -    typedef _Tp value_type;
 -    typedef typename DataType<_Tp>::channel_type channel_type;
 -    typedef MatIterator_<_Tp> iterator;
 -    typedef MatConstIterator_<_Tp> const_iterator;
 -
 -    //! default constructor
 -    Mat_();
 -    //! equivalent to Mat(_rows, _cols, DataType<_Tp>::type)
 -    Mat_(int _rows, int _cols);
 -    //! constructor that sets each matrix element to specified value
 -    Mat_(int _rows, int _cols, const _Tp& value);
 -    //! equivalent to Mat(_size, DataType<_Tp>::type)
 -    explicit Mat_(Size _size);
 -    //! constructor that sets each matrix element to specified value
 -    Mat_(Size _size, const _Tp& value);
 -    //! n-dim array constructor
 -    Mat_(int _ndims, const int* _sizes);
 -    //! n-dim array constructor that sets each matrix element to specified value
 -    Mat_(int _ndims, const int* _sizes, const _Tp& value);
 -    //! copy/conversion contructor. If m is of different type, it's converted
 -    Mat_(const Mat& m);
 -    //! copy constructor
 -    Mat_(const Mat_& m);
 -    //! constructs a matrix on top of user-allocated data. step is in bytes(!!!), regardless of the type
 -    Mat_(int _rows, int _cols, _Tp* _data, size_t _step=AUTO_STEP);
 -    //! constructs n-dim matrix on top of user-allocated data. steps are in bytes(!!!), regardless of the type
 -    Mat_(int _ndims, const int* _sizes, _Tp* _data, const size_t* _steps=0);
 -    //! selects a submatrix
 -    Mat_(const Mat_& m, const Range& rowRange, const Range& colRange=Range::all());
 -    //! selects a submatrix
 -    Mat_(const Mat_& m, const Rect& roi);
 -    //! selects a submatrix, n-dim version
 -    Mat_(const Mat_& m, const Range* ranges);
 -    //! from a matrix expression
 -    explicit Mat_(const MatExpr& e);
 -    //! makes a matrix out of Vec, std::vector, Point_ or Point3_. The matrix will have a single column
 -    explicit Mat_(const vector<_Tp>& vec, bool copyData=false);
 -    template<int n> explicit Mat_(const Vec<typename DataType<_Tp>::channel_type, n>& vec, bool copyData=true);
 -    template<int m, int n> explicit Mat_(const Matx<typename DataType<_Tp>::channel_type, m, n>& mtx, bool copyData=true);
 -    explicit Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData=true);
 -    explicit Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData=true);
 -    explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer);
 -
 -    Mat_& operator = (const Mat& m);
 -    Mat_& operator = (const Mat_& m);
 -    //! set all the elements to s.
 -    Mat_& operator = (const _Tp& s);
 -    //! assign a matrix expression
 -    Mat_& operator = (const MatExpr& e);
 -
 -    //! iterators; they are smart enough to skip gaps in the end of rows
 -    iterator begin();
 -    iterator end();
 -    const_iterator begin() const;
 -    const_iterator end() const;
 -
 -    //! equivalent to Mat::create(_rows, _cols, DataType<_Tp>::type)
 -    void create(int _rows, int _cols);
 -    //! equivalent to Mat::create(_size, DataType<_Tp>::type)
 -    void create(Size _size);
 -    //! equivalent to Mat::create(_ndims, _sizes, DatType<_Tp>::type)
 -    void create(int _ndims, const int* _sizes);
 -    //! cross-product
 -    Mat_ cross(const Mat_& m) const;
 -    //! data type conversion
 -    template<typename T2> operator Mat_<T2>() const;
 -    //! overridden forms of Mat::row() etc.
 -    Mat_ row(int y) const;
 -    Mat_ col(int x) const;
 -    Mat_ diag(int d=0) const;
 -    Mat_ clone() const;
 -
 -    //! overridden forms of Mat::elemSize() etc.
 -    size_t elemSize() const;
 -    size_t elemSize1() const;
 -    int type() const;
 -    int depth() const;
 -    int channels() const;
 -    size_t step1(int i=0) const;
 -    //! returns step()/sizeof(_Tp)
 -    size_t stepT(int i=0) const;
 -
 -    //! overridden forms of Mat::zeros() etc. Data type is omitted, of course
 -    static MatExpr zeros(int rows, int cols);
 -    static MatExpr zeros(Size size);
 -    static MatExpr zeros(int _ndims, const int* _sizes);
 -    static MatExpr ones(int rows, int cols);
 -    static MatExpr ones(Size size);
 -    static MatExpr ones(int _ndims, const int* _sizes);
 -    static MatExpr eye(int rows, int cols);
 -    static MatExpr eye(Size size);
 -
 -    //! some more overriden methods
 -    Mat_& adjustROI( int dtop, int dbottom, int dleft, int dright );
 -    Mat_ operator()( const Range& rowRange, const Range& colRange ) const;
 -    Mat_ operator()( const Rect& roi ) const;
 -    Mat_ operator()( const Range* ranges ) const;
 -
 -    //! more convenient forms of row and element access operators
 -    _Tp* operator [](int y);
 -    const _Tp* operator [](int y) const;
 -
 -    //! returns reference to the specified element
 -    _Tp& operator ()(const int* idx);
 -    //! returns read-only reference to the specified element
 -    const _Tp& operator ()(const int* idx) const;
 -
 -    //! returns reference to the specified element
 -    template<int n> _Tp& operator ()(const Vec<int, n>& idx);
 -    //! returns read-only reference to the specified element
 -    template<int n> const _Tp& operator ()(const Vec<int, n>& idx) const;
 -
 -    //! returns reference to the specified element (1D case)
 -    _Tp& operator ()(int idx0);
 -    //! returns read-only reference to the specified element (1D case)
 -    const _Tp& operator ()(int idx0) const;
 -    //! returns reference to the specified element (2D case)
 -    _Tp& operator ()(int idx0, int idx1);
 -    //! returns read-only reference to the specified element (2D case)
 -    const _Tp& operator ()(int idx0, int idx1) const;
 -    //! returns reference to the specified element (3D case)
 -    _Tp& operator ()(int idx0, int idx1, int idx2);
 -    //! returns read-only reference to the specified element (3D case)
 -    const _Tp& operator ()(int idx0, int idx1, int idx2) const;
 -
 -    _Tp& operator ()(Point pt);
 -    const _Tp& operator ()(Point pt) const;
 -
 -    //! conversion to vector.
 -    operator vector<_Tp>() const;
 -    //! conversion to Vec
 -    template<int n> operator Vec<typename DataType<_Tp>::channel_type, n>() const;
 -    //! conversion to Matx
 -    template<int m, int n> operator Matx<typename DataType<_Tp>::channel_type, m, n>() const;
 -};
 -
 -typedef Mat_<uchar> Mat1b;
 -typedef Mat_<Vec2b> Mat2b;
 -typedef Mat_<Vec3b> Mat3b;
 -typedef Mat_<Vec4b> Mat4b;
 -
 -typedef Mat_<short> Mat1s;
 -typedef Mat_<Vec2s> Mat2s;
 -typedef Mat_<Vec3s> Mat3s;
 -typedef Mat_<Vec4s> Mat4s;
 -
 -typedef Mat_<ushort> Mat1w;
 -typedef Mat_<Vec2w> Mat2w;
 -typedef Mat_<Vec3w> Mat3w;
 -typedef Mat_<Vec4w> Mat4w;
 -
 -typedef Mat_<int>   Mat1i;
 -typedef Mat_<Vec2i> Mat2i;
 -typedef Mat_<Vec3i> Mat3i;
 -typedef Mat_<Vec4i> Mat4i;
 -
 -typedef Mat_<float> Mat1f;
 -typedef Mat_<Vec2f> Mat2f;
 -typedef Mat_<Vec3f> Mat3f;
 -typedef Mat_<Vec4f> Mat4f;
 -
 -typedef Mat_<double> Mat1d;
 -typedef Mat_<Vec2d> Mat2d;
 -typedef Mat_<Vec3d> Mat3d;
 -typedef Mat_<Vec4d> Mat4d;
 -
 -//////////// Iterators & Comma initializers //////////////////
 -
 -class CV_EXPORTS MatConstIterator
 -{
 -public:
 -    typedef uchar* value_type;
 -    typedef ptrdiff_t difference_type;
 -    typedef const uchar** pointer;
 -    typedef uchar* reference;
 -    typedef std::random_access_iterator_tag iterator_category;
 -
 -    //! default constructor
 -    MatConstIterator();
 -    //! constructor that sets the iterator to the beginning of the matrix
 -    MatConstIterator(const Mat* _m);
 -    //! constructor that sets the iterator to the specified element of the matrix
 -    MatConstIterator(const Mat* _m, int _row, int _col=0);
 -    //! constructor that sets the iterator to the specified element of the matrix
 -    MatConstIterator(const Mat* _m, Point _pt);
 -    //! constructor that sets the iterator to the specified element of the matrix
 -    MatConstIterator(const Mat* _m, const int* _idx);
 -    //! copy constructor
 -    MatConstIterator(const MatConstIterator& it);
 -
 -    //! copy operator
 -    MatConstIterator& operator = (const MatConstIterator& it);
 -    //! returns the current matrix element
 -    uchar* operator *() const;
 -    //! returns the i-th matrix element, relative to the current
 -    uchar* operator [](ptrdiff_t i) const;
 -
 -    //! shifts the iterator forward by the specified number of elements
 -    MatConstIterator& operator += (ptrdiff_t ofs);
 -    //! shifts the iterator backward by the specified number of elements
 -    MatConstIterator& operator -= (ptrdiff_t ofs);
 -    //! decrements the iterator
 -    MatConstIterator& operator --();
 -    //! decrements the iterator
 -    MatConstIterator operator --(int);
 -    //! increments the iterator
 -    MatConstIterator& operator ++();
 -    //! increments the iterator
 -    MatConstIterator operator ++(int);
 -    //! returns the current iterator position
 -    Point pos() const;
 -    //! returns the current iterator position
 -    void pos(int* _idx) const;
 -    ptrdiff_t lpos() const;
 -    void seek(ptrdiff_t ofs, bool relative=false);
 -    void seek(const int* _idx, bool relative=false);
 -
 -    const Mat* m;
 -    size_t elemSize;
 -    uchar* ptr;
 -    uchar* sliceStart;
 -    uchar* sliceEnd;
 -};
 -
 -/*!
 - Matrix read-only iterator
 -
 - */
 -template<typename _Tp>
 -class CV_EXPORTS MatConstIterator_ : public MatConstIterator
 -{
 -public:
 -    typedef _Tp value_type;
 -    typedef ptrdiff_t difference_type;
 -    typedef const _Tp* pointer;
 -    typedef const _Tp& reference;
 -    typedef std::random_access_iterator_tag iterator_category;
 -
 -    //! default constructor
 -    MatConstIterator_();
 -    //! constructor that sets the iterator to the beginning of the matrix
 -    MatConstIterator_(const Mat_<_Tp>* _m);
 -    //! constructor that sets the iterator to the specified element of the matrix
 -    MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col=0);
 -    //! constructor that sets the iterator to the specified element of the matrix
 -    MatConstIterator_(const Mat_<_Tp>* _m, Point _pt);
 -    //! constructor that sets the iterator to the specified element of the matrix
 -    MatConstIterator_(const Mat_<_Tp>* _m, const int* _idx);
 -    //! copy constructor
 -    MatConstIterator_(const MatConstIterator_& it);
 -
 -    //! copy operator
 -    MatConstIterator_& operator = (const MatConstIterator_& it);
 -    //! returns the current matrix element
 -    _Tp operator *() const;
 -    //! returns the i-th matrix element, relative to the current
 -    _Tp operator [](ptrdiff_t i) const;
 -
 -    //! shifts the iterator forward by the specified number of elements
 -    MatConstIterator_& operator += (ptrdiff_t ofs);
 -    //! shifts the iterator backward by the specified number of elements
 -    MatConstIterator_& operator -= (ptrdiff_t ofs);
 -    //! decrements the iterator
 -    MatConstIterator_& operator --();
 -    //! decrements the iterator
 -    MatConstIterator_ operator --(int);
 -    //! increments the iterator
 -    MatConstIterator_& operator ++();
 -    //! increments the iterator
 -    MatConstIterator_ operator ++(int);
 -    //! returns the current iterator position
 -    Point pos() const;
 -};
 -
 -
 -/*!
 - Matrix read-write iterator
 -
 -*/
 -template<typename _Tp>
 -class CV_EXPORTS MatIterator_ : public MatConstIterator_<_Tp>
 -{
 -public:
 -    typedef _Tp* pointer;
 -    typedef _Tp& reference;
 -    typedef std::random_access_iterator_tag iterator_category;
 -
 -    //! the default constructor
 -    MatIterator_();
 -    //! constructor that sets the iterator to the beginning of the matrix
 -    MatIterator_(Mat_<_Tp>* _m);
 -    //! constructor that sets the iterator to the specified element of the matrix
 -    MatIterator_(Mat_<_Tp>* _m, int _row, int _col=0);
 -    //! constructor that sets the iterator to the specified element of the matrix
 -    MatIterator_(const Mat_<_Tp>* _m, Point _pt);
 -    //! constructor that sets the iterator to the specified element of the matrix
 -    MatIterator_(const Mat_<_Tp>* _m, const int* _idx);
 -    //! copy constructor
 -    MatIterator_(const MatIterator_& it);
 -    //! copy operator
 -    MatIterator_& operator = (const MatIterator_<_Tp>& it );
 -
 -    //! returns the current matrix element
 -    _Tp& operator *() const;
 -    //! returns the i-th matrix element, relative to the current
 -    _Tp& operator [](ptrdiff_t i) const;
 -
 -    //! shifts the iterator forward by the specified number of elements
 -    MatIterator_& operator += (ptrdiff_t ofs);
 -    //! shifts the iterator backward by the specified number of elements
 -    MatIterator_& operator -= (ptrdiff_t ofs);
 -    //! decrements the iterator
 -    MatIterator_& operator --();
 -    //! decrements the iterator
 -    MatIterator_ operator --(int);
 -    //! increments the iterator
 -    MatIterator_& operator ++();
 -    //! increments the iterator
 -    MatIterator_ operator ++(int);
 -};
 -
 -template<typename _Tp> class CV_EXPORTS MatOp_Iter_;
 -
 -/*!
 - Comma-separated Matrix Initializer
 -
 - The class instances are usually not created explicitly.
 - Instead, they are created on "matrix << firstValue" operator.
 -
 - The sample below initializes 2x2 rotation matrix:
 -
 - \code
 - double angle = 30, a = cos(angle*CV_PI/180), b = sin(angle*CV_PI/180);
 - Mat R = (Mat_<double>(2,2) << a, -b, b, a);
 - \endcode
 -*/
 -template<typename _Tp> class CV_EXPORTS MatCommaInitializer_
 -{
 -public:
 -    //! the constructor, created by "matrix << firstValue" operator, where matrix is cv::Mat
 -    MatCommaInitializer_(Mat_<_Tp>* _m);
 -    //! the operator that takes the next value and put it to the matrix
 -    template<typename T2> MatCommaInitializer_<_Tp>& operator , (T2 v);
 -    //! another form of conversion operator
 -    Mat_<_Tp> operator *() const;
 -    operator Mat_<_Tp>() const;
 -protected:
 -    MatIterator_<_Tp> it;
 -};
 -
 -
 -template<typename _Tp, int m, int n> class CV_EXPORTS MatxCommaInitializer
 -{
 -public:
 -    MatxCommaInitializer(Matx<_Tp, m, n>* _mtx);
 -    template<typename T2> MatxCommaInitializer<_Tp, m, n>& operator , (T2 val);
 -    Matx<_Tp, m, n> operator *() const;
 -
 -    Matx<_Tp, m, n>* dst;
 -    int idx;
 -};
 -
 -template<typename _Tp, int m> class CV_EXPORTS VecCommaInitializer : public MatxCommaInitializer<_Tp, m, 1>
 -{
 -public:
 -    VecCommaInitializer(Vec<_Tp, m>* _vec);
 -    template<typename T2> VecCommaInitializer<_Tp, m>& operator , (T2 val);
 -    Vec<_Tp, m> operator *() const;
 -};
 -
 -/*!
 - Automatically Allocated Buffer Class
 -
 - The class is used for temporary buffers in functions and methods.
 - If a temporary buffer is usually small (a few K's of memory),
 - but its size depends on the parameters, it makes sense to create a small
 - fixed-size array on stack and use it if it's large enough. If the required buffer size
 - is larger than the fixed size, another buffer of sufficient size is allocated dynamically
 - and released after the processing. Therefore, in typical cases, when the buffer size is small,
 - there is no overhead associated with malloc()/free().
 - At the same time, there is no limit on the size of processed data.
 -
 - This is what AutoBuffer does. The template takes 2 parameters - type of the buffer elements and
 - the number of stack-allocated elements. Here is how the class is used:
 -
 - \code
 - void my_func(const cv::Mat& m)
 - {
 -    cv::AutoBuffer<float, 1000> buf; // create automatic buffer containing 1000 floats
 -
 -    buf.allocate(m.rows); // if m.rows <= 1000, the pre-allocated buffer is used,
 -                          // otherwise the buffer of "m.rows" floats will be allocated
 -                          // dynamically and deallocated in cv::AutoBuffer destructor
 -    ...
 - }
 - \endcode
 -*/
 -template<typename _Tp, size_t fixed_size=4096/sizeof(_Tp)+8> class CV_EXPORTS AutoBuffer
 -{
 -public:
 -    typedef _Tp value_type;
 -    enum { buffer_padding = (int)((16 + sizeof(_Tp) - 1)/sizeof(_Tp)) };
 -
 -    //! the default contructor
 -    AutoBuffer();
 -    //! constructor taking the real buffer size
 -    AutoBuffer(size_t _size);
 -    //! destructor. calls deallocate()
 -    ~AutoBuffer();
 -
 -    //! allocates the new buffer of size _size. if the _size is small enough, stack-allocated buffer is used
 -    void allocate(size_t _size);
 -    //! deallocates the buffer if it was dynamically allocated
 -    void deallocate();
 -    //! returns pointer to the real buffer, stack-allocated or head-allocated
 -    operator _Tp* ();
 -    //! returns read-only pointer to the real buffer, stack-allocated or head-allocated
 -    operator const _Tp* () const;
 -
 -protected:
 -    //! pointer to the real buffer, can point to buf if the buffer is small enough
 -    _Tp* ptr;
 -    //! size of the real buffer
 -    size_t size;
 -    //! pre-allocated buffer
 -    _Tp buf[fixed_size+buffer_padding];
 -};
 -
 -/////////////////////////// multi-dimensional dense matrix //////////////////////////
 -
 -/*!
 - n-Dimensional Dense Matrix Iterator Class.
 -
 - The class cv::NAryMatIterator is used for iterating over one or more n-dimensional dense arrays (cv::Mat's).
 -
 - The iterator is completely different from cv::Mat_ and cv::SparseMat_ iterators.
 - It iterates through the slices (or planes), not the elements, where "slice" is a continuous part of the arrays.
 -
 - Here is the example on how the iterator can be used to normalize 3D histogram:
 -
 - \code
 - void normalizeColorHist(Mat& hist)
 - {
 - #if 1
 -     // intialize iterator (the style is different from STL).
 -     // after initialization the iterator will contain
 -     // the number of slices or planes
 -     // the iterator will go through
 -     Mat* arrays[] = { &hist, 0 };
 -     Mat planes[1];
 -     NAryMatIterator it(arrays, planes);
 -     double s = 0;
 -     // iterate through the matrix. on each iteration
 -     // it.planes[i] (of type Mat) will be set to the current plane of
 -     // i-th n-dim matrix passed to the iterator constructor.
 -     for(int p = 0; p < it.nplanes; p++, ++it)
 -        s += sum(it.planes[0])[0];
 -     it = NAryMatIterator(hist);
 -     s = 1./s;
 -     for(int p = 0; p < it.nplanes; p++, ++it)
 -        it.planes[0] *= s;
 - #elif 1
 -     // this is a shorter implementation of the above
 -     // using built-in operations on Mat
 -     double s = sum(hist)[0];
 -     hist.convertTo(hist, hist.type(), 1./s, 0);
 - #else
 -     // and this is even shorter one
 -     // (assuming that the histogram elements are non-negative)
 -     normalize(hist, hist, 1, 0, NORM_L1);
 - #endif
 - }
 - \endcode
 -
 - You can iterate through several matrices simultaneously as long as they have the same geometry
 - (dimensionality and all the dimension sizes are the same), which is useful for binary
 - and n-ary operations on such matrices. Just pass those matrices to cv::MatNDIterator.
 - Then, during the iteration it.planes[0], it.planes[1], ... will
 - be the slices of the corresponding matrices
 -*/
 -class CV_EXPORTS NAryMatIterator
 -{
 -public:
 -    //! the default constructor
 -    NAryMatIterator();
 -    //! the full constructor taking arbitrary number of n-dim matrices
 -    NAryMatIterator(const Mat** arrays, uchar** ptrs, int narrays=-1);
 -    //! the full constructor taking arbitrary number of n-dim matrices
 -    NAryMatIterator(const Mat** arrays, Mat* planes, int narrays=-1);
 -    //! the separate iterator initialization method
 -    void init(const Mat** arrays, Mat* planes, uchar** ptrs, int narrays=-1);
 -
 -    //! proceeds to the next plane of every iterated matrix
 -    NAryMatIterator& operator ++();
 -    //! proceeds to the next plane of every iterated matrix (postfix increment operator)
 -    NAryMatIterator operator ++(int);
 -
 -    //! the iterated arrays
 -    const Mat** arrays;
 -    //! the current planes
 -    Mat* planes;
 -    //! data pointers
 -    uchar** ptrs;
 -    //! the number of arrays
 -    int narrays;
 -    //! the number of hyper-planes that the iterator steps through
 -    size_t nplanes;
 -    //! the size of each segment (in elements)
 -    size_t size;
 -protected:
 -    int iterdepth;
 -    size_t idx;
 -};
 -
 -//typedef NAryMatIterator NAryMatNDIterator;
 -
 -typedef void (*ConvertData)(const void* from, void* to, int cn);
 -typedef void (*ConvertScaleData)(const void* from, void* to, int cn, double alpha, double beta);
 -
 -//! returns the function for converting pixels from one data type to another
 -CV_EXPORTS ConvertData getConvertElem(int fromType, int toType);
 -//! returns the function for converting pixels from one data type to another with the optional scaling
 -CV_EXPORTS ConvertScaleData getConvertScaleElem(int fromType, int toType);
 -
 -
 -/////////////////////////// multi-dimensional sparse matrix //////////////////////////
 -
 -class SparseMatIterator;
 -class SparseMatConstIterator;
 -template<typename _Tp> class SparseMatIterator_;
 -template<typename _Tp> class SparseMatConstIterator_;
 -
 -/*!
 - Sparse matrix class.
 -
 - The class represents multi-dimensional sparse numerical arrays. Such a sparse array can store elements
 - of any type that cv::Mat is able to store. "Sparse" means that only non-zero elements
 - are stored (though, as a result of some operations on a sparse matrix, some of its stored elements
 - can actually become 0. It's user responsibility to detect such elements and delete them using cv::SparseMat::erase().
 - The non-zero elements are stored in a hash table that grows when it's filled enough,
 - so that the search time remains O(1) in average. Elements can be accessed using the following methods:
 -
 - <ol>
 - <li>Query operations: cv::SparseMat::ptr() and the higher-level cv::SparseMat::ref(),
 -      cv::SparseMat::value() and cv::SparseMat::find, for example:
 - \code
 - const int dims = 5;
 - int size[] = {10, 10, 10, 10, 10};
 - SparseMat sparse_mat(dims, size, CV_32F);
 - for(int i = 0; i < 1000; i++)
 - {
 -     int idx[dims];
 -     for(int k = 0; k < dims; k++)
 -        idx[k] = rand()%sparse_mat.size(k);
 -     sparse_mat.ref<float>(idx) += 1.f;
 - }
 - \endcode
 -
 - <li>Sparse matrix iterators. Like cv::Mat iterators and unlike cv::Mat iterators, the sparse matrix iterators are STL-style,
 - that is, the iteration is done as following:
 - \code
 - // prints elements of a sparse floating-point matrix and the sum of elements.
 - SparseMatConstIterator_<float>
 -        it = sparse_mat.begin<float>(),
 -        it_end = sparse_mat.end<float>();
 - double s = 0;
 - int dims = sparse_mat.dims();
 - for(; it != it_end; ++it)
 - {
 -     // print element indices and the element value
 -     const Node* n = it.node();
 -     printf("(")
 -     for(int i = 0; i < dims; i++)
 -        printf("%3d%c", n->idx[i], i < dims-1 ? ',' : ')');
 -     printf(": %f\n", *it);
 -     s += *it;
 - }
 - printf("Element sum is %g\n", s);
 - \endcode
 - If you run this loop, you will notice that elements are enumerated
 - in no any logical order (lexicographical etc.),
 - they come in the same order as they stored in the hash table, i.e. semi-randomly.
 -
 - You may collect pointers to the nodes and sort them to get the proper ordering.
 - Note, however, that pointers to the nodes may become invalid when you add more
 - elements to the matrix; this is because of possible buffer reallocation.
 -
 - <li>A combination of the above 2 methods when you need to process 2 or more sparse
 - matrices simultaneously, e.g. this is how you can compute unnormalized
 - cross-correlation of the 2 floating-point sparse matrices:
 - \code
 - double crossCorr(const SparseMat& a, const SparseMat& b)
 - {
 -     const SparseMat *_a = &a, *_b = &b;
 -     // if b contains less elements than a,
 -     // it's faster to iterate through b
 -     if(_a->nzcount() > _b->nzcount())
 -        std::swap(_a, _b);
 -     SparseMatConstIterator_<float> it = _a->begin<float>(),
 -                                    it_end = _a->end<float>();
 -     double ccorr = 0;
 -     for(; it != it_end; ++it)
 -     {
 -         // take the next element from the first matrix
 -         float avalue = *it;
 -         const Node* anode = it.node();
 -         // and try to find element with the same index in the second matrix.
 -         // since the hash value depends only on the element index,
 -         // we reuse hashvalue stored in the node
 -         float bvalue = _b->value<float>(anode->idx,&anode->hashval);
 -         ccorr += avalue*bvalue;
 -     }
 -     return ccorr;
 - }
 - \endcode
 - </ol>
 -*/
 -class CV_EXPORTS SparseMat
 -{
 -public:
 -    typedef SparseMatIterator iterator;
 -    typedef SparseMatConstIterator const_iterator;
 -
 -    //! the sparse matrix header
 -    struct CV_EXPORTS Hdr
 -    {
 -        Hdr(int _dims, const int* _sizes, int _type);
 -        void clear();
 -        int refcount;
 -        int dims;
 -        int valueOffset;
 -        size_t nodeSize;
 -        size_t nodeCount;
 -        size_t freeList;
 -        vector<uchar> pool;
 -        vector<size_t> hashtab;
 -        int size[CV_MAX_DIM];
 -    };
 -
 -    //! sparse matrix node - element of a hash table
 -    struct CV_EXPORTS Node
 -    {
 -        //! hash value
 -        size_t hashval;
 -        //! index of the next node in the same hash table entry
 -        size_t next;
 -        //! index of the matrix element
 -        int idx[CV_MAX_DIM];
 -    };
 -
 -    //! default constructor
 -    SparseMat();
 -    //! creates matrix of the specified size and type
 -    SparseMat(int dims, const int* _sizes, int _type);
 -    //! copy constructor
 -    SparseMat(const SparseMat& m);
 -    //! converts dense 2d matrix to the sparse form
 -    /*!
 -     \param m the input matrix
 -     \param try1d if true and m is a single-column matrix (Nx1),
 -            then the sparse matrix will be 1-dimensional.
 -    */
 -    explicit SparseMat(const Mat& m);
 -    //! converts old-style sparse matrix to the new-style. All the data is copied
 -    SparseMat(const CvSparseMat* m);
 -    //! the destructor
 -    ~SparseMat();
 -
 -    //! assignment operator. This is O(1) operation, i.e. no data is copied
 -    SparseMat& operator = (const SparseMat& m);
 -    //! equivalent to the corresponding constructor
 -    SparseMat& operator = (const Mat& m);
 -
 -    //! creates full copy of the matrix
 -    SparseMat clone() const;
 -
 -    //! copies all the data to the destination matrix. All the previous content of m is erased
 -    void copyTo( SparseMat& m ) const;
 -    //! converts sparse matrix to dense matrix.
 -    void copyTo( Mat& m ) const;
 -    //! multiplies all the matrix elements by the specified scale factor alpha and converts the results to the specified data type
 -    void convertTo( SparseMat& m, int rtype, double alpha=1 ) const;
 -    //! converts sparse matrix to dense n-dim matrix with optional type conversion and scaling.
 -    /*!
 -      \param rtype The output matrix data type. When it is =-1, the output array will have the same data type as (*this)
 -      \param alpha The scale factor
 -      \param beta The optional delta added to the scaled values before the conversion
 -    */
 -    void convertTo( Mat& m, int rtype, double alpha=1, double beta=0 ) const;
 -
 -    // not used now
 -    void assignTo( SparseMat& m, int type=-1 ) const;
 -
 -    //! reallocates sparse matrix.
 -    /*!
 -        If the matrix already had the proper size and type,
 -        it is simply cleared with clear(), otherwise,
 -        the old matrix is released (using release()) and the new one is allocated.
 -    */
 -    void create(int dims, const int* _sizes, int _type);
 -    //! sets all the sparse matrix elements to 0, which means clearing the hash table.
 -    void clear();
 -    //! manually increments the reference counter to the header.
 -    void addref();
 -    // decrements the header reference counter. When the counter reaches 0, the header and all the underlying data are deallocated.
 -    void release();
 -
 -    //! converts sparse matrix to the old-style representation; all the elements are copied.
 -    operator CvSparseMat*() const;
 -    //! returns the size of each element in bytes (not including the overhead - the space occupied by SparseMat::Node elements)
 -    size_t elemSize() const;
 -    //! returns elemSize()/channels()
 -    size_t elemSize1() const;
 -
 -    //! returns type of sparse matrix elements
 -    int type() const;
 -    //! returns the depth of sparse matrix elements
 -    int depth() const;
 -    //! returns the number of channels
 -    int channels() const;
 -
 -    //! returns the array of sizes, or NULL if the matrix is not allocated
 -    const int* size() const;
 -    //! returns the size of i-th matrix dimension (or 0)
 -    int size(int i) const;
 -    //! returns the matrix dimensionality
 -    int dims() const;
 -    //! returns the number of non-zero elements (=the number of hash table nodes)
 -    size_t nzcount() const;
 -
 -    //! computes the element hash value (1D case)
 -    size_t hash(int i0) const;
 -    //! computes the element hash value (2D case)
 -    size_t hash(int i0, int i1) const;
 -    //! computes the element hash value (3D case)
 -    size_t hash(int i0, int i1, int i2) const;
 -    //! computes the element hash value (nD case)
 -    size_t hash(const int* idx) const;
 -
 -    //@{
 -    /*!
 -     specialized variants for 1D, 2D, 3D cases and the generic_type one for n-D case.
 -
 -     return pointer to the matrix element.
 -     <ul>
 -      <li>if the element is there (it's non-zero), the pointer to it is returned
 -      <li>if it's not there and createMissing=false, NULL pointer is returned
 -      <li>if it's not there and createMissing=true, then the new element
 -        is created and initialized with 0. Pointer to it is returned
 -      <li>if the optional hashval pointer is not NULL, the element hash value is
 -      not computed, but *hashval is taken instead.
 -     </ul>
 -    */
 -    //! returns pointer to the specified element (1D case)
 -    uchar* ptr(int i0, bool createMissing, size_t* hashval=0);
 -    //! returns pointer to the specified element (2D case)
 -    uchar* ptr(int i0, int i1, bool createMissing, size_t* hashval=0);
 -    //! returns pointer to the specified element (3D case)
 -    uchar* ptr(int i0, int i1, int i2, bool createMissing, size_t* hashval=0);
 -    //! returns pointer to the specified element (nD case)
 -    uchar* ptr(const int* idx, bool createMissing, size_t* hashval=0);
 -    //@}
 -
 -    //@{
 -    /*!
 -     return read-write reference to the specified sparse matrix element.
 -
 -     ref<_Tp>(i0,...[,hashval]) is equivalent to *(_Tp*)ptr(i0,...,true[,hashval]).
 -     The methods always return a valid reference.
 -     If the element did not exist, it is created and initialiazed with 0.
 -    */
 -    //! returns reference to the specified element (1D case)
 -    template<typename _Tp> _Tp& ref(int i0, size_t* hashval=0);
 -    //! returns reference to the specified element (2D case)
 -    template<typename _Tp> _Tp& ref(int i0, int i1, size_t* hashval=0);
 -    //! returns reference to the specified element (3D case)
 -    template<typename _Tp> _Tp& ref(int i0, int i1, int i2, size_t* hashval=0);
 -    //! returns reference to the specified element (nD case)
 -    template<typename _Tp> _Tp& ref(const int* idx, size_t* hashval=0);
 -    //@}
 -
 -    //@{
 -    /*!
 -     return value of the specified sparse matrix element.
 -
 -     value<_Tp>(i0,...[,hashval]) is equivalent
 -
 -     \code
 -     { const _Tp* p = find<_Tp>(i0,...[,hashval]); return p ? *p : _Tp(); }
 -     \endcode
 -
 -     That is, if the element did not exist, the methods return 0.
 -     */
 -    //! returns value of the specified element (1D case)
 -    template<typename _Tp> _Tp value(int i0, size_t* hashval=0) const;
 -    //! returns value of the specified element (2D case)
 -    template<typename _Tp> _Tp value(int i0, int i1, size_t* hashval=0) const;
 -    //! returns value of the specified element (3D case)
 -    template<typename _Tp> _Tp value(int i0, int i1, int i2, size_t* hashval=0) const;
 -    //! returns value of the specified element (nD case)
 -    template<typename _Tp> _Tp value(const int* idx, size_t* hashval=0) const;
 -    //@}
 -
 -    //@{
 -    /*!
 -     Return pointer to the specified sparse matrix element if it exists
 -
 -     find<_Tp>(i0,...[,hashval]) is equivalent to (_const Tp*)ptr(i0,...false[,hashval]).
 -
 -     If the specified element does not exist, the methods return NULL.
 -    */
 -    //! returns pointer to the specified element (1D case)
 -    template<typename _Tp> const _Tp* find(int i0, size_t* hashval=0) const;
 -    //! returns pointer to the specified element (2D case)
 -    template<typename _Tp> const _Tp* find(int i0, int i1, size_t* hashval=0) const;
 -    //! returns pointer to the specified element (3D case)
 -    template<typename _Tp> const _Tp* find(int i0, int i1, int i2, size_t* hashval=0) const;
 -    //! returns pointer to the specified element (nD case)
 -    template<typename _Tp> const _Tp* find(const int* idx, size_t* hashval=0) const;
 -
 -    //! erases the specified element (2D case)
 -    void erase(int i0, int i1, size_t* hashval=0);
 -    //! erases the specified element (3D case)
 -    void erase(int i0, int i1, int i2, size_t* hashval=0);
 -    //! erases the specified element (nD case)
 -    void erase(const int* idx, size_t* hashval=0);
 -
 -    //@{
 -    /*!
 -       return the sparse matrix iterator pointing to the first sparse matrix element
 -    */
 -    //! returns the sparse matrix iterator at the matrix beginning
 -    SparseMatIterator begin();
 -    //! returns the sparse matrix iterator at the matrix beginning
 -    template<typename _Tp> SparseMatIterator_<_Tp> begin();
 -    //! returns the read-only sparse matrix iterator at the matrix beginning
 -    SparseMatConstIterator begin() const;
 -    //! returns the read-only sparse matrix iterator at the matrix beginning
 -    template<typename _Tp> SparseMatConstIterator_<_Tp> begin() const;
 -    //@}
 -    /*!
 -       return the sparse matrix iterator pointing to the element following the last sparse matrix element
 -    */
 -    //! returns the sparse matrix iterator at the matrix end
 -    SparseMatIterator end();
 -    //! returns the read-only sparse matrix iterator at the matrix end
 -    SparseMatConstIterator end() const;
 -    //! returns the typed sparse matrix iterator at the matrix end
 -    template<typename _Tp> SparseMatIterator_<_Tp> end();
 -    //! returns the typed read-only sparse matrix iterator at the matrix end
 -    template<typename _Tp> SparseMatConstIterator_<_Tp> end() const;
 -
 -    //! returns the value stored in the sparse martix node
 -    template<typename _Tp> _Tp& value(Node* n);
 -    //! returns the value stored in the sparse martix node
 -    template<typename _Tp> const _Tp& value(const Node* n) const;
 -
 -    ////////////// some internal-use methods ///////////////
 -    Node* node(size_t nidx);
 -    const Node* node(size_t nidx) const;
 -
 -    uchar* newNode(const int* idx, size_t hashval);
 -    void removeNode(size_t hidx, size_t nidx, size_t previdx);
 -    void resizeHashTab(size_t newsize);
 -
 -    enum { MAGIC_VAL=0x42FD0000, MAX_DIM=CV_MAX_DIM, HASH_SCALE=0x5bd1e995, HASH_BIT=0x80000000 };
 -
 -    int flags;
 -    Hdr* hdr;
 -};
 -
 -//! finds global minimum and maximum sparse array elements and returns their values and their locations
 -CV_EXPORTS void minMaxLoc(const SparseMat& a, double* minVal,
 -                          double* maxVal, int* minIdx=0, int* maxIdx=0);
 -//! computes norm of a sparse matrix
 -CV_EXPORTS double norm( const SparseMat& src, int normType );
 -//! scales and shifts array elements so that either the specified norm (alpha) or the minimum (alpha) and maximum (beta) array values get the specified values
 -CV_EXPORTS void normalize( const SparseMat& src, SparseMat& dst, double alpha, int normType );
 -
 -/*!
 - Read-Only Sparse Matrix Iterator.
 - Here is how to use the iterator to compute the sum of floating-point sparse matrix elements:
 -
 - \code
 - SparseMatConstIterator it = m.begin(), it_end = m.end();
 - double s = 0;
 - CV_Assert( m.type() == CV_32F );
 - for( ; it != it_end; ++it )
 -    s += it.value<float>();
 - \endcode
 -*/
 -class CV_EXPORTS SparseMatConstIterator
 -{
 -public:
 -    //! the default constructor
 -    SparseMatConstIterator();
 -    //! the full constructor setting the iterator to the first sparse matrix element
 -    SparseMatConstIterator(const SparseMat* _m);
 -    //! the copy constructor
 -    SparseMatConstIterator(const SparseMatConstIterator& it);
 -
 -    //! the assignment operator
 -    SparseMatConstIterator& operator = (const SparseMatConstIterator& it);
 -
 -    //! template method returning the current matrix element
 -    template<typename _Tp> const _Tp& value() const;
 -    //! returns the current node of the sparse matrix. it.node->idx is the current element index
 -    const SparseMat::Node* node() const;
 -
 -    //! moves iterator to the previous element
 -    SparseMatConstIterator& operator --();
 -    //! moves iterator to the previous element
 -    SparseMatConstIterator operator --(int);
 -    //! moves iterator to the next element
 -    SparseMatConstIterator& operator ++();
 -    //! moves iterator to the next element
 -    SparseMatConstIterator operator ++(int);
 -
 -    //! moves iterator to the element after the last element
 -    void seekEnd();
 -
 -    const SparseMat* m;
 -    size_t hashidx;
 -    uchar* ptr;
 -};
 -
 -/*!
 - Read-write Sparse Matrix Iterator
 -
 - The class is similar to cv::SparseMatConstIterator,
 - but can be used for in-place modification of the matrix elements.
 -*/
 -class CV_EXPORTS SparseMatIterator : public SparseMatConstIterator
 -{
 -public:
 -    //! the default constructor
 -    SparseMatIterator();
 -    //! the full constructor setting the iterator to the first sparse matrix element
 -    SparseMatIterator(SparseMat* _m);
 -    //! the full constructor setting the iterator to the specified sparse matrix element
 -    SparseMatIterator(SparseMat* _m, const int* idx);
 -    //! the copy constructor
 -    SparseMatIterator(const SparseMatIterator& it);
 -
 -    //! the assignment operator
 -    SparseMatIterator& operator = (const SparseMatIterator& it);
 -    //! returns read-write reference to the current sparse matrix element
 -    template<typename _Tp> _Tp& value() const;
 -    //! returns pointer to the current sparse matrix node. it.node->idx is the index of the current element (do not modify it!)
 -    SparseMat::Node* node() const;
 -
 -    //! moves iterator to the next element
 -    SparseMatIterator& operator ++();
 -    //! moves iterator to the next element
 -    SparseMatIterator operator ++(int);
 -};
 -
 -/*!
 - The Template Sparse Matrix class derived from cv::SparseMat
 -
 - The class provides slightly more convenient operations for accessing elements.
 -
 - \code
 - SparseMat m;
 - ...
 - SparseMat_<int> m_ = (SparseMat_<int>&)m;
 - m_.ref(1)++; // equivalent to m.ref<int>(1)++;
 - m_.ref(2) += m_(3); // equivalent to m.ref<int>(2) += m.value<int>(3);
 - \endcode
 -*/
 -template<typename _Tp> class CV_EXPORTS SparseMat_ : public SparseMat
 -{
 -public:
 -    typedef SparseMatIterator_<_Tp> iterator;
 -    typedef SparseMatConstIterator_<_Tp> const_iterator;
 -
 -    //! the default constructor
 -    SparseMat_();
 -    //! the full constructor equivelent to SparseMat(dims, _sizes, DataType<_Tp>::type)
 -    SparseMat_(int dims, const int* _sizes);
 -    //! the copy constructor. If DataType<_Tp>.type != m.type(), the m elements are converted
 -    SparseMat_(const SparseMat& m);
 -    //! the copy constructor. This is O(1) operation - no data is copied
 -    SparseMat_(const SparseMat_& m);
 -    //! converts dense matrix to the sparse form
 -    SparseMat_(const Mat& m);
 -    //! converts the old-style sparse matrix to the C++ class. All the elements are copied
 -    SparseMat_(const CvSparseMat* m);
 -    //! the assignment operator. If DataType<_Tp>.type != m.type(), the m elements are converted
 -    SparseMat_& operator = (const SparseMat& m);
 -    //! the assignment operator. This is O(1) operation - no data is copied
 -    SparseMat_& operator = (const SparseMat_& m);
 -    //! converts dense matrix to the sparse form
 -    SparseMat_& operator = (const Mat& m);
 -
 -    //! makes full copy of the matrix. All the elements are duplicated
 -    SparseMat_ clone() const;
 -    //! equivalent to cv::SparseMat::create(dims, _sizes, DataType<_Tp>::type)
 -    void create(int dims, const int* _sizes);
 -    //! converts sparse matrix to the old-style CvSparseMat. All the elements are copied
 -    operator CvSparseMat*() const;
 -
 -    //! returns type of the matrix elements
 -    int type() const;
 -    //! returns depth of the matrix elements
 -    int depth() const;
 -    //! returns the number of channels in each matrix element
 -    int channels() const;
 -
 -    //! equivalent to SparseMat::ref<_Tp>(i0, hashval)
 -    _Tp& ref(int i0, size_t* hashval=0);
 -    //! equivalent to SparseMat::ref<_Tp>(i0, i1, hashval)
 -    _Tp& ref(int i0, int i1, size_t* hashval=0);
 -    //! equivalent to SparseMat::ref<_Tp>(i0, i1, i2, hashval)
 -    _Tp& ref(int i0, int i1, int i2, size_t* hashval=0);
 -    //! equivalent to SparseMat::ref<_Tp>(idx, hashval)
 -    _Tp& ref(const int* idx, size_t* hashval=0);
 -
 -    //! equivalent to SparseMat::value<_Tp>(i0, hashval)
 -    _Tp operator()(int i0, size_t* hashval=0) const;
 -    //! equivalent to SparseMat::value<_Tp>(i0, i1, hashval)
 -    _Tp operator()(int i0, int i1, size_t* hashval=0) const;
 -    //! equivalent to SparseMat::value<_Tp>(i0, i1, i2, hashval)
 -    _Tp operator()(int i0, int i1, int i2, size_t* hashval=0) const;
 -    //! equivalent to SparseMat::value<_Tp>(idx, hashval)
 -    _Tp operator()(const int* idx, size_t* hashval=0) const;
 -
 -    //! returns sparse matrix iterator pointing to the first sparse matrix element
 -    SparseMatIterator_<_Tp> begin();
 -    //! returns read-only sparse matrix iterator pointing to the first sparse matrix element
 -    SparseMatConstIterator_<_Tp> begin() const;
 -    //! returns sparse matrix iterator pointing to the element following the last sparse matrix element
 -    SparseMatIterator_<_Tp> end();
 -    //! returns read-only sparse matrix iterator pointing to the element following the last sparse matrix element
 -    SparseMatConstIterator_<_Tp> end() const;
 -};
 -
 -
 -/*!
 - Template Read-Only Sparse Matrix Iterator Class.
 -
 - This is the derived from SparseMatConstIterator class that
 - introduces more convenient operator *() for accessing the current element.
 -*/
 -template<typename _Tp> class CV_EXPORTS SparseMatConstIterator_ : public SparseMatConstIterator
 -{
 -public:
 -    typedef std::forward_iterator_tag iterator_category;
 -
 -    //! the default constructor
 -    SparseMatConstIterator_();
 -    //! the full constructor setting the iterator to the first sparse matrix element
 -    SparseMatConstIterator_(const SparseMat_<_Tp>* _m);
 -    SparseMatConstIterator_(const SparseMat* _m);
 -    //! the copy constructor
 -    SparseMatConstIterator_(const SparseMatConstIterator_& it);
 -
 -    //! the assignment operator
 -    SparseMatConstIterator_& operator = (const SparseMatConstIterator_& it);
 -    //! the element access operator
 -    const _Tp& operator *() const;
 -
 -    //! moves iterator to the next element
 -    SparseMatConstIterator_& operator ++();
 -    //! moves iterator to the next element
 -    SparseMatConstIterator_ operator ++(int);
 -};
 -
 -/*!
 - Template Read-Write Sparse Matrix Iterator Class.
 -
 - This is the derived from cv::SparseMatConstIterator_ class that
 - introduces more convenient operator *() for accessing the current element.
 -*/
 -template<typename _Tp> class CV_EXPORTS SparseMatIterator_ : public SparseMatConstIterator_<_Tp>
 -{
 -public:
 -    typedef std::forward_iterator_tag iterator_category;
 -
 -    //! the default constructor
 -    SparseMatIterator_();
 -    //! the full constructor setting the iterator to the first sparse matrix element
 -    SparseMatIterator_(SparseMat_<_Tp>* _m);
 -    SparseMatIterator_(SparseMat* _m);
 -    //! the copy constructor
 -    SparseMatIterator_(const SparseMatIterator_& it);
 -
 -    //! the assignment operator
 -    SparseMatIterator_& operator = (const SparseMatIterator_& it);
 -    //! returns the reference to the current element
 -    _Tp& operator *() const;
 -
 -    //! moves the iterator to the next element
 -    SparseMatIterator_& operator ++();
 -    //! moves the iterator to the next element
 -    SparseMatIterator_ operator ++(int);
 -};
 -
 -//////////////////// Fast Nearest-Neighbor Search Structure ////////////////////
 -
 -/*!
 - Fast Nearest Neighbor Search Class.
 -
 - The class implements D. Lowe BBF (Best-Bin-First) algorithm for the last
 - approximate (or accurate) nearest neighbor search in multi-dimensional spaces.
 -
 - First, a set of vectors is passed to KDTree::KDTree() constructor
 - or KDTree::build() method, where it is reordered.
 -
 - Then arbitrary vectors can be passed to KDTree::findNearest() methods, which
 - find the K nearest neighbors among the vectors from the initial set.
 - The user can balance between the speed and accuracy of the search by varying Emax
 - parameter, which is the number of leaves that the algorithm checks.
 - The larger parameter values yield more accurate results at the expense of lower processing speed.
 -
 - \code
 - KDTree T(points, false);
 - const int K = 3, Emax = INT_MAX;
 - int idx[K];
 - float dist[K];
 - T.findNearest(query_vec, K, Emax, idx, 0, dist);
 - CV_Assert(dist[0] <= dist[1] && dist[1] <= dist[2]);
 - \endcode
 -*/
 -class CV_EXPORTS_W KDTree
 -{
 -public:
 -    /*!
 -        The node of the search tree.
 -    */
 -    struct Node
 -    {
 -        Node() : idx(-1), left(-1), right(-1), boundary(0.f) {}
 -        Node(int _idx, int _left, int _right, float _boundary)
 -            : idx(_idx), left(_left), right(_right), boundary(_boundary) {}
 -        //! split dimension; >=0 for nodes (dim), < 0 for leaves (index of the point)
 -        int idx;
 -        //! node indices of the left and the right branches
 -        int left, right;
 -        //! go to the left if query_vec[node.idx]<=node.boundary, otherwise go to the right
 -        float boundary;
 -    };
 -
 -    //! the default constructor
 -    CV_WRAP KDTree();
 -    //! the full constructor that builds the search tree
 -    CV_WRAP KDTree(InputArray points, bool copyAndReorderPoints=false);
 -    //! the full constructor that builds the search tree
 -    CV_WRAP KDTree(InputArray points, InputArray _labels,
 -                   bool copyAndReorderPoints=false);
 -    //! builds the search tree
 -    CV_WRAP void build(InputArray points, bool copyAndReorderPoints=false);
 -    //! builds the search tree
 -    CV_WRAP void build(InputArray points, InputArray labels,
 -                       bool copyAndReorderPoints=false);
 -    //! finds the K nearest neighbors of "vec" while looking at Emax (at most) leaves
 -    CV_WRAP int findNearest(InputArray vec, int K, int Emax,
 -                            OutputArray neighborsIdx,
 -                            OutputArray neighbors=noArray(),
 -                            OutputArray dist=noArray(),
 -                            OutputArray labels=noArray()) const;
 -    //! finds all the points from the initial set that belong to the specified box
 -    CV_WRAP void findOrthoRange(InputArray minBounds,
 -                                InputArray maxBounds,
 -                                OutputArray neighborsIdx,
 -                                OutputArray neighbors=noArray(),
 -                                OutputArray labels=noArray()) const;
 -    //! returns vectors with the specified indices
 -    CV_WRAP void getPoints(InputArray idx, OutputArray pts,
 -                           OutputArray labels=noArray()) const;
 -    //! return a vector with the specified index
 -    const float* getPoint(int ptidx, int* label=0) const;
 -    //! returns the search space dimensionality
 -    CV_WRAP int dims() const;
 -
 -    vector<Node> nodes; //!< all the tree nodes
 -    CV_PROP Mat points; //!< all the points. It can be a reordered copy of the input vector set or the original vector set.
 -    CV_PROP vector<int> labels; //!< the parallel array of labels.
 -    CV_PROP int maxDepth; //!< maximum depth of the search tree. Do not modify it
 -    CV_PROP_RW int normType; //!< type of the distance (cv::NORM_L1 or cv::NORM_L2) used for search. Initially set to cv::NORM_L2, but you can modify it
 -};
 -
 -//////////////////////////////////////// XML & YAML I/O ////////////////////////////////////
 -
 -class CV_EXPORTS FileNode;
 -
 -/*!
 - XML/YAML File Storage Class.
 -
 - The class describes an object associated with XML or YAML file.
 - It can be used to store data to such a file or read and decode the data.
 -
 - The storage is organized as a tree of nested sequences (or lists) and mappings.
 - Sequence is a heterogenious array, which elements are accessed by indices or sequentially using an iterator.
 - Mapping is analogue of std::map or C structure, which elements are accessed by names.
 - The most top level structure is a mapping.
 - Leaves of the file storage tree are integers, floating-point numbers and text strings.
 -
 - For example, the following code:
 -
 - \code
 - // open file storage for writing. Type of the file is determined from the extension
 - FileStorage fs("test.yml", FileStorage::WRITE);
 - fs << "test_int" << 5 << "test_real" << 3.1 << "test_string" << "ABCDEFGH";
 - fs << "test_mat" << Mat::eye(3,3,CV_32F);
 -
 - fs << "test_list" << "[" << 0.0000000000001 << 2 << CV_PI << -3435345 << "2-502 2-029 3egegeg" <<
 - "{:" << "month" << 12 << "day" << 31 << "year" << 1969 << "}" << "]";
 - fs << "test_map" << "{" << "x" << 1 << "y" << 2 << "width" << 100 << "height" << 200 << "lbp" << "[:";
 -
 - const uchar arr[] = {0, 1, 1, 0, 1, 1, 0, 1};
 - fs.writeRaw("u", arr, (int)(sizeof(arr)/sizeof(arr[0])));
 -
 - fs << "]" << "}";
 - \endcode
 -
 - will produce the following file:
 -
 - \verbatim
 - %YAML:1.0
 - test_int: 5
 - test_real: 3.1000000000000001e+00
 - test_string: ABCDEFGH
 - test_mat: !!opencv-matrix
 -     rows: 3
 -     cols: 3
 -     dt: f
 -     data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1. ]
 - test_list:
 -     - 1.0000000000000000e-13
 -     - 2
 -     - 3.1415926535897931e+00
 -     - -3435345
 -     - "2-502 2-029 3egegeg"
 -     - { month:12, day:31, year:1969 }
 - test_map:
 -     x: 1
 -     y: 2
 -     width: 100
 -     height: 200
 -     lbp: [ 0, 1, 1, 0, 1, 1, 0, 1 ]
 - \endverbatim
 -
 - and to read the file above, the following code can be used:
 -
 - \code
 - // open file storage for reading.
 - // Type of the file is determined from the content, not the extension
 - FileStorage fs("test.yml", FileStorage::READ);
 - int test_int = (int)fs["test_int"];
 - double test_real = (double)fs["test_real"];
 - string test_string = (string)fs["test_string"];
 -
 - Mat M;
 - fs["test_mat"] >> M;
 -
 - FileNode tl = fs["test_list"];
 - CV_Assert(tl.type() == FileNode::SEQ && tl.size() == 6);
 - double tl0 = (double)tl[0];
 - int tl1 = (int)tl[1];
 - double tl2 = (double)tl[2];
 - int tl3 = (int)tl[3];
 - string tl4 = (string)tl[4];
 - CV_Assert(tl[5].type() == FileNode::MAP && tl[5].size() == 3);
 -
 - int month = (int)tl[5]["month"];
 - int day = (int)tl[5]["day"];
 - int year = (int)tl[5]["year"];
 -
 - FileNode tm = fs["test_map"];
 -
 - int x = (int)tm["x"];
 - int y = (int)tm["y"];
 - int width = (int)tm["width"];
 - int height = (int)tm["height"];
 -
 - int lbp_val = 0;
 - FileNodeIterator it = tm["lbp"].begin();
 -
 - for(int k = 0; k < 8; k++, ++it)
 -    lbp_val |= ((int)*it) << k;
 - \endcode
 -*/
 -class CV_EXPORTS_W FileStorage
 -{
 -public:
 -    //! file storage mode
 -    enum
 -    {
 -        READ=0, //! read mode
 -        WRITE=1, //! write mode
 -        APPEND=2, //! append mode
 -        MEMORY=4,
 -        FORMAT_MASK=(7<<3),
 -        FORMAT_AUTO=0,
 -        FORMAT_XML=(1<<3),
 -        FORMAT_YAML=(2<<3)
 -    };
 -    enum
 -    {
 -        UNDEFINED=0,
 -        VALUE_EXPECTED=1,
 -        NAME_EXPECTED=2,
 -        INSIDE_MAP=4
 -    };
 -    //! the default constructor
 -    CV_WRAP FileStorage();
 -    //! the full constructor that opens file storage for reading or writing
 -    CV_WRAP FileStorage(const string& source, int flags, const string& encoding=string());
 -    //! the constructor that takes pointer to the C FileStorage structure
 -    FileStorage(CvFileStorage* fs);
 -    //! the destructor. calls release()
 -    virtual ~FileStorage();
 -
 -    //! opens file storage for reading or writing. The previous storage is closed with release()
 -    CV_WRAP virtual bool open(const string& filename, int flags, const string& encoding=string());
 -    //! returns true if the object is associated with currently opened file.
 -    CV_WRAP virtual bool isOpened() const;
 -    //! closes the file and releases all the memory buffers
 -    CV_WRAP virtual void release();
 -    //! closes the file, releases all the memory buffers and returns the text string
 -    CV_WRAP string releaseAndGetString();
 -
 -    //! returns the first element of the top-level mapping
 -    CV_WRAP FileNode getFirstTopLevelNode() const;
 -    //! returns the top-level mapping. YAML supports multiple streams
 -    CV_WRAP FileNode root(int streamidx=0) const;
 -    //! returns the specified element of the top-level mapping
 -    FileNode operator[](const string& nodename) const;
 -    //! returns the specified element of the top-level mapping
 -    CV_WRAP FileNode operator[](const char* nodename) const;
 -
 -    //! returns pointer to the underlying C FileStorage structure
 -    CvFileStorage* operator *() { return fs; }
 -    //! returns pointer to the underlying C FileStorage structure
 -    const CvFileStorage* operator *() const { return fs; }
 -    //! writes one or more numbers of the specified format to the currently written structure
 -    void writeRaw( const string& fmt, const uchar* vec, size_t len );
 -    //! writes the registered C structure (CvMat, CvMatND, CvSeq). See cvWrite()
 -    void writeObj( const string& name, const void* obj );
 -
 -    //! returns the normalized object name for the specified file name
 -    static string getDefaultObjectName(const string& filename);
 -
 -    Ptr<CvFileStorage> fs; //!< the underlying C FileStorage structure
 -    string elname; //!< the currently written element
 -    vector<char> structs; //!< the stack of written structures
 -    int state; //!< the writer state
 -};
 -
 -class CV_EXPORTS FileNodeIterator;
 -
 -/*!
 - File Storage Node class
 -
 - The node is used to store each and every element of the file storage opened for reading -
 - from the primitive objects, such as numbers and text strings, to the complex nodes:
 - sequences, mappings and the registered objects.
 -
 - Note that file nodes are only used for navigating file storages opened for reading.
 - When a file storage is opened for writing, no data is stored in memory after it is written.
 -*/
 -class CV_EXPORTS_W_SIMPLE FileNode
 -{
 -public:
 -    //! type of the file storage node
 -    enum
 -    {
 -        NONE=0, //!< empty node
 -        INT=1, //!< an integer
 -        REAL=2, //!< floating-point number
 -        FLOAT=REAL, //!< synonym or REAL
 -        STR=3, //!< text string in UTF-8 encoding
 -        STRING=STR, //!< synonym for STR
 -        REF=4, //!< integer of size size_t. Typically used for storing complex dynamic structures where some elements reference the others
 -        SEQ=5, //!< sequence
 -        MAP=6, //!< mapping
 -        TYPE_MASK=7,
 -        FLOW=8, //!< compact representation of a sequence or mapping. Used only by YAML writer
 -        USER=16, //!< a registered object (e.g. a matrix)
 -        EMPTY=32, //!< empty structure (sequence or mapping)
 -        NAMED=64 //!< the node has a name (i.e. it is element of a mapping)
 -    };
 -    //! the default constructor
 -    CV_WRAP FileNode();
 -    //! the full constructor wrapping CvFileNode structure.
 -    FileNode(const CvFileStorage* fs, const CvFileNode* node);
 -    //! the copy constructor
 -    FileNode(const FileNode& node);
 -    //! returns element of a mapping node
 -    FileNode operator[](const string& nodename) const;
 -    //! returns element of a mapping node
 -    CV_WRAP FileNode operator[](const char* nodename) const;
 -    //! returns element of a sequence node
 -    CV_WRAP FileNode operator[](int i) const;
 -    //! returns type of the node
 -    CV_WRAP int type() const;
 -
 -    //! returns true if the node is empty
 -    CV_WRAP bool empty() const;
 -    //! returns true if the node is a "none" object
 -    CV_WRAP bool isNone() const;
 -    //! returns true if the node is a sequence
 -    CV_WRAP bool isSeq() const;
 -    //! returns true if the node is a mapping
 -    CV_WRAP bool isMap() const;
 -    //! returns true if the node is an integer
 -    CV_WRAP bool isInt() const;
 -    //! returns true if the node is a floating-point number
 -    CV_WRAP bool isReal() const;
 -    //! returns true if the node is a text string
 -    CV_WRAP bool isString() const;
 -    //! returns true if the node has a name
 -    CV_WRAP bool isNamed() const;
 -    //! returns the node name or an empty string if the node is nameless
 -    CV_WRAP string name() const;
 -    //! returns the number of elements in the node, if it is a sequence or mapping, or 1 otherwise.
 -    CV_WRAP size_t size() const;
 -    //! returns the node content as an integer. If the node stores floating-point number, it is rounded.
 -    operator int() const;
 -    //! returns the node content as float
 -    operator float() const;
 -    //! returns the node content as double
 -    operator double() const;
 -    //! returns the node content as text string
 -    operator string() const;
 -
 -    //! returns pointer to the underlying file node
 -    CvFileNode* operator *();
 -    //! returns pointer to the underlying file node
 -    const CvFileNode* operator* () const;
 -
 -    //! returns iterator pointing to the first node element
 -    FileNodeIterator begin() const;
 -    //! returns iterator pointing to the element following the last node element
 -    FileNodeIterator end() const;
 -
 -    //! reads node elements to the buffer with the specified format
 -    void readRaw( const string& fmt, uchar* vec, size_t len ) const;
 -    //! reads the registered object and returns pointer to it
 -    void* readObj() const;
 -
 -    // do not use wrapper pointer classes for better efficiency
 -    const CvFileStorage* fs;
 -    const CvFileNode* node;
 -};
 -
 -
 -/*!
 - File Node Iterator
 -
 - The class is used for iterating sequences (usually) and mappings.
 - */
 -class CV_EXPORTS FileNodeIterator
 -{
 -public:
 -    //! the default constructor
 -    FileNodeIterator();
 -    //! the full constructor set to the ofs-th element of the node
 -    FileNodeIterator(const CvFileStorage* fs, const CvFileNode* node, size_t ofs=0);
 -    //! the copy constructor
 -    FileNodeIterator(const FileNodeIterator& it);
 -    //! returns the currently observed element
 -    FileNode operator *() const;
 -    //! accesses the currently observed element methods
 -    FileNode operator ->() const;
 -
 -    //! moves iterator to the next node
 -    FileNodeIterator& operator ++ ();
 -    //! moves iterator to the next node
 -    FileNodeIterator operator ++ (int);
 -    //! moves iterator to the previous node
 -    FileNodeIterator& operator -- ();
 -    //! moves iterator to the previous node
 -    FileNodeIterator operator -- (int);
 -    //! moves iterator forward by the specified offset (possibly negative)
 -    FileNodeIterator& operator += (int ofs);
 -    //! moves iterator backward by the specified offset (possibly negative)
 -    FileNodeIterator& operator -= (int ofs);
 -
 -    //! reads the next maxCount elements (or less, if the sequence/mapping last element occurs earlier) to the buffer with the specified format
 -    FileNodeIterator& readRaw( const string& fmt, uchar* vec,
 -                               size_t maxCount=(size_t)INT_MAX );
 -
 -    const CvFileStorage* fs;
 -    const CvFileNode* container;
 -    CvSeqReader reader;
 -    size_t remaining;
 -};
 -
 -////////////// convenient wrappers for operating old-style dynamic structures //////////////
 -
 -template<typename _Tp> class SeqIterator;
 -
 -typedef Ptr<CvMemStorage> MemStorage;
 -
 -/*!
 - Template Sequence Class derived from CvSeq
 -
 - The class provides more convenient access to sequence elements,
 - STL-style operations and iterators.
 -
 - \note The class is targeted for simple data types,
 -    i.e. no constructors or destructors
 -    are called for the sequence elements.
 -*/
 -template<typename _Tp> class CV_EXPORTS Seq
 -{
 -public:
 -    typedef SeqIterator<_Tp> iterator;
 -    typedef SeqIterator<_Tp> const_iterator;
 -
 -    //! the default constructor
 -    Seq();
 -    //! the constructor for wrapping CvSeq structure. The real element type in CvSeq should match _Tp.
 -    Seq(const CvSeq* seq);
 -    //! creates the empty sequence that resides in the specified storage
 -    Seq(MemStorage& storage, int headerSize = sizeof(CvSeq));
 -    //! returns read-write reference to the specified element
 -    _Tp& operator [](int idx);
 -    //! returns read-only reference to the specified element
 -    const _Tp& operator[](int idx) const;
 -    //! returns iterator pointing to the beginning of the sequence
 -    SeqIterator<_Tp> begin() const;
 -    //! returns iterator pointing to the element following the last sequence element
 -    SeqIterator<_Tp> end() const;
 -    //! returns the number of elements in the sequence
 -    size_t size() const;
 -    //! returns the type of sequence elements (CV_8UC1 ... CV_64FC(CV_CN_MAX) ...)
 -    int type() const;
 -    //! returns the depth of sequence elements (CV_8U ... CV_64F)
 -    int depth() const;
 -    //! returns the number of channels in each sequence element
 -    int channels() const;
 -    //! returns the size of each sequence element
 -    size_t elemSize() const;
 -    //! returns index of the specified sequence element
 -    size_t index(const _Tp& elem) const;
 -    //! appends the specified element to the end of the sequence
 -    void push_back(const _Tp& elem);
 -    //! appends the specified element to the front of the sequence
 -    void push_front(const _Tp& elem);
 -    //! appends zero or more elements to the end of the sequence
 -    void push_back(const _Tp* elems, size_t count);
 -    //! appends zero or more elements to the front of the sequence
 -    void push_front(const _Tp* elems, size_t count);
 -    //! inserts the specified element to the specified position
 -    void insert(int idx, const _Tp& elem);
 -    //! inserts zero or more elements to the specified position
 -    void insert(int idx, const _Tp* elems, size_t count);
 -    //! removes element at the specified position
 -    void remove(int idx);
 -    //! removes the specified subsequence
 -    void remove(const Range& r);
 -
 -    //! returns reference to the first sequence element
 -    _Tp& front();
 -    //! returns read-only reference to the first sequence element
 -    const _Tp& front() const;
 -    //! returns reference to the last sequence element
 -    _Tp& back();
 -    //! returns read-only reference to the last sequence element
 -    const _Tp& back() const;
 -    //! returns true iff the sequence contains no elements
 -    bool empty() const;
 -
 -    //! removes all the elements from the sequence
 -    void clear();
 -    //! removes the first element from the sequence
 -    void pop_front();
 -    //! removes the last element from the sequence
 -    void pop_back();
 -    //! removes zero or more elements from the beginning of the sequence
 -    void pop_front(_Tp* elems, size_t count);
 -    //! removes zero or more elements from the end of the sequence
 -    void pop_back(_Tp* elems, size_t count);
 -
 -    //! copies the whole sequence or the sequence slice to the specified vector
 -    void copyTo(vector<_Tp>& vec, const Range& range=Range::all()) const;
 -    //! returns the vector containing all the sequence elements
 -    operator vector<_Tp>() const;
 -
 -    CvSeq* seq;
 -};
 -
 -
 -/*!
 - STL-style Sequence Iterator inherited from the CvSeqReader structure
 -*/
 -template<typename _Tp> class CV_EXPORTS SeqIterator : public CvSeqReader
 -{
 -public:
 -    //! the default constructor
 -    SeqIterator();
 -    //! the constructor setting the iterator to the beginning or to the end of the sequence
 -    SeqIterator(const Seq<_Tp>& seq, bool seekEnd=false);
 -    //! positions the iterator within the sequence
 -    void seek(size_t pos);
 -    //! reports the current iterator position
 -    size_t tell() const;
 -    //! returns reference to the current sequence element
 -    _Tp& operator *();
 -    //! returns read-only reference to the current sequence element
 -    const _Tp& operator *() const;
 -    //! moves iterator to the next sequence element
 -    SeqIterator& operator ++();
 -    //! moves iterator to the next sequence element
 -    SeqIterator operator ++(int) const;
 -    //! moves iterator to the previous sequence element
 -    SeqIterator& operator --();
 -    //! moves iterator to the previous sequence element
 -    SeqIterator operator --(int) const;
 -
 -    //! moves iterator forward by the specified offset (possibly negative)
 -    SeqIterator& operator +=(int);
 -    //! moves iterator backward by the specified offset (possibly negative)
 -    SeqIterator& operator -=(int);
 -
 -    // this is index of the current element module seq->total*2
 -    // (to distinguish between 0 and seq->total)
 -    int index;
 -};
 -
 -
 -class CV_EXPORTS Algorithm;
 -class CV_EXPORTS AlgorithmInfo;
 -struct CV_EXPORTS AlgorithmInfoData;
 -
 -template<typename _Tp> struct ParamType {};
 -
 -/*!
 -  Base class for high-level OpenCV algorithms
 -*/
 -class CV_EXPORTS_W Algorithm
 -{
 -public:
 -    Algorithm();
 -    virtual ~Algorithm();
 -    string name() const;
 -
 -    template<typename _Tp> typename ParamType<_Tp>::member_type get(const string& name) const;
 -    template<typename _Tp> typename ParamType<_Tp>::member_type get(const char* name) const;
 -
 -    CV_WRAP int getInt(const string& name) const;
 -    CV_WRAP double getDouble(const string& name) const;
 -    CV_WRAP bool getBool(const string& name) const;
 -    CV_WRAP string getString(const string& name) const;
 -    CV_WRAP Mat getMat(const string& name) const;
 -    CV_WRAP vector<Mat> getMatVector(const string& name) const;
 -    CV_WRAP Ptr<Algorithm> getAlgorithm(const string& name) const;
 -
 -    void set(const string& name, int value);
 -    void set(const string& name, double value);
 -    void set(const string& name, bool value);
 -    void set(const string& name, const string& value);
 -    void set(const string& name, const Mat& value);
 -    void set(const string& name, const vector<Mat>& value);
 -    void set(const string& name, const Ptr<Algorithm>& value);
 -    template<typename _Tp> void set(const string& name, const Ptr<_Tp>& value);
 -
 -    CV_WRAP void setInt(const string& name, int value);
 -    CV_WRAP void setDouble(const string& name, double value);
 -    CV_WRAP void setBool(const string& name, bool value);
 -    CV_WRAP void setString(const string& name, const string& value);
 -    CV_WRAP void setMat(const string& name, const Mat& value);
 -    CV_WRAP void setMatVector(const string& name, const vector<Mat>& value);
 -    CV_WRAP void setAlgorithm(const string& name, const Ptr<Algorithm>& value);
 -    template<typename _Tp> void setAlgorithm(const string& name, const Ptr<_Tp>& value);
 -
 -    void set(const char* name, int value);
 -    void set(const char* name, double value);
 -    void set(const char* name, bool value);
 -    void set(const char* name, const string& value);
 -    void set(const char* name, const Mat& value);
 -    void set(const char* name, const vector<Mat>& value);
 -    void set(const char* name, const Ptr<Algorithm>& value);
 -    template<typename _Tp> void set(const char* name, const Ptr<_Tp>& value);
 -
 -    void setInt(const char* name, int value);
 -    void setDouble(const char* name, double value);
 -    void setBool(const char* name, bool value);
 -    void setString(const char* name, const string& value);
 -    void setMat(const char* name, const Mat& value);
 -    void setMatVector(const char* name, const vector<Mat>& value);
 -    void setAlgorithm(const char* name, const Ptr<Algorithm>& value);
 -    template<typename _Tp> void setAlgorithm(const char* name, const Ptr<_Tp>& value);
 -
 -    CV_WRAP string paramHelp(const string& name) const;
 -    int paramType(const char* name) const;
 -    CV_WRAP int paramType(const string& name) const;
 -    CV_WRAP void getParams(CV_OUT vector<string>& names) const;
 -
 -
 -    virtual void write(FileStorage& fs) const;
 -    virtual void read(const FileNode& fn);
 -
 -    typedef Algorithm* (*Constructor)(void);
 -    typedef int (Algorithm::*Getter)() const;
 -    typedef void (Algorithm::*Setter)(int);
 -
 -    CV_WRAP static void getList(CV_OUT vector<string>& algorithms);
 -    CV_WRAP static Ptr<Algorithm> _create(const string& name);
 -    template<typename _Tp> static Ptr<_Tp> create(const string& name);
 -
 -    virtual AlgorithmInfo* info() const /* TODO: make it = 0;*/ { return 0; }
 -};
 -
 -
 -class CV_EXPORTS AlgorithmInfo
 -{
 -public:
 -    friend class Algorithm;
 -    AlgorithmInfo(const string& name, Algorithm::Constructor create);
 -    ~AlgorithmInfo();
 -    void get(const Algorithm* algo, const char* name, int argType, void* value) const;
 -    void addParam_(Algorithm& algo, const char* name, int argType,
 -                   void* value, bool readOnly,
 -                   Algorithm::Getter getter, Algorithm::Setter setter,
 -                   const string& help=string());
 -    string paramHelp(const char* name) const;
 -    int paramType(const char* name) const;
 -    void getParams(vector<string>& names) const;
 -
 -    void write(const Algorithm* algo, FileStorage& fs) const;
 -    void read(Algorithm* algo, const FileNode& fn) const;
 -    string name() const;
 -
 -    void addParam(Algorithm& algo, const char* name,
 -                  int& value, bool readOnly=false,
 -                  int (Algorithm::*getter)()=0,
 -                  void (Algorithm::*setter)(int)=0,
 -                  const string& help=string());
 -    void addParam(Algorithm& algo, const char* name,
 -                  short& value, bool readOnly=false,
 -                  int (Algorithm::*getter)()=0,
 -                  void (Algorithm::*setter)(int)=0,
 -                  const string& help=string());
 -    void addParam(Algorithm& algo, const char* name,
 -                  bool& value, bool readOnly=false,
 -                  int (Algorithm::*getter)()=0,
 -                  void (Algorithm::*setter)(int)=0,
 -                  const string& help=string());
 -    void addParam(Algorithm& algo, const char* name,
 -                  double& value, bool readOnly=false,
 -                  double (Algorithm::*getter)()=0,
 -                  void (Algorithm::*setter)(double)=0,
 -                  const string& help=string());
 -    void addParam(Algorithm& algo, const char* name,
 -                  string& value, bool readOnly=false,
 -                  string (Algorithm::*getter)()=0,
 -                  void (Algorithm::*setter)(const string&)=0,
 -                  const string& help=string());
 -    void addParam(Algorithm& algo, const char* name,
 -                  Mat& value, bool readOnly=false,
 -                  Mat (Algorithm::*getter)()=0,
 -                  void (Algorithm::*setter)(const Mat&)=0,
 -                  const string& help=string());
 -    void addParam(Algorithm& algo, const char* name,
 -                  vector<Mat>& value, bool readOnly=false,
 -                  vector<Mat> (Algorithm::*getter)()=0,
 -                  void (Algorithm::*setter)(const vector<Mat>&)=0,
 -                  const string& help=string());
 -    void addParam(Algorithm& algo, const char* name,
 -                  Ptr<Algorithm>& value, bool readOnly=false,
 -                  Ptr<Algorithm> (Algorithm::*getter)()=0,
 -                  void (Algorithm::*setter)(const Ptr<Algorithm>&)=0,
 -                  const string& help=string());
 -    void addParam(Algorithm& algo, const char* name,
 -                  float& value, bool readOnly=false,
 -                  float (Algorithm::*getter)()=0,
 -                  void (Algorithm::*setter)(float)=0,
 -                  const string& help=string());
 -    void addParam(Algorithm& algo, const char* name,
 -                  unsigned int& value, bool readOnly=false,
 -                  unsigned int (Algorithm::*getter)()=0,
 -                  void (Algorithm::*setter)(unsigned int)=0,
 -                  const string& help=string());
 -    void addParam(Algorithm& algo, const char* name,
 -                  uint64& value, bool readOnly=false,
 -                  uint64 (Algorithm::*getter)()=0,
 -                  void (Algorithm::*setter)(uint64)=0,
 -                  const string& help=string());
 -    void addParam(Algorithm& algo, const char* name,
 -                  uchar& value, bool readOnly=false,
 -                  uchar (Algorithm::*getter)()=0,
 -                  void (Algorithm::*setter)(uchar)=0,
 -                  const string& help=string());
 -    template<typename _Tp, typename _Base> void addParam(Algorithm& algo, const char* name,
 -                  Ptr<_Tp>& value, bool readOnly=false,
 -                  Ptr<_Tp> (Algorithm::*getter)()=0,
 -                  void (Algorithm::*setter)(const Ptr<_Tp>&)=0,
 -                  const string& help=string());
 -    template<typename _Tp> void addParam(Algorithm& algo, const char* name,
 -                  Ptr<_Tp>& value, bool readOnly=false,
 -                  Ptr<_Tp> (Algorithm::*getter)()=0,
 -                  void (Algorithm::*setter)(const Ptr<_Tp>&)=0,
 -                  const string& help=string());
 -protected:
 -    AlgorithmInfoData* data;
 -    void set(Algorithm* algo, const char* name, int argType,
 -              const void* value, bool force=false) const;
 -};
 -
 -
 -struct CV_EXPORTS Param
 -{
 -    enum { INT=0, BOOLEAN=1, REAL=2, STRING=3, MAT=4, MAT_VECTOR=5, ALGORITHM=6, FLOAT=7, UNSIGNED_INT=8, UINT64=9, SHORT=10, UCHAR=11 };
 -
 -    Param();
 -    Param(int _type, bool _readonly, int _offset,
 -          Algorithm::Getter _getter=0,
 -          Algorithm::Setter _setter=0,
 -          const string& _help=string());
 -    int type;
 -    int offset;
 -    bool readonly;
 -    Algorithm::Getter getter;
 -    Algorithm::Setter setter;
 -    string help;
 -};
 -
 -template<> struct ParamType<bool>
 -{
 -    typedef bool const_param_type;
 -    typedef bool member_type;
 -
 -    enum { type = Param::BOOLEAN };
 -};
 -
 -template<> struct ParamType<int>
 -{
 -    typedef int const_param_type;
 -    typedef int member_type;
 -
 -    enum { type = Param::INT };
 -};
 -
 -template<> struct ParamType<short>
 -{
 -    typedef int const_param_type;
 -    typedef int member_type;
 -
 -    enum { type = Param::SHORT };
 -};
 -
 -template<> struct ParamType<double>
 -{
 -    typedef double const_param_type;
 -    typedef double member_type;
 -
 -    enum { type = Param::REAL };
 -};
 -
 -template<> struct ParamType<string>
 -{
 -    typedef const string& const_param_type;
 -    typedef string member_type;
 -
 -    enum { type = Param::STRING };
 -};
 -
 -template<> struct ParamType<Mat>
 -{
 -    typedef const Mat& const_param_type;
 -    typedef Mat member_type;
 -
 -    enum { type = Param::MAT };
 -};
 -
 -template<> struct ParamType<vector<Mat> >
 -{
 -    typedef const vector<Mat>& const_param_type;
 -    typedef vector<Mat> member_type;
 -
 -    enum { type = Param::MAT_VECTOR };
 -};
 -
 -template<> struct ParamType<Algorithm>
 -{
 -    typedef const Ptr<Algorithm>& const_param_type;
 -    typedef Ptr<Algorithm> member_type;
 -
 -    enum { type = Param::ALGORITHM };
 -};
 -
 -template<> struct ParamType<float>
 -{
 -    typedef float const_param_type;
 -    typedef float member_type;
 -
 -    enum { type = Param::FLOAT };
 -};
 -
 -template<> struct ParamType<unsigned>
 -{
 -    typedef unsigned const_param_type;
 -    typedef unsigned member_type;
 -
 -    enum { type = Param::UNSIGNED_INT };
 -};
 -
 -template<> struct ParamType<uint64>
 -{
 -    typedef uint64 const_param_type;
 -    typedef uint64 member_type;
 -
 -    enum { type = Param::UINT64 };
 -};
 -
 -template<> struct ParamType<uchar>
 -{
 -    typedef uchar const_param_type;
 -    typedef uchar member_type;
 -
 -    enum { type = Param::UCHAR };
 -};
 -
 -/*!
 -"\nThe CommandLineParser class is designed for command line arguments parsing\n"
 -           "Keys map: \n"
 -           "Before you start to work with CommandLineParser you have to create a map for keys.\n"
 -           "    It will look like this\n"
 -           "    const char* keys =\n"
 -           "    {\n"
 -           "        {    s|  string|  123asd |string parameter}\n"
 -           "        {    d|  digit |  100    |digit parameter }\n"
 -           "        {    c|noCamera|false    |without camera  }\n"
 -           "        {    1|        |some text|help            }\n"
 -           "        {    2|        |333      |another help    }\n"
 -           "    };\n"
 -           "Usage syntax: \n"
 -           "    \"{\" - start of parameter string.\n"
 -           "    \"}\" - end of parameter string\n"
 -           "    \"|\" - separator between short name, full name, default value and help\n"
 -           "Supported syntax: \n"
 -           "    --key1=arg1  <If a key with '--' must has an argument\n"
 -           "                  you have to assign it through '=' sign.> \n"
 -           "<If the key with '--' doesn't have any argument, it means that it is a bool key>\n"
 -           "    -key2=arg2   <If a key with '-' must has an argument \n"
 -           "                  you have to assign it through '=' sign.> \n"
 -           "If the key with '-' doesn't have any argument, it means that it is a bool key\n"
 -           "    key3                 <This key can't has any parameter> \n"
 -           "Usage: \n"
 -           "      Imagine that the input parameters are next:\n"
 -           "                -s=string_value --digit=250 --noCamera lena.jpg 10000\n"
 -           "    CommandLineParser parser(argc, argv, keys) - create a parser object\n"
 -           "    parser.get<string>(\"s\" or \"string\") will return you first parameter value\n"
 -           "    parser.get<string>(\"s\", false or \"string\", false) will return you first parameter value\n"
 -           "                                                                without spaces in end and begin\n"
 -           "    parser.get<int>(\"d\" or \"digit\") will return you second parameter value.\n"
 -           "                    It also works with 'unsigned int', 'double', and 'float' types>\n"
 -           "    parser.get<bool>(\"c\" or \"noCamera\") will return you true .\n"
 -           "                                If you enter this key in commandline>\n"
 -           "                                It return you false otherwise.\n"
 -           "    parser.get<string>(\"1\") will return you the first argument without parameter (lena.jpg) \n"
 -           "    parser.get<int>(\"2\") will return you the second argument without parameter (10000)\n"
 -           "                          It also works with 'unsigned int', 'double', and 'float' types \n"
 -*/
 -class CV_EXPORTS CommandLineParser
 -{
 -    public:
 -
 -    //! the default constructor
 -      CommandLineParser(int argc, const char* const argv[], const char* key_map);
 -
 -    //! get parameter, you can choose: delete spaces in end and begin or not
 -    template<typename _Tp>
 -    _Tp get(const std::string& name, bool space_delete=true)
 -    {
 -        if (!has(name))
 -        {
 -            return _Tp();
 -        }
 -        std::string str = getString(name);
 -        return analyzeValue<_Tp>(str, space_delete);
 -    }
 -
 -    //! print short name, full name, current value and help for all params
 -    void printParams();
 -
 -    protected:
 -    std::map<std::string, std::vector<std::string> > data;
 -    std::string getString(const std::string& name);
 -
 -    bool has(const std::string& keys);
 -
 -    template<typename _Tp>
 -    _Tp analyzeValue(const std::string& str, bool space_delete=false);
 -
 -    template<typename _Tp>
 -    static _Tp getData(const std::string& str)
 -    {
 -        _Tp res = _Tp();
 -        std::stringstream s1(str);
 -        s1 >> res;
 -        return res;
 -    }
 -
 -    template<typename _Tp>
 -     _Tp fromStringNumber(const std::string& str);//the default conversion function for numbers
 -
 -    };
 -
 -template<> CV_EXPORTS
 -bool CommandLineParser::get<bool>(const std::string& name, bool space_delete);
 -
 -template<> CV_EXPORTS
 -std::string CommandLineParser::analyzeValue<std::string>(const std::string& str, bool space_delete);
 -
 -template<> CV_EXPORTS
 -int CommandLineParser::analyzeValue<int>(const std::string& str, bool space_delete);
 -
 -template<> CV_EXPORTS
 -unsigned int CommandLineParser::analyzeValue<unsigned int>(const std::string& str, bool space_delete);
 -
 -template<> CV_EXPORTS
 -uint64 CommandLineParser::analyzeValue<uint64>(const std::string& str, bool space_delete);
 -
 -template<> CV_EXPORTS
 -float CommandLineParser::analyzeValue<float>(const std::string& str, bool space_delete);
 -
 -template<> CV_EXPORTS
 -double CommandLineParser::analyzeValue<double>(const std::string& str, bool space_delete);
 -
 -
 -/////////////////////////////// Parallel Primitives //////////////////////////////////
 -
 -// a base body class
 -class CV_EXPORTS ParallelLoopBody
 -{
 -public:
 -    virtual ~ParallelLoopBody();
 -    virtual void operator() (const Range& range) const = 0;
 -};
 -
 -CV_EXPORTS void parallel_for_(const Range& range, const ParallelLoopBody& body, double nstripes=-1.);
 -
 -/////////////////////////// Synchronization Primitives ///////////////////////////////
 -
 -class CV_EXPORTS Mutex
 -{
 -public:
 -    Mutex();
 -    ~Mutex();
 -    Mutex(const Mutex& m);
 -    Mutex& operator = (const Mutex& m);
 -
 -    void lock();
 -    bool trylock();
 -    void unlock();
 -
 -    struct Impl;
 -protected:
 -    Impl* impl;
 -};
 -
 -class CV_EXPORTS AutoLock
 -{
 -public:
 -    AutoLock(Mutex& m) : mutex(&m) { mutex->lock(); }
 -    ~AutoLock() { mutex->unlock(); }
 -protected:
 -    Mutex* mutex;
 -};
 -
 -}
 -
 -#endif // __cplusplus
 -
 -#include "opencv2/core/operations.hpp"
 -#include "opencv2/core/mat.hpp"
  
- #include "opencv2/core.hpp"
 -#endif /*__OPENCV_CORE_HPP__*/
++#include "opencv2/core.hpp"
index 7ce9bb8,0000000..ce33c15
mode 100644,000000..100644
--- /dev/null
@@@ -1,458 -1,0 +1,464 @@@
-     // while this is not IEEE754-compliant rounding, it's usually a good enough approximation
-     return (int)(value + (value >= 0 ? 0.5 : -0.5));
 +/*M///////////////////////////////////////////////////////////////////////////////////////
 +//
 +//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
 +//
 +//  By downloading, copying, installing or using the software you agree to this license.
 +//  If you do not agree to this license, do not download, install,
 +//  copy or use the software.
 +//
 +//
 +//                          License Agreement
 +//                For Open Source Computer Vision Library
 +//
 +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
 +// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
 +// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
 +// Third party copyrights are property of their respective owners.
 +//
 +// Redistribution and use in source and binary forms, with or without modification,
 +// are permitted provided that the following conditions are met:
 +//
 +//   * Redistribution's of source code must retain the above copyright notice,
 +//     this list of conditions and the following disclaimer.
 +//
 +//   * Redistribution's in binary form must reproduce the above copyright notice,
 +//     this list of conditions and the following disclaimer in the documentation
 +//     and/or other materials provided with the distribution.
 +//
 +//   * The name of the copyright holders may not be used to endorse or promote products
 +//     derived from this software without specific prior written permission.
 +//
 +// This software is provided by the copyright holders and contributors "as is" and
 +// any express or implied warranties, including, but not limited to, the implied
 +// warranties of merchantability and fitness for a particular purpose are disclaimed.
 +// In no event shall the Intel Corporation or contributors be liable for any direct,
 +// indirect, incidental, special, exemplary, or consequential damages
 +// (including, but not limited to, procurement of substitute goods or services;
 +// loss of use, data, or profits; or business interruption) however caused
 +// and on any theory of liability, whether in contract, strict liability,
 +// or tort (including negligence or otherwise) arising in any way out of
 +// the use of this software, even if advised of the possibility of such damage.
 +//
 +//M*/
 +
 +#ifndef __OPENCV_CORE_CVDEF_H__
 +#define __OPENCV_CORE_CVDEF_H__
 +
 +#if !defined _CRT_SECURE_NO_DEPRECATE && defined _MSC_VER && _MSC_VER > 1300
 +#  define _CRT_SECURE_NO_DEPRECATE /* to avoid multiple Visual Studio warnings */
 +#endif
 +
 +// undef problematic defines sometimes defined by system headers (windows.h in particular)
 +#undef small
 +#undef min
 +#undef max
 +#undef abs
 +#undef Complex
 +
 +#if defined __ICL
 +#  define CV_ICC   __ICL
 +#elif defined __ICC
 +#  define CV_ICC   __ICC
 +#elif defined __ECL
 +#  define CV_ICC   __ECL
 +#elif defined __ECC
 +#  define CV_ICC   __ECC
 +#elif defined __INTEL_COMPILER
 +#  define CV_ICC   __INTEL_COMPILER
 +#endif
 +
 +#if defined CV_ICC && !defined CV_ENABLE_UNROLLED
 +#  define CV_ENABLE_UNROLLED 0
 +#else
 +#  define CV_ENABLE_UNROLLED 1
 +#endif
 +
 +#if (defined WIN32 || defined _WIN32 || defined WINCE) && defined CVAPI_EXPORTS
 +#  define CV_EXPORTS __declspec(dllexport)
 +#else
 +#  define CV_EXPORTS
 +#endif
 +
 +#ifndef CV_INLINE
 +#  if defined __cplusplus
 +#    define CV_INLINE static inline
 +#  elif (defined WIN32 || defined _WIN32 || defined WINCE) && !defined __GNUC__
 +#    define CV_INLINE __inline
 +#  else
 +#    define CV_INLINE static
 +#  endif
 +#endif
 +
 +#ifndef CV_EXTERN_C
 +#  ifdef __cplusplus
 +#    define CV_EXTERN_C extern "C"
 +#  else
 +#    define CV_EXTERN_C
 +#  endif
 +#endif
 +
 +/* CPU features and intrinsics support */
 +#define CV_CPU_NONE    0
 +#define CV_CPU_MMX     1
 +#define CV_CPU_SSE     2
 +#define CV_CPU_SSE2    3
 +#define CV_CPU_SSE3    4
 +#define CV_CPU_SSSE3   5
 +#define CV_CPU_SSE4_1  6
 +#define CV_CPU_SSE4_2  7
 +#define CV_CPU_POPCNT  8
 +#define CV_CPU_AVX    10
 +#define CV_CPU_NEON   11
 +#define CV_HARDWARE_MAX_FEATURE 255
 +
 +// do not include SSE/AVX/NEON headers for NVCC compiler
 +#ifndef __CUDACC__
 +
 +#if defined __SSE2__ || defined _M_X64  || (defined _M_IX86_FP && _M_IX86_FP >= 2)
 +#  include <emmintrin.h>
 +#  define CV_SSE 1
 +#  define CV_SSE2 1
 +#  if defined __SSE3__ || (defined _MSC_VER && _MSC_VER >= 1500)
 +#    include <pmmintrin.h>
 +#    define CV_SSE3 1
 +#  endif
 +#  if defined __SSSE3__  || (defined _MSC_VER && _MSC_VER >= 1500)
 +#    include <tmmintrin.h>
 +#    define CV_SSSE3 1
 +#  endif
 +#  if defined __SSE4_1__ || (defined _MSC_VER && _MSC_VER >= 1500)
 +#    include <smmintrin.h>
 +#    define CV_SSE4_1 1
 +#  endif
 +#  if defined __SSE4_2__ || (defined _MSC_VER && _MSC_VER >= 1500)
 +#    include <nmmintrin.h>
 +#    define CV_SSE4_2 1
 +#  endif
 +#  if defined __AVX__ || (defined _MSC_FULL_VER && _MSC_FULL_VER >= 160040219)
 +// MS Visual Studio 2010 (2012?) has no macro pre-defined to identify the use of /arch:AVX
 +// See: http://connect.microsoft.com/VisualStudio/feedback/details/605858/arch-avx-should-define-a-predefined-macro-in-x64-and-set-a-unique-value-for-m-ix86-fp-in-win32
 +#    include <immintrin.h>
 +#    define CV_AVX 1
 +#    if defined(_XCR_XFEATURE_ENABLED_MASK)
 +#      define __xgetbv() _xgetbv(_XCR_XFEATURE_ENABLED_MASK)
 +#    else
 +#      define __xgetbv() 0
 +#    endif
 +#  endif
 +#endif
 +
 +#ifdef __ARM_NEON__
 +#  include <arm_neon.h>
 +#  define CV_NEON 1
 +#endif
 +
 +#endif // __CUDACC__
 +
 +#ifndef CV_SSE
 +#  define CV_SSE 0
 +#endif
 +#ifndef CV_SSE2
 +#  define CV_SSE2 0
 +#endif
 +#ifndef CV_SSE3
 +#  define CV_SSE3 0
 +#endif
 +#ifndef CV_SSSE3
 +#  define CV_SSSE3 0
 +#endif
 +#ifndef CV_SSE4_1
 +#  define CV_SSE4_1 0
 +#endif
 +#ifndef CV_SSE4_2
 +#  define CV_SSE4_2 0
 +#endif
 +#ifndef CV_AVX
 +#  define CV_AVX 0
 +#endif
 +#ifndef CV_NEON
 +#  define CV_NEON 0
 +#endif
 +
 +/* primitive types */
 +/*
 +  schar  - signed 1 byte integer
 +  uchar  - unsigned 1 byte integer
 +  short  - signed 2 byte integer
 +  ushort - unsigned 2 byte integer
 +  int    - signed 4 byte integer
 +  uint   - unsigned 4 byte integer
 +  int64  - signed 8 byte integer
 +  uint64 - unsigned 8 byte integer
 +*/
 +
 +#if !defined _MSC_VER && !defined __BORLANDC__
 +#  if defined __cplusplus && __cplusplus >= 201103L
 +#    include <cstdint>
 +#  else
 +#    include <stdint.h>
 +#  endif
 +#else
 +   typedef unsigned uint;
 +#endif
 +
 +typedef signed char schar;
 +
 +#ifndef __IPL_H__
 +   typedef unsigned char uchar;
 +   typedef unsigned short ushort;
 +#endif
 +
 +#if defined _MSC_VER || defined __BORLANDC__
 +   typedef __int64 int64;
 +   typedef unsigned __int64 uint64;
 +#  define CV_BIG_INT(n)   n##I64
 +#  define CV_BIG_UINT(n)  n##UI64
 +#else
 +   typedef int64_t int64;
 +   typedef uint64_t uint64;
 +#  define CV_BIG_INT(n)   n##LL
 +#  define CV_BIG_UINT(n)  n##ULL
 +#endif
 +
 +/* special informative macros for wrapper generators */
 +#define CV_EXPORTS_W CV_EXPORTS
 +#define CV_EXPORTS_W_SIMPLE CV_EXPORTS
 +#define CV_EXPORTS_AS(synonym) CV_EXPORTS
 +#define CV_EXPORTS_W_MAP CV_EXPORTS
 +#define CV_IN_OUT
 +#define CV_OUT
 +#define CV_PROP
 +#define CV_PROP_RW
 +#define CV_WRAP
 +#define CV_WRAP_AS(synonym)
 +
 +/* fundamental constants */
 +#define CV_PI   3.1415926535897932384626433832795
 +#define CV_LOG2 0.69314718055994530941723212145818
 +
 +/****************************************************************************************\
 +*                                  Matrix type (Mat)                                     *
 +\****************************************************************************************/
 +
 +#define CV_CN_MAX     512
 +#define CV_CN_SHIFT   3
 +#define CV_DEPTH_MAX  (1 << CV_CN_SHIFT)
 +
 +#define CV_8U   0
 +#define CV_8S   1
 +#define CV_16U  2
 +#define CV_16S  3
 +#define CV_32S  4
 +#define CV_32F  5
 +#define CV_64F  6
 +#define CV_USRTYPE1 7
 +
 +#define CV_MAT_DEPTH_MASK       (CV_DEPTH_MAX - 1)
 +#define CV_MAT_DEPTH(flags)     ((flags) & CV_MAT_DEPTH_MASK)
 +
 +#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))
 +#define CV_MAKE_TYPE CV_MAKETYPE
 +
 +#define CV_8UC1 CV_MAKETYPE(CV_8U,1)
 +#define CV_8UC2 CV_MAKETYPE(CV_8U,2)
 +#define CV_8UC3 CV_MAKETYPE(CV_8U,3)
 +#define CV_8UC4 CV_MAKETYPE(CV_8U,4)
 +#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n))
 +
 +#define CV_8SC1 CV_MAKETYPE(CV_8S,1)
 +#define CV_8SC2 CV_MAKETYPE(CV_8S,2)
 +#define CV_8SC3 CV_MAKETYPE(CV_8S,3)
 +#define CV_8SC4 CV_MAKETYPE(CV_8S,4)
 +#define CV_8SC(n) CV_MAKETYPE(CV_8S,(n))
 +
 +#define CV_16UC1 CV_MAKETYPE(CV_16U,1)
 +#define CV_16UC2 CV_MAKETYPE(CV_16U,2)
 +#define CV_16UC3 CV_MAKETYPE(CV_16U,3)
 +#define CV_16UC4 CV_MAKETYPE(CV_16U,4)
 +#define CV_16UC(n) CV_MAKETYPE(CV_16U,(n))
 +
 +#define CV_16SC1 CV_MAKETYPE(CV_16S,1)
 +#define CV_16SC2 CV_MAKETYPE(CV_16S,2)
 +#define CV_16SC3 CV_MAKETYPE(CV_16S,3)
 +#define CV_16SC4 CV_MAKETYPE(CV_16S,4)
 +#define CV_16SC(n) CV_MAKETYPE(CV_16S,(n))
 +
 +#define CV_32SC1 CV_MAKETYPE(CV_32S,1)
 +#define CV_32SC2 CV_MAKETYPE(CV_32S,2)
 +#define CV_32SC3 CV_MAKETYPE(CV_32S,3)
 +#define CV_32SC4 CV_MAKETYPE(CV_32S,4)
 +#define CV_32SC(n) CV_MAKETYPE(CV_32S,(n))
 +
 +#define CV_32FC1 CV_MAKETYPE(CV_32F,1)
 +#define CV_32FC2 CV_MAKETYPE(CV_32F,2)
 +#define CV_32FC3 CV_MAKETYPE(CV_32F,3)
 +#define CV_32FC4 CV_MAKETYPE(CV_32F,4)
 +#define CV_32FC(n) CV_MAKETYPE(CV_32F,(n))
 +
 +#define CV_64FC1 CV_MAKETYPE(CV_64F,1)
 +#define CV_64FC2 CV_MAKETYPE(CV_64F,2)
 +#define CV_64FC3 CV_MAKETYPE(CV_64F,3)
 +#define CV_64FC4 CV_MAKETYPE(CV_64F,4)
 +#define CV_64FC(n) CV_MAKETYPE(CV_64F,(n))
 +
 +#define CV_MAT_CN_MASK          ((CV_CN_MAX - 1) << CV_CN_SHIFT)
 +#define CV_MAT_CN(flags)        ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1)
 +#define CV_MAT_TYPE_MASK        (CV_DEPTH_MAX*CV_CN_MAX - 1)
 +#define CV_MAT_TYPE(flags)      ((flags) & CV_MAT_TYPE_MASK)
 +#define CV_MAT_CONT_FLAG_SHIFT  14
 +#define CV_MAT_CONT_FLAG        (1 << CV_MAT_CONT_FLAG_SHIFT)
 +#define CV_IS_MAT_CONT(flags)   ((flags) & CV_MAT_CONT_FLAG)
 +#define CV_IS_CONT_MAT          CV_IS_MAT_CONT
 +#define CV_SUBMAT_FLAG_SHIFT    15
 +#define CV_SUBMAT_FLAG          (1 << CV_SUBMAT_FLAG_SHIFT)
 +#define CV_IS_SUBMAT(flags)     ((flags) & CV_MAT_SUBMAT_FLAG)
 +
 +/* Size of each channel item,
 +   0x124489 = 1000 0100 0100 0010 0010 0001 0001 ~ array of sizeof(arr_type_elem) */
 +#define CV_ELEM_SIZE1(type) \
 +    ((((sizeof(size_t)<<28)|0x8442211) >> CV_MAT_DEPTH(type)*4) & 15)
 +
 +/* 0x3a50 = 11 10 10 01 01 00 00 ~ array of log2(sizeof(arr_type_elem)) */
 +#define CV_ELEM_SIZE(type) \
 +    (CV_MAT_CN(type) << ((((sizeof(size_t)/4+1)*16384|0x3a50) >> CV_MAT_DEPTH(type)*2) & 3))
 +
 +
 +/****************************************************************************************\
 +*                                      fast math                                         *
 +\****************************************************************************************/
 +
 +#if defined __BORLANDC__
 +#  include <fastmath.h>
 +#elif defined __cplusplus
 +#  include <cmath>
 +#else
 +#  include <math.h>
 +#endif
 +
 +#ifndef MIN
 +#  define MIN(a,b)  ((a) > (b) ? (b) : (a))
 +#endif
 +
 +#ifndef MAX
 +#  define MAX(a,b)  ((a) < (b) ? (b) : (a))
 +#endif
 +
 +#ifdef HAVE_TEGRA_OPTIMIZATION
 +#  include "tegra_round.hpp"
 +#endif
 +
 +CV_INLINE int cvRound( double value )
 +{
 +#if ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__)
 +    __m128d t = _mm_set_sd( value );
 +    return _mm_cvtsd_si32(t);
 +#elif defined _MSC_VER && defined _M_IX86
 +    int t;
 +    __asm
 +    {
 +        fld value;
 +        fistp t;
 +    }
 +    return t;
++#elif defined _MSC_VER && defined _M_ARM && defined HAVE_TEGRA_OPTIMIZATION
++    TEGRA_ROUND(value);
 +#elif defined HAVE_LRINT || defined CV_ICC || defined __GNUC__
 +#  ifdef HAVE_TEGRA_OPTIMIZATION
 +    TEGRA_ROUND(value);
 +#  else
 +    return (int)lrint(value);
 +#  endif
 +#else
++    double intpart, fractpart;
++    fractpart = modf(value, &intpart);
++    if ((fabs(fractpart) != 0.5) || ((((int)intpart) % 2) != 0))
++        return (int)(value + (value >= 0 ? 0.5 : -0.5));
++    else
++        return (int)intpart;
 +#endif
 +}
 +
 +CV_INLINE int cvFloor( double value )
 +{
 +#if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__)
 +    __m128d t = _mm_set_sd( value );
 +    int i = _mm_cvtsd_si32(t);
 +    return i - _mm_movemask_pd(_mm_cmplt_sd(t, _mm_cvtsi32_sd(t,i)));
 +#elif defined __GNUC__
 +    int i = (int)value;
 +    return i - (i > value);
 +#else
 +    int i = cvRound(value);
 +    float diff = (float)(value - i);
 +    return i - (diff < 0);
 +#endif
 +}
 +
 +CV_INLINE int cvCeil( double value )
 +{
 +#if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__&& !defined __APPLE__)) && !defined(__CUDACC__)
 +    __m128d t = _mm_set_sd( value );
 +    int i = _mm_cvtsd_si32(t);
 +    return i + _mm_movemask_pd(_mm_cmplt_sd(_mm_cvtsi32_sd(t,i), t));
 +#elif defined __GNUC__
 +    int i = (int)value;
 +    return i + (i < value);
 +#else
 +    int i = cvRound(value);
 +    float diff = (float)(i - value);
 +    return i + (diff < 0);
 +#endif
 +}
 +
 +CV_INLINE int cvIsNaN( double value )
 +{
 +    union { uint64 u; double f; } ieee754;
 +    ieee754.f = value;
 +    return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) +
 +           ((unsigned)ieee754.u != 0) > 0x7ff00000;
 +}
 +
 +CV_INLINE int cvIsInf( double value )
 +{
 +    union { uint64 u; double f; } ieee754;
 +    ieee754.f = value;
 +    return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
 +           (unsigned)ieee754.u == 0;
 +}
 +
 +/****************************************************************************************\
 +*          exchange-add operation for atomic operations on reference counters            *
 +\****************************************************************************************/
 +
 +#if defined __INTEL_COMPILER && !(defined WIN32 || defined _WIN32)
 +   // atomic increment on the linux version of the Intel(tm) compiler
 +#  define CV_XADD(addr, delta) (int)_InterlockedExchangeAdd(const_cast<void*>(reinterpret_cast<volatile void*>(addr)), delta)
 +#elif defined __GNUC__
 +#  if defined __clang__ && __clang_major__ >= 3 && !defined __ANDROID__
 +#    ifdef __ATOMIC_ACQ_REL
 +#      define CV_XADD(addr, delta) __c11_atomic_fetch_add((_Atomic(int)*)(addr), delta, __ATOMIC_ACQ_REL)
 +#    else
 +#      define CV_XADD(addr, delta) __atomic_fetch_add((_Atomic(int)*)(addr), delta, 4)
 +#    endif
 +#  else
 +#    if defined __ATOMIC_ACQ_REL && !defined __clang__
 +       // version for gcc >= 4.7
 +#      define CV_XADD(addr, delta) __atomic_fetch_add(addr, delta, __ATOMIC_ACQ_REL)
 +#    else
 +#      define CV_XADD(addr, delta) __sync_fetch_and_add(addr, delta)
 +#    endif
 +#  endif
 +#elif (defined WIN32 || defined _WIN32 || defined WINCE) && (!defined RC_INVOKED)
 +#  if !defined(_M_AMD64) && !defined(_M_IA64) && !defined(_M_ARM)
 +     CV_EXTERN_C __declspec(dllimport) long __stdcall InterlockedExchangeAdd(long volatile *Addend, long Value);
 +#    define CV_XADD(addr, delta) (int)InterlockedExchangeAdd((long volatile*)addr, delta)
 +#  else
 +     CV_EXTERN_C long _InterlockedExchangeAdd (long volatile *Addend, long Value);
 +#    pragma intrinsic(_InterlockedExchangeAdd)
 +#    define CV_XADD(addr, delta) (int)_InterlockedExchangeAdd((long volatile*)addr, delta)
 +#  endif
 +#else
 +   CV_INLINE CV_XADD(int* addr, int delta) { int tmp = *addr; *addr += delta; return tmp; }
 +#endif
 +
 +#endif // __OPENCV_CORE_CVDEF_H__
  //
  //M*/
  
 -#ifndef __OPENCV_CORE_MATRIX_OPERATIONS_HPP__
 -#define __OPENCV_CORE_MATRIX_OPERATIONS_HPP__
 +#ifndef __OPENCV_CORE_MAT_HPP__
 +#define __OPENCV_CORE_MAT_HPP__
  
 -#ifndef SKIP_INCLUDES
 -#include <limits.h>
 -#include <string.h>
 -#endif // SKIP_INCLUDES
 -
 -#ifdef __cplusplus
 -
 -namespace cv
 -{
 +#ifndef __cplusplus
 +#  error mat.hpp header must be compiled as C++
 +#endif
  
 -//////////////////////////////// Mat ////////////////////////////////
 +#include "opencv2/core/matx.hpp"
 +#include "opencv2/core/types.hpp"
  
 -inline void Mat::initEmpty()
 -{
 -    flags = MAGIC_VAL;
 -    dims = rows = cols = 0;
 -    data = datastart = dataend = datalimit = 0;
 -    refcount = 0;
 -    allocator = 0;
 -}
 -
 -inline Mat::Mat() : size(&rows)
 -{
 -    initEmpty();
 -}
  
 -inline Mat::Mat(int _rows, int _cols, int _type) : size(&rows)
 +namespace cv
  {
 -    initEmpty();
 -    create(_rows, _cols, _type);
 -}
  
 -inline Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s) : size(&rows)
 -{
 -    initEmpty();
 -    create(_rows, _cols, _type);
 -    *this = _s;
 -}
 +//////////////////////// Input/Output Array Arguments /////////////////////////////////
  
 -inline Mat::Mat(Size _sz, int _type) : size(&rows)
 +/*!
 + Proxy datatype for passing Mat's and vector<>'s as input parameters
 + */
 +class CV_EXPORTS _InputArray
  {
 -    initEmpty();
 -    create( _sz.height, _sz.width, _type );
 -}
 +public:
 +    enum {
 +        KIND_SHIFT = 16,
 +        FIXED_TYPE = 0x8000 << KIND_SHIFT,
 +        FIXED_SIZE = 0x4000 << KIND_SHIFT,
 +        KIND_MASK = ~(FIXED_TYPE|FIXED_SIZE) - (1 << KIND_SHIFT) + 1,
 +
 +        NONE              = 0 << KIND_SHIFT,
 +        MAT               = 1 << KIND_SHIFT,
 +        MATX              = 2 << KIND_SHIFT,
 +        STD_VECTOR        = 3 << KIND_SHIFT,
 +        STD_VECTOR_VECTOR = 4 << KIND_SHIFT,
 +        STD_VECTOR_MAT    = 5 << KIND_SHIFT,
 +        EXPR              = 6 << KIND_SHIFT,
 +        OPENGL_BUFFER     = 7 << KIND_SHIFT,
 +        OPENGL_TEXTURE    = 8 << KIND_SHIFT,
 +        GPU_MAT           = 9 << KIND_SHIFT
 +    };
 +
 +    _InputArray();
 +    _InputArray(const Mat& m);
 +    _InputArray(const MatExpr& expr);
 +    _InputArray(const std::vector<Mat>& vec);
 +    template<typename _Tp> _InputArray(const Mat_<_Tp>& m);
 +    template<typename _Tp> _InputArray(const std::vector<_Tp>& vec);
 +    template<typename _Tp> _InputArray(const std::vector<std::vector<_Tp> >& vec);
 +    template<typename _Tp> _InputArray(const std::vector<Mat_<_Tp> >& vec);
 +    template<typename _Tp> _InputArray(const _Tp* vec, int n);
 +    template<typename _Tp, int m, int n> _InputArray(const Matx<_Tp, m, n>& matx);
 +    _InputArray(const double& val);
 +    _InputArray(const gpu::GpuMat& d_mat);
 +    _InputArray(const ogl::Buffer& buf);
 +    _InputArray(const ogl::Texture2D& tex);
 +
 +    virtual Mat getMat(int i=-1) const;
 +    virtual void getMatVector(std::vector<Mat>& mv) const;
 +    virtual gpu::GpuMat getGpuMat() const;
 +    virtual ogl::Buffer getOGlBuffer() const;
 +    virtual ogl::Texture2D getOGlTexture2D() const;
 +
 +    virtual int kind() const;
 +    virtual Size size(int i=-1) const;
 +    virtual size_t total(int i=-1) const;
 +    virtual int type(int i=-1) const;
 +    virtual int depth(int i=-1) const;
 +    virtual int channels(int i=-1) const;
 +    virtual bool empty() const;
 +
 +    virtual ~_InputArray();
  
 -inline Mat::Mat(Size _sz, int _type, const Scalar& _s) : size(&rows)
 -{
 -    initEmpty();
 -    create(_sz.height, _sz.width, _type);
 -    *this = _s;
 -}
 +    int flags;
 +    void* obj;
 +    Size sz;
 +};
  
 -inline Mat::Mat(int _dims, const int* _sz, int _type) : size(&rows)
 -{
 -    initEmpty();
 -    create(_dims, _sz, _type);
 -}
  
 -inline Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s) : size(&rows)
 -{
 -    initEmpty();
 -    create(_dims, _sz, _type);
 -    *this = _s;
 -}
 -
 -inline Mat::Mat(const Mat& m)
 -    : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
 -    refcount(m.refcount), datastart(m.datastart), dataend(m.dataend),
 -    datalimit(m.datalimit), allocator(m.allocator), size(&rows)
 -{
 -    if( refcount )
 -        CV_XADD(refcount, 1);
 -    if( m.dims <= 2 )
 -    {
 -        step[0] = m.step[0]; step[1] = m.step[1];
 -    }
 -    else
 -    {
 -        dims = 0;
 -        copySize(m);
 -    }
 -}
 -
 -inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
 -    : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_rows), cols(_cols),
 -    data((uchar*)_data), refcount(0), datastart((uchar*)_data), dataend(0),
 -    datalimit(0), allocator(0), size(&rows)
 -{
 -    size_t esz = CV_ELEM_SIZE(_type), minstep = cols*esz;
 -    if( _step == AUTO_STEP )
 -    {
 -        _step = minstep;
 -        flags |= CONTINUOUS_FLAG;
 -    }
 -    else
 -    {
 -        if( rows == 1 ) _step = minstep;
 -        CV_DbgAssert( _step >= minstep );
 -        flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
 -    }
 -    step[0] = _step; step[1] = esz;
 -    datalimit = datastart + _step*rows;
 -    dataend = datalimit - _step + minstep;
 -}
 -
 -inline Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
 -    : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_sz.height), cols(_sz.width),
 -    data((uchar*)_data), refcount(0), datastart((uchar*)_data), dataend(0),
 -    datalimit(0), allocator(0), size(&rows)
 -{
 -    size_t esz = CV_ELEM_SIZE(_type), minstep = cols*esz;
 -    if( _step == AUTO_STEP )
 -    {
 -        _step = minstep;
 -        flags |= CONTINUOUS_FLAG;
 -    }
 -    else
 -    {
 -        if( rows == 1 ) _step = minstep;
 -        CV_DbgAssert( _step >= minstep );
 -        flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
 -    }
 -    step[0] = _step; step[1] = esz;
 -    datalimit = datastart + _step*rows;
 -    dataend = datalimit - _step + minstep;
 -}
 -
 -
 -template<typename _Tp> inline Mat::Mat(const vector<_Tp>& vec, bool copyData)
 -    : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
 -    dims(2), rows((int)vec.size()), cols(1), data(0), refcount(0),
 -    datastart(0), dataend(0), allocator(0), size(&rows)
 +/*!
 + Proxy datatype for passing Mat's and vector<>'s as input parameters
 + */
 +class CV_EXPORTS _OutputArray : public _InputArray
  {
 -    if(vec.empty())
 -        return;
 -    if( !copyData )
 -    {
 -        step[0] = step[1] = sizeof(_Tp);
 -        data = datastart = (uchar*)&vec[0];
 -        datalimit = dataend = datastart + rows*step[0];
 -    }
 -    else
 -        Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
 -}
 -
 -
 -template<typename _Tp, int n> inline Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
 -    : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
 -    dims(2), rows(n), cols(1), data(0), refcount(0),
 -    datastart(0), dataend(0), allocator(0), size(&rows)
 -{
 -    if( !copyData )
 -    {
 -        step[0] = step[1] = sizeof(_Tp);
 -        data = datastart = (uchar*)vec.val;
 -        datalimit = dataend = datastart + rows*step[0];
 -    }
 -    else
 -        Mat(n, 1, DataType<_Tp>::type, (void*)vec.val).copyTo(*this);
 -}
 -
 -
 -template<typename _Tp, int m, int n> inline Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
 -    : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
 -    dims(2), rows(m), cols(n), data(0), refcount(0),
 -    datastart(0), dataend(0), allocator(0), size(&rows)
 -{
 -    if( !copyData )
 -    {
 -        step[0] = cols*sizeof(_Tp);
 -        step[1] = sizeof(_Tp);
 -        data = datastart = (uchar*)M.val;
 -        datalimit = dataend = datastart + rows*step[0];
 -    }
 -    else
 -        Mat(m, n, DataType<_Tp>::type, (uchar*)M.val).copyTo(*this);
 -}
 -
 -
 -template<typename _Tp> inline Mat::Mat(const Point_<_Tp>& pt, bool copyData)
 -    : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
 -    dims(2), rows(2), cols(1), data(0), refcount(0),
 -    datastart(0), dataend(0), allocator(0), size(&rows)
 -{
 -    if( !copyData )
 -    {
 -        step[0] = step[1] = sizeof(_Tp);
 -        data = datastart = (uchar*)&pt.x;
 -        datalimit = dataend = datastart + rows*step[0];
 -    }
 -    else
 +public:
 +    enum
      {
 -        create(2, 1, DataType<_Tp>::type);
 -        ((_Tp*)data)[0] = pt.x;
 -        ((_Tp*)data)[1] = pt.y;
 -    }
 -}
 -
 +        DEPTH_MASK_8U = 1 << CV_8U,
 +        DEPTH_MASK_8S = 1 << CV_8S,
 +        DEPTH_MASK_16U = 1 << CV_16U,
 +        DEPTH_MASK_16S = 1 << CV_16S,
 +        DEPTH_MASK_32S = 1 << CV_32S,
 +        DEPTH_MASK_32F = 1 << CV_32F,
 +        DEPTH_MASK_64F = 1 << CV_64F,
 +        DEPTH_MASK_ALL = (DEPTH_MASK_64F<<1)-1,
 +        DEPTH_MASK_ALL_BUT_8S = DEPTH_MASK_ALL & ~DEPTH_MASK_8S,
 +        DEPTH_MASK_FLT = DEPTH_MASK_32F + DEPTH_MASK_64F
 +    };
 +
 +    _OutputArray();
 +    _OutputArray(Mat& m);
 +    _OutputArray(std::vector<Mat>& vec);
 +    _OutputArray(gpu::GpuMat& d_mat);
 +    _OutputArray(ogl::Buffer& buf);
 +    _OutputArray(ogl::Texture2D& tex);
 +    template<typename _Tp> _OutputArray(std::vector<_Tp>& vec);
 +    template<typename _Tp> _OutputArray(std::vector<std::vector<_Tp> >& vec);
 +    template<typename _Tp> _OutputArray(std::vector<Mat_<_Tp> >& vec);
 +    template<typename _Tp> _OutputArray(Mat_<_Tp>& m);
 +    template<typename _Tp> _OutputArray(_Tp* vec, int n);
 +    template<typename _Tp, int m, int n> _OutputArray(Matx<_Tp, m, n>& matx);
 +
 +    _OutputArray(const Mat& m);
 +    _OutputArray(const std::vector<Mat>& vec);
 +    _OutputArray(const gpu::GpuMat& d_mat);
 +    _OutputArray(const ogl::Buffer& buf);
 +    _OutputArray(const ogl::Texture2D& tex);
 +    template<typename _Tp> _OutputArray(const std::vector<_Tp>& vec);
 +    template<typename _Tp> _OutputArray(const std::vector<std::vector<_Tp> >& vec);
 +    template<typename _Tp> _OutputArray(const std::vector<Mat_<_Tp> >& vec);
 +    template<typename _Tp> _OutputArray(const Mat_<_Tp>& m);
 +    template<typename _Tp> _OutputArray(const _Tp* vec, int n);
 +    template<typename _Tp, int m, int n> _OutputArray(const Matx<_Tp, m, n>& matx);
 +
 +    virtual bool fixedSize() const;
 +    virtual bool fixedType() const;
 +    virtual bool needed() const;
 +    virtual Mat& getMatRef(int i=-1) const;
 +    virtual gpu::GpuMat& getGpuMatRef() const;
 +    virtual ogl::Buffer& getOGlBufferRef() const;
 +    virtual ogl::Texture2D& getOGlTexture2DRef() const;
 +    virtual void create(Size sz, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
 +    virtual void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
 +    virtual void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
 +    virtual void release() const;
 +    virtual void clear() const;
 +
 +    virtual ~_OutputArray();
 +};
  
 -template<typename _Tp> inline Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
 -    : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
 -    dims(2), rows(3), cols(1), data(0), refcount(0),
 -    datastart(0), dataend(0), allocator(0), size(&rows)
 -{
 -    if( !copyData )
 -    {
 -        step[0] = step[1] = sizeof(_Tp);
 -        data = datastart = (uchar*)&pt.x;
 -        datalimit = dataend = datastart + rows*step[0];
 -    }
 -    else
 -    {
 -        create(3, 1, DataType<_Tp>::type);
 -        ((_Tp*)data)[0] = pt.x;
 -        ((_Tp*)data)[1] = pt.y;
 -        ((_Tp*)data)[2] = pt.z;
 -    }
 -}
 -
 -
 -template<typename _Tp> inline Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer)
 -    : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
 -    dims(0), rows(0), cols(0), data(0), refcount(0),
 -    datastart(0), dataend(0), allocator(0), size(&rows)
 -{
 -    *this = *commaInitializer;
 -}
 +typedef const _InputArray& InputArray;
 +typedef InputArray InputArrayOfArrays;
 +typedef const _OutputArray& OutputArray;
 +typedef OutputArray OutputArrayOfArrays;
 +typedef OutputArray InputOutputArray;
 +typedef OutputArray InputOutputArrayOfArrays;
  
 -inline Mat::~Mat()
 -{
 -    release();
 -    if( step.p != step.buf )
 -        fastFree(step.p);
 -}
 +CV_EXPORTS OutputArray noArray();
  
 -inline Mat& Mat::operator = (const Mat& m)
 -{
 -    if( this != &m )
 -    {
 -        if( m.refcount )
 -            CV_XADD(m.refcount, 1);
 -        release();
 -        flags = m.flags;
 -        if( dims <= 2 && m.dims <= 2 )
 -        {
 -            dims = m.dims;
 -            rows = m.rows;
 -            cols = m.cols;
 -            step[0] = m.step[0];
 -            step[1] = m.step[1];
 -        }
 -        else
 -            copySize(m);
 -        data = m.data;
 -        datastart = m.datastart;
 -        dataend = m.dataend;
 -        datalimit = m.datalimit;
 -        refcount = m.refcount;
 -        allocator = m.allocator;
 -    }
 -    return *this;
 -}
 -
 -inline Mat Mat::row(int y) const { return Mat(*this, Range(y, y+1), Range::all()); }
 -inline Mat Mat::col(int x) const { return Mat(*this, Range::all(), Range(x, x+1)); }
 -inline Mat Mat::rowRange(int startrow, int endrow) const
 -    { return Mat(*this, Range(startrow, endrow), Range::all()); }
 -inline Mat Mat::rowRange(const Range& r) const
 -    { return Mat(*this, r, Range::all()); }
 -inline Mat Mat::colRange(int startcol, int endcol) const
 -    { return Mat(*this, Range::all(), Range(startcol, endcol)); }
 -inline Mat Mat::colRange(const Range& r) const
 -    { return Mat(*this, Range::all(), r); }
 -
 -inline Mat Mat::diag(const Mat& d)
 -{
 -    CV_Assert( d.cols == 1 || d.rows == 1 );
 -    int len = d.rows + d.cols - 1;
 -    Mat m(len, len, d.type(), Scalar(0)), md = m.diag();
 -    if( d.cols == 1 )
 -        d.copyTo(md);
 -    else
 -        transpose(d, md);
 -    return m;
 -}
 -
 -inline Mat Mat::clone() const
 -{
 -    Mat m;
 -    copyTo(m);
 -    return m;
 -}
  
 -inline void Mat::assignTo( Mat& m, int _type ) const
 -{
 -    if( _type < 0 )
 -        m = *this;
 -    else
 -        convertTo(m, _type);
 -}
  
 -inline void Mat::create(int _rows, int _cols, int _type)
 -{
 -    _type &= TYPE_MASK;
 -    if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data )
 -        return;
 -    int sz[] = {_rows, _cols};
 -    create(2, sz, _type);
 -}
 -
 -inline void Mat::create(Size _sz, int _type)
 -{
 -    create(_sz.height, _sz.width, _type);
 -}
 +/////////////////////////////////// MatAllocator //////////////////////////////////////
  
 -inline void Mat::addref()
 -{ if( refcount ) CV_XADD(refcount, 1); }
 +/*!
 +   Custom array allocator
  
 -inline void Mat::release()
 +*/
 +class CV_EXPORTS MatAllocator
  {
 -    if( refcount && CV_XADD(refcount, -1) == 1 )
 -        deallocate();
 -    data = datastart = dataend = datalimit = 0;
 -    size.p[0] = 0;
 -    refcount = 0;
 -}
 -
 -inline Mat Mat::operator()( Range _rowRange, Range _colRange ) const
 -{
 -    return Mat(*this, _rowRange, _colRange);
 -}
 -
 -inline Mat Mat::operator()( const Rect& roi ) const
 -{ return Mat(*this, roi); }
 +public:
 +    MatAllocator() {}
 +    virtual ~MatAllocator() {}
 +    virtual void allocate(int dims, const int* sizes, int type, int*& refcount,
 +                          uchar*& datastart, uchar*& data, size_t* step) = 0;
 +    virtual void deallocate(int* refcount, uchar* datastart, uchar* data) = 0;
 +};
  
 -inline Mat Mat::operator()(const Range* ranges) const
 -{
 -    return Mat(*this, ranges);
 -}
  
 -inline Mat::operator CvMat() const
 -{
 -    CV_DbgAssert(dims <= 2);
 -    CvMat m = cvMat(rows, dims == 1 ? 1 : cols, type(), data);
 -    m.step = (int)step[0];
 -    m.type = (m.type & ~CONTINUOUS_FLAG) | (flags & CONTINUOUS_FLAG);
 -    return m;
 -}
 -
 -inline bool Mat::isContinuous() const { return (flags & CONTINUOUS_FLAG) != 0; }
 -inline bool Mat::isSubmatrix() const { return (flags & SUBMATRIX_FLAG) != 0; }
 -inline size_t Mat::elemSize() const { return dims > 0 ? step.p[dims-1] : 0; }
 -inline size_t Mat::elemSize1() const { return CV_ELEM_SIZE1(flags); }
 -inline int Mat::type() const { return CV_MAT_TYPE(flags); }
 -inline int Mat::depth() const { return CV_MAT_DEPTH(flags); }
 -inline int Mat::channels() const { return CV_MAT_CN(flags); }
 -inline size_t Mat::step1(int i) const { return step.p[i]/elemSize1(); }
 -inline bool Mat::empty() const { return data == 0 || total() == 0; }
 -inline size_t Mat::total() const
 -{
 -    if( dims <= 2 )
 -        return (size_t)rows*cols;
 -    size_t p = 1;
 -    for( int i = 0; i < dims; i++ )
 -        p *= size[i];
 -    return p;
 -}
 -
 -inline uchar* Mat::ptr(int y)
 -{
 -    CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
 -    return data + step.p[0]*y;
 -}
  
 -inline const uchar* Mat::ptr(int y) const
 -{
 -    CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
 -    return data + step.p[0]*y;
 -}
 +//////////////////////////////// MatCommaInitializer //////////////////////////////////
  
 -template<typename _Tp> inline _Tp* Mat::ptr(int y)
 -{
 -    CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
 -    return (_Tp*)(data + step.p[0]*y);
 -}
 +/*!
 + Comma-separated Matrix Initializer
  
 -template<typename _Tp> inline const _Tp* Mat::ptr(int y) const
 -{
 -    CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
 -    return (const _Tp*)(data + step.p[0]*y);
 -}
 + The class instances are usually not created explicitly.
 + Instead, they are created on "matrix << firstValue" operator.
  
 + The sample below initializes 2x2 rotation matrix:
  
 -inline uchar* Mat::ptr(int i0, int i1)
 + \code
 + double angle = 30, a = cos(angle*CV_PI/180), b = sin(angle*CV_PI/180);
 + Mat R = (Mat_<double>(2,2) << a, -b, b, a);
 + \endcode
 +*/
 +template<typename _Tp> class MatCommaInitializer_
  {
 -    CV_DbgAssert( dims >= 2 && data &&
 -                  (unsigned)i0 < (unsigned)size.p[0] &&
 -                  (unsigned)i1 < (unsigned)size.p[1] );
 -    return data + i0*step.p[0] + i1*step.p[1];
 -}
 +public:
 +    //! the constructor, created by "matrix << firstValue" operator, where matrix is cv::Mat
 +    MatCommaInitializer_(Mat_<_Tp>* _m);
 +    //! the operator that takes the next value and put it to the matrix
 +    template<typename T2> MatCommaInitializer_<_Tp>& operator , (T2 v);
 +    //! another form of conversion operator
 +    operator Mat_<_Tp>() const;
 +protected:
 +    MatIterator_<_Tp> it;
 +};
  
 -inline const uchar* Mat::ptr(int i0, int i1) const
 -{
 -    CV_DbgAssert( dims >= 2 && data &&
 -                 (unsigned)i0 < (unsigned)size.p[0] &&
 -                 (unsigned)i1 < (unsigned)size.p[1] );
 -    return data + i0*step.p[0] + i1*step.p[1];
 -}
  
 -template<typename _Tp> inline _Tp* Mat::ptr(int i0, int i1)
 -{
 -    CV_DbgAssert( dims >= 2 && data &&
 -                  (unsigned)i0 < (unsigned)size.p[0] &&
 -                  (unsigned)i1 < (unsigned)size.p[1] );
 -    return (_Tp*)(data + i0*step.p[0] + i1*step.p[1]);
 -}
  
 -template<typename _Tp> inline const _Tp* Mat::ptr(int i0, int i1) const
 -{
 -    CV_DbgAssert( dims >= 2 && data &&
 -                  (unsigned)i0 < (unsigned)size.p[0] &&
 -                  (unsigned)i1 < (unsigned)size.p[1] );
 -    return (const _Tp*)(data + i0*step.p[0] + i1*step.p[1]);
 -}
  
 -inline uchar* Mat::ptr(int i0, int i1, int i2)
 -{
 -    CV_DbgAssert( dims >= 3 && data &&
 -                  (unsigned)i0 < (unsigned)size.p[0] &&
 -                  (unsigned)i1 < (unsigned)size.p[1] &&
 -                  (unsigned)i2 < (unsigned)size.p[2] );
 -    return data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2];
 -}
 -
 -inline const uchar* Mat::ptr(int i0, int i1, int i2) const
 -{
 -    CV_DbgAssert( dims >= 3 && data &&
 -                  (unsigned)i0 < (unsigned)size.p[0] &&
 -                  (unsigned)i1 < (unsigned)size.p[1] &&
 -                  (unsigned)i2 < (unsigned)size.p[2] );
 -    return data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2];
 -}
 -
 -template<typename _Tp> inline _Tp* Mat::ptr(int i0, int i1, int i2)
 +/////////////////////////////////////// Mat ///////////////////////////////////////////
 +
 +/*!
 +   The n-dimensional matrix class.
 +
 +   The class represents an n-dimensional dense numerical array that can act as
 +   a matrix, image, optical flow map, 3-focal tensor etc.
 +   It is very similar to CvMat and CvMatND types from earlier versions of OpenCV,
 +   and similarly to those types, the matrix can be multi-channel. It also fully supports ROI mechanism.
 +
 +   There are many different ways to create cv::Mat object. Here are the some popular ones:
 +   <ul>
 +   <li> using cv::Mat::create(nrows, ncols, type) method or
 +     the similar constructor cv::Mat::Mat(nrows, ncols, type[, fill_value]) constructor.
 +     A new matrix of the specified size and specifed type will be allocated.
 +     "type" has the same meaning as in cvCreateMat function,
 +     e.g. CV_8UC1 means 8-bit single-channel matrix, CV_32FC2 means 2-channel (i.e. complex)
 +     floating-point matrix etc:
 +
 +     \code
 +     // make 7x7 complex matrix filled with 1+3j.
 +     cv::Mat M(7,7,CV_32FC2,Scalar(1,3));
 +     // and now turn M to 100x60 15-channel 8-bit matrix.
 +     // The old content will be deallocated
 +     M.create(100,60,CV_8UC(15));
 +     \endcode
 +
 +     As noted in the introduction of this chapter, Mat::create()
 +     will only allocate a new matrix when the current matrix dimensionality
 +     or type are different from the specified.
 +
 +   <li> by using a copy constructor or assignment operator, where on the right side it can
 +     be a matrix or expression, see below. Again, as noted in the introduction,
 +     matrix assignment is O(1) operation because it only copies the header
 +     and increases the reference counter. cv::Mat::clone() method can be used to get a full
 +     (a.k.a. deep) copy of the matrix when you need it.
 +
 +   <li> by constructing a header for a part of another matrix. It can be a single row, single column,
 +     several rows, several columns, rectangular region in the matrix (called a minor in algebra) or
 +     a diagonal. Such operations are also O(1), because the new header will reference the same data.
 +     You can actually modify a part of the matrix using this feature, e.g.
 +
 +     \code
 +     // add 5-th row, multiplied by 3 to the 3rd row
 +     M.row(3) = M.row(3) + M.row(5)*3;
 +
 +     // now copy 7-th column to the 1-st column
 +     // M.col(1) = M.col(7); // this will not work
 +     Mat M1 = M.col(1);
 +     M.col(7).copyTo(M1);
 +
 +     // create new 320x240 image
 +     cv::Mat img(Size(320,240),CV_8UC3);
 +     // select a roi
 +     cv::Mat roi(img, Rect(10,10,100,100));
 +     // fill the ROI with (0,255,0) (which is green in RGB space);
 +     // the original 320x240 image will be modified
 +     roi = Scalar(0,255,0);
 +     \endcode
 +
 +     Thanks to the additional cv::Mat::datastart and cv::Mat::dataend members, it is possible to
 +     compute the relative sub-matrix position in the main "container" matrix using cv::Mat::locateROI():
 +
 +     \code
 +     Mat A = Mat::eye(10, 10, CV_32S);
 +     // extracts A columns, 1 (inclusive) to 3 (exclusive).
 +     Mat B = A(Range::all(), Range(1, 3));
 +     // extracts B rows, 5 (inclusive) to 9 (exclusive).
 +     // that is, C ~ A(Range(5, 9), Range(1, 3))
 +     Mat C = B(Range(5, 9), Range::all());
 +     Size size; Point ofs;
 +     C.locateROI(size, ofs);
 +     // size will be (width=10,height=10) and the ofs will be (x=1, y=5)
 +     \endcode
 +
 +     As in the case of whole matrices, if you need a deep copy, use cv::Mat::clone() method
 +     of the extracted sub-matrices.
 +
 +   <li> by making a header for user-allocated-data. It can be useful for
 +      <ol>
 +      <li> processing "foreign" data using OpenCV (e.g. when you implement
 +         a DirectShow filter or a processing module for gstreamer etc.), e.g.
 +
 +         \code
 +         void process_video_frame(const unsigned char* pixels,
 +                                  int width, int height, int step)
 +         {
 +            cv::Mat img(height, width, CV_8UC3, pixels, step);
 +            cv::GaussianBlur(img, img, cv::Size(7,7), 1.5, 1.5);
 +         }
 +         \endcode
 +
 +      <li> for quick initialization of small matrices and/or super-fast element access
 +
 +         \code
 +         double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}};
 +         cv::Mat M = cv::Mat(3, 3, CV_64F, m).inv();
 +         \endcode
 +      </ol>
 +
 +       partial yet very common cases of this "user-allocated data" case are conversions
 +       from CvMat and IplImage to cv::Mat. For this purpose there are special constructors
 +       taking pointers to CvMat or IplImage and the optional
 +       flag indicating whether to copy the data or not.
 +
 +       Backward conversion from cv::Mat to CvMat or IplImage is provided via cast operators
 +       cv::Mat::operator CvMat() an cv::Mat::operator IplImage().
 +       The operators do not copy the data.
 +
 +
 +       \code
 +       IplImage* img = cvLoadImage("greatwave.jpg", 1);
 +       Mat mtx(img); // convert IplImage* -> cv::Mat
 +       CvMat oldmat = mtx; // convert cv::Mat -> CvMat
 +       CV_Assert(oldmat.cols == img->width && oldmat.rows == img->height &&
 +           oldmat.data.ptr == (uchar*)img->imageData && oldmat.step == img->widthStep);
 +       \endcode
 +
 +   <li> by using MATLAB-style matrix initializers, cv::Mat::zeros(), cv::Mat::ones(), cv::Mat::eye(), e.g.:
 +
 +   \code
 +   // create a double-precision identity martix and add it to M.
 +   M += Mat::eye(M.rows, M.cols, CV_64F);
 +   \endcode
 +
 +   <li> by using comma-separated initializer:
 +
 +   \code
 +   // create 3x3 double-precision identity matrix
 +   Mat M = (Mat_<double>(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);
 +   \endcode
 +
 +   here we first call constructor of cv::Mat_ class (that we describe further) with the proper matrix,
 +   and then we just put "<<" operator followed by comma-separated values that can be constants,
 +   variables, expressions etc. Also, note the extra parentheses that are needed to avoid compiler errors.
 +
 +   </ul>
 +
 +   Once matrix is created, it will be automatically managed by using reference-counting mechanism
 +   (unless the matrix header is built on top of user-allocated data,
 +   in which case you should handle the data by yourself).
 +   The matrix data will be deallocated when no one points to it;
 +   if you want to release the data pointed by a matrix header before the matrix destructor is called,
 +   use cv::Mat::release().
 +
 +   The next important thing to learn about the matrix class is element access. Here is how the matrix is stored.
 +   The elements are stored in row-major order (row by row). The cv::Mat::data member points to the first element of the first row,
 +   cv::Mat::rows contains the number of matrix rows and cv::Mat::cols - the number of matrix columns. There is yet another member,
 +   cv::Mat::step that is used to actually compute address of a matrix element. cv::Mat::step is needed because the matrix can be
 +   a part of another matrix or because there can some padding space in the end of each row for a proper alignment.
 +
 +   \image html roi.png
 +
 +   Given these parameters, address of the matrix element M_{ij} is computed as following:
 +
 +   addr(M_{ij})=M.data + M.step*i + j*M.elemSize()
 +
 +   if you know the matrix element type, e.g. it is float, then you can use cv::Mat::at() method:
 +
 +   addr(M_{ij})=&M.at<float>(i,j)
 +
 +   (where & is used to convert the reference returned by cv::Mat::at() to a pointer).
 +   if you need to process a whole row of matrix, the most efficient way is to get
 +   the pointer to the row first, and then just use plain C operator []:
 +
 +   \code
 +   // compute sum of positive matrix elements
 +   // (assuming that M is double-precision matrix)
 +   double sum=0;
 +   for(int i = 0; i < M.rows; i++)
 +   {
 +       const double* Mi = M.ptr<double>(i);
 +       for(int j = 0; j < M.cols; j++)
 +           sum += std::max(Mi[j], 0.);
 +   }
 +   \endcode
 +
 +   Some operations, like the above one, do not actually depend on the matrix shape,
 +   they just process elements of a matrix one by one (or elements from multiple matrices
 +   that are sitting in the same place, e.g. matrix addition). Such operations are called
 +   element-wise and it makes sense to check whether all the input/output matrices are continuous,
 +   i.e. have no gaps in the end of each row, and if yes, process them as a single long row:
 +
 +   \code
 +   // compute sum of positive matrix elements, optimized variant
 +   double sum=0;
 +   int cols = M.cols, rows = M.rows;
 +   if(M.isContinuous())
 +   {
 +       cols *= rows;
 +       rows = 1;
 +   }
 +   for(int i = 0; i < rows; i++)
 +   {
 +       const double* Mi = M.ptr<double>(i);
 +       for(int j = 0; j < cols; j++)
 +           sum += std::max(Mi[j], 0.);
 +   }
 +   \endcode
 +   in the case of continuous matrix the outer loop body will be executed just once,
 +   so the overhead will be smaller, which will be especially noticeable in the case of small matrices.
 +
 +   Finally, there are STL-style iterators that are smart enough to skip gaps between successive rows:
 +   \code
 +   // compute sum of positive matrix elements, iterator-based variant
 +   double sum=0;
 +   MatConstIterator_<double> it = M.begin<double>(), it_end = M.end<double>();
 +   for(; it != it_end; ++it)
 +       sum += std::max(*it, 0.);
 +   \endcode
 +
 +   The matrix iterators are random-access iterators, so they can be passed
 +   to any STL algorithm, including std::sort().
 +*/
 +class CV_EXPORTS Mat
  {
 -    CV_DbgAssert( dims >= 3 && data &&
 -                  (unsigned)i0 < (unsigned)size.p[0] &&
 -                  (unsigned)i1 < (unsigned)size.p[1] &&
 -                  (unsigned)i2 < (unsigned)size.p[2] );
 -    return (_Tp*)(data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2]);
 -}
 -
 -template<typename _Tp> inline const _Tp* Mat::ptr(int i0, int i1, int i2) const
 -{
 -    CV_DbgAssert( dims >= 3 && data &&
 -                  (unsigned)i0 < (unsigned)size.p[0] &&
 -                  (unsigned)i1 < (unsigned)size.p[1] &&
 -                  (unsigned)i2 < (unsigned)size.p[2] );
 -    return (const _Tp*)(data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2]);
 -}
 -
 -inline uchar* Mat::ptr(const int* idx)
 -{
 -    int i, d = dims;
 -    uchar* p = data;
 -    CV_DbgAssert( d >= 1 && p );
 -    for( i = 0; i < d; i++ )
 +public:
 +    //! default constructor
 +    Mat();
 +    //! constructs 2D matrix of the specified size and type
 +    // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
 +    Mat(int rows, int cols, int type);
 +    Mat(Size size, int type);
 +    //! constucts 2D matrix and fills it with the specified value _s.
 +    Mat(int rows, int cols, int type, const Scalar& s);
 +    Mat(Size size, int type, const Scalar& s);
 +
 +    //! constructs n-dimensional matrix
 +    Mat(int ndims, const int* sizes, int type);
 +    Mat(int ndims, const int* sizes, int type, const Scalar& s);
 +
 +    //! copy constructor
 +    Mat(const Mat& m);
 +    //! constructor for matrix headers pointing to user-allocated data
 +    Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP);
 +    Mat(Size size, int type, void* data, size_t step=AUTO_STEP);
 +    Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0);
 +
 +    //! creates a matrix header for a part of the bigger matrix
 +    Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all());
 +    Mat(const Mat& m, const Rect& roi);
 +    Mat(const Mat& m, const Range* ranges);
 +    //! builds matrix from std::vector with or without copying the data
 +    template<typename _Tp> explicit Mat(const std::vector<_Tp>& vec, bool copyData=false);
 +    //! builds matrix from cv::Vec; the data is copied by default
 +    template<typename _Tp, int n> explicit Mat(const Vec<_Tp, n>& vec, bool copyData=true);
 +    //! builds matrix from cv::Matx; the data is copied by default
 +    template<typename _Tp, int m, int n> explicit Mat(const Matx<_Tp, m, n>& mtx, bool copyData=true);
 +    //! builds matrix from a 2D point
 +    template<typename _Tp> explicit Mat(const Point_<_Tp>& pt, bool copyData=true);
 +    //! builds matrix from a 3D point
 +    template<typename _Tp> explicit Mat(const Point3_<_Tp>& pt, bool copyData=true);
 +    //! builds matrix from comma initializer
 +    template<typename _Tp> explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer);
 +
 +    // //! converts old-style CvMat to the new matrix; the data is not copied by default
 +    // Mat(const CvMat* m, bool copyData=false);
 +    // //! converts old-style CvMatND to the new matrix; the data is not copied by default
 +    // Mat(const CvMatND* m, bool copyData=false);
 +    // //! converts old-style IplImage to the new matrix; the data is not copied by default
 +    // Mat(const IplImage* img, bool copyData=false);
 +    //Mat(const void* img, bool copyData=false);
 +
 +    //! download data from GpuMat
 +    explicit Mat(const gpu::GpuMat& m);
 +
 +    //! destructor - calls release()
 +    ~Mat();
 +    //! assignment operators
 +    Mat& operator = (const Mat& m);
 +    Mat& operator = (const MatExpr& expr);
 +
 +    //! returns a new matrix header for the specified row
 +    Mat row(int y) const;
 +    //! returns a new matrix header for the specified column
 +    Mat col(int x) const;
 +    //! ... for the specified row span
 +    Mat rowRange(int startrow, int endrow) const;
 +    Mat rowRange(const Range& r) const;
 +    //! ... for the specified column span
 +    Mat colRange(int startcol, int endcol) const;
 +    Mat colRange(const Range& r) const;
 +    //! ... for the specified diagonal
 +    // (d=0 - the main diagonal,
 +    //  >0 - a diagonal from the lower half,
 +    //  <0 - a diagonal from the upper half)
 +    Mat diag(int d=0) const;
 +    //! constructs a square diagonal matrix which main diagonal is vector "d"
 +    static Mat diag(const Mat& d);
 +
 +    //! returns deep copy of the matrix, i.e. the data is copied
 +    Mat clone() const;
 +    //! copies the matrix content to "m".
 +    // It calls m.create(this->size(), this->type()).
 +    void copyTo( OutputArray m ) const;
 +    //! copies those matrix elements to "m" that are marked with non-zero mask elements.
 +    void copyTo( OutputArray m, InputArray mask ) const;
 +    //! converts matrix to another datatype with optional scalng. See cvConvertScale.
 +    void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;
 +
 +    void assignTo( Mat& m, int type=-1 ) const;
 +
 +    //! sets every matrix element to s
 +    Mat& operator = (const Scalar& s);
 +    //! sets some of the matrix elements to s, according to the mask
 +    Mat& setTo(InputArray value, InputArray mask=noArray());
 +    //! creates alternative matrix header for the same data, with different
 +    // number of channels and/or different number of rows. see cvReshape.
 +    Mat reshape(int cn, int rows=0) const;
 +    Mat reshape(int cn, int newndims, const int* newsz) const;
 +
 +    //! matrix transposition by means of matrix expressions
 +    MatExpr t() const;
 +    //! matrix inversion by means of matrix expressions
 +    MatExpr inv(int method=DECOMP_LU) const;
 +    //! per-element matrix multiplication by means of matrix expressions
 +    MatExpr mul(InputArray m, double scale=1) const;
 +
 +    //! computes cross-product of 2 3D vectors
 +    Mat cross(InputArray m) const;
 +    //! computes dot-product
 +    double dot(InputArray m) const;
 +
 +    //! Matlab-style matrix initialization
 +    static MatExpr zeros(int rows, int cols, int type);
 +    static MatExpr zeros(Size size, int type);
 +    static MatExpr zeros(int ndims, const int* sz, int type);
 +    static MatExpr ones(int rows, int cols, int type);
 +    static MatExpr ones(Size size, int type);
 +    static MatExpr ones(int ndims, const int* sz, int type);
 +    static MatExpr eye(int rows, int cols, int type);
 +    static MatExpr eye(Size size, int type);
 +
 +    //! allocates new matrix data unless the matrix already has specified size and type.
 +    // previous data is unreferenced if needed.
 +    void create(int rows, int cols, int type);
 +    void create(Size size, int type);
 +    void create(int ndims, const int* sizes, int type);
 +
 +    //! increases the reference counter; use with care to avoid memleaks
 +    void addref();
 +    //! decreases reference counter;
 +    // deallocates the data when reference counter reaches 0.
 +    void release();
 +
 +    //! deallocates the matrix data
 +    void deallocate();
 +    //! internal use function; properly re-allocates _size, _step arrays
 +    void copySize(const Mat& m);
 +
 +    //! reserves enough space to fit sz hyper-planes
 +    void reserve(size_t sz);
 +    //! resizes matrix to the specified number of hyper-planes
 +    void resize(size_t sz);
 +    //! resizes matrix to the specified number of hyper-planes; initializes the newly added elements
 +    void resize(size_t sz, const Scalar& s);
 +    //! internal function
 +    void push_back_(const void* elem);
 +    //! adds element to the end of 1d matrix (or possibly multiple elements when _Tp=Mat)
 +    template<typename _Tp> void push_back(const _Tp& elem);
 +    template<typename _Tp> void push_back(const Mat_<_Tp>& elem);
 +    void push_back(const Mat& m);
 +    //! removes several hyper-planes from bottom of the matrix
 +    void pop_back(size_t nelems=1);
 +
 +    //! locates matrix header within a parent matrix. See below
 +    void locateROI( Size& wholeSize, Point& ofs ) const;
 +    //! moves/resizes the current matrix ROI inside the parent matrix.
 +    Mat& adjustROI( int dtop, int dbottom, int dleft, int dright );
 +    //! extracts a rectangular sub-matrix
 +    // (this is a generalized form of row, rowRange etc.)
 +    Mat operator()( Range rowRange, Range colRange ) const;
 +    Mat operator()( const Rect& roi ) const;
 +    Mat operator()( const Range* ranges ) const;
 +
 +    // //! converts header to CvMat; no data is copied
 +    // operator CvMat() const;
 +    // //! converts header to CvMatND; no data is copied
 +    // operator CvMatND() const;
 +    // //! converts header to IplImage; no data is copied
 +    // operator IplImage() const;
 +
 +    template<typename _Tp> operator std::vector<_Tp>() const;
 +    template<typename _Tp, int n> operator Vec<_Tp, n>() const;
 +    template<typename _Tp, int m, int n> operator Matx<_Tp, m, n>() const;
 +
 +    //! returns true iff the matrix data is continuous
 +    // (i.e. when there are no gaps between successive rows).
 +    // similar to CV_IS_MAT_CONT(cvmat->type)
 +    bool isContinuous() const;
 +
 +    //! returns true if the matrix is a submatrix of another matrix
 +    bool isSubmatrix() const;
 +
 +    //! returns element size in bytes,
 +    // similar to CV_ELEM_SIZE(cvmat->type)
 +    size_t elemSize() const;
 +    //! returns the size of element channel in bytes.
 +    size_t elemSize1() const;
 +    //! returns element type, similar to CV_MAT_TYPE(cvmat->type)
 +    int type() const;
 +    //! returns element type, similar to CV_MAT_DEPTH(cvmat->type)
 +    int depth() const;
 +    //! returns element type, similar to CV_MAT_CN(cvmat->type)
 +    int channels() const;
 +    //! returns step/elemSize1()
 +    size_t step1(int i=0) const;
 +    //! returns true if matrix data is NULL
 +    bool empty() const;
 +    //! returns the total number of matrix elements
 +    size_t total() const;
 +
 +    //! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise
 +    int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const;
 +
 +    //! returns pointer to i0-th submatrix along the dimension #0
 +    uchar* ptr(int i0=0);
 +    const uchar* ptr(int i0=0) const;
 +
 +    //! returns pointer to (i0,i1) submatrix along the dimensions #0 and #1
 +    uchar* ptr(int i0, int i1);
 +    const uchar* ptr(int i0, int i1) const;
 +
 +    //! returns pointer to (i0,i1,i3) submatrix along the dimensions #0, #1, #2
 +    uchar* ptr(int i0, int i1, int i2);
 +    const uchar* ptr(int i0, int i1, int i2) const;
 +
 +    //! returns pointer to the matrix element
 +    uchar* ptr(const int* idx);
 +    //! returns read-only pointer to the matrix element
 +    const uchar* ptr(const int* idx) const;
 +
 +    template<int n> uchar* ptr(const Vec<int, n>& idx);
 +    template<int n> const uchar* ptr(const Vec<int, n>& idx) const;
 +
 +    //! template version of the above method
 +    template<typename _Tp> _Tp* ptr(int i0=0);
 +    template<typename _Tp> const _Tp* ptr(int i0=0) const;
 +
 +    template<typename _Tp> _Tp* ptr(int i0, int i1);
 +    template<typename _Tp> const _Tp* ptr(int i0, int i1) const;
 +
 +    template<typename _Tp> _Tp* ptr(int i0, int i1, int i2);
 +    template<typename _Tp> const _Tp* ptr(int i0, int i1, int i2) const;
 +
 +    template<typename _Tp> _Tp* ptr(const int* idx);
 +    template<typename _Tp> const _Tp* ptr(const int* idx) const;
 +
 +    template<typename _Tp, int n> _Tp* ptr(const Vec<int, n>& idx);
 +    template<typename _Tp, int n> const _Tp* ptr(const Vec<int, n>& idx) const;
 +
 +    //! the same as above, with the pointer dereferencing
 +    template<typename _Tp> _Tp& at(int i0=0);
 +    template<typename _Tp> const _Tp& at(int i0=0) const;
 +
 +    template<typename _Tp> _Tp& at(int i0, int i1);
 +    template<typename _Tp> const _Tp& at(int i0, int i1) const;
 +
 +    template<typename _Tp> _Tp& at(int i0, int i1, int i2);
 +    template<typename _Tp> const _Tp& at(int i0, int i1, int i2) const;
 +
 +    template<typename _Tp> _Tp& at(const int* idx);
 +    template<typename _Tp> const _Tp& at(const int* idx) const;
 +
 +    template<typename _Tp, int n> _Tp& at(const Vec<int, n>& idx);
 +    template<typename _Tp, int n> const _Tp& at(const Vec<int, n>& idx) const;
 +
 +    //! special versions for 2D arrays (especially convenient for referencing image pixels)
 +    template<typename _Tp> _Tp& at(Point pt);
 +    template<typename _Tp> const _Tp& at(Point pt) const;
 +
 +    //! template methods for iteration over matrix elements.
 +    // the iterators take care of skipping gaps in the end of rows (if any)
 +    template<typename _Tp> MatIterator_<_Tp> begin();
 +    template<typename _Tp> MatIterator_<_Tp> end();
 +    template<typename _Tp> MatConstIterator_<_Tp> begin() const;
 +    template<typename _Tp> MatConstIterator_<_Tp> end() const;
 +
 +    enum { MAGIC_VAL=0x42FF0000, AUTO_STEP=0, CONTINUOUS_FLAG=CV_MAT_CONT_FLAG, SUBMATRIX_FLAG=CV_SUBMAT_FLAG };
 +    enum { MAGIC_MASK=0xFFFF0000, TYPE_MASK=0x00000FFF, DEPTH_MASK=7 };
 +
 +    /*! includes several bit-fields:
 +         - the magic signature
 +         - continuity flag
 +         - depth
 +         - number of channels
 +     */
 +    int flags;
 +    //! the matrix dimensionality, >= 2
 +    int dims;
 +    //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
 +    int rows, cols;
 +    //! pointer to the data
 +    uchar* data;
 +
 +    //! pointer to the reference counter;
 +    // when matrix points to user-allocated data, the pointer is NULL
 +    int* refcount;
 +
 +    //! helper fields used in locateROI and adjustROI
 +    uchar* datastart;
 +    uchar* dataend;
 +    uchar* datalimit;
 +
 +    //! custom allocator
 +    MatAllocator* allocator;
 +
 +    struct CV_EXPORTS MSize
      {
 -        CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
 -        p += idx[i]*step.p[i];
 -    }
 -    return p;
 -}
 -
 -inline const uchar* Mat::ptr(const int* idx) const
 -{
 -    int i, d = dims;
 -    uchar* p = data;
 -    CV_DbgAssert( d >= 1 && p );
 -    for( i = 0; i < d; i++ )
 +        MSize(int* _p);
 +        Size operator()() const;
 +        const int& operator[](int i) const;
 +        int& operator[](int i);
 +        operator const int*() const;
 +        bool operator == (const MSize& sz) const;
 +        bool operator != (const MSize& sz) const;
 +
 +        int* p;
 +    };
 +
 +    struct CV_EXPORTS MStep
      {
 -        CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
 -        p += idx[i]*step.p[i];
 -    }
 -    return p;
 -}
 -
 -template<typename _Tp> inline _Tp& Mat::at(int i0, int i1)
 -{
 -    CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
 -        (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
 -        CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
 -    return ((_Tp*)(data + step.p[0]*i0))[i1];
 -}
 -
 -template<typename _Tp> inline const _Tp& Mat::at(int i0, int i1) const
 -{
 -    CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
 -        (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
 -        CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
 -    return ((const _Tp*)(data + step.p[0]*i0))[i1];
 -}
 -
 -template<typename _Tp> inline _Tp& Mat::at(Point pt)
 -{
 -    CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
 -        (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
 -        CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
 -    return ((_Tp*)(data + step.p[0]*pt.y))[pt.x];
 -}
 -
 -template<typename _Tp> inline const _Tp& Mat::at(Point pt) const
 -{
 -    CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
 -        (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
 -        CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
 -    return ((const _Tp*)(data + step.p[0]*pt.y))[pt.x];
 -}
 -
 -template<typename _Tp> inline _Tp& Mat::at(int i0)
 -{
 -    CV_DbgAssert( dims <= 2 && data &&
 -                 (unsigned)i0 < (unsigned)(size.p[0]*size.p[1]) &&
 -                 elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
 -    if( isContinuous() || size.p[0] == 1 )
 -        return ((_Tp*)data)[i0];
 -    if( size.p[1] == 1 )
 -        return *(_Tp*)(data + step.p[0]*i0);
 -    int i = i0/cols, j = i0 - i*cols;
 -    return ((_Tp*)(data + step.p[0]*i))[j];
 -}
 -
 -template<typename _Tp> inline const _Tp& Mat::at(int i0) const
 -{
 -    CV_DbgAssert( dims <= 2 && data &&
 -                 (unsigned)i0 < (unsigned)(size.p[0]*size.p[1]) &&
 -                 elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
 -    if( isContinuous() || size.p[0] == 1 )
 -        return ((const _Tp*)data)[i0];
 -    if( size.p[1] == 1 )
 -        return *(const _Tp*)(data + step.p[0]*i0);
 -    int i = i0/cols, j = i0 - i*cols;
 -    return ((const _Tp*)(data + step.p[0]*i))[j];
 -}
 -
 -template<typename _Tp> inline _Tp& Mat::at(int i0, int i1, int i2)
 -{
 -    CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
 -    return *(_Tp*)ptr(i0, i1, i2);
 -}
 -template<typename _Tp> inline const _Tp& Mat::at(int i0, int i1, int i2) const
 -{
 -    CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
 -    return *(const _Tp*)ptr(i0, i1, i2);
 -}
 -template<typename _Tp> inline _Tp& Mat::at(const int* idx)
 -{
 -    CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
 -    return *(_Tp*)ptr(idx);
 -}
 -template<typename _Tp> inline const _Tp& Mat::at(const int* idx) const
 -{
 -    CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
 -    return *(const _Tp*)ptr(idx);
 -}
 -template<typename _Tp, int n> _Tp& Mat::at(const Vec<int, n>& idx)
 -{
 -    CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
 -    return *(_Tp*)ptr(idx.val);
 -}
 -template<typename _Tp, int n> inline const _Tp& Mat::at(const Vec<int, n>& idx) const
 -{
 -    CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
 -    return *(const _Tp*)ptr(idx.val);
 -}
 -
 -
 -template<typename _Tp> inline MatConstIterator_<_Tp> Mat::begin() const
 -{
 -    CV_DbgAssert( elemSize() == sizeof(_Tp) );
 -    return MatConstIterator_<_Tp>((const Mat_<_Tp>*)this);
 -}
 -
 -template<typename _Tp> inline MatConstIterator_<_Tp> Mat::end() const
 -{
 -    CV_DbgAssert( elemSize() == sizeof(_Tp) );
 -    MatConstIterator_<_Tp> it((const Mat_<_Tp>*)this);
 -    it += total();
 -    return it;
 -}
 -
 -template<typename _Tp> inline MatIterator_<_Tp> Mat::begin()
 -{
 -    CV_DbgAssert( elemSize() == sizeof(_Tp) );
 -    return MatIterator_<_Tp>((Mat_<_Tp>*)this);
 -}
 +        MStep();
 +        MStep(size_t s);
 +        const size_t& operator[](int i) const;
 +        size_t& operator[](int i);
 +        operator size_t() const;
 +        MStep& operator = (size_t s);
 +
 +        size_t* p;
 +        size_t buf[2];
 +    protected:
 +        MStep& operator = (const MStep&);
 +    };
 +
 +    MSize size;
 +    MStep step;
 +
 +protected:
 +};
  
 -template<typename _Tp> inline MatIterator_<_Tp> Mat::end()
 -{
 -    CV_DbgAssert( elemSize() == sizeof(_Tp) );
 -    MatIterator_<_Tp> it((Mat_<_Tp>*)this);
 -    it += total();
 -    return it;
 -}
  
 -template<typename _Tp> inline Mat::operator vector<_Tp>() const
 -{
 -    vector<_Tp> v;
 -    copyTo(v);
 -    return v;
 -}
 +///////////////////////////////// Mat_<_Tp> ////////////////////////////////////
  
 -template<typename _Tp, int n> inline Mat::operator Vec<_Tp, n>() const
 +/*!
 + Template matrix class derived from Mat
 +
 + The class Mat_ is a "thin" template wrapper on top of cv::Mat. It does not have any extra data fields,
 + nor it or cv::Mat have any virtual methods and thus references or pointers to these two classes
 + can be safely converted one to another. But do it with care, for example:
 +
 + \code
 + // create 100x100 8-bit matrix
 + Mat M(100,100,CV_8U);
 + // this will compile fine. no any data conversion will be done.
 + Mat_<float>& M1 = (Mat_<float>&)M;
 + // the program will likely crash at the statement below
 + M1(99,99) = 1.f;
 + \endcode
 +
 + While cv::Mat is sufficient in most cases, cv::Mat_ can be more convenient if you use a lot of element
 + access operations and if you know matrix type at compile time.
 + Note that cv::Mat::at<_Tp>(int y, int x) and cv::Mat_<_Tp>::operator ()(int y, int x) do absolutely the
 + same thing and run at the same speed, but the latter is certainly shorter:
 +
 + \code
 + Mat_<double> M(20,20);
 + for(int i = 0; i < M.rows; i++)
 +    for(int j = 0; j < M.cols; j++)
 +       M(i,j) = 1./(i+j+1);
 + Mat E, V;
 + eigen(M,E,V);
 + cout << E.at<double>(0,0)/E.at<double>(M.rows-1,0);
 + \endcode
 +
 + It is easy to use Mat_ for multi-channel images/matrices - just pass cv::Vec as cv::Mat_ template parameter:
 +
 + \code
 + // allocate 320x240 color image and fill it with green (in RGB space)
 + Mat_<Vec3b> img(240, 320, Vec3b(0,255,0));
 + // now draw a diagonal white line
 + for(int i = 0; i < 100; i++)
 +     img(i,i)=Vec3b(255,255,255);
 + // and now modify the 2nd (red) channel of each pixel
 + for(int i = 0; i < img.rows; i++)
 +    for(int j = 0; j < img.cols; j++)
 +       img(i,j)[2] ^= (uchar)(i ^ j); // img(y,x)[c] accesses c-th channel of the pixel (x,y)
 + \endcode
 +*/
 +template<typename _Tp> class CV_EXPORTS Mat_ : public Mat
  {
 -    CV_Assert( data && dims <= 2 && (rows == 1 || cols == 1) &&
 -               rows + cols - 1 == n && channels() == 1 );
 -
 -    if( isContinuous() && type() == DataType<_Tp>::type )
 -        return Vec<_Tp, n>((_Tp*)data);
 -    Vec<_Tp, n> v; Mat tmp(rows, cols, DataType<_Tp>::type, v.val);
 -    convertTo(tmp, tmp.type());
 -    return v;
 -}
 +public:
 +    typedef _Tp value_type;
 +    typedef typename DataType<_Tp>::channel_type channel_type;
 +    typedef MatIterator_<_Tp> iterator;
 +    typedef MatConstIterator_<_Tp> const_iterator;
 +
 +    //! default constructor
 +    Mat_();
 +    //! equivalent to Mat(_rows, _cols, DataType<_Tp>::type)
 +    Mat_(int _rows, int _cols);
 +    //! constructor that sets each matrix element to specified value
 +    Mat_(int _rows, int _cols, const _Tp& value);
 +    //! equivalent to Mat(_size, DataType<_Tp>::type)
 +    explicit Mat_(Size _size);
 +    //! constructor that sets each matrix element to specified value
 +    Mat_(Size _size, const _Tp& value);
 +    //! n-dim array constructor
 +    Mat_(int _ndims, const int* _sizes);
 +    //! n-dim array constructor that sets each matrix element to specified value
 +    Mat_(int _ndims, const int* _sizes, const _Tp& value);
 +    //! copy/conversion contructor. If m is of different type, it's converted
 +    Mat_(const Mat& m);
 +    //! copy constructor
 +    Mat_(const Mat_& m);
 +    //! constructs a matrix on top of user-allocated data. step is in bytes(!!!), regardless of the type
 +    Mat_(int _rows, int _cols, _Tp* _data, size_t _step=AUTO_STEP);
 +    //! constructs n-dim matrix on top of user-allocated data. steps are in bytes(!!!), regardless of the type
 +    Mat_(int _ndims, const int* _sizes, _Tp* _data, const size_t* _steps=0);
 +    //! selects a submatrix
 +    Mat_(const Mat_& m, const Range& rowRange, const Range& colRange=Range::all());
 +    //! selects a submatrix
 +    Mat_(const Mat_& m, const Rect& roi);
 +    //! selects a submatrix, n-dim version
 +    Mat_(const Mat_& m, const Range* ranges);
 +    //! from a matrix expression
 +    explicit Mat_(const MatExpr& e);
 +    //! makes a matrix out of Vec, std::vector, Point_ or Point3_. The matrix will have a single column
 +    explicit Mat_(const std::vector<_Tp>& vec, bool copyData=false);
 +    template<int n> explicit Mat_(const Vec<typename DataType<_Tp>::channel_type, n>& vec, bool copyData=true);
 +    template<int m, int n> explicit Mat_(const Matx<typename DataType<_Tp>::channel_type, m, n>& mtx, bool copyData=true);
 +    explicit Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData=true);
 +    explicit Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData=true);
 +    explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer);
 +
 +    Mat_& operator = (const Mat& m);
 +    Mat_& operator = (const Mat_& m);
 +    //! set all the elements to s.
 +    Mat_& operator = (const _Tp& s);
 +    //! assign a matrix expression
 +    Mat_& operator = (const MatExpr& e);
 +
 +    //! iterators; they are smart enough to skip gaps in the end of rows
 +    iterator begin();
 +    iterator end();
 +    const_iterator begin() const;
 +    const_iterator end() const;
 +
 +    //! equivalent to Mat::create(_rows, _cols, DataType<_Tp>::type)
 +    void create(int _rows, int _cols);
 +    //! equivalent to Mat::create(_size, DataType<_Tp>::type)
 +    void create(Size _size);
 +    //! equivalent to Mat::create(_ndims, _sizes, DatType<_Tp>::type)
 +    void create(int _ndims, const int* _sizes);
 +    //! cross-product
 +    Mat_ cross(const Mat_& m) const;
 +    //! data type conversion
 +    template<typename T2> operator Mat_<T2>() const;
 +    //! overridden forms of Mat::row() etc.
 +    Mat_ row(int y) const;
 +    Mat_ col(int x) const;
 +    Mat_ diag(int d=0) const;
 +    Mat_ clone() const;
 +
 +    //! overridden forms of Mat::elemSize() etc.
 +    size_t elemSize() const;
 +    size_t elemSize1() const;
 +    int type() const;
 +    int depth() const;
 +    int channels() const;
 +    size_t step1(int i=0) const;
 +    //! returns step()/sizeof(_Tp)
 +    size_t stepT(int i=0) const;
 +
 +    //! overridden forms of Mat::zeros() etc. Data type is omitted, of course
 +    static MatExpr zeros(int rows, int cols);
 +    static MatExpr zeros(Size size);
 +    static MatExpr zeros(int _ndims, const int* _sizes);
 +    static MatExpr ones(int rows, int cols);
 +    static MatExpr ones(Size size);
 +    static MatExpr ones(int _ndims, const int* _sizes);
 +    static MatExpr eye(int rows, int cols);
 +    static MatExpr eye(Size size);
 +
 +    //! some more overriden methods
 +    Mat_& adjustROI( int dtop, int dbottom, int dleft, int dright );
 +    Mat_ operator()( const Range& rowRange, const Range& colRange ) const;
 +    Mat_ operator()( const Rect& roi ) const;
 +    Mat_ operator()( const Range* ranges ) const;
 +
 +    //! more convenient forms of row and element access operators
 +    _Tp* operator [](int y);
 +    const _Tp* operator [](int y) const;
 +
 +    //! returns reference to the specified element
 +    _Tp& operator ()(const int* idx);
 +    //! returns read-only reference to the specified element
 +    const _Tp& operator ()(const int* idx) const;
 +
 +    //! returns reference to the specified element
 +    template<int n> _Tp& operator ()(const Vec<int, n>& idx);
 +    //! returns read-only reference to the specified element
 +    template<int n> const _Tp& operator ()(const Vec<int, n>& idx) const;
 +
 +    //! returns reference to the specified element (1D case)
 +    _Tp& operator ()(int idx0);
 +    //! returns read-only reference to the specified element (1D case)
 +    const _Tp& operator ()(int idx0) const;
 +    //! returns reference to the specified element (2D case)
 +    _Tp& operator ()(int idx0, int idx1);
 +    //! returns read-only reference to the specified element (2D case)
 +    const _Tp& operator ()(int idx0, int idx1) const;
 +    //! returns reference to the specified element (3D case)
 +    _Tp& operator ()(int idx0, int idx1, int idx2);
 +    //! returns read-only reference to the specified element (3D case)
 +    const _Tp& operator ()(int idx0, int idx1, int idx2) const;
 +
 +    _Tp& operator ()(Point pt);
 +    const _Tp& operator ()(Point pt) const;
 +
 +    //! conversion to vector.
 +    operator std::vector<_Tp>() const;
 +    //! conversion to Vec
 +    template<int n> operator Vec<typename DataType<_Tp>::channel_type, n>() const;
 +    //! conversion to Matx
 +    template<int m, int n> operator Matx<typename DataType<_Tp>::channel_type, m, n>() const;
 +};
  
 -template<typename _Tp, int m, int n> inline Mat::operator Matx<_Tp, m, n>() const
 +typedef Mat_<uchar> Mat1b;
 +typedef Mat_<Vec2b> Mat2b;
 +typedef Mat_<Vec3b> Mat3b;
 +typedef Mat_<Vec4b> Mat4b;
 +
 +typedef Mat_<short> Mat1s;
 +typedef Mat_<Vec2s> Mat2s;
 +typedef Mat_<Vec3s> Mat3s;
 +typedef Mat_<Vec4s> Mat4s;
 +
 +typedef Mat_<ushort> Mat1w;
 +typedef Mat_<Vec2w> Mat2w;
 +typedef Mat_<Vec3w> Mat3w;
 +typedef Mat_<Vec4w> Mat4w;
 +
 +typedef Mat_<int>   Mat1i;
 +typedef Mat_<Vec2i> Mat2i;
 +typedef Mat_<Vec3i> Mat3i;
 +typedef Mat_<Vec4i> Mat4i;
 +
 +typedef Mat_<float> Mat1f;
 +typedef Mat_<Vec2f> Mat2f;
 +typedef Mat_<Vec3f> Mat3f;
 +typedef Mat_<Vec4f> Mat4f;
 +
 +typedef Mat_<double> Mat1d;
 +typedef Mat_<Vec2d> Mat2d;
 +typedef Mat_<Vec3d> Mat3d;
 +typedef Mat_<Vec4d> Mat4d;
 +
 +
 +
 +/////////////////////////// multi-dimensional sparse matrix //////////////////////////
 +
 +/*!
 + Sparse matrix class.
 +
 + The class represents multi-dimensional sparse numerical arrays. Such a sparse array can store elements
 + of any type that cv::Mat is able to store. "Sparse" means that only non-zero elements
 + are stored (though, as a result of some operations on a sparse matrix, some of its stored elements
 + can actually become 0. It's user responsibility to detect such elements and delete them using cv::SparseMat::erase().
 + The non-zero elements are stored in a hash table that grows when it's filled enough,
 + so that the search time remains O(1) in average. Elements can be accessed using the following methods:
 +
 + <ol>
 + <li>Query operations: cv::SparseMat::ptr() and the higher-level cv::SparseMat::ref(),
 +      cv::SparseMat::value() and cv::SparseMat::find, for example:
 + \code
 + const int dims = 5;
 + int size[] = {10, 10, 10, 10, 10};
 + SparseMat sparse_mat(dims, size, CV_32F);
 + for(int i = 0; i < 1000; i++)
 + {
 +     int idx[dims];
 +     for(int k = 0; k < dims; k++)
 +        idx[k] = rand()%sparse_mat.size(k);
 +     sparse_mat.ref<float>(idx) += 1.f;
 + }
 + \endcode
 +
 + <li>Sparse matrix iterators. Like cv::Mat iterators and unlike cv::Mat iterators, the sparse matrix iterators are STL-style,
 + that is, the iteration is done as following:
 + \code
 + // prints elements of a sparse floating-point matrix and the sum of elements.
 + SparseMatConstIterator_<float>
 +        it = sparse_mat.begin<float>(),
 +        it_end = sparse_mat.end<float>();
 + double s = 0;
 + int dims = sparse_mat.dims();
 + for(; it != it_end; ++it)
 + {
 +     // print element indices and the element value
 +     const Node* n = it.node();
 +     printf("(")
 +     for(int i = 0; i < dims; i++)
 +        printf("%3d%c", n->idx[i], i < dims-1 ? ',' : ')');
 +     printf(": %f\n", *it);
 +     s += *it;
 + }
 + printf("Element sum is %g\n", s);
 + \endcode
 + If you run this loop, you will notice that elements are enumerated
 + in no any logical order (lexicographical etc.),
 + they come in the same order as they stored in the hash table, i.e. semi-randomly.
 +
 + You may collect pointers to the nodes and sort them to get the proper ordering.
 + Note, however, that pointers to the nodes may become invalid when you add more
 + elements to the matrix; this is because of possible buffer reallocation.
 +
 + <li>A combination of the above 2 methods when you need to process 2 or more sparse
 + matrices simultaneously, e.g. this is how you can compute unnormalized
 + cross-correlation of the 2 floating-point sparse matrices:
 + \code
 + double crossCorr(const SparseMat& a, const SparseMat& b)
 + {
 +     const SparseMat *_a = &a, *_b = &b;
 +     // if b contains less elements than a,
 +     // it's faster to iterate through b
 +     if(_a->nzcount() > _b->nzcount())
 +        std::swap(_a, _b);
 +     SparseMatConstIterator_<float> it = _a->begin<float>(),
 +                                    it_end = _a->end<float>();
 +     double ccorr = 0;
 +     for(; it != it_end; ++it)
 +     {
 +         // take the next element from the first matrix
 +         float avalue = *it;
 +         const Node* anode = it.node();
 +         // and try to find element with the same index in the second matrix.
 +         // since the hash value depends only on the element index,
 +         // we reuse hashvalue stored in the node
 +         float bvalue = _b->value<float>(anode->idx,&anode->hashval);
 +         ccorr += avalue*bvalue;
 +     }
 +     return ccorr;
 + }
 + \endcode
 + </ol>
 +*/
 +class CV_EXPORTS SparseMat
  {
 -    CV_Assert( data && dims <= 2 && rows == m && cols == n && channels() == 1 );
 -
 -    if( isContinuous() && type() == DataType<_Tp>::type )
 -        return Matx<_Tp, m, n>((_Tp*)data);
 -    Matx<_Tp, m, n> mtx; Mat tmp(rows, cols, DataType<_Tp>::type, mtx.val);
 -    convertTo(tmp, tmp.type());
 -    return mtx;
 -}
 +public:
 +    typedef SparseMatIterator iterator;
 +    typedef SparseMatConstIterator const_iterator;
  
 +    enum { MAGIC_VAL=0x42FD0000, MAX_DIM=32, HASH_SCALE=0x5bd1e995, HASH_BIT=0x80000000 };
  
 -template<typename _Tp> inline void Mat::push_back(const _Tp& elem)
 -{
 -    if( !data )
 +    //! the sparse matrix header
 +    struct CV_EXPORTS Hdr
      {
 -        *this = Mat(1, 1, DataType<_Tp>::type, (void*)&elem).clone();
 -        return;
 -    }
 -    CV_Assert(DataType<_Tp>::type == type() && cols == 1
 -              /* && dims == 2 (cols == 1 implies dims == 2) */);
 -    uchar* tmp = dataend + step[0];
 -    if( !isSubmatrix() && isContinuous() && tmp <= datalimit )
 +        Hdr(int _dims, const int* _sizes, int _type);
 +        void clear();
 +        int refcount;
 +        int dims;
 +        int valueOffset;
 +        size_t nodeSize;
 +        size_t nodeCount;
 +        size_t freeList;
 +        std::vector<uchar> pool;
 +        std::vector<size_t> hashtab;
 +        int size[MAX_DIM];
 +    };
 +
 +    //! sparse matrix node - element of a hash table
 +    struct CV_EXPORTS Node
      {
 -        *(_Tp*)(data + (size.p[0]++)*step.p[0]) = elem;
 -        dataend = tmp;
 -    }
 -    else
 -        push_back_(&elem);
 -}
 -
 -template<typename _Tp> inline void Mat::push_back(const Mat_<_Tp>& m)
 -{
 -    push_back((const Mat&)m);
 -}
 -
 -inline Mat::MSize::MSize(int* _p) : p(_p) {}
 -inline Size Mat::MSize::operator()() const
 -{
 -    CV_DbgAssert(p[-1] <= 2);
 -    return Size(p[1], p[0]);
 -}
 -inline const int& Mat::MSize::operator[](int i) const { return p[i]; }
 -inline int& Mat::MSize::operator[](int i) { return p[i]; }
 -inline Mat::MSize::operator const int*() const { return p; }
 -
 -inline bool Mat::MSize::operator == (const MSize& sz) const
 -{
 -    int d = p[-1], dsz = sz.p[-1];
 -    if( d != dsz )
 -        return false;
 -    if( d == 2 )
 -        return p[0] == sz.p[0] && p[1] == sz.p[1];
 -
 -    for( int i = 0; i < d; i++ )
 -        if( p[i] != sz.p[i] )
 -            return false;
 -    return true;
 -}
 -
 -inline bool Mat::MSize::operator != (const MSize& sz) const
 -{
 -    return !(*this == sz);
 -}
 -
 -inline Mat::MStep::MStep() { p = buf; p[0] = p[1] = 0; }
 -inline Mat::MStep::MStep(size_t s) { p = buf; p[0] = s; p[1] = 0; }
 -inline const size_t& Mat::MStep::operator[](int i) const { return p[i]; }
 -inline size_t& Mat::MStep::operator[](int i) { return p[i]; }
 -inline Mat::MStep::operator size_t() const
 -{
 -    CV_DbgAssert( p == buf );
 -    return buf[0];
 -}
 -inline Mat::MStep& Mat::MStep::operator = (size_t s)
 -{
 -    CV_DbgAssert( p == buf );
 -    buf[0] = s;
 -    return *this;
 -}
 -
 -static inline Mat cvarrToMatND(const CvArr* arr, bool copyData=false, int coiMode=0)
 -{
 -    return cvarrToMat(arr, copyData, true, coiMode);
 -}
 -
 -///////////////////////////////////////////// SVD //////////////////////////////////////////////////////
 -
 -inline SVD::SVD() {}
 -inline SVD::SVD( InputArray m, int flags ) { operator ()(m, flags); }
 -inline void SVD::solveZ( InputArray m, OutputArray _dst )
 -{
 -    Mat mtx = m.getMat();
 -    SVD svd(mtx, (mtx.rows >= mtx.cols ? 0 : SVD::FULL_UV));
 -    _dst.create(svd.vt.cols, 1, svd.vt.type());
 -    Mat dst = _dst.getMat();
 -    svd.vt.row(svd.vt.rows-1).reshape(1,svd.vt.cols).copyTo(dst);
 -}
 -
 -template<typename _Tp, int m, int n, int nm> inline void
 -    SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt )
 -{
 -    assert( nm == MIN(m, n));
 -    Mat _a(a, false), _u(u, false), _w(w, false), _vt(vt, false);
 -    SVD::compute(_a, _w, _u, _vt);
 -    CV_Assert(_w.data == (uchar*)&w.val[0] && _u.data == (uchar*)&u.val[0] && _vt.data == (uchar*)&vt.val[0]);
 -}
 -
 -template<typename _Tp, int m, int n, int nm> inline void
 -SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w )
 -{
 -    assert( nm == MIN(m, n));
 -    Mat _a(a, false), _w(w, false);
 -    SVD::compute(_a, _w);
 -    CV_Assert(_w.data == (uchar*)&w.val[0]);
 -}
 -
 -template<typename _Tp, int m, int n, int nm, int nb> inline void
 -SVD::backSubst( const Matx<_Tp, nm, 1>& w, const Matx<_Tp, m, nm>& u,
 -                const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs,
 -                Matx<_Tp, n, nb>& dst )
 -{
 -    assert( nm == MIN(m, n));
 -    Mat _u(u, false), _w(w, false), _vt(vt, false), _rhs(rhs, false), _dst(dst, false);
 -    SVD::backSubst(_w, _u, _vt, _rhs, _dst);
 -    CV_Assert(_dst.data == (uchar*)&dst.val[0]);
 -}
 -
 -///////////////////////////////// Mat_<_Tp> ////////////////////////////////////
 -
 -template<typename _Tp> inline Mat_<_Tp>::Mat_()
 -    : Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; }
 -
 -template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols)
 -    : Mat(_rows, _cols, DataType<_Tp>::type) {}
 -
 -template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value)
 -    : Mat(_rows, _cols, DataType<_Tp>::type) { *this = value; }
 -
 -template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _sz)
 -    : Mat(_sz.height, _sz.width, DataType<_Tp>::type) {}
 -
 -template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _sz, const _Tp& value)
 -    : Mat(_sz.height, _sz.width, DataType<_Tp>::type) { *this = value; }
 -
 -template<typename _Tp> inline Mat_<_Tp>::Mat_(int _dims, const int* _sz)
 -    : Mat(_dims, _sz, DataType<_Tp>::type) {}
 -
 -template<typename _Tp> inline Mat_<_Tp>::Mat_(int _dims, const int* _sz, const _Tp& _s)
 -    : Mat(_dims, _sz, DataType<_Tp>::type, Scalar(_s)) {}
 -
 -template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const Range* ranges)
 -    : Mat(m, ranges) {}
 -
 -template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat& m)
 -    : Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; *this = m; }
 -
 -template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m)
 -    : Mat(m) {}
 -
 -template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t steps)
 -    : Mat(_rows, _cols, DataType<_Tp>::type, _data, steps) {}
 -
 -template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Range& _rowRange, const Range& _colRange)
 -    : Mat(m, _rowRange, _colRange) {}
 +        //! hash value
 +        size_t hashval;
 +        //! index of the next node in the same hash table entry
 +        size_t next;
 +        //! index of the matrix element
 +        int idx[MAX_DIM];
 +    };
 +
 +    //! default constructor
 +    SparseMat();
 +    //! creates matrix of the specified size and type
 +    SparseMat(int dims, const int* _sizes, int _type);
 +    //! copy constructor
 +    SparseMat(const SparseMat& m);
 +    //! converts dense 2d matrix to the sparse form
 +    /*!
 +     \param m the input matrix
 +     \param try1d if true and m is a single-column matrix (Nx1),
 +            then the sparse matrix will be 1-dimensional.
 +    */
 +    explicit SparseMat(const Mat& m);
 +    //! converts old-style sparse matrix to the new-style. All the data is copied
 +    //SparseMat(const CvSparseMat* m);
 +    //! the destructor
 +    ~SparseMat();
 +
 +    //! assignment operator. This is O(1) operation, i.e. no data is copied
 +    SparseMat& operator = (const SparseMat& m);
 +    //! equivalent to the corresponding constructor
 +    SparseMat& operator = (const Mat& m);
 +
 +    //! creates full copy of the matrix
 +    SparseMat clone() const;
 +
 +    //! copies all the data to the destination matrix. All the previous content of m is erased
 +    void copyTo( SparseMat& m ) const;
 +    //! converts sparse matrix to dense matrix.
 +    void copyTo( Mat& m ) const;
 +    //! multiplies all the matrix elements by the specified scale factor alpha and converts the results to the specified data type
 +    void convertTo( SparseMat& m, int rtype, double alpha=1 ) const;
 +    //! converts sparse matrix to dense n-dim matrix with optional type conversion and scaling.
 +    /*!
 +      \param rtype The output matrix data type. When it is =-1, the output array will have the same data type as (*this)
 +      \param alpha The scale factor
 +      \param beta The optional delta added to the scaled values before the conversion
 +    */
 +    void convertTo( Mat& m, int rtype, double alpha=1, double beta=0 ) const;
 +
 +    // not used now
 +    void assignTo( SparseMat& m, int type=-1 ) const;
 +
 +    //! reallocates sparse matrix.
 +    /*!
 +        If the matrix already had the proper size and type,
 +        it is simply cleared with clear(), otherwise,
 +        the old matrix is released (using release()) and the new one is allocated.
 +    */
 +    void create(int dims, const int* _sizes, int _type);
 +    //! sets all the sparse matrix elements to 0, which means clearing the hash table.
 +    void clear();
 +    //! manually increments the reference counter to the header.
 +    void addref();
 +    // decrements the header reference counter. When the counter reaches 0, the header and all the underlying data are deallocated.
 +    void release();
 +
 +    //! converts sparse matrix to the old-style representation; all the elements are copied.
 +    //operator CvSparseMat*() const;
 +    //! returns the size of each element in bytes (not including the overhead - the space occupied by SparseMat::Node elements)
 +    size_t elemSize() const;
 +    //! returns elemSize()/channels()
 +    size_t elemSize1() const;
 +
 +    //! returns type of sparse matrix elements
 +    int type() const;
 +    //! returns the depth of sparse matrix elements
 +    int depth() const;
 +    //! returns the number of channels
 +    int channels() const;
 +
 +    //! returns the array of sizes, or NULL if the matrix is not allocated
 +    const int* size() const;
 +    //! returns the size of i-th matrix dimension (or 0)
 +    int size(int i) const;
 +    //! returns the matrix dimensionality
 +    int dims() const;
 +    //! returns the number of non-zero elements (=the number of hash table nodes)
 +    size_t nzcount() const;
 +
 +    //! computes the element hash value (1D case)
 +    size_t hash(int i0) const;
 +    //! computes the element hash value (2D case)
 +    size_t hash(int i0, int i1) const;
 +    //! computes the element hash value (3D case)
 +    size_t hash(int i0, int i1, int i2) const;
 +    //! computes the element hash value (nD case)
 +    size_t hash(const int* idx) const;
 +
 +    //@{
 +    /*!
 +     specialized variants for 1D, 2D, 3D cases and the generic_type one for n-D case.
 +
 +     return pointer to the matrix element.
 +     <ul>
 +      <li>if the element is there (it's non-zero), the pointer to it is returned
 +      <li>if it's not there and createMissing=false, NULL pointer is returned
 +      <li>if it's not there and createMissing=true, then the new element
 +        is created and initialized with 0. Pointer to it is returned
 +      <li>if the optional hashval pointer is not NULL, the element hash value is
 +      not computed, but *hashval is taken instead.
 +     </ul>
 +    */
 +    //! returns pointer to the specified element (1D case)
 +    uchar* ptr(int i0, bool createMissing, size_t* hashval=0);
 +    //! returns pointer to the specified element (2D case)
 +    uchar* ptr(int i0, int i1, bool createMissing, size_t* hashval=0);
 +    //! returns pointer to the specified element (3D case)
 +    uchar* ptr(int i0, int i1, int i2, bool createMissing, size_t* hashval=0);
 +    //! returns pointer to the specified element (nD case)
 +    uchar* ptr(const int* idx, bool createMissing, size_t* hashval=0);
 +    //@}
 +
 +    //@{
 +    /*!
 +     return read-write reference to the specified sparse matrix element.
 +
 +     ref<_Tp>(i0,...[,hashval]) is equivalent to *(_Tp*)ptr(i0,...,true[,hashval]).
 +     The methods always return a valid reference.
 +     If the element did not exist, it is created and initialiazed with 0.
 +    */
 +    //! returns reference to the specified element (1D case)
 +    template<typename _Tp> _Tp& ref(int i0, size_t* hashval=0);
 +    //! returns reference to the specified element (2D case)
 +    template<typename _Tp> _Tp& ref(int i0, int i1, size_t* hashval=0);
 +    //! returns reference to the specified element (3D case)
 +    template<typename _Tp> _Tp& ref(int i0, int i1, int i2, size_t* hashval=0);
 +    //! returns reference to the specified element (nD case)
 +    template<typename _Tp> _Tp& ref(const int* idx, size_t* hashval=0);
 +    //@}
 +
 +    //@{
 +    /*!
 +     return value of the specified sparse matrix element.
 +
 +     value<_Tp>(i0,...[,hashval]) is equivalent
 +
 +     \code
 +     { const _Tp* p = find<_Tp>(i0,...[,hashval]); return p ? *p : _Tp(); }
 +     \endcode
 +
 +     That is, if the element did not exist, the methods return 0.
 +     */
 +    //! returns value of the specified element (1D case)
 +    template<typename _Tp> _Tp value(int i0, size_t* hashval=0) const;
 +    //! returns value of the specified element (2D case)
 +    template<typename _Tp> _Tp value(int i0, int i1, size_t* hashval=0) const;
 +    //! returns value of the specified element (3D case)
 +    template<typename _Tp> _Tp value(int i0, int i1, int i2, size_t* hashval=0) const;
 +    //! returns value of the specified element (nD case)
 +    template<typename _Tp> _Tp value(const int* idx, size_t* hashval=0) const;
 +    //@}
 +
 +    //@{
 +    /*!
 +     Return pointer to the specified sparse matrix element if it exists
 +
 +     find<_Tp>(i0,...[,hashval]) is equivalent to (_const Tp*)ptr(i0,...false[,hashval]).
 +
 +     If the specified element does not exist, the methods return NULL.
 +    */
 +    //! returns pointer to the specified element (1D case)
 +    template<typename _Tp> const _Tp* find(int i0, size_t* hashval=0) const;
 +    //! returns pointer to the specified element (2D case)
 +    template<typename _Tp> const _Tp* find(int i0, int i1, size_t* hashval=0) const;
 +    //! returns pointer to the specified element (3D case)
 +    template<typename _Tp> const _Tp* find(int i0, int i1, int i2, size_t* hashval=0) const;
 +    //! returns pointer to the specified element (nD case)
 +    template<typename _Tp> const _Tp* find(const int* idx, size_t* hashval=0) const;
 +
 +    //! erases the specified element (2D case)
 +    void erase(int i0, int i1, size_t* hashval=0);
 +    //! erases the specified element (3D case)
 +    void erase(int i0, int i1, int i2, size_t* hashval=0);
 +    //! erases the specified element (nD case)
 +    void erase(const int* idx, size_t* hashval=0);
 +
 +    //@{
 +    /*!
 +       return the sparse matrix iterator pointing to the first sparse matrix element
 +    */
 +    //! returns the sparse matrix iterator at the matrix beginning
 +    SparseMatIterator begin();
 +    //! returns the sparse matrix iterator at the matrix beginning
 +    template<typename _Tp> SparseMatIterator_<_Tp> begin();
 +    //! returns the read-only sparse matrix iterator at the matrix beginning
 +    SparseMatConstIterator begin() const;
 +    //! returns the read-only sparse matrix iterator at the matrix beginning
 +    template<typename _Tp> SparseMatConstIterator_<_Tp> begin() const;
 +    //@}
 +    /*!
 +       return the sparse matrix iterator pointing to the element following the last sparse matrix element
 +    */
 +    //! returns the sparse matrix iterator at the matrix end
 +    SparseMatIterator end();
 +    //! returns the read-only sparse matrix iterator at the matrix end
 +    SparseMatConstIterator end() const;
 +    //! returns the typed sparse matrix iterator at the matrix end
 +    template<typename _Tp> SparseMatIterator_<_Tp> end();
 +    //! returns the typed read-only sparse matrix iterator at the matrix end
 +    template<typename _Tp> SparseMatConstIterator_<_Tp> end() const;
 +
 +    //! returns the value stored in the sparse martix node
 +    template<typename _Tp> _Tp& value(Node* n);
 +    //! returns the value stored in the sparse martix node
 +    template<typename _Tp> const _Tp& value(const Node* n) const;
 +
 +    ////////////// some internal-use methods ///////////////
 +    Node* node(size_t nidx);
 +    const Node* node(size_t nidx) const;
 +
 +    uchar* newNode(const int* idx, size_t hashval);
 +    void removeNode(size_t hidx, size_t nidx, size_t previdx);
 +    void resizeHashTab(size_t newsize);
  
 -template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
 -    : Mat(m, roi) {}
 +    int flags;
 +    Hdr* hdr;
 +};
  
 -template<typename _Tp> template<int n> inline
 -    Mat_<_Tp>::Mat_(const Vec<typename DataType<_Tp>::channel_type, n>& vec, bool copyData)
 -    : Mat(n/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&vec)
 -{
 -    CV_Assert(n%DataType<_Tp>::channels == 0);
 -    if( copyData )
 -        *this = clone();
 -}
 -
 -template<typename _Tp> template<int m, int n> inline
 -    Mat_<_Tp>::Mat_(const Matx<typename DataType<_Tp>::channel_type,m,n>& M, bool copyData)
 -    : Mat(m, n/DataType<_Tp>::channels, DataType<_Tp>::type, (void*)&M)
 -{
 -    CV_Assert(n % DataType<_Tp>::channels == 0);
 -    if( copyData )
 -        *this = clone();
 -}
  
 -template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
 -    : Mat(2/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
 -{
 -    CV_Assert(2 % DataType<_Tp>::channels == 0);
 -    if( copyData )
 -        *this = clone();
 -}
  
 -template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
 -    : Mat(3/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
 -{
 -    CV_Assert(3 % DataType<_Tp>::channels == 0);
 -    if( copyData )
 -        *this = clone();
 -}
 +///////////////////////////////// SparseMat_<_Tp> ////////////////////////////////////
  
 -template<typename _Tp> inline Mat_<_Tp>::Mat_(const MatCommaInitializer_<_Tp>& commaInitializer)
 -    : Mat(commaInitializer) {}
 +/*!
 + The Template Sparse Matrix class derived from cv::SparseMat
  
 -template<typename _Tp> inline Mat_<_Tp>::Mat_(const vector<_Tp>& vec, bool copyData)
 -    : Mat(vec, copyData) {}
 + The class provides slightly more convenient operations for accessing elements.
  
 -template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m)
 -{
 -    if( DataType<_Tp>::type == m.type() )
 -    {
 -        Mat::operator = (m);
 -        return *this;
 -    }
 -    if( DataType<_Tp>::depth == m.depth() )
 -    {
 -        return (*this = m.reshape(DataType<_Tp>::channels, m.dims, 0));
 -    }
 -    CV_DbgAssert(DataType<_Tp>::channels == m.channels());
 -    m.convertTo(*this, type());
 -    return *this;
 -}
 -
 -template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat_& m)
 + \code
 + SparseMat m;
 + ...
 + SparseMat_<int> m_ = (SparseMat_<int>&)m;
 + m_.ref(1)++; // equivalent to m.ref<int>(1)++;
 + m_.ref(2) += m_(3); // equivalent to m.ref<int>(2) += m.value<int>(3);
 + \endcode
 +*/
 +template<typename _Tp> class CV_EXPORTS SparseMat_ : public SparseMat
  {
 -    Mat::operator=(m);
 -    return *this;
 -}
 +public:
 +    typedef SparseMatIterator_<_Tp> iterator;
 +    typedef SparseMatConstIterator_<_Tp> const_iterator;
 +
 +    //! the default constructor
 +    SparseMat_();
 +    //! the full constructor equivelent to SparseMat(dims, _sizes, DataType<_Tp>::type)
 +    SparseMat_(int dims, const int* _sizes);
 +    //! the copy constructor. If DataType<_Tp>.type != m.type(), the m elements are converted
 +    SparseMat_(const SparseMat& m);
 +    //! the copy constructor. This is O(1) operation - no data is copied
 +    SparseMat_(const SparseMat_& m);
 +    //! converts dense matrix to the sparse form
 +    SparseMat_(const Mat& m);
 +    //! converts the old-style sparse matrix to the C++ class. All the elements are copied
 +    //SparseMat_(const CvSparseMat* m);
 +    //! the assignment operator. If DataType<_Tp>.type != m.type(), the m elements are converted
 +    SparseMat_& operator = (const SparseMat& m);
 +    //! the assignment operator. This is O(1) operation - no data is copied
 +    SparseMat_& operator = (const SparseMat_& m);
 +    //! converts dense matrix to the sparse form
 +    SparseMat_& operator = (const Mat& m);
 +
 +    //! makes full copy of the matrix. All the elements are duplicated
 +    SparseMat_ clone() const;
 +    //! equivalent to cv::SparseMat::create(dims, _sizes, DataType<_Tp>::type)
 +    void create(int dims, const int* _sizes);
 +    //! converts sparse matrix to the old-style CvSparseMat. All the elements are copied
 +    //operator CvSparseMat*() const;
 +
 +    //! returns type of the matrix elements
 +    int type() const;
 +    //! returns depth of the matrix elements
 +    int depth() const;
 +    //! returns the number of channels in each matrix element
 +    int channels() const;
 +
 +    //! equivalent to SparseMat::ref<_Tp>(i0, hashval)
 +    _Tp& ref(int i0, size_t* hashval=0);
 +    //! equivalent to SparseMat::ref<_Tp>(i0, i1, hashval)
 +    _Tp& ref(int i0, int i1, size_t* hashval=0);
 +    //! equivalent to SparseMat::ref<_Tp>(i0, i1, i2, hashval)
 +    _Tp& ref(int i0, int i1, int i2, size_t* hashval=0);
 +    //! equivalent to SparseMat::ref<_Tp>(idx, hashval)
 +    _Tp& ref(const int* idx, size_t* hashval=0);
 +
 +    //! equivalent to SparseMat::value<_Tp>(i0, hashval)
 +    _Tp operator()(int i0, size_t* hashval=0) const;
 +    //! equivalent to SparseMat::value<_Tp>(i0, i1, hashval)
 +    _Tp operator()(int i0, int i1, size_t* hashval=0) const;
 +    //! equivalent to SparseMat::value<_Tp>(i0, i1, i2, hashval)
 +    _Tp operator()(int i0, int i1, int i2, size_t* hashval=0) const;
 +    //! equivalent to SparseMat::value<_Tp>(idx, hashval)
 +    _Tp operator()(const int* idx, size_t* hashval=0) const;
 +
 +    //! returns sparse matrix iterator pointing to the first sparse matrix element
 +    SparseMatIterator_<_Tp> begin();
 +    //! returns read-only sparse matrix iterator pointing to the first sparse matrix element
 +    SparseMatConstIterator_<_Tp> begin() const;
 +    //! returns sparse matrix iterator pointing to the element following the last sparse matrix element
 +    SparseMatIterator_<_Tp> end();
 +    //! returns read-only sparse matrix iterator pointing to the element following the last sparse matrix element
 +    SparseMatConstIterator_<_Tp> end() const;
 +};
  
 -template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const _Tp& s)
 -{
 -    typedef typename DataType<_Tp>::vec_type VT;
 -    Mat::operator=(Scalar((const VT&)s));
 -    return *this;
 -}
  
 -template<typename _Tp> inline void Mat_<_Tp>::create(int _rows, int _cols)
 -{
 -    Mat::create(_rows, _cols, DataType<_Tp>::type);
 -}
  
 -template<typename _Tp> inline void Mat_<_Tp>::create(Size _sz)
 -{
 -    Mat::create(_sz, DataType<_Tp>::type);
 -}
 +////////////////////////////////// MatConstIterator //////////////////////////////////
  
 -template<typename _Tp> inline void Mat_<_Tp>::create(int _dims, const int* _sz)
 +class CV_EXPORTS MatConstIterator
  {
 -    Mat::create(_dims, _sz, DataType<_Tp>::type);
 -}
 +public:
 +    typedef uchar* value_type;
 +    typedef ptrdiff_t difference_type;
 +    typedef const uchar** pointer;
 +    typedef uchar* reference;
  
 +#ifndef OPENCV_NOSTL
 +    typedef std::random_access_iterator_tag iterator_category;
 +#endif
  
 -template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const
 -{ return Mat_<_Tp>(Mat::cross(m)); }
 +    //! default constructor
 +    MatConstIterator();
 +    //! constructor that sets the iterator to the beginning of the matrix
 +    MatConstIterator(const Mat* _m);
 +    //! constructor that sets the iterator to the specified element of the matrix
 +    MatConstIterator(const Mat* _m, int _row, int _col=0);
 +    //! constructor that sets the iterator to the specified element of the matrix
 +    MatConstIterator(const Mat* _m, Point _pt);
 +    //! constructor that sets the iterator to the specified element of the matrix
 +    MatConstIterator(const Mat* _m, const int* _idx);
 +    //! copy constructor
 +    MatConstIterator(const MatConstIterator& it);
 +
 +    //! copy operator
 +    MatConstIterator& operator = (const MatConstIterator& it);
 +    //! returns the current matrix element
 +    uchar* operator *() const;
 +    //! returns the i-th matrix element, relative to the current
 +    uchar* operator [](ptrdiff_t i) const;
 +
 +    //! shifts the iterator forward by the specified number of elements
 +    MatConstIterator& operator += (ptrdiff_t ofs);
 +    //! shifts the iterator backward by the specified number of elements
 +    MatConstIterator& operator -= (ptrdiff_t ofs);
 +    //! decrements the iterator
 +    MatConstIterator& operator --();
 +    //! decrements the iterator
 +    MatConstIterator operator --(int);
 +    //! increments the iterator
 +    MatConstIterator& operator ++();
 +    //! increments the iterator
 +    MatConstIterator operator ++(int);
 +    //! returns the current iterator position
 +    Point pos() const;
 +    //! returns the current iterator position
 +    void pos(int* _idx) const;
 +
 +    ptrdiff_t lpos() const;
 +    void seek(ptrdiff_t ofs, bool relative = false);
 +    void seek(const int* _idx, bool relative = false);
 +
 +    const Mat* m;
 +    size_t elemSize;
 +    uchar* ptr;
 +    uchar* sliceStart;
 +    uchar* sliceEnd;
 +};
  
 -template<typename _Tp> template<typename T2> inline Mat_<_Tp>::operator Mat_<T2>() const
 -{ return Mat_<T2>(*this); }
  
 -template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::row(int y) const
 -{ return Mat_(*this, Range(y, y+1), Range::all()); }
 -template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::col(int x) const
 -{ return Mat_(*this, Range::all(), Range(x, x+1)); }
 -template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::diag(int d) const
 -{ return Mat_(Mat::diag(d)); }
 -template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::clone() const
 -{ return Mat_(Mat::clone()); }
  
 -template<typename _Tp> inline size_t Mat_<_Tp>::elemSize() const
 -{
 -    CV_DbgAssert( Mat::elemSize() == sizeof(_Tp) );
 -    return sizeof(_Tp);
 -}
 +////////////////////////////////// MatConstIterator_ /////////////////////////////////
  
 -template<typename _Tp> inline size_t Mat_<_Tp>::elemSize1() const
 +/*!
 + Matrix read-only iterator
 + */
 +template<typename _Tp>
 +class MatConstIterator_ : public MatConstIterator
  {
 -    CV_DbgAssert( Mat::elemSize1() == sizeof(_Tp)/DataType<_Tp>::channels );
 -    return sizeof(_Tp)/DataType<_Tp>::channels;
 -}
 -template<typename _Tp> inline int Mat_<_Tp>::type() const
 -{
 -    CV_DbgAssert( Mat::type() == DataType<_Tp>::type );
 -    return DataType<_Tp>::type;
 -}
 -template<typename _Tp> inline int Mat_<_Tp>::depth() const
 -{
 -    CV_DbgAssert( Mat::depth() == DataType<_Tp>::depth );
 -    return DataType<_Tp>::depth;
 -}
 -template<typename _Tp> inline int Mat_<_Tp>::channels() const
 -{
 -    CV_DbgAssert( Mat::channels() == DataType<_Tp>::channels );
 -    return DataType<_Tp>::channels;
 -}
 -template<typename _Tp> inline size_t Mat_<_Tp>::stepT(int i) const { return step.p[i]/elemSize(); }
 -template<typename _Tp> inline size_t Mat_<_Tp>::step1(int i) const { return step.p[i]/elemSize1(); }
 +public:
 +    typedef _Tp value_type;
 +    typedef ptrdiff_t difference_type;
 +    typedef const _Tp* pointer;
 +    typedef const _Tp& reference;
  
 -template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::adjustROI( int dtop, int dbottom, int dleft, int dright )
 -{ return (Mat_<_Tp>&)(Mat::adjustROI(dtop, dbottom, dleft, dright));  }
 +#ifndef OPENCV_NOSTL
 +    typedef std::random_access_iterator_tag iterator_category;
 +#endif
  
 -template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range& _rowRange, const Range& _colRange ) const
 -{ return Mat_<_Tp>(*this, _rowRange, _colRange); }
 +    //! default constructor
 +    MatConstIterator_();
 +    //! constructor that sets the iterator to the beginning of the matrix
 +    MatConstIterator_(const Mat_<_Tp>* _m);
 +    //! constructor that sets the iterator to the specified element of the matrix
 +    MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col=0);
 +    //! constructor that sets the iterator to the specified element of the matrix
 +    MatConstIterator_(const Mat_<_Tp>* _m, Point _pt);
 +    //! constructor that sets the iterator to the specified element of the matrix
 +    MatConstIterator_(const Mat_<_Tp>* _m, const int* _idx);
 +    //! copy constructor
 +    MatConstIterator_(const MatConstIterator_& it);
 +
 +    //! copy operator
 +    MatConstIterator_& operator = (const MatConstIterator_& it);
 +    //! returns the current matrix element
 +    _Tp operator *() const;
 +    //! returns the i-th matrix element, relative to the current
 +    _Tp operator [](ptrdiff_t i) const;
 +
 +    //! shifts the iterator forward by the specified number of elements
 +    MatConstIterator_& operator += (ptrdiff_t ofs);
 +    //! shifts the iterator backward by the specified number of elements
 +    MatConstIterator_& operator -= (ptrdiff_t ofs);
 +    //! decrements the iterator
 +    MatConstIterator_& operator --();
 +    //! decrements the iterator
 +    MatConstIterator_ operator --(int);
 +    //! increments the iterator
 +    MatConstIterator_& operator ++();
 +    //! increments the iterator
 +    MatConstIterator_ operator ++(int);
 +    //! returns the current iterator position
 +    Point pos() const;
 +};
  
 -template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const
 -{ return Mat_<_Tp>(*this, roi); }
  
 -template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range* ranges ) const
 -{ return Mat_<_Tp>(*this, ranges); }
  
 -template<typename _Tp> inline _Tp* Mat_<_Tp>::operator [](int y)
 -{ return (_Tp*)ptr(y); }
 -template<typename _Tp> inline const _Tp* Mat_<_Tp>::operator [](int y) const
 -{ return (const _Tp*)ptr(y); }
 +//////////////////////////////////// MatIterator_ ////////////////////////////////////
  
 -template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0, int i1)
 -{
 -    CV_DbgAssert( dims <= 2 && data &&
 -                  (unsigned)i0 < (unsigned)size.p[0] &&
 -                  (unsigned)i1 < (unsigned)size.p[1] &&
 -                  type() == DataType<_Tp>::type );
 -    return ((_Tp*)(data + step.p[0]*i0))[i1];
 -}
 -
 -template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0, int i1) const
 -{
 -    CV_DbgAssert( dims <= 2 && data &&
 -                  (unsigned)i0 < (unsigned)size.p[0] &&
 -                  (unsigned)i1 < (unsigned)size.p[1] &&
 -                  type() == DataType<_Tp>::type );
 -    return ((const _Tp*)(data + step.p[0]*i0))[i1];
 -}
 -
 -template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(Point pt)
 +/*!
 + Matrix read-write iterator
 +*/
 +template<typename _Tp>
 +class MatIterator_ : public MatConstIterator_<_Tp>
  {
 -    CV_DbgAssert( dims <= 2 && data &&
 -                  (unsigned)pt.y < (unsigned)size.p[0] &&
 -                  (unsigned)pt.x < (unsigned)size.p[1] &&
 -                  type() == DataType<_Tp>::type );
 -    return ((_Tp*)(data + step.p[0]*pt.y))[pt.x];
 -}
 -
 -template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(Point pt) const
 -{
 -    CV_DbgAssert( dims <= 2 && data &&
 -                  (unsigned)pt.y < (unsigned)size.p[0] &&
 -                  (unsigned)pt.x < (unsigned)size.p[1] &&
 -                 type() == DataType<_Tp>::type );
 -    return ((const _Tp*)(data + step.p[0]*pt.y))[pt.x];
 -}
 -
 -template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(const int* idx)
 -{
 -    return Mat::at<_Tp>(idx);
 -}
 +public:
 +    typedef _Tp* pointer;
 +    typedef _Tp& reference;
  
 -template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(const int* idx) const
 -{
 -    return Mat::at<_Tp>(idx);
 -}
 +#ifndef OPENCV_NOSTL
 +    typedef std::random_access_iterator_tag iterator_category;
 +#endif
  
 -template<typename _Tp> template<int n> inline _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx)
 -{
 -    return Mat::at<_Tp>(idx);
 -}
 +    //! the default constructor
 +    MatIterator_();
 +    //! constructor that sets the iterator to the beginning of the matrix
 +    MatIterator_(Mat_<_Tp>* _m);
 +    //! constructor that sets the iterator to the specified element of the matrix
 +    MatIterator_(Mat_<_Tp>* _m, int _row, int _col=0);
 +    //! constructor that sets the iterator to the specified element of the matrix
 +    MatIterator_(const Mat_<_Tp>* _m, Point _pt);
 +    //! constructor that sets the iterator to the specified element of the matrix
 +    MatIterator_(const Mat_<_Tp>* _m, const int* _idx);
 +    //! copy constructor
 +    MatIterator_(const MatIterator_& it);
 +    //! copy operator
 +    MatIterator_& operator = (const MatIterator_<_Tp>& it );
 +
 +    //! returns the current matrix element
 +    _Tp& operator *() const;
 +    //! returns the i-th matrix element, relative to the current
 +    _Tp& operator [](ptrdiff_t i) const;
 +
 +    //! shifts the iterator forward by the specified number of elements
 +    MatIterator_& operator += (ptrdiff_t ofs);
 +    //! shifts the iterator backward by the specified number of elements
 +    MatIterator_& operator -= (ptrdiff_t ofs);
 +    //! decrements the iterator
 +    MatIterator_& operator --();
 +    //! decrements the iterator
 +    MatIterator_ operator --(int);
 +    //! increments the iterator
 +    MatIterator_& operator ++();
 +    //! increments the iterator
 +    MatIterator_ operator ++(int);
 +};
  
 -template<typename _Tp> template<int n> inline const _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx) const
 -{
 -    return Mat::at<_Tp>(idx);
 -}
  
 -template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0)
 -{
 -    return this->at<_Tp>(i0);
 -}
  
 -template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0) const
 -{
 -    return this->at<_Tp>(i0);
 -}
 +/////////////////////////////// SparseMatConstIterator ///////////////////////////////
  
 -template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2)
 -{
 -    return this->at<_Tp>(i0, i1, i2);
 -}
 +/*!
 + Read-Only Sparse Matrix Iterator.
 + Here is how to use the iterator to compute the sum of floating-point sparse matrix elements:
  
 -template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2) const
 + \code
 + SparseMatConstIterator it = m.begin(), it_end = m.end();
 + double s = 0;
 + CV_Assert( m.type() == CV_32F );
 + for( ; it != it_end; ++it )
 +    s += it.value<float>();
 + \endcode
 +*/
 +class CV_EXPORTS SparseMatConstIterator
  {
 -    return this->at<_Tp>(i0, i1, i2);
 -}
 +public:
 +    //! the default constructor
 +    SparseMatConstIterator();
 +    //! the full constructor setting the iterator to the first sparse matrix element
 +    SparseMatConstIterator(const SparseMat* _m);
 +    //! the copy constructor
 +    SparseMatConstIterator(const SparseMatConstIterator& it);
 +
 +    //! the assignment operator
 +    SparseMatConstIterator& operator = (const SparseMatConstIterator& it);
 +
 +    //! template method returning the current matrix element
 +    template<typename _Tp> const _Tp& value() const;
 +    //! returns the current node of the sparse matrix. it.node->idx is the current element index
 +    const SparseMat::Node* node() const;
 +
 +    //! moves iterator to the previous element
 +    SparseMatConstIterator& operator --();
 +    //! moves iterator to the previous element
 +    SparseMatConstIterator operator --(int);
 +    //! moves iterator to the next element
 +    SparseMatConstIterator& operator ++();
 +    //! moves iterator to the next element
 +    SparseMatConstIterator operator ++(int);
 +
 +    //! moves iterator to the element after the last element
 +    void seekEnd();
 +
 +    const SparseMat* m;
 +    size_t hashidx;
 +    uchar* ptr;
 +};
  
  
 -template<typename _Tp> inline Mat_<_Tp>::operator vector<_Tp>() const
 -{
 -    vector<_Tp> v;
 -    copyTo(v);
 -    return v;
 -}
  
 -template<typename _Tp> template<int n> inline Mat_<_Tp>::operator Vec<typename DataType<_Tp>::channel_type, n>() const
 -{
 -    CV_Assert(n % DataType<_Tp>::channels == 0);
 -    return this->Mat::operator Vec<typename DataType<_Tp>::channel_type, n>();
 -}
 +////////////////////////////////// SparseMatIterator /////////////////////////////////
  
 -template<typename _Tp> template<int m, int n> inline Mat_<_Tp>::operator Matx<typename DataType<_Tp>::channel_type, m, n>() const
 -{
 -    CV_Assert(n % DataType<_Tp>::channels == 0);
 -    return this->Mat::operator Matx<typename DataType<_Tp>::channel_type, m, n>();
 -}
 +/*!
 + Read-write Sparse Matrix Iterator
  
 -template<typename T1, typename T2, typename Op> inline void
 -process( const Mat_<T1>& m1, Mat_<T2>& m2, Op op )
 + The class is similar to cv::SparseMatConstIterator,
 + but can be used for in-place modification of the matrix elements.
 +*/
 +class CV_EXPORTS SparseMatIterator : public SparseMatConstIterator
  {
 -    int y, x, rows = m1.rows, cols = m1.cols;
 +public:
 +    //! the default constructor
 +    SparseMatIterator();
 +    //! the full constructor setting the iterator to the first sparse matrix element
 +    SparseMatIterator(SparseMat* _m);
 +    //! the full constructor setting the iterator to the specified sparse matrix element
 +    SparseMatIterator(SparseMat* _m, const int* idx);
 +    //! the copy constructor
 +    SparseMatIterator(const SparseMatIterator& it);
 +
 +    //! the assignment operator
 +    SparseMatIterator& operator = (const SparseMatIterator& it);
 +    //! returns read-write reference to the current sparse matrix element
 +    template<typename _Tp> _Tp& value() const;
 +    //! returns pointer to the current sparse matrix node. it.node->idx is the index of the current element (do not modify it!)
 +    SparseMat::Node* node() const;
 +
 +    //! moves iterator to the next element
 +    SparseMatIterator& operator ++();
 +    //! moves iterator to the next element
 +    SparseMatIterator operator ++(int);
 +};
  
 -    CV_DbgAssert( m1.size() == m2.size() );
  
 -    for( y = 0; y < rows; y++ )
 -    {
 -        const T1* src = m1[y];
 -        T2* dst = m2[y];
  
 -        for( x = 0; x < cols; x++ )
 -            dst[x] = op(src[x]);
 -    }
 -}
 +/////////////////////////////// SparseMatConstIterator_ //////////////////////////////
  
 -template<typename T1, typename T2, typename T3, typename Op> inline void
 -process( const Mat_<T1>& m1, const Mat_<T2>& m2, Mat_<T3>& m3, Op op )
 -{
 -    int y, x, rows = m1.rows, cols = m1.cols;
 +/*!
 + Template Read-Only Sparse Matrix Iterator Class.
  
 -    CV_DbgAssert( m1.size() == m2.size() );
 + This is the derived from SparseMatConstIterator class that
 + introduces more convenient operator *() for accessing the current element.
 +*/
 +template<typename _Tp> class SparseMatConstIterator_ : public SparseMatConstIterator
 +{
 +public:
  
 -    for( y = 0; y < rows; y++ )
 -    {
 -        const T1* src1 = m1[y];
 -        const T2* src2 = m2[y];
 -        T3* dst = m3[y];
 +#ifndef OPENCV_NOSTL
 +    typedef std::forward_iterator_tag iterator_category;
 +#endif
  
 -        for( x = 0; x < cols; x++ )
 -            dst[x] = op( src1[x], src2[x] );
 -    }
 -}
 +    //! the default constructor
 +    SparseMatConstIterator_();
 +    //! the full constructor setting the iterator to the first sparse matrix element
 +    SparseMatConstIterator_(const SparseMat_<_Tp>* _m);
++    SparseMatConstIterator_(const SparseMat* _m);
 +    //! the copy constructor
 +    SparseMatConstIterator_(const SparseMatConstIterator_& it);
 +
 +    //! the assignment operator
 +    SparseMatConstIterator_& operator = (const SparseMatConstIterator_& it);
 +    //! the element access operator
 +    const _Tp& operator *() const;
 +
 +    //! moves iterator to the next element
 +    SparseMatConstIterator_& operator ++();
 +    //! moves iterator to the next element
 +    SparseMatConstIterator_ operator ++(int);
 +};
  
  
 -/////////////////////////////// Input/Output Arrays /////////////////////////////////
  
 -template<typename _Tp> inline _InputArray::_InputArray(const vector<_Tp>& vec)
 -    : flags(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type), obj((void*)&vec) {}
 +///////////////////////////////// SparseMatIterator_ /////////////////////////////////
  
 -template<typename _Tp> inline _InputArray::_InputArray(const vector<vector<_Tp> >& vec)
 -    : flags(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type), obj((void*)&vec) {}
 +/*!
 + Template Read-Write Sparse Matrix Iterator Class.
  
 -template<typename _Tp> inline _InputArray::_InputArray(const vector<Mat_<_Tp> >& vec)
 -    : flags(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type), obj((void*)&vec) {}
 + This is the derived from cv::SparseMatConstIterator_ class that
 + introduces more convenient operator *() for accessing the current element.
 +*/
 +template<typename _Tp> class CV_EXPORTS SparseMatIterator_ : public SparseMatConstIterator_<_Tp>
 +{
 +public:
  
 -template<typename _Tp, int m, int n> inline _InputArray::_InputArray(const Matx<_Tp, m, n>& mtx)
 -    : flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)&mtx), sz(n, m) {}
 +#ifndef OPENCV_NOSTL
 +    typedef std::forward_iterator_tag iterator_category;
 +#endif
  
 -template<typename _Tp> inline _InputArray::_InputArray(const _Tp* vec, int n)
 -    : flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)vec), sz(n, 1) {}
 +    //! the default constructor
 +    SparseMatIterator_();
 +    //! the full constructor setting the iterator to the first sparse matrix element
 +    SparseMatIterator_(SparseMat_<_Tp>* _m);
++    SparseMatIterator_(SparseMat* _m);
 +    //! the copy constructor
 +    SparseMatIterator_(const SparseMatIterator_& it);
 +
 +    //! the assignment operator
 +    SparseMatIterator_& operator = (const SparseMatIterator_& it);
 +    //! returns the reference to the current element
 +    _Tp& operator *() const;
 +
 +    //! moves the iterator to the next element
 +    SparseMatIterator_& operator ++();
 +    //! moves the iterator to the next element
 +    SparseMatIterator_ operator ++(int);
 +};
  
 -inline _InputArray::_InputArray(const Scalar& s)
 -    : flags(FIXED_TYPE + FIXED_SIZE + MATX + CV_64F), obj((void*)&s), sz(1, 4) {}
  
 -template<typename _Tp> inline _InputArray::_InputArray(const Mat_<_Tp>& m)
 -    : flags(FIXED_TYPE + MAT + DataType<_Tp>::type), obj((void*)&m) {}
  
 -template<typename _Tp> inline _OutputArray::_OutputArray(vector<_Tp>& vec)
 -    : _InputArray(vec) {}
 -template<typename _Tp> inline _OutputArray::_OutputArray(vector<vector<_Tp> >& vec)
 -    : _InputArray(vec) {}
 -template<typename _Tp> inline _OutputArray::_OutputArray(vector<Mat_<_Tp> >& vec)
 -    : _InputArray(vec) {}
 -template<typename _Tp> inline _OutputArray::_OutputArray(Mat_<_Tp>& m)
 -    : _InputArray(m) {}
 -template<typename _Tp, int m, int n> inline _OutputArray::_OutputArray(Matx<_Tp, m, n>& mtx)
 -    : _InputArray(mtx) {}
 -template<typename _Tp> inline _OutputArray::_OutputArray(_Tp* vec, int n)
 -    : _InputArray(vec, n) {}
 +/////////////////////////////////// NAryMatIterator //////////////////////////////////
 +
 +/*!
 + n-Dimensional Dense Matrix Iterator Class.
 +
 + The class cv::NAryMatIterator is used for iterating over one or more n-dimensional dense arrays (cv::Mat's).
 +
 + The iterator is completely different from cv::Mat_ and cv::SparseMat_ iterators.
 + It iterates through the slices (or planes), not the elements, where "slice" is a continuous part of the arrays.
 +
 + Here is the example on how the iterator can be used to normalize 3D histogram:
 +
 + \code
 + void normalizeColorHist(Mat& hist)
 + {
 + #if 1
 +     // intialize iterator (the style is different from STL).
 +     // after initialization the iterator will contain
 +     // the number of slices or planes
 +     // the iterator will go through
 +     Mat* arrays[] = { &hist, 0 };
 +     Mat planes[1];
 +     NAryMatIterator it(arrays, planes);
 +     double s = 0;
 +     // iterate through the matrix. on each iteration
 +     // it.planes[i] (of type Mat) will be set to the current plane of
 +     // i-th n-dim matrix passed to the iterator constructor.
 +     for(int p = 0; p < it.nplanes; p++, ++it)
 +        s += sum(it.planes[0])[0];
 +     it = NAryMatIterator(hist);
 +     s = 1./s;
 +     for(int p = 0; p < it.nplanes; p++, ++it)
 +        it.planes[0] *= s;
 + #elif 1
 +     // this is a shorter implementation of the above
 +     // using built-in operations on Mat
 +     double s = sum(hist)[0];
 +     hist.convertTo(hist, hist.type(), 1./s, 0);
 + #else
 +     // and this is even shorter one
 +     // (assuming that the histogram elements are non-negative)
 +     normalize(hist, hist, 1, 0, NORM_L1);
 + #endif
 + }
 + \endcode
 +
 + You can iterate through several matrices simultaneously as long as they have the same geometry
 + (dimensionality and all the dimension sizes are the same), which is useful for binary
 + and n-ary operations on such matrices. Just pass those matrices to cv::MatNDIterator.
 + Then, during the iteration it.planes[0], it.planes[1], ... will
 + be the slices of the corresponding matrices
 +*/
 +class CV_EXPORTS NAryMatIterator
 +{
 +public:
 +    //! the default constructor
 +    NAryMatIterator();
 +    //! the full constructor taking arbitrary number of n-dim matrices
 +    NAryMatIterator(const Mat** arrays, uchar** ptrs, int narrays=-1);
 +    //! the full constructor taking arbitrary number of n-dim matrices
 +    NAryMatIterator(const Mat** arrays, Mat* planes, int narrays=-1);
 +    //! the separate iterator initialization method
 +    void init(const Mat** arrays, Mat* planes, uchar** ptrs, int narrays=-1);
 +
 +    //! proceeds to the next plane of every iterated matrix
 +    NAryMatIterator& operator ++();
 +    //! proceeds to the next plane of every iterated matrix (postfix increment operator)
 +    NAryMatIterator operator ++(int);
 +
 +    //! the iterated arrays
 +    const Mat** arrays;
 +    //! the current planes
 +    Mat* planes;
 +    //! data pointers
 +    uchar** ptrs;
 +    //! the number of arrays
 +    int narrays;
 +    //! the number of hyper-planes that the iterator steps through
 +    size_t nplanes;
 +    //! the size of each segment (in elements)
 +    size_t size;
 +protected:
 +    int iterdepth;
 +    size_t idx;
 +};
  
 -template<typename _Tp> inline _OutputArray::_OutputArray(const vector<_Tp>& vec)
 -    : _InputArray(vec) {flags |= FIXED_SIZE;}
 -template<typename _Tp> inline _OutputArray::_OutputArray(const vector<vector<_Tp> >& vec)
 -    : _InputArray(vec) {flags |= FIXED_SIZE;}
 -template<typename _Tp> inline _OutputArray::_OutputArray(const vector<Mat_<_Tp> >& vec)
 -    : _InputArray(vec) {flags |= FIXED_SIZE;}
  
 -template<typename _Tp> inline _OutputArray::_OutputArray(const Mat_<_Tp>& m)
 -    : _InputArray(m) {flags |= FIXED_SIZE;}
 -template<typename _Tp, int m, int n> inline _OutputArray::_OutputArray(const Matx<_Tp, m, n>& mtx)
 -    : _InputArray(mtx) {}
 -template<typename _Tp> inline _OutputArray::_OutputArray(const _Tp* vec, int n)
 -    : _InputArray(vec, n) {}
  
 -//////////////////////////////////// Matrix Expressions /////////////////////////////////////////
 +///////////////////////////////// Matrix Expressions /////////////////////////////////
  
  class CV_EXPORTS MatOp
  {
index a5ecea8,0000000..026ab69
mode 100644,000000..100644
--- /dev/null
@@@ -1,2949 -1,0 +1,2961 @@@
 +/*M///////////////////////////////////////////////////////////////////////////////////////
 +//
 +//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
 +//
 +//  By downloading, copying, installing or using the software you agree to this license.
 +//  If you do not agree to this license, do not download, install,
 +//  copy or use the software.
 +//
 +//
 +//                           License Agreement
 +//                For Open Source Computer Vision Library
 +//
 +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
 +// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
 +// Third party copyrights are property of their respective owners.
 +//
 +// Redistribution and use in source and binary forms, with or without modification,
 +// are permitted provided that the following conditions are met:
 +//
 +//   * Redistribution's of source code must retain the above copyright notice,
 +//     this list of conditions and the following disclaimer.
 +//
 +//   * Redistribution's in binary form must reproduce the above copyright notice,
 +//     this list of conditions and the following disclaimer in the documentation
 +//     and/or other materials provided with the distribution.
 +//
 +//   * The name of the copyright holders may not be used to endorse or promote products
 +//     derived from this software without specific prior written permission.
 +//
 +// This software is provided by the copyright holders and contributors "as is" and
 +// any express or implied warranties, including, but not limited to, the implied
 +// warranties of merchantability and fitness for a particular purpose are disclaimed.
 +// In no event shall the Intel Corporation or contributors be liable for any direct,
 +// indirect, incidental, special, exemplary, or consequential damages
 +// (including, but not limited to, procurement of substitute goods or services;
 +// loss of use, data, or profits; or business interruption) however caused
 +// and on any theory of liability, whether in contract, strict liability,
 +// or tort (including negligence or otherwise) arising in any way out of
 +// the use of this software, even if advised of the possibility of such damage.
 +//
 +//M*/
 +
 +#ifndef __OPENCV_CORE_MATRIX_OPERATIONS_HPP__
 +#define __OPENCV_CORE_MATRIX_OPERATIONS_HPP__
 +
 +#ifndef __cplusplus
 +#  error mat.inl.hpp header must be compiled as C++
 +#endif
 +
 +namespace cv
 +{
 +
 +//////////////////////// Input/Output Arrays ////////////////////////
 +
 +template<typename _Tp> inline
 +_InputArray::_InputArray(const std::vector<_Tp>& vec)
 +    : flags(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type), obj((void*)&vec)
 +{}
 +
 +template<typename _Tp> inline
 +_InputArray::_InputArray(const std::vector<std::vector<_Tp> >& vec)
 +    : flags(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type), obj((void*)&vec)
 +{}
 +
 +template<typename _Tp> inline
 +_InputArray::_InputArray(const std::vector<Mat_<_Tp> >& vec)
 +    : flags(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type), obj((void*)&vec)
 +{}
 +
 +template<typename _Tp, int m, int n> inline
 +_InputArray::_InputArray(const Matx<_Tp, m, n>& mtx)
 +    : flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)&mtx), sz(n, m)
 +{}
 +
 +template<typename _Tp> inline
 +_InputArray::_InputArray(const _Tp* vec, int n)
 +    : flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)vec), sz(n, 1)
 +{}
 +
 +template<typename _Tp> inline
 +_InputArray::_InputArray(const Mat_<_Tp>& m)
 +    : flags(FIXED_TYPE + MAT + DataType<_Tp>::type), obj((void*)&m)
 +{}
 +
 +
 +template<typename _Tp> inline
 +_OutputArray::_OutputArray(std::vector<_Tp>& vec)
 +    : _InputArray(vec)
 +{}
 +
 +template<typename _Tp> inline
 +_OutputArray::_OutputArray(std::vector<std::vector<_Tp> >& vec)
 +    : _InputArray(vec)
 +{}
 +
 +template<typename _Tp> inline
 +_OutputArray::_OutputArray(std::vector<Mat_<_Tp> >& vec)
 +    : _InputArray(vec)
 +{}
 +
 +template<typename _Tp> inline
 +_OutputArray::_OutputArray(Mat_<_Tp>& m)
 +    : _InputArray(m)
 +{}
 +
 +template<typename _Tp, int m, int n> inline
 +_OutputArray::_OutputArray(Matx<_Tp, m, n>& mtx)
 +    : _InputArray(mtx)
 +{}
 +
 +template<typename _Tp> inline
 +_OutputArray::_OutputArray(_Tp* vec, int n)
 +    : _InputArray(vec, n)
 +{}
 +
 +template<typename _Tp> inline
 +_OutputArray::_OutputArray(const std::vector<_Tp>& vec)
 +    : _InputArray(vec)
 +{
 +    flags |= FIXED_SIZE;
 +}
 +
 +template<typename _Tp> inline
 +_OutputArray::_OutputArray(const std::vector<std::vector<_Tp> >& vec)
 +    : _InputArray(vec)
 +{
 +    flags |= FIXED_SIZE;
 +}
 +
 +template<typename _Tp> inline
 +_OutputArray::_OutputArray(const std::vector<Mat_<_Tp> >& vec)
 +    : _InputArray(vec)
 +{
 +    flags |= FIXED_SIZE;
 +}
 +
 +template<typename _Tp> inline
 +_OutputArray::_OutputArray(const Mat_<_Tp>& m)
 +    : _InputArray(m)
 +{
 +    flags |= FIXED_SIZE;
 +}
 +
 +template<typename _Tp, int m, int n> inline
 +_OutputArray::_OutputArray(const Matx<_Tp, m, n>& mtx)
 +    : _InputArray(mtx)
 +{}
 +
 +template<typename _Tp> inline
 +_OutputArray::_OutputArray(const _Tp* vec, int n)
 +    : _InputArray(vec, n)
 +{}
 +
 +
 +
 +//////////////////////////////// Mat ////////////////////////////////
 +
 +inline
 +Mat::Mat()
 +    : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), refcount(0), datastart(0), dataend(0),
 +      datalimit(0), allocator(0), size(&rows)
 +{}
 +
 +inline
 +Mat::Mat(int _rows, int _cols, int _type)
 +    : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), refcount(0), datastart(0), dataend(0),
 +      datalimit(0), allocator(0), size(&rows)
 +{
 +    create(_rows, _cols, _type);
 +}
 +
 +inline
 +Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
 +    : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), refcount(0), datastart(0), dataend(0),
 +      datalimit(0), allocator(0), size(&rows)
 +{
 +    create(_rows, _cols, _type);
 +    *this = _s;
 +}
 +
 +inline
 +Mat::Mat(Size _sz, int _type)
 +    : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), refcount(0), datastart(0), dataend(0),
 +      datalimit(0), allocator(0), size(&rows)
 +{
 +    create( _sz.height, _sz.width, _type );
 +}
 +
 +inline
 +Mat::Mat(Size _sz, int _type, const Scalar& _s)
 +    : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), refcount(0), datastart(0), dataend(0),
 +      datalimit(0), allocator(0), size(&rows)
 +{
 +    create(_sz.height, _sz.width, _type);
 +    *this = _s;
 +}
 +
 +inline
 +Mat::Mat(int _dims, const int* _sz, int _type)
 +    : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), refcount(0), datastart(0), dataend(0),
 +      datalimit(0), allocator(0), size(&rows)
 +{
 +    create(_dims, _sz, _type);
 +}
 +
 +inline
 +Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s)
 +    : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), refcount(0), datastart(0), dataend(0),
 +      datalimit(0), allocator(0), size(&rows)
 +{
 +    create(_dims, _sz, _type);
 +    *this = _s;
 +}
 +
 +inline
 +Mat::Mat(const Mat& m)
 +    : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data), refcount(m.refcount),
 +      datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit), allocator(m.allocator),
 +      size(&rows)
 +{
 +    if( refcount )
 +        CV_XADD(refcount, 1);
 +    if( m.dims <= 2 )
 +    {
 +        step[0] = m.step[0]; step[1] = m.step[1];
 +    }
 +    else
 +    {
 +        dims = 0;
 +        copySize(m);
 +    }
 +}
 +
 +inline
 +Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
 +    : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_rows), cols(_cols),
 +      data((uchar*)_data), refcount(0), datastart((uchar*)_data), dataend(0), datalimit(0),
 +      allocator(0), size(&rows)
 +{
 +    size_t esz = CV_ELEM_SIZE(_type);
 +    size_t minstep = cols * esz;
 +    if( _step == AUTO_STEP )
 +    {
 +        _step = minstep;
 +        flags |= CONTINUOUS_FLAG;
 +    }
 +    else
 +    {
 +        if( rows == 1 ) _step = minstep;
 +        CV_DbgAssert( _step >= minstep );
 +        flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
 +    }
 +    step[0] = _step;
 +    step[1] = esz;
 +    datalimit = datastart + _step * rows;
 +    dataend = datalimit - _step + minstep;
 +}
 +
 +inline
 +Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
 +    : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_sz.height), cols(_sz.width),
 +      data((uchar*)_data), refcount(0), datastart((uchar*)_data), dataend(0), datalimit(0),
 +      allocator(0), size(&rows)
 +{
 +    size_t esz = CV_ELEM_SIZE(_type);
 +    size_t minstep = cols*esz;
 +    if( _step == AUTO_STEP )
 +    {
 +        _step = minstep;
 +        flags |= CONTINUOUS_FLAG;
 +    }
 +    else
 +    {
 +        if( rows == 1 ) _step = minstep;
 +        CV_DbgAssert( _step >= minstep );
 +        flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
 +    }
 +    step[0] = _step;
 +    step[1] = esz;
 +    datalimit = datastart + _step*rows;
 +    dataend = datalimit - _step + minstep;
 +}
 +
 +template<typename _Tp> inline
 +Mat::Mat(const std::vector<_Tp>& vec, bool copyData)
 +    : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
 +      cols(1), data(0), refcount(0), datastart(0), dataend(0), allocator(0), size(&rows)
 +{
 +    if(vec.empty())
 +        return;
 +    if( !copyData )
 +    {
 +        step[0] = step[1] = sizeof(_Tp);
 +        data = datastart = (uchar*)&vec[0];
 +        datalimit = dataend = datastart + rows * step[0];
 +    }
 +    else
 +        Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
 +}
 +
 +template<typename _Tp, int n> inline
 +Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
 +    : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(n), cols(1), data(0),
 +      refcount(0), datastart(0), dataend(0), allocator(0), size(&rows)
 +{
 +    if( !copyData )
 +    {
 +        step[0] = step[1] = sizeof(_Tp);
 +        data = datastart = (uchar*)vec.val;
 +        datalimit = dataend = datastart + rows * step[0];
 +    }
 +    else
 +        Mat(n, 1, DataType<_Tp>::type, (void*)vec.val).copyTo(*this);
 +}
 +
 +
 +template<typename _Tp, int m, int n> inline
 +Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
 +    : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(m), cols(n), data(0),
 +      refcount(0), datastart(0), dataend(0), allocator(0), size(&rows)
 +{
 +    if( !copyData )
 +    {
 +        step[0] = cols * sizeof(_Tp);
 +        step[1] = sizeof(_Tp);
 +        data = datastart = (uchar*)M.val;
 +        datalimit = dataend = datastart + rows * step[0];
 +    }
 +    else
 +        Mat(m, n, DataType<_Tp>::type, (uchar*)M.val).copyTo(*this);
 +}
 +
 +template<typename _Tp> inline
 +Mat::Mat(const Point_<_Tp>& pt, bool copyData)
 +    : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(2), cols(1), data(0),
 +      refcount(0), datastart(0), dataend(0), allocator(0), size(&rows)
 +{
 +    if( !copyData )
 +    {
 +        step[0] = step[1] = sizeof(_Tp);
 +        data = datastart = (uchar*)&pt.x;
 +        datalimit = dataend = datastart + rows * step[0];
 +    }
 +    else
 +    {
 +        create(2, 1, DataType<_Tp>::type);
 +        ((_Tp*)data)[0] = pt.x;
 +        ((_Tp*)data)[1] = pt.y;
 +    }
 +}
 +
 +template<typename _Tp> inline
 +Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
 +    : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(3), cols(1), data(0),
 +      refcount(0), datastart(0), dataend(0), allocator(0), size(&rows)
 +{
 +    if( !copyData )
 +    {
 +        step[0] = step[1] = sizeof(_Tp);
 +        data = datastart = (uchar*)&pt.x;
 +        datalimit = dataend = datastart + rows * step[0];
 +    }
 +    else
 +    {
 +        create(3, 1, DataType<_Tp>::type);
 +        ((_Tp*)data)[0] = pt.x;
 +        ((_Tp*)data)[1] = pt.y;
 +        ((_Tp*)data)[2] = pt.z;
 +    }
 +}
 +
 +template<typename _Tp> inline
 +Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer)
 +    : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(0), rows(0), cols(0), data(0),
 +      refcount(0), datastart(0), dataend(0), allocator(0), size(&rows)
 +{
 +    *this = commaInitializer.operator Mat_<_Tp>();
 +}
 +
 +inline
 +Mat::~Mat()
 +{
 +    release();
 +    if( step.p != step.buf )
 +        fastFree(step.p);
 +}
 +
 +inline
 +Mat& Mat::operator = (const Mat& m)
 +{
 +    if( this != &m )
 +    {
 +        if( m.refcount )
 +            CV_XADD(m.refcount, 1);
 +        release();
 +        flags = m.flags;
 +        if( dims <= 2 && m.dims <= 2 )
 +        {
 +            dims = m.dims;
 +            rows = m.rows;
 +            cols = m.cols;
 +            step[0] = m.step[0];
 +            step[1] = m.step[1];
 +        }
 +        else
 +            copySize(m);
 +        data = m.data;
 +        datastart = m.datastart;
 +        dataend = m.dataend;
 +        datalimit = m.datalimit;
 +        refcount = m.refcount;
 +        allocator = m.allocator;
 +    }
 +    return *this;
 +}
 +
 +inline
 +Mat Mat::row(int y) const
 +{
 +    return Mat(*this, Range(y, y + 1), Range::all());
 +}
 +
 +inline
 +Mat Mat::col(int x) const
 +{
 +    return Mat(*this, Range::all(), Range(x, x + 1));
 +}
 +
 +inline
 +Mat Mat::rowRange(int startrow, int endrow) const
 +{
 +    return Mat(*this, Range(startrow, endrow), Range::all());
 +}
 +
 +inline
 +Mat Mat::rowRange(const Range& r) const
 +{
 +    return Mat(*this, r, Range::all());
 +}
 +
 +inline
 +Mat Mat::colRange(int startcol, int endcol) const
 +{
 +    return Mat(*this, Range::all(), Range(startcol, endcol));
 +}
 +
 +inline
 +Mat Mat::colRange(const Range& r) const
 +{
 +    return Mat(*this, Range::all(), r);
 +}
 +
 +inline
 +Mat Mat::clone() const
 +{
 +    Mat m;
 +    copyTo(m);
 +    return m;
 +}
 +
 +inline
 +void Mat::assignTo( Mat& m, int _type ) const
 +{
 +    if( _type < 0 )
 +        m = *this;
 +    else
 +        convertTo(m, _type);
 +}
 +
 +inline
 +void Mat::create(int _rows, int _cols, int _type)
 +{
 +    _type &= TYPE_MASK;
 +    if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data )
 +        return;
 +    int sz[] = {_rows, _cols};
 +    create(2, sz, _type);
 +}
 +
 +inline
 +void Mat::create(Size _sz, int _type)
 +{
 +    create(_sz.height, _sz.width, _type);
 +}
 +
 +inline
 +void Mat::addref()
 +{
 +    if( refcount )
 +        CV_XADD(refcount, 1);
 +}
 +
 +inline void Mat::release()
 +{
 +    if( refcount && CV_XADD(refcount, -1) == 1 )
 +        deallocate();
 +    data = datastart = dataend = datalimit = 0;
 +    size.p[0] = 0;
 +    refcount = 0;
 +}
 +
 +inline
 +Mat Mat::operator()( Range _rowRange, Range _colRange ) const
 +{
 +    return Mat(*this, _rowRange, _colRange);
 +}
 +
 +inline
 +Mat Mat::operator()( const Rect& roi ) const
 +{
 +    return Mat(*this, roi);
 +}
 +
 +inline
 +Mat Mat::operator()(const Range* ranges) const
 +{
 +    return Mat(*this, ranges);
 +}
 +
 +inline
 +bool Mat::isContinuous() const
 +{
 +    return (flags & CONTINUOUS_FLAG) != 0;
 +}
 +
 +inline
 +bool Mat::isSubmatrix() const
 +{
 +    return (flags & SUBMATRIX_FLAG) != 0;
 +}
 +
 +inline
 +size_t Mat::elemSize() const
 +{
 +    return dims > 0 ? step.p[dims - 1] : 0;
 +}
 +
 +inline
 +size_t Mat::elemSize1() const
 +{
 +    return CV_ELEM_SIZE1(flags);
 +}
 +
 +inline
 +int Mat::type() const
 +{
 +    return CV_MAT_TYPE(flags);
 +}
 +
 +inline
 +int Mat::depth() const
 +{
 +    return CV_MAT_DEPTH(flags);
 +}
 +
 +inline
 +int Mat::channels() const
 +{
 +    return CV_MAT_CN(flags);
 +}
 +
 +inline
 +size_t Mat::step1(int i) const
 +{
 +    return step.p[i] / elemSize1();
 +}
 +
 +inline
 +bool Mat::empty() const
 +{
 +    return data == 0 || total() == 0;
 +}
 +
 +inline
 +size_t Mat::total() const
 +{
 +    if( dims <= 2 )
 +        return (size_t)rows * cols;
 +    size_t p = 1;
 +    for( int i = 0; i < dims; i++ )
 +        p *= size[i];
 +    return p;
 +}
 +
 +inline
 +uchar* Mat::ptr(int y)
 +{
 +    CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
 +    return data + step.p[0] * y;
 +}
 +
 +inline
 +const uchar* Mat::ptr(int y) const
 +{
 +    CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
 +    return data + step.p[0] * y;
 +}
 +
 +template<typename _Tp> inline
 +_Tp* Mat::ptr(int y)
 +{
 +    CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
 +    return (_Tp*)(data + step.p[0] * y);
 +}
 +
 +template<typename _Tp> inline
 +const _Tp* Mat::ptr(int y) const
 +{
 +    CV_DbgAssert( y == 0 || (data && dims >= 1 && data && (unsigned)y < (unsigned)size.p[0]) );
 +    return (const _Tp*)(data + step.p[0] * y);
 +}
 +
 +inline
 +uchar* Mat::ptr(int i0, int i1)
 +{
 +    CV_DbgAssert( dims >= 2 && data &&
 +                  (unsigned)i0 < (unsigned)size.p[0] &&
 +                  (unsigned)i1 < (unsigned)size.p[1] );
 +    return data + i0 * step.p[0] + i1 * step.p[1];
 +}
 +
 +inline
 +const uchar* Mat::ptr(int i0, int i1) const
 +{
 +    CV_DbgAssert( dims >= 2 && data &&
 +                 (unsigned)i0 < (unsigned)size.p[0] &&
 +                 (unsigned)i1 < (unsigned)size.p[1] );
 +    return data + i0 * step.p[0] + i1 * step.p[1];
 +}
 +
 +template<typename _Tp> inline
 +_Tp* Mat::ptr(int i0, int i1)
 +{
 +    CV_DbgAssert( dims >= 2 && data &&
 +                  (unsigned)i0 < (unsigned)size.p[0] &&
 +                  (unsigned)i1 < (unsigned)size.p[1] );
 +    return (_Tp*)(data + i0 * step.p[0] + i1 * step.p[1]);
 +}
 +
 +template<typename _Tp> inline
 +const _Tp* Mat::ptr(int i0, int i1) const
 +{
 +    CV_DbgAssert( dims >= 2 && data &&
 +                  (unsigned)i0 < (unsigned)size.p[0] &&
 +                  (unsigned)i1 < (unsigned)size.p[1] );
 +    return (const _Tp*)(data + i0 * step.p[0] + i1 * step.p[1]);
 +}
 +
 +inline
 +uchar* Mat::ptr(int i0, int i1, int i2)
 +{
 +    CV_DbgAssert( dims >= 3 && data &&
 +                  (unsigned)i0 < (unsigned)size.p[0] &&
 +                  (unsigned)i1 < (unsigned)size.p[1] &&
 +                  (unsigned)i2 < (unsigned)size.p[2] );
 +    return data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2];
 +}
 +
 +inline
 +const uchar* Mat::ptr(int i0, int i1, int i2) const
 +{
 +    CV_DbgAssert( dims >= 3 && data &&
 +                  (unsigned)i0 < (unsigned)size.p[0] &&
 +                  (unsigned)i1 < (unsigned)size.p[1] &&
 +                  (unsigned)i2 < (unsigned)size.p[2] );
 +    return data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2];
 +}
 +
 +template<typename _Tp> inline
 +_Tp* Mat::ptr(int i0, int i1, int i2)
 +{
 +    CV_DbgAssert( dims >= 3 && data &&
 +                  (unsigned)i0 < (unsigned)size.p[0] &&
 +                  (unsigned)i1 < (unsigned)size.p[1] &&
 +                  (unsigned)i2 < (unsigned)size.p[2] );
 +    return (_Tp*)(data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2]);
 +}
 +
 +template<typename _Tp> inline
 +const _Tp* Mat::ptr(int i0, int i1, int i2) const
 +{
 +    CV_DbgAssert( dims >= 3 && data &&
 +                  (unsigned)i0 < (unsigned)size.p[0] &&
 +                  (unsigned)i1 < (unsigned)size.p[1] &&
 +                  (unsigned)i2 < (unsigned)size.p[2] );
 +    return (const _Tp*)(data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2]);
 +}
 +
 +inline
 +uchar* Mat::ptr(const int* idx)
 +{
 +    int i, d = dims;
 +    uchar* p = data;
 +    CV_DbgAssert( d >= 1 && p );
 +    for( i = 0; i < d; i++ )
 +    {
 +        CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
 +        p += idx[i] * step.p[i];
 +    }
 +    return p;
 +}
 +
 +inline
 +const uchar* Mat::ptr(const int* idx) const
 +{
 +    int i, d = dims;
 +    uchar* p = data;
 +    CV_DbgAssert( d >= 1 && p );
 +    for( i = 0; i < d; i++ )
 +    {
 +        CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
 +        p += idx[i] * step.p[i];
 +    }
 +    return p;
 +}
 +
 +template<typename _Tp> inline
 +_Tp& Mat::at(int i0, int i1)
 +{
 +    CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
 +        (unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()) &&
 +        CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
 +    return ((_Tp*)(data + step.p[0] * i0))[i1];
 +}
 +
 +template<typename _Tp> inline
 +const _Tp& Mat::at(int i0, int i1) const
 +{
 +    CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
 +        (unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()) &&
 +        CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
 +    return ((const _Tp*)(data + step.p[0] * i0))[i1];
 +}
 +
 +template<typename _Tp> inline
 +_Tp& Mat::at(Point pt)
 +{
 +    CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
 +        (unsigned)(pt.x * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()) &&
 +        CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
 +    return ((_Tp*)(data + step.p[0] * pt.y))[pt.x];
 +}
 +
 +template<typename _Tp> inline
 +const _Tp& Mat::at(Point pt) const
 +{
 +    CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
 +        (unsigned)(pt.x * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()) &&
 +        CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
 +    return ((const _Tp*)(data + step.p[0] * pt.y))[pt.x];
 +}
 +
 +template<typename _Tp> inline
 +_Tp& Mat::at(int i0)
 +{
 +    CV_DbgAssert( dims <= 2 && data &&
 +                 (unsigned)i0 < (unsigned)(size.p[0] * size.p[1]) &&
 +                 elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
 +    if( isContinuous() || size.p[0] == 1 )
 +        return ((_Tp*)data)[i0];
 +    if( size.p[1] == 1 )
 +        return *(_Tp*)(data + step.p[0] * i0);
 +    int i = i0 / cols, j = i0 - i * cols;
 +    return ((_Tp*)(data + step.p[0] * i))[j];
 +}
 +
 +template<typename _Tp> inline
 +const _Tp& Mat::at(int i0) const
 +{
 +    CV_DbgAssert( dims <= 2 && data &&
 +                 (unsigned)i0 < (unsigned)(size.p[0] * size.p[1]) &&
 +                 elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
 +    if( isContinuous() || size.p[0] == 1 )
 +        return ((const _Tp*)data)[i0];
 +    if( size.p[1] == 1 )
 +        return *(const _Tp*)(data + step.p[0] * i0);
 +    int i = i0 / cols, j = i0 - i * cols;
 +    return ((const _Tp*)(data + step.p[0] * i))[j];
 +}
 +
 +template<typename _Tp> inline
 +_Tp& Mat::at(int i0, int i1, int i2)
 +{
 +    CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
 +    return *(_Tp*)ptr(i0, i1, i2);
 +}
 +
 +template<typename _Tp> inline
 +const _Tp& Mat::at(int i0, int i1, int i2) const
 +{
 +    CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
 +    return *(const _Tp*)ptr(i0, i1, i2);
 +}
 +
 +template<typename _Tp> inline
 +_Tp& Mat::at(const int* idx)
 +{
 +    CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
 +    return *(_Tp*)ptr(idx);
 +}
 +
 +template<typename _Tp> inline
 +const _Tp& Mat::at(const int* idx) const
 +{
 +    CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
 +    return *(const _Tp*)ptr(idx);
 +}
 +
 +template<typename _Tp, int n> inline
 +_Tp& Mat::at(const Vec<int, n>& idx)
 +{
 +    CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
 +    return *(_Tp*)ptr(idx.val);
 +}
 +
 +template<typename _Tp, int n> inline
 +const _Tp& Mat::at(const Vec<int, n>& idx) const
 +{
 +    CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
 +    return *(const _Tp*)ptr(idx.val);
 +}
 +
 +template<typename _Tp> inline
 +MatConstIterator_<_Tp> Mat::begin() const
 +{
 +    CV_DbgAssert( elemSize() == sizeof(_Tp) );
 +    return MatConstIterator_<_Tp>((const Mat_<_Tp>*)this);
 +}
 +
 +template<typename _Tp> inline
 +MatConstIterator_<_Tp> Mat::end() const
 +{
 +    CV_DbgAssert( elemSize() == sizeof(_Tp) );
 +    MatConstIterator_<_Tp> it((const Mat_<_Tp>*)this);
 +    it += total();
 +    return it;
 +}
 +
 +template<typename _Tp> inline
 +MatIterator_<_Tp> Mat::begin()
 +{
 +    CV_DbgAssert( elemSize() == sizeof(_Tp) );
 +    return MatIterator_<_Tp>((Mat_<_Tp>*)this);
 +}
 +
 +template<typename _Tp> inline
 +MatIterator_<_Tp> Mat::end()
 +{
 +    CV_DbgAssert( elemSize() == sizeof(_Tp) );
 +    MatIterator_<_Tp> it((Mat_<_Tp>*)this);
 +    it += total();
 +    return it;
 +}
 +
 +template<typename _Tp> inline
 +Mat::operator std::vector<_Tp>() const
 +{
 +    std::vector<_Tp> v;
 +    copyTo(v);
 +    return v;
 +}
 +
 +template<typename _Tp, int n> inline
 +Mat::operator Vec<_Tp, n>() const
 +{
 +    CV_Assert( data && dims <= 2 && (rows == 1 || cols == 1) &&
 +               rows + cols - 1 == n && channels() == 1 );
 +
 +    if( isContinuous() && type() == DataType<_Tp>::type )
 +        return Vec<_Tp, n>((_Tp*)data);
 +    Vec<_Tp, n> v;
 +    Mat tmp(rows, cols, DataType<_Tp>::type, v.val);
 +    convertTo(tmp, tmp.type());
 +    return v;
 +}
 +
 +template<typename _Tp, int m, int n> inline
 +Mat::operator Matx<_Tp, m, n>() const
 +{
 +    CV_Assert( data && dims <= 2 && rows == m && cols == n && channels() == 1 );
 +
 +    if( isContinuous() && type() == DataType<_Tp>::type )
 +        return Matx<_Tp, m, n>((_Tp*)data);
 +    Matx<_Tp, m, n> mtx;
 +    Mat tmp(rows, cols, DataType<_Tp>::type, mtx.val);
 +    convertTo(tmp, tmp.type());
 +    return mtx;
 +}
 +
 +template<typename _Tp> inline
 +void Mat::push_back(const _Tp& elem)
 +{
 +    if( !data )
 +    {
 +        *this = Mat(1, 1, DataType<_Tp>::type, (void*)&elem).clone();
 +        return;
 +    }
 +    CV_Assert(DataType<_Tp>::type == type() && cols == 1
 +              /* && dims == 2 (cols == 1 implies dims == 2) */);
 +    uchar* tmp = dataend + step[0];
 +    if( !isSubmatrix() && isContinuous() && tmp <= datalimit )
 +    {
 +        *(_Tp*)(data + (size.p[0]++) * step.p[0]) = elem;
 +        dataend = tmp;
 +    }
 +    else
 +        push_back_(&elem);
 +}
 +
 +template<typename _Tp> inline
 +void Mat::push_back(const Mat_<_Tp>& m)
 +{
 +    push_back((const Mat&)m);
 +}
 +
 +
 +
 +///////////////////////////// Mat::MSize ////////////////////////////
 +
 +inline
 +Mat::MSize::MSize(int* _p)
 +    : p(_p) {}
 +
 +inline
 +Size Mat::MSize::operator()() const
 +{
 +    CV_DbgAssert(p[-1] <= 2);
 +    return Size(p[1], p[0]);
 +}
 +
 +inline
 +const int& Mat::MSize::operator[](int i) const
 +{
 +    return p[i];
 +}
 +
 +inline
 +int& Mat::MSize::operator[](int i)
 +{
 +    return p[i];
 +}
 +
 +inline
 +Mat::MSize::operator const int*() const
 +{
 +    return p;
 +}
 +
 +inline
 +bool Mat::MSize::operator == (const MSize& sz) const
 +{
 +    int d = p[-1];
 +    int dsz = sz.p[-1];
 +    if( d != dsz )
 +        return false;
 +    if( d == 2 )
 +        return p[0] == sz.p[0] && p[1] == sz.p[1];
 +
 +    for( int i = 0; i < d; i++ )
 +        if( p[i] != sz.p[i] )
 +            return false;
 +    return true;
 +}
 +
 +inline
 +bool Mat::MSize::operator != (const MSize& sz) const
 +{
 +    return !(*this == sz);
 +}
 +
 +
 +
 +///////////////////////////// Mat::MStep ////////////////////////////
 +
 +inline
 +Mat::MStep::MStep()
 +{
 +    p = buf; p[0] = p[1] = 0;
 +}
 +
 +inline
 +Mat::MStep::MStep(size_t s)
 +{
 +    p = buf; p[0] = s; p[1] = 0;
 +}
 +
 +inline
 +const size_t& Mat::MStep::operator[](int i) const
 +{
 +    return p[i];
 +}
 +
 +inline
 +size_t& Mat::MStep::operator[](int i)
 +{
 +    return p[i];
 +}
 +
 +inline Mat::MStep::operator size_t() const
 +{
 +    CV_DbgAssert( p == buf );
 +    return buf[0];
 +}
 +
 +inline Mat::MStep& Mat::MStep::operator = (size_t s)
 +{
 +    CV_DbgAssert( p == buf );
 +    buf[0] = s;
 +    return *this;
 +}
 +
 +
 +
 +////////////////////////////// Mat_<_Tp> ////////////////////////////
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::Mat_()
 +    : Mat()
 +{
 +    flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::Mat_(int _rows, int _cols)
 +    : Mat(_rows, _cols, DataType<_Tp>::type)
 +{
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value)
 +    : Mat(_rows, _cols, DataType<_Tp>::type)
 +{
 +    *this = value;
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::Mat_(Size _sz)
 +    : Mat(_sz.height, _sz.width, DataType<_Tp>::type)
 +{}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::Mat_(Size _sz, const _Tp& value)
 +    : Mat(_sz.height, _sz.width, DataType<_Tp>::type)
 +{
 +    *this = value;
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::Mat_(int _dims, const int* _sz)
 +    : Mat(_dims, _sz, DataType<_Tp>::type)
 +{}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::Mat_(int _dims, const int* _sz, const _Tp& _s)
 +    : Mat(_dims, _sz, DataType<_Tp>::type, Scalar(_s))
 +{}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const Range* ranges)
 +    : Mat(m, ranges)
 +{}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::Mat_(const Mat& m)
 +    : Mat()
 +{
 +    flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
 +    *this = m;
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::Mat_(const Mat_& m)
 +    : Mat(m)
 +{}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t steps)
 +    : Mat(_rows, _cols, DataType<_Tp>::type, _data, steps)
 +{}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::Mat_(const Mat_& m, const Range& _rowRange, const Range& _colRange)
 +    : Mat(m, _rowRange, _colRange)
 +{}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
 +    : Mat(m, roi)
 +{}
 +
 +template<typename _Tp> template<int n> inline
 +Mat_<_Tp>::Mat_(const Vec<typename DataType<_Tp>::channel_type, n>& vec, bool copyData)
 +    : Mat(n / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&vec)
 +{
 +    CV_Assert(n%DataType<_Tp>::channels == 0);
 +    if( copyData )
 +        *this = clone();
 +}
 +
 +template<typename _Tp> template<int m, int n> inline
 +Mat_<_Tp>::Mat_(const Matx<typename DataType<_Tp>::channel_type, m, n>& M, bool copyData)
 +    : Mat(m, n / DataType<_Tp>::channels, DataType<_Tp>::type, (void*)&M)
 +{
 +    CV_Assert(n % DataType<_Tp>::channels == 0);
 +    if( copyData )
 +        *this = clone();
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
 +    : Mat(2 / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
 +{
 +    CV_Assert(2 % DataType<_Tp>::channels == 0);
 +    if( copyData )
 +        *this = clone();
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
 +    : Mat(3 / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
 +{
 +    CV_Assert(3 % DataType<_Tp>::channels == 0);
 +    if( copyData )
 +        *this = clone();
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::Mat_(const MatCommaInitializer_<_Tp>& commaInitializer)
 +    : Mat(commaInitializer)
 +{}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::Mat_(const std::vector<_Tp>& vec, bool copyData)
 +    : Mat(vec, copyData)
 +{}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m)
 +{
 +    if( DataType<_Tp>::type == m.type() )
 +    {
 +        Mat::operator = (m);
 +        return *this;
 +    }
 +    if( DataType<_Tp>::depth == m.depth() )
 +    {
 +        return (*this = m.reshape(DataType<_Tp>::channels, m.dims, 0));
 +    }
 +    CV_DbgAssert(DataType<_Tp>::channels == m.channels());
 +    m.convertTo(*this, type());
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat_& m)
 +{
 +    Mat::operator=(m);
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>& Mat_<_Tp>::operator = (const _Tp& s)
 +{
 +    typedef typename DataType<_Tp>::vec_type VT;
 +    Mat::operator=(Scalar((const VT&)s));
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +void Mat_<_Tp>::create(int _rows, int _cols)
 +{
 +    Mat::create(_rows, _cols, DataType<_Tp>::type);
 +}
 +
 +template<typename _Tp> inline
 +void Mat_<_Tp>::create(Size _sz)
 +{
 +    Mat::create(_sz, DataType<_Tp>::type);
 +}
 +
 +template<typename _Tp> inline
 +void Mat_<_Tp>::create(int _dims, const int* _sz)
 +{
 +    Mat::create(_dims, _sz, DataType<_Tp>::type);
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const
 +{
 +    return Mat_<_Tp>(Mat::cross(m));
 +}
 +
 +template<typename _Tp> template<typename T2> inline
 +Mat_<_Tp>::operator Mat_<T2>() const
 +{
 +    return Mat_<T2>(*this);
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp> Mat_<_Tp>::row(int y) const
 +{
 +    return Mat_(*this, Range(y, y+1), Range::all());
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp> Mat_<_Tp>::col(int x) const
 +{
 +    return Mat_(*this, Range::all(), Range(x, x+1));
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp> Mat_<_Tp>::diag(int d) const
 +{
 +    return Mat_(Mat::diag(d));
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp> Mat_<_Tp>::clone() const
 +{
 +    return Mat_(Mat::clone());
 +}
 +
 +template<typename _Tp> inline
 +size_t Mat_<_Tp>::elemSize() const
 +{
 +    CV_DbgAssert( Mat::elemSize() == sizeof(_Tp) );
 +    return sizeof(_Tp);
 +}
 +
 +template<typename _Tp> inline
 +size_t Mat_<_Tp>::elemSize1() const
 +{
 +    CV_DbgAssert( Mat::elemSize1() == sizeof(_Tp) / DataType<_Tp>::channels );
 +    return sizeof(_Tp) / DataType<_Tp>::channels;
 +}
 +
 +template<typename _Tp> inline
 +int Mat_<_Tp>::type() const
 +{
 +    CV_DbgAssert( Mat::type() == DataType<_Tp>::type );
 +    return DataType<_Tp>::type;
 +}
 +
 +template<typename _Tp> inline
 +int Mat_<_Tp>::depth() const
 +{
 +    CV_DbgAssert( Mat::depth() == DataType<_Tp>::depth );
 +    return DataType<_Tp>::depth;
 +}
 +
 +template<typename _Tp> inline
 +int Mat_<_Tp>::channels() const
 +{
 +    CV_DbgAssert( Mat::channels() == DataType<_Tp>::channels );
 +    return DataType<_Tp>::channels;
 +}
 +
 +template<typename _Tp> inline
 +size_t Mat_<_Tp>::stepT(int i) const
 +{
 +    return step.p[i] / elemSize();
 +}
 +
 +template<typename _Tp> inline
 +size_t Mat_<_Tp>::step1(int i) const
 +{
 +    return step.p[i] / elemSize1();
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>& Mat_<_Tp>::adjustROI( int dtop, int dbottom, int dleft, int dright )
 +{
 +    return (Mat_<_Tp>&)(Mat::adjustROI(dtop, dbottom, dleft, dright));
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp> Mat_<_Tp>::operator()( const Range& _rowRange, const Range& _colRange ) const
 +{
 +    return Mat_<_Tp>(*this, _rowRange, _colRange);
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const
 +{
 +    return Mat_<_Tp>(*this, roi);
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp> Mat_<_Tp>::operator()( const Range* ranges ) const
 +{
 +    return Mat_<_Tp>(*this, ranges);
 +}
 +
 +template<typename _Tp> inline
 +_Tp* Mat_<_Tp>::operator [](int y)
 +{
 +    return (_Tp*)ptr(y);
 +}
 +
 +template<typename _Tp> inline
 +const _Tp* Mat_<_Tp>::operator [](int y) const
 +{
 +    return (const _Tp*)ptr(y);
 +}
 +
 +template<typename _Tp> inline
 +_Tp& Mat_<_Tp>::operator ()(int i0, int i1)
 +{
 +    CV_DbgAssert( dims <= 2 && data &&
 +                  (unsigned)i0 < (unsigned)size.p[0] &&
 +                  (unsigned)i1 < (unsigned)size.p[1] &&
 +                  type() == DataType<_Tp>::type );
 +    return ((_Tp*)(data + step.p[0] * i0))[i1];
 +}
 +
 +template<typename _Tp> inline
 +const _Tp& Mat_<_Tp>::operator ()(int i0, int i1) const
 +{
 +    CV_DbgAssert( dims <= 2 && data &&
 +                  (unsigned)i0 < (unsigned)size.p[0] &&
 +                  (unsigned)i1 < (unsigned)size.p[1] &&
 +                  type() == DataType<_Tp>::type );
 +    return ((const _Tp*)(data + step.p[0] * i0))[i1];
 +}
 +
 +template<typename _Tp> inline
 +_Tp& Mat_<_Tp>::operator ()(Point pt)
 +{
 +    CV_DbgAssert( dims <= 2 && data &&
 +                  (unsigned)pt.y < (unsigned)size.p[0] &&
 +                  (unsigned)pt.x < (unsigned)size.p[1] &&
 +                  type() == DataType<_Tp>::type );
 +    return ((_Tp*)(data + step.p[0] * pt.y))[pt.x];
 +}
 +
 +template<typename _Tp> inline
 +const _Tp& Mat_<_Tp>::operator ()(Point pt) const
 +{
 +    CV_DbgAssert( dims <= 2 && data &&
 +                  (unsigned)pt.y < (unsigned)size.p[0] &&
 +                  (unsigned)pt.x < (unsigned)size.p[1] &&
 +                 type() == DataType<_Tp>::type );
 +    return ((const _Tp*)(data + step.p[0] * pt.y))[pt.x];
 +}
 +
 +template<typename _Tp> inline
 +_Tp& Mat_<_Tp>::operator ()(const int* idx)
 +{
 +    return Mat::at<_Tp>(idx);
 +}
 +
 +template<typename _Tp> inline
 +const _Tp& Mat_<_Tp>::operator ()(const int* idx) const
 +{
 +    return Mat::at<_Tp>(idx);
 +}
 +
 +template<typename _Tp> template<int n> inline
 +_Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx)
 +{
 +    return Mat::at<_Tp>(idx);
 +}
 +
 +template<typename _Tp> template<int n> inline
 +const _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx) const
 +{
 +    return Mat::at<_Tp>(idx);
 +}
 +
 +template<typename _Tp> inline
 +_Tp& Mat_<_Tp>::operator ()(int i0)
 +{
 +    return this->at<_Tp>(i0);
 +}
 +
 +template<typename _Tp> inline
 +const _Tp& Mat_<_Tp>::operator ()(int i0) const
 +{
 +    return this->at<_Tp>(i0);
 +}
 +
 +template<typename _Tp> inline
 +_Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2)
 +{
 +    return this->at<_Tp>(i0, i1, i2);
 +}
 +
 +template<typename _Tp> inline
 +const _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2) const
 +{
 +    return this->at<_Tp>(i0, i1, i2);
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::operator std::vector<_Tp>() const
 +{
 +    std::vector<_Tp> v;
 +    copyTo(v);
 +    return v;
 +}
 +
 +template<typename _Tp> template<int n> inline
 +Mat_<_Tp>::operator Vec<typename DataType<_Tp>::channel_type, n>() const
 +{
 +    CV_Assert(n % DataType<_Tp>::channels == 0);
 +    return this->Mat::operator Vec<typename DataType<_Tp>::channel_type, n>();
 +}
 +
 +template<typename _Tp> template<int m, int n> inline
 +Mat_<_Tp>::operator Matx<typename DataType<_Tp>::channel_type, m, n>() const
 +{
 +    CV_Assert(n % DataType<_Tp>::channels == 0);
 +    return this->Mat::operator Matx<typename DataType<_Tp>::channel_type, m, n>();
 +}
 +
 +template<typename _Tp> inline
 +MatConstIterator_<_Tp> Mat_<_Tp>::begin() const
 +{
 +    return Mat::begin<_Tp>();
 +}
 +
 +template<typename _Tp> inline
 +MatConstIterator_<_Tp> Mat_<_Tp>::end() const
 +{
 +    return Mat::end<_Tp>();
 +}
 +
 +template<typename _Tp> inline
 +MatIterator_<_Tp> Mat_<_Tp>::begin()
 +{
 +    return Mat::begin<_Tp>();
 +}
 +
 +template<typename _Tp> inline
 +MatIterator_<_Tp> Mat_<_Tp>::end()
 +{
 +    return Mat::end<_Tp>();
 +}
 +
 +
 +/*template<typename T1, typename T2, typename Op> inline
 +void process( const Mat_<T1>& m1, Mat_<T2>& m2, Op op )
 +{
 +    int y, x, rows = m1.rows, cols = m1.cols;
 +
 +    CV_DbgAssert( m1.size() == m2.size() );
 +
 +    for( y = 0; y < rows; y++ )
 +    {
 +        const T1* src = m1[y];
 +        T2* dst = m2[y];
 +
 +        for( x = 0; x < cols; x++ )
 +            dst[x] = op(src[x]);
 +    }
 +}
 +
 +template<typename T1, typename T2, typename T3, typename Op> inline
 +void process( const Mat_<T1>& m1, const Mat_<T2>& m2, Mat_<T3>& m3, Op op )
 +{
 +    int y, x, rows = m1.rows, cols = m1.cols;
 +
 +    CV_DbgAssert( m1.size() == m2.size() );
 +
 +    for( y = 0; y < rows; y++ )
 +    {
 +        const T1* src1 = m1[y];
 +        const T2* src2 = m2[y];
 +        T3* dst = m3[y];
 +
 +        for( x = 0; x < cols; x++ )
 +            dst[x] = op( src1[x], src2[x] );
 +    }
 +}*/
 +
 +
 +
 +///////////////////////////// SparseMat /////////////////////////////
 +
 +inline
 +SparseMat::SparseMat()
 +    : flags(MAGIC_VAL), hdr(0)
 +{}
 +
 +inline
 +SparseMat::SparseMat(int _dims, const int* _sizes, int _type)
 +    : flags(MAGIC_VAL), hdr(0)
 +{
 +    create(_dims, _sizes, _type);
 +}
 +
 +inline
 +SparseMat::SparseMat(const SparseMat& m)
 +    : flags(m.flags), hdr(m.hdr)
 +{
 +    addref();
 +}
 +
 +inline
 +SparseMat::~SparseMat()
 +{
 +    release();
 +}
 +
 +inline
 +SparseMat& SparseMat::operator = (const SparseMat& m)
 +{
 +    if( this != &m )
 +    {
 +        if( m.hdr )
 +            CV_XADD(&m.hdr->refcount, 1);
 +        release();
 +        flags = m.flags;
 +        hdr = m.hdr;
 +    }
 +    return *this;
 +}
 +
 +inline
 +SparseMat& SparseMat::operator = (const Mat& m)
 +{
 +    return (*this = SparseMat(m));
 +}
 +
 +inline
 +SparseMat SparseMat::clone() const
 +{
 +    SparseMat temp;
 +    this->copyTo(temp);
 +    return temp;
 +}
 +
 +inline
 +void SparseMat::assignTo( SparseMat& m, int _type ) const
 +{
 +    if( _type < 0 )
 +        m = *this;
 +    else
 +        convertTo(m, _type);
 +}
 +
 +inline
 +void SparseMat::addref()
 +{
 +    if( hdr )
 +        CV_XADD(&hdr->refcount, 1);
 +}
 +
 +inline
 +void SparseMat::release()
 +{
 +    if( hdr && CV_XADD(&hdr->refcount, -1) == 1 )
 +        delete hdr;
 +    hdr = 0;
 +}
 +
 +inline
 +size_t SparseMat::elemSize() const
 +{
 +    return CV_ELEM_SIZE(flags);
 +}
 +
 +inline
 +size_t SparseMat::elemSize1() const
 +{
 +    return CV_ELEM_SIZE1(flags);
 +}
 +
 +inline
 +int SparseMat::type() const
 +{
 +    return CV_MAT_TYPE(flags);
 +}
 +
 +inline
 +int SparseMat::depth() const
 +{
 +    return CV_MAT_DEPTH(flags);
 +}
 +
 +inline
 +int SparseMat::channels() const
 +{
 +    return CV_MAT_CN(flags);
 +}
 +
 +inline
 +const int* SparseMat::size() const
 +{
 +    return hdr ? hdr->size : 0;
 +}
 +
 +inline
 +int SparseMat::size(int i) const
 +{
 +    if( hdr )
 +    {
 +        CV_DbgAssert((unsigned)i < (unsigned)hdr->dims);
 +        return hdr->size[i];
 +    }
 +    return 0;
 +}
 +
 +inline
 +int SparseMat::dims() const
 +{
 +    return hdr ? hdr->dims : 0;
 +}
 +
 +inline
 +size_t SparseMat::nzcount() const
 +{
 +    return hdr ? hdr->nodeCount : 0;
 +}
 +
 +inline
 +size_t SparseMat::hash(int i0) const
 +{
 +    return (size_t)i0;
 +}
 +
 +inline
 +size_t SparseMat::hash(int i0, int i1) const
 +{
 +    return (size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1;
 +}
 +
 +inline
 +size_t SparseMat::hash(int i0, int i1, int i2) const
 +{
 +    return ((size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1) * HASH_SCALE + (unsigned)i2;
 +}
 +
 +inline
 +size_t SparseMat::hash(const int* idx) const
 +{
 +    size_t h = (unsigned)idx[0];
 +    if( !hdr )
 +        return 0;
 +    int d = hdr->dims;
 +    for(int i = 1; i < d; i++ )
 +        h = h * HASH_SCALE + (unsigned)idx[i];
 +    return h;
 +}
 +
 +template<typename _Tp> inline
 +_Tp& SparseMat::ref(int i0, size_t* hashval)
 +{
 +    return *(_Tp*)((SparseMat*)this)->ptr(i0, true, hashval);
 +}
 +
 +template<typename _Tp> inline
 +_Tp& SparseMat::ref(int i0, int i1, size_t* hashval)
 +{
 +    return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, true, hashval);
 +}
 +
 +template<typename _Tp> inline
 +_Tp& SparseMat::ref(int i0, int i1, int i2, size_t* hashval)
 +{
 +    return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, i2, true, hashval);
 +}
 +
 +template<typename _Tp> inline
 +_Tp& SparseMat::ref(const int* idx, size_t* hashval)
 +{
 +    return *(_Tp*)((SparseMat*)this)->ptr(idx, true, hashval);
 +}
 +
 +template<typename _Tp> inline
 +_Tp SparseMat::value(int i0, size_t* hashval) const
 +{
 +    const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
 +    return p ? *p : _Tp();
 +}
 +
 +template<typename _Tp> inline
 +_Tp SparseMat::value(int i0, int i1, size_t* hashval) const
 +{
 +    const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
 +    return p ? *p : _Tp();
 +}
 +
 +template<typename _Tp> inline
 +_Tp SparseMat::value(int i0, int i1, int i2, size_t* hashval) const
 +{
 +    const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval);
 +    return p ? *p : _Tp();
 +}
 +
 +template<typename _Tp> inline
 +_Tp SparseMat::value(const int* idx, size_t* hashval) const
 +{
 +    const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval);
 +    return p ? *p : _Tp();
 +}
 +
 +template<typename _Tp> inline
 +const _Tp* SparseMat::find(int i0, size_t* hashval) const
 +{
 +    return (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
 +}
 +
 +template<typename _Tp> inline
 +const _Tp* SparseMat::find(int i0, int i1, size_t* hashval) const
 +{
 +    return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
 +}
 +
 +template<typename _Tp> inline
 +const _Tp* SparseMat::find(int i0, int i1, int i2, size_t* hashval) const
 +{
 +    return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval);
 +}
 +
 +template<typename _Tp> inline
 +const _Tp* SparseMat::find(const int* idx, size_t* hashval) const
 +{
 +    return (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval);
 +}
 +
 +template<typename _Tp> inline
 +_Tp& SparseMat::value(Node* n)
 +{
 +    return *(_Tp*)((uchar*)n + hdr->valueOffset);
 +}
 +
 +template<typename _Tp> inline
 +const _Tp& SparseMat::value(const Node* n) const
 +{
 +    return *(const _Tp*)((const uchar*)n + hdr->valueOffset);
 +}
 +
 +inline
 +SparseMat::Node* SparseMat::node(size_t nidx)
 +{
 +    return (Node*)&hdr->pool[nidx];
 +}
 +
 +inline
 +const SparseMat::Node* SparseMat::node(size_t nidx) const
 +{
 +    return (const Node*)&hdr->pool[nidx];
 +}
 +
 +inline
 +SparseMatIterator SparseMat::begin()
 +{
 +    return SparseMatIterator(this);
 +}
 +
 +inline
 +SparseMatConstIterator SparseMat::begin() const
 +{
 +    return SparseMatConstIterator(this);
 +}
 +
 +inline
 +SparseMatIterator SparseMat::end()
 +{
 +    SparseMatIterator it(this);
 +    it.seekEnd();
 +    return it;
 +}
 +
 +inline
 +SparseMatConstIterator SparseMat::end() const
 +{
 +    SparseMatConstIterator it(this);
 +    it.seekEnd();
 +    return it;
 +}
 +
 +template<typename _Tp> inline
 +SparseMatIterator_<_Tp> SparseMat::begin()
 +{
 +    return SparseMatIterator_<_Tp>(this);
 +}
 +
 +template<typename _Tp> inline
 +SparseMatConstIterator_<_Tp> SparseMat::begin() const
 +{
 +    return SparseMatConstIterator_<_Tp>(this);
 +}
 +
 +template<typename _Tp> inline
 +SparseMatIterator_<_Tp> SparseMat::end()
 +{
 +    SparseMatIterator_<_Tp> it(this);
 +    it.seekEnd();
 +    return it;
 +}
 +
 +template<typename _Tp> inline
 +SparseMatConstIterator_<_Tp> SparseMat::end() const
 +{
 +    SparseMatConstIterator_<_Tp> it(this);
 +    it.seekEnd();
 +    return it;
 +}
 +
 +
 +
 +///////////////////////////// SparseMat_ ////////////////////////////
 +
 +template<typename _Tp> inline
 +SparseMat_<_Tp>::SparseMat_()
 +{
 +    flags = MAGIC_VAL | DataType<_Tp>::type;
 +}
 +
 +template<typename _Tp> inline
 +SparseMat_<_Tp>::SparseMat_(int _dims, const int* _sizes)
 +    : SparseMat(_dims, _sizes, DataType<_Tp>::type)
 +{}
 +
 +template<typename _Tp> inline
 +SparseMat_<_Tp>::SparseMat_(const SparseMat& m)
 +{
 +    if( m.type() == DataType<_Tp>::type )
 +        *this = (const SparseMat_<_Tp>&)m;
 +    else
 +        m.convertTo(this, DataType<_Tp>::type);
 +}
 +
 +template<typename _Tp> inline
 +SparseMat_<_Tp>::SparseMat_(const SparseMat_<_Tp>& m)
 +{
 +    this->flags = m.flags;
 +    this->hdr = m.hdr;
 +    if( this->hdr )
 +        CV_XADD(&this->hdr->refcount, 1);
 +}
 +
 +template<typename _Tp> inline
 +SparseMat_<_Tp>::SparseMat_(const Mat& m)
 +{
 +    SparseMat sm(m);
 +    *this = sm;
 +}
 +
 +template<typename _Tp> inline
 +SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const SparseMat_<_Tp>& m)
 +{
 +    if( this != &m )
 +    {
 +        if( m.hdr ) CV_XADD(&m.hdr->refcount, 1);
 +        release();
 +        flags = m.flags;
 +        hdr = m.hdr;
 +    }
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const SparseMat& m)
 +{
 +    if( m.type() == DataType<_Tp>::type )
 +        return (*this = (const SparseMat_<_Tp>&)m);
 +    m.convertTo(*this, DataType<_Tp>::type);
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const Mat& m)
 +{
 +    return (*this = SparseMat(m));
 +}
 +
 +template<typename _Tp> inline
 +SparseMat_<_Tp> SparseMat_<_Tp>::clone() const
 +{
 +    SparseMat_<_Tp> m;
 +    this->copyTo(m);
 +    return m;
 +}
 +
 +template<typename _Tp> inline
 +void SparseMat_<_Tp>::create(int _dims, const int* _sizes)
 +{
 +    SparseMat::create(_dims, _sizes, DataType<_Tp>::type);
 +}
 +
 +template<typename _Tp> inline
 +int SparseMat_<_Tp>::type() const
 +{
 +    return DataType<_Tp>::type;
 +}
 +
 +template<typename _Tp> inline
 +int SparseMat_<_Tp>::depth() const
 +{
 +    return DataType<_Tp>::depth;
 +}
 +
 +template<typename _Tp> inline
 +int SparseMat_<_Tp>::channels() const
 +{
 +    return DataType<_Tp>::channels;
 +}
 +
 +template<typename _Tp> inline
 +_Tp& SparseMat_<_Tp>::ref(int i0, size_t* hashval)
 +{
 +    return SparseMat::ref<_Tp>(i0, hashval);
 +}
 +
 +template<typename _Tp> inline
 +_Tp SparseMat_<_Tp>::operator()(int i0, size_t* hashval) const
 +{
 +    return SparseMat::value<_Tp>(i0, hashval);
 +}
 +
 +template<typename _Tp> inline
 +_Tp& SparseMat_<_Tp>::ref(int i0, int i1, size_t* hashval)
 +{
 +    return SparseMat::ref<_Tp>(i0, i1, hashval);
 +}
 +
 +template<typename _Tp> inline
 +_Tp SparseMat_<_Tp>::operator()(int i0, int i1, size_t* hashval) const
 +{
 +    return SparseMat::value<_Tp>(i0, i1, hashval);
 +}
 +
 +template<typename _Tp> inline
 +_Tp& SparseMat_<_Tp>::ref(int i0, int i1, int i2, size_t* hashval)
 +{
 +    return SparseMat::ref<_Tp>(i0, i1, i2, hashval);
 +}
 +
 +template<typename _Tp> inline
 +_Tp SparseMat_<_Tp>::operator()(int i0, int i1, int i2, size_t* hashval) const
 +{
 +    return SparseMat::value<_Tp>(i0, i1, i2, hashval);
 +}
 +
 +template<typename _Tp> inline
 +_Tp& SparseMat_<_Tp>::ref(const int* idx, size_t* hashval)
 +{
 +    return SparseMat::ref<_Tp>(idx, hashval);
 +}
 +
 +template<typename _Tp> inline
 +_Tp SparseMat_<_Tp>::operator()(const int* idx, size_t* hashval) const
 +{
 +    return SparseMat::value<_Tp>(idx, hashval);
 +}
 +
 +template<typename _Tp> inline
 +SparseMatIterator_<_Tp> SparseMat_<_Tp>::begin()
 +{
 +    return SparseMatIterator_<_Tp>(this);
 +}
 +
 +template<typename _Tp> inline
 +SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::begin() const
 +{
 +    return SparseMatConstIterator_<_Tp>(this);
 +}
 +
 +template<typename _Tp> inline
 +SparseMatIterator_<_Tp> SparseMat_<_Tp>::end()
 +{
 +    SparseMatIterator_<_Tp> it(this);
 +    it.seekEnd();
 +    return it;
 +}
 +
 +template<typename _Tp> inline
 +SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::end() const
 +{
 +    SparseMatConstIterator_<_Tp> it(this);
 +    it.seekEnd();
 +    return it;
 +}
 +
 +
 +
 +////////////////////////// MatConstIterator /////////////////////////
 +
 +inline
 +MatConstIterator::MatConstIterator()
 +    : m(0), elemSize(0), ptr(0), sliceStart(0), sliceEnd(0)
 +{}
 +
 +inline
 +MatConstIterator::MatConstIterator(const Mat* _m)
 +    : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
 +{
 +    if( m && m->isContinuous() )
 +    {
 +        sliceStart = m->data;
 +        sliceEnd = sliceStart + m->total()*elemSize;
 +    }
 +    seek((const int*)0);
 +}
 +
 +inline
 +MatConstIterator::MatConstIterator(const Mat* _m, int _row, int _col)
 +    : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
 +{
 +    CV_Assert(m && m->dims <= 2);
 +    if( m->isContinuous() )
 +    {
 +        sliceStart = m->data;
 +        sliceEnd = sliceStart + m->total()*elemSize;
 +    }
 +    int idx[] = {_row, _col};
 +    seek(idx);
 +}
 +
 +inline
 +MatConstIterator::MatConstIterator(const Mat* _m, Point _pt)
 +    : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
 +{
 +    CV_Assert(m && m->dims <= 2);
 +    if( m->isContinuous() )
 +    {
 +        sliceStart = m->data;
 +        sliceEnd = sliceStart + m->total()*elemSize;
 +    }
 +    int idx[] = {_pt.y, _pt.x};
 +    seek(idx);
 +}
 +
 +inline
 +MatConstIterator::MatConstIterator(const MatConstIterator& it)
 +    : m(it.m), elemSize(it.elemSize), ptr(it.ptr), sliceStart(it.sliceStart), sliceEnd(it.sliceEnd)
 +{}
 +
 +inline
 +MatConstIterator& MatConstIterator::operator = (const MatConstIterator& it )
 +{
 +    m = it.m; elemSize = it.elemSize; ptr = it.ptr;
 +    sliceStart = it.sliceStart; sliceEnd = it.sliceEnd;
 +    return *this;
 +}
 +
 +inline
 +uchar* MatConstIterator::operator *() const
 +{
 +    return ptr;
 +}
 +
 +inline MatConstIterator& MatConstIterator::operator += (ptrdiff_t ofs)
 +{
 +    if( !m || ofs == 0 )
 +        return *this;
 +    ptrdiff_t ofsb = ofs*elemSize;
 +    ptr += ofsb;
 +    if( ptr < sliceStart || sliceEnd <= ptr )
 +    {
 +        ptr -= ofsb;
 +        seek(ofs, true);
 +    }
 +    return *this;
 +}
 +
 +inline
 +MatConstIterator& MatConstIterator::operator -= (ptrdiff_t ofs)
 +{
 +    return (*this += -ofs);
 +}
 +
 +inline
 +MatConstIterator& MatConstIterator::operator --()
 +{
 +    if( m && (ptr -= elemSize) < sliceStart )
 +    {
 +        ptr += elemSize;
 +        seek(-1, true);
 +    }
 +    return *this;
 +}
 +
 +inline
 +MatConstIterator MatConstIterator::operator --(int)
 +{
 +    MatConstIterator b = *this;
 +    *this += -1;
 +    return b;
 +}
 +
 +inline
 +MatConstIterator& MatConstIterator::operator ++()
 +{
 +    if( m && (ptr += elemSize) >= sliceEnd )
 +    {
 +        ptr -= elemSize;
 +        seek(1, true);
 +    }
 +    return *this;
 +}
 +
 +inline MatConstIterator MatConstIterator::operator ++(int)
 +{
 +    MatConstIterator b = *this;
 +    *this += 1;
 +    return b;
 +}
 +
 +
 +static inline
 +bool operator == (const MatConstIterator& a, const MatConstIterator& b)
 +{
 +    return a.m == b.m && a.ptr == b.ptr;
 +}
 +
 +static inline
 +bool operator != (const MatConstIterator& a, const MatConstIterator& b)
 +{
 +    return !(a == b);
 +}
 +
 +static inline
 +bool operator < (const MatConstIterator& a, const MatConstIterator& b)
 +{
 +    return a.ptr < b.ptr;
 +}
 +
 +static inline
 +bool operator > (const MatConstIterator& a, const MatConstIterator& b)
 +{
 +    return a.ptr > b.ptr;
 +}
 +
 +static inline
 +bool operator <= (const MatConstIterator& a, const MatConstIterator& b)
 +{
 +    return a.ptr <= b.ptr;
 +}
 +
 +static inline
 +bool operator >= (const MatConstIterator& a, const MatConstIterator& b)
 +{
 +    return a.ptr >= b.ptr;
 +}
 +
 +static inline
 +ptrdiff_t operator - (const MatConstIterator& b, const MatConstIterator& a)
 +{
 +    if( a.m != b.m )
 +        return ((size_t)(-1) >> 1);
 +    if( a.sliceEnd == b.sliceEnd )
 +        return (b.ptr - a.ptr)/b.elemSize;
 +
 +    return b.lpos() - a.lpos();
 +}
 +
 +static inline
 +MatConstIterator operator + (const MatConstIterator& a, ptrdiff_t ofs)
 +{
 +    MatConstIterator b = a;
 +    return b += ofs;
 +}
 +
 +static inline
 +MatConstIterator operator + (ptrdiff_t ofs, const MatConstIterator& a)
 +{
 +    MatConstIterator b = a;
 +    return b += ofs;
 +}
 +
 +static inline
 +MatConstIterator operator - (const MatConstIterator& a, ptrdiff_t ofs)
 +{
 +    MatConstIterator b = a;
 +    return b += -ofs;
 +}
 +
 +
 +inline
 +uchar* MatConstIterator::operator [](ptrdiff_t i) const
 +{
 +    return *(*this + i);
 +}
 +
 +
 +
 +///////////////////////// MatConstIterator_ /////////////////////////
 +
 +template<typename _Tp> inline
 +MatConstIterator_<_Tp>::MatConstIterator_()
 +{}
 +
 +template<typename _Tp> inline
 +MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m)
 +    : MatConstIterator(_m)
 +{}
 +
 +template<typename _Tp> inline
 +MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col)
 +    : MatConstIterator(_m, _row, _col)
 +{}
 +
 +template<typename _Tp> inline
 +MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m, Point _pt)
 +    : MatConstIterator(_m, _pt)
 +{}
 +
 +template<typename _Tp> inline
 +MatConstIterator_<_Tp>::MatConstIterator_(const MatConstIterator_& it)
 +    : MatConstIterator(it)
 +{}
 +
 +template<typename _Tp> inline
 +MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator = (const MatConstIterator_& it )
 +{
 +    MatConstIterator::operator = (it);
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +_Tp MatConstIterator_<_Tp>::operator *() const
 +{
 +    return *(_Tp*)(this->ptr);
 +}
 +
 +template<typename _Tp> inline
 +MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator += (ptrdiff_t ofs)
 +{
 +    MatConstIterator::operator += (ofs);
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator -= (ptrdiff_t ofs)
 +{
 +    return (*this += -ofs);
 +}
 +
 +template<typename _Tp> inline
 +MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator --()
 +{
 +    MatConstIterator::operator --();
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator --(int)
 +{
 +    MatConstIterator_ b = *this;
 +    MatConstIterator::operator --();
 +    return b;
 +}
 +
 +template<typename _Tp> inline
 +MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator ++()
 +{
 +    MatConstIterator::operator ++();
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator ++(int)
 +{
 +    MatConstIterator_ b = *this;
 +    MatConstIterator::operator ++();
 +    return b;
 +}
 +
 +
 +template<typename _Tp> inline
 +Point MatConstIterator_<_Tp>::pos() const
 +{
 +    if( !m )
 +        return Point();
 +    CV_DbgAssert( m->dims <= 2 );
 +    if( m->isContinuous() )
 +    {
 +        ptrdiff_t ofs = (const _Tp*)ptr - (const _Tp*)m->data;
 +        int y = (int)(ofs / m->cols);
 +        int x = (int)(ofs - (ptrdiff_t)y * m->cols);
 +        return Point(x, y);
 +    }
 +    else
 +    {
 +        ptrdiff_t ofs = (uchar*)ptr - m->data;
 +        int y = (int)(ofs / m->step);
 +        int x = (int)((ofs - y * m->step)/sizeof(_Tp));
 +        return Point(x, y);
 +    }
 +}
 +
 +
 +template<typename _Tp> static inline
 +bool operator == (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
 +{
 +    return a.m == b.m && a.ptr == b.ptr;
 +}
 +
 +template<typename _Tp> static inline
 +bool operator != (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
 +{
 +    return a.m != b.m || a.ptr != b.ptr;
 +}
 +
 +template<typename _Tp> static inline
 +MatConstIterator_<_Tp> operator + (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
 +{
 +    MatConstIterator t = (const MatConstIterator&)a + ofs;
 +    return (MatConstIterator_<_Tp>&)t;
 +}
 +
 +template<typename _Tp> static inline
 +MatConstIterator_<_Tp> operator + (ptrdiff_t ofs, const MatConstIterator_<_Tp>& a)
 +{
 +    MatConstIterator t = (const MatConstIterator&)a + ofs;
 +    return (MatConstIterator_<_Tp>&)t;
 +}
 +
 +template<typename _Tp> static inline
 +MatConstIterator_<_Tp> operator - (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
 +{
 +    MatConstIterator t = (const MatConstIterator&)a - ofs;
 +    return (MatConstIterator_<_Tp>&)t;
 +}
 +
 +template<typename _Tp> inline
 +_Tp MatConstIterator_<_Tp>::operator [](ptrdiff_t i) const
 +{
 +    return *(_Tp*)MatConstIterator::operator [](i);
 +}
 +
 +
 +
 +//////////////////////////// MatIterator_ ///////////////////////////
 +
 +template<typename _Tp> inline
 +MatIterator_<_Tp>::MatIterator_()
 +    : MatConstIterator_<_Tp>()
 +{}
 +
 +template<typename _Tp> inline
 +MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m)
 +    : MatConstIterator_<_Tp>(_m)
 +{}
 +
 +template<typename _Tp> inline
 +MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, int _row, int _col)
 +    : MatConstIterator_<_Tp>(_m, _row, _col)
 +{}
 +
 +template<typename _Tp> inline
 +MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, Point _pt)
 +    : MatConstIterator_<_Tp>(_m, _pt)
 +{}
 +
 +template<typename _Tp> inline
 +MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, const int* _idx)
 +    : MatConstIterator_<_Tp>(_m, _idx)
 +{}
 +
 +template<typename _Tp> inline
 +MatIterator_<_Tp>::MatIterator_(const MatIterator_& it)
 +    : MatConstIterator_<_Tp>(it)
 +{}
 +
 +template<typename _Tp> inline
 +MatIterator_<_Tp>& MatIterator_<_Tp>::operator = (const MatIterator_<_Tp>& it )
 +{
 +    MatConstIterator::operator = (it);
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +_Tp& MatIterator_<_Tp>::operator *() const
 +{
 +    return *(_Tp*)(this->ptr);
 +}
 +
 +template<typename _Tp> inline
 +MatIterator_<_Tp>& MatIterator_<_Tp>::operator += (ptrdiff_t ofs)
 +{
 +    MatConstIterator::operator += (ofs);
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +MatIterator_<_Tp>& MatIterator_<_Tp>::operator -= (ptrdiff_t ofs)
 +{
 +    MatConstIterator::operator += (-ofs);
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +MatIterator_<_Tp>& MatIterator_<_Tp>::operator --()
 +{
 +    MatConstIterator::operator --();
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +MatIterator_<_Tp> MatIterator_<_Tp>::operator --(int)
 +{
 +    MatIterator_ b = *this;
 +    MatConstIterator::operator --();
 +    return b;
 +}
 +
 +template<typename _Tp> inline
 +MatIterator_<_Tp>& MatIterator_<_Tp>::operator ++()
 +{
 +    MatConstIterator::operator ++();
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +MatIterator_<_Tp> MatIterator_<_Tp>::operator ++(int)
 +{
 +    MatIterator_ b = *this;
 +    MatConstIterator::operator ++();
 +    return b;
 +}
 +
 +template<typename _Tp> inline
 +_Tp& MatIterator_<_Tp>::operator [](ptrdiff_t i) const
 +{
 +    return *(*this + i);
 +}
 +
 +
 +template<typename _Tp> static inline
 +bool operator == (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
 +{
 +    return a.m == b.m && a.ptr == b.ptr;
 +}
 +
 +template<typename _Tp> static inline
 +bool operator != (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
 +{
 +    return a.m != b.m || a.ptr != b.ptr;
 +}
 +
 +template<typename _Tp> static inline
 +MatIterator_<_Tp> operator + (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
 +{
 +    MatConstIterator t = (const MatConstIterator&)a + ofs;
 +    return (MatIterator_<_Tp>&)t;
 +}
 +
 +template<typename _Tp> static inline
 +MatIterator_<_Tp> operator + (ptrdiff_t ofs, const MatIterator_<_Tp>& a)
 +{
 +    MatConstIterator t = (const MatConstIterator&)a + ofs;
 +    return (MatIterator_<_Tp>&)t;
 +}
 +
 +template<typename _Tp> static inline
 +MatIterator_<_Tp> operator - (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
 +{
 +    MatConstIterator t = (const MatConstIterator&)a - ofs;
 +    return (MatIterator_<_Tp>&)t;
 +}
 +
 +
 +
 +/////////////////////// SparseMatConstIterator //////////////////////
 +
 +inline
 +SparseMatConstIterator::SparseMatConstIterator()
 +    : m(0), hashidx(0), ptr(0)
 +{}
 +
 +inline
 +SparseMatConstIterator::SparseMatConstIterator(const SparseMatConstIterator& it)
 +    : m(it.m), hashidx(it.hashidx), ptr(it.ptr)
 +{}
 +
 +inline SparseMatConstIterator& SparseMatConstIterator::operator = (const SparseMatConstIterator& it)
 +{
 +    if( this != &it )
 +    {
 +        m = it.m;
 +        hashidx = it.hashidx;
 +        ptr = it.ptr;
 +    }
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +const _Tp& SparseMatConstIterator::value() const
 +{
 +    return *(_Tp*)ptr;
 +}
 +
 +inline
 +const SparseMat::Node* SparseMatConstIterator::node() const
 +{
 +    return (ptr && m && m->hdr) ? (const SparseMat::Node*)(ptr - m->hdr->valueOffset) : 0;
 +}
 +
 +inline
 +SparseMatConstIterator SparseMatConstIterator::operator ++(int)
 +{
 +    SparseMatConstIterator it = *this;
 +    ++*this;
 +    return it;
 +}
 +
 +inline
 +void SparseMatConstIterator::seekEnd()
 +{
 +    if( m && m->hdr )
 +    {
 +        hashidx = m->hdr->hashtab.size();
 +        ptr = 0;
 +    }
 +}
 +
 +
 +static inline
 +bool operator == (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
 +{
 +    return it1.m == it2.m && it1.ptr == it2.ptr;
 +}
 +
 +static inline
 +bool operator != (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
 +{
 +    return !(it1 == it2);
 +}
 +
 +
 +
 +///////////////////////// SparseMatIterator /////////////////////////
 +
 +inline
 +SparseMatIterator::SparseMatIterator()
 +{}
 +
 +inline
 +SparseMatIterator::SparseMatIterator(SparseMat* _m)
 +    : SparseMatConstIterator(_m)
 +{}
 +
 +inline
 +SparseMatIterator::SparseMatIterator(const SparseMatIterator& it)
 +    : SparseMatConstIterator(it)
 +{}
 +
 +inline
 +SparseMatIterator& SparseMatIterator::operator = (const SparseMatIterator& it)
 +{
 +    (SparseMatConstIterator&)*this = it;
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +_Tp& SparseMatIterator::value() const
 +{
 +    return *(_Tp*)ptr;
 +}
 +
 +inline
 +SparseMat::Node* SparseMatIterator::node() const
 +{
 +    return (SparseMat::Node*)SparseMatConstIterator::node();
 +}
 +
 +inline
 +SparseMatIterator& SparseMatIterator::operator ++()
 +{
 +    SparseMatConstIterator::operator ++();
 +    return *this;
 +}
 +
 +inline
 +SparseMatIterator SparseMatIterator::operator ++(int)
 +{
 +    SparseMatIterator it = *this;
 +    ++*this;
 +    return it;
 +}
 +
 +
 +
 +////////////////////// SparseMatConstIterator_ //////////////////////
 +
 +template<typename _Tp> inline
 +SparseMatConstIterator_<_Tp>::SparseMatConstIterator_()
 +{}
 +
 +template<typename _Tp> inline
 +SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat_<_Tp>* _m)
 +    : SparseMatConstIterator(_m)
 +{}
 +
 +template<typename _Tp> inline
++SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat* _m)
++    : SparseMatConstIterator(_m)
++{
++    CV_Assert( _m->type() == DataType<_Tp>::type );
++}
++
++template<typename _Tp> inline
 +SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMatConstIterator_<_Tp>& it)
 +    : SparseMatConstIterator(it)
 +{}
 +
 +template<typename _Tp> inline
 +SparseMatConstIterator_<_Tp>& SparseMatConstIterator_<_Tp>::operator = (const SparseMatConstIterator_<_Tp>& it)
 +{
 +    return reinterpret_cast<SparseMatConstIterator_<_Tp>&>
 +         (*reinterpret_cast<SparseMatConstIterator*>(this) =
 +           reinterpret_cast<const SparseMatConstIterator&>(it));
 +}
 +
 +template<typename _Tp> inline
 +const _Tp& SparseMatConstIterator_<_Tp>::operator *() const
 +{
 +    return *(const _Tp*)this->ptr;
 +}
 +
 +template<typename _Tp> inline
 +SparseMatConstIterator_<_Tp>& SparseMatConstIterator_<_Tp>::operator ++()
 +{
 +    SparseMatConstIterator::operator ++();
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +SparseMatConstIterator_<_Tp> SparseMatConstIterator_<_Tp>::operator ++(int)
 +{
 +    SparseMatConstIterator it = *this;
 +    SparseMatConstIterator::operator ++();
 +    return it;
 +}
 +
 +
 +
 +///////////////////////// SparseMatIterator_ ////////////////////////
 +
 +template<typename _Tp> inline
 +SparseMatIterator_<_Tp>::SparseMatIterator_()
 +{}
 +
 +template<typename _Tp> inline
 +SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat_<_Tp>* _m)
 +    : SparseMatConstIterator_<_Tp>(_m)
 +{}
 +
 +template<typename _Tp> inline
++SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat* _m)
++    : SparseMatConstIterator_<_Tp>(_m)
++{}
++
++template<typename _Tp> inline
 +SparseMatIterator_<_Tp>::SparseMatIterator_(const SparseMatIterator_<_Tp>& it)
 +    : SparseMatConstIterator_<_Tp>(it)
 +{}
 +
 +template<typename _Tp> inline
 +SparseMatIterator_<_Tp>& SparseMatIterator_<_Tp>::operator = (const SparseMatIterator_<_Tp>& it)
 +{
 +    return reinterpret_cast<SparseMatIterator_<_Tp>&>
 +         (*reinterpret_cast<SparseMatConstIterator*>(this) =
 +           reinterpret_cast<const SparseMatConstIterator&>(it));
 +}
 +
 +template<typename _Tp> inline
 +_Tp& SparseMatIterator_<_Tp>::operator *() const
 +{
 +    return *(_Tp*)this->ptr;
 +}
 +
 +template<typename _Tp> inline
 +SparseMatIterator_<_Tp>& SparseMatIterator_<_Tp>::operator ++()
 +{
 +    SparseMatConstIterator::operator ++();
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +SparseMatIterator_<_Tp> SparseMatIterator_<_Tp>::operator ++(int)
 +{
 +    SparseMatIterator it = *this;
 +    SparseMatConstIterator::operator ++();
 +    return it;
 +}
 +
 +
 +
 +//////////////////////// MatCommaInitializer_ ///////////////////////
 +
 +template<typename _Tp> inline
 +MatCommaInitializer_<_Tp>::MatCommaInitializer_(Mat_<_Tp>* _m)
 +    : it(_m)
 +{}
 +
 +template<typename _Tp> template<typename T2> inline
 +MatCommaInitializer_<_Tp>& MatCommaInitializer_<_Tp>::operator , (T2 v)
 +{
 +    CV_DbgAssert( this->it < ((const Mat_<_Tp>*)this->it.m)->end() );
 +    *this->it = _Tp(v);
 +    ++this->it;
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +MatCommaInitializer_<_Tp>::operator Mat_<_Tp>() const
 +{
 +    CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
 +    return Mat_<_Tp>(*this->it.m);
 +}
 +
 +
 +template<typename _Tp, typename T2> static inline
 +MatCommaInitializer_<_Tp> operator << (const Mat_<_Tp>& m, T2 val)
 +{
 +    MatCommaInitializer_<_Tp> commaInitializer((Mat_<_Tp>*)&m);
 +    return (commaInitializer, val);
 +}
 +
 +
 +
 +///////////////////////// Matrix Expressions ////////////////////////
 +
 +inline
 +Mat& Mat::operator = (const MatExpr& e)
 +{
 +    e.op->assign(e, *this);
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>::Mat_(const MatExpr& e)
 +{
 +    e.op->assign(e, *this, DataType<_Tp>::type);
 +}
 +
 +template<typename _Tp> inline
 +Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr& e)
 +{
 +    e.op->assign(e, *this, DataType<_Tp>::type);
 +    return *this;
 +}
 +
 +template<typename _Tp> inline
 +MatExpr Mat_<_Tp>::zeros(int rows, int cols)
 +{
 +    return Mat::zeros(rows, cols, DataType<_Tp>::type);
 +}
 +
 +template<typename _Tp> inline
 +MatExpr Mat_<_Tp>::zeros(Size sz)
 +{
 +    return Mat::zeros(sz, DataType<_Tp>::type);
 +}
 +
 +template<typename _Tp> inline
 +MatExpr Mat_<_Tp>::ones(int rows, int cols)
 +{
 +    return Mat::ones(rows, cols, DataType<_Tp>::type);
 +}
 +
 +template<typename _Tp> inline
 +MatExpr Mat_<_Tp>::ones(Size sz)
 +{
 +    return Mat::ones(sz, DataType<_Tp>::type);
 +}
 +
 +template<typename _Tp> inline
 +MatExpr Mat_<_Tp>::eye(int rows, int cols)
 +{
 +    return Mat::eye(rows, cols, DataType<_Tp>::type);
 +}
 +
 +template<typename _Tp> inline
 +MatExpr Mat_<_Tp>::eye(Size sz)
 +{
 +    return Mat::eye(sz, DataType<_Tp>::type);
 +}
 +
 +inline
 +MatExpr::MatExpr()
 +    : op(0), flags(0), a(Mat()), b(Mat()), c(Mat()), alpha(0), beta(0), s()
 +{}
 +
 +inline
 +MatExpr::MatExpr(const MatOp* _op, int _flags, const Mat& _a, const Mat& _b,
 +                 const Mat& _c, double _alpha, double _beta, const Scalar& _s)
 +    : op(_op), flags(_flags), a(_a), b(_b), c(_c), alpha(_alpha), beta(_beta), s(_s)
 +{}
 +
 +inline
 +MatExpr::operator Mat() const
 +{
 +    Mat m;
 +    op->assign(*this, m);
 +    return m;
 +}
 +
 +template<typename _Tp> inline
 +MatExpr::operator Mat_<_Tp>() const
 +{
 +    Mat_<_Tp> m;
 +    op->assign(*this, m, DataType<_Tp>::type);
 +    return m;
 +}
 +
 +
 +template<typename _Tp> static inline
 +MatExpr min(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
 +{
 +    return cv::min((const Mat&)a, (const Mat&)b);
 +}
 +
 +template<typename _Tp> static inline
 +MatExpr min(const Mat_<_Tp>& a, double s)
 +{
 +    return cv::min((const Mat&)a, s);
 +}
 +
 +template<typename _Tp> static inline
 +MatExpr min(double s, const Mat_<_Tp>& a)
 +{
 +    return cv::min((const Mat&)a, s);
 +}
 +
 +template<typename _Tp> static inline
 +MatExpr max(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
 +{
 +    return cv::max((const Mat&)a, (const Mat&)b);
 +}
 +
 +template<typename _Tp> static inline
 +MatExpr max(const Mat_<_Tp>& a, double s)
 +{
 +    return cv::max((const Mat&)a, s);
 +}
 +
 +template<typename _Tp> static inline
 +MatExpr max(double s, const Mat_<_Tp>& a)
 +{
 +    return cv::max((const Mat&)a, s);
 +}
 +
 +template<typename _Tp> static inline
 +MatExpr abs(const Mat_<_Tp>& m)
 +{
 +    return cv::abs((const Mat&)m);
 +}
 +
 +
 +static inline
 +Mat& operator += (Mat& a, const MatExpr& b)
 +{
 +    b.op->augAssignAdd(b, a);
 +    return a;
 +}
 +
 +static inline
 +const Mat& operator += (const Mat& a, const MatExpr& b)
 +{
 +    b.op->augAssignAdd(b, (Mat&)a);
 +    return a;
 +}
 +
 +template<typename _Tp> static inline
 +Mat_<_Tp>& operator += (Mat_<_Tp>& a, const MatExpr& b)
 +{
 +    b.op->augAssignAdd(b, a);
 +    return a;
 +}
 +
 +template<typename _Tp> static inline
 +const Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const MatExpr& b)
 +{
 +    b.op->augAssignAdd(b, (Mat&)a);
 +    return a;
 +}
 +
 +static inline
 +Mat& operator -= (Mat& a, const MatExpr& b)
 +{
 +    b.op->augAssignSubtract(b, a);
 +    return a;
 +}
 +
 +static inline
 +const Mat& operator -= (const Mat& a, const MatExpr& b)
 +{
 +    b.op->augAssignSubtract(b, (Mat&)a);
 +    return a;
 +}
 +
 +template<typename _Tp> static inline
 +Mat_<_Tp>& operator -= (Mat_<_Tp>& a, const MatExpr& b)
 +{
 +    b.op->augAssignSubtract(b, a);
 +    return a;
 +}
 +
 +template<typename _Tp> static inline
 +const Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const MatExpr& b)
 +{
 +    b.op->augAssignSubtract(b, (Mat&)a);
 +    return a;
 +}
 +
 +static inline
 +Mat& operator *= (Mat& a, const MatExpr& b)
 +{
 +    b.op->augAssignMultiply(b, a);
 +    return a;
 +}
 +
 +static inline
 +const Mat& operator *= (const Mat& a, const MatExpr& b)
 +{
 +    b.op->augAssignMultiply(b, (Mat&)a);
 +    return a;
 +}
 +
 +template<typename _Tp> static inline
 +Mat_<_Tp>& operator *= (Mat_<_Tp>& a, const MatExpr& b)
 +{
 +    b.op->augAssignMultiply(b, a);
 +    return a;
 +}
 +
 +template<typename _Tp> static inline
 +const Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const MatExpr& b)
 +{
 +    b.op->augAssignMultiply(b, (Mat&)a);
 +    return a;
 +}
 +
 +static inline
 +Mat& operator /= (Mat& a, const MatExpr& b)
 +{
 +    b.op->augAssignDivide(b, a);
 +    return a;
 +}
 +
 +static inline
 +const Mat& operator /= (const Mat& a, const MatExpr& b)
 +{
 +    b.op->augAssignDivide(b, (Mat&)a);
 +    return a;
 +}
 +
 +template<typename _Tp> static inline
 +Mat_<_Tp>& operator /= (Mat_<_Tp>& a, const MatExpr& b)
 +{
 +    b.op->augAssignDivide(b, a);
 +    return a;
 +}
 +
 +template<typename _Tp> static inline
 +const Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const MatExpr& b)
 +{
 +    b.op->augAssignDivide(b, (Mat&)a);
 +    return a;
 +}
 +
 +} //cv
 +
 +#endif
Simple merge
Simple merge
Simple merge
@@@ -1551,3 -1551,16 +1551,16 @@@ TEST(Core_Add, AddToColumnWhen4Rows
  
      ASSERT_EQ(0, countNonZero(m1 - m2));
  }
 -}
+ TEST(Core_round, CvRound)
+ {
+     ASSERT_EQ(2, cvRound(2.0));
+     ASSERT_EQ(2, cvRound(2.1));
+     ASSERT_EQ(-2, cvRound(-2.1));
+     ASSERT_EQ(3, cvRound(2.8));
+     ASSERT_EQ(-3, cvRound(-2.8));
+     ASSERT_EQ(2, cvRound(2.5));
+     ASSERT_EQ(4, cvRound(3.5));
+     ASSERT_EQ(-2, cvRound(-2.5));
+     ASSERT_EQ(-4, cvRound(-3.5));
++}
@@@ -66,10 -189,10 +66,10 @@@ struct KeypointResponseGreate
  };
  
  // takes keypoints and culls them by the response
 -void KeyPointsFilter::retainBest(vector<KeyPoint>& keypoints, int n_points)
 +void KeyPointsFilter::retainBest(std::vector<KeyPoint>& keypoints, int n_points)
  {
      //this is only necessary if the keypoints size is greater than the number of desired points.
-     if( n_points > 0 && keypoints.size() > (size_t)n_points )
+     if( n_points >= 0 && keypoints.size() > (size_t)n_points )
      {
          if (n_points==0)
          {
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -41,9 -41,9 +41,9 @@@
  //M*/
  
  #include "test_precomp.hpp"
 -#include "opencv2/highgui/highgui.hpp"
 +#include "opencv2/highgui.hpp"
  
- #if defined HAVE_GTK  || defined HAVE_QT || defined WIN32 || defined _WIN32 || defined HAVE_CARBON || defined HAVE_COCOA
+ #if defined HAVE_GTK || defined HAVE_QT || defined HAVE_WIN32UI || defined HAVE_CARBON || defined HAVE_COCOA
  
  using namespace cv;
  using namespace std;
@@@ -9,14 -9,16 +9,14 @@@
  #ifndef __OPENCV_TEST_PRECOMP_HPP__
  #define __OPENCV_TEST_PRECOMP_HPP__
  
 -#ifdef HAVE_CVCONFIG_H
 -# include "cvconfig.h"
 -#endif
 -
 -#include "opencv2/ts/ts.hpp"
 -#include "opencv2/imgproc/imgproc.hpp"
 -#include "opencv2/imgproc/imgproc_c.h"
  #include <iostream>
 +#include "opencv2/ts.hpp"
 +#include "opencv2/imgproc.hpp"
 +#include "opencv2/imgproc/imgproc_c.h"
 +
 +#include "opencv2/core/private.hpp"
  
- #if defined(HAVE_VIDEOINPUT)   || \
+ #if defined(HAVE_DSHOW)        || \
      defined(HAVE_TYZX)         || \
      defined(HAVE_VFW)          || \
      defined(HAVE_LIBV4L)       || \
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -9,13 -9,15 +9,16 @@@
  #ifndef __OPENCV_TEST_PRECOMP_HPP__
  #define __OPENCV_TEST_PRECOMP_HPP__
  
 -#include "opencv2/ts/ts.hpp"
 -#include "opencv2/imgproc/imgproc.hpp"
 -#include "opencv2/highgui/highgui.hpp"
 -#include "opencv2/nonfree/nonfree.hpp"
 +#include <iostream>
 +#include "opencv2/ts.hpp"
 +#include "opencv2/imgproc.hpp"
 +#include "opencv2/highgui.hpp"
 +#include "opencv2/nonfree.hpp"
  
+ #include "opencv2/ts/gpu_test.hpp"
  #include "opencv2/opencv_modules.hpp"
  #ifdef HAVE_OPENCV_OCL
  #  include "opencv2/nonfree/ocl.hpp"
  #endif
@@@ -3,5 -3,5 +3,5 @@@ if(NOT HAVE_OPENCL
  endif()
  
  set(the_description "OpenCL-accelerated Computer Vision")
- ocv_define_module(ocl opencv_core opencv_imgproc opencv_objdetect opencv_video)
 -ocv_define_module(ocl opencv_core opencv_imgproc opencv_features2d opencv_objdetect opencv_video)
++ocv_define_module(ocl opencv_core opencv_imgproc opencv_objdetect opencv_video opencv_features2d)
  ocv_warnings_disable(CMAKE_CXX_FLAGS -Wshadow)
index 2d8f5df,0000000..f79e6b8
mode 100644,000000..100644
--- /dev/null
@@@ -1,1728 -1,0 +1,1760 @@@
- //#include "opencv2/features2d.hpp"
 +/*M///////////////////////////////////////////////////////////////////////////////////////
 +//
 +//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
 +//
 +//  By downloading, copying, installing or using the software you agree to this license.
 +//  If you do not agree to this license, do not download, install,
 +//  copy or use the software.
 +//
 +//
 +//                           License Agreement
 +//                For Open Source Computer Vision Library
 +//
 +// Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved.
 +// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
 +// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
 +// Third party copyrights are property of their respective owners.
 +//
 +// Redistribution and use in source and binary forms, with or without modification,
 +// are permitted provided that the following conditions are met:
 +//
 +//   * Redistribution's of source code must retain the above copyright notice,
 +//     this list of conditions and the following disclaimer.
 +//
 +//   * Redistribution's in binary form must reproduce the above copyright notice,
 +//     this list of conditions and the following disclaimer in the documentation
 +//     and/or other oclMaterials provided with the distribution.
 +//
 +//   * The name of the copyright holders may not be used to endorse or promote products
 +//     derived from this software without specific prior written permission.
 +//
 +// This software is provided by the copyright holders and contributors "as is" and
 +// any express or implied warranties, including, but not limited to, the implied
 +// warranties of merchantability and fitness for a particular purpose are disclaimed.
 +// In no event shall the Intel Corporation or contributors be liable for any direct,
 +// indirect, incidental, special, exemplary, or consequential damages
 +// (including, but not limited to, procurement of substitute goods or services;
 +// loss of use, data, or profits; or business interruption) however caused
 +// and on any theory of liability, whether in contract, strict liability,
 +// or tort (including negligence or otherwise) arising in any way out of
 +// the use of this software, even if advised of the possibility of such damage.
 +//
 +//M*/
 +
 +#ifndef __OPENCV_OCL_HPP__
 +#define __OPENCV_OCL_HPP__
 +
 +#include <memory>
 +#include <vector>
 +
 +#include "opencv2/core.hpp"
 +#include "opencv2/imgproc.hpp"
 +#include "opencv2/objdetect.hpp"
 +
 +namespace cv
 +{
 +    namespace ocl
 +    {
 +        enum
 +        {
 +            CVCL_DEVICE_TYPE_DEFAULT     = (1 << 0),
 +            CVCL_DEVICE_TYPE_CPU         = (1 << 1),
 +            CVCL_DEVICE_TYPE_GPU         = (1 << 2),
 +            CVCL_DEVICE_TYPE_ACCELERATOR = (1 << 3),
 +            //CVCL_DEVICE_TYPE_CUSTOM      = (1 << 4)
 +            CVCL_DEVICE_TYPE_ALL         = 0xFFFFFFFF
 +        };
 +
 +        enum DevMemRW
 +        {
 +            DEVICE_MEM_R_W = 0,
 +            DEVICE_MEM_R_ONLY,
 +            DEVICE_MEM_W_ONLY
 +        };
 +
 +        enum DevMemType
 +        {
 +            DEVICE_MEM_DEFAULT = 0,
 +            DEVICE_MEM_AHP,         //alloc host pointer
 +            DEVICE_MEM_UHP,         //use host pointer
 +            DEVICE_MEM_CHP,         //copy host pointer
 +            DEVICE_MEM_PM           //persistent memory
 +        };
 +
 +        //Get the global device memory and read/write type
 +        //return 1 if unified memory system supported, otherwise return 0
 +        CV_EXPORTS int getDevMemType(DevMemRW& rw_type, DevMemType& mem_type);
 +
 +        //Set the global device memory and read/write type,
 +        //the newly generated oclMat will all use this type
 +        //return -1 if the target type is unsupported, otherwise return 0
 +        CV_EXPORTS int setDevMemType(DevMemRW rw_type = DEVICE_MEM_R_W, DevMemType mem_type = DEVICE_MEM_DEFAULT);
 +
 +        //this class contains ocl runtime information
 +        class CV_EXPORTS Info
 +        {
 +        public:
 +            struct Impl;
 +            Impl *impl;
 +
 +            Info();
 +            Info(const Info &m);
 +            ~Info();
 +            void release();
 +            Info &operator = (const Info &m);
 +            std::vector<String> DeviceName;
 +        };
 +        //////////////////////////////// Initialization & Info ////////////////////////
 +        //this function may be obsoleted
 +        //CV_EXPORTS cl_device_id getDevice();
 +        //the function must be called before any other cv::ocl::functions, it initialize ocl runtime
 +        //each Info relates to an OpenCL platform
 +        //there is one or more devices in each platform, each one has a separate name
 +        CV_EXPORTS int getDevice(std::vector<Info> &oclinfo, int devicetype = CVCL_DEVICE_TYPE_GPU);
 +
 +        //set device you want to use, optional function after getDevice be called
 +        //the devnum is the index of the selected device in DeviceName vector of INfo
 +        CV_EXPORTS void setDevice(Info &oclinfo, int devnum = 0);
 +
 +        //optional function, if you want save opencl binary kernel to the file, set its path
 +        CV_EXPORTS  void setBinpath(const char *path);
 +
 +        //The two functions below enable other opencl program to use ocl module's cl_context and cl_command_queue
 +        CV_EXPORTS void* getoclContext();
 +
 +        CV_EXPORTS void* getoclCommandQueue();
 +
++        //explicit call clFinish. The global command queue will be used.
++        CV_EXPORTS void finish();
++
 +        //this function enable ocl module to use customized cl_context and cl_command_queue
 +        //getDevice also need to be called before this function
 +        CV_EXPORTS void setDeviceEx(Info &oclinfo, void *ctx, void *qu, int devnum = 0);
 +
 +        //////////////////////////////// Error handling ////////////////////////
 +        CV_EXPORTS void error(const char *error_string, const char *file, const int line, const char *func);
 +
 +        //////////////////////////////// OpenCL context ////////////////////////
 +        //This is a global singleton class used to represent a OpenCL context.
 +        class CV_EXPORTS Context
 +        {
 +        protected:
 +            Context();
 +            friend class std::auto_ptr<Context>;
 +
 +        private:
 +            static std::auto_ptr<Context> clCxt;
 +            static int val;
 +        public:
 +            ~Context();
 +            void release();
 +            Info::Impl* impl;
 +
 +            static Context *getContext();
 +            static void setContext(Info &oclinfo);
 +
 +            enum {CL_DOUBLE, CL_UNIFIED_MEM};
 +            bool supportsFeature(int ftype);
 +            size_t computeUnits();
 +            size_t maxWorkGroupSize();
 +            void* oclContext();
 +            void* oclCommandQueue();
 +        };
 +
 +        //! Calls a kernel, by string. Pass globalThreads = NULL, and cleanUp = true, to finally clean-up without executing.
 +        CV_EXPORTS double openCLExecuteKernelInterop(Context *clCxt ,
 +                                                        const char **source, String kernelName,
 +                                                        size_t globalThreads[3], size_t localThreads[3],
 +                                                        std::vector< std::pair<size_t, const void *> > &args,
 +                                                        int channels, int depth, const char *build_options,
 +                                                        bool finish = true, bool measureKernelTime = false,
 +                                                        bool cleanUp = true);
 +
 +        //! Calls a kernel, by file. Pass globalThreads = NULL, and cleanUp = true, to finally clean-up without executing.
 +        CV_EXPORTS double openCLExecuteKernelInterop(Context *clCxt ,
 +                                                        const char **fileName, const int numFiles, String kernelName,
 +                                                        size_t globalThreads[3], size_t localThreads[3],
 +                                                        std::vector< std::pair<size_t, const void *> > &args,
 +                                                        int channels, int depth, const char *build_options,
 +                                                        bool finish = true, bool measureKernelTime = false,
 +                                                        bool cleanUp = true);
 +
 +        class CV_EXPORTS oclMatExpr;
 +        //////////////////////////////// oclMat ////////////////////////////////
 +        class CV_EXPORTS oclMat
 +        {
 +        public:
 +            //! default constructor
 +            oclMat();
 +            //! constructs oclMatrix of the specified size and type (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
 +            oclMat(int rows, int cols, int type);
 +            oclMat(Size size, int type);
 +            //! constucts oclMatrix and fills it with the specified value _s.
 +            oclMat(int rows, int cols, int type, const Scalar &s);
 +            oclMat(Size size, int type, const Scalar &s);
 +            //! copy constructor
 +            oclMat(const oclMat &m);
 +
 +            //! constructor for oclMatrix headers pointing to user-allocated data
 +            oclMat(int rows, int cols, int type, void *data, size_t step = Mat::AUTO_STEP);
 +            oclMat(Size size, int type, void *data, size_t step = Mat::AUTO_STEP);
 +
 +            //! creates a matrix header for a part of the bigger matrix
 +            oclMat(const oclMat &m, const Range &rowRange, const Range &colRange);
 +            oclMat(const oclMat &m, const Rect &roi);
 +
 +            //! builds oclMat from Mat. Perfom blocking upload to device.
 +            explicit oclMat (const Mat &m);
 +
 +            //! destructor - calls release()
 +            ~oclMat();
 +
 +            //! assignment operators
 +            oclMat &operator = (const oclMat &m);
 +            //! assignment operator. Perfom blocking upload to device.
 +            oclMat &operator = (const Mat &m);
 +            oclMat &operator = (const oclMatExpr& expr);
 +
 +            //! pefroms blocking upload data to oclMat.
 +            void upload(const cv::Mat &m);
 +
 +
 +            //! downloads data from device to host memory. Blocking calls.
 +            operator Mat() const;
 +            void download(cv::Mat &m) const;
 +
 +
 +            //! returns a new oclMatrix header for the specified row
 +            oclMat row(int y) const;
 +            //! returns a new oclMatrix header for the specified column
 +            oclMat col(int x) const;
 +            //! ... for the specified row span
 +            oclMat rowRange(int startrow, int endrow) const;
 +            oclMat rowRange(const Range &r) const;
 +            //! ... for the specified column span
 +            oclMat colRange(int startcol, int endcol) const;
 +            oclMat colRange(const Range &r) const;
 +
 +            //! returns deep copy of the oclMatrix, i.e. the data is copied
 +            oclMat clone() const;
 +            //! copies the oclMatrix content to "m".
 +            // It calls m.create(this->size(), this->type()).
 +            // It supports any data type
 +            void copyTo( oclMat &m ) const;
 +            //! copies those oclMatrix elements to "m" that are marked with non-zero mask elements.
 +            //It supports 8UC1 8UC4 32SC1 32SC4 32FC1 32FC4
 +            void copyTo( oclMat &m, const oclMat &mask ) const;
 +            //! converts oclMatrix to another datatype with optional scalng. See cvConvertScale.
 +            //It supports 8UC1 8UC4 32SC1 32SC4 32FC1 32FC4
 +            void convertTo( oclMat &m, int rtype, double alpha = 1, double beta = 0 ) const;
 +
 +            void assignTo( oclMat &m, int type = -1 ) const;
 +
 +            //! sets every oclMatrix element to s
 +            //It supports 8UC1 8UC4 32SC1 32SC4 32FC1 32FC4
 +            oclMat& operator = (const Scalar &s);
 +            //! sets some of the oclMatrix elements to s, according to the mask
 +            //It supports 8UC1 8UC4 32SC1 32SC4 32FC1 32FC4
 +            oclMat& setTo(const Scalar &s, const oclMat &mask = oclMat());
 +            //! creates alternative oclMatrix header for the same data, with different
 +            // number of channels and/or different number of rows. see cvReshape.
 +            oclMat reshape(int cn, int rows = 0) const;
 +
 +            //! allocates new oclMatrix data unless the oclMatrix already has specified size and type.
 +            // previous data is unreferenced if needed.
 +            void create(int rows, int cols, int type);
 +            void create(Size size, int type);
 +
 +            //! allocates new oclMatrix with specified device memory type.
 +            void createEx(int rows, int cols, int type, DevMemRW rw_type, DevMemType mem_type);
 +            void createEx(Size size, int type, DevMemRW rw_type, DevMemType mem_type);
 +
 +            //! decreases reference counter;
 +            // deallocate the data when reference counter reaches 0.
 +            void release();
 +
 +            //! swaps with other smart pointer
 +            void swap(oclMat &mat);
 +
 +            //! locates oclMatrix header within a parent oclMatrix. See below
 +            void locateROI( Size &wholeSize, Point &ofs ) const;
 +            //! moves/resizes the current oclMatrix ROI inside the parent oclMatrix.
 +            oclMat& adjustROI( int dtop, int dbottom, int dleft, int dright );
 +            //! extracts a rectangular sub-oclMatrix
 +            // (this is a generalized form of row, rowRange etc.)
 +            oclMat operator()( Range rowRange, Range colRange ) const;
 +            oclMat operator()( const Rect &roi ) const;
 +
 +            oclMat& operator+=( const oclMat& m );
 +            oclMat& operator-=( const oclMat& m );
 +            oclMat& operator*=( const oclMat& m );
 +            oclMat& operator/=( const oclMat& m );
 +
 +            //! returns true if the oclMatrix data is continuous
 +            // (i.e. when there are no gaps between successive rows).
 +            // similar to CV_IS_oclMat_CONT(cvoclMat->type)
 +            bool isContinuous() const;
 +            //! returns element size in bytes,
 +            // similar to CV_ELEM_SIZE(cvMat->type)
 +            size_t elemSize() const;
 +            //! returns the size of element channel in bytes.
 +            size_t elemSize1() const;
 +            //! returns element type, similar to CV_MAT_TYPE(cvMat->type)
 +            int type() const;
 +            //! returns element type, i.e. 8UC3 returns 8UC4 because in ocl
 +            //! 3 channels element actually use 4 channel space
 +            int ocltype() const;
 +            //! returns element type, similar to CV_MAT_DEPTH(cvMat->type)
 +            int depth() const;
 +            //! returns element type, similar to CV_MAT_CN(cvMat->type)
 +            int channels() const;
 +            //! returns element type, return 4 for 3 channels element,
 +            //!becuase 3 channels element actually use 4 channel space
 +            int oclchannels() const;
 +            //! returns step/elemSize1()
 +            size_t step1() const;
 +            //! returns oclMatrix size:
 +            // width == number of columns, height == number of rows
 +            Size size() const;
 +            //! returns true if oclMatrix data is NULL
 +            bool empty() const;
 +
 +            //! returns pointer to y-th row
 +            uchar* ptr(int y = 0);
 +            const uchar *ptr(int y = 0) const;
 +
 +            //! template version of the above method
 +            template<typename _Tp> _Tp *ptr(int y = 0);
 +            template<typename _Tp> const _Tp *ptr(int y = 0) const;
 +
 +            //! matrix transposition
 +            oclMat t() const;
 +
 +            /*! includes several bit-fields:
 +              - the magic signature
 +              - continuity flag
 +              - depth
 +              - number of channels
 +              */
 +            int flags;
 +            //! the number of rows and columns
 +            int rows, cols;
 +            //! a distance between successive rows in bytes; includes the gap if any
 +            size_t step;
 +            //! pointer to the data(OCL memory object)
 +            uchar *data;
 +
 +            //! pointer to the reference counter;
 +            // when oclMatrix points to user-allocated data, the pointer is NULL
 +            int *refcount;
 +
 +            //! helper fields used in locateROI and adjustROI
 +            //datastart and dataend are not used in current version
 +            uchar *datastart;
 +            uchar *dataend;
 +
 +            //! OpenCL context associated with the oclMat object.
 +            Context *clCxt;
 +            //add offset for handle ROI, calculated in byte
 +            int offset;
 +            //add wholerows and wholecols for the whole matrix, datastart and dataend are no longer used
 +            int wholerows;
 +            int wholecols;
 +        };
 +
 +
 +        ///////////////////// mat split and merge /////////////////////////////////
 +        //! Compose a multi-channel array from several single-channel arrays
 +        // Support all types
 +        CV_EXPORTS void merge(const oclMat *src, size_t n, oclMat &dst);
 +        CV_EXPORTS void merge(const std::vector<oclMat> &src, oclMat &dst);
 +
 +        //! Divides multi-channel array into several single-channel arrays
 +        // Support all types
 +        CV_EXPORTS void split(const oclMat &src, oclMat *dst);
 +        CV_EXPORTS void split(const oclMat &src, std::vector<oclMat> &dst);
 +
 +        ////////////////////////////// Arithmetics ///////////////////////////////////
 +        //#if defined DOUBLE_SUPPORT
 +        //typedef double F;
 +        //#else
 +        //typedef float F;
 +        //#endif
 +        //    CV_EXPORTS void addWeighted(const oclMat& a,F  alpha, const oclMat& b,F beta,F gama, oclMat& c);
 +        CV_EXPORTS void addWeighted(const oclMat &a, double  alpha, const oclMat &b, double beta, double gama, oclMat &c);
 +        //! adds one matrix to another (c = a + b)
 +        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
 +        CV_EXPORTS void add(const oclMat &a, const oclMat &b, oclMat &c);
 +        //! adds one matrix to another (c = a + b)
 +        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
 +        CV_EXPORTS void add(const oclMat &a, const oclMat &b, oclMat &c, const oclMat &mask);
 +        //! adds scalar to a matrix (c = a + s)
 +        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
 +        CV_EXPORTS void add(const oclMat &a, const Scalar &sc, oclMat &c, const oclMat &mask = oclMat());
 +        //! subtracts one matrix from another (c = a - b)
 +        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
 +        CV_EXPORTS void subtract(const oclMat &a, const oclMat &b, oclMat &c);
 +        //! subtracts one matrix from another (c = a - b)
 +        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
 +        CV_EXPORTS void subtract(const oclMat &a, const oclMat &b, oclMat &c, const oclMat &mask);
 +        //! subtracts scalar from a matrix (c = a - s)
 +        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
 +        CV_EXPORTS void subtract(const oclMat &a, const Scalar &sc, oclMat &c, const oclMat &mask = oclMat());
 +        //! subtracts scalar from a matrix (c = a - s)
 +        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
 +        CV_EXPORTS void subtract(const Scalar &sc, const oclMat &a, oclMat &c, const oclMat &mask = oclMat());
 +        //! computes element-wise product of the two arrays (c = a * b)
 +        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
 +        CV_EXPORTS void multiply(const oclMat &a, const oclMat &b, oclMat &c, double scale = 1);
 +        //! computes element-wise quotient of the two arrays (c = a / b)
 +        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
 +        CV_EXPORTS void divide(const oclMat &a, const oclMat &b, oclMat &c, double scale = 1);
 +        //! computes element-wise quotient of the two arrays (c = a / b)
 +        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
 +        CV_EXPORTS void divide(double scale, const oclMat &b, oclMat &c);
 +
 +        //! compares elements of two arrays (c = a <cmpop> b)
 +        // supports except CV_8SC1,CV_8SC2,CV8SC3,CV_8SC4 types
 +        CV_EXPORTS void compare(const oclMat &a, const oclMat &b, oclMat &c, int cmpop);
 +
 +        //! transposes the matrix
 +        // supports  CV_8UC1, 8UC4, 8SC4, 16UC2, 16SC2, 32SC1 and 32FC1.(the same as cuda)
 +        CV_EXPORTS void transpose(const oclMat &src, oclMat &dst);
 +
 +        //! computes element-wise absolute difference of two arrays (c = abs(a - b))
 +        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
 +        CV_EXPORTS void absdiff(const oclMat &a, const oclMat &b, oclMat &c);
 +        //! computes element-wise absolute difference of array and scalar (c = abs(a - s))
 +        // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
 +        CV_EXPORTS void absdiff(const oclMat &a, const Scalar &s, oclMat &c);
 +
 +        //! computes mean value and standard deviation of all or selected array elements
 +        // supports except CV_32F,CV_64F
 +        CV_EXPORTS void meanStdDev(const oclMat &mtx, Scalar &mean, Scalar &stddev);
 +
 +        //! computes norm of array
 +        // supports NORM_INF, NORM_L1, NORM_L2
 +        // supports only CV_8UC1 type
 +        CV_EXPORTS double norm(const oclMat &src1, int normType = NORM_L2);
 +
 +        //! computes norm of the difference between two arrays
 +        // supports NORM_INF, NORM_L1, NORM_L2
 +        // supports only CV_8UC1 type
 +        CV_EXPORTS double norm(const oclMat &src1, const oclMat &src2, int normType = NORM_L2);
 +
 +        //! reverses the order of the rows, columns or both in a matrix
 +        // supports all types
 +        CV_EXPORTS void flip(const oclMat &a, oclMat &b, int flipCode);
 +
 +        //! computes sum of array elements
 +        // disabled until fix crash
 +        // support all types
 +        CV_EXPORTS Scalar sum(const oclMat &m);
 +        CV_EXPORTS Scalar absSum(const oclMat &m);
 +        CV_EXPORTS Scalar sqrSum(const oclMat &m);
 +
 +        //! finds global minimum and maximum array elements and returns their values
 +        // support all C1 types
 +
 +        CV_EXPORTS void minMax(const oclMat &src, double *minVal, double *maxVal = 0, const oclMat &mask = oclMat());
 +
 +        //! finds global minimum and maximum array elements and returns their values with locations
 +        // support all C1 types
 +
 +        CV_EXPORTS void minMaxLoc(const oclMat &src, double *minVal, double *maxVal = 0, Point *minLoc = 0, Point *maxLoc = 0,
 +                                  const oclMat &mask = oclMat());
 +
 +        //! counts non-zero array elements
 +        // support all types
 +        CV_EXPORTS int countNonZero(const oclMat &src);
 +
 +        //! transforms 8-bit unsigned integers using lookup table: dst(i)=lut(src(i))
 +        // destination array will have the depth type as lut and the same channels number as source
 +        //It supports 8UC1 8UC4 only
 +        CV_EXPORTS void LUT(const oclMat &src, const oclMat &lut, oclMat &dst);
 +
 +        //! only 8UC1 and 256 bins is supported now
 +        CV_EXPORTS void calcHist(const oclMat &mat_src, oclMat &mat_hist);
 +        //! only 8UC1 and 256 bins is supported now
 +        CV_EXPORTS void equalizeHist(const oclMat &mat_src, oclMat &mat_dst);
 +        //! bilateralFilter
 +        // supports 8UC1 8UC4
 +        CV_EXPORTS void bilateralFilter(const oclMat& src, oclMat& dst, int d, double sigmaColor, double sigmaSpave, int borderType=BORDER_DEFAULT);
 +        //! computes exponent of each matrix element (b = e**a)
 +        // supports only CV_32FC1 type
 +        CV_EXPORTS void exp(const oclMat &a, oclMat &b);
 +
 +        //! computes natural logarithm of absolute value of each matrix element: b = log(abs(a))
 +        // supports only CV_32FC1 type
 +        CV_EXPORTS void log(const oclMat &a, oclMat &b);
 +
 +        //! computes magnitude of each (x(i), y(i)) vector
 +        // supports only CV_32F CV_64F type
 +        CV_EXPORTS void magnitude(const oclMat &x, const oclMat &y, oclMat &magnitude);
 +        CV_EXPORTS void magnitudeSqr(const oclMat &x, const oclMat &y, oclMat &magnitude);
 +
 +        CV_EXPORTS void magnitudeSqr(const oclMat &x, oclMat &magnitude);
 +
 +        //! computes angle (angle(i)) of each (x(i), y(i)) vector
 +        // supports only CV_32F CV_64F type
 +        CV_EXPORTS void phase(const oclMat &x, const oclMat &y, oclMat &angle, bool angleInDegrees = false);
 +
 +        //! the function raises every element of tne input array to p
 +        //! support only CV_32F CV_64F type
 +        CV_EXPORTS void pow(const oclMat &x, double p, oclMat &y);
 +
 +        //! converts Cartesian coordinates to polar
 +        // supports only CV_32F CV_64F type
 +        CV_EXPORTS void cartToPolar(const oclMat &x, const oclMat &y, oclMat &magnitude, oclMat &angle, bool angleInDegrees = false);
 +
 +        //! converts polar coordinates to Cartesian
 +        // supports only CV_32F CV_64F type
 +        CV_EXPORTS void polarToCart(const oclMat &magnitude, const oclMat &angle, oclMat &x, oclMat &y, bool angleInDegrees = false);
 +
 +        //! perfroms per-elements bit-wise inversion
 +        // supports all types
 +        CV_EXPORTS void bitwise_not(const oclMat &src, oclMat &dst);
 +        //! calculates per-element bit-wise disjunction of two arrays
 +        // supports all types
 +        CV_EXPORTS void bitwise_or(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask = oclMat());
 +        CV_EXPORTS void bitwise_or(const oclMat &src1, const Scalar &s, oclMat &dst, const oclMat &mask = oclMat());
 +        //! calculates per-element bit-wise conjunction of two arrays
 +        // supports all types
 +        CV_EXPORTS void bitwise_and(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask = oclMat());
 +        CV_EXPORTS void bitwise_and(const oclMat &src1, const Scalar &s, oclMat &dst, const oclMat &mask = oclMat());
 +        //! calculates per-element bit-wise "exclusive or" operation
 +        // supports all types
 +        CV_EXPORTS void bitwise_xor(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask = oclMat());
 +        CV_EXPORTS void bitwise_xor(const oclMat &src1, const Scalar &s, oclMat &dst, const oclMat &mask = oclMat());
 +
 +        //! Logical operators
 +        CV_EXPORTS oclMat operator ~ (const oclMat &);
 +        CV_EXPORTS oclMat operator | (const oclMat &, const oclMat &);
 +        CV_EXPORTS oclMat operator & (const oclMat &, const oclMat &);
 +        CV_EXPORTS oclMat operator ^ (const oclMat &, const oclMat &);
 +
 +
 +        //! Mathematics operators
 +        CV_EXPORTS oclMatExpr operator + (const oclMat &src1, const oclMat &src2);
 +        CV_EXPORTS oclMatExpr operator - (const oclMat &src1, const oclMat &src2);
 +        CV_EXPORTS oclMatExpr operator * (const oclMat &src1, const oclMat &src2);
 +        CV_EXPORTS oclMatExpr operator / (const oclMat &src1, const oclMat &src2);
 +
 +        //! computes convolution of two images
 +        //! support only CV_32FC1 type
 +        CV_EXPORTS void convolve(const oclMat &image, const oclMat &temp1, oclMat &result);
 +
 +        CV_EXPORTS void cvtColor(const oclMat &src, oclMat &dst, int code , int dcn = 0);
 +
 +        //////////////////////////////// Filter Engine ////////////////////////////////
 +
 +        /*!
 +          The Base Class for 1D or Row-wise Filters
 +
 +          This is the base class for linear or non-linear filters that process 1D data.
 +          In particular, such filters are used for the "horizontal" filtering parts in separable filters.
 +          */
 +        class CV_EXPORTS BaseRowFilter_GPU
 +        {
 +        public:
 +            BaseRowFilter_GPU(int ksize_, int anchor_, int bordertype_) : ksize(ksize_), anchor(anchor_), bordertype(bordertype_) {}
 +            virtual ~BaseRowFilter_GPU() {}
 +            virtual void operator()(const oclMat &src, oclMat &dst) = 0;
 +            int ksize, anchor, bordertype;
 +        };
 +
 +        /*!
 +          The Base Class for Column-wise Filters
 +
 +          This is the base class for linear or non-linear filters that process columns of 2D arrays.
 +          Such filters are used for the "vertical" filtering parts in separable filters.
 +          */
 +        class CV_EXPORTS BaseColumnFilter_GPU
 +        {
 +        public:
 +            BaseColumnFilter_GPU(int ksize_, int anchor_, int bordertype_) : ksize(ksize_), anchor(anchor_), bordertype(bordertype_) {}
 +            virtual ~BaseColumnFilter_GPU() {}
 +            virtual void operator()(const oclMat &src, oclMat &dst) = 0;
 +            int ksize, anchor, bordertype;
 +        };
 +
 +        /*!
 +          The Base Class for Non-Separable 2D Filters.
 +
 +          This is the base class for linear or non-linear 2D filters.
 +          */
 +        class CV_EXPORTS BaseFilter_GPU
 +        {
 +        public:
 +            BaseFilter_GPU(const Size &ksize_, const Point &anchor_, const int &borderType_)
 +                : ksize(ksize_), anchor(anchor_), borderType(borderType_) {}
 +            virtual ~BaseFilter_GPU() {}
 +            virtual void operator()(const oclMat &src, oclMat &dst) = 0;
 +            Size ksize;
 +            Point anchor;
 +            int borderType;
 +        };
 +
 +        /*!
 +          The Base Class for Filter Engine.
 +
 +          The class can be used to apply an arbitrary filtering operation to an image.
 +          It contains all the necessary intermediate buffers.
 +          */
 +        class CV_EXPORTS FilterEngine_GPU
 +        {
 +        public:
 +            virtual ~FilterEngine_GPU() {}
 +
 +            virtual void apply(const oclMat &src, oclMat &dst, Rect roi = Rect(0, 0, -1, -1)) = 0;
 +        };
 +
 +        //! returns the non-separable filter engine with the specified filter
 +        CV_EXPORTS Ptr<FilterEngine_GPU> createFilter2D_GPU(const Ptr<BaseFilter_GPU> filter2D);
 +
 +        //! returns the primitive row filter with the specified kernel
 +        CV_EXPORTS Ptr<BaseRowFilter_GPU> getLinearRowFilter_GPU(int srcType, int bufType, const Mat &rowKernel,
 +                int anchor = -1, int bordertype = BORDER_DEFAULT);
 +
 +        //! returns the primitive column filter with the specified kernel
 +        CV_EXPORTS Ptr<BaseColumnFilter_GPU> getLinearColumnFilter_GPU(int bufType, int dstType, const Mat &columnKernel,
 +                int anchor = -1, int bordertype = BORDER_DEFAULT, double delta = 0.0);
 +
 +        //! returns the separable linear filter engine
 +        CV_EXPORTS Ptr<FilterEngine_GPU> createSeparableLinearFilter_GPU(int srcType, int dstType, const Mat &rowKernel,
 +                const Mat &columnKernel, const Point &anchor = Point(-1, -1), double delta = 0.0, int bordertype = BORDER_DEFAULT);
 +
 +        //! returns the separable filter engine with the specified filters
 +        CV_EXPORTS Ptr<FilterEngine_GPU> createSeparableFilter_GPU(const Ptr<BaseRowFilter_GPU> &rowFilter,
 +                const Ptr<BaseColumnFilter_GPU> &columnFilter);
 +
 +        //! returns the Gaussian filter engine
 +        CV_EXPORTS Ptr<FilterEngine_GPU> createGaussianFilter_GPU(int type, Size ksize, double sigma1, double sigma2 = 0, int bordertype = BORDER_DEFAULT);
 +
 +        //! returns filter engine for the generalized Sobel operator
 +        CV_EXPORTS Ptr<FilterEngine_GPU> createDerivFilter_GPU( int srcType, int dstType, int dx, int dy, int ksize, int borderType = BORDER_DEFAULT );
 +
 +        //! applies Laplacian operator to the image
 +        // supports only ksize = 1 and ksize = 3 8UC1 8UC4 32FC1 32FC4 data type
 +        CV_EXPORTS void Laplacian(const oclMat &src, oclMat &dst, int ddepth, int ksize = 1, double scale = 1);
 +
 +        //! returns 2D box filter
 +        // supports CV_8UC1 and CV_8UC4 source type, dst type must be the same as source type
 +        CV_EXPORTS Ptr<BaseFilter_GPU> getBoxFilter_GPU(int srcType, int dstType,
 +                const Size &ksize, Point anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
 +
 +        //! returns box filter engine
 +        CV_EXPORTS Ptr<FilterEngine_GPU> createBoxFilter_GPU(int srcType, int dstType, const Size &ksize,
 +                const Point &anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
 +
 +        //! returns 2D filter with the specified kernel
 +        // supports CV_8UC1 and CV_8UC4 types
 +        CV_EXPORTS Ptr<BaseFilter_GPU> getLinearFilter_GPU(int srcType, int dstType, const Mat &kernel, const Size &ksize,
 +                Point anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
 +
 +        //! returns the non-separable linear filter engine
 +        CV_EXPORTS Ptr<FilterEngine_GPU> createLinearFilter_GPU(int srcType, int dstType, const Mat &kernel,
 +                const Point &anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
 +
 +        //! smooths the image using the normalized box filter
 +        // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
 +        // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101,BORDER_WRAP
 +        CV_EXPORTS void boxFilter(const oclMat &src, oclMat &dst, int ddepth, Size ksize,
 +                                  Point anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
 +
 +        //! returns 2D morphological filter
 +        //! only MORPH_ERODE and MORPH_DILATE are supported
 +        // supports CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 types
 +        // kernel must have CV_8UC1 type, one rows and cols == ksize.width * ksize.height
 +        CV_EXPORTS Ptr<BaseFilter_GPU> getMorphologyFilter_GPU(int op, int type, const Mat &kernel, const Size &ksize,
 +                Point anchor = Point(-1, -1));
 +
 +        //! returns morphological filter engine. Only MORPH_ERODE and MORPH_DILATE are supported.
 +        CV_EXPORTS Ptr<FilterEngine_GPU> createMorphologyFilter_GPU(int op, int type, const Mat &kernel,
 +                const Point &anchor = Point(-1, -1), int iterations = 1);
 +
 +        //! a synonym for normalized box filter
 +        // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
 +        // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101
 +        static inline void blur(const oclMat &src, oclMat &dst, Size ksize, Point anchor = Point(-1, -1),
 +                                int borderType = BORDER_CONSTANT)
 +        {
 +            boxFilter(src, dst, -1, ksize, anchor, borderType);
 +        }
 +
 +        //! applies non-separable 2D linear filter to the image
 +        CV_EXPORTS void filter2D(const oclMat &src, oclMat &dst, int ddepth, const Mat &kernel,
 +                                 Point anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
 +
 +        //! applies separable 2D linear filter to the image
 +        CV_EXPORTS void sepFilter2D(const oclMat &src, oclMat &dst, int ddepth, const Mat &kernelX, const Mat &kernelY,
 +                                    Point anchor = Point(-1, -1), double delta = 0.0, int bordertype = BORDER_DEFAULT);
 +
 +        //! applies generalized Sobel operator to the image
 +        // dst.type must equalize src.type
 +        // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
 +        // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101
 +        CV_EXPORTS void Sobel(const oclMat &src, oclMat &dst, int ddepth, int dx, int dy, int ksize = 3, double scale = 1, double delta = 0.0, int bordertype = BORDER_DEFAULT);
 +
 +        //! applies the vertical or horizontal Scharr operator to the image
 +        // dst.type must equalize src.type
 +        // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
 +        // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101
 +        CV_EXPORTS void Scharr(const oclMat &src, oclMat &dst, int ddepth, int dx, int dy, double scale = 1, double delta = 0.0, int bordertype = BORDER_DEFAULT);
 +
 +        //! smooths the image using Gaussian filter.
 +        // dst.type must equalize src.type
 +        // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
 +        // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101
 +        CV_EXPORTS void GaussianBlur(const oclMat &src, oclMat &dst, Size ksize, double sigma1, double sigma2 = 0, int bordertype = BORDER_DEFAULT);
 +
 +        //! erodes the image (applies the local minimum operator)
 +        // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
 +        CV_EXPORTS void erode( const oclMat &src, oclMat &dst, const Mat &kernel, Point anchor = Point(-1, -1), int iterations = 1,
 +
 +                               int borderType = BORDER_CONSTANT, const Scalar &borderValue = morphologyDefaultBorderValue());
 +
 +
 +        //! dilates the image (applies the local maximum operator)
 +        // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
 +        CV_EXPORTS void dilate( const oclMat &src, oclMat &dst, const Mat &kernel, Point anchor = Point(-1, -1), int iterations = 1,
 +
 +                                int borderType = BORDER_CONSTANT, const Scalar &borderValue = morphologyDefaultBorderValue());
 +
 +
 +        //! applies an advanced morphological operation to the image
 +        CV_EXPORTS void morphologyEx( const oclMat &src, oclMat &dst, int op, const Mat &kernel, Point anchor = Point(-1, -1), int iterations = 1,
 +
 +                                      int borderType = BORDER_CONSTANT, const Scalar &borderValue = morphologyDefaultBorderValue());
 +
 +
 +        ////////////////////////////// Image processing //////////////////////////////
 +        //! Does mean shift filtering on GPU.
 +        CV_EXPORTS void meanShiftFiltering(const oclMat &src, oclMat &dst, int sp, int sr,
 +                                           TermCriteria criteria = TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 5, 1));
 +
 +        //! Does mean shift procedure on GPU.
 +        CV_EXPORTS void meanShiftProc(const oclMat &src, oclMat &dstr, oclMat &dstsp, int sp, int sr,
 +                                      TermCriteria criteria = TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 5, 1));
 +
 +        //! Does mean shift segmentation with elimiation of small regions.
 +        CV_EXPORTS void meanShiftSegmentation(const oclMat &src, Mat &dst, int sp, int sr, int minsize,
 +                                              TermCriteria criteria = TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 5, 1));
 +
 +        //! applies fixed threshold to the image.
 +        // supports CV_8UC1 and CV_32FC1 data type
 +        // supports threshold type: THRESH_BINARY, THRESH_BINARY_INV, THRESH_TRUNC, THRESH_TOZERO, THRESH_TOZERO_INV
 +        CV_EXPORTS double threshold(const oclMat &src, oclMat &dst, double thresh, double maxVal, int type = THRESH_TRUNC);
 +
 +        //! resizes the image
 +        // Supports INTER_NEAREST, INTER_LINEAR
 +        // supports CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 types
 +        CV_EXPORTS void resize(const oclMat &src, oclMat &dst, Size dsize, double fx = 0, double fy = 0, int interpolation = INTER_LINEAR);
 +
 +        //! Applies a generic geometrical transformation to an image.
 +
 +        // Supports INTER_NEAREST, INTER_LINEAR.
 +
 +        // Map1 supports CV_16SC2, CV_32FC2  types.
 +
 +        // Src supports CV_8UC1, CV_8UC2, CV_8UC4.
 +
 +        CV_EXPORTS void remap(const oclMat &src, oclMat &dst, oclMat &map1, oclMat &map2, int interpolation, int bordertype, const Scalar &value = Scalar());
 +
 +        //! copies 2D array to a larger destination array and pads borders with user-specifiable constant
 +        // supports CV_8UC1, CV_8UC4, CV_32SC1 types
 +        CV_EXPORTS void copyMakeBorder(const oclMat &src, oclMat &dst, int top, int bottom, int left, int right, int boardtype, const Scalar &value = Scalar());
 +
 +        //! Smoothes image using median filter
 +        // The source 1- or 4-channel image. When m is 3 or 5, the image depth should be CV 8U or CV 32F.
 +        CV_EXPORTS void medianFilter(const oclMat &src, oclMat &dst, int m);
 +
 +        //! warps the image using affine transformation
 +        // Supports INTER_NEAREST, INTER_LINEAR, INTER_CUBIC
 +        // supports CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 types
 +        CV_EXPORTS void warpAffine(const oclMat &src, oclMat &dst, const Mat &M, Size dsize, int flags = INTER_LINEAR);
 +
 +        //! warps the image using perspective transformation
 +        // Supports INTER_NEAREST, INTER_LINEAR, INTER_CUBIC
 +        // supports CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 types
 +        CV_EXPORTS void warpPerspective(const oclMat &src, oclMat &dst, const Mat &M, Size dsize, int flags = INTER_LINEAR);
 +
 +        //! computes the integral image and integral for the squared image
 +        // sum will have CV_32S type, sqsum - CV32F type
 +        // supports only CV_8UC1 source type
 +        CV_EXPORTS void integral(const oclMat &src, oclMat &sum, oclMat &sqsum);
 +        CV_EXPORTS void integral(const oclMat &src, oclMat &sum);
 +        CV_EXPORTS void cornerHarris(const oclMat &src, oclMat &dst, int blockSize, int ksize, double k, int bordertype = cv::BORDER_DEFAULT);
 +        CV_EXPORTS void cornerMinEigenVal(const oclMat &src, oclMat &dst, int blockSize, int ksize, int bordertype = cv::BORDER_DEFAULT);
 +
 +        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 +        ///////////////////////////////////////////CascadeClassifier//////////////////////////////////////////////////////////////////
 +        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 +
 +        class CV_EXPORTS_W OclCascadeClassifier : public  cv::CascadeClassifier
 +        {
 +        public:
 +            OclCascadeClassifier() {};
 +            ~OclCascadeClassifier() {};
 +
 +            CvSeq* oclHaarDetectObjects(oclMat &gimg, CvMemStorage *storage, double scaleFactor,
 +                                        int minNeighbors, int flags, CvSize minSize = cvSize(0, 0), CvSize maxSize = cvSize(0, 0));
 +        };
 +
 +
 +
 +        /////////////////////////////// Pyramid /////////////////////////////////////
 +        CV_EXPORTS void pyrDown(const oclMat &src, oclMat &dst);
 +
 +        //! upsamples the source image and then smoothes it
 +        CV_EXPORTS void pyrUp(const oclMat &src, oclMat &dst);
 +
 +        //! performs linear blending of two images
 +        //! to avoid accuracy errors sum of weigths shouldn't be very close to zero
 +        // supports only CV_8UC1 source type
 +        CV_EXPORTS void blendLinear(const oclMat &img1, const oclMat &img2, const oclMat &weights1, const oclMat &weights2, oclMat &result);
 +
 +        //! computes vertical sum, supports only CV_32FC1 images
 +        CV_EXPORTS void columnSum(const oclMat &src, oclMat &sum);
 +
 +        ///////////////////////////////////////// match_template /////////////////////////////////////////////////////////////
 +        struct CV_EXPORTS MatchTemplateBuf
 +        {
 +            Size user_block_size;
 +            oclMat imagef, templf;
 +            std::vector<oclMat> images;
 +            std::vector<oclMat> image_sums;
 +            std::vector<oclMat> image_sqsums;
 +        };
 +
 +
 +        //! computes the proximity map for the raster template and the image where the template is searched for
 +        // Supports TM_SQDIFF, TM_SQDIFF_NORMED, TM_CCORR, TM_CCORR_NORMED, TM_CCOEFF, TM_CCOEFF_NORMED for type 8UC1 and 8UC4
 +        // Supports TM_SQDIFF, TM_CCORR for type 32FC1 and 32FC4
 +        CV_EXPORTS void matchTemplate(const oclMat &image, const oclMat &templ, oclMat &result, int method);
 +
 +        //! computes the proximity map for the raster template and the image where the template is searched for
 +        // Supports TM_SQDIFF, TM_SQDIFF_NORMED, TM_CCORR, TM_CCORR_NORMED, TM_CCOEFF, TM_CCOEFF_NORMED for type 8UC1 and 8UC4
 +        // Supports TM_SQDIFF, TM_CCORR for type 32FC1 and 32FC4
 +        CV_EXPORTS void matchTemplate(const oclMat &image, const oclMat &templ, oclMat &result, int method, MatchTemplateBuf &buf);
 +
 +
 +
 +        ///////////////////////////////////////////// Canny /////////////////////////////////////////////
 +
 +        struct CV_EXPORTS CannyBuf;
 +
 +
 +
 +        //! compute edges of the input image using Canny operator
 +
 +        // Support CV_8UC1 only
 +
 +        CV_EXPORTS void Canny(const oclMat &image, oclMat &edges, double low_thresh, double high_thresh, int apperture_size = 3, bool L2gradient = false);
 +
 +        CV_EXPORTS void Canny(const oclMat &image, CannyBuf &buf, oclMat &edges, double low_thresh, double high_thresh, int apperture_size = 3, bool L2gradient = false);
 +
 +        CV_EXPORTS void Canny(const oclMat &dx, const oclMat &dy, oclMat &edges, double low_thresh, double high_thresh, bool L2gradient = false);
 +
 +        CV_EXPORTS void Canny(const oclMat &dx, const oclMat &dy, CannyBuf &buf, oclMat &edges, double low_thresh, double high_thresh, bool L2gradient = false);
 +
 +
 +
 +        struct CV_EXPORTS CannyBuf
 +
 +        {
 +
 +            CannyBuf() : counter(NULL) {}
 +
 +            ~CannyBuf()
 +            {
 +                release();
 +            }
 +
 +            explicit CannyBuf(const Size &image_size, int apperture_size = 3) : counter(NULL)
 +
 +            {
 +
 +                create(image_size, apperture_size);
 +
 +            }
 +
 +            CannyBuf(const oclMat &dx_, const oclMat &dy_);
 +
 +
 +
 +            void create(const Size &image_size, int apperture_size = 3);
 +
 +
 +
 +            void release();
 +
 +
 +
 +            oclMat dx, dy;
 +
 +            oclMat dx_buf, dy_buf;
 +
 +            oclMat edgeBuf;
 +
 +            oclMat trackBuf1, trackBuf2;
 +
 +            void *counter;
 +
 +            Ptr<FilterEngine_GPU> filterDX, filterDY;
 +
 +        };
 +
 +        ///////////////////////////////////////// Hough Transform /////////////////////////////////////////
 +        //! HoughCircles
 +        struct HoughCirclesBuf
 +        {
 +            oclMat edges;
 +            oclMat accum;
 +            oclMat srcPoints;
 +            oclMat centers;
 +            CannyBuf cannyBuf;
 +        };
 +
 +        CV_EXPORTS void HoughCircles(const oclMat& src, oclMat& circles, int method, float dp, float minDist, int cannyThreshold, int votesThreshold, int minRadius, int maxRadius, int maxCircles = 4096);
 +        CV_EXPORTS void HoughCircles(const oclMat& src, oclMat& circles, HoughCirclesBuf& buf, int method, float dp, float minDist, int cannyThreshold, int votesThreshold, int minRadius, int maxRadius, int maxCircles = 4096);
 +        CV_EXPORTS void HoughCirclesDownload(const oclMat& d_circles, OutputArray h_circles);
 +
 +
 +        ///////////////////////////////////////// clAmdFft related /////////////////////////////////////////
 +        //! Performs a forward or inverse discrete Fourier transform (1D or 2D) of floating point matrix.
 +        //! Param dft_size is the size of DFT transform.
 +        //!
 +        //! For complex-to-real transform it is assumed that the source matrix is packed in CLFFT's format.
 +        // support src type of CV32FC1, CV32FC2
 +        // support flags: DFT_INVERSE, DFT_REAL_OUTPUT, DFT_COMPLEX_OUTPUT, DFT_ROWS
 +        // dft_size is the size of original input, which is used for transformation from complex to real.
 +        // dft_size must be powers of 2, 3 and 5
 +        // real to complex dft requires at least v1.8 clAmdFft
 +        // real to complex dft output is not the same with cpu version
 +        // real to complex and complex to real does not support DFT_ROWS
 +        CV_EXPORTS void dft(const oclMat &src, oclMat &dst, Size dft_size = Size(0, 0), int flags = 0);
 +
 +        //! implements generalized matrix product algorithm GEMM from BLAS
 +        // The functionality requires clAmdBlas library
 +        // only support type CV_32FC1
 +        // flag GEMM_3_T is not supported
 +        CV_EXPORTS void gemm(const oclMat &src1, const oclMat &src2, double alpha,
 +                             const oclMat &src3, double beta, oclMat &dst, int flags = 0);
 +
 +        //////////////// HOG (Histogram-of-Oriented-Gradients) Descriptor and Object Detector //////////////
 +
 +        struct CV_EXPORTS HOGDescriptor
 +
 +        {
 +
 +            enum { DEFAULT_WIN_SIGMA = -1 };
 +
 +            enum { DEFAULT_NLEVELS = 64 };
 +
 +            enum { DESCR_FORMAT_ROW_BY_ROW, DESCR_FORMAT_COL_BY_COL };
 +
 +
 +
 +            HOGDescriptor(Size win_size = Size(64, 128), Size block_size = Size(16, 16),
 +
 +                          Size block_stride = Size(8, 8), Size cell_size = Size(8, 8),
 +
 +                          int nbins = 9, double win_sigma = DEFAULT_WIN_SIGMA,
 +
 +                          double threshold_L2hys = 0.2, bool gamma_correction = true,
 +
 +                          int nlevels = DEFAULT_NLEVELS);
 +
 +
 +
 +            size_t getDescriptorSize() const;
 +
 +            size_t getBlockHistogramSize() const;
 +
 +
 +
 +            void setSVMDetector(const std::vector<float> &detector);
 +
 +
 +
 +            static std::vector<float> getDefaultPeopleDetector();
 +
 +            static std::vector<float> getPeopleDetector48x96();
 +
 +            static std::vector<float> getPeopleDetector64x128();
 +
 +
 +
 +            void detect(const oclMat &img, std::vector<Point> &found_locations,
 +
 +                        double hit_threshold = 0, Size win_stride = Size(),
 +
 +                        Size padding = Size());
 +
 +
 +
 +            void detectMultiScale(const oclMat &img, std::vector<Rect> &found_locations,
 +
 +                                  double hit_threshold = 0, Size win_stride = Size(),
 +
 +                                  Size padding = Size(), double scale0 = 1.05,
 +
 +                                  int group_threshold = 2);
 +
 +
 +
 +            void getDescriptors(const oclMat &img, Size win_stride,
 +
 +                                oclMat &descriptors,
 +
 +                                int descr_format = DESCR_FORMAT_COL_BY_COL);
 +
 +
 +
 +            Size win_size;
 +
 +            Size block_size;
 +
 +            Size block_stride;
 +
 +            Size cell_size;
 +
 +            int nbins;
 +
 +            double win_sigma;
 +
 +            double threshold_L2hys;
 +
 +            bool gamma_correction;
 +
 +            int nlevels;
 +
 +
 +
 +        protected:
 +
 +            // initialize buffers; only need to do once in case of multiscale detection
 +
 +            void init_buffer(const oclMat &img, Size win_stride);
 +
 +
 +
 +            void computeBlockHistograms(const oclMat &img);
 +
 +            void computeGradient(const oclMat &img, oclMat &grad, oclMat &qangle);
 +
 +
 +
 +            double getWinSigma() const;
 +
 +            bool checkDetectorSize() const;
 +
 +
 +
 +            static int numPartsWithin(int size, int part_size, int stride);
 +
 +            static Size numPartsWithin(Size size, Size part_size, Size stride);
 +
 +
 +
 +            // Coefficients of the separating plane
 +
 +            float free_coef;
 +
 +            oclMat detector;
 +
 +
 +
 +            // Results of the last classification step
 +
 +            oclMat labels;
 +
 +            Mat labels_host;
 +
 +
 +
 +            // Results of the last histogram evaluation step
 +
 +            oclMat block_hists;
 +
 +
 +
 +            // Gradients conputation results
 +
 +            oclMat grad, qangle;
 +
 +
 +
 +            // scaled image
 +
 +            oclMat image_scale;
 +
 +
 +
 +            // effect size of input image (might be different from original size after scaling)
 +
 +            Size effect_size;
 +
 +        };
 +
 +
 +        ////////////////////////feature2d_ocl/////////////////
 +        /****************************************************************************************\
 +        *                                      Distance                                          *
 +        \****************************************************************************************/
 +
 +        template<typename T>
 +        struct CV_EXPORTS Accumulator
 +        {
 +            typedef T Type;
 +        };
 +
 +        template<> struct Accumulator<unsigned char>
 +        {
 +            typedef float Type;
 +        };
 +        template<> struct Accumulator<unsigned short>
 +        {
 +            typedef float Type;
 +        };
 +        template<> struct Accumulator<char>
 +        {
 +            typedef float Type;
 +        };
 +        template<> struct Accumulator<short>
 +        {
 +            typedef float Type;
 +        };
 +
 +        /*
 +         * Manhattan distance (city block distance) functor
 +         */
 +        template<class T>
 +        struct CV_EXPORTS L1
 +        {
 +            enum { normType = NORM_L1 };
 +            typedef T ValueType;
 +            typedef typename Accumulator<T>::Type ResultType;
 +
 +            ResultType operator()( const T *a, const T *b, int size ) const
 +            {
 +                return normL1<ValueType, ResultType>(a, b, size);
 +            }
 +        };
 +
 +        /*
 +         * Euclidean distance functor
 +         */
 +        template<class T>
 +        struct CV_EXPORTS L2
 +        {
 +            enum { normType = NORM_L2 };
 +            typedef T ValueType;
 +            typedef typename Accumulator<T>::Type ResultType;
 +
 +            ResultType operator()( const T *a, const T *b, int size ) const
 +            {
 +                return (ResultType)std::sqrt((double)normL2Sqr<ValueType, ResultType>(a, b, size));
 +            }
 +        };
 +
 +        /*
 +         * Hamming distance functor - counts the bit differences between two strings - useful for the Brief descriptor
 +         * bit count of A exclusive XOR'ed with B
 +         */
 +        struct CV_EXPORTS Hamming
 +        {
 +            enum { normType = NORM_HAMMING };
 +            typedef unsigned char ValueType;
 +            typedef int ResultType;
 +
 +            /** this will count the bits in a ^ b
 +             */
 +            ResultType operator()( const unsigned char *a, const unsigned char *b, int size ) const
 +            {
 +                return normHamming(a, b, size);
 +            }
 +        };
 +
 +        ////////////////////////////////// BruteForceMatcher //////////////////////////////////
 +
 +        class CV_EXPORTS BruteForceMatcher_OCL_base
 +        {
 +        public:
 +            enum DistType {L1Dist = 0, L2Dist, HammingDist};
 +
 +            explicit BruteForceMatcher_OCL_base(DistType distType = L2Dist);
 +
 +
 +
 +            // Add descriptors to train descriptor collection
 +
 +            void add(const std::vector<oclMat> &descCollection);
 +
 +
 +
 +            // Get train descriptors collection
 +
 +            const std::vector<oclMat> &getTrainDescriptors() const;
 +
 +
 +
 +            // Clear train descriptors collection
 +
 +            void clear();
 +
 +
 +
 +            // Return true if there are not train descriptors in collection
 +
 +            bool empty() const;
 +
 +
 +
 +            // Return true if the matcher supports mask in match methods
 +
 +            bool isMaskSupported() const;
 +
 +
 +
 +            // Find one best match for each query descriptor
 +
 +            void matchSingle(const oclMat &query, const oclMat &train,
 +
 +                             oclMat &trainIdx, oclMat &distance,
 +
 +                             const oclMat &mask = oclMat());
 +
 +
 +
 +            // Download trainIdx and distance and convert it to CPU vector with DMatch
 +
 +            static void matchDownload(const oclMat &trainIdx, const oclMat &distance, std::vector<DMatch> &matches);
 +
 +            // Convert trainIdx and distance to vector with DMatch
 +
 +            static void matchConvert(const Mat &trainIdx, const Mat &distance, std::vector<DMatch> &matches);
 +
 +
 +
 +            // Find one best match for each query descriptor
 +
 +            void match(const oclMat &query, const oclMat &train, std::vector<DMatch> &matches, const oclMat &mask = oclMat());
 +
 +
 +
 +            // Make gpu collection of trains and masks in suitable format for matchCollection function
 +
 +            void makeGpuCollection(oclMat &trainCollection, oclMat &maskCollection, const std::vector<oclMat> &masks = std::vector<oclMat>());
 +
 +
 +
 +            // Find one best match from train collection for each query descriptor
 +
 +            void matchCollection(const oclMat &query, const oclMat &trainCollection,
 +
 +                                 oclMat &trainIdx, oclMat &imgIdx, oclMat &distance,
 +
 +                                 const oclMat &masks = oclMat());
 +
 +
 +
 +            // Download trainIdx, imgIdx and distance and convert it to vector with DMatch
 +
 +            static void matchDownload(const oclMat &trainIdx, const oclMat &imgIdx, const oclMat &distance, std::vector<DMatch> &matches);
 +
 +            // Convert trainIdx, imgIdx and distance to vector with DMatch
 +
 +            static void matchConvert(const Mat &trainIdx, const Mat &imgIdx, const Mat &distance, std::vector<DMatch> &matches);
 +
 +
 +
 +            // Find one best match from train collection for each query descriptor.
 +
 +            void match(const oclMat &query, std::vector<DMatch> &matches, const std::vector<oclMat> &masks = std::vector<oclMat>());
 +
 +
 +
 +            // Find k best matches for each query descriptor (in increasing order of distances)
 +
 +            void knnMatchSingle(const oclMat &query, const oclMat &train,
 +
 +                                oclMat &trainIdx, oclMat &distance, oclMat &allDist, int k,
 +
 +                                const oclMat &mask = oclMat());
 +
 +
 +
 +            // Download trainIdx and distance and convert it to vector with DMatch
 +
 +            // compactResult is used when mask is not empty. If compactResult is false matches
 +
 +            // vector will have the same size as queryDescriptors rows. If compactResult is true
 +
 +            // matches vector will not contain matches for fully masked out query descriptors.
 +
 +            static void knnMatchDownload(const oclMat &trainIdx, const oclMat &distance,
 +
 +                                         std::vector< std::vector<DMatch> > &matches, bool compactResult = false);
 +
 +            // Convert trainIdx and distance to vector with DMatch
 +
 +            static void knnMatchConvert(const Mat &trainIdx, const Mat &distance,
 +
 +                                        std::vector< std::vector<DMatch> > &matches, bool compactResult = false);
 +
 +
 +
 +            // Find k best matches for each query descriptor (in increasing order of distances).
 +
 +            // compactResult is used when mask is not empty. If compactResult is false matches
 +
 +            // vector will have the same size as queryDescriptors rows. If compactResult is true
 +
 +            // matches vector will not contain matches for fully masked out query descriptors.
 +
 +            void knnMatch(const oclMat &query, const oclMat &train,
 +
 +                          std::vector< std::vector<DMatch> > &matches, int k, const oclMat &mask = oclMat(),
 +
 +                          bool compactResult = false);
 +
 +
 +
 +            // Find k best matches from train collection for each query descriptor (in increasing order of distances)
 +
 +            void knnMatch2Collection(const oclMat &query, const oclMat &trainCollection,
 +
 +                                     oclMat &trainIdx, oclMat &imgIdx, oclMat &distance,
 +
 +                                     const oclMat &maskCollection = oclMat());
 +
 +
 +
 +            // Download trainIdx and distance and convert it to vector with DMatch
 +
 +            // compactResult is used when mask is not empty. If compactResult is false matches
 +
 +            // vector will have the same size as queryDescriptors rows. If compactResult is true
 +
 +            // matches vector will not contain matches for fully masked out query descriptors.
 +
 +            static void knnMatch2Download(const oclMat &trainIdx, const oclMat &imgIdx, const oclMat &distance,
 +
 +                                          std::vector< std::vector<DMatch> > &matches, bool compactResult = false);
 +
 +            // Convert trainIdx and distance to vector with DMatch
 +
 +            static void knnMatch2Convert(const Mat &trainIdx, const Mat &imgIdx, const Mat &distance,
 +
 +                                         std::vector< std::vector<DMatch> > &matches, bool compactResult = false);
 +
 +
 +
 +            // Find k best matches  for each query descriptor (in increasing order of distances).
 +
 +            // compactResult is used when mask is not empty. If compactResult is false matches
 +
 +            // vector will have the same size as queryDescriptors rows. If compactResult is true
 +
 +            // matches vector will not contain matches for fully masked out query descriptors.
 +
 +            void knnMatch(const oclMat &query, std::vector< std::vector<DMatch> > &matches, int k,
 +
 +                          const std::vector<oclMat> &masks = std::vector<oclMat>(), bool compactResult = false);
 +
 +
 +
 +            // Find best matches for each query descriptor which have distance less than maxDistance.
 +
 +            // nMatches.at<int>(0, queryIdx) will contain matches count for queryIdx.
 +
 +            // carefully nMatches can be greater than trainIdx.cols - it means that matcher didn't find all matches,
 +
 +            // because it didn't have enough memory.
 +
 +            // If trainIdx is empty, then trainIdx and distance will be created with size nQuery x max((nTrain / 100), 10),
 +
 +            // otherwize user can pass own allocated trainIdx and distance with size nQuery x nMaxMatches
 +
 +            // Matches doesn't sorted.
 +
 +            void radiusMatchSingle(const oclMat &query, const oclMat &train,
 +
 +                                   oclMat &trainIdx, oclMat &distance, oclMat &nMatches, float maxDistance,
 +
 +                                   const oclMat &mask = oclMat());
 +
 +
 +
 +            // Download trainIdx, nMatches and distance and convert it to vector with DMatch.
 +
 +            // matches will be sorted in increasing order of distances.
 +
 +            // compactResult is used when mask is not empty. If compactResult is false matches
 +
 +            // vector will have the same size as queryDescriptors rows. If compactResult is true
 +
 +            // matches vector will not contain matches for fully masked out query descriptors.
 +
 +            static void radiusMatchDownload(const oclMat &trainIdx, const oclMat &distance, const oclMat &nMatches,
 +
 +                                            std::vector< std::vector<DMatch> > &matches, bool compactResult = false);
 +
 +            // Convert trainIdx, nMatches and distance to vector with DMatch.
 +
 +            static void radiusMatchConvert(const Mat &trainIdx, const Mat &distance, const Mat &nMatches,
 +
 +                                           std::vector< std::vector<DMatch> > &matches, bool compactResult = false);
 +
 +
 +
 +            // Find best matches for each query descriptor which have distance less than maxDistance
 +
 +            // in increasing order of distances).
 +
 +            void radiusMatch(const oclMat &query, const oclMat &train,
 +
 +                             std::vector< std::vector<DMatch> > &matches, float maxDistance,
 +
 +                             const oclMat &mask = oclMat(), bool compactResult = false);
 +
 +
 +
 +            // Find best matches for each query descriptor which have distance less than maxDistance.
 +
 +            // If trainIdx is empty, then trainIdx and distance will be created with size nQuery x max((nQuery / 100), 10),
 +
 +            // otherwize user can pass own allocated trainIdx and distance with size nQuery x nMaxMatches
 +
 +            // Matches doesn't sorted.
 +
 +            void radiusMatchCollection(const oclMat &query, oclMat &trainIdx, oclMat &imgIdx, oclMat &distance, oclMat &nMatches, float maxDistance,
 +
 +                                       const std::vector<oclMat> &masks = std::vector<oclMat>());
 +
 +
 +
 +            // Download trainIdx, imgIdx, nMatches and distance and convert it to vector with DMatch.
 +
 +            // matches will be sorted in increasing order of distances.
 +
 +            // compactResult is used when mask is not empty. If compactResult is false matches
 +
 +            // vector will have the same size as queryDescriptors rows. If compactResult is true
 +
 +            // matches vector will not contain matches for fully masked out query descriptors.
 +
 +            static void radiusMatchDownload(const oclMat &trainIdx, const oclMat &imgIdx, const oclMat &distance, const oclMat &nMatches,
 +
 +                                            std::vector< std::vector<DMatch> > &matches, bool compactResult = false);
 +
 +            // Convert trainIdx, nMatches and distance to vector with DMatch.
 +
 +            static void radiusMatchConvert(const Mat &trainIdx, const Mat &imgIdx, const Mat &distance, const Mat &nMatches,
 +
 +                                           std::vector< std::vector<DMatch> > &matches, bool compactResult = false);
 +
 +
 +
 +            // Find best matches from train collection for each query descriptor which have distance less than
 +
 +            // maxDistance (in increasing order of distances).
 +
 +            void radiusMatch(const oclMat &query, std::vector< std::vector<DMatch> > &matches, float maxDistance,
 +
 +                             const std::vector<oclMat> &masks = std::vector<oclMat>(), bool compactResult = false);
 +
 +
 +
 +            DistType distType;
 +
 +
 +
 +        private:
 +
 +            std::vector<oclMat> trainDescCollection;
 +
 +        };
 +
 +
 +
 +        template <class Distance>
 +
 +        class CV_EXPORTS BruteForceMatcher_OCL;
 +
 +
 +
 +        template <typename T>
 +
 +        class CV_EXPORTS BruteForceMatcher_OCL< L1<T> > : public BruteForceMatcher_OCL_base
 +
 +        {
 +
 +        public:
 +
 +            explicit BruteForceMatcher_OCL() : BruteForceMatcher_OCL_base(L1Dist) {}
 +
 +            explicit BruteForceMatcher_OCL(L1<T> /*d*/) : BruteForceMatcher_OCL_base(L1Dist) {}
 +
 +        };
 +
 +        template <typename T>
 +
 +        class CV_EXPORTS BruteForceMatcher_OCL< L2<T> > : public BruteForceMatcher_OCL_base
 +
 +        {
 +
 +        public:
 +
 +            explicit BruteForceMatcher_OCL() : BruteForceMatcher_OCL_base(L2Dist) {}
 +
 +            explicit BruteForceMatcher_OCL(L2<T> /*d*/) : BruteForceMatcher_OCL_base(L2Dist) {}
 +
 +        };
 +
 +        template <> class CV_EXPORTS BruteForceMatcher_OCL< Hamming > : public BruteForceMatcher_OCL_base
 +
 +        {
 +
 +        public:
 +
 +            explicit BruteForceMatcher_OCL() : BruteForceMatcher_OCL_base(HammingDist) {}
 +
 +            explicit BruteForceMatcher_OCL(Hamming /*d*/) : BruteForceMatcher_OCL_base(HammingDist) {}
 +
 +        };
 +
 +
 +
 +        /////////////////////////////// PyrLKOpticalFlow /////////////////////////////////////
 +
 +        class CV_EXPORTS PyrLKOpticalFlow
 +
 +        {
 +
 +        public:
 +
 +            PyrLKOpticalFlow()
 +
 +            {
 +
 +                winSize = Size(21, 21);
 +
 +                maxLevel = 3;
 +
 +                iters = 30;
 +
 +                derivLambda = 0.5;
 +
 +                useInitialFlow = false;
 +
 +                minEigThreshold = 1e-4f;
 +
 +                getMinEigenVals = false;
 +
 +                isDeviceArch11_ = false;
 +
 +            }
 +
 +
 +
 +            void sparse(const oclMat &prevImg, const oclMat &nextImg, const oclMat &prevPts, oclMat &nextPts,
 +
 +                        oclMat &status, oclMat *err = 0);
 +
 +
 +
 +            void dense(const oclMat &prevImg, const oclMat &nextImg, oclMat &u, oclMat &v, oclMat *err = 0);
 +
 +
 +
 +            Size winSize;
 +
 +            int maxLevel;
 +
 +            int iters;
 +
 +            double derivLambda;
 +
 +            bool useInitialFlow;
 +
 +            float minEigThreshold;
 +
 +            bool getMinEigenVals;
 +
 +
 +
 +            void releaseMemory()
 +
 +            {
 +
 +                dx_calcBuf_.release();
 +
 +                dy_calcBuf_.release();
 +
 +
 +
 +                prevPyr_.clear();
 +
 +                nextPyr_.clear();
 +
 +
 +
 +                dx_buf_.release();
 +
 +                dy_buf_.release();
 +
 +            }
 +
 +
 +
 +        private:
 +
 +            void calcSharrDeriv(const oclMat &src, oclMat &dx, oclMat &dy);
 +
 +
 +
 +            void buildImagePyramid(const oclMat &img0, std::vector<oclMat> &pyr, bool withBorder);
 +
 +
 +
 +            oclMat dx_calcBuf_;
 +
 +            oclMat dy_calcBuf_;
 +
 +
 +
 +            std::vector<oclMat> prevPyr_;
 +
 +            std::vector<oclMat> nextPyr_;
 +
 +
 +
 +            oclMat dx_buf_;
 +
 +            oclMat dy_buf_;
 +
 +
 +
 +            oclMat uPyr_[2];
 +
 +            oclMat vPyr_[2];
 +
 +
 +
 +            bool isDeviceArch11_;
 +
 +        };
 +        //////////////// build warping maps ////////////////////
 +        //! builds plane warping maps
 +        CV_EXPORTS void buildWarpPlaneMaps(Size src_size, Rect dst_roi, const Mat &K, const Mat &R, const Mat &T, float scale, oclMat &map_x, oclMat &map_y);
 +        //! builds cylindrical warping maps
 +        CV_EXPORTS void buildWarpCylindricalMaps(Size src_size, Rect dst_roi, const Mat &K, const Mat &R, float scale, oclMat &map_x, oclMat &map_y);
 +        //! builds spherical warping maps
 +        CV_EXPORTS void buildWarpSphericalMaps(Size src_size, Rect dst_roi, const Mat &K, const Mat &R, float scale, oclMat &map_x, oclMat &map_y);
 +        //! builds Affine warping maps
 +        CV_EXPORTS void buildWarpAffineMaps(const Mat &M, bool inverse, Size dsize, oclMat &xmap, oclMat &ymap);
 +
 +        //! builds Perspective warping maps
 +        CV_EXPORTS void buildWarpPerspectiveMaps(const Mat &M, bool inverse, Size dsize, oclMat &xmap, oclMat &ymap);
 +
 +        ///////////////////////////////////// interpolate frames //////////////////////////////////////////////
 +        //! Interpolate frames (images) using provided optical flow (displacement field).
 +        //! frame0   - frame 0 (32-bit floating point images, single channel)
 +        //! frame1   - frame 1 (the same type and size)
 +        //! fu       - forward horizontal displacement
 +        //! fv       - forward vertical displacement
 +        //! bu       - backward horizontal displacement
 +        //! bv       - backward vertical displacement
 +        //! pos      - new frame position
 +        //! newFrame - new frame
 +        //! buf      - temporary buffer, will have width x 6*height size, CV_32FC1 type and contain 6 oclMat;
 +        //!            occlusion masks            0, occlusion masks            1,
 +        //!            interpolated forward flow  0, interpolated forward flow  1,
 +        //!            interpolated backward flow 0, interpolated backward flow 1
 +        //!
 +        CV_EXPORTS void interpolateFrames(const oclMat &frame0, const oclMat &frame1,
 +                                          const oclMat &fu, const oclMat &fv,
 +                                          const oclMat &bu, const oclMat &bv,
 +                                          float pos, oclMat &newFrame, oclMat &buf);
 +
 +        //! computes moments of the rasterized shape or a vector of points
 +        CV_EXPORTS Moments ocl_moments(InputArray _array, bool binaryImage);
 +
 +        class CV_EXPORTS StereoBM_OCL
 +        {
 +        public:
 +            enum { BASIC_PRESET = 0, PREFILTER_XSOBEL = 1 };
 +
 +            enum { DEFAULT_NDISP = 64, DEFAULT_WINSZ = 19 };
 +
 +            //! the default constructor
 +            StereoBM_OCL();
 +            //! the full constructor taking the camera-specific preset, number of disparities and the SAD window size. ndisparities must be multiple of 8.
 +            StereoBM_OCL(int preset, int ndisparities = DEFAULT_NDISP, int winSize = DEFAULT_WINSZ);
 +
 +            //! the stereo correspondence operator. Finds the disparity for the specified rectified stereo pair
 +            //! Output disparity has CV_8U type.
 +            void operator() ( const oclMat &left, const oclMat &right, oclMat &disparity);
 +
 +            //! Some heuristics that tries to estmate
 +            // if current GPU will be faster then CPU in this algorithm.
 +            // It queries current active device.
 +            static bool checkIfGpuCallReasonable();
 +
 +            int preset;
 +            int ndisp;
 +            int winSize;
 +
 +            // If avergeTexThreshold  == 0 => post procesing is disabled
 +            // If avergeTexThreshold != 0 then disparity is set 0 in each point (x,y) where for left image
 +            // SumOfHorizontalGradiensInWindow(x, y, winSize) < (winSize * winSize) * avergeTexThreshold
 +            // i.e. input left image is low textured.
 +            float avergeTexThreshold;
 +        private:
 +            oclMat minSSD, leBuf, riBuf;
 +        };
++        class CV_EXPORTS StereoBeliefPropagation
++        {
++        public:
++            enum { DEFAULT_NDISP  = 64 };
++            enum { DEFAULT_ITERS  = 5  };
++            enum { DEFAULT_LEVELS = 5  };
++            static void estimateRecommendedParams(int width, int height, int &ndisp, int &iters, int &levels);
++            explicit StereoBeliefPropagation(int ndisp  = DEFAULT_NDISP,
++                                             int iters  = DEFAULT_ITERS,
++                                             int levels = DEFAULT_LEVELS,
++                                             int msg_type = CV_16S);
++            StereoBeliefPropagation(int ndisp, int iters, int levels,
++                                    float max_data_term, float data_weight,
++                                    float max_disc_term, float disc_single_jump,
++                                    int msg_type = CV_32F);
++            void operator()(const oclMat &left, const oclMat &right, oclMat &disparity);
++            void operator()(const oclMat &data, oclMat &disparity);
++            int ndisp;
++            int iters;
++            int levels;
++            float max_data_term;
++            float data_weight;
++            float max_disc_term;
++            float disc_single_jump;
++            int msg_type;
++        private:
++            oclMat u, d, l, r, u2, d2, l2, r2;
++            std::vector<oclMat> datas;
++            oclMat out;
++        };
 +    }
 +}
 +#if defined _MSC_VER && _MSC_VER >= 1200
 +#  pragma warning( push)
 +#  pragma warning( disable: 4267)
 +#endif
 +#include "opencv2/ocl/matrix_operations.hpp"
 +#if defined _MSC_VER && _MSC_VER >= 1200
 +#  pragma warning( pop)
 +#endif
 +
 +#endif /* __OPENCV_OCL_HPP__ */
  
  #include "precomp.hpp"
  
- #ifdef HAVE_OPENCL
+ int main(int argc, const char *argv[])
+ {
+     vector<ocl::Info> oclinfo;
+     int num_devices = getDevice(oclinfo);
  
- using namespace std;
- using namespace cv;
- using namespace cv::ocl;
- using namespace cvtest;
- using namespace testing;
+     if (num_devices < 1)
+     {
+         cerr << "no device found\n";
+         return -1;
+     }
+     int devidx = 0;
+     for (size_t i = 0; i < oclinfo.size(); i++)
+     {
+         for (size_t j = 0; j < oclinfo[i].DeviceName.size(); j++)
+         {
+             printf("device %d: %s\n", devidx++, oclinfo[i].DeviceName[j].c_str());
+         }
+     }
+     redirectError(cvErrorCallback);
  
- void print_info()
- {
-     printf("\n");
- #if defined _WIN32
- #   if defined _WIN64
-     puts("OS: Windows 64");
- #   else
-     puts("OS: Windows 32");
- #   endif
- #elif defined linux
- #   if defined _LP64
-     puts("OS: Linux 64");
- #   else
-     puts("OS: Linux 32");
- #   endif
- #elif defined __APPLE__
- #   if defined _LP64
-     puts("OS: Apple 64");
- #   else
-     puts("OS: Apple 32");
- #   endif
- #endif
- }
- std::string workdir;
- int main(int argc, char **argv)
- {
-     TS::ptr()->init("ocl");
-     InitGoogleTest(&argc, argv);
      const char *keys =
-         "{ h | false              | print help message }"
-               "{ w | ../../../samples/c/| set working directory i.e. -w=C:\\}"
-         "{ t | gpu                | set device type:i.e. -t=cpu or gpu}"
-         "{ p | 0                  | set platform id i.e. -p=0}"
-         "{ d | 0                  | set device id i.e. -d=0}";
 -        "{ h | help    | false | print help message }"
 -        "{ f | filter  |       | filter for test }"
 -        "{ w | workdir |       | set working directory }"
 -        "{ l | list    | false | show all tests }"
 -        "{ d | device  | 0     | device id }"
 -        "{ i | iters   | 10    | iteration count }"
 -        "{ m | warmup  | 1     | gpu warm up iteration count}"
 -        "{ t | xtop    | 1.1    | xfactor top boundary}"
 -        "{ b | xbottom | 0.9    | xfactor bottom boundary}"
 -        "{ v | verify  | false | only run gpu once to verify if problems occur}";
++        "{ h help    | false | print help message }"
++        "{ f filter  |       | filter for test }"
++        "{ w workdir |       | set working directory }"
++        "{ l list    | false | show all tests }"
++        "{ d device  | 0     | device id }"
++        "{ i iters   | 10    | iteration count }"
++        "{ m warmup  | 1     | gpu warm up iteration count}"
++        "{ t xtop    | 1.1      | xfactor top boundary}"
++        "{ b xbottom | 0.9      | xfactor bottom boundary}"
++        "{ v verify  | false | only run gpu once to verify if problems occur}";
  
      CommandLineParser cmd(argc, argv, keys);
-     if (cmd.get<string>("h")=="true")
 -    if (cmd.get<bool>("help"))
++    if (cmd.has("help"))
      {
-         cout << "Avaible options besides goole test option:" << endl;
+         cout << "Avaible options:" << endl;
 -        cmd.printParams();
 +        cmd.printMessage();
          return 0;
      }
-     workdir = cmd.get<string>("w");
-     string type = cmd.get<string>("t");
-     unsigned int pid = cmd.get<unsigned int>("p");
-     int device = cmd.get<int>("d");
-     print_info();
-     // int flag = CVCL_DEVICE_TYPE_GPU;
-     // if(type == "cpu")
-     // {
-     //     flag = CVCL_DEVICE_TYPE_CPU;
-     // }
-     std::vector<cv::ocl::Info> oclinfo;
-     int devnums = getDevice(oclinfo);
-     if(devnums <= device || device < 0)
+     int device = cmd.get<int>("device");
+     if (device < 0 || device >= num_devices)
      {
-         std::cout << "device invalid\n";
+         cerr << "Invalid device ID" << endl;
          return -1;
      }
  
-     if(pid >= oclinfo.size())
+     if (cmd.get<bool>("verify"))
      {
-         std::cout << "platform invalid\n";
-         return -1;
+         TestSystem::instance().setNumIters(1);
+         TestSystem::instance().setGPUWarmupIters(0);
+         TestSystem::instance().setCPUIters(0);
      }
  
-     if(pid != 0 || device != 0)
+     devidx = 0;
+     for (size_t i = 0; i < oclinfo.size(); i++)
      {
-         setDevice(oclinfo[pid], device);
+         for (size_t j = 0; j < oclinfo[i].DeviceName.size(); j++, devidx++)
+         {
+             if (device == devidx)
+             {
+                 ocl::setDevice(oclinfo[i], (int)j);
+                 TestSystem::instance().setRecordName(oclinfo[i].DeviceName[j]);
+                 printf("\nuse %d: %s\n", devidx, oclinfo[i].DeviceName[j].c_str());
+                 goto END_DEV;
+             }
+         }
      }
  
-     cout << "Device type:" << type << endl << "Device name:" << oclinfo[pid].DeviceName[device] << endl;
-     setBinpath(CLBINPATH);
-     return RUN_ALL_TESTS();
- }
+ END_DEV:
  
- #else // DON'T HAVE_OPENCL
+     string filter = cmd.get<string>("filter");
+     string workdir = cmd.get<string>("workdir");
 -    bool list = cmd.get<bool>("list");
++    bool list = cmd.has("list");
+     int iters = cmd.get<int>("iters");
+     int wu_iters = cmd.get<int>("warmup");
+     double x_top = cmd.get<double>("xtop");
+     double x_bottom = cmd.get<double>("xbottom");
  
- int main()
- {
-     printf("OpenCV was built without OpenCL support\n");
-     return 0;
- }
+     TestSystem::instance().setTopThreshold(x_top);
+     TestSystem::instance().setBottomThreshold(x_bottom);
+     if (!filter.empty())
+     {
+         TestSystem::instance().setTestFilter(filter);
+     }
+     if (!workdir.empty())
+     {
+         if (workdir[workdir.size() - 1] != '/' && workdir[workdir.size() - 1] != '\\')
+         {
+             workdir += '/';
+         }
+         TestSystem::instance().setWorkingDir(workdir);
+     }
+     if (list)
+     {
+         TestSystem::instance().setListMode(true);
+     }
  
+     TestSystem::instance().setNumIters(iters);
+     TestSystem::instance().setGPUWarmupIters(wu_iters);
  
- #endif // HAVE_OPENCL
+     TestSystem::instance().run();
+     return 0;
+ }
  
  #include "precomp.hpp"
  
 -      if(msg != "CL_INVALID_BUFFER_SIZE")
 -      {
 -              cout << TAB << "[error: " << msg << "] " << cur_subtest_description_.str() << endl;
 -      }
+ // This program test most of the functions in ocl module and generate data metrix of x-factor in .csv files
+ // All images needed in this test are in samples/gpu folder.
+ // For haar template, haarcascade_frontalface_alt.xml shouold be in working directory
+ void TestSystem::run()
+ {
+     if (is_list_mode_)
+     {
+         for (vector<Runnable *>::iterator it = tests_.begin(); it != tests_.end(); ++it)
+         {
+             cout << (*it)->name() << endl;
+         }
+         return;
+     }
+     // Run test initializers
+     for (vector<Runnable *>::iterator it = inits_.begin(); it != inits_.end(); ++it)
+     {
+         if ((*it)->name().find(test_filter_, 0) != string::npos)
+         {
+             (*it)->run();
+         }
+     }
+     printHeading();
+     writeHeading();
+     // Run tests
+     for (vector<Runnable *>::iterator it = tests_.begin(); it != tests_.end(); ++it)
+     {
+         try
+         {
+             if ((*it)->name().find(test_filter_, 0) != string::npos)
+             {
+                 cout << endl << (*it)->name() << ":\n";
+                 setCurrentTest((*it)->name());
+                 //fprintf(record_,"%s\n",(*it)->name().c_str());
+                 (*it)->run();
+                 finishCurrentSubtest();
+             }
+         }
+         catch (const Exception &)
+         {
+             // Message is printed via callback
+             resetCurrentSubtest();
+         }
+         catch (const runtime_error &e)
+         {
+             printError(e.what());
+             resetCurrentSubtest();
+         }
+     }
+     printSummary();
+     writeSummary();
+ }
+ void TestSystem::finishCurrentSubtest()
+ {
+     if (cur_subtest_is_empty_)
+         // There is no need to print subtest statistics
+     {
+         return;
+     }
+     double cpu_time = cpu_elapsed_ / getTickFrequency() * 1000.0;
+     double gpu_time = gpu_elapsed_ / getTickFrequency() * 1000.0;
+     double gpu_full_time = gpu_full_elapsed_ / getTickFrequency() * 1000.0;
+     double speedup = static_cast<double>(cpu_elapsed_) / std::max(1.0, gpu_elapsed_);
+     speedup_total_ += speedup;
+     double fullspeedup = static_cast<double>(cpu_elapsed_) / std::max(1.0, gpu_full_elapsed_);
+     speedup_full_total_ += fullspeedup;
+     if (speedup > top_)
+     {
+         speedup_faster_count_++;
+     }
+     else if (speedup < bottom_)
+     {
+         speedup_slower_count_++;
+     }
+     else
+     {
+         speedup_equal_count_++;
+     }
+     if (fullspeedup > top_)
+     {
+         speedup_full_faster_count_++;
+     }
+     else if (fullspeedup < bottom_)
+     {
+         speedup_full_slower_count_++;
+     }
+     else
+     {
+         speedup_full_equal_count_++;
+     }
+     // compute min, max and
+     std::sort(gpu_times_.begin(), gpu_times_.end());
+     double gpu_min = gpu_times_.front() / getTickFrequency() * 1000.0;
+     double gpu_max = gpu_times_.back() / getTickFrequency() * 1000.0;
+     double deviation = 0;
+     if (gpu_times_.size() > 1)
+     {
+         double sum = 0;
+         for (size_t i = 0; i < gpu_times_.size(); i++)
+         {
+             int64 diff = gpu_times_[i] - static_cast<int64>(gpu_elapsed_);
+             double diff_time = diff * 1000 / getTickFrequency();
+             sum += diff_time * diff_time;
+         }
+         deviation = std::sqrt(sum / gpu_times_.size());
+     }
+     printMetrics(cpu_time, gpu_time, gpu_full_time, speedup, fullspeedup);
+     writeMetrics(cpu_time, gpu_time, gpu_full_time, speedup, fullspeedup, gpu_min, gpu_max, deviation);
+     num_subtests_called_++;
+     resetCurrentSubtest();
+ }
+ double TestSystem::meanTime(const vector<int64> &samples)
+ {
+     double sum = accumulate(samples.begin(), samples.end(), 0.);
+     return sum / samples.size();
+ }
+ void TestSystem::printHeading()
+ {
+     cout << endl;
+     cout << setiosflags(ios_base::left);
+     cout << TAB << setw(10) << "CPU, ms" << setw(10) << "GPU, ms"
+          << setw(14) << "SPEEDUP" << setw(14) << "GPUTOTAL, ms" << setw(14) << "TOTALSPEEDUP"
+          << "DESCRIPTION\n";
+     cout << resetiosflags(ios_base::left);
+ }
+ void TestSystem::writeHeading()
+ {
+     if (!record_)
+     {
+         recordname_ += "_OCL.csv";
+         record_ = fopen(recordname_.c_str(), "w");
+     }
+     fprintf(record_, "NAME,DESCRIPTION,CPU (ms),GPU (ms),SPEEDUP,GPUTOTAL (ms),TOTALSPEEDUP,GPU Min (ms),GPU Max (ms), Standard deviation (ms)\n");
+     fflush(record_);
+ }
+ void TestSystem::printSummary()
+ {
+     cout << setiosflags(ios_base::fixed);
+     cout << "\naverage GPU speedup: x"
+          << setprecision(3) << speedup_total_ / std::max(1, num_subtests_called_)
+          << endl;
+     cout << "\nGPU exceeded: "
+          << setprecision(3) << speedup_faster_count_
+          << "\nGPU passed: "
+          << setprecision(3) << speedup_equal_count_
+          << "\nGPU failed: "
+          << setprecision(3) << speedup_slower_count_
+          << endl;
+     cout << "\nGPU exceeded rate: "
+          << setprecision(3) << (float)speedup_faster_count_ / std::max(1, num_subtests_called_) * 100
+          << "%"
+          << "\nGPU passed rate: "
+          << setprecision(3) << (float)speedup_equal_count_ / std::max(1, num_subtests_called_) * 100
+          << "%"
+          << "\nGPU failed rate: "
+          << setprecision(3) << (float)speedup_slower_count_ / std::max(1, num_subtests_called_) * 100
+          << "%"
+          << endl;
+     cout << "\naverage GPUTOTAL speedup: x"
+          << setprecision(3) << speedup_full_total_ / std::max(1, num_subtests_called_)
+          << endl;
+     cout << "\nGPUTOTAL exceeded: "
+          << setprecision(3) << speedup_full_faster_count_
+          << "\nGPUTOTAL passed: "
+          << setprecision(3) << speedup_full_equal_count_
+          << "\nGPUTOTAL failed: "
+          << setprecision(3) << speedup_full_slower_count_
+          << endl;
+     cout << "\nGPUTOTAL exceeded rate: "
+          << setprecision(3) << (float)speedup_full_faster_count_ / std::max(1, num_subtests_called_) * 100
+          << "%"
+          << "\nGPUTOTAL passed rate: "
+          << setprecision(3) << (float)speedup_full_equal_count_ / std::max(1, num_subtests_called_) * 100
+          << "%"
+          << "\nGPUTOTAL failed rate: "
+          << setprecision(3) << (float)speedup_full_slower_count_ / std::max(1, num_subtests_called_) * 100
+          << "%"
+          << endl;
+     cout << resetiosflags(ios_base::fixed);
+ }
+ void TestSystem::printMetrics(double cpu_time, double gpu_time, double gpu_full_time, double speedup, double fullspeedup)
+ {
+     cout << TAB << setiosflags(ios_base::left);
+     stringstream stream;
+     stream << cpu_time;
+     cout << setw(10) << stream.str();
+     stream.str("");
+     stream << gpu_time;
+     cout << setw(10) << stream.str();
+     stream.str("");
+     stream << "x" << setprecision(3) << speedup;
+     cout << setw(14) << stream.str();
+     stream.str("");
+     stream << gpu_full_time;
+     cout << setw(14) << stream.str();
+     stream.str("");
+     stream << "x" << setprecision(3) << fullspeedup;
+     cout << setw(14) << stream.str();
+     cout << cur_subtest_description_.str();
+     cout << resetiosflags(ios_base::left) << endl;
+ }
+ void TestSystem::writeMetrics(double cpu_time, double gpu_time, double gpu_full_time, double speedup, double fullspeedup, double gpu_min, double gpu_max, double std_dev)
+ {
+     if (!record_)
+     {
+         recordname_ += ".csv";
+         record_ = fopen(recordname_.c_str(), "w");
+     }
+     fprintf(record_, "%s,%s,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f\n", itname_changed_ ? itname_.c_str() : "",
+             cur_subtest_description_.str().c_str(),
+             cpu_time, gpu_time, speedup, gpu_full_time, fullspeedup,
+             gpu_min, gpu_max, std_dev);
+     if (itname_changed_)
+     {
+         itname_changed_ = false;
+     }
+     fflush(record_);
+ }
+ void TestSystem::writeSummary()
+ {
+     if (!record_)
+     {
+         recordname_ += ".csv";
+         record_ = fopen(recordname_.c_str(), "w");
+     }
+     fprintf(record_, "\nAverage GPU speedup: %.3f\n"
+             "exceeded: %d (%.3f%%)\n"
+             "passed: %d (%.3f%%)\n"
+             "failed: %d (%.3f%%)\n"
+             "\nAverage GPUTOTAL speedup: %.3f\n"
+             "exceeded: %d (%.3f%%)\n"
+             "passed: %d (%.3f%%)\n"
+             "failed: %d (%.3f%%)\n",
+             speedup_total_ / std::max(1, num_subtests_called_),
+             speedup_faster_count_, (float)speedup_faster_count_ / std::max(1, num_subtests_called_) * 100,
+             speedup_equal_count_, (float)speedup_equal_count_ / std::max(1, num_subtests_called_) * 100,
+             speedup_slower_count_, (float)speedup_slower_count_ / std::max(1, num_subtests_called_) * 100,
+             speedup_full_total_ / std::max(1, num_subtests_called_),
+             speedup_full_faster_count_, (float)speedup_full_faster_count_ / std::max(1, num_subtests_called_) * 100,
+             speedup_full_equal_count_, (float)speedup_full_equal_count_ / std::max(1, num_subtests_called_) * 100,
+             speedup_full_slower_count_, (float)speedup_full_slower_count_ / std::max(1, num_subtests_called_) * 100
+            );
+     fflush(record_);
+ }
+ void TestSystem::printError(const std::string &msg)
+ {
++    if(msg != "CL_INVALID_BUFFER_SIZE")
++    {
++        cout << TAB << "[error: " << msg << "] " << cur_subtest_description_.str() << endl;
++    }
+ }
+ void gen(Mat &mat, int rows, int cols, int type, Scalar low, Scalar high)
+ {
+     mat.create(rows, cols, type);
+     RNG rng(0);
+     rng.fill(mat, RNG::UNIFORM, low, high);
+ }
+ string abspath(const string &relpath)
+ {
+     return TestSystem::instance().workingDir() + relpath;
+ }
+ int CV_CDECL cvErrorCallback(int /*status*/, const char * /*func_name*/,
+                              const char *err_msg, const char * /*file_name*/,
+                              int /*line*/, void * /*userdata*/)
+ {
+     TestSystem::instance().printError(err_msg);
+     return 0;
+ }
  
  //
  //M*/
  
- #ifdef __GNUC__
- #  pragma GCC diagnostic ignored "-Wmissing-declarations"
- #  if defined __clang__ || defined __APPLE__
- #    pragma GCC diagnostic ignored "-Wmissing-prototypes"
- #    pragma GCC diagnostic ignored "-Wextra"
- #  endif
- #endif
- #ifndef __OPENCV_TEST_PRECOMP_HPP__
- #define __OPENCV_TEST_PRECOMP_HPP__
- #include <cmath>
- #include <cstdio>
- #include <iostream>
- #include <fstream>
- #include <sstream>
+ #include <iomanip>
+ #include <stdexcept>
  #include <string>
- #include <limits>
- #include <algorithm>
- #include <iterator>
- #include <string>
- #include <cstdarg>
- #include "opencv2/highgui.hpp"
+ #include <iostream>
+ #include <cstdio>
+ #include <vector>
+ #include <numeric>
 -#include "opencv2/core/core.hpp"
 -#include "opencv2/imgproc/imgproc.hpp"
 -#include "opencv2/highgui/highgui.hpp"
 -#include "opencv2/video/video.hpp"
 -#include "opencv2/objdetect/objdetect.hpp"
 -#include "opencv2/features2d/features2d.hpp"
 -#include "opencv2/ocl/ocl.hpp"
++#include "opencv2/core.hpp"
 +#include "opencv2/imgproc.hpp"
++#include "opencv2/highgui.hpp"
 +#include "opencv2/video.hpp"
- #include "opencv2/ts.hpp"
++#include "opencv2/objdetect.hpp"
++#include "opencv2/features2d.hpp"
 +#include "opencv2/ocl.hpp"
  
- #include "utility.hpp"
- #include "interpolation.hpp"
+ #define Min_Size 1000
+ #define Max_Size 4000
+ #define Multiple 2
+ #define TAB "    "
+ using namespace std;
+ using namespace cv;
+ void gen(Mat &mat, int rows, int cols, int type, Scalar low, Scalar high);
+ string abspath(const string &relpath);
+ int CV_CDECL cvErrorCallback(int, const char *, const char *, const char *, int, void *);
+ typedef struct
+ {
+     short x;
+     short y;
+ } COOR;
+ COOR do_meanShift(int x0, int y0, uchar *sptr, uchar *dptr, int sstep,
+                   cv::Size size, int sp, int sr, int maxIter, float eps, int *tab);
+ void meanShiftProc_(const Mat &src_roi, Mat &dst_roi, Mat &dstCoor_roi,
+                     int sp, int sr, cv::TermCriteria crit);
+ class Runnable
+ {
+ public:
+     explicit Runnable(const std::string &runname): name_(runname) {}
+     virtual ~Runnable() {}
+     const std::string &name() const
+     {
+         return name_;
+     }
+     virtual void run() = 0;
+ private:
+     std::string name_;
+ };
+ class TestSystem
+ {
+ public:
+     static TestSystem &instance()
+     {
+         static TestSystem me;
+         return me;
+     }
+     void setWorkingDir(const std::string &val)
+     {
+         working_dir_ = val;
+     }
+     const std::string &workingDir() const
+     {
+         return working_dir_;
+     }
+     void setTestFilter(const std::string &val)
+     {
+         test_filter_ = val;
+     }
+     const std::string &testFilter() const
+     {
+         return test_filter_;
+     }
+     void setNumIters(int num_iters)
+     {
+         num_iters_ = num_iters;
+     }
+     void setGPUWarmupIters(int num_iters)
+     {
+         gpu_warmup_iters_ = num_iters;
+     }
+     void setCPUIters(int num_iters)
+     {
+         cpu_num_iters_ = num_iters;
+     }
+     void setTopThreshold(double top)
+     {
+         top_ = top;
+     }
+     void setBottomThreshold(double bottom)
+     {
+         bottom_ = bottom;
+     }
+     void addInit(Runnable *init)
+     {
+         inits_.push_back(init);
+     }
+     void addTest(Runnable *test)
+     {
+         tests_.push_back(test);
+     }
+     void run();
+     // It's public because OpenCV callback uses it
+     void printError(const std::string &msg);
+     std::stringstream &startNewSubtest()
+     {
+         finishCurrentSubtest();
+         return cur_subtest_description_;
+     }
+     bool stop() const
+     {
+         return cur_iter_idx_ >= num_iters_;
+     }
+     bool cpu_stop() const
+     {
+         return cur_iter_idx_ >= cpu_num_iters_;
+     }
+     bool warmupStop()
+     {
+         return cur_warmup_idx_++ >= gpu_warmup_iters_;
+     }
+     void warmupComplete()
+     {
+         cur_warmup_idx_ = 0;
+     }
+     void cpuOn()
+     {
+         cpu_started_ = cv::getTickCount();
+     }
+     void cpuOff()
+     {
+         int64 delta = cv::getTickCount() - cpu_started_;
+         cpu_times_.push_back(delta);
+         ++cur_iter_idx_;
+     }
+     void cpuComplete()
+     {
+         cpu_elapsed_ += meanTime(cpu_times_);
+         cur_subtest_is_empty_ = false;
+         cur_iter_idx_ = 0;
+     }
+     void gpuOn()
+     {
+         gpu_started_ = cv::getTickCount();
+     }
+     void gpuOff()
+     {
+         int64 delta = cv::getTickCount() - gpu_started_;
+         gpu_times_.push_back(delta);
+         ++cur_iter_idx_;
+     }
+     void gpuComplete()
+     {
+         gpu_elapsed_ += meanTime(gpu_times_);
+         cur_subtest_is_empty_ = false;
+         cur_iter_idx_ = 0;
+     }
+     void gpufullOn()
+     {
+         gpu_full_started_ = cv::getTickCount();
+     }
+     void gpufullOff()
+     {
+         int64 delta = cv::getTickCount() - gpu_full_started_;
+         gpu_full_times_.push_back(delta);
+         ++cur_iter_idx_;
+     }
+     void gpufullComplete()
+     {
+         gpu_full_elapsed_ += meanTime(gpu_full_times_);
+         cur_subtest_is_empty_ = false;
+         cur_iter_idx_ = 0;
+     }
+     bool isListMode() const
+     {
+         return is_list_mode_;
+     }
+     void setListMode(bool value)
+     {
+         is_list_mode_ = value;
+     }
+     void setRecordName(const std::string &name)
+     {
+         recordname_ = name;
+     }
+     void setCurrentTest(const std::string &name)
+     {
+         itname_ = name;
+         itname_changed_ = true;
+     }
+ private:
+     TestSystem():
+         cur_subtest_is_empty_(true), cpu_elapsed_(0),
+         gpu_elapsed_(0), gpu_full_elapsed_(0), speedup_total_(0.0),
+         num_subtests_called_(0),
+         speedup_faster_count_(0), speedup_slower_count_(0), speedup_equal_count_(0),
+         speedup_full_faster_count_(0), speedup_full_slower_count_(0), speedup_full_equal_count_(0), is_list_mode_(false),
+         num_iters_(10), cpu_num_iters_(2),
+         gpu_warmup_iters_(1), cur_iter_idx_(0), cur_warmup_idx_(0),
+         record_(0), recordname_("performance"), itname_changed_(true)
+     {
+         cpu_times_.reserve(num_iters_);
+         gpu_times_.reserve(num_iters_);
+         gpu_full_times_.reserve(num_iters_);
+     }
+     void finishCurrentSubtest();
+     void resetCurrentSubtest()
+     {
+         cpu_elapsed_ = 0;
+         gpu_elapsed_ = 0;
+         gpu_full_elapsed_ = 0;
+         cur_subtest_description_.str("");
+         cur_subtest_is_empty_ = true;
+         cur_iter_idx_ = 0;
+         cpu_times_.clear();
+         gpu_times_.clear();
+         gpu_full_times_.clear();
+     }
+     double meanTime(const std::vector<int64> &samples);
+     void printHeading();
+     void printSummary();
+     void printMetrics(double cpu_time, double gpu_time = 0.0f, double gpu_full_time = 0.0f, double speedup = 0.0f, double fullspeedup = 0.0f);
+     void writeHeading();
+     void writeSummary();
+     void writeMetrics(double cpu_time, double gpu_time = 0.0f, double gpu_full_time = 0.0f,
+                       double speedup = 0.0f, double fullspeedup = 0.0f,
+                       double gpu_min = 0.0f, double gpu_max = 0.0f, double std_dev = 0.0f);
+     std::string working_dir_;
+     std::string test_filter_;
+     std::vector<Runnable *> inits_;
+     std::vector<Runnable *> tests_;
+     std::stringstream cur_subtest_description_;
+     bool cur_subtest_is_empty_;
+     int64 cpu_started_;
+     int64 gpu_started_;
+     int64 gpu_full_started_;
+     double cpu_elapsed_;
+     double gpu_elapsed_;
+     double gpu_full_elapsed_;
+     double speedup_total_;
+     double speedup_full_total_;
+     int num_subtests_called_;
+     int speedup_faster_count_;
+     int speedup_slower_count_;
+     int speedup_equal_count_;
+     int speedup_full_faster_count_;
+     int speedup_full_slower_count_;
+     int speedup_full_equal_count_;
+     bool is_list_mode_;
+     double top_;
+     double bottom_;
+     int num_iters_;
 -    int cpu_num_iters_;               //there's no need to set cpu running same times with gpu
 -    int gpu_warmup_iters_;    //gpu warm up times, default is 1
++    int cpu_num_iters_;     //there's no need to set cpu running same times with gpu
++    int gpu_warmup_iters_;  //gpu warm up times, default is 1
+     int cur_iter_idx_;
 -    int cur_warmup_idx_;      //current gpu warm up times
++    int cur_warmup_idx_;    //current gpu warm up times
+     std::vector<int64> cpu_times_;
+     std::vector<int64> gpu_times_;
+     std::vector<int64> gpu_full_times_;
+     FILE *record_;
+     std::string recordname_;
+     std::string itname_;
+     bool itname_changed_;
+ };
+ #define GLOBAL_INIT(name) \
+ struct name##_init: Runnable { \
 -      name##_init(): Runnable(#name) { \
 -      TestSystem::instance().addInit(this); \
++    name##_init(): Runnable(#name) { \
++    TestSystem::instance().addInit(this); \
+ } \
 -      void run(); \
++    void run(); \
+ } name##_init_instance; \
 -      void name##_init::run()
++    void name##_init::run()
+ #define TEST(name) \
+ struct name##_test: Runnable { \
 -      name##_test(): Runnable(#name) { \
 -      TestSystem::instance().addTest(this); \
++    name##_test(): Runnable(#name) { \
++    TestSystem::instance().addTest(this); \
+ } \
 -      void run(); \
++    void run(); \
+ } name##_test_instance; \
 -      void name##_test::run()
++    void name##_test::run()
+ #define SUBTEST TestSystem::instance().startNewSubtest()
+ #define CPU_ON \
 -      while (!TestSystem::instance().cpu_stop()) { \
 -      TestSystem::instance().cpuOn()
++    while (!TestSystem::instance().cpu_stop()) { \
++    TestSystem::instance().cpuOn()
+ #define CPU_OFF \
 -      TestSystem::instance().cpuOff(); \
 -      } TestSystem::instance().cpuComplete()
++    TestSystem::instance().cpuOff(); \
++    } TestSystem::instance().cpuComplete()
  
- #include "opencv2/core/private.hpp"
+ #define GPU_ON \
 -      while (!TestSystem::instance().stop()) { \
 -      TestSystem::instance().gpuOn()
++    while (!TestSystem::instance().stop()) { \
++    TestSystem::instance().gpuOn()
+ #define GPU_OFF \
+     ocl::finish(); \
 -      TestSystem::instance().gpuOff(); \
 -      } TestSystem::instance().gpuComplete()
++    TestSystem::instance().gpuOff(); \
++    } TestSystem::instance().gpuComplete()
  
- #endif
+ #define GPU_FULL_ON \
 -      while (!TestSystem::instance().stop()) { \
 -      TestSystem::instance().gpufullOn()
++    while (!TestSystem::instance().stop()) { \
++    TestSystem::instance().gpufullOn()
+ #define GPU_FULL_OFF \
 -      TestSystem::instance().gpufullOff(); \
 -      } TestSystem::instance().gpufullComplete()
++    TestSystem::instance().gpufullOff(); \
++    } TestSystem::instance().gpufullComplete()
  
 -      while (!TestSystem::instance().warmupStop()) {
+ #define WARMUP_ON \
 -      } TestSystem::instance().warmupComplete()
++    while (!TestSystem::instance().warmupStop()) {
+ #define WARMUP_OFF \
+         ocl::finish(); \
++    } TestSystem::instance().warmupComplete()
Simple merge
@@@ -902,19 -910,21 +907,21 @@@ namespace c
          }
  
          /////////////////////////////OpenCL initialization/////////////////
 -        auto_ptr<Context> Context::clCxt;
 +        std::auto_ptr<Context> Context::clCxt;
          int Context::val = 0;
          static Mutex cs;
-         Context *Context::getContext()
+         static volatile int context_tear_down = 0;
+         Context* Context::getContext()
          {
              if(*((volatile int*)&val) != 1)
              {
                  AutoLock al(cs);
                  if(*((volatile int*)&val) != 1)
                  {
+                     if (context_tear_down)
+                         return clCxt.get();
                      if( 0 == clCxt.get())
 -                        clCxt.reset(new Context);
 +                    clCxt.reset(new Context);
                      std::vector<Info> oclinfo;
                      CV_Assert(getDevice(oclinfo, CVCL_DEVICE_TYPE_ALL) > 0);
                      oclinfo[0].impl->setDevice(0, 0, 0);
@@@ -195,7 -197,8 +195,8 @@@ namespace c
                  const size_t regin[3] = {mat.cols * mat.elemSize(), mat.rows, 1};
                  clEnqueueCopyBufferRect((cl_command_queue)mat.clCxt->oclCommandQueue(), (cl_mem)mat.data, devData, origin, origin,
                      regin, mat.step, 0, mat.cols * mat.elemSize(), 0, 0, NULL, NULL);
-             }
 -                clFlush((cl_command_queue)mat.clCxt->oclCommandQueue()); 
++                clFlush((cl_command_queue)mat.clCxt->oclCommandQueue());
+            }
              else
              {
                  devData = (cl_mem)mat.data;
@@@ -62,7 -66,10 +66,10 @@@ __kernel void arithm_absdiff_D0 (__glob
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
+ #ifdef dst_align
+ #undef dst_align
+ #endif
          #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
@@@ -110,8 -117,11 +117,11 @@@ __kernel void arithm_absdiff_D2 (__glob
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -144,8 -154,11 +154,11 @@@ __kernel void arithm_absdiff_D3 (__glob
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -248,8 -261,11 +261,11 @@@ __kernel void arithm_s_absdiff_C1_D0 (_
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -287,8 -303,11 +303,11 @@@ __kernel void arithm_s_absdiff_C1_D2 (_
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -318,8 -337,11 +337,11 @@@ __kernel void arithm_s_absdiff_C1_D3 (_
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -421,8 -443,11 +443,11 @@@ __kernel void arithm_s_absdiff_C2_D0 (_
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -563,8 -588,11 +588,11 @@@ __kernel void arithm_s_absdiff_C3_D0 (_
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -617,8 -645,11 +645,11 @@@ __kernel void arithm_s_absdiff_C3_D2 (_
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -667,8 -698,11 +698,11 @@@ __kernel void arithm_s_absdiff_C3_D3 (_
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -121,8 -128,11 +128,11 @@@ __kernel void addWeighted_D2 (__global 
      {
  
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset -( dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset -( dst_align << 1));
  
@@@ -181,8 -191,11 +191,11 @@@ __kernel void addWeighted_D3 (__global 
      {
  
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset -( dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset -( dst_align << 1));
  
@@@ -241,9 -254,12 +254,12 @@@ __kernel void addWeighted_D4 (__global 
  
          x = x << 2;
  
        #define bitOfInt  (sizeof(int)== 4 ? 2: 3)
+ #define bitOfInt  (sizeof(int)== 4 ? 2: 3)
 -        
 +
-         #define dst_align ((dst_offset >> bitOfInt) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> bitOfInt) & 3)
  
          int src1_index = mad24(y, src1_step, (x << bitOfInt) + src1_offset - (dst_align << bitOfInt));
          int src2_index = mad24(y, src2_step, (x << bitOfInt) + src2_offset - (dst_align << bitOfInt));
@@@ -303,8 -319,11 +319,11 @@@ __kernel void addWeighted_D5 (__global 
      {
  
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 2) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 2) & 3)
  
          int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2));
          int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2));
@@@ -365,8 -384,11 +384,11 @@@ __kernel void addWeighted_D6 (__global 
      {
  
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 3) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 3) & 3)
  
          int src1_index = mad24(y, src1_step, (x << 3) + src1_offset - (dst_align << 3));
          int src2_index = mad24(y, src2_step, (x << 3) + src2_offset - (dst_align << 3));
@@@ -58,8 -62,11 +62,11 @@@ __kernel void arithm_s_add_C1_D0 (__glo
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -98,8 -105,11 +105,11 @@@ __kernel void arithm_s_add_C1_D2 (__glo
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -130,8 -140,11 +140,11 @@@ __kernel void arithm_s_add_C1_D3 (__glo
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -232,8 -245,11 +245,11 @@@ __kernel void arithm_s_add_C2_D0 (__glo
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -377,8 -393,11 +393,11 @@@ __kernel void arithm_s_add_C3_D0 (__glo
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -431,8 -450,11 +450,11 @@@ __kernel void arithm_s_add_C3_D2 (__glo
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -481,8 -503,11 +503,11 @@@ __kernel void arithm_s_add_C3_D3 (__glo
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -60,8 -64,11 +64,11 @@@ __kernel void arithm_s_add_with_mask_C1
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -110,8 -117,11 +117,11 @@@ __kernel void arithm_s_add_with_mask_C1
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -145,8 -155,11 +155,11 @@@ __kernel void arithm_s_add_with_mask_C1
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -266,8 -279,11 +279,11 @@@ __kernel void arithm_s_add_with_mask_C2
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -442,8 -458,11 +458,11 @@@ __kernel void arithm_s_add_with_mask_C3
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -500,8 -519,11 +519,11 @@@ __kernel void arithm_s_add_with_mask_C3
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -554,8 -576,11 +576,11 @@@ __kernel void arithm_s_add_with_mask_C3
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -61,8 -65,11 +65,11 @@@ __kernel void arithm_bitwise_and_D0 (__
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
  
@@@ -111,8 -118,11 +118,11 @@@ __kernel void arithm_bitwise_and_D1 (__
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
  
@@@ -162,8 -172,11 +172,11 @@@ __kernel void arithm_bitwise_and_D2 (__
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -214,8 -227,11 +227,11 @@@ __kernel void arithm_bitwise_and_D3 (__
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -63,8 -67,11 +67,11 @@@ __kernel void arithm_bitwise_and_with_m
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -104,8 -112,11 +112,11 @@@ __kernel void arithm_bitwise_and_with_m
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -145,8 -157,11 +157,11 @@@ __kernel void arithm_bitwise_and_with_m
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -184,8 -200,11 +200,11 @@@ __kernel void arithm_bitwise_and_with_m
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -322,8 -343,11 +343,11 @@@ __kernel void arithm_bitwise_and_with_m
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -360,8 -385,11 +385,11 @@@ __kernel void arithm_bitwise_and_with_m
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -547,8 -580,11 +580,11 @@@ __kernel void arithm_bitwise_and_with_m
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
          int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -609,8 -646,11 +646,11 @@@ __kernel void arithm_bitwise_and_with_m
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
          int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -670,8 -711,11 +711,11 @@@ __kernel void arithm_bitwise_and_with_m
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
          int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -726,8 -771,11 +771,11 @@@ __kernel void arithm_bitwise_and_with_m
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
          int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -62,8 -65,11 +65,11 @@@ __kernel void arithm_s_bitwise_and_C1_D
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -96,8 -103,11 +103,11 @@@ __kernel void arithm_s_bitwise_and_C1_D
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -130,8 -141,11 +141,11 @@@ __kernel void arithm_s_bitwise_and_C1_D
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -161,8 -176,11 +176,11 @@@ __kernel void arithm_s_bitwise_and_C1_D
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -267,8 -288,11 +288,11 @@@ __kernel void arithm_s_bitwise_and_C2_D
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -301,8 -326,11 +326,11 @@@ __kernel void arithm_s_bitwise_and_C2_D
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -439,8 -473,11 +473,11 @@@ __kernel void arithm_s_bitwise_and_C3_D
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -495,8 -533,11 +533,11 @@@ __kernel void arithm_s_bitwise_and_C3_D
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -550,8 -592,11 +592,11 @@@ __kernel void arithm_s_bitwise_and_C3_D
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -600,8 -646,11 +646,11 @@@ __kernel void arithm_s_bitwise_and_C3_D
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -64,8 -66,11 +66,11 @@@ __kernel void arithm_s_bitwise_and_with
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -102,8 -108,11 +108,11 @@@ __kernel void arithm_s_bitwise_and_with
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -139,8 -149,11 +149,11 @@@ __kernel void arithm_s_bitwise_and_with
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -173,8 -187,11 +187,11 @@@ __kernel void arithm_s_bitwise_and_with
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -292,8 -313,11 +313,11 @@@ __kernel void arithm_s_bitwise_and_with
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -328,8 -353,11 +353,11 @@@ __kernel void arithm_s_bitwise_and_with
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -501,8 -535,11 +535,11 @@@ __kernel void arithm_s_bitwise_and_with
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -561,8 -599,11 +599,11 @@@ __kernel void arithm_s_bitwise_and_with
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -620,8 -662,11 +662,11 @@@ __kernel void arithm_s_bitwise_and_with
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -674,8 -720,11 +720,11 @@@ __kernel void arithm_s_bitwise_and_with
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -60,8 -63,11 +63,11 @@@ __kernel void arithm_bitwise_not_D0 (__
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -100,8 -106,11 +106,11 @@@ __kernel void arithm_bitwise_not_D1 (__
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -134,8 -143,11 +143,11 @@@ __kernel void arithm_bitwise_not_D2 (__
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -169,8 -181,11 +181,11 @@@ __kernel void arithm_bitwise_not_D3 (__
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -61,8 -65,11 +65,11 @@@ __kernel void arithm_bitwise_or_D0 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
  
@@@ -109,8 -116,11 +116,11 @@@ __kernel void arithm_bitwise_or_D1 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
  
@@@ -146,8 -156,11 +156,11 @@@ __kernel void arithm_bitwise_or_D2 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -184,8 -197,11 +197,11 @@@ __kernel void arithm_bitwise_or_D3 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -63,8 -67,11 +67,11 @@@ __kernel void arithm_bitwise_or_with_ma
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -104,8 -112,11 +112,11 @@@ __kernel void arithm_bitwise_or_with_ma
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -145,8 -157,11 +157,11 @@@ __kernel void arithm_bitwise_or_with_ma
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -184,8 -200,11 +200,11 @@@ __kernel void arithm_bitwise_or_with_ma
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -322,8 -343,11 +343,11 @@@ __kernel void arithm_bitwise_or_with_ma
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -360,8 -385,11 +385,11 @@@ __kernel void arithm_bitwise_or_with_ma
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -547,8 -580,11 +580,11 @@@ __kernel void arithm_bitwise_or_with_ma
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
          int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -609,8 -646,11 +646,11 @@@ __kernel void arithm_bitwise_or_with_ma
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
          int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -670,8 -711,11 +711,11 @@@ __kernel void arithm_bitwise_or_with_ma
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
          int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -726,8 -771,11 +771,11 @@@ __kernel void arithm_bitwise_or_with_ma
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
          int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -60,8 -65,11 +65,11 @@@ __kernel void arithm_s_bitwise_or_C1_D
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -94,8 -103,11 +103,11 @@@ __kernel void arithm_s_bitwise_or_C1_D
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -128,8 -141,11 +141,11 @@@ __kernel void arithm_s_bitwise_or_C1_D
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -159,8 -176,11 +176,11 @@@ __kernel void arithm_s_bitwise_or_C1_D
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -258,8 -281,11 +281,11 @@@ __kernel void arithm_s_bitwise_or_C2_D
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -292,8 -319,11 +319,11 @@@ __kernel void arithm_s_bitwise_or_C2_D
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -435,8 -470,11 +470,11 @@@ __kernel void arithm_s_bitwise_or_C3_D
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -492,8 -531,11 +531,11 @@@ __kernel void arithm_s_bitwise_or_C3_D
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -548,8 -591,11 +591,11 @@@ __kernel void arithm_s_bitwise_or_C3_D
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -599,8 -646,11 +646,11 @@@ __kernel void arithm_s_bitwise_or_C3_D
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -63,8 -67,11 +67,11 @@@ __kernel void arithm_s_bitwise_or_with_
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -102,8 -110,11 +110,11 @@@ __kernel void arithm_s_bitwise_or_with_
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -140,8 -152,11 +152,11 @@@ __kernel void arithm_s_bitwise_or_with_
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -175,8 -191,11 +191,11 @@@ __kernel void arithm_s_bitwise_or_with_
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -298,8 -320,11 +320,11 @@@ __kernel void arithm_s_bitwise_or_with_
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -335,8 -361,11 +361,11 @@@ __kernel void arithm_s_bitwise_or_with_
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -512,8 -547,11 +547,11 @@@ __kernel void arithm_s_bitwise_or_with_
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -573,8 -612,11 +612,11 @@@ __kernel void arithm_s_bitwise_or_with_
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -633,8 -676,11 +676,11 @@@ __kernel void arithm_s_bitwise_or_with_
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -688,8 -735,11 +735,11 @@@ __kernel void arithm_s_bitwise_or_with_
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -61,8 -64,11 +64,11 @@@ __kernel void arithm_bitwise_xor_D0 (__
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
  
@@@ -111,8 -117,11 +117,11 @@@ __kernel void arithm_bitwise_xor_D1 (__
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
  
@@@ -162,8 -171,11 +171,11 @@@ __kernel void arithm_bitwise_xor_D2 (__
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -214,8 -226,11 +226,11 @@@ __kernel void arithm_bitwise_xor_D3 (__
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -63,8 -67,11 +67,11 @@@ __kernel void arithm_bitwise_xor_with_m
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -104,8 -112,11 +112,11 @@@ __kernel void arithm_bitwise_xor_with_m
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -145,8 -157,11 +157,11 @@@ __kernel void arithm_bitwise_xor_with_m
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -184,8 -200,11 +200,11 @@@ __kernel void arithm_bitwise_xor_with_m
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -322,8 -343,11 +343,11 @@@ __kernel void arithm_bitwise_xor_with_m
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -360,8 -385,11 +385,11 @@@ __kernel void arithm_bitwise_xor_with_m
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -547,8 -580,11 +580,11 @@@ __kernel void arithm_bitwise_xor_with_m
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
          int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -609,8 -646,11 +646,11 @@@ __kernel void arithm_bitwise_xor_with_m
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
          int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -670,8 -711,11 +711,11 @@@ __kernel void arithm_bitwise_xor_with_m
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
          int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -726,8 -771,11 +771,11 @@@ __kernel void arithm_bitwise_xor_with_m
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
          int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
@@@ -62,8 -64,11 +64,11 @@@ __kernel void arithm_s_bitwise_xor_C1_D
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -96,8 -102,11 +102,11 @@@ __kernel void arithm_s_bitwise_xor_C1_D
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -130,8 -140,11 +140,11 @@@ __kernel void arithm_s_bitwise_xor_C1_D
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -161,8 -175,11 +175,11 @@@ __kernel void arithm_s_bitwise_xor_C1_D
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -267,8 -288,11 +288,11 @@@ __kernel void arithm_s_bitwise_xor_C2_D
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -301,8 -326,11 +326,11 @@@ __kernel void arithm_s_bitwise_xor_C2_D
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -439,8 -473,11 +473,11 @@@ __kernel void arithm_s_bitwise_xor_C3_D
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -495,8 -533,11 +533,11 @@@ __kernel void arithm_s_bitwise_xor_C3_D
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -550,8 -592,11 +592,11 @@@ __kernel void arithm_s_bitwise_xor_C3_D
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -600,8 -646,11 +646,11 @@@ __kernel void arithm_s_bitwise_xor_C3_D
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -64,8 -67,11 +67,11 @@@ __kernel void arithm_s_bitwise_xor_with
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -102,8 -109,11 +109,11 @@@ __kernel void arithm_s_bitwise_xor_with
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -139,8 -150,11 +150,11 @@@ __kernel void arithm_s_bitwise_xor_with
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -173,8 -188,11 +188,11 @@@ __kernel void arithm_s_bitwise_xor_with
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -292,8 -314,11 +314,11 @@@ __kernel void arithm_s_bitwise_xor_with
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -328,8 -354,11 +354,11 @@@ __kernel void arithm_s_bitwise_xor_with
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -501,8 -536,11 +536,11 @@@ __kernel void arithm_s_bitwise_xor_with
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -561,8 -600,11 +600,11 @@@ __kernel void arithm_s_bitwise_xor_with
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
          int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -620,8 -663,11 +663,11 @@@ __kernel void arithm_s_bitwise_xor_with
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -674,8 -721,11 +721,11 @@@ __kernel void arithm_s_bitwise_xor_with
      if (x < cols && y < rows)
      {
          x = x << 1;
 -        
 +
-         #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
          int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
          int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
  
@@@ -61,8 -65,11 +65,11 @@@ __kernel void arithm_compare_eq_D0 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
  
@@@ -113,8 -120,11 +120,11 @@@ __kernel void arithm_compare_ne_D2 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1)& 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1)& 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -164,8 -174,11 +174,11 @@@ __kernel void arithm_compare_eq_D3 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -357,8 -380,11 +380,11 @@@ __kernel void arithm_compare_gt_D0 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
  
@@@ -408,8 -434,11 +434,11 @@@ __kernel void arithm_compare_gt_D2 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -461,8 -490,11 +490,11 @@@ __kernel void arithm_compare_gt_D3 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -659,8 -700,11 +700,11 @@@ __kernel void arithm_compare_ge_D0 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
  
@@@ -713,8 -757,11 +757,11 @@@ __kernel void arithm_compare_ge_D2 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -768,8 -815,11 +815,11 @@@ __kernel void arithm_compare_ge_D3 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1)& 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1)& 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -819,8 -869,11 +869,11 @@@ __kernel void arithm_compare_ge_D4 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 2)& 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 2)& 3)
          int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2));
          int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2));
  
@@@ -868,8 -921,11 +921,11 @@@ __kernel void arithm_compare_ge_D5 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 2)& 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 2)& 3)
          int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2));
          int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2));
  
@@@ -919,8 -975,11 +975,11 @@@ __kernel void arithm_compare_ge_D6 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 3)& 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 3)& 3)
          int src1_index = mad24(y, src1_step, (x << 3) + src1_offset - (dst_align << 3));
          int src2_index = mad24(y, src2_step, (x << 3) + src2_offset - (dst_align << 3));
  
@@@ -57,8 -61,11 +61,11 @@@ __kernel void arithm_compare_ne_D0 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
  
@@@ -109,8 -116,11 +116,11 @@@ __kernel void arithm_compare_ne_D2 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1)& 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1)& 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -161,8 -171,11 +171,11 @@@ __kernel void arithm_compare_ne_D3 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1)& 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1)& 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -357,8 -380,11 +380,11 @@@ __kernel void arithm_compare_lt_D0 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
  
@@@ -409,8 -435,11 +435,11 @@@ __kernel void arithm_compare_lt_D2 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -462,8 -491,11 +491,11 @@@ __kernel void arithm_compare_lt_D3 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -663,8 -704,11 +704,11 @@@ __kernel void arithm_compare_le_D0 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
  
@@@ -716,8 -760,11 +760,11 @@@ __kernel void arithm_compare_le_D2 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -769,8 -816,11 +816,11 @@@ __kernel void arithm_compare_le_D3 (__g
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -94,39 -88,41 +88,41 @@@ __kernel void arithm_div_D0 (__global u
                               __global uchar *dst,  int dst_step,  int dst_offset,
                               int rows, int cols, int dst_step1, F scalar)
  {
-     int x = get_global_id(0);
-     int y = get_global_id(1);
+     int2 coor = (int2)(get_global_id(0), get_global_id(1));
  
-     if (x < cols && y < rows)
+     if (coor.x < cols && coor.y < rows)
      {
-         x = x << 2;
+         coor.x = coor.x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
-         int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
-         int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
+         int2 src_index = (int2)(mad24(coor.y, src1_step, coor.x + src1_offset - dst_align),
+                                 mad24(coor.y, src2_step, coor.x + src2_offset - dst_align));
  
-         int dst_start  = mad24(y, dst_step, dst_offset);
-         int dst_end    = mad24(y, dst_step, dst_offset + dst_step1);
-         int dst_index  = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+         int4 dst_args  = (int4)(mad24(coor.y, dst_step, dst_offset),
+                                 mad24(coor.y, dst_step, dst_offset + dst_step1),
+                                 mad24(coor.y, dst_step, dst_offset + coor.x & (int)0xfffffffc),
+                                 0);
  
-         uchar4 src1_data = vload4(0, src1 + src1_index);
-         uchar4 src2_data = vload4(0, src2 + src2_index);
-         uchar4 dst_data  = *((__global uchar4 *)(dst + dst_index));
+         uchar4 src1_data = vload4(0, src1 + src_index.x);
+         uchar4 src2_data = vload4(0, src2 + src_index.y);
+         uchar4 dst_data  = *((__global uchar4 *)(dst + dst_args.z));
  
          F4 tmp      = convert_F4(src1_data) * scalar;
          uchar4 tmp_data;
-         tmp_data.x = ((tmp.x == 0) || (src2_data.x == 0)) ? 0 : round2_uchar(tmp.x / (F)src2_data.x);
-         tmp_data.y = ((tmp.y == 0) || (src2_data.y == 0)) ? 0 : round2_uchar(tmp.y / (F)src2_data.y);
-         tmp_data.z = ((tmp.z == 0) || (src2_data.z == 0)) ? 0 : round2_uchar(tmp.z / (F)src2_data.z);
-         tmp_data.w = ((tmp.w == 0) || (src2_data.w == 0)) ? 0 : round2_uchar(tmp.w / (F)src2_data.w);
+         tmp_data.x = ((tmp.x == 0) || (src2_data.x == 0)) ? 0 : round2_uchar(tmp.x / src2_data.x);
+         tmp_data.y = ((tmp.y == 0) || (src2_data.y == 0)) ? 0 : round2_uchar(tmp.y / src2_data.y);
+         tmp_data.z = ((tmp.z == 0) || (src2_data.z == 0)) ? 0 : round2_uchar(tmp.z / src2_data.z);
+         tmp_data.w = ((tmp.w == 0) || (src2_data.w == 0)) ? 0 : round2_uchar(tmp.w / src2_data.w);
  
-         dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
-         dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
-         dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
-         dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+         dst_data.x = ((dst_args.z + 0 >= dst_args.x) && (dst_args.z + 0 < dst_args.y)) ? tmp_data.x : dst_data.x;
+         dst_data.y = ((dst_args.z + 1 >= dst_args.x) && (dst_args.z + 1 < dst_args.y)) ? tmp_data.y : dst_data.y;
+         dst_data.z = ((dst_args.z + 2 >= dst_args.x) && (dst_args.z + 2 < dst_args.y)) ? tmp_data.z : dst_data.z;
+         dst_data.w = ((dst_args.z + 3 >= dst_args.x) && (dst_args.z + 3 < dst_args.y)) ? tmp_data.w : dst_data.w;
  
-         *((__global uchar4 *)(dst + dst_index)) = dst_data;
+         *((__global uchar4 *)(dst + dst_args.z)) = dst_data;
      }
  }
  
@@@ -141,8 -137,11 +137,11 @@@ __kernel void arithm_div_D2 (__global u
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -181,8 -180,11 +180,11 @@@ __kernel void arithm_div_D3 (__global s
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -296,8 -298,11 +298,11 @@@ __kernel void arithm_s_div_D0 (__globa
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src_index = mad24(y, src_step, x + src_offset - dst_align);
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -332,8 -337,11 +337,11 @@@ __kernel void arithm_s_div_D2 (__globa
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src_index = mad24(y, src_step, (x << 1) + src_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -367,8 -375,11 +375,11 @@@ __kernel void arithm_s_div_D3 (__globa
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src_index = mad24(y, src_step, (x << 1) + src_offset - (dst_align << 1));
  
          int dst_start  = mad24(y, dst_step, dst_offset);
@@@ -60,8 -64,11 +64,11 @@@ __kernel void arithm_flip_rows_D0 (__gl
      if (x < cols && y < thread_rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src_index_0 = mad24(y,            src_step, x + src_offset - dst_align);
          int src_index_1 = mad24(rows - y - 1, src_step, x + src_offset - dst_align);
  
@@@ -115,8 -122,11 +122,11 @@@ __kernel void arithm_flip_rows_D1 (__gl
      if (x < cols && y < thread_rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src_index_0 = mad24(y,            src_step, x + src_offset - dst_align);
          int src_index_1 = mad24(rows - y - 1, src_step, x + src_offset - dst_align);
  
@@@ -157,8 -167,11 +167,11 @@@ __kernel void arithm_flip_rows_D2 (__gl
      if (x < cols && y < thread_rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset >> 1) & 3) << 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset >> 1) & 3) << 1)
          int src_index_0 = mad24(y,            src_step, (x << 1) + src_offset - dst_align);
          int src_index_1 = mad24(rows - y - 1, src_step, (x << 1) + src_offset - dst_align);
  
@@@ -199,8 -212,11 +212,11 @@@ __kernel void arithm_flip_rows_D3 (__gl
      if (x < cols && y < thread_rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (((dst_offset >> 1) & 3) << 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset >> 1) & 3) << 1)
          int src_index_0 = mad24(y,            src_step, (x << 1) + src_offset - dst_align);
          int src_index_1 = mad24(rows - y - 1, src_step, (x << 1) + src_offset - dst_align);
  
@@@ -84,8 -90,11 +90,11 @@@ __kernel void arithm_mul_D0 (__global u
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
          int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
          int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
  
@@@ -129,8 -138,11 +138,11 @@@ __kernel void arithm_mul_D2 (__global u
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
@@@ -165,8 -177,11 +177,11 @@@ __kernel void arithm_mul_D3 (__global s
      if (x < cols && y < rows)
      {
          x = x << 2;
 -        
 +
-         #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
          int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
          int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
  
index 0000000,3196e58..3993aca
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,380 +1,380 @@@
 -    return convert_short_sat_rte(v); 
+ /*M///////////////////////////////////////////////////////////////////////////////////////
+ //
+ //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+ //
+ //  By downloading, copying, installing or using the software you agree to this license.
+ //  If you do not agree to this license, do not download, install,
+ //  copy or use the software.
+ //
+ //
+ //                           License Agreement
+ //                For Open Source Computer Vision Library
+ // Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
+ // Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved.
+ // Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
+ // Third party copyrights are property of their respective owners.
+ //
+ // @Authors
+ //    Jia Haipeng, jiahaipeng95@gmail.com
+ //    Peng Xiao,   pengxiao@outlook.com
+ //
+ // Redistribution and use in source and binary forms, with or without modification,
+ // are permitted provided that the following conditions are met:
+ //
+ //   * Redistribution's of source code must retain the above copyright notice,
+ //     this list of conditions and the following disclaimer.
+ //
+ //   * Redistribution's in binary form must reproduce the above copyright notice,
+ //     this list of conditions and the following disclaimer in the documentation
+ //     and/or other GpuMaterials provided with the distribution.
+ //
+ //   * The name of the copyright holders may not be used to endorse or promote products
+ //     derived from this software without specific prior written permission.
+ //
+ // This software is provided by the copyright holders and contributors as is and
+ // any express or implied warranties, including, but not limited to, the implied
+ // warranties of merchantability and fitness for a particular purpose are disclaimed.
+ // In no event shall the Intel Corporation or contributors be liable for any direct,
+ // indirect, incidental, special, exemplary, or consequential damages
+ // (including, but not limited to, procurement of substitute goods or services;
+ // loss of use, data, or profits; or business interruption) however caused
+ // and on any theory of liability, whether in contract, strict liability,
+ // or tort (including negligence or otherwise) arising in any way out of
+ // the use of this software, even if advised of the possibility of such damage.
+ //
+ //M*/
+ #if defined (DOUBLE_SUPPORT)
+ #ifdef cl_khr_fp64
+ #pragma OPENCL EXTENSION cl_khr_fp64:enable
+ #elif defined (cl_amd_fp64)
+ #pragma OPENCL EXTENSION cl_amd_fp64:enable
+ #endif
+ #endif
+ #ifdef T_FLOAT
+ #define T float
+ #else
+ #define T short
+ #endif
+ ///////////////////////////////////////////////////////////////
+ /////////////////common///////////////////////////////////////
+ /////////////////////////////////////////////////////////////
+ T saturate_cast(float v){
+ #ifdef T_SHORT
 -    return abs((int)(*ls) - *rs); 
++    return convert_short_sat_rte(v);
+ #else
+     return v;
+ #endif
+ }
+ #define FLOAT_MAX 3.402823466e+38f
+ typedef struct
+ {
+     int   cndisp;
+     float cmax_data_term;
+     float cdata_weight;
+     float cmax_disc_term;
+     float cdisc_single_jump;
+ }con_srtuct_t;
+ ///////////////////////////////////////////////////////////////
+ ////////////////////////// comp data //////////////////////////
+ ///////////////////////////////////////////////////////////////
+ float pix_diff_1(__global const uchar *ls, __global const uchar *rs)
+ {
 -                ds[disp * disp_step] =  saturate_cast(fmin(con_st -> cdata_weight * val, 
++    return abs((int)(*ls) - *rs);
+ }
+ float pix_diff_3(__global const uchar *ls, __global const uchar *rs)
+ {
+     const float tr = 0.299f;
+     const float tg = 0.587f;
+     const float tb = 0.114f;
+     float val;
+     val =  tb * abs((int)ls[0] - rs[0]);
+     val += tg * abs((int)ls[1] - rs[1]);
+     val += tr * abs((int)ls[2] - rs[2]);
+     return val;
+ }
+ float pix_diff_4(__global const uchar *ls, __global const uchar *rs)
+ {
+     uchar4 l, r;
+     l = *((__global uchar4 *)ls);
+     r = *((__global uchar4 *)rs);
+     const float tr = 0.299f;
+     const float tg = 0.587f;
+     const float tb = 0.114f;
+     float val;
+     val  = tb * abs((int)l.x - r.x);
+     val += tg * abs((int)l.y - r.y);
+     val += tr * abs((int)l.z - r.z);
+     return val;
+ }
+ #ifndef CN
+ #define CN 4
+ #endif
+ #define CAT(X,Y) X##Y
+ #define CAT2(X,Y) CAT(X,Y)
+ #define PIX_DIFF CAT2(pix_diff_, CN)
+ __kernel void comp_data(__global uchar *left,  int left_rows,  int left_cols,  int left_step,
+                         __global uchar *right, int right_step,
+                         __global T *data, int data_step,
+                         __constant con_srtuct_t *con_st)
+ {
+     int x = get_global_id(0);
+     int y = get_global_id(1);
+     if (y > 0 && y < (left_rows - 1) && x > 0 && x < (left_cols - 1))
+     {
+         data_step /= sizeof(T);
+         const __global uchar* ls = left  + y * left_step  + x * CN;
+         const __global uchar* rs = right + y * right_step + x * CN;
+         __global T *ds = data + y * data_step + x;
+         const unsigned int disp_step = data_step * left_rows;
+         for (int disp = 0; disp < con_st -> cndisp; disp++)
+         {
+             if (x - disp >= 1)
+             {
+                 float val = 0;
+                 val = PIX_DIFF(ls, rs - disp * CN);
 -__kernel void data_step_down(__global T *src, int src_rows, 
 -                             __global T *dst, int dst_rows, int dst_cols, 
++                ds[disp * disp_step] =  saturate_cast(fmin(con_st -> cdata_weight * val,
+                     con_st -> cdata_weight * con_st -> cmax_data_term));
+             }
+             else
+             {
+                 ds[disp * disp_step] =  saturate_cast(con_st -> cdata_weight * con_st -> cmax_data_term);
+             }
+         }
+     }
+ }
+ ///////////////////////////////////////////////////////////////
+ //////////////////////// data step down ///////////////////////
+ ///////////////////////////////////////////////////////////////
 -void calc_min_linear_penalty(__global T * dst, int disp_step, 
++__kernel void data_step_down(__global T *src, int src_rows,
++                             __global T *dst, int dst_rows, int dst_cols,
+                              int src_step, int dst_step,
+                              int cndisp)
+ {
+     const int x = get_global_id(0);
+     const int y = get_global_id(1);
+     if (x < dst_cols && y < dst_rows)
+     {
+         src_step /= sizeof(T);
+         dst_step /= sizeof(T);
+         for (int d = 0; d < cndisp; ++d)
+         {
+             float dst_reg;
+             dst_reg  = src[(d * src_rows + (2*y+0)) * src_step + 2*x+0];
+             dst_reg += src[(d * src_rows + (2*y+1)) * src_step + 2*x+0];
+             dst_reg += src[(d * src_rows + (2*y+0)) * src_step + 2*x+1];
+             dst_reg += src[(d * src_rows + (2*y+1)) * src_step + 2*x+1];
+             dst[(d * dst_rows + y) * dst_step + x] = saturate_cast(dst_reg);
+         }
+     }
+ }
+ ///////////////////////////////////////////////////////////////
+ /////////////////// level up messages  ////////////////////////
+ ///////////////////////////////////////////////////////////////
+ __kernel void level_up_message(__global T *src, int src_rows, int src_step,
+                                __global T *dst, int dst_rows, int dst_cols, int dst_step,
+                                int cndisp)
+ {
+     const int x = get_global_id(0);
+     const int y = get_global_id(1);
+     if (x < dst_cols && y < dst_rows)
+     {
+         src_step /= sizeof(T);
+         dst_step /= sizeof(T);
+         const int dst_disp_step = dst_step * dst_rows;
+         const int src_disp_step = src_step * src_rows;
+         __global T       *dstr = dst + y * dst_step + x;
+         __global const T *srcr = src + (y / 2 * src_step) + (x / 2);
+         for (int d = 0; d < cndisp; ++d)
+             dstr[d * dst_disp_step] = srcr[d * src_disp_step];
+     }
+ }
+ ///////////////////////////////////////////////////////////////
+ ////////////////////  calc all iterations /////////////////////
+ ///////////////////////////////////////////////////////////////
 -                            int t, int cols, int rows, 
++void calc_min_linear_penalty(__global T * dst, int disp_step,
+                              int cndisp, float cdisc_single_jump)
+ {
+     float prev = dst[0];
+     float cur;
+     for (int disp = 1; disp < cndisp; ++disp)
+     {
+         prev += cdisc_single_jump;
+         cur = dst[disp_step * disp];
+         if (prev < cur)
+         {
+             cur = prev;
+             dst[disp_step * disp] = saturate_cast(prev);
+         }
+         prev = cur;
+     }
+     prev = dst[(cndisp - 1) * disp_step];
+     for (int disp = cndisp - 2; disp >= 0; disp--)
+     {
+         prev += cdisc_single_jump;
+         cur = dst[disp_step * disp];
+         if (prev < cur)
+         {
+             cur = prev;
+             dst[disp_step * disp] = saturate_cast(prev);
+         }
+         prev = cur;
+     }
+ }
+ void message(const __global T *msg1, const __global T *msg2,
+              const __global T *msg3, const __global T *data, __global T *dst,
+              int msg_disp_step, int data_disp_step, int cndisp, float cmax_disc_term, float cdisc_single_jump)
+ {
+     float minimum = FLOAT_MAX;
+     for(int i = 0; i < cndisp; ++i)
+     {
+         float dst_reg;
+         dst_reg  = msg1[msg_disp_step * i];
+         dst_reg += msg2[msg_disp_step * i];
+         dst_reg += msg3[msg_disp_step * i];
+         dst_reg += data[data_disp_step * i];
+         if (dst_reg < minimum)
+             minimum = dst_reg;
+         dst[msg_disp_step * i] = saturate_cast(dst_reg);
+     }
+     calc_min_linear_penalty(dst, msg_disp_step, cndisp, cdisc_single_jump);
+     minimum += cmax_disc_term;
+     float sum = 0;
+     for(int i = 0; i < cndisp; ++i)
+     {
+         float dst_reg = dst[msg_disp_step * i];
+         if (dst_reg > minimum)
+         {
+             dst_reg = minimum;
+             dst[msg_disp_step * i] = saturate_cast(minimum);
+         }
+         sum += dst_reg;
+     }
+     sum /= cndisp;
+     for(int i = 0; i < cndisp; ++i)
+         dst[msg_disp_step * i] -= sum;
+ }
+ __kernel void one_iteration(__global T *u,    int u_step,
+                             __global T *data, int data_step,
+                             __global T *d,    __global T *l, __global T *r,
 -        message(us + u_step, ls      + 1, rs - 1, dt, us, msg_disp_step, data_disp_step, cndisp, 
++                            int t, int cols, int rows,
+                             int cndisp, float cmax_disc_term, float cdisc_single_jump)
+ {
+     const int y = get_global_id(1);
+     const int x = ((get_global_id(0)) << 1) + ((y + t) & 1);
+     if ((y > 0) && (y < rows - 1) && (x > 0) && (x < cols - 1))
+     {
+         u_step    /= sizeof(T);
+         data_step /= sizeof(T);
+         __global T *us = u + y * u_step + x;
+         __global T *ds = d + y * u_step + x;
+         __global T *ls = l + y * u_step + x;
+         __global T *rs = r + y * u_step + x;
+         const __global  T *dt = data + y * data_step + x;
+         int msg_disp_step = u_step * rows;
+         int data_disp_step = data_step * rows;
++        message(us + u_step, ls      + 1, rs - 1, dt, us, msg_disp_step, data_disp_step, cndisp,
+             cmax_disc_term, cdisc_single_jump);
+         message(ds - u_step, ls      + 1, rs - 1, dt, ds, msg_disp_step, data_disp_step, cndisp,
+             cmax_disc_term, cdisc_single_jump);
+         message(us + u_step, ds - u_step, rs - 1, dt, rs, msg_disp_step, data_disp_step, cndisp,
+             cmax_disc_term, cdisc_single_jump);
+         message(us + u_step, ds - u_step, ls + 1, dt, ls, msg_disp_step, data_disp_step, cndisp,
+             cmax_disc_term, cdisc_single_jump);
+     }
+ }
+ ///////////////////////////////////////////////////////////////
+ /////////////////////////// output ////////////////////////////
+ ///////////////////////////////////////////////////////////////
+ __kernel void output(const __global T *u, int u_step,
+                      const __global T *d, const __global T *l,
+                      const __global T *r, const __global T *data,
+                      __global T *disp, int disp_rows, int disp_cols, int disp_step,
+                      int cndisp)
+ {
+     const int x = get_global_id(0);
+     const int y = get_global_id(1);
+     if (y > 0 && y < disp_rows - 1 && x > 0 && x < disp_cols - 1)
+     {
+         u_step    /= sizeof(T);
+         disp_step /= sizeof(T);
+         const __global T *us = u + (y + 1) * u_step + x;
+         const __global T *ds = d + (y - 1) * u_step + x;
+         const __global T *ls = l + y * u_step + (x + 1);
+         const __global T *rs = r + y * u_step + (x - 1);
+         const __global T *dt = data + y * u_step + x;
+         int disp_steps = disp_rows * u_step;
+         int best = 0;
+         float best_val = FLOAT_MAX;
+         for (int d = 0; d < cndisp; ++d)
+         {
+             float val;
+             val  = us[d * disp_steps];
+             val += ds[d * disp_steps];
+             val += ls[d * disp_steps];
+             val += rs[d * disp_steps];
+             val += dt[d * disp_steps];
+             if (val < best_val)
+             {
+                 best_val = val;
+                 best = d;
+             }
+         }
+         (disp + y * disp_step)[x] = convert_short_sat(best);
+     }
+ }
index 0000000,bd88ec0..50072c2
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,519 +1,517 @@@
 -using namespace std;
+ /*M///////////////////////////////////////////////////////////////////////////////////////
+ //
+ //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+ //
+ //  By downloading, copying, installing or using the software you agree to this license.
+ //  If you do not agree to this license, do not download, install,
+ //  copy or use the software.
+ //
+ //
+ //                           License Agreement
+ //                For Open Source Computer Vision Library
+ //
+ // Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
+ // Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved.
+ // Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
+ // Third party copyrights are property of their respective owners.
+ //
+ // @Authors
+ //    Jia Haipeng, jiahaipeng95@gmail.com
+ //    Peng Xiao,   pengxiao@outlook.com
+ // Redistribution and use in source and binary forms, with or without modification,
+ // are permitted provided that the following conditions are met:
+ //
+ //   * Redistribution's of source code must retain the above copyright notice,
+ //     this list of conditions and the following disclaimer.
+ //
+ //   * Redistribution's in binary form must reproduce the above copyright notice,
+ //     this list of conditions and the following disclaimer in the documentation
+ //     and/or other oclMaterials provided with the distribution.
+ //
+ //   * The name of the copyright holders may not be used to endorse or promote products
+ //     derived from this software without specific prior written permission.
+ //
+ // This software is provided by the copyright holders and contributors "as is" and
+ // any express or implied warranties, including, but not limited to, the implied
+ // warranties of merchantability and fitness for a particular purpose are disclaimed.
+ // In no event shall the Intel Corporation or contributors be liable for any direct,
+ // indirect, incidental, special, exemplary, or consequential damages
+ // (including, but not limited to, procurement of substitute goods or services;
+ // loss of use, data, or profits; or business interruption) however caused
+ // and on any theory of liability, whether in contract, strict liability,
+ // or tort (including negligence or otherwise) arising in any way out of
+ // the use of this software, even if advised of the possibility of such damage.
+ //
+ //M*/
+ #include "precomp.hpp"
+ #include <vector>
+ #include <cstdio>
+ using namespace cv;
+ using namespace cv::ocl;
 -                              float /*cmax_data_term*/, float /*cdata_weight*/)
+ ////////////////////////////////////////////////////////////////////////
+ ///////////////// stereoBP /////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////
+ namespace cv
+ {
+     namespace ocl
+     {
+         ///////////////////////////OpenCL kernel strings///////////////////////////
+         extern const char *stereobp;
+     }
+ }
+ namespace cv
+ {
+     namespace ocl
+     {
+         namespace stereoBP
+         {
+             //////////////////////////////////////////////////////////////////////////
+             //////////////////////////////common////////////////////////////////////
+             ////////////////////////////////////////////////////////////////////////
+             typedef struct
+             {
+                 int   cndisp;
+                 float cmax_data_term;
+                 float cdata_weight;
+                 float cmax_disc_term;
+                 float cdisc_single_jump;
+             } con_struct_t;
+             cl_mem cl_con_struct =  NULL;
+             static void load_constants(int ndisp, float max_data_term, float data_weight,
+                                 float max_disc_term, float disc_single_jump)
+             {
+                 con_struct_t *con_struct = new con_struct_t;
+                 con_struct -> cndisp            = ndisp;
+                 con_struct -> cmax_data_term    = max_data_term;
+                 con_struct -> cdata_weight      = data_weight;
+                 con_struct -> cmax_disc_term    = max_disc_term;
+                 con_struct -> cdisc_single_jump = disc_single_jump;
+                 cl_con_struct = load_constant(*((cl_context*)getoclContext()), *((cl_command_queue*)getoclCommandQueue()), (void *)con_struct,
+                                               sizeof(con_struct_t));
+                 delete con_struct;
+             }
+             static void release_constants()
+             {
+                 openCLFree(cl_con_struct);
+             }
+             static inline int divUp(int total, int grain)
+             {
+                 return (total + grain - 1) / grain;
+             }
+             /////////////////////////////////////////////////////////////////////////////
+             ///////////////////////////comp data////////////////////////////////////////
+             /////////////////////////////////////////////////////////////////////////
+             static void  comp_data_call(const oclMat &left, const oclMat &right, oclMat &data, int /*disp*/,
 -                string kernelName = "comp_data";
++                float /*cmax_data_term*/, float /*cdata_weight*/)
+             {
+                 Context  *clCxt = left.clCxt;
+                 int channels = left.oclchannels();
+                 int data_type = data.type();
 -                vector<pair<size_t , const void *> > args;
++                String kernelName = "comp_data";
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&left.data));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&left.rows));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&left.cols));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&left.step));
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&right.data));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&right.step));
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&data.data));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&data.step));
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&cl_con_struct));
++                std::vector<std::pair<size_t , const void *> > args;
 -                sprintf( cn_opt, "%s -D CN=%d", 
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&left.data));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&left.rows));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&left.cols));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&left.step));
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&right.data));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&right.step));
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&data.data));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&data.step));
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&cl_con_struct));
+                 size_t gt[3] = {left.cols, left.rows, 1}, lt[3] = {16, 16, 1};
+                 const int OPT_SIZE = 50;
+                 char cn_opt [OPT_SIZE] = "";
 -                string kernelName = "data_step_down";
++                sprintf( cn_opt, "%s -D CN=%d",
+                     (data_type == CV_16S ? "-D T_SHORT":"-D T_FLOAT"),
+                     channels
+                     );
+                 openCLExecuteKernel(clCxt, &stereobp, kernelName, gt, lt, args, -1, -1, cn_opt);
+             }
+             ///////////////////////////////////////////////////////////////////////////////////
+             /////////////////////////data set down////////////////////////////////////////////
+             /////////////////////////////////////////////////////////////////////////////////
+             static void data_step_down_call(int dst_cols, int dst_rows, int src_rows,
+                 const oclMat &src, oclMat &dst, int disp)
+             {
+                 Context  *clCxt = src.clCxt;
+                 int data_type = src.type();
 -                vector<pair<size_t , const void *> > args;
++                String kernelName = "data_step_down";
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&src_rows));
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_rows));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_cols));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&src.step));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.step));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&disp));
++                std::vector<std::pair<size_t , const void *> > args;
 -                string kernelName = "level_up_message";
 -                vector<pair<size_t , const void *> > args;
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&src.data));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src_rows));
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&dst.data));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst_rows));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst_cols));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.step));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst.step));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&disp));
+                 size_t gt[3] = {dst_cols, dst_rows, 1}, lt[3] = {16, 16, 1};
+                 const char* t_opt  = data_type == CV_16S ? "-D T_SHORT":"-D T_FLOAT";
+                 openCLExecuteKernel(clCxt, &stereobp, kernelName, gt, lt, args, -1, -1, t_opt);
+             }
+             /////////////////////////////////////////////////////////////////////////////////
+             ///////////////////////////live up message////////////////////////////////////////
+             /////////////////////////////////////////////////////////////////////////////////
+             static void level_up_message_call(int dst_cols, int dst_rows, int src_rows,
+                 oclMat &src, oclMat &dst, int ndisp)
+             {
+                 Context  *clCxt = src.clCxt;
+                 int data_type = src.type();
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&src_rows));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&src.step));
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_rows));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_cols));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.step));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&ndisp));
++                String kernelName = "level_up_message";
++                std::vector<std::pair<size_t , const void *> > args;
 -                string kernelName = "one_iteration";
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&src.data));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src_rows));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.step));
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&dst.data));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst_rows));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst_cols));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst.step));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&ndisp));
+                 size_t gt[3] = {dst_cols, dst_rows, 1}, lt[3] = {16, 16, 1};
+                 const char* t_opt  = data_type == CV_16S ? "-D T_SHORT":"-D T_FLOAT";
+                 openCLExecuteKernel(clCxt, &stereobp, kernelName, gt, lt, args, -1, -1, t_opt);
+             }
+             static void level_up_messages_calls(int dst_idx, int dst_cols, int dst_rows, int src_rows,
+                                          oclMat *mus, oclMat *mds, oclMat *mls, oclMat *mrs,
+                                          int ndisp)
+             {
+                 int src_idx = (dst_idx + 1) & 1;
+                 level_up_message_call(dst_cols, dst_rows, src_rows,
+                                       mus[src_idx], mus[dst_idx], ndisp);
+                 level_up_message_call(dst_cols, dst_rows, src_rows,
+                                       mds[src_idx], mds[dst_idx], ndisp);
+                 level_up_message_call(dst_cols, dst_rows, src_rows,
+                                       mls[src_idx], mls[dst_idx], ndisp);
+                 level_up_message_call(dst_cols, dst_rows, src_rows,
+                                       mrs[src_idx], mrs[dst_idx], ndisp);
+             }
+             //////////////////////////////////////////////////////////////////////////////////
+             //////////////////////////////cals_all_iterations_call///////////////////////////
+             /////////////////////////////////////////////////////////////////////////////////
+             static void calc_all_iterations_call(int cols, int rows, oclMat &u, oclMat &d,
+                 oclMat &l, oclMat &r, oclMat &data,
+                 int t, int cndisp, float cmax_disc_term,
+                 float cdisc_single_jump)
+             {
+                 Context  *clCxt = l.clCxt;
+                 int data_type = u.type();
 -                vector<pair<size_t , const void *> > args;
++                String kernelName = "one_iteration";
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&u.data));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&u.step));
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&data.data));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&data.step));
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&d.data));
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&l.data));
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&r.data));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&t));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&cols));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&rows));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&cndisp));
 -                args.push_back( make_pair( sizeof(cl_float) , (void *)&cmax_disc_term));
 -                args.push_back( make_pair( sizeof(cl_float) , (void *)&cdisc_single_jump));
++                std::vector<std::pair<size_t , const void *> > args;
 -                string kernelName = "output";
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&u.data));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&u.step));
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&data.data));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&data.step));
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&d.data));
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&l.data));
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&r.data));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&t));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&cols));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&rows));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&cndisp));
++                args.push_back( std::make_pair( sizeof(cl_float) , (void *)&cmax_disc_term));
++                args.push_back( std::make_pair( sizeof(cl_float) , (void *)&cdisc_single_jump));
+                 size_t gt[3] = {cols, rows, 1}, lt[3] = {16, 16, 1};
+                 const char* t_opt  = data_type == CV_16S ? "-D T_SHORT":"-D T_FLOAT";
+                 openCLExecuteKernel(clCxt, &stereobp, kernelName, gt, lt, args, -1, -1, t_opt);
+             }
+             static void calc_all_iterations_calls(int cols, int rows, int iters, oclMat &u,
+                                            oclMat &d, oclMat &l, oclMat &r,
+                                            oclMat &data, int cndisp, float cmax_disc_term,
+                                            float cdisc_single_jump)
+             {
+                 for(int t = 0; t < iters; ++t)
+                     calc_all_iterations_call(cols, rows, u, d, l, r, data, t, cndisp,
+                                              cmax_disc_term, cdisc_single_jump);
+             }
+             ///////////////////////////////////////////////////////////////////////////////
+             ///////////////////////output///////////////////////////////////////////////////
+             ////////////////////////////////////////////////////////////////////////////////
+             static void output_call(const oclMat &u, const oclMat &d, const oclMat l, const oclMat &r,
+                 const oclMat &data, oclMat &disp, int ndisp)
+             {
+                 Context  *clCxt = u.clCxt;
+                 int data_type = u.type();
 -                vector<pair<size_t , const void *> > args;
++                String kernelName = "output";
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&u.data));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&u.step));
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&d.data));
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&l.data));
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&r.data));
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&data.data));
 -                args.push_back( make_pair( sizeof(cl_mem) , (void *)&disp.data));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&disp.rows));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&disp.cols));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&disp.step));
 -                args.push_back( make_pair( sizeof(cl_int) , (void *)&ndisp));
++                std::vector<std::pair<size_t , const void *> > args;
 -                                    vector<oclMat> &datas_, oclMat &out_)
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&u.data));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&u.step));
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&d.data));
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&l.data));
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&r.data));
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&data.data));
++                args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&disp.data));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&disp.rows));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&disp.cols));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&disp.step));
++                args.push_back( std::make_pair( sizeof(cl_int) , (void *)&ndisp));
+                 size_t gt[3] = {disp.cols, disp.rows, 1}, lt[3] = {16, 16, 1};
+                 const char* t_opt  = data_type == CV_16S ? "-D T_SHORT":"-D T_FLOAT";
+                 openCLExecuteKernel(clCxt, &stereobp, kernelName, gt, lt, args, -1, -1, t_opt);
+             }
+         }
+     }
+ }
+ namespace
+ {
+     const float DEFAULT_MAX_DATA_TERM = 10.0f;
+     const float DEFAULT_DATA_WEIGHT = 0.07f;
+     const float DEFAULT_MAX_DISC_TERM = 1.7f;
+     const float DEFAULT_DISC_SINGLE_JUMP = 1.0f;
+ }
+ void cv::ocl::StereoBeliefPropagation::estimateRecommendedParams(int width, int height, int &ndisp, int &iters, int &levels)
+ {
+     ndisp = width / 4;
+     if ((ndisp & 1) != 0)
+         ndisp++;
+     int mm = ::max(width, height);
+     iters = mm / 100 + 2;
+     levels = (int)(::log(static_cast<double>(mm)) + 1) * 4 / 5;
+     if (levels == 0) levels++;
+ }
+ cv::ocl::StereoBeliefPropagation::StereoBeliefPropagation(int ndisp_, int iters_, int levels_, int msg_type_)
+     : ndisp(ndisp_), iters(iters_), levels(levels_),
+       max_data_term(DEFAULT_MAX_DATA_TERM), data_weight(DEFAULT_DATA_WEIGHT),
+       max_disc_term(DEFAULT_MAX_DISC_TERM), disc_single_jump(DEFAULT_DISC_SINGLE_JUMP),
+       msg_type(msg_type_), datas(levels_)
+ {
+ }
+ cv::ocl::StereoBeliefPropagation::StereoBeliefPropagation(int ndisp_, int iters_, int levels_, float max_data_term_, float data_weight_, float max_disc_term_, float disc_single_jump_, int msg_type_)
+     : ndisp(ndisp_), iters(iters_), levels(levels_),
+       max_data_term(max_data_term_), data_weight(data_weight_),
+       max_disc_term(max_disc_term_), disc_single_jump(disc_single_jump_),
+       msg_type(msg_type_), datas(levels_)
+ {
+ }
+ namespace
+ {
+     class StereoBeliefPropagationImpl
+     {
+     public:
+         StereoBeliefPropagationImpl(StereoBeliefPropagation &rthis_,
+                                     oclMat &u_, oclMat &d_, oclMat &l_, oclMat &r_,
+                                     oclMat &u2_, oclMat &d2_, oclMat &l2_, oclMat &r2_,
 -            CV_Assert(rthis.msg_type == CV_32F || (1 << (rthis.levels - 1)) * scale * rthis.max_data_term < numeric_limits<short>::max());
++                                    std::vector<oclMat> &datas_, oclMat &out_)
+             : rthis(rthis_), u(u_), d(d_), l(l_), r(r_), u2(u2_), d2(d2_), l2(l2_), r2(r2_), datas(datas_), out(out_),
+               zero(Scalar::all(0)), scale(rthis_.msg_type == CV_32F ? 1.0f : 10.0f)
+         {
+             CV_Assert(0 < rthis.ndisp && 0 < rthis.iters && 0 < rthis.levels);
+             CV_Assert(rthis.msg_type == CV_32F || rthis.msg_type == CV_16S);
 -        vector<oclMat> &datas;
++            CV_Assert(rthis.msg_type == CV_32F || (1 << (rthis.levels - 1)) * scale * rthis.max_data_term < std::numeric_limits<short>::max());
+         }
+         void operator()(const oclMat &left, const oclMat &right, oclMat &disp)
+         {
+             CV_Assert(left.size() == right.size() && left.type() == right.type());
+             CV_Assert(left.type() == CV_8UC1 || left.type() == CV_8UC3 || left.type() == CV_8UC4);
+             rows = left.rows;
+             cols = left.cols;
+             int divisor = (int)pow(2.f, rthis.levels - 1.0f);
+             int lowest_cols = cols / divisor;
+             int lowest_rows = rows / divisor;
+             const int min_image_dim_size = 2;
+             CV_Assert(min(lowest_cols, lowest_rows) > min_image_dim_size);
+             init();
+             datas[0].create(rows * rthis.ndisp, cols, rthis.msg_type);
+             datas[0].setTo(Scalar_<short>::all(0));
+             cv::ocl::stereoBP::comp_data_call(left, right, datas[0], rthis.ndisp, rthis.max_data_term, scale * rthis.data_weight);
+             calcBP(disp);
+         }
+         void operator()(const oclMat &data, oclMat &disp)
+         {
+             CV_Assert((data.type() == rthis.msg_type) && (data.rows % rthis.ndisp == 0));
+             rows = data.rows / rthis.ndisp;
+             cols = data.cols;
+             int divisor = (int)pow(2.f, rthis.levels - 1.0f);
+             int lowest_cols = cols / divisor;
+             int lowest_rows = rows / divisor;
+             const int min_image_dim_size = 2;
+             CV_Assert(min(lowest_cols, lowest_rows) > min_image_dim_size);
+             init();
+             datas[0] = data;
+             calcBP(disp);
+         }
+     private:
+         void init()
+         {
+             u.create(rows * rthis.ndisp, cols, rthis.msg_type);
+             d.create(rows * rthis.ndisp, cols, rthis.msg_type);
+             l.create(rows * rthis.ndisp, cols, rthis.msg_type);
+             r.create(rows * rthis.ndisp, cols, rthis.msg_type);
+             if (rthis.levels & 1)
+             {
+                 //can clear less area
+                 u = zero;
+                 d = zero;
+                 l = zero;
+                 r = zero;
+             }
+             if (rthis.levels > 1)
+             {
+                 int less_rows = (rows + 1) / 2;
+                 int less_cols = (cols + 1) / 2;
+                 u2.create(less_rows * rthis.ndisp, less_cols, rthis.msg_type);
+                 d2.create(less_rows * rthis.ndisp, less_cols, rthis.msg_type);
+                 l2.create(less_rows * rthis.ndisp, less_cols, rthis.msg_type);
+                 r2.create(less_rows * rthis.ndisp, less_cols, rthis.msg_type);
+                 if ((rthis.levels & 1) == 0)
+                 {
+                     u2 = zero;
+                     d2 = zero;
+                     l2 = zero;
+                     r2 = zero;
+                 }
+             }
+             cv::ocl::stereoBP::load_constants(rthis.ndisp, rthis.max_data_term, scale * rthis.data_weight,
+                                               scale * rthis.max_disc_term, scale * rthis.disc_single_jump);
+             datas.resize(rthis.levels);
+             cols_all.resize(rthis.levels);
+             rows_all.resize(rthis.levels);
+             cols_all[0] = cols;
+             rows_all[0] = rows;
+         }
+         void calcBP(oclMat &disp)
+         {
+             using namespace cv::ocl::stereoBP;
+             for (int i = 1; i < rthis.levels; ++i)
+             {
+                 cols_all[i] = (cols_all[i - 1] + 1) / 2;
+                 rows_all[i] = (rows_all[i - 1] + 1) / 2;
+                 datas[i].create(rows_all[i] * rthis.ndisp, cols_all[i], rthis.msg_type);
+                 datas[i].setTo(Scalar_<short>::all(0));
+                 data_step_down_call(cols_all[i], rows_all[i], rows_all[i - 1],
+                                     datas[i - 1], datas[i], rthis.ndisp);
+             }
+             oclMat mus[] = {u, u2};
+             oclMat mds[] = {d, d2};
+             oclMat mrs[] = {r, r2};
+             oclMat mls[] = {l, l2};
+             int mem_idx = (rthis.levels & 1) ? 0 : 1;
+             for (int i = rthis.levels - 1; i >= 0; --i)
+             {
+                 // for lower level we have already computed messages by setting to zero
+                 if (i != rthis.levels - 1)
+                     level_up_messages_calls(mem_idx, cols_all[i], rows_all[i], rows_all[i + 1],
+                                             mus, mds, mls, mrs, rthis.ndisp);
+                 calc_all_iterations_calls(cols_all[i], rows_all[i], rthis.iters, mus[mem_idx],
+                                           mds[mem_idx], mls[mem_idx], mrs[mem_idx], datas[i],
+                                           rthis.ndisp, scale * rthis.max_disc_term,
+                                           scale * rthis.disc_single_jump);
+                 mem_idx = (mem_idx + 1) & 1;
+             }
+             if (disp.empty())
+                 disp.create(rows, cols, CV_16S);
+             out = ((disp.type() == CV_16S) ? disp : (out.create(rows, cols, CV_16S), out));
+             out = zero;
+             output_call(u, d, l, r, datas.front(), out, rthis.ndisp);
+             if (disp.type() != CV_16S)
+                 out.convertTo(disp, disp.type());
+             release_constants();
+         }
+         StereoBeliefPropagationImpl& operator=(const StereoBeliefPropagationImpl&);
+         StereoBeliefPropagation &rthis;
+         oclMat &u;
+         oclMat &d;
+         oclMat &l;
+         oclMat &r;
+         oclMat &u2;
+         oclMat &d2;
+         oclMat &l2;
+         oclMat &r2;
 -        vector<int> cols_all, rows_all;
++        std::vector<oclMat> &datas;
+         oclMat &out;
+         const Scalar zero;
+         const float scale;
+         int rows, cols;
 -
++        std::vector<int> cols_all, rows_all;
+     };
+ }
+ void cv::ocl::StereoBeliefPropagation::operator()(const oclMat &left, const oclMat &right, oclMat &disp)
+ {
+     ::StereoBeliefPropagationImpl impl(*this, u, d, l, r, u2, d2, l2, r2, datas, out);
+     impl(left, right, disp);
+ }
+ void cv::ocl::StereoBeliefPropagation::operator()(const oclMat &data, oclMat &disp)
+ {
+     ::StereoBeliefPropagationImpl impl(*this, u, d, l, r, u2, d2, l2, r2, datas, out);
+     impl(data, disp);
+ }
@@@ -63,15 -63,15 +63,15 @@@ PARAM_TEST_CASE(StereoMatchBM, int, int
      }
  };
  
- TEST_P(StereoMatchBM, Accuracy)
        {
+ TEST_P(StereoMatchBM, Regression)
+ {
  
-     Mat left_image  = readImage(workdir + "../ocl/aloe-L.png", IMREAD_GRAYSCALE);
-     Mat right_image = readImage(workdir + "../ocl/aloe-R.png", IMREAD_GRAYSCALE);
-     Mat disp_gold   = readImage(workdir + "../ocl/aloe-disp.png", IMREAD_GRAYSCALE);
+     Mat left_image  = readImage("stereobm/aloe-L.png", IMREAD_GRAYSCALE);
+     Mat right_image = readImage("stereobm/aloe-R.png", IMREAD_GRAYSCALE);
+     Mat disp_gold   = readImage("stereobm/aloe-disp.png", IMREAD_GRAYSCALE);
 -      ocl::oclMat d_left, d_right;
 -      ocl::oclMat d_disp(left_image.size(), CV_8U);
 -      Mat  disp;
 +    ocl::oclMat d_left, d_right;
 +    ocl::oclMat d_disp(left_image.size(), CV_8U);
 +    Mat  disp;
  
      ASSERT_FALSE(left_image.empty());
      ASSERT_FALSE(right_image.empty());
      EXPECT_MAT_SIMILAR(disp_gold, disp, 1e-3);
  }
  
- INSTANTIATE_TEST_CASE_P(GPU_Calib3D, StereoMatchBM, testing::Combine(testing::Values(128),
+ INSTANTIATE_TEST_CASE_P(OCL_Calib3D, StereoMatchBM, testing::Combine(testing::Values(128),
 -                                         testing::Values(19)));
 +                                       testing::Values(19)));
  
+ PARAM_TEST_CASE(StereoMatchBP, int, int, int, float, float, float, float)
+ {
+     int ndisp_;
+     int iters_;
+     int levels_;
+     float max_data_term_;
+     float data_weight_;
+     float max_disc_term_;
+     float disc_single_jump_;
+     virtual void SetUp()
+     {
+         ndisp_          = GET_PARAM(0);
+         iters_          = GET_PARAM(1);
+         levels_         = GET_PARAM(2);
+         max_data_term_  = GET_PARAM(3);
+         data_weight_    = GET_PARAM(4);
+         max_disc_term_     = GET_PARAM(5);
+         disc_single_jump_  = GET_PARAM(6);
+     }
+ };
+ TEST_P(StereoMatchBP, Regression)
+ {
+     Mat left_image  = readImage("stereobp/aloe-L.png");
+     Mat right_image = readImage("stereobp/aloe-R.png");
+     Mat disp_gold   = readImage("stereobp/aloe-disp.png", IMREAD_GRAYSCALE);
+     ocl::oclMat d_left, d_right;
+     ocl::oclMat d_disp;
+     Mat  disp;
+     ASSERT_FALSE(left_image.empty());
+     ASSERT_FALSE(right_image.empty());
+     ASSERT_FALSE(disp_gold.empty());
+     d_left.upload(left_image);
+     d_right.upload(right_image);
+     ocl::StereoBeliefPropagation bp(ndisp_, iters_, levels_, max_data_term_, data_weight_,
+         max_disc_term_, disc_single_jump_, CV_16S);
+     bp(d_left, d_right, d_disp);
+     d_disp.download(disp);
+     disp.convertTo(disp, disp_gold.depth());
+     EXPECT_MAT_NEAR(disp_gold, disp, 0.0, "");
+ }
+ INSTANTIATE_TEST_CASE_P(OCL_Calib3D, StereoMatchBP, testing::Combine(testing::Values(64),
+     testing::Values(8),testing::Values(2),testing::Values(25.0f),
+     testing::Values(0.1f),testing::Values(15.0f),testing::Values(1.0f)));
  #endif // HAVE_OPENCL
Simple merge
@@@ -347,9 -348,16 +347,16 @@@ SurfFeaturesFinder::SurfFeaturesFinder(
  void SurfFeaturesFinder::find(const Mat &image, ImageFeatures &features)
  {
      Mat gray_image;
-     CV_Assert(image.type() == CV_8UC3);
-     cvtColor(image, gray_image, CV_BGR2GRAY);
+     CV_Assert((image.type() == CV_8UC3) || (image.type() == CV_8UC1));
+     if(image.type() == CV_8UC3)
+     {
+         cvtColor(image, gray_image, CV_BGR2GRAY);
+     }
+     else
+     {
+         gray_image = image;
+     }
 -    if (surf == 0)
 +    if (surf.empty())
      {
          detector_->detect(gray_image, features.keypoints);
          extractor_->compute(gray_image, features.keypoints, features.descriptors);
Simple merge
Simple merge
@@@ -47,9 -46,8 +47,8 @@@ static Ptr<DenseOpticalFlowExt> createO
      else
      {
          cerr << "Incorrect Optical Flow algorithm - " << name << endl;
 -        exit(-1);
      }
-     return Ptr<DenseOpticalFlowExt>();
++    return 0;
  }
  
  int main(int argc, const char* argv[])
index 0000000,32a91e3..9aac53a
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,100 +1,100 @@@
 -        the image center. Swaps quadrant 1 with 3, and 2 with 4. 
 -       
+ #/usr/bin/env python
+ import cv2
+ import numpy as np
+ import sys
+ def shift_dft(src, dst=None):
+     '''
+         Rearrange the quadrants of Fourier image so that the origin is at
 -    
++        the image center. Swaps quadrant 1 with 3, and 2 with 4.
++
+         src and dst arrays must be equal size & type
+     '''
 -    
++
+     if dst is None:
+         dst = np.empty(src.shape, src.dtype)
+     elif src.shape != dst.shape:
+         raise ValueError("src and dst must have equal sizes")
+     elif src.dtype != dst.dtype:
+         raise TypeError("src and dst must have equal types")
 -    
++
+     if src is dst:
+         ret = np.empty(src.shape, src.dtype)
+     else:
+         ret = dst
 -    
++
+     h, w = src.shape[:2]
 -    
++
+     cx1 = cx2 = w/2
+     cy1 = cy2 = h/2
 -        cy2 += 1 
 -        
++
+     # if the size is odd, then adjust the bottom/right quadrants
+     if w % 2 != 0:
+         cx2 += 1
+     if h % 2 != 0:
 -    
++        cy2 += 1
++
+     # swap quadrants
 -    
++
+     # swap q1 and q3
+     ret[h-cy1:, w-cx1:] = src[0:cy1 , 0:cx1 ]   # q1 -> q3
+     ret[0:cy2 , 0:cx2 ] = src[h-cy2:, w-cx2:]   # q3 -> q1
 -    
++
+     # swap q2 and q4
+     ret[0:cy2 , w-cx2:] = src[h-cy2:, 0:cx2 ]   # q2 -> q4
+     ret[h-cy1:, 0:cx1 ] = src[0:cy1 , w-cx1:]   # q4 -> q2
 -    
++
+     if src is dst:
+         dst[:,:] = ret
 -        
++
+     return dst
+ if __name__ == "__main__":
 -    
++
+     if len(sys.argv)>1:
+         im = cv2.imread(sys.argv[1])
+     else :
+         im = cv2.imread('../c/baboon.jpg')
+         print "usage : python dft.py <image_file>"
+     # convert to grayscale
+     im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
+     h, w = im.shape[:2]
 -    
++
+     realInput = im.astype(np.float64)
 -    
++
+     # perform an optimally sized dft
+     dft_M = cv2.getOptimalDFTSize(w)
+     dft_N = cv2.getOptimalDFTSize(h)
+     # copy A to dft_A and pad dft_A with zeros
+     dft_A = np.zeros((dft_N, dft_M, 2), dtype=np.float64)
+     dft_A[:h, :w, 0] = realInput
 -    
++
+     # no need to pad bottom part of dft_A with zeros because of
+     # use of nonzeroRows parameter in cv2.dft()
+     cv2.dft(dft_A, dst=dft_A, nonzeroRows=h)
 -    
++
+     cv2.imshow("win", im)
 -    
++
+     # Split fourier into real and imaginary parts
+     image_Re, image_Im = cv2.split(dft_A)
 -    
++
+     # Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2)
+     magnitude = cv2.sqrt(image_Re**2.0 + image_Im**2.0)
 -    
++
+     # Compute log(1 + Mag)
+     log_spectrum = cv2.log(1.0 + magnitude)
++
+     # Rearrange the quadrants of Fourier image so that the origin is at
+     # the image center
+     shift_dft(log_spectrum, log_spectrum)
+     # normalize and display the results as rgb
+     cv2.normalize(log_spectrum, log_spectrum, 0.0, 1.0, cv2.cv.CV_MINMAX)
+     cv2.imshow("magnitude", log_spectrum)
+     cv2.waitKey(0)
+     cv2.destroyAllWindows()