-/*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
-//
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
// 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 "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/objdetect.hpp"
+#include "opencv2/ml.hpp"
namespace cv
{
namespace ocl
{
- enum
+ enum DeviceType
{
CVCL_DEVICE_TYPE_DEFAULT = (1 << 0),
CVCL_DEVICE_TYPE_CPU = (1 << 1),
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);
+ // these classes contain OpenCL runtime information
- //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);
+ struct PlatformInfo;
- //this class contains ocl runtime information
- class CV_EXPORTS Info
+ struct DeviceInfo
{
public:
- struct Impl;
- Impl *impl;
+ int _id; // reserved, don't use it
- Info();
- Info(const Info &m);
- ~Info();
- void release();
- Info &operator = (const Info &m);
- std::vector<String> DeviceName;
- String PlatformName;
+ DeviceType deviceType;
+ std::string deviceProfile;
+ std::string deviceVersion;
+ std::string deviceName;
+ std::string deviceVendor;
+ int deviceVendorId;
+ std::string deviceDriverVersion;
+ std::string deviceExtensions;
+
+ size_t maxWorkGroupSize;
+ std::vector<size_t> maxWorkItemSizes;
+ int maxComputeUnits;
+ size_t localMemorySize;
+ size_t maxMemAllocSize;
+
+ int deviceVersionMajor;
+ int deviceVersionMinor;
+
+ bool haveDoubleSupport;
+ bool isUnifiedMemory; // 1 means integrated GPU, otherwise this value is 0
+ bool isIntelDevice;
+
+ std::string compilationExtraOptions;
+
+ const PlatformInfo* platform;
+
+ DeviceInfo();
+ ~DeviceInfo();
};
+
+ struct PlatformInfo
+ {
+ int _id; // reserved, don't use it
+
+ std::string platformProfile;
+ std::string platformVersion;
+ std::string platformName;
+ std::string platformVendor;
+ std::string platformExtensons;
+
+ int platformVersionMajor;
+ int platformVersionMinor;
+
+ std::vector<const DeviceInfo*> devices;
+
+ PlatformInfo();
+ ~PlatformInfo();
+ };
+
//////////////////////////////// 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();
+ typedef std::vector<const PlatformInfo*> PlatformsInfo;
+
+ CV_EXPORTS int getOpenCLPlatforms(PlatformsInfo& platforms);
+
+ typedef std::vector<const DeviceInfo*> DevicesInfo;
+
+ CV_EXPORTS int getOpenCLDevices(DevicesInfo& devices, int deviceType = CVCL_DEVICE_TYPE_GPU,
+ const PlatformInfo* platform = NULL);
- //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);
+ // set device you want to use
+ CV_EXPORTS void setDevice(const DeviceInfo* info);
- //returns true when global OpenCL context is initialized
- CV_EXPORTS bool initialized();
+ // Initialize from OpenCL handles directly.
+ // Argument types is (pointers): cl_platform_id*, cl_context*, cl_device_id*
+ CV_EXPORTS void initializeContext(void* pClPlatform, void* pClContext, void* pClDevice);
- //////////////////////////////// OpenCL context ////////////////////////
- //This is a global singleton class used to represent a OpenCL context.
+ enum FEATURE_TYPE
+ {
+ FEATURE_CL_DOUBLE = 1,
+ FEATURE_CL_UNIFIED_MEM,
+ FEATURE_CL_VER_1_2,
+ FEATURE_CL_INTEL_DEVICE
+ };
+
+ // Represents OpenCL context, interface
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;
+ Context() { }
+ ~Context() { }
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();
+
+ bool supportsFeature(FEATURE_TYPE featureType) const;
+ const DeviceInfo& getDeviceInfo() const;
+
+ const void* getOpenCLContextPtr() const;
+ const void* getOpenCLCommandQueuePtr() const;
+ const void* getOpenCLDeviceIDPtr() const;
};
- //! 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);
+ inline const void *getClContextPtr()
+ {
+ return Context::getContext()->getOpenCLContextPtr();
+ }
+
+ inline const void *getClCommandQueuePtr()
+ {
+ return Context::getContext()->getOpenCLCommandQueuePtr();
+ }
+
+ CV_EXPORTS bool supportsFeature(FEATURE_TYPE featureType);
+
+ CV_EXPORTS void finish();
+ enum BINARY_CACHE_MODE
+ {
+ CACHE_NONE = 0, // do not cache OpenCL binary
+ CACHE_DEBUG = 0x1 << 0, // cache OpenCL binary when built in debug mode
+ CACHE_RELEASE = 0x1 << 1, // default behavior, only cache when built in release mode
+ CACHE_ALL = CACHE_DEBUG | CACHE_RELEASE, // cache opencl binary
+ };
//! 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.
- };
+ // This feature is enabled by default.
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);
+ CV_EXPORTS void setBinaryPath(const char *path);
+
+ struct ProgramSource
+ {
+ const char* name;
+ const char* programStr;
+ const char* programHash;
+
+ // Cache in memory by name (should be unique). Caching on disk disabled.
+ inline ProgramSource(const char* _name, const char* _programStr)
+ : name(_name), programStr(_programStr), programHash(NULL)
+ {
+ }
+
+ // Cache in memory by name (should be unique). Caching on disk uses programHash mark.
+ inline ProgramSource(const char* _name, const char* _programStr, const char* _programHash)
+ : name(_name), programStr(_programStr), programHash(_programHash)
+ {
+ }
+ };
+
+ //! Calls OpenCL kernel. Pass globalThreads = NULL, and cleanUp = true, to finally clean-up without executing.
+ //! Deprecated, will be replaced
+ CV_EXPORTS void openCLExecuteKernelInterop(Context *clCxt,
+ const cv::ocl::ProgramSource& 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);
class CV_EXPORTS oclMatExpr;
//////////////////////////////// oclMat ////////////////////////////////
//! returns deep copy of the oclMatrix, i.e. the data is copied
oclMat clone() const;
- //! copies the oclMatrix content to "m".
+
+ //! copies those oclMatrix elements to "m" that are marked with non-zero mask elements.
// 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;
+ void copyTo( oclMat &m, const oclMat &mask = oclMat()) 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.
//! 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);
+ DevMemRW rw_type, DevMemType mem_type);
void createEx(Size size, int type, DevMemRW rw_type,
- DevMemType mem_type, void* hptr = 0);
+ DevMemType mem_type);
//! decreases reference counter;
// deallocate the data when reference counter reaches 0.
//! 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;
uchar *dataend;
//! OpenCL context associated with the oclMat object.
- Context *clCxt;
+ Context *clCxt; // TODO clCtx
//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
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);
+
+ //! adds one matrix to another with scale (dst = src1 * alpha + src2 * beta + gama)
+ // supports all data types
+ CV_EXPORTS void addWeighted(const oclMat &src1, double alpha, const oclMat &src2, double beta, double gama, oclMat &dst);
+
+ //! adds one matrix to another (dst = src1 + src2)
+ // supports all data types
+ CV_EXPORTS void add(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask = oclMat());
+ //! adds scalar to a matrix (dst = src1 + s)
+ // supports all data types
+ CV_EXPORTS void add(const oclMat &src1, const Scalar &s, oclMat &dst, const oclMat &mask = oclMat());
+
+ //! subtracts one matrix from another (dst = src1 - src2)
+ // supports all data types
+ CV_EXPORTS void subtract(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask = oclMat());
+ //! subtracts scalar from a matrix (dst = src1 - s)
+ // supports all data types
+ CV_EXPORTS void subtract(const oclMat &src1, const Scalar &s, oclMat &dst, const oclMat &mask = oclMat());
+
+ //! computes element-wise product of the two arrays (dst = src1 * scale * src2)
+ // supports all data types
+ CV_EXPORTS void multiply(const oclMat &src1, const oclMat &src2, oclMat &dst, double scale = 1);
//! multiplies matrix to a number (dst = scalar * src)
- // supports CV_32FC1 only
+ // supports all data types
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);
+ //! computes element-wise quotient of the two arrays (dst = src1 * scale / src2)
+ // supports all data types
+ CV_EXPORTS void divide(const oclMat &src1, const oclMat &src2, oclMat &dst, double scale = 1);
+ //! computes element-wise quotient of the two arrays (dst = scale / src)
+ // supports all data types
+ CV_EXPORTS void divide(double scale, const oclMat &src1, oclMat &dst);
+
+ //! computes element-wise minimum of the two arrays (dst = min(src1, src2))
+ // supports all data types
+ CV_EXPORTS void min(const oclMat &src1, const oclMat &src2, oclMat &dst);
+
+ //! computes element-wise maximum of the two arrays (dst = max(src1, src2))
+ // supports all data types
+ CV_EXPORTS void max(const oclMat &src1, const oclMat &src2, oclMat &dst);
+
+ //! compares elements of two arrays (dst = src1 <cmpop> src2)
+ // supports all data types
+ CV_EXPORTS void compare(const oclMat &src1, const oclMat &src2, oclMat &dst, int cmpop);
//! transposes the matrix
- // supports CV_8UC1, 8UC4, 8SC4, 16UC2, 16SC2, 32SC1 and 32FC1.(the same as cuda)
+ // supports all data types
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 element-wise absolute values of an array (dst = abs(src))
+ // supports all data types
+ CV_EXPORTS void abs(const oclMat &src, oclMat &dst);
+
+ //! computes element-wise absolute difference of two arrays (dst = abs(src1 - src2))
+ // supports all data types
+ CV_EXPORTS void absdiff(const oclMat &src1, const oclMat &src2, oclMat &dst);
+ //! computes element-wise absolute difference of array and scalar (dst = abs(src1 - s))
+ // supports all data types
+ CV_EXPORTS void absdiff(const oclMat &src1, const Scalar &s, oclMat &dst);
//! computes mean value and standard deviation of all or selected array elements
- // supports except CV_32F,CV_64F
+ // supports all data types
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
+ // supports all data types
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
+ // supports all data types
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);
+ CV_EXPORTS void flip(const oclMat &src, oclMat &dst, 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);
//! 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());
//! 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);
+ CV_EXPORTS void bilateralFilter(const oclMat& src, oclMat& dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT);
- //! 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);
+ //! Applies an adaptive bilateral filter to the input image
+ // Unlike the usual bilateral filter that uses fixed value for sigmaColor,
+ // the adaptive version calculates the local variance in he ksize neighborhood
+ // and use this as sigmaColor, for the value filtering. However, the local standard deviation is
+ // clamped to the maxSigmaColor.
+ // supports 8UC1, 8UC3
+ CV_EXPORTS void adaptiveBilateralFilter(const oclMat& src, oclMat& dst, Size ksize, double sigmaSpace, double maxSigmaColor=20.0, Point anchor = Point(-1, -1), int borderType=BORDER_DEFAULT);
+
+ //! computes exponent of each matrix element (dst = e**src)
+ // supports only CV_32FC1, CV_64FC1 type
+ CV_EXPORTS void exp(const oclMat &src, oclMat &dst);
+
+ //! computes natural logarithm of absolute value of each matrix element: dst = log(abs(src))
+ // supports only CV_32FC1, CV_64FC1 type
+ CV_EXPORTS void log(const oclMat &src, oclMat &dst);
+
+ //! computes square root of each matrix element
+ // supports only CV_32FC1, CV_64FC1 type
+ CV_EXPORTS void sqrt(const oclMat &src, oclMat &dst);
//! computes magnitude of each (x(i), y(i)) vector
- // supports only CV_32F CV_64F type
+ // 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
+ // 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
+ // support only CV_32F, CV_64F type
CV_EXPORTS void pow(const oclMat &x, double p, oclMat &y);
//! converts Cartesian coordinates to polar
//! 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());
};
//! computes convolution of two images, may use discrete Fourier transform
- //! support only CV_32FC1 type
+ // 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);
//! 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);
+ CV_EXPORTS void cvtColor(const oclMat &src, oclMat &dst, int code, int dcn = 0);
+
+ //! initializes a scaled identity matrix
+ CV_EXPORTS void setIdentity(oclMat& src, const Scalar & val = Scalar(1));
+
+ //! fills the output array with repeated copies of the input array
+ CV_EXPORTS void repeat(const oclMat & src, int ny, int nx, oclMat & dst);
//////////////////////////////// Filter Engine ////////////////////////////////
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);
+ // supports only ksize = 1 and ksize = 3
+ CV_EXPORTS void Laplacian(const oclMat &src, oclMat &dst, int ddepth, int ksize = 1, double scale = 1,
+ double delta=0, int borderType=BORDER_DEFAULT);
//! returns 2D box filter
- // supports CV_8UC1 and CV_8UC4 source type, dst type must be the same as 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);
const Point &anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
//! returns 2D filter with the specified kernel
- // supports CV_8UC1 and CV_8UC4 types
+ // supports: dst type must be the same as source type
CV_EXPORTS Ptr<BaseFilter_GPU> getLinearFilter_GPU(int srcType, int dstType, const Mat &kernel, const Size &ksize,
const Point &anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
//! returns the non-separable linear filter engine
+ // supports: dst type must be the same as source type
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);
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)
{
}
//! 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);
+ Point anchor = Point(-1, -1), double delta = 0.0, 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,
//! 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
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.
+ // The source 1- or 4-channel image. m should be 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
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
+ // sum will support CV_32S, CV_32F, sqsum - support CV32F, CV_64F
// 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 integral(const oclMat &src, oclMat &sum, oclMat &sqsum, int sdepth=-1 );
+ CV_EXPORTS void integral(const oclMat &src, oclMat &sum, int sdepth=-1 );
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);
//! 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 ¢ers);
+ // supports NORM_L1 and NORM_L2 distType
+ // if indices is provided, only the indexed rows will be calculated and their results are in the same
+ // order of indices
+ CV_EXPORTS void distanceToCenters(const oclMat &src, const oclMat ¢ers, Mat &dists, Mat &labels, int distType = NORM_L2SQR);
//!Does k-means procedure on GPU
// supports CV_32FC1/CV_32FC2/CV_32FC4 data type
{
public:
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());
+ double scaleFactor = 1.1, int minNeighbors = 3, int flags = 0,
+ Size minSize = Size(), Size maxSize = Size());
};
/////////////////////////////// Pyramid /////////////////////////////////////
struct CV_EXPORTS CannyBuf
{
- CannyBuf() : counter(NULL) {}
+ CannyBuf() : counter(1, 1, CV_32S) { }
~CannyBuf()
{
release();
}
- explicit CannyBuf(const Size &image_size, int apperture_size = 3) : counter(NULL)
+ explicit CannyBuf(const Size &image_size, int apperture_size = 3) : counter(1, 1, CV_32S)
{
create(image_size, apperture_size);
}
oclMat dx_buf, dy_buf;
oclMat magBuf, mapBuf;
oclMat trackBuf1, trackBuf2;
- void *counter;
+ oclMat counter;
Ptr<FilterEngine_GPU> filterDX, filterDY;
};
// 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);
+ CV_EXPORTS void dft(const oclMat &src, oclMat &dst, Size dft_size = Size(), int flags = 0);
//! implements generalized matrix product algorithm GEMM from BLAS
// The functionality requires clAmdBlas library
harrisK = harrisK_;
}
+ ////////////////////////////////// FAST Feature Detector //////////////////////////////////
+ class CV_EXPORTS FAST_OCL
+ {
+ public:
+ enum
+ {
+ X_ROW = 0,
+ Y_ROW,
+ RESPONSE_ROW,
+ ROWS_COUNT
+ };
+
+ // all features have same size
+ static const int FEATURE_SIZE = 7;
+
+ explicit FAST_OCL(int threshold, bool nonmaxSupression = true, double keypointsRatio = 0.05);
+
+ //! finds the keypoints using FAST detector
+ //! supports only CV_8UC1 images
+ void operator ()(const oclMat& image, const oclMat& mask, oclMat& keypoints);
+ void operator ()(const oclMat& image, const oclMat& mask, std::vector<KeyPoint>& keypoints);
+
+ //! download keypoints from device to host memory
+ static void downloadKeypoints(const oclMat& d_keypoints, std::vector<KeyPoint>& keypoints);
+
+ //! convert keypoints to KeyPoint vector
+ static void convertKeypoints(const Mat& h_keypoints, std::vector<KeyPoint>& keypoints);
+
+ //! release temporary buffer's memory
+ void release();
+
+ bool nonmaxSupression;
+
+ int threshold;
+
+ //! max keypoints = keypointsRatio * img.size().area()
+ double keypointsRatio;
+
+ //! find keypoints and compute it's response if nonmaxSupression is true
+ //! return count of detected keypoints
+ int calcKeyPointsLocation(const oclMat& image, const oclMat& mask);
+
+ //! get final array of keypoints
+ //! performs nonmax supression if needed
+ //! return final count of keypoints
+ int getKeyPoints(oclMat& keypoints);
+
+ private:
+ oclMat kpLoc_;
+ int count_;
+
+ oclMat score_;
+
+ oclMat d_keypoints_;
+
+ int calcKeypointsOCL(const oclMat& img, const oclMat& mask, int maxKeypoints);
+ int nonmaxSupressionOCL(oclMat& keypoints);
+ };
+
/////////////////////////////// PyrLKOpticalFlow /////////////////////////////////////
class CV_EXPORTS PyrLKOpticalFlow
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);
+ //! _array should be a vector a points standing for the contour
+ CV_EXPORTS Moments ocl_moments(InputArray contour);
+ //! src should be a general image uploaded to the GPU.
+ //! the supported oclMat type are CV_8UC1, CV_16UC1, CV_16SC1, CV_32FC1 and CV_64FC1
+ //! to use type of CV_64FC1, the GPU should support CV_64FC1
+ CV_EXPORTS Moments ocl_moments(oclMat& src, bool binary);
class CV_EXPORTS StereoBM_OCL
{
};
//! Returns the sorted result of all the elements in input based on equivalent keys.
//
- // The element unit in the values to be sorted is determined from the data type,
+ // The element unit in the values to be sorted is determined from the data type,
// i.e., a CV_32FC2 input {a1a2, b1b2} will be considered as two elements, regardless its
// matrix dimension.
// both keys and values will be sorted inplace
// output -
// keys = {1, 2, 3} (CV_8UC1)
// values = {6,2, 10,5, 4,3} (CV_8UC2)
- void CV_EXPORTS sortByKey(oclMat& keys, oclMat& values, int method, bool isGreaterThan = false);
+ CV_EXPORTS void sortByKey(oclMat& keys, oclMat& values, int method, bool isGreaterThan = false);
+ /*!Base class for MOG and MOG2!*/
+ class CV_EXPORTS BackgroundSubtractor
+ {
+ public:
+ //! the virtual destructor
+ virtual ~BackgroundSubtractor();
+ //! the update operator that takes the next video frame and returns the current foreground mask as 8-bit binary image.
+ virtual void operator()(const oclMat& image, oclMat& fgmask, float learningRate);
+
+ //! computes a background image
+ virtual void getBackgroundImage(oclMat& backgroundImage) const = 0;
+ };
+ /*!
+ Gaussian Mixture-based Backbround/Foreground Segmentation Algorithm
+
+ The class implements the following algorithm:
+ "An improved adaptive background mixture model for real-time tracking with shadow detection"
+ P. KadewTraKuPong and R. Bowden,
+ Proc. 2nd European Workshp on Advanced Video-Based Surveillance Systems, 2001."
+ http://personal.ee.surrey.ac.uk/Personal/R.Bowden/publications/avbs01/avbs01.pdf
+ */
+ class CV_EXPORTS MOG: public cv::ocl::BackgroundSubtractor
+ {
+ public:
+ //! the default constructor
+ MOG(int nmixtures = -1);
+
+ //! re-initiaization method
+ void initialize(Size frameSize, int frameType);
+
+ //! the update operator
+ void operator()(const oclMat& frame, oclMat& fgmask, float learningRate = 0.f);
+
+ //! computes a background image which are the mean of all background gaussians
+ void getBackgroundImage(oclMat& backgroundImage) const;
+
+ //! releases all inner buffers
+ void release();
+
+ int history;
+ float varThreshold;
+ float backgroundRatio;
+ float noiseSigma;
+
+ private:
+ int nmixtures_;
+
+ Size frameSize_;
+ int frameType_;
+ int nframes_;
+
+ oclMat weight_;
+ oclMat sortKey_;
+ oclMat mean_;
+ oclMat var_;
+ };
+
+ /*!
+ The class implements the following algorithm:
+ "Improved adaptive Gausian mixture model for background subtraction"
+ Z.Zivkovic
+ International Conference Pattern Recognition, UK, August, 2004.
+ http://www.zoranz.net/Publications/zivkovic2004ICPR.pdf
+ */
+ class CV_EXPORTS MOG2: public cv::ocl::BackgroundSubtractor
+ {
+ public:
+ //! the default constructor
+ MOG2(int nmixtures = -1);
+
+ //! re-initiaization method
+ void initialize(Size frameSize, int frameType);
+
+ //! the update operator
+ void operator()(const oclMat& frame, oclMat& fgmask, float learningRate = -1.0f);
+
+ //! computes a background image which are the mean of all background gaussians
+ void getBackgroundImage(oclMat& backgroundImage) const;
+
+ //! releases all inner buffers
+ void release();
+
+ // parameters
+ // you should call initialize after parameters changes
+
+ int history;
+
+ //! here it is the maximum allowed number of mixture components.
+ //! Actual number is determined dynamically per pixel
+ float varThreshold;
+ // threshold on the squared Mahalanobis distance to decide if it is well described
+ // by the background model or not. Related to Cthr from the paper.
+ // This does not influence the update of the background. A typical value could be 4 sigma
+ // and that is varThreshold=4*4=16; Corresponds to Tb in the paper.
+
+ /////////////////////////
+ // less important parameters - things you might change but be carefull
+ ////////////////////////
+
+ float backgroundRatio;
+ // corresponds to fTB=1-cf from the paper
+ // TB - threshold when the component becomes significant enough to be included into
+ // the background model. It is the TB=1-cf from the paper. So I use cf=0.1 => TB=0.
+ // For alpha=0.001 it means that the mode should exist for approximately 105 frames before
+ // it is considered foreground
+ // float noiseSigma;
+ float varThresholdGen;
+
+ //correspondts to Tg - threshold on the squared Mahalan. dist. to decide
+ //when a sample is close to the existing components. If it is not close
+ //to any a new component will be generated. I use 3 sigma => Tg=3*3=9.
+ //Smaller Tg leads to more generated components and higher Tg might make
+ //lead to small number of components but they can grow too large
+ float fVarInit;
+ float fVarMin;
+ float fVarMax;
+
+ //initial variance for the newly generated components.
+ //It will will influence the speed of adaptation. A good guess should be made.
+ //A simple way is to estimate the typical standard deviation from the images.
+ //I used here 10 as a reasonable value
+ // min and max can be used to further control the variance
+ float fCT; //CT - complexity reduction prior
+ //this is related to the number of samples needed to accept that a component
+ //actually exists. We use CT=0.05 of all the samples. By setting CT=0 you get
+ //the standard Stauffer&Grimson algorithm (maybe not exact but very similar)
+
+ //shadow detection parameters
+ bool bShadowDetection; //default 1 - do shadow detection
+ unsigned char nShadowDetection; //do shadow detection - insert this value as the detection result - 127 default value
+ float fTau;
+ // Tau - shadow threshold. The shadow is detected if the pixel is darker
+ //version of the background. Tau is a threshold on how much darker the shadow can be.
+ //Tau= 0.5 means that if pixel is more than 2 times darker then it is not shadow
+ //See: Prati,Mikic,Trivedi,Cucchiarra,"Detecting Moving Shadows...",IEEE PAMI,2003.
+
+ private:
+ int nmixtures_;
+
+ Size frameSize_;
+ int frameType_;
+ int nframes_;
+
+ oclMat weight_;
+ oclMat variance_;
+ oclMat mean_;
+
+ oclMat bgmodelUsedModes_; //keep track of number of modes per pixel
+ };
+
+ /*!***************Kalman Filter*************!*/
+ class CV_EXPORTS KalmanFilter
+ {
+ public:
+ KalmanFilter();
+ //! the full constructor taking the dimensionality of the state, of the measurement and of the control vector
+ KalmanFilter(int dynamParams, int measureParams, int controlParams=0, int type=CV_32F);
+ //! re-initializes Kalman filter. The previous content is destroyed.
+ void init(int dynamParams, int measureParams, int controlParams=0, int type=CV_32F);
+
+ const oclMat& predict(const oclMat& control=oclMat());
+ const oclMat& correct(const oclMat& measurement);
+
+ oclMat statePre; //!< predicted state (x'(k)): x(k)=A*x(k-1)+B*u(k)
+ oclMat statePost; //!< corrected state (x(k)): x(k)=x'(k)+K(k)*(z(k)-H*x'(k))
+ oclMat transitionMatrix; //!< state transition matrix (A)
+ oclMat controlMatrix; //!< control matrix (B) (not used if there is no control)
+ oclMat measurementMatrix; //!< measurement matrix (H)
+ oclMat processNoiseCov; //!< process noise covariance matrix (Q)
+ oclMat measurementNoiseCov;//!< measurement noise covariance matrix (R)
+ oclMat errorCovPre; //!< priori error estimate covariance matrix (P'(k)): P'(k)=A*P(k-1)*At + Q)*/
+ oclMat gain; //!< Kalman gain matrix (K(k)): K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R)
+ oclMat errorCovPost; //!< posteriori error estimate covariance matrix (P(k)): P(k)=(I-K(k)*H)*P'(k)
+ private:
+ oclMat temp1;
+ oclMat temp2;
+ oclMat temp3;
+ oclMat temp4;
+ oclMat temp5;
+ };
+
+ /*!***************K Nearest Neighbour*************!*/
+ class CV_EXPORTS KNearestNeighbour: public CvKNearest
+ {
+ public:
+ KNearestNeighbour();
+ ~KNearestNeighbour();
+
+ bool train(const Mat& trainData, Mat& labels, Mat& sampleIdx = Mat().setTo(Scalar::all(0)),
+ bool isRegression = false, int max_k = 32, bool updateBase = false);
+
+ void clear();
+
+ void find_nearest(const oclMat& samples, int k, oclMat& lables);
+
+ private:
+ oclMat samples_ocl;
+ };
+
+ /*!*************** SVM *************!*/
+ class CV_EXPORTS CvSVM_OCL : public CvSVM
+ {
+ public:
+ CvSVM_OCL();
+
+ CvSVM_OCL(const cv::Mat& trainData, const cv::Mat& responses,
+ const cv::Mat& varIdx=cv::Mat(), const cv::Mat& sampleIdx=cv::Mat(),
+ CvSVMParams params=CvSVMParams());
+ CV_WRAP float predict( const int row_index, Mat& src, bool returnDFVal=false ) const;
+ CV_WRAP void predict( cv::InputArray samples, cv::OutputArray results ) const;
+ CV_WRAP float predict( const cv::Mat& sample, bool returnDFVal=false ) const;
+ float predict( const CvMat* samples, CV_OUT CvMat* results ) const;
+
+ protected:
+ float predict( const int row_index, int row_len, Mat& src, bool returnDFVal=false ) const;
+ void create_kernel();
+ void create_solver();
+ };
+
+ /*!*************** END *************!*/
}
}
#if defined _MSC_VER && _MSC_VER >= 1200