Merge remote-tracking branch 'origin/2.4' into merge-2.4
authorRoman Donchenko <roman.donchenko@itseez.com>
Mon, 15 Jul 2013 14:40:54 +0000 (18:40 +0400)
committerRoman Donchenko <roman.donchenko@itseez.com>
Tue, 16 Jul 2013 07:52:41 +0000 (11:52 +0400)
Conflicts:
modules/core/include/opencv2/core/version.hpp
modules/ocl/include/opencv2/ocl/ocl.hpp
modules/ocl/src/initialization.cpp
modules/ocl/test/main.cpp
modules/superres/CMakeLists.txt
modules/superres/src/input_array_utility.cpp
modules/superres/src/input_array_utility.hpp
modules/superres/src/optical_flow.cpp

24 files changed:
1  2 
modules/core/doc/xml_yaml_persistence.rst
modules/features2d/src/brisk.cpp
modules/highgui/src/cap.cpp
modules/imgproc/src/templmatch.cpp
modules/ocl/include/opencv2/ocl.hpp
modules/ocl/src/gftt.cpp
modules/ocl/src/initialization.cpp
modules/ocl/src/kmeans.cpp
modules/ocl/test/main.cpp
modules/ocl/test/test_kmeans.cpp
modules/ocl/test/test_moments.cpp
modules/ocl/test/test_objdetect.cpp
modules/superres/CMakeLists.txt
modules/superres/include/opencv2/superres.hpp
modules/superres/include/opencv2/superres/optical_flow.hpp
modules/superres/perf/perf_superres_ocl.cpp
modules/superres/src/btv_l1_ocl.cpp
modules/superres/src/frame_source.cpp
modules/superres/src/input_array_utility.cpp
modules/superres/src/input_array_utility.hpp
modules/superres/src/optical_flow.cpp
modules/superres/src/precomp.hpp
modules/superres/test/test_superres.cpp
modules/ts/include/opencv2/ts.hpp

Simple merge
Simple merge
Simple merge
index 3da9352,0000000..a8ebcba
mode 100644,000000..100644
--- /dev/null
@@@ -1,1819 -1,0 +1,1832 @@@
 +/*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;
 +            String PlatformName;
 +        };
 +        //////////////////////////////// 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);
 +
 +        //The two functions below enable other opencl program to use ocl module's cl_context and cl_command_queue
 +        //returns cl_context *
 +        CV_EXPORTS void* getoclContext();
 +        //returns cl_command_queue *
 +        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);
 +
 +        //returns true when global OpenCL context is initialized
 +        CV_EXPORTS bool initialized();
 +
 +        //////////////////////////////// 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>;
 +            friend bool initialized();
 +        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, CL_VER_1_2};
 +            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);
 +
 +        //! Enable or disable OpenCL program binary caching onto local disk
 +        // After a program (*.cl files in opencl/ folder) is built at runtime, we allow the
 +        // compiled OpenCL program to be cached to the path automatically as "path/*.clb"
 +        // binary file, which will be reused when the OpenCV executable is started again.
 +        //
 +        // Caching mode is controlled by the following enums
 +        // Notes
 +        //   1. the feature is by default enabled when OpenCV is built in release mode.
 +        //   2. the CACHE_DEBUG / CACHE_RELEASE flags only effectively work with MSVC compiler;
 +        //      for GNU compilers, the function always treats the build as release mode (enabled by default).
 +        enum
 +        {
 +            CACHE_NONE    = 0,        // do not cache OpenCL binary
 +            CACHE_DEBUG   = 0x1 << 0, // cache OpenCL binary when built in debug mode (only work with MSVC)
 +            CACHE_RELEASE = 0x1 << 1, // default behavior, only cache when built in release mode (only work with MSVC)
 +            CACHE_ALL     = CACHE_DEBUG | CACHE_RELEASE, // always cache opencl binary
 +            CACHE_UPDATE  = 0x1 << 2  // if the binary cache file with the same name is already on the disk, it will be updated.
 +        };
 +        CV_EXPORTS void setBinaryDiskCache(int mode = CACHE_RELEASE, cv::String path = "./");
 +
 +        //! set where binary cache to be saved to
 +        CV_EXPORTS void setBinpath(const char *path);
 +
 +        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;
 +
 +            //! convert to _InputArray
 +            operator _InputArray();
 +
 +            //! convert to _OutputArray
 +            operator _OutputArray();
 +
 +            //! 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* hptr = 0);
 +            void createEx(Size size, int type, DevMemRW rw_type,
 +                          DevMemType mem_type, void* hptr = 0);
 +
 +            //! 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;
 +        };
 +
 +        // convert InputArray/OutputArray to oclMat references
 +        CV_EXPORTS oclMat& getOclMatRef(InputArray src);
 +        CV_EXPORTS oclMat& getOclMatRef(OutputArray src);
 +
 +        ///////////////////// 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);
 +        //! multiplies matrix to a number (dst = scalar * src)
 +        // supports CV_32FC1 only
 +        CV_EXPORTS void multiply(double scalar, const oclMat &src, oclMat &dst);
 +        //! 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());
 +        CV_EXPORTS void minMax_buf(const oclMat &src, double *minVal, double *maxVal, const oclMat &mask, oclMat& buf);
 +
 +        //! 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);
 +
 +        //! only 8UC1 is supported now
 +        CV_EXPORTS Ptr<cv::CLAHE> createCLAHE(double clipLimit = 40.0, Size tileGridSize = Size(8, 8));
 +
 +        //! 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);
 +
 +        struct CV_EXPORTS ConvolveBuf
 +        {
 +            Size result_size;
 +            Size block_size;
 +            Size user_block_size;
 +            Size dft_size;
 +
 +            oclMat image_spect, templ_spect, result_spect;
 +            oclMat image_block, templ_block, result_data;
 +
 +            void create(Size image_size, Size templ_size);
 +            static Size estimateBlockSize(Size result_size, Size templ_size);
 +        };
 +
 +        //! computes convolution of two images, may use discrete Fourier transform
 +        //! support only CV_32FC1 type
 +        CV_EXPORTS void convolve(const oclMat &image, const oclMat &temp1, oclMat &result, bool ccorr = false);
 +        CV_EXPORTS void convolve(const oclMat &image, const oclMat &temp1, oclMat &result, bool ccorr, ConvolveBuf& buf);
 +
 +        //! Performs a per-element multiplication of two Fourier spectrums.
 +        //! Only full (not packed) CV_32FC2 complex spectrums in the interleaved format are supported for now.
 +        //! support only CV_32FC2 type
 +        CV_EXPORTS void mulSpectrums(const oclMat &a, const oclMat &b, oclMat &c, int flags, float scale, bool conjB = false);
 +
 +        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
 +        //  Note, at the moment this function only works when anchor point is in the kernel center
 +        //  and kernel size supported is either 3x3 or 5x5; otherwise the function will fail to output valid result
 +        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 cornerHarris_dxdy(const oclMat &src, oclMat &dst, oclMat &Dx, oclMat &Dy,
 +            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);
 +        CV_EXPORTS void cornerMinEigenVal_dxdy(const oclMat &src, oclMat &dst, oclMat &Dx, oclMat &Dy,
 +            int blockSize, int ksize, int bordertype = cv::BORDER_DEFAULT);
 +
++
++        /////////////////////////////////// ML ///////////////////////////////////////////
++
++        //! Compute closest centers for each lines in source and lable it after center's index
++        // supports CV_32FC1/CV_32FC2/CV_32FC4 data type
++        CV_EXPORTS void distanceToCenters(oclMat &dists, oclMat &labels, const oclMat &src, const oclMat &centers);
++
++        //!Does k-means procedure on GPU
++        // supports CV_32FC1/CV_32FC2/CV_32FC4 data type
++        CV_EXPORTS double kmeans(const oclMat &src, int K, oclMat &bestLabels,
++                                     TermCriteria criteria, int attemps, int flags, oclMat &centers);
++
++
 +        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 +        ///////////////////////////////////////////CascadeClassifier//////////////////////////////////////////////////////////////////
 +        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 +
 +#if 0
 +        class CV_EXPORTS 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));
 +        };
 +#endif
 +
 +#if 0
 +        class CV_EXPORTS OclCascadeClassifierBuf : public  cv::CascadeClassifier
 +        {
 +        public:
 +            OclCascadeClassifierBuf() :
 +                m_flags(0), initialized(false), m_scaleFactor(0), buffers(NULL) {}
 +
 +            ~OclCascadeClassifierBuf() { release(); }
 +
 +            void detectMultiScale(oclMat &image, CV_OUT std::vector<cv::Rect>& faces,
 +                                  double scaleFactor = 1.1, int minNeighbors = 3, int flags = 0,
 +                                  Size minSize = Size(), Size maxSize = Size());
 +            void release();
 +
 +        private:
 +            void Init(const int rows, const int cols, double scaleFactor, int flags,
 +                      const int outputsz, const size_t localThreads[],
 +                      Size minSize, Size maxSize);
 +            void CreateBaseBufs(const int datasize, const int totalclassifier, const int flags, const int outputsz);
 +            void CreateFactorRelatedBufs(const int rows, const int cols, const int flags,
 +                                         const double scaleFactor, const size_t localThreads[],
 +                                         Size minSize, Size maxSize);
 +            void GenResult(CV_OUT std::vector<cv::Rect>& faces, const std::vector<cv::Rect> &rectList, const std::vector<int> &rweights);
 +
 +            int m_rows;
 +            int m_cols;
 +            int m_flags;
 +            int m_loopcount;
 +            int m_nodenum;
 +            bool findBiggestObject;
 +            bool initialized;
 +            double m_scaleFactor;
 +            Size m_minSize;
 +            Size m_maxSize;
 +            std::vector<Size> sizev;
 +            std::vector<float> scalev;
 +            oclMat gimg1, gsum, gsqsum;
 +            void * buffers;
 +        };
 +#endif
 +
 +        /////////////////////////////// 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 magBuf, mapBuf;
 +            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) {}
 +        };
 +
 +        class CV_EXPORTS BFMatcher_OCL : public BruteForceMatcher_OCL_base
 +        {
 +        public:
 +            explicit BFMatcher_OCL(int norm = NORM_L2) : BruteForceMatcher_OCL_base(norm == NORM_L1 ? L1Dist : norm == NORM_L2 ? L2Dist : HammingDist) {}
 +        };
 +
 +        class CV_EXPORTS GoodFeaturesToTrackDetector_OCL
 +        {
 +        public:
 +            explicit GoodFeaturesToTrackDetector_OCL(int maxCorners = 1000, double qualityLevel = 0.01, double minDistance = 0.0,
 +                int blockSize = 3, bool useHarrisDetector = false, double harrisK = 0.04);
 +
 +            //! return 1 rows matrix with CV_32FC2 type
 +            void operator ()(const oclMat& image, oclMat& corners, const oclMat& mask = oclMat());
 +            //! download points of type Point2f to a vector. the vector's content will be erased
 +            void downloadPoints(const oclMat &points, std::vector<Point2f> &points_v);
 +
 +            int maxCorners;
 +            double qualityLevel;
 +            double minDistance;
 +
 +            int blockSize;
 +            bool useHarrisDetector;
 +            double harrisK;
 +            void releaseMemory()
 +            {
 +                Dx_.release();
 +                Dy_.release();
 +                eig_.release();
 +                minMaxbuf_.release();
 +                tmpCorners_.release();
 +            }
 +        private:
 +            oclMat Dx_;
 +            oclMat Dy_;
 +            oclMat eig_;
 +            oclMat minMaxbuf_;
 +            oclMat tmpCorners_;
 +        };
 +
 +        inline GoodFeaturesToTrackDetector_OCL::GoodFeaturesToTrackDetector_OCL(int maxCorners_, double qualityLevel_, double minDistance_,
 +            int blockSize_, bool useHarrisDetector_, double harrisK_)
 +        {
 +            maxCorners = maxCorners_;
 +            qualityLevel = qualityLevel_;
 +            minDistance = minDistance_;
 +            blockSize = blockSize_;
 +            useHarrisDetector = useHarrisDetector_;
 +            harrisK = harrisK_;
 +        }
 +
 +        /////////////////////////////// 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_;
 +        };
 +
 +        class CV_EXPORTS FarnebackOpticalFlow
 +        {
 +        public:
 +            FarnebackOpticalFlow();
 +
 +            int numLevels;
 +            double pyrScale;
 +            bool fastPyramids;
 +            int winSize;
 +            int numIters;
 +            int polyN;
 +            double polySigma;
 +            int flags;
 +
 +            void operator ()(const oclMat &frame0, const oclMat &frame1, oclMat &flowx, oclMat &flowy);
 +
 +            void releaseMemory();
 +
 +        private:
 +            void prepareGaussian(
 +                int n, double sigma, float *g, float *xg, float *xxg,
 +                double &ig11, double &ig03, double &ig33, double &ig55);
 +
 +            void setPolynomialExpansionConsts(int n, double sigma);
 +
 +            void updateFlow_boxFilter(
 +                const oclMat& R0, const oclMat& R1, oclMat& flowx, oclMat &flowy,
 +                oclMat& M, oclMat &bufM, int blockSize, bool updateMatrices);
 +
 +            void updateFlow_gaussianBlur(
 +                const oclMat& R0, const oclMat& R1, oclMat& flowx, oclMat& flowy,
 +                oclMat& M, oclMat &bufM, int blockSize, bool updateMatrices);
 +
 +            oclMat frames_[2];
 +            oclMat pyrLevel_[2], M_, bufM_, R_[2], blurredFrame_[2];
 +            std::vector<oclMat> pyramid0_, pyramid1_;
 +        };
 +
 +        //////////////// 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;
 +        };
 +
 +        class CV_EXPORTS StereoConstantSpaceBP
 +        {
 +        public:
 +            enum { DEFAULT_NDISP    = 128 };
 +            enum { DEFAULT_ITERS    = 8   };
 +            enum { DEFAULT_LEVELS   = 4   };
 +            enum { DEFAULT_NR_PLANE = 4   };
 +            static void estimateRecommendedParams(int width, int height, int &ndisp, int &iters, int &levels, int &nr_plane);
 +            explicit StereoConstantSpaceBP(
 +                int ndisp    = DEFAULT_NDISP,
 +                int iters    = DEFAULT_ITERS,
 +                int levels   = DEFAULT_LEVELS,
 +                int nr_plane = DEFAULT_NR_PLANE,
 +                int msg_type = CV_32F);
 +            StereoConstantSpaceBP(int ndisp, int iters, int levels, int nr_plane,
 +                float max_data_term, float data_weight, float max_disc_term, float disc_single_jump,
 +                int min_disp_th = 0,
 +                int msg_type = CV_32F);
 +            void operator()(const oclMat &left, const oclMat &right, oclMat &disparity);
 +            int ndisp;
 +            int iters;
 +            int levels;
 +            int nr_plane;
 +            float max_data_term;
 +            float data_weight;
 +            float max_disc_term;
 +            float disc_single_jump;
 +            int min_disp_th;
 +            int msg_type;
 +            bool use_local_init_data_cost;
 +        private:
 +            oclMat u[2], d[2], l[2], r[2];
 +            oclMat disp_selected_pyr[2];
 +            oclMat data_cost;
 +            oclMat data_cost_selected;
 +            oclMat temp;
 +            oclMat out;
 +        };
 +
 +        // Implementation of the Zach, Pock and Bischof Dual TV-L1 Optical Flow method
 +        //
 +        // see reference:
 +        //   [1] C. Zach, T. Pock and H. Bischof, "A Duality Based Approach for Realtime TV-L1 Optical Flow".
 +        //   [2] Javier Sanchez, Enric Meinhardt-Llopis and Gabriele Facciolo. "TV-L1 Optical Flow Estimation".
 +        class CV_EXPORTS OpticalFlowDual_TVL1_OCL
 +        {
 +        public:
 +            OpticalFlowDual_TVL1_OCL();
 +
 +            void operator ()(const oclMat& I0, const oclMat& I1, oclMat& flowx, oclMat& flowy);
 +
 +            void collectGarbage();
 +
 +            /**
 +            * Time step of the numerical scheme.
 +            */
 +            double tau;
 +
 +            /**
 +            * Weight parameter for the data term, attachment parameter.
 +            * This is the most relevant parameter, which determines the smoothness of the output.
 +            * The smaller this parameter is, the smoother the solutions we obtain.
 +            * It depends on the range of motions of the images, so its value should be adapted to each image sequence.
 +            */
 +            double lambda;
 +
 +            /**
 +            * Weight parameter for (u - v)^2, tightness parameter.
 +            * It serves as a link between the attachment and the regularization terms.
 +            * In theory, it should have a small value in order to maintain both parts in correspondence.
 +            * The method is stable for a large range of values of this parameter.
 +            */
 +            double theta;
 +
 +            /**
 +            * Number of scales used to create the pyramid of images.
 +            */
 +            int nscales;
 +
 +            /**
 +            * Number of warpings per scale.
 +            * Represents the number of times that I1(x+u0) and grad( I1(x+u0) ) are computed per scale.
 +            * This is a parameter that assures the stability of the method.
 +            * It also affects the running time, so it is a compromise between speed and accuracy.
 +            */
 +            int warps;
 +
 +            /**
 +            * Stopping criterion threshold used in the numerical scheme, which is a trade-off between precision and running time.
 +            * A small value will yield more accurate solutions at the expense of a slower convergence.
 +            */
 +            double epsilon;
 +
 +            /**
 +            * Stopping criterion iterations number used in the numerical scheme.
 +            */
 +            int iterations;
 +
 +            bool useInitialFlow;
 +
 +        private:
 +            void procOneScale(const oclMat& I0, const oclMat& I1, oclMat& u1, oclMat& u2);
 +
 +            std::vector<oclMat> I0s;
 +            std::vector<oclMat> I1s;
 +            std::vector<oclMat> u1s;
 +            std::vector<oclMat> u2s;
 +
 +            oclMat I1x_buf;
 +            oclMat I1y_buf;
 +
 +            oclMat I1w_buf;
 +            oclMat I1wx_buf;
 +            oclMat I1wy_buf;
 +
 +            oclMat grad_buf;
 +            oclMat rho_c_buf;
 +
 +            oclMat p11_buf;
 +            oclMat p12_buf;
 +            oclMat p21_buf;
 +            oclMat p22_buf;
 +
 +            oclMat diff_buf;
 +            oclMat norm_buf;
 +        };
 +    }
 +}
 +#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__ */
Simple merge
Simple merge
index 0000000,22f8660..ce5ecbc
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,438 +1,438 @@@
 -static void generateRandomCenter(const vector<Vec2f>& box, float* center, RNG& rng)
+ /*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, Advanced Micro Devices, Inc., all rights reserved.
+ // Third party copyrights are property of their respective owners.
+ //
+ // @Authors
+ //     Xiaopeng Fu, fuxiaopeng2222@163.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 <iomanip>
+ #include "precomp.hpp"
+ using namespace cv;
+ using namespace ocl;
+ namespace cv
+ {
+ namespace ocl
+ {
+ ////////////////////////////////////OpenCL kernel strings//////////////////////////
+ extern const char *kmeans_kernel;
+ }
+ }
 -    vector<int> _centers(K);
++static void generateRandomCenter(const std::vector<Vec2f>& box, float* center, RNG& rng)
+ {
+     size_t j, dims = box.size();
+     float margin = 1.f/dims;
+     for( j = 0; j < dims; j++ )
+         center[j] = ((float)rng*(1.f+margin*2.f)-margin)*(box[j][1] - box[j][0]) + box[j][0];
+ }
+ // This class is copied from matrix.cpp in core module.
+ class KMeansPPDistanceComputer : public ParallelLoopBody
+ {
+ public:
+     KMeansPPDistanceComputer( float *_tdist2,
+                               const float *_data,
+                               const float *_dist,
+                               int _dims,
+                               size_t _step,
+                               size_t _stepci )
+         : tdist2(_tdist2),
+           data(_data),
+           dist(_dist),
+           dims(_dims),
+           step(_step),
+           stepci(_stepci) { }
+     void operator()( const cv::Range& range ) const
+     {
+         const int begin = range.start;
+         const int end = range.end;
+         for ( int i = begin; i<end; i++ )
+         {
+             tdist2[i] = std::min(normL2Sqr_(data + step*i, data + stepci, dims), dist[i]);
+         }
+     }
+ private:
+     KMeansPPDistanceComputer& operator=(const KMeansPPDistanceComputer&); // to quiet MSVC
+     float *tdist2;
+     const float *data;
+     const float *dist;
+     const int dims;
+     const size_t step;
+     const size_t stepci;
+ };
+ /*
+ k-means center initialization using the following algorithm:
+ Arthur & Vassilvitskii (2007) k-means++: The Advantages of Careful Seeding
+ */
+ static void generateCentersPP(const Mat& _data, Mat& _out_centers,
+                               int K, RNG& rng, int trials)
+ {
+     int i, j, k, dims = _data.cols, N = _data.rows;
+     const float* data = (float*)_data.data;
+     size_t step = _data.step/sizeof(data[0]);
 -    vector<float> _dist(N*3);
++    std::vector<int> _centers(K);
+     int* centers = &_centers[0];
 -    string kernelname = "distanceToCenters";
++    std::vector<float> _dist(N*3);
+     float* dist = &_dist[0], *tdist = dist + N, *tdist2 = tdist + N;
+     double sum0 = 0;
+     centers[0] = (unsigned)rng % N;
+     for( i = 0; i < N; i++ )
+     {
+         dist[i] = normL2Sqr_(data + step*i, data + step*centers[0], dims);
+         sum0 += dist[i];
+     }
+     for( k = 1; k < K; k++ )
+     {
+         double bestSum = DBL_MAX;
+         int bestCenter = -1;
+         for( j = 0; j < trials; j++ )
+         {
+             double p = (double)rng*sum0, s = 0;
+             for( i = 0; i < N-1; i++ )
+                 if( (p -= dist[i]) <= 0 )
+                     break;
+             int ci = i;
+             parallel_for_(Range(0, N),
+                           KMeansPPDistanceComputer(tdist2, data, dist, dims, step, step*ci));
+             for( i = 0; i < N; i++ )
+             {
+                 s += tdist2[i];
+             }
+             if( s < bestSum )
+             {
+                 bestSum = s;
+                 bestCenter = ci;
+                 std::swap(tdist, tdist2);
+             }
+         }
+         centers[k] = bestCenter;
+         sum0 = bestSum;
+         std::swap(dist, tdist);
+     }
+     for( k = 0; k < K; k++ )
+     {
+         const float* src = data + step*centers[k];
+         float* dst = _out_centers.ptr<float>(k);
+         for( j = 0; j < dims; j++ )
+             dst[j] = src[j];
+     }
+ }
+ void cv::ocl::distanceToCenters(oclMat &dists, oclMat &labels, const oclMat &src, const oclMat &centers)
+ {
+     //if(src.clCxt -> impl -> double_support == 0 && src.type() == CV_64F)
+     //{
+     //    CV_Error(CV_GpuNotSupported, "Selected device don't support double\r\n");
+     //    return;
+     //}
+     Context  *clCxt = src.clCxt;
+     int labels_step = (int)(labels.step/labels.elemSize());
 -    vector<pair<size_t, const void *> > args;
 -    args.push_back(make_pair(sizeof(cl_int), (void *)&labels_step));
 -    args.push_back(make_pair(sizeof(cl_int), (void *)&centers.rows));
 -    args.push_back(make_pair(sizeof(cl_mem), (void *)&src.data));
 -    args.push_back(make_pair(sizeof(cl_mem), (void *)&labels.data));
 -    args.push_back(make_pair(sizeof(cl_int), (void *)&centers.cols));
 -    args.push_back(make_pair(sizeof(cl_int), (void *)&src.rows));
 -    args.push_back(make_pair(sizeof(cl_mem), (void *)&centers.data));
 -    args.push_back(make_pair(sizeof(cl_mem), (void*)&dists.data));
++    String kernelname = "distanceToCenters";
+     int threadNum = src.rows > 256 ? 256 : src.rows;
+     size_t localThreads[3]  = {1, threadNum, 1};
+     size_t globalThreads[3] = {1, src.rows, 1};
 -    if( flags & CV_KMEANS_USE_INITIAL_LABELS )
++    std::vector<std::pair<size_t, const void *> > args;
++    args.push_back(std::make_pair(sizeof(cl_int), (void *)&labels_step));
++    args.push_back(std::make_pair(sizeof(cl_int), (void *)&centers.rows));
++    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&src.data));
++    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&labels.data));
++    args.push_back(std::make_pair(sizeof(cl_int), (void *)&centers.cols));
++    args.push_back(std::make_pair(sizeof(cl_int), (void *)&src.rows));
++    args.push_back(std::make_pair(sizeof(cl_mem), (void *)&centers.data));
++    args.push_back(std::make_pair(sizeof(cl_mem), (void*)&dists.data));
+     openCLExecuteKernel(clCxt, &kmeans_kernel, kernelname, globalThreads, localThreads, args, -1, -1, NULL);
+ }
+ ///////////////////////////////////k - means /////////////////////////////////////////////////////////
+ double cv::ocl::kmeans(const oclMat &_src, int K, oclMat &_bestLabels,
+                        TermCriteria criteria, int attempts, int flags, oclMat &_centers)
+ {
+     const int SPP_TRIALS = 3;
+     bool isrow = _src.rows == 1 && _src.oclchannels() > 1;
+     int N = !isrow ? _src.rows : _src.cols;
+     int dims = (!isrow ? _src.cols : 1) * _src.oclchannels();
+     int type = _src.depth();
+     attempts = std::max(attempts, 1);
+     CV_Assert(type == CV_32F && K > 0 );
+     CV_Assert( N >= K );
+     Mat _labels;
 -    vector<int> counters(K);
 -    vector<Vec2f> _box(dims);
++    if( flags & KMEANS_USE_INITIAL_LABELS )
+     {
+         CV_Assert( (_bestLabels.cols == 1 || _bestLabels.rows == 1) &&
+                    _bestLabels.cols * _bestLabels.rows == N &&
+                    _bestLabels.type() == CV_32S );
+         _bestLabels.download(_labels);
+     }
+     else
+     {
+         if( !((_bestLabels.cols == 1 || _bestLabels.rows == 1) &&
+                 _bestLabels.cols * _bestLabels.rows == N &&
+                 _bestLabels.type() == CV_32S &&
+                 _bestLabels.isContinuous()))
+             _bestLabels.create(N, 1, CV_32S);
+         _labels.create(_bestLabels.size(), _bestLabels.type());
+     }
+     int* labels = _labels.ptr<int>();
+     Mat data;
+     _src.download(data);
+     Mat centers(K, dims, type), old_centers(K, dims, type), temp(1, dims, type);
++    std::vector<int> counters(K);
++    std::vector<Vec2f> _box(dims);
+     Vec2f* box = &_box[0];
+     double best_compactness = DBL_MAX, compactness = 0;
+     RNG& rng = theRNG();
+     int a, iter, i, j, k;
+     if( criteria.type & TermCriteria::EPS )
+         criteria.epsilon = std::max(criteria.epsilon, 0.);
+     else
+         criteria.epsilon = FLT_EPSILON;
+     criteria.epsilon *= criteria.epsilon;
+     if( criteria.type & TermCriteria::COUNT )
+         criteria.maxCount = std::min(std::max(criteria.maxCount, 2), 100);
+     else
+         criteria.maxCount = 100;
+     if( K == 1 )
+     {
+         attempts = 1;
+         criteria.maxCount = 2;
+     }
+     const float* sample = data.ptr<float>();
+     for( j = 0; j < dims; j++ )
+         box[j] = Vec2f(sample[j], sample[j]);
+     for( i = 1; i < N; i++ )
+     {
+         sample = data.ptr<float>(i);
+         for( j = 0; j < dims; j++ )
+         {
+             float v = sample[j];
+             box[j][0] = std::min(box[j][0], v);
+             box[j][1] = std::max(box[j][1], v);
+         }
+     }
+     for( a = 0; a < attempts; a++ )
+     {
+         double max_center_shift = DBL_MAX;
+         for( iter = 0;; )
+         {
+             swap(centers, old_centers);
+             if( iter == 0 && (a > 0 || !(flags & KMEANS_USE_INITIAL_LABELS)) )
+             {
+                 if( flags & KMEANS_PP_CENTERS )
+                     generateCentersPP(data, centers, K, rng, SPP_TRIALS);
+                 else
+                 {
+                     for( k = 0; k < K; k++ )
+                         generateRandomCenter(_box, centers.ptr<float>(k), rng);
+                 }
+             }
+             else
+             {
+                 if( iter == 0 && a == 0 && (flags & KMEANS_USE_INITIAL_LABELS) )
+                 {
+                     for( i = 0; i < N; i++ )
+                         CV_Assert( (unsigned)labels[i] < (unsigned)K );
+                 }
+                 // compute centers
+                 centers = Scalar(0);
+                 for( k = 0; k < K; k++ )
+                     counters[k] = 0;
+                 for( i = 0; i < N; i++ )
+                 {
+                     sample = data.ptr<float>(i);
+                     k = labels[i];
+                     float* center = centers.ptr<float>(k);
+                     j=0;
+ #if CV_ENABLE_UNROLLED
+                     for(; j <= dims - 4; j += 4 )
+                     {
+                         float t0 = center[j] + sample[j];
+                         float t1 = center[j+1] + sample[j+1];
+                         center[j] = t0;
+                         center[j+1] = t1;
+                         t0 = center[j+2] + sample[j+2];
+                         t1 = center[j+3] + sample[j+3];
+                         center[j+2] = t0;
+                         center[j+3] = t1;
+                     }
+ #endif
+                     for( ; j < dims; j++ )
+                         center[j] += sample[j];
+                     counters[k]++;
+                 }
+                 if( iter > 0 )
+                     max_center_shift = 0;
+                 for( k = 0; k < K; k++ )
+                 {
+                     if( counters[k] != 0 )
+                         continue;
+                     // if some cluster appeared to be empty then:
+                     //   1. find the biggest cluster
+                     //   2. find the farthest from the center point in the biggest cluster
+                     //   3. exclude the farthest point from the biggest cluster and form a new 1-point cluster.
+                     int max_k = 0;
+                     for( int k1 = 1; k1 < K; k1++ )
+                     {
+                         if( counters[max_k] < counters[k1] )
+                             max_k = k1;
+                     }
+                     double max_dist = 0;
+                     int farthest_i = -1;
+                     float* new_center =  centers.ptr<float>(k);
+                     float* old_center =  centers.ptr<float>(max_k);
+                     float* _old_center = temp.ptr<float>(); // normalized
+                     float scale = 1.f/counters[max_k];
+                     for( j = 0; j < dims; j++ )
+                         _old_center[j] = old_center[j]*scale;
+                     for( i = 0; i < N; i++ )
+                     {
+                         if( labels[i] != max_k )
+                             continue;
+                         sample = data.ptr<float>(i);
+                         double dist = normL2Sqr_(sample, _old_center, dims);
+                         if( max_dist <= dist )
+                         {
+                             max_dist = dist;
+                             farthest_i = i;
+                         }
+                     }
+                     counters[max_k]--;
+                     counters[k]++;
+                     labels[farthest_i] = k;
+                     sample = data.ptr<float>(farthest_i);
+                     for( j = 0; j < dims; j++ )
+                     {
+                         old_center[j] -= sample[j];
+                         new_center[j] += sample[j];
+                     }
+                 }
+                 for( k = 0; k < K; k++ )
+                 {
+                     float* center = centers.ptr<float>(k);
+                     CV_Assert( counters[k] != 0 );
+                     float scale = 1.f/counters[k];
+                     for( j = 0; j < dims; j++ )
+                         center[j] *= scale;
+                     if( iter > 0 )
+                     {
+                         double dist = 0;
+                         const float* old_center = old_centers.ptr<float>(k);
+                         for( j = 0; j < dims; j++ )
+                         {
+                             double t = center[j] - old_center[j];
+                             dist += t*t;
+                         }
+                         max_center_shift = std::max(max_center_shift, dist);
+                     }
+                 }
+             }
+             if( ++iter == MAX(criteria.maxCount, 2) || max_center_shift <= criteria.epsilon )
+                 break;
+             // assign labels
+             oclMat _dists(1, N, CV_64F);
+             _bestLabels.upload(_labels);
+             _centers.upload(centers);
+             distanceToCenters(_dists, _bestLabels, _src, _centers);
+             Mat dists;
+             _dists.download(dists);
+             _bestLabels.download(_labels);
+             double* dist = dists.ptr<double>(0);
+             compactness = 0;
+             for( i = 0; i < N; i++ )
+             {
+                 compactness += dist[i];
+             }
+         }
+         if( compactness < best_compactness )
+         {
+             best_compactness = compactness;
+         }
+     }
+     return best_compactness;
+ }
@@@ -73,29 -73,26 +73,26 @@@ void print_info(
  #endif
  
  }
- std::string workdir;
  int main(int argc, char **argv)
  {
-     TS::ptr()->init("ocl");
+     TS::ptr()->init(".");
      InitGoogleTest(&argc, argv);
      const char *keys =
 -        "{ h | help     | false              | print help message }"
 -        "{ t | type     | gpu                | set device type:cpu or gpu}"
 -        "{ p | platform | 0                  | set platform id }"
 -        "{ d | device   | 0                  | set device id }";
 +        "{ 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}";
  
      CommandLineParser cmd(argc, argv, keys);
 -    if (cmd.get<bool>("help"))
 +    if (cmd.get<string>("h")=="true")
      {
          cout << "Avaible options besides goole test option:" << endl;
 -        cmd.printParams();
 +        cmd.printMessage();
          return 0;
      }
-     workdir = cmd.get<string>("w");
 -    string type = cmd.get<string>("type");
 -    unsigned int pid = cmd.get<unsigned int>("platform");
 -    int device = cmd.get<int>("device");
 +    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;
index 0000000,ebade3b..a29c879
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,162 +1,162 @@@
 -            TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 100, 0),
+ /*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, Advanced Micro Devices, Inc., all rights reserved.
+ // Third party copyrights are property of their respective owners.
+ //
+ // @Authors
+ //    Erping Pang,   pang_er_ping@163.com
+ //    Xiaopeng Fu,   fuxiaopeng2222@163.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"
+ #ifdef HAVE_OPENCL
+ using namespace cvtest;
+ using namespace testing;
+ using namespace std;
+ using namespace cv;
+ #define OCL_KMEANS_USE_INITIAL_LABELS 1
+ #define OCL_KMEANS_PP_CENTERS         2
+ PARAM_TEST_CASE(Kmeans, int, int, int)
+ {
+     int type;
+     int K;
+     int flags;
+     cv::Mat src ;
+     ocl::oclMat d_src, d_dists;
+     Mat labels, centers;
+     ocl::oclMat d_labels, d_centers;
+     cv::RNG rng ;
+     virtual void SetUp(){
+         K = GET_PARAM(0);
+         type = GET_PARAM(1);
+         flags = GET_PARAM(2);
+         rng = TS::ptr()->get_rng();
+         // MWIDTH=256, MHEIGHT=256. defined in utility.hpp
+         cv::Size size = cv::Size(MWIDTH, MHEIGHT);
+         src.create(size, type);
+         int row_idx = 0;
+         const int max_neighbour = MHEIGHT / K - 1;
+         CV_Assert(K <= MWIDTH);
+         for(int i = 0; i < K; i++ )
+         {
+             Mat center_row_header = src.row(row_idx);
+             center_row_header.setTo(0);
+             int nchannel = center_row_header.channels();
+             for(int j = 0; j < nchannel; j++)
+                 center_row_header.at<float>(0, i*nchannel+j) = 50000.0;
+             for(int j = 0; (j < max_neighbour) || 
+                            (i == K-1 && j < max_neighbour + MHEIGHT%K); j ++)
+             {
+                 Mat cur_row_header = src.row(row_idx + 1 + j);
+                 center_row_header.copyTo(cur_row_header);
+                 Mat tmpmat = randomMat(rng, cur_row_header.size(), cur_row_header.type(), -200, 200, false);
+                 cur_row_header += tmpmat;
+             }
+             row_idx += 1 + max_neighbour;
+         }
+     }
+ };
+ TEST_P(Kmeans, Mat){
+     if(flags & KMEANS_USE_INITIAL_LABELS)
+     {
+         // inital a given labels
+         labels.create(src.rows, 1, CV_32S);
+         int *label = labels.ptr<int>();
+         for(int i = 0; i < src.rows; i++)
+             label[i] = rng.uniform(0, K);
+         d_labels.upload(labels);
+     }
+     d_src.upload(src);
+     for(int j = 0; j < LOOP_TIMES; j++)
+     {
+         kmeans(src, K, labels,
 -            TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 100, 0),
++            TermCriteria( TermCriteria::EPS + TermCriteria::MAX_ITER, 100, 0),
+             1, flags, centers);
+         ocl::kmeans(d_src, K, d_labels,
++            TermCriteria( TermCriteria::EPS + TermCriteria::MAX_ITER, 100, 0),
+             1, flags, d_centers);
+   
+         Mat dd_labels(d_labels);
+         Mat dd_centers(d_centers);
+         if(flags & KMEANS_USE_INITIAL_LABELS)
+         {
+             EXPECT_MAT_NEAR(labels, dd_labels, 0);
+             EXPECT_MAT_NEAR(centers, dd_centers, 1e-3);
+         } 
+         else 
+         {
+             int row_idx = 0;
+             for(int i = 0; i < K; i++)
+             {
+                 // verify lables with ground truth resutls
+                 int label = labels.at<int>(row_idx);
+                 int header_label = dd_labels.at<int>(row_idx);
+                 for(int j = 0; (j < MHEIGHT/K)||(i == K-1 && j < MHEIGHT/K+MHEIGHT%K); j++)
+                 {
+                     ASSERT_NEAR(labels.at<int>(row_idx+j), label, 0);
+                     ASSERT_NEAR(dd_labels.at<int>(row_idx+j), header_label, 0);
+                 }
+                 // verify centers
+                 float *center = centers.ptr<float>(label);
+                 float *header_center = dd_centers.ptr<float>(header_label);
+                 for(int t = 0; t < centers.cols; t++)
+                     ASSERT_NEAR(center[t], header_center[t], 1e-3);
+                 row_idx += MHEIGHT/K;
+             }
+         }
+     }
+ }
+ INSTANTIATE_TEST_CASE_P(OCL_ML, Kmeans, Combine(
+     Values(3, 5, 8),
+     Values(CV_32FC1, CV_32FC2, CV_32FC4),
+     Values(OCL_KMEANS_USE_INITIAL_LABELS/*, OCL_KMEANS_PP_CENTERS*/))); 
+ #endif
Simple merge
Simple merge
@@@ -4,6 -4,4 +4,6 @@@ endif(
  
  set(the_description "Super Resolution")
  ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 -Wundef)
 -ocv_define_module(superres opencv_imgproc opencv_video OPTIONAL opencv_gpu opencv_highgui opencv_ocl)
 +ocv_define_module(superres opencv_imgproc opencv_video
-                   OPTIONAL opencv_highgui
++                  OPTIONAL opencv_highgui opencv_ocl
 +                  opencv_gpuarithm opencv_gpufilters opencv_gpuwarping opencv_gpuimgproc opencv_gpuoptflow opencv_gpucodec)
index b85d0c1,0000000..ac12c42
mode 100644,000000..100644
--- /dev/null
@@@ -1,98 -1,0 +1,99 @@@
 +/*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_SUPERRES_HPP__
 +#define __OPENCV_SUPERRES_HPP__
 +
 +#include "opencv2/core.hpp"
 +
 +namespace cv
 +{
 +    namespace superres
 +    {
 +        CV_EXPORTS bool initModule_superres();
 +
 +        class CV_EXPORTS FrameSource
 +        {
 +        public:
 +            virtual ~FrameSource();
 +
 +            virtual void nextFrame(OutputArray frame) = 0;
 +            virtual void reset() = 0;
 +        };
 +
 +        CV_EXPORTS Ptr<FrameSource> createFrameSource_Empty();
 +
 +        CV_EXPORTS Ptr<FrameSource> createFrameSource_Video(const String& fileName);
 +        CV_EXPORTS Ptr<FrameSource> createFrameSource_Video_GPU(const String& fileName);
 +
 +        CV_EXPORTS Ptr<FrameSource> createFrameSource_Camera(int deviceId = 0);
 +
 +        class CV_EXPORTS SuperResolution : public cv::Algorithm, public FrameSource
 +        {
 +        public:
 +            void setInput(const Ptr<FrameSource>& frameSource);
 +
 +            void nextFrame(OutputArray frame);
 +            void reset();
 +
 +            virtual void collectGarbage();
 +
 +        protected:
 +            SuperResolution();
 +
 +            virtual void initImpl(Ptr<FrameSource>& frameSource) = 0;
 +            virtual void processImpl(Ptr<FrameSource>& frameSource, OutputArray output) = 0;
 +
 +        private:
 +            Ptr<FrameSource> frameSource_;
 +            bool firstCall_;
 +        };
 +
 +        // S. Farsiu , D. Robinson, M. Elad, P. Milanfar. Fast and robust multiframe super resolution.
 +        // Dennis Mitzel, Thomas Pock, Thomas Schoenemann, Daniel Cremers. Video Super Resolution using Duality Based TV-L1 Optical Flow.
 +        CV_EXPORTS Ptr<SuperResolution> createSuperResolution_BTVL1();
 +        CV_EXPORTS Ptr<SuperResolution> createSuperResolution_BTVL1_GPU();
++        CV_EXPORTS Ptr<SuperResolution> createSuperResolution_BTVL1_OCL();
 +    }
 +}
 +
 +#endif // __OPENCV_SUPERRES_HPP__
index 0000000,e75a877..ca9c81e
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,146 +1,147 @@@
 -#include "opencv2/ocl/ocl.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, Multicoreware, Inc., all rights reserved.
+ // Copyright (C) 2010-2012, Advanced Micro Devices, 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*/
+ #include "perf_precomp.hpp"
+ #ifdef HAVE_OPENCL
++#include "opencv2/ocl.hpp"
+ using namespace std;
++using namespace std::tr1;
+ using namespace testing;
+ using namespace perf;
+ using namespace cv;
+ using namespace cv::superres;
+ namespace
+ {
+     class OneFrameSource_OCL : public FrameSource
+     {
+     public:
+         explicit OneFrameSource_OCL(const ocl::oclMat& frame) : frame_(frame) {}
+         void nextFrame(OutputArray frame)
+         {
+             ocl::getOclMatRef(frame) = frame_;
+         }
+         void reset()
+         {
+         }
+     private:
+         ocl::oclMat frame_;
+     };
+     class ZeroOpticalFlowOCL : public DenseOpticalFlowExt
+     {
+     public:
+         void calc(InputArray frame0, InputArray, OutputArray flow1, OutputArray flow2)
+         {
+             ocl::oclMat& frame0_ = ocl::getOclMatRef(frame0);
+             ocl::oclMat& flow1_ = ocl::getOclMatRef(flow1);
+             ocl::oclMat& flow2_ = ocl::getOclMatRef(flow2);
+             cv::Size size = frame0_.size();
+             if(!flow2.needed())
+             {
+                 flow1_.create(size, CV_32FC2);
+                 flow1_.setTo(Scalar::all(0));
+             }
+             else
+             {
+                 flow1_.create(size, CV_32FC1);
+                 flow2_.create(size, CV_32FC1);
+                 flow1_.setTo(Scalar::all(0));
+                 flow2_.setTo(Scalar::all(0));
+             }
+         }
+         void collectGarbage()
+         {
+         }
+     };
+ }
+ PERF_TEST_P(Size_MatType, SuperResolution_BTVL1_OCL,
+     Combine(Values(szSmall64, szSmall128),
+     Values(MatType(CV_8UC1), MatType(CV_8UC3))))
+ {
+     std::vector<cv::ocl::Info>info;
+     cv::ocl::getDevice(info);
+     declare.time(5 * 60);
+     const Size size = get<0>(GetParam());
+     const int type = get<1>(GetParam());
+     Mat frame(size, type);
+     declare.in(frame, WARMUP_RNG);
+     ocl::oclMat frame_ocl;
+     frame_ocl.upload(frame);
+     const int scale = 2;
+     const int iterations = 50;
+     const int temporalAreaRadius = 1;
+     Ptr<DenseOpticalFlowExt> opticalFlowOcl(new ZeroOpticalFlowOCL);
+     Ptr<SuperResolution> superRes_ocl = createSuperResolution_BTVL1_OCL();
+     superRes_ocl->set("scale", scale);
+     superRes_ocl->set("iterations", iterations);
+     superRes_ocl->set("temporalAreaRadius", temporalAreaRadius);
+     superRes_ocl->set("opticalFlow", opticalFlowOcl);
+     superRes_ocl->setInput(new OneFrameSource_OCL(frame_ocl));
+     ocl::oclMat dst_ocl;
+     superRes_ocl->nextFrame(dst_ocl);
+     TEST_CYCLE_N(10) superRes_ocl->nextFrame(dst_ocl);
+     frame_ocl.release();
+     CPU_SANITY_CHECK(dst_ocl);
+ }
+ #endif
index 0000000,5f9e326..e417d89
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,748 +1,748 @@@
 -    CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");
+ /*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, Advanced Micro Devices, Inc., all rights reserved.
+ // Third party copyrights are property of their respective owners.
+ //
+ // @Authors
+ //            Jin Ma, jin@multicorewareinc.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 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*/
+ // S. Farsiu , D. Robinson, M. Elad, P. Milanfar. Fast and robust multiframe super resolution.
+ // Dennis Mitzel, Thomas Pock, Thomas Schoenemann, Daniel Cremers. Video Super Resolution using Duality Based TV-L1 Optical Flow.
+ #include "precomp.hpp"
+ #if !defined(HAVE_OPENCL) || !defined(HAVE_OPENCV_OCL)
+ cv::Ptr<cv::superres::SuperResolution> cv::superres::createSuperResolution_BTVL1_OCL()
+ {
 -#endif
++    CV_Error(cv::Error::StsNotImplemented, "The called functionality is disabled for current build or platform");
+     return Ptr<SuperResolution>();
+ }
+ #else
+ using namespace std;
+ using namespace cv;
+ using namespace cv::ocl;
+ using namespace cv::superres;
+ using namespace cv::superres::detail;
+ namespace cv
+ {
+     namespace ocl
+     {
+         extern const char* superres_btvl1;
+         float* btvWeights_ = NULL;
+         size_t btvWeights_size = 0;
+     }
+ }
+ namespace btv_l1_device_ocl
+ {
+     void buildMotionMaps(const oclMat& forwardMotionX, const oclMat& forwardMotionY,
+         const oclMat& backwardMotionX, const oclMat& bacwardMotionY,
+         oclMat& forwardMapX, oclMat& forwardMapY,
+         oclMat& backwardMapX, oclMat& backwardMapY);
+     void upscale(const oclMat& src, oclMat& dst, int scale);
+     float diffSign(float a, float b);
+     Point3f diffSign(Point3f a, Point3f b);
+     void diffSign(const oclMat& src1, const oclMat& src2, oclMat& dst);
+     void calcBtvRegularization(const oclMat& src, oclMat& dst, int ksize);
+ }
+ void btv_l1_device_ocl::buildMotionMaps(const oclMat& forwardMotionX, const oclMat& forwardMotionY,
+     const oclMat& backwardMotionX, const oclMat& backwardMotionY,
+     oclMat& forwardMapX, oclMat& forwardMapY,
+     oclMat& backwardMapX, oclMat& backwardMapY)
+ {
+     Context* clCxt = Context::getContext();
+     size_t local_thread[] = {32, 8, 1};
+     size_t global_thread[] = {forwardMapX.cols, forwardMapX.rows, 1};
+     int forwardMotionX_step = (int)(forwardMotionX.step/forwardMotionX.elemSize());
+     int forwardMotionY_step = (int)(forwardMotionY.step/forwardMotionY.elemSize());
+     int backwardMotionX_step = (int)(backwardMotionX.step/backwardMotionX.elemSize());
+     int backwardMotionY_step = (int)(backwardMotionY.step/backwardMotionY.elemSize());
+     int forwardMapX_step = (int)(forwardMapX.step/forwardMapX.elemSize());
+     int forwardMapY_step = (int)(forwardMapY.step/forwardMapY.elemSize());
+     int backwardMapX_step = (int)(backwardMapX.step/backwardMapX.elemSize());
+     int backwardMapY_step = (int)(backwardMapY.step/backwardMapY.elemSize());
+     String kernel_name = "buildMotionMapsKernel";
+     vector< pair<size_t, const void*> > args;
+     args.push_back(make_pair(sizeof(cl_mem), (void*)&forwardMotionX.data));
+     args.push_back(make_pair(sizeof(cl_mem), (void*)&forwardMotionY.data));
+     args.push_back(make_pair(sizeof(cl_mem), (void*)&backwardMotionX.data));
+     args.push_back(make_pair(sizeof(cl_mem), (void*)&backwardMotionY.data));
+     args.push_back(make_pair(sizeof(cl_mem), (void*)&forwardMapX.data));
+     args.push_back(make_pair(sizeof(cl_mem), (void*)&forwardMapY.data));
+     args.push_back(make_pair(sizeof(cl_mem), (void*)&backwardMapX.data));
+     args.push_back(make_pair(sizeof(cl_mem), (void*)&backwardMapY.data));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&forwardMotionX.rows));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&forwardMotionY.cols));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&forwardMotionX_step));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&forwardMotionY_step));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&backwardMotionX_step));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&backwardMotionY_step));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&forwardMapX_step));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&forwardMapY_step));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&backwardMapX_step));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&backwardMapY_step));
+     openCLExecuteKernel(clCxt, &superres_btvl1, kernel_name, global_thread, local_thread, args, -1, -1);
+ }
+ void btv_l1_device_ocl::upscale(const oclMat& src, oclMat& dst, int scale)
+ {
+     Context* clCxt = Context::getContext();
+     size_t local_thread[] = {32, 8, 1};
+     size_t global_thread[] = {src.cols, src.rows, 1};
+     int src_step = (int)(src.step/src.elemSize());
+     int dst_step = (int)(dst.step/dst.elemSize());
+     String kernel_name = "upscaleKernel";
+     vector< pair<size_t, const void*> > args;
+     int cn = src.oclchannels();
+     args.push_back(make_pair(sizeof(cl_mem), (void*)&src.data));
+     args.push_back(make_pair(sizeof(cl_mem), (void*)&dst.data));
+     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*)&src.rows));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&src.cols));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&scale));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&cn));    
+     openCLExecuteKernel(clCxt, &superres_btvl1, kernel_name, global_thread, local_thread, args, -1, -1);
+ }
+ float btv_l1_device_ocl::diffSign(float a, float b)
+ {
+     return a > b ? 1.0f : a < b ? -1.0f : 0.0f;
+ }
+ Point3f btv_l1_device_ocl::diffSign(Point3f a, Point3f b)
+ {
+     return Point3f(
+         a.x > b.x ? 1.0f : a.x < b.x ? -1.0f : 0.0f,
+         a.y > b.y ? 1.0f : a.y < b.y ? -1.0f : 0.0f,
+         a.z > b.z ? 1.0f : a.z < b.z ? -1.0f : 0.0f
+         );
+ }
+ void btv_l1_device_ocl::diffSign(const oclMat& src1, const oclMat& src2, oclMat& dst)
+ {
+     Context* clCxt = Context::getContext();
+     oclMat src1_ = src1.reshape(1);
+     oclMat src2_ = src2.reshape(1);
+     oclMat dst_ = dst.reshape(1);
+     int src1_step = (int)(src1_.step/src1_.elemSize());
+     int src2_step = (int)(src2_.step/src2_.elemSize());
+     int dst_step = (int)(dst_.step/dst_.elemSize());
+     size_t local_thread[] = {32, 8, 1};
+     size_t global_thread[] = {src1_.cols, src1_.rows, 1};
+     String kernel_name = "diffSignKernel";
+     vector< pair<size_t, const void*> > args;
+     args.push_back(make_pair(sizeof(cl_mem), (void*)&src1_.data));
+     args.push_back(make_pair(sizeof(cl_mem), (void*)&src2_.data));
+     args.push_back(make_pair(sizeof(cl_mem), (void*)&dst_.data));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&src1_.rows));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&src1_.cols));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&dst_step));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&src1_step));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&src2_step));
+     openCLExecuteKernel(clCxt, &superres_btvl1, kernel_name, global_thread, local_thread, args, -1, -1);
+ }
+ void btv_l1_device_ocl::calcBtvRegularization(const oclMat& src, oclMat& dst, int ksize)
+ {
+     Context* clCxt = Context::getContext();
+     oclMat src_ = src.reshape(1);
+     oclMat dst_ = dst.reshape(1);
+     size_t local_thread[] = {32, 8, 1};
+     size_t global_thread[] = {src.cols, src.rows, 1};
+     int src_step = (int)(src_.step/src_.elemSize());
+     int dst_step = (int)(dst_.step/dst_.elemSize());
+     String kernel_name = "calcBtvRegularizationKernel";
+     vector< pair<size_t, const void*> > args;
+     int cn = src.oclchannels();
+     cl_mem c_btvRegWeights;
+     size_t count = btvWeights_size * sizeof(float);
+     c_btvRegWeights = openCLCreateBuffer(clCxt, CL_MEM_READ_ONLY, count);
+     int cl_safe_check = clEnqueueWriteBuffer((cl_command_queue)clCxt->oclCommandQueue(), c_btvRegWeights, 1, 0, count, btvWeights_, 0, NULL, NULL);
+     CV_Assert(cl_safe_check == CL_SUCCESS);
+     args.push_back(make_pair(sizeof(cl_mem), (void*)&src_.data));
+     args.push_back(make_pair(sizeof(cl_mem), (void*)&dst_.data));
+     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*)&src.rows));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&src.cols));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&ksize));
+     args.push_back(make_pair(sizeof(cl_int), (void*)&cn));
+     args.push_back(make_pair(sizeof(cl_mem), (void*)&c_btvRegWeights));
+     openCLExecuteKernel(clCxt, &superres_btvl1, kernel_name, global_thread, local_thread, args, -1, -1);
+     cl_safe_check = clReleaseMemObject(c_btvRegWeights);
+     CV_Assert(cl_safe_check == CL_SUCCESS);
+ }
+ namespace
+ {
+     void calcRelativeMotions(const vector<pair<oclMat, oclMat> >& forwardMotions, const vector<pair<oclMat, oclMat> >& backwardMotions,
+         vector<pair<oclMat, oclMat> >& relForwardMotions, vector<pair<oclMat, oclMat> >& relBackwardMotions,
+         int baseIdx, Size size)
+     {
+         const int count = static_cast<int>(forwardMotions.size());
+         relForwardMotions.resize(count);
+         relForwardMotions[baseIdx].first.create(size, CV_32FC1);
+         relForwardMotions[baseIdx].first.setTo(Scalar::all(0));
+         relForwardMotions[baseIdx].second.create(size, CV_32FC1);
+         relForwardMotions[baseIdx].second.setTo(Scalar::all(0));
+         relBackwardMotions.resize(count);
+         relBackwardMotions[baseIdx].first.create(size, CV_32FC1);
+         relBackwardMotions[baseIdx].first.setTo(Scalar::all(0));
+         relBackwardMotions[baseIdx].second.create(size, CV_32FC1);
+         relBackwardMotions[baseIdx].second.setTo(Scalar::all(0));
+         for (int i = baseIdx - 1; i >= 0; --i)
+         {
+             ocl::add(relForwardMotions[i + 1].first, forwardMotions[i].first, relForwardMotions[i].first);
+             ocl::add(relForwardMotions[i + 1].second, forwardMotions[i].second, relForwardMotions[i].second);
+             ocl::add(relBackwardMotions[i + 1].first, backwardMotions[i + 1].first, relBackwardMotions[i].first);
+             ocl::add(relBackwardMotions[i + 1].second, backwardMotions[i + 1].second, relBackwardMotions[i].second);
+         }
+         for (int i = baseIdx + 1; i < count; ++i)
+         {
+             ocl::add(relForwardMotions[i - 1].first, backwardMotions[i].first, relForwardMotions[i].first);
+             ocl::add(relForwardMotions[i - 1].second, backwardMotions[i].second, relForwardMotions[i].second);
+             ocl::add(relBackwardMotions[i - 1].first, forwardMotions[i - 1].first, relBackwardMotions[i].first);
+             ocl::add(relBackwardMotions[i - 1].second, forwardMotions[i - 1].second, relBackwardMotions[i].second);
+         }
+     }
+     void upscaleMotions(const vector<pair<oclMat, oclMat> >& lowResMotions, vector<pair<oclMat, oclMat> >& highResMotions, int scale)
+     {
+         highResMotions.resize(lowResMotions.size());
+         for (size_t i = 0; i < lowResMotions.size(); ++i)
+         {
+             ocl::resize(lowResMotions[i].first, highResMotions[i].first, Size(), scale, scale, INTER_LINEAR);
+             ocl::resize(lowResMotions[i].second, highResMotions[i].second, Size(), scale, scale, INTER_LINEAR);
+             ocl::multiply(scale, highResMotions[i].first, highResMotions[i].first);
+             ocl::multiply(scale, highResMotions[i].second, highResMotions[i].second);
+         }
+     }
+     void buildMotionMaps(const pair<oclMat, oclMat>& forwardMotion, const pair<oclMat, oclMat>& backwardMotion,
+         pair<oclMat, oclMat>& forwardMap, pair<oclMat, oclMat>& backwardMap)
+     {
+         forwardMap.first.create(forwardMotion.first.size(), CV_32FC1);
+         forwardMap.second.create(forwardMotion.first.size(), CV_32FC1);
+         backwardMap.first.create(forwardMotion.first.size(), CV_32FC1);
+         backwardMap.second.create(forwardMotion.first.size(), CV_32FC1);
+         btv_l1_device_ocl::buildMotionMaps(forwardMotion.first, forwardMotion.second,
+             backwardMotion.first, backwardMotion.second,
+             forwardMap.first, forwardMap.second,
+             backwardMap.first, backwardMap.second);
+     }
+     void upscale(const oclMat& src, oclMat& dst, int scale)
+     {
+         CV_Assert( src.channels() == 1 || src.channels() == 3 || src.channels() == 4 );
+         dst.create(src.rows * scale, src.cols * scale, src.type());
+         dst.setTo(Scalar::all(0));
+         btv_l1_device_ocl::upscale(src, dst, scale);
+     }
+     void diffSign(const oclMat& src1, const oclMat& src2, oclMat& dst)
+     {
+         dst.create(src1.size(), src1.type());
+         btv_l1_device_ocl::diffSign(src1, src2, dst);
+     }
+     void calcBtvWeights(int btvKernelSize, double alpha, vector<float>& btvWeights)
+     {
+         const size_t size = btvKernelSize * btvKernelSize;
+         btvWeights.resize(size);
+         const int ksize = (btvKernelSize - 1) / 2;
+         const float alpha_f = static_cast<float>(alpha);
+         for (int m = 0, ind = 0; m <= ksize; ++m)
+         {
+             for (int l = ksize; l + m >= 0; --l, ++ind)
+                 btvWeights[ind] = pow(alpha_f, std::abs(m) + std::abs(l));
+         }
+         btvWeights_ = &btvWeights[0];
+         btvWeights_size = size;
+     }
+     void calcBtvRegularization(const oclMat& src, oclMat& dst, int btvKernelSize)
+     {
+         dst.create(src.size(), src.type());
+         dst.setTo(Scalar::all(0));
+         const int ksize = (btvKernelSize - 1) / 2;
+         btv_l1_device_ocl::calcBtvRegularization(src, dst, ksize);
+     }
+     class BTVL1_OCL_Base
+     {
+     public:
+         BTVL1_OCL_Base();
+         void process(const vector<oclMat>& src, oclMat& dst,
+             const vector<pair<oclMat, oclMat> >& forwardMotions, const vector<pair<oclMat, oclMat> >& backwardMotions,
+             int baseIdx);
+         void collectGarbage();
+     protected:
+         int scale_;
+         int iterations_;
+         double lambda_;
+         double tau_;
+         double alpha_;
+         int btvKernelSize_;
+         int blurKernelSize_;
+         double blurSigma_;
+         Ptr<DenseOpticalFlowExt> opticalFlow_;
+     private:
+         vector<Ptr<cv::ocl::FilterEngine_GPU> > filters_;
+         int curBlurKernelSize_;
+         double curBlurSigma_;
+         int curSrcType_;
+         vector<float> btvWeights_;
+         int curBtvKernelSize_;
+         double curAlpha_;
+         vector<pair<oclMat, oclMat> > lowResForwardMotions_;
+         vector<pair<oclMat, oclMat> > lowResBackwardMotions_;
+         vector<pair<oclMat, oclMat> > highResForwardMotions_;
+         vector<pair<oclMat, oclMat> > highResBackwardMotions_;
+         vector<pair<oclMat, oclMat> > forwardMaps_;
+         vector<pair<oclMat, oclMat> > backwardMaps_;
+         oclMat highRes_;
+         vector<oclMat> diffTerms_;
+         vector<oclMat> a_, b_, c_;
+         oclMat regTerm_;
+     };
+     BTVL1_OCL_Base::BTVL1_OCL_Base()
+     {
+         scale_ = 4;
+         iterations_ = 180;
+         lambda_ = 0.03;
+         tau_ = 1.3;
+         alpha_ = 0.7;
+         btvKernelSize_ = 7;
+         blurKernelSize_ = 5;
+         blurSigma_ = 0.0;
+         opticalFlow_ = createOptFlow_DualTVL1_OCL();
+         curBlurKernelSize_ = -1;
+         curBlurSigma_ = -1.0;
+         curSrcType_ = -1;
+         curBtvKernelSize_ = -1;
+         curAlpha_ = -1.0;
+     }
+     void BTVL1_OCL_Base::process(const vector<oclMat>& src, oclMat& dst,
+         const vector<pair<oclMat, oclMat> >& forwardMotions, const vector<pair<oclMat, oclMat> >& backwardMotions,
+         int baseIdx)
+     {
+         CV_Assert( scale_ > 1 );
+         CV_Assert( iterations_ > 0 );
+         CV_Assert( tau_ > 0.0 );
+         CV_Assert( alpha_ > 0.0 );
+         CV_Assert( btvKernelSize_ > 0 && btvKernelSize_ <= 16 );
+         CV_Assert( blurKernelSize_ > 0 );
+         CV_Assert( blurSigma_ >= 0.0 );
+         // update blur filter and btv weights
+         if (filters_.size() != src.size() || blurKernelSize_ != curBlurKernelSize_ || blurSigma_ != curBlurSigma_ || src[0].type() != curSrcType_)
+         {
+             filters_.resize(src.size());
+             for (size_t i = 0; i < src.size(); ++i)
+                 filters_[i] = cv::ocl::createGaussianFilter_GPU(src[0].type(), Size(blurKernelSize_, blurKernelSize_), blurSigma_);
+             curBlurKernelSize_ = blurKernelSize_;
+             curBlurSigma_ = blurSigma_;
+             curSrcType_ = src[0].type();
+         }
+         if (btvWeights_.empty() || btvKernelSize_ != curBtvKernelSize_ || alpha_ != curAlpha_)
+         {
+             calcBtvWeights(btvKernelSize_, alpha_, btvWeights_);
+             curBtvKernelSize_ = btvKernelSize_;
+             curAlpha_ = alpha_;
+         }
+         // calc motions between input frames
+         calcRelativeMotions(forwardMotions, backwardMotions, 
+             lowResForwardMotions_, lowResBackwardMotions_, 
+             baseIdx, src[0].size());
+         upscaleMotions(lowResForwardMotions_, highResForwardMotions_, scale_);
+         upscaleMotions(lowResBackwardMotions_, highResBackwardMotions_, scale_);
+         forwardMaps_.resize(highResForwardMotions_.size());
+         backwardMaps_.resize(highResForwardMotions_.size());
+         for (size_t i = 0; i < highResForwardMotions_.size(); ++i)
+         {
+             buildMotionMaps(highResForwardMotions_[i], highResBackwardMotions_[i], forwardMaps_[i], backwardMaps_[i]);
+         }
+         // initial estimation
+         const Size lowResSize = src[0].size();
+         const Size highResSize(lowResSize.width * scale_, lowResSize.height * scale_);
+         ocl::resize(src[baseIdx], highRes_, highResSize, 0, 0, INTER_LINEAR);
+         // iterations
+         diffTerms_.resize(src.size());
+         a_.resize(src.size());
+         b_.resize(src.size());
+         c_.resize(src.size());
+         for (int i = 0; i < iterations_; ++i)
+         {
+             for (size_t k = 0; k < src.size(); ++k)
+             {
+                 diffTerms_[k].create(highRes_.size(), highRes_.type());
+                 a_[k].create(highRes_.size(), highRes_.type());
+                 b_[k].create(highRes_.size(), highRes_.type());
+                 c_[k].create(lowResSize, highRes_.type());
+                 // a = M * Ih
+                 ocl::remap(highRes_, a_[k], backwardMaps_[k].first, backwardMaps_[k].second, INTER_NEAREST, BORDER_CONSTANT, Scalar());
+                 // b = HM * Ih
+                 filters_[k]->apply(a_[k], b_[k], Rect(0,0,-1,-1));
+                 // c = DHF * Ih
+                 ocl::resize(b_[k], c_[k], lowResSize, 0, 0, INTER_NEAREST);
+                 diffSign(src[k], c_[k], c_[k]);
+                 // a = Dt * diff
+                 upscale(c_[k], a_[k], scale_);
+                 // b = HtDt * diff
+                 filters_[k]->apply(a_[k], b_[k], Rect(0,0,-1,-1));
+                 // diffTerm = MtHtDt * diff
+                 ocl::remap(b_[k], diffTerms_[k], forwardMaps_[k].first, forwardMaps_[k].second, INTER_NEAREST, BORDER_CONSTANT, Scalar());
+             }
+             if (lambda_ > 0)
+             {
+                 calcBtvRegularization(highRes_, regTerm_, btvKernelSize_);
+                 ocl::addWeighted(highRes_, 1.0, regTerm_, -tau_ * lambda_, 0.0, highRes_);
+             }
+             for (size_t k = 0; k < src.size(); ++k)
+             {
+                 ocl::addWeighted(highRes_, 1.0, diffTerms_[k], tau_, 0.0, highRes_);
+             }
+         }
+         Rect inner(btvKernelSize_, btvKernelSize_, highRes_.cols - 2 * btvKernelSize_, highRes_.rows - 2 * btvKernelSize_);
+         highRes_(inner).copyTo(dst);
+     }
+     void BTVL1_OCL_Base::collectGarbage()
+     {
+         filters_.clear();
+         lowResForwardMotions_.clear();
+         lowResBackwardMotions_.clear();
+         highResForwardMotions_.clear();
+         highResBackwardMotions_.clear();
+         forwardMaps_.clear();
+         backwardMaps_.clear();
+         highRes_.release();
+         diffTerms_.clear();
+         a_.clear();
+         b_.clear();
+         c_.clear();
+         regTerm_.release();
+     }
+     ////////////////////////////////////////////////////////////
+     class BTVL1_OCL : public SuperResolution, private BTVL1_OCL_Base
+     {
+     public:
+         AlgorithmInfo* info() const;
+         BTVL1_OCL();
+         void collectGarbage();
+     protected:
+         void initImpl(Ptr<FrameSource>& frameSource);
+         void processImpl(Ptr<FrameSource>& frameSource, OutputArray output);
+     private:
+         int temporalAreaRadius_;
+         void readNextFrame(Ptr<FrameSource>& frameSource);
+         void processFrame(int idx);
+         oclMat curFrame_;
+         oclMat prevFrame_;
+         vector<oclMat> frames_;
+         vector<pair<oclMat, oclMat> > forwardMotions_;
+         vector<pair<oclMat, oclMat> > backwardMotions_;
+         vector<oclMat> outputs_;
+         int storePos_;
+         int procPos_;
+         int outPos_;
+         vector<oclMat> srcFrames_;
+         vector<pair<oclMat, oclMat> > srcForwardMotions_;
+         vector<pair<oclMat, oclMat> > srcBackwardMotions_;
+         oclMat finalOutput_;
+     };
+     CV_INIT_ALGORITHM(BTVL1_OCL, "SuperResolution.BTVL1_OCL",
+     obj.info()->addParam(obj, "scale", obj.scale_, false, 0, 0, "Scale factor.");
+     obj.info()->addParam(obj, "iterations", obj.iterations_, false, 0, 0, "Iteration count.");
+     obj.info()->addParam(obj, "tau", obj.tau_, false, 0, 0, "Asymptotic value of steepest descent method.");
+     obj.info()->addParam(obj, "lambda", obj.lambda_, false, 0, 0, "Weight parameter to balance data term and smoothness term.");
+     obj.info()->addParam(obj, "alpha", obj.alpha_, false, 0, 0, "Parameter of spacial distribution in Bilateral-TV.");
+     obj.info()->addParam(obj, "btvKernelSize", obj.btvKernelSize_, false, 0, 0, "Kernel size of Bilateral-TV filter.");
+     obj.info()->addParam(obj, "blurKernelSize", obj.blurKernelSize_, false, 0, 0, "Gaussian blur kernel size.");
+     obj.info()->addParam(obj, "blurSigma", obj.blurSigma_, false, 0, 0, "Gaussian blur sigma.");
+     obj.info()->addParam(obj, "temporalAreaRadius", obj.temporalAreaRadius_, false, 0, 0, "Radius of the temporal search area.");
+     obj.info()->addParam<DenseOpticalFlowExt>(obj, "opticalFlow", obj.opticalFlow_, false, 0, 0, "Dense optical flow algorithm."));
+     BTVL1_OCL::BTVL1_OCL()
+     {
+         temporalAreaRadius_ = 4;
+     }
+     void BTVL1_OCL::collectGarbage()
+     {
+         curFrame_.release();
+         prevFrame_.release();
+         frames_.clear();
+         forwardMotions_.clear();
+         backwardMotions_.clear();
+         outputs_.clear();
+         srcFrames_.clear();
+         srcForwardMotions_.clear();
+         srcBackwardMotions_.clear();
+         finalOutput_.release();
+         SuperResolution::collectGarbage();
+         BTVL1_OCL_Base::collectGarbage();
+     }
+     void BTVL1_OCL::initImpl(Ptr<FrameSource>& frameSource)
+     {
+         const int cacheSize = 2 * temporalAreaRadius_ + 1;
+         frames_.resize(cacheSize);
+         forwardMotions_.resize(cacheSize);
+         backwardMotions_.resize(cacheSize);
+         outputs_.resize(cacheSize);
+         storePos_ = -1;
+         for (int t = -temporalAreaRadius_; t <= temporalAreaRadius_; ++t)
+             readNextFrame(frameSource);
+         for (int i = 0; i <= temporalAreaRadius_; ++i)
+             processFrame(i);
+         procPos_ = temporalAreaRadius_;
+         outPos_ = -1;
+     }
+     void BTVL1_OCL::processImpl(Ptr<FrameSource>& frameSource, OutputArray _output)
+     {
+         if (outPos_ >= storePos_)
+         {
+             if(_output.kind() == _InputArray::OCL_MAT)
+             {
+                 getOclMatRef(_output).release();
+             }
+             else
+             {
+                 _output.release();
+             }
+             return;
+         }
+         readNextFrame(frameSource);
+         if (procPos_ < storePos_)
+         {
+             ++procPos_;
+             processFrame(procPos_);
+         }
+         ++outPos_;
+         const oclMat& curOutput = at(outPos_, outputs_);
+         if (_output.kind() == _InputArray::OCL_MAT)
+             curOutput.convertTo(getOclMatRef(_output), CV_8U);
+         else
+         {
+             curOutput.convertTo(finalOutput_, CV_8U);
+             arrCopy(finalOutput_, _output);
+         }
+     }
+     void BTVL1_OCL::readNextFrame(Ptr<FrameSource>& frameSource)
+     {
+         curFrame_.release();
+         frameSource->nextFrame(curFrame_);
+         if (curFrame_.empty())
+             return;
+         ++storePos_;
+         curFrame_.convertTo(at(storePos_, frames_), CV_32F);
+         if (storePos_ > 0)
+         {
+             pair<oclMat, oclMat>& forwardMotion = at(storePos_ - 1, forwardMotions_);
+             pair<oclMat, oclMat>& backwardMotion = at(storePos_, backwardMotions_);
+             opticalFlow_->calc(prevFrame_, curFrame_, forwardMotion.first, forwardMotion.second);
+             opticalFlow_->calc(curFrame_, prevFrame_, backwardMotion.first, backwardMotion.second);
+         }
+         curFrame_.copyTo(prevFrame_);
+     }
+     void BTVL1_OCL::processFrame(int idx)
+     {
+         const int startIdx = max(idx - temporalAreaRadius_, 0);
+         const int procIdx = idx;
+         const int endIdx = min(startIdx + 2 * temporalAreaRadius_, storePos_);
+         const int count = endIdx - startIdx + 1;
+         srcFrames_.resize(count);
+         srcForwardMotions_.resize(count);
+         srcBackwardMotions_.resize(count);
+         int baseIdx = -1;
+         for (int i = startIdx, k = 0; i <= endIdx; ++i, ++k)
+         {
+             if (i == procIdx)
+                 baseIdx = k;
+             srcFrames_[k] = at(i, frames_);
+             if (i < endIdx)
+                 srcForwardMotions_[k] = at(i, forwardMotions_);
+             if (i > startIdx)
+                 srcBackwardMotions_[k] = at(i, backwardMotions_);
+         }
+         process(srcFrames_, at(idx, outputs_), srcForwardMotions_, srcBackwardMotions_, baseIdx);
+     }
+ }
+ Ptr<SuperResolution> cv::superres::createSuperResolution_BTVL1_OCL()
+ {
+     return new BTVL1_OCL;
+ }
++#endif
Simple merge
@@@ -108,23 -125,52 +108,52 @@@ namespac
      {
          src.getGpuMat().copyTo(dst.getGpuMatRef());
      }
 -        CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");;
+ #ifdef HAVE_OPENCV_OCL
+     void ocl2mat(InputArray src, OutputArray dst)
+     {
+         dst.getMatRef() = (Mat)ocl::getOclMatRef(src);
+     }
+     void mat2ocl(InputArray src, OutputArray dst)
+     {
+         Mat m = src.getMat();
+         ocl::getOclMatRef(dst) = (ocl::oclMat)m;
+     }
+     void ocl2ocl(InputArray src, OutputArray dst)
+     {
+         ocl::getOclMatRef(src).copyTo(ocl::getOclMatRef(dst));
+     }
+ #else
+     void ocl2mat(InputArray, OutputArray)
+     {
 -        CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");;
++        CV_Error(Error::StsNotImplemented, "The called functionality is disabled for current build or platform");;
+     }
+     void mat2ocl(InputArray, OutputArray)
+     {
 -        CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform");
++        CV_Error(Error::StsNotImplemented, "The called functionality is disabled for current build or platform");;
+     }
+     void ocl2ocl(InputArray, OutputArray)
+     {
++        CV_Error(Error::StsNotImplemented, "The called functionality is disabled for current build or platform");
+     }
+ #endif
  }
  
  void cv::superres::arrCopy(InputArray src, OutputArray dst)
  {
      typedef void (*func_t)(InputArray src, OutputArray dst);
-     static const func_t funcs[10][10] =
+     static const func_t funcs[11][11] =
      {
          {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-         {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, 0 /*arr2tex*/, mat2gpu},
-         {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, 0 /*arr2tex*/, mat2gpu},
-         {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, 0 /*arr2tex*/, mat2gpu},
-         {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, 0 /*arr2tex*/, mat2gpu},
-         {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, 0 /*arr2tex*/, mat2gpu},
-         {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, 0 /*arr2tex*/, mat2gpu},
-         {0, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, 0 /*buf2arr*/, buf2arr},
-         {0, 0 /*tex2arr*/, 0 /*tex2arr*/, 0 /*tex2arr*/, 0 /*tex2arr*/, 0 /*tex2arr*/, 0 /*tex2arr*/, 0 /*tex2arr*/, 0 /*tex2arr*/, 0 /*tex2arr*/},
-         {0, gpu2mat, gpu2mat, gpu2mat, gpu2mat, gpu2mat, gpu2mat, arr2buf, 0 /*arr2tex*/, gpu2gpu}
 -        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, arr2tex, mat2gpu, mat2ocl},
 -        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, arr2tex, mat2gpu, mat2ocl},
 -        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, arr2tex, mat2gpu, mat2ocl},
 -        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, arr2tex, mat2gpu, mat2ocl},
 -        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, arr2tex, mat2gpu, mat2ocl},
 -        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, arr2tex, mat2gpu, mat2ocl},
 -        {0, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, 0      },
 -        {0, tex2arr, tex2arr, tex2arr, tex2arr, tex2arr, tex2arr, tex2arr, tex2arr, tex2arr, 0      },
 -        {0, gpu2mat, gpu2mat, gpu2mat, gpu2mat, gpu2mat, gpu2mat, arr2buf, arr2tex, gpu2gpu, 0      },
 -        {0, ocl2mat, ocl2mat, ocl2mat, ocl2mat, ocl2mat, ocl2mat, 0,       0,       0,       ocl2ocl}
++        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, 0 /*arr2tex*/, mat2gpu, mat2ocl},
++        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, 0 /*arr2tex*/, mat2gpu, mat2ocl},
++        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, 0 /*arr2tex*/, mat2gpu, mat2ocl},
++        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, 0 /*arr2tex*/, mat2gpu, mat2ocl},
++        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, 0 /*arr2tex*/, mat2gpu, mat2ocl},
++        {0, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, mat2mat, arr2buf, 0 /*arr2tex*/, mat2gpu, mat2ocl},
++        {0, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, buf2arr, 0 /*buf2arr*/, buf2arr, 0      },
++        {0, 0 /*tex2arr*/, 0 /*tex2arr*/, 0 /*tex2arr*/, 0 /*tex2arr*/, 0 /*tex2arr*/, 0 /*tex2arr*/, 0 /*tex2arr*/, 0 /*tex2arr*/, 0 /*tex2arr*/, 0},
++        {0, gpu2mat, gpu2mat, gpu2mat, gpu2mat, gpu2mat, gpu2mat, arr2buf, 0 /*arr2tex*/, gpu2gpu, 0      },
++        {0, ocl2mat, ocl2mat, ocl2mat, ocl2mat, ocl2mat, ocl2mat, 0,       0,             0,       ocl2ocl}
      };
  
      const int src_kind = src.kind() >> _InputArray::KIND_SHIFT;
  #ifndef __OPENCV_SUPERRES_INPUT_ARRAY_UTILITY_HPP__
  #define __OPENCV_SUPERRES_INPUT_ARRAY_UTILITY_HPP__
  
 -#include "opencv2/core/core.hpp"
 -#include "opencv2/core/gpumat.hpp"
 +#include "opencv2/core.hpp"
 +#include "opencv2/core/gpu.hpp"
+ #ifdef HAVE_OPENCV_OCL
 -#include "opencv2/ocl/ocl.hpp"
++#include "opencv2/ocl.hpp"
+ #endif
  
  namespace cv
  {
@@@ -717,4 -718,196 +717,196 @@@ Ptr<DenseOpticalFlowExt> cv::superres::
      return new DualTVL1_GPU;
  }
  
 -#endif // HAVE_OPENCV_GPU
 +#endif // HAVE_OPENCV_GPUOPTFLOW
+ #ifdef HAVE_OPENCV_OCL
+ namespace
+ {
+     class oclOpticalFlow : public DenseOpticalFlowExt
+     {
+     public:
+         explicit oclOpticalFlow(int work_type);
+         void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2);
+         void collectGarbage();
+     protected:
+         virtual void impl(const cv::ocl::oclMat& input0, const cv::ocl::oclMat& input1, cv::ocl::oclMat& dst1, cv::ocl::oclMat& dst2) = 0;
+     private:
+         int work_type_;
+         cv::ocl::oclMat buf_[6];
+         cv::ocl::oclMat u_, v_, flow_;
+     };
+     oclOpticalFlow::oclOpticalFlow(int work_type) : work_type_(work_type)
+     {
+     }
+     void oclOpticalFlow::calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2)
+     {
+         ocl::oclMat& _frame0 = ocl::getOclMatRef(frame0);
+         ocl::oclMat& _frame1 = ocl::getOclMatRef(frame1);
+         ocl::oclMat& _flow1  = ocl::getOclMatRef(flow1);
+         ocl::oclMat& _flow2  = ocl::getOclMatRef(flow2);
+         CV_Assert( _frame1.type() == _frame0.type() );
+         CV_Assert( _frame1.size() == _frame0.size() );
+         cv::ocl::oclMat input0_ = convertToType(_frame0, work_type_, buf_[2], buf_[3]);
+         cv::ocl::oclMat input1_ = convertToType(_frame1, work_type_, buf_[4], buf_[5]);
+         impl(input0_, input1_, u_, v_);//go to tvl1 algorithm
+         u_.copyTo(_flow1);
+         v_.copyTo(_flow2);
+     }
+     void oclOpticalFlow::collectGarbage()
+     {
+         for (int i = 0; i < 6; ++i)
+             buf_[i].release();
+         u_.release();
+         v_.release();
+         flow_.release();
+     }
+ }
+ ///////////////////////////////////////////////////////////////////
+ // PyrLK_OCL
+ namespace
+ {
+     class PyrLK_OCL : public oclOpticalFlow
+     {
+     public:
+         AlgorithmInfo* info() const;
+         PyrLK_OCL();
+         void collectGarbage();
+     protected:
+         void impl(const ocl::oclMat& input0, const ocl::oclMat& input1, ocl::oclMat& dst1, ocl::oclMat& dst2);
+     private:
+         int winSize_;
+         int maxLevel_;
+         int iterations_;
+         ocl::PyrLKOpticalFlow alg_;
+     };
+     CV_INIT_ALGORITHM(PyrLK_OCL, "DenseOpticalFlowExt.PyrLK_OCL",
+         obj.info()->addParam(obj, "winSize", obj.winSize_);
+     obj.info()->addParam(obj, "maxLevel", obj.maxLevel_);
+     obj.info()->addParam(obj, "iterations", obj.iterations_));
+     PyrLK_OCL::PyrLK_OCL() : oclOpticalFlow(CV_8UC1)
+     {
+         winSize_ = alg_.winSize.width;
+         maxLevel_ = alg_.maxLevel;
+         iterations_ = alg_.iters;
+     }
+     void PyrLK_OCL::impl(const cv::ocl::oclMat& input0, const cv::ocl::oclMat& input1, cv::ocl::oclMat& dst1, cv::ocl::oclMat& dst2)
+     {
+         alg_.winSize.width = winSize_;
+         alg_.winSize.height = winSize_;
+         alg_.maxLevel = maxLevel_;
+         alg_.iters = iterations_;
+         alg_.dense(input0, input1, dst1, dst2);
+     }
+     void PyrLK_OCL::collectGarbage()
+     {
+         alg_.releaseMemory();
+         oclOpticalFlow::collectGarbage();
+     }
+ }
+ Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_PyrLK_OCL()
+ {
+     return new PyrLK_OCL;
+ }
+ ///////////////////////////////////////////////////////////////////
+ // DualTVL1_OCL
+ namespace
+ {
+     class DualTVL1_OCL : public oclOpticalFlow
+     {
+     public:
+         AlgorithmInfo* info() const;
+         DualTVL1_OCL();
+         void collectGarbage();
+     protected:
+         void impl(const cv::ocl::oclMat& input0, const cv::ocl::oclMat& input1, cv::ocl::oclMat& dst1, cv::ocl::oclMat& dst2);
+     private:
+         double tau_;
+         double lambda_;
+         double theta_;
+         int nscales_;
+         int warps_;
+         double epsilon_;
+         int iterations_;
+         bool useInitialFlow_;
+         ocl::OpticalFlowDual_TVL1_OCL alg_;
+     };
+     CV_INIT_ALGORITHM(DualTVL1_OCL, "DenseOpticalFlowExt.DualTVL1_OCL",
+     obj.info()->addParam(obj, "tau", obj.tau_);
+     obj.info()->addParam(obj, "lambda", obj.lambda_);
+     obj.info()->addParam(obj, "theta", obj.theta_);
+     obj.info()->addParam(obj, "nscales", obj.nscales_);
+     obj.info()->addParam(obj, "warps", obj.warps_);
+     obj.info()->addParam(obj, "epsilon", obj.epsilon_);
+     obj.info()->addParam(obj, "iterations", obj.iterations_);
+     obj.info()->addParam(obj, "useInitialFlow", obj.useInitialFlow_));
+     DualTVL1_OCL::DualTVL1_OCL() : oclOpticalFlow(CV_8UC1)
+     {
+         tau_ = alg_.tau;
+         lambda_ = alg_.lambda;
+         theta_ = alg_.theta;
+         nscales_ = alg_.nscales;
+         warps_ = alg_.warps;
+         epsilon_ = alg_.epsilon;
+         iterations_ = alg_.iterations;
+         useInitialFlow_ = alg_.useInitialFlow;
+     }
+     void DualTVL1_OCL::impl(const cv::ocl::oclMat& input0, const cv::ocl::oclMat& input1, cv::ocl::oclMat& dst1, cv::ocl::oclMat& dst2)
+     {
+         alg_.tau = tau_;
+         alg_.lambda = lambda_;
+         alg_.theta = theta_;
+         alg_.nscales = nscales_;
+         alg_.warps = warps_;
+         alg_.epsilon = epsilon_;
+         alg_.iterations = iterations_;
+         alg_.useInitialFlow = useInitialFlow_;
+         alg_(input0, input1, dst1, dst2);
+     }
+     void DualTVL1_OCL::collectGarbage()
+     {
+         alg_.collectGarbage();
+         oclOpticalFlow::collectGarbage();
+     }
+ }
+ Ptr<DenseOpticalFlowExt> cv::superres::createOptFlow_DualTVL1_OCL()
+ {
+     return new DualTVL1_OCL;
+ }
 -#endif
++#endif
  #include <vector>
  #include <limits>
  
 -#ifdef HAVE_CVCONFIG_H
 -  #include "cvconfig.h"
 -#endif
 -
  #include "opencv2/opencv_modules.hpp"
 -#include "opencv2/core/core.hpp"
 -#include "opencv2/core/gpumat.hpp"
 -#include "opencv2/core/opengl_interop.hpp"
 -#include "opencv2/core/internal.hpp"
 -#include "opencv2/imgproc/imgproc.hpp"
 +#include "opencv2/core.hpp"
 +#include "opencv2/core/gpu.hpp"
 +#include "opencv2/core/opengl.hpp"
 +#include "opencv2/core/utility.hpp"
 +#include "opencv2/imgproc.hpp"
  #include "opencv2/video/tracking.hpp"
 +#include "opencv2/core/private.hpp"
 +
 +#include "opencv2/core/private.gpu.hpp"
 +
 +#ifdef HAVE_OPENCV_GPUARITHM
 +#  include "opencv2/gpuarithm.hpp"
 +#endif
 +
 +#ifdef HAVE_OPENCV_GPUWARPING
 +#  include "opencv2/gpuwarping.hpp"
 +#endif
  
 -#ifdef HAVE_OPENCV_GPU
 -    #include "opencv2/gpu/gpu.hpp"
 -    #ifdef HAVE_CUDA
 -        #include "opencv2/gpu/stream_accessor.hpp"
 -    #endif
 +#ifdef HAVE_OPENCV_GPUFILTERS
 +#  include "opencv2/gpufilters.hpp"
 +#endif
 +
 +#ifdef HAVE_OPENCV_GPUIMGPROC
 +#  include "opencv2/gpuimgproc.hpp"
 +#endif
 +
 +#ifdef HAVE_OPENCV_GPUOPTFLOW
 +#  include "opencv2/gpuoptflow.hpp"
 +#endif
 +
 +#ifdef HAVE_OPENCV_GPUCODEC
 +#  include "opencv2/gpucodec.hpp"
  #endif
  
+ #ifdef HAVE_OPENCV_OCL
+     #include "opencv2/ocl/private/util.hpp"
+ #endif
  #ifdef HAVE_OPENCV_HIGHGUI
 -    #include "opencv2/highgui/highgui.hpp"
 +    #include "opencv2/highgui.hpp"
  #endif
  
 -#include "opencv2/superres/superres.hpp"
 +#include "opencv2/superres.hpp"
  #include "opencv2/superres/optical_flow.hpp"
  #include "input_array_utility.hpp"
  
index f4ff827,0000000..f41b421
mode 100644,000000..100644
--- /dev/null
@@@ -1,556 -1,0 +1,563 @@@
 +#ifndef __OPENCV_GTESTCV_HPP__
 +#define __OPENCV_GTESTCV_HPP__
 +
 +#include "opencv2/core/cvdef.h"
 +#include <stdarg.h> // for va_list
 +
 +#include "cvconfig.h"
 +
 +#ifndef GTEST_CREATE_SHARED_LIBRARY
 +#ifdef BUILD_SHARED_LIBS
 +#define GTEST_LINKED_AS_SHARED_LIBRARY 1
 +#endif
 +#endif
 +
 +#ifdef _MSC_VER
 +#pragma warning( disable: 4127 )
 +#endif
 +
 +#define GTEST_DONT_DEFINE_FAIL      0
 +#define GTEST_DONT_DEFINE_SUCCEED   0
 +#define GTEST_DONT_DEFINE_ASSERT_EQ 0
 +#define GTEST_DONT_DEFINE_ASSERT_NE 0
 +#define GTEST_DONT_DEFINE_ASSERT_LE 0
 +#define GTEST_DONT_DEFINE_ASSERT_LT 0
 +#define GTEST_DONT_DEFINE_ASSERT_GE 0
 +#define GTEST_DONT_DEFINE_ASSERT_GT 0
 +#define GTEST_DONT_DEFINE_TEST      0
 +
 +#include "opencv2/ts/ts_gtest.h"
 +
 +#ifndef GTEST_USES_SIMPLE_RE
 +#  define GTEST_USES_SIMPLE_RE 0
 +#endif
 +#ifndef GTEST_USES_POSIX_RE
 +#  define GTEST_USES_POSIX_RE 0
 +#endif
 +
 +#include "opencv2/core.hpp"
 +#include "opencv2/core/utility.hpp"
 +
 +namespace cvtest
 +{
 +
 +using std::vector;
 +using std::string;
 +using cv::RNG;
 +using cv::Mat;
 +using cv::Scalar;
 +using cv::Size;
 +using cv::Point;
 +using cv::Rect;
 +
 +class CV_EXPORTS TS;
 +
 +CV_EXPORTS int64 readSeed(const char* str);
 +
 +CV_EXPORTS void randUni( RNG& rng, Mat& a, const Scalar& param1, const Scalar& param2 );
 +
 +inline unsigned randInt( RNG& rng )
 +{
 +    return (unsigned)rng;
 +}
 +
 +inline  double randReal( RNG& rng )
 +{
 +    return (double)rng;
 +}
 +
 +
 +CV_EXPORTS const char* getTypeName( int type );
 +CV_EXPORTS int typeByName( const char* type_name );
 +
 +CV_EXPORTS string vec2str(const string& sep, const int* v, size_t nelems);
 +
 +inline int clipInt( int val, int min_val, int max_val )
 +{
 +    if( val < min_val )
 +        val = min_val;
 +    if( val > max_val )
 +        val = max_val;
 +    return val;
 +}
 +
 +CV_EXPORTS double getMinVal(int depth);
 +CV_EXPORTS double getMaxVal(int depth);
 +
 +CV_EXPORTS Size randomSize(RNG& rng, double maxSizeLog);
 +CV_EXPORTS void randomSize(RNG& rng, int minDims, int maxDims, double maxSizeLog, vector<int>& sz);
 +CV_EXPORTS int randomType(RNG& rng, int typeMask, int minChannels, int maxChannels);
 +CV_EXPORTS Mat randomMat(RNG& rng, Size size, int type, double minVal, double maxVal, bool useRoi);
 +CV_EXPORTS Mat randomMat(RNG& rng, const vector<int>& size, int type, double minVal, double maxVal, bool useRoi);
 +CV_EXPORTS void add(const Mat& a, double alpha, const Mat& b, double beta,
 +                      Scalar gamma, Mat& c, int ctype, bool calcAbs=false);
 +CV_EXPORTS void multiply(const Mat& a, const Mat& b, Mat& c, double alpha=1);
 +CV_EXPORTS void divide(const Mat& a, const Mat& b, Mat& c, double alpha=1);
 +
 +CV_EXPORTS void convert(const Mat& src, cv::OutputArray dst, int dtype, double alpha=1, double beta=0);
 +CV_EXPORTS void copy(const Mat& src, Mat& dst, const Mat& mask=Mat(), bool invertMask=false);
 +CV_EXPORTS void set(Mat& dst, const Scalar& gamma, const Mat& mask=Mat());
 +
 +// working with multi-channel arrays
 +CV_EXPORTS void extract( const Mat& a, Mat& plane, int coi );
 +CV_EXPORTS void insert( const Mat& plane, Mat& a, int coi );
 +
 +// checks that the array does not have NaNs and/or Infs and all the elements are
 +// within [min_val,max_val). idx is the index of the first "bad" element.
 +CV_EXPORTS int check( const Mat& data, double min_val, double max_val, vector<int>* idx );
 +
 +// modifies values that are close to zero
 +CV_EXPORTS void  patchZeros( Mat& mat, double level );
 +
 +CV_EXPORTS void transpose(const Mat& src, Mat& dst);
 +CV_EXPORTS void erode(const Mat& src, Mat& dst, const Mat& _kernel, Point anchor=Point(-1,-1),
 +                      int borderType=0, const Scalar& borderValue=Scalar());
 +CV_EXPORTS void dilate(const Mat& src, Mat& dst, const Mat& _kernel, Point anchor=Point(-1,-1),
 +                       int borderType=0, const Scalar& borderValue=Scalar());
 +CV_EXPORTS void filter2D(const Mat& src, Mat& dst, int ddepth, const Mat& kernel,
 +                         Point anchor, double delta, int borderType,
 +                         const Scalar& borderValue=Scalar());
 +CV_EXPORTS void copyMakeBorder(const Mat& src, Mat& dst, int top, int bottom, int left, int right,
 +                               int borderType, const Scalar& borderValue=Scalar());
 +CV_EXPORTS Mat calcSobelKernel2D( int dx, int dy, int apertureSize, int origin=0 );
 +CV_EXPORTS Mat calcLaplaceKernel2D( int aperture_size );
 +
 +CV_EXPORTS void initUndistortMap( const Mat& a, const Mat& k, Size sz, Mat& mapx, Mat& mapy );
 +
 +CV_EXPORTS void minMaxLoc(const Mat& src, double* minval, double* maxval,
 +                          vector<int>* minloc, vector<int>* maxloc, const Mat& mask=Mat());
 +CV_EXPORTS double norm(const Mat& src, int normType, const Mat& mask=Mat());
 +CV_EXPORTS double norm(const Mat& src1, const Mat& src2, int normType, const Mat& mask=Mat());
 +CV_EXPORTS Scalar mean(const Mat& src, const Mat& mask=Mat());
 +
 +CV_EXPORTS bool cmpUlps(const Mat& data, const Mat& refdata, int expMaxDiff, double* realMaxDiff, vector<int>* idx);
 +
 +// compares two arrays. max_diff is the maximum actual difference,
 +// success_err_level is maximum allowed difference, idx is the index of the first
 +// element for which difference is >success_err_level
 +// (or index of element with the maximum difference)
 +CV_EXPORTS int cmpEps( const Mat& data, const Mat& refdata, double* max_diff,
 +                       double success_err_level, vector<int>* idx,
 +                       bool element_wise_relative_error );
 +
 +// a wrapper for the previous function. in case of error prints the message to log file.
 +CV_EXPORTS int cmpEps2( TS* ts, const Mat& data, const Mat& refdata, double success_err_level,
 +                        bool element_wise_relative_error, const char* desc );
 +
 +CV_EXPORTS int cmpEps2_64f( TS* ts, const double* val, const double* refval, int len,
 +                        double eps, const char* param_name );
 +
 +CV_EXPORTS void logicOp(const Mat& src1, const Mat& src2, Mat& dst, char c);
 +CV_EXPORTS void logicOp(const Mat& src, const Scalar& s, Mat& dst, char c);
 +CV_EXPORTS void min(const Mat& src1, const Mat& src2, Mat& dst);
 +CV_EXPORTS void min(const Mat& src, double s, Mat& dst);
 +CV_EXPORTS void max(const Mat& src1, const Mat& src2, Mat& dst);
 +CV_EXPORTS void max(const Mat& src, double s, Mat& dst);
 +
 +CV_EXPORTS void compare(const Mat& src1, const Mat& src2, Mat& dst, int cmpop);
 +CV_EXPORTS void compare(const Mat& src, double s, Mat& dst, int cmpop);
 +CV_EXPORTS void gemm(const Mat& src1, const Mat& src2, double alpha,
 +                     const Mat& src3, double beta, Mat& dst, int flags);
 +    CV_EXPORTS void transform( const Mat& src, Mat& dst, const Mat& transmat, const Mat& shift );
 +CV_EXPORTS double crossCorr(const Mat& src1, const Mat& src2);
 +
 +struct CV_EXPORTS MatInfo
 +{
 +    MatInfo(const Mat& _m) : m(&_m) {}
 +    const Mat* m;
 +};
 +
 +CV_EXPORTS std::ostream& operator << (std::ostream& out, const MatInfo& m);
 +
 +struct CV_EXPORTS MatComparator
 +{
 +public:
 +    MatComparator(double maxdiff, int context);
 +
 +    ::testing::AssertionResult operator()(const char* expr1, const char* expr2,
 +                                          const Mat& m1, const Mat& m2);
 +
 +    double maxdiff;
 +    double realmaxdiff;
 +    vector<int> loc0;
 +    int context;
 +};
 +
 +
 +
 +class BaseTest;
 +class TS;
 +
 +class CV_EXPORTS BaseTest
 +{
 +public:
 +    // constructor(s) and destructor
 +    BaseTest();
 +    virtual ~BaseTest();
 +
 +    // the main procedure of the test
 +    virtual void run( int start_from );
 +
 +    // the wrapper for run that cares of exceptions
 +    virtual void safe_run( int start_from=0 );
 +
 +    const string& get_name() const { return name; }
 +
 +    // returns true if and only if the different test cases do not depend on each other
 +    // (so that test system could get right to a problematic test case)
 +    virtual bool can_do_fast_forward();
 +
 +    // deallocates all the memory.
 +    // called by init() (before initialization) and by the destructor
 +    virtual void clear();
 +
 +protected:
 +    int test_case_count; // the total number of test cases
 +
 +    // read test params
 +    virtual int read_params( CvFileStorage* fs );
 +
 +    // returns the number of tests or -1 if it is unknown a-priori
 +    virtual int get_test_case_count();
 +
 +    // prepares data for the next test case. rng seed is updated by the function
 +    virtual int prepare_test_case( int test_case_idx );
 +
 +    // checks if the test output is valid and accurate
 +    virtual int validate_test_results( int test_case_idx );
 +
 +    // calls the tested function. the method is called from run_test_case()
 +    virtual void run_func(); // runs tested func(s)
 +
 +    // updates progress bar
 +    virtual int update_progress( int progress, int test_case_idx, int count, double dt );
 +
 +    // finds test parameter
 +    const CvFileNode* find_param( CvFileStorage* fs, const char* param_name );
 +
 +    // name of the test (it is possible to locate a test by its name)
 +    string name;
 +
 +    // pointer to the system that includes the test
 +    TS* ts;
 +};
 +
 +
 +/*****************************************************************************************\
 +*                               Information about a failed test                           *
 +\*****************************************************************************************/
 +
 +struct TestInfo
 +{
 +    TestInfo();
 +
 +    // pointer to the test
 +    BaseTest* test;
 +
 +    // failure code (CV_FAIL*)
 +    int code;
 +
 +    // seed value right before the data for the failed test case is prepared.
 +    uint64 rng_seed;
 +
 +    // seed value right before running the test
 +    uint64 rng_seed0;
 +
 +    // index of test case, can be then passed to BaseTest::proceed_to_test_case()
 +    int test_case_idx;
 +};
 +
 +/*****************************************************************************************\
 +*                                 Base Class for test system                              *
 +\*****************************************************************************************/
 +
 +// common parameters:
 +struct CV_EXPORTS TSParams
 +{
 +    TSParams();
 +
 +    // RNG seed, passed to and updated by every test executed.
 +    uint64 rng_seed;
 +
 +    // whether to use IPP, MKL etc. or not
 +    bool use_optimized;
 +
 +    // extensivity of the tests, scale factor for test_case_count
 +    double test_case_count_scale;
 +};
 +
 +
 +class CV_EXPORTS TS
 +{
 +public:
 +    // constructor(s) and destructor
 +    TS();
 +    virtual ~TS();
 +
 +    enum
 +    {
 +        NUL=0,
 +        SUMMARY_IDX=0,
 +        SUMMARY=1 << SUMMARY_IDX,
 +        LOG_IDX=1,
 +        LOG=1 << LOG_IDX,
 +        CSV_IDX=2,
 +        CSV=1 << CSV_IDX,
 +        CONSOLE_IDX=3,
 +        CONSOLE=1 << CONSOLE_IDX,
 +        MAX_IDX=4
 +    };
 +
 +    static TS* ptr();
 +
 +    // initialize test system before running the first test
 +    virtual void init( const string& modulename );
 +
 +    // low-level printing functions that are used by individual tests and by the system itself
 +    virtual void printf( int streams, const char* fmt, ... );
 +    virtual void vprintf( int streams, const char* fmt, va_list arglist );
 +
 +    // updates the context: current test, test case, rng state
 +    virtual void update_context( BaseTest* test, int test_case_idx, bool update_ts_context );
 +
 +    const TestInfo* get_current_test_info() { return &current_test_info; }
 +
 +    // sets information about a failed test
 +    virtual void set_failed_test_info( int fail_code );
 +
 +    virtual void set_gtest_status();
 +
 +    // test error codes
 +    enum
 +    {
 +        // everything is Ok
 +        OK=0,
 +
 +        // generic error: stub value to be used
 +        // temporarily if the error's cause is unknown
 +        FAIL_GENERIC=-1,
 +
 +        // the test is missing some essential data to proceed further
 +        FAIL_MISSING_TEST_DATA=-2,
 +
 +        // the tested function raised an error via cxcore error handler
 +        FAIL_ERROR_IN_CALLED_FUNC=-3,
 +
 +        // an exception has been raised;
 +        // for memory and arithmetic exception
 +        // there are two specialized codes (see below...)
 +        FAIL_EXCEPTION=-4,
 +
 +        // a memory exception
 +        // (access violation, access to missed page, stack overflow etc.)
 +        FAIL_MEMORY_EXCEPTION=-5,
 +
 +        // arithmetic exception (overflow, division by zero etc.)
 +        FAIL_ARITHM_EXCEPTION=-6,
 +
 +        // the tested function corrupted memory (no exception have been raised)
 +        FAIL_MEMORY_CORRUPTION_BEGIN=-7,
 +        FAIL_MEMORY_CORRUPTION_END=-8,
 +
 +        // the tested function (or test ifself) do not deallocate some memory
 +        FAIL_MEMORY_LEAK=-9,
 +
 +        // the tested function returned invalid object, e.g. matrix, containing NaNs,
 +        // structure with NULL or out-of-range fields (while it should not)
 +        FAIL_INVALID_OUTPUT=-10,
 +
 +        // the tested function returned valid object, but it does not match to
 +        // the original (or produced by the test) object
 +        FAIL_MISMATCH=-11,
 +
 +        // the tested function returned valid object (a single number or numerical array),
 +        // but it differs too much from the original (or produced by the test) object
 +        FAIL_BAD_ACCURACY=-12,
 +
 +        // the tested function hung. Sometimes, can be determined by unexpectedly long
 +        // processing time (in this case there should be possibility to interrupt such a function
 +        FAIL_HANG=-13,
 +
 +        // unexpected responce on passing bad arguments to the tested function
 +        // (the function crashed, proceed succesfully (while it should not), or returned
 +        // error code that is different from what is expected)
 +        FAIL_BAD_ARG_CHECK=-14,
 +
 +        // the test data (in whole or for the particular test case) is invalid
 +        FAIL_INVALID_TEST_DATA=-15,
 +
 +        // the test has been skipped because it is not in the selected subset of the tests to run,
 +        // because it has been run already within the same run with the same parameters, or because
 +        // of some other reason and this is not considered as an error.
 +        // Normally TS::run() (or overrided method in the derived class) takes care of what
 +        // needs to be run, so this code should not occur.
 +        SKIPPED=1
 +    };
 +
 +    // get file storage
 +    CvFileStorage* get_file_storage();
 +
 +    // get RNG to generate random input data for a test
 +    RNG& get_rng() { return rng; }
 +
 +    // returns the current error code
 +    int get_err_code() { return current_test_info.code; }
 +
 +    // returns the test extensivity scale
 +    double get_test_case_count_scale() { return params.test_case_count_scale; }
 +
 +    const string& get_data_path() const { return data_path; }
 +
 +    // returns textual description of failure code
 +    static string str_from_code( int code );
 +
 +protected:
 +
 +    // these are allocated within a test to try keep them valid in case of stack corruption
 +    RNG rng;
 +
 +    // information about the current test
 +    TestInfo current_test_info;
 +
 +    // the path to data files used by tests
 +    string data_path;
 +
 +    TSParams params;
 +    std::string output_buf[MAX_IDX];
 +};
 +
 +
 +/*****************************************************************************************\
 +*            Subclass of BaseTest for testing functions that process dense arrays           *
 +\*****************************************************************************************/
 +
 +class CV_EXPORTS ArrayTest : public BaseTest
 +{
 +public:
 +    // constructor(s) and destructor
 +    ArrayTest();
 +    virtual ~ArrayTest();
 +
 +    virtual void clear();
 +
 +protected:
 +
 +    virtual int read_params( CvFileStorage* fs );
 +    virtual int prepare_test_case( int test_case_idx );
 +    virtual int validate_test_results( int test_case_idx );
 +
 +    virtual void prepare_to_validation( int test_case_idx );
 +    virtual void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
 +    virtual void fill_array( int test_case_idx, int i, int j, Mat& arr );
 +    virtual void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high );
 +    virtual double get_success_error_level( int test_case_idx, int i, int j );
 +
 +    bool cvmat_allowed;
 +    bool iplimage_allowed;
 +    bool optional_mask;
 +    bool element_wise_relative_error;
 +
 +    int min_log_array_size;
 +    int max_log_array_size;
 +
 +    enum { INPUT, INPUT_OUTPUT, OUTPUT, REF_INPUT_OUTPUT, REF_OUTPUT, TEMP, MASK, MAX_ARR };
 +
 +    vector<vector<void*> > test_array;
 +    vector<vector<Mat> > test_mat;
 +    float buf[4];
 +};
 +
 +
 +class CV_EXPORTS BadArgTest : public BaseTest
 +{
 +public:
 +    // constructor(s) and destructor
 +    BadArgTest();
 +    virtual ~BadArgTest();
 +
 +protected:
 +    virtual int run_test_case( int expected_code, const string& descr );
 +    virtual void run_func(void) = 0;
 +    int test_case_idx;
 +
 +    template<class F>
 +    int run_test_case( int expected_code, const string& _descr, F f)
 +    {
 +        int errcount = 0;
 +        bool thrown = false;
 +        const char* descr = _descr.c_str() ? _descr.c_str() : "";
 +
 +        try
 +        {
 +            f();
 +        }
 +        catch(const cv::Exception& e)
 +        {
 +            thrown = true;
 +            if( e.code != expected_code )
 +            {
 +                ts->printf(TS::LOG, "%s (test case #%d): the error code %d is different from the expected %d\n",
 +                    descr, test_case_idx, e.code, expected_code);
 +                errcount = 1;
 +            }
 +        }
 +        catch(...)
 +        {
 +            thrown = true;
 +            ts->printf(TS::LOG, "%s  (test case #%d): unknown exception was thrown (the function has likely crashed)\n",
 +                       descr, test_case_idx);
 +            errcount = 1;
 +        }
 +        if(!thrown)
 +        {
 +            ts->printf(TS::LOG, "%s  (test case #%d): no expected exception was thrown\n",
 +                       descr, test_case_idx);
 +            errcount = 1;
 +        }
 +        test_case_idx++;
 +
 +        return errcount;
 +    }
 +};
 +
 +struct CV_EXPORTS DefaultRngAuto
 +{
 +    const uint64 old_state;
 +
 +    DefaultRngAuto() : old_state(cv::theRNG().state) { cv::theRNG().state = (uint64)-1; }
 +    ~DefaultRngAuto() { cv::theRNG().state = old_state; }
 +
 +    DefaultRngAuto& operator=(const DefaultRngAuto&);
 +};
 +
 +}
 +
 +namespace cvtest
 +{
 +
 +// test images generation functions
 +CV_EXPORTS void fillGradient(Mat& img, int delta = 5);
 +CV_EXPORTS void smoothBorder(Mat& img, const Scalar& color, int delta = 3);
 +
 +CV_EXPORTS void printVersionInfo(bool useStdOut = true);
 +} //namespace cvtest
 +
 +#define CV_TEST_MAIN(resourcesubdir) \
 +int main(int argc, char **argv) \
 +{ \
 +    cvtest::TS::ptr()->init(resourcesubdir); \
 +    ::testing::InitGoogleTest(&argc, argv); \
 +    cvtest::printVersionInfo();\
 +    return RUN_ALL_TESTS(); \
 +}
 +
++// This usually only makes sense in perf tests with several implementations,
++// some of which are not available.
++#define CV_TEST_FAIL_NO_IMPL() do { \
++    ::testing::Test::RecordProperty("custom_status", "noimpl"); \
++    FAIL() << "No equivalent implementation."; \
++} while (0)
++
 +#endif
 +
 +#include "opencv2/ts/ts_perf.hpp"