OCV_OPTION(WITH_CUBLAS "Include NVidia Cuda Basic Linear Algebra Subprograms (BLAS) library support" OFF IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS) )
OCV_OPTION(WITH_NVCUVID "Include NVidia Video Decoding library support" OFF IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS AND NOT APPLE) )
OCV_OPTION(WITH_EIGEN "Include Eigen2/Eigen3 support" ON)
+ OCV_OPTION(WITH_VFW "Include Video for Windows support" ON IF WIN32 )
OCV_OPTION(WITH_FFMPEG "Include FFMPEG support" ON IF (NOT ANDROID AND NOT IOS))
OCV_OPTION(WITH_GSTREAMER "Include Gstreamer support" ON IF (UNIX AND NOT APPLE AND NOT ANDROID) )
+OCV_OPTION(WITH_GSTREAMER_1_X "Include Gstreamer 1.x support" OFF)
OCV_OPTION(WITH_GTK "Include GTK support" ON IF (UNIX AND NOT APPLE AND NOT ANDROID) )
-OCV_OPTION(WITH_IMAGEIO "ImageIO support for OS X" OFF IF APPLE )
OCV_OPTION(WITH_IPP "Include Intel IPP support" OFF IF (MSVC OR X86 OR X86_64) )
OCV_OPTION(WITH_JASPER "Include JPEG2K support" ON IF (NOT IOS) )
OCV_OPTION(WITH_JPEG "Include JPEG support" ON)
OCV_OPTION(WITH_TIFF "Include TIFF support" ON IF (NOT IOS) )
OCV_OPTION(WITH_UNICAP "Include Unicap support (GPL)" OFF IF (UNIX AND NOT APPLE AND NOT ANDROID) )
OCV_OPTION(WITH_V4L "Include Video 4 Linux support" ON IF (UNIX AND NOT ANDROID) )
- OCV_OPTION(WITH_VIDEOINPUT "Build HighGUI with DirectShow support" ON IF WIN32 )
+ OCV_OPTION(WITH_DSHOW "Build HighGUI with DirectShow support" ON IF (WIN32 AND NOT ARM) )
+ OCV_OPTION(WITH_MSMF "Build HighGUI with Media Foundation support" OFF IF WIN32 )
OCV_OPTION(WITH_XIMEA "Include XIMEA cameras support" OFF IF (NOT ANDROID AND NOT APPLE) )
OCV_OPTION(WITH_XINE "Include Xine support (GPL)" OFF IF (UNIX AND NOT APPLE AND NOT ANDROID) )
-OCV_OPTION(WITH_OPENCL "Include OpenCL Runtime support" ON IF (NOT ANDROID AND NOT IOS) )
-OCV_OPTION(WITH_OPENCLAMDFFT "Include AMD OpenCL FFT library support" ON IF (NOT ANDROID AND NOT IOS) )
-OCV_OPTION(WITH_OPENCLAMDBLAS "Include AMD OpenCL BLAS library support" ON IF (NOT ANDROID AND NOT IOS) )
+OCV_OPTION(WITH_CLP "Include Clp support (EPL)" OFF)
+OCV_OPTION(WITH_OPENCL "Include OpenCL Runtime support" ON IF (NOT ANDROID AND NOT IOS) )
+OCV_OPTION(WITH_OPENCLAMDFFT "Include AMD OpenCL FFT library support" ON IF (NOT ANDROID AND NOT IOS) )
+OCV_OPTION(WITH_OPENCLAMDBLAS "Include AMD OpenCL BLAS library support" ON IF (NOT ANDROID AND NOT IOS) )
# OpenCV build components
# Detect 3rd-party video IO libraries
# ----------------------------------------------------------------------------
+ ocv_clear_vars(HAVE_VFW)
+ if (WITH_VFW)
+ TRY_COMPILE(HAVE_VFW
+ "${OPENCV_BINARY_DIR}/CMakeFiles/CMakeTmp"
+ "${OpenCV_SOURCE_DIR}/cmake/checks/vfwtest.cpp"
+ CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=vfw32"
+ OUTPUT_VARIABLE OUTPUT)
+ endif(WITH_VFW)
+
# --- GStreamer ---
ocv_clear_vars(HAVE_GSTREAMER)
-if(WITH_GSTREAMER)
- CHECK_MODULE(gstreamer-base-0.10 HAVE_GSTREAMER)
- if(HAVE_GSTREAMER)
- CHECK_MODULE(gstreamer-app-0.10 HAVE_GSTREAMER)
+# try to find gstreamer 0.10 first
+if(WITH_GSTREAMER AND NOT WITH_GSTREAMER_1_X)
+ CHECK_MODULE(gstreamer-base-0.10 HAVE_GSTREAMER_BASE)
+ CHECK_MODULE(gstreamer-video-0.10 HAVE_GSTREAMER_VIDEO)
+ CHECK_MODULE(gstreamer-app-0.10 HAVE_GSTREAMER_APP)
+ CHECK_MODULE(gstreamer-riff-0.10 HAVE_GSTREAMER_RIFF)
+ CHECK_MODULE(gstreamer-pbutils-0.10 HAVE_GSTREAMER_PBUTILS)
+
+ if(HAVE_GSTREAMER_BASE AND HAVE_GSTREAMER_VIDEO AND HAVE_GSTREAMER_APP AND HAVE_GSTREAMER_RIFF AND HAVE_GSTREAMER_PBUTILS)
+ set(HAVE_GSTREAMER TRUE)
+ set(GSTREAMER_BASE_VERSION ${ALIASOF_gstreamer-base-0.10_VERSION})
+ set(GSTREAMER_VIDEO_VERSION ${ALIASOF_gstreamer-video-0.10_VERSION})
+ set(GSTREAMER_APP_VERSION ${ALIASOF_gstreamer-app-0.10_VERSION})
+ set(GSTREAMER_RIFF_VERSION ${ALIASOF_gstreamer-riff-0.10_VERSION})
+ set(GSTREAMER_PBUTILS_VERSION ${ALIASOF_gstreamer-pbutils-0.10_VERSION})
endif()
- if(HAVE_GSTREAMER)
- CHECK_MODULE(gstreamer-video-0.10 HAVE_GSTREAMER)
+
+endif(WITH_GSTREAMER AND NOT WITH_GSTREAMER_1_X)
+
+# if gstreamer 0.10 was not found, or we specified we wanted 1.x, try to find it
+if(WITH_GSTREAMER_1_X OR NOT HAVE_GSTREAMER)
+ #check for 1.x
+ CHECK_MODULE(gstreamer-base-1.0 HAVE_GSTREAMER_BASE)
+ CHECK_MODULE(gstreamer-video-1.0 HAVE_GSTREAMER_VIDEO)
+ CHECK_MODULE(gstreamer-app-1.0 HAVE_GSTREAMER_APP)
+ CHECK_MODULE(gstreamer-riff-1.0 HAVE_GSTREAMER_RIFF)
+ CHECK_MODULE(gstreamer-pbutils-1.0 HAVE_GSTREAMER_PBUTILS)
+
+ if(HAVE_GSTREAMER_BASE AND HAVE_GSTREAMER_VIDEO AND HAVE_GSTREAMER_APP AND HAVE_GSTREAMER_RIFF AND HAVE_GSTREAMER_PBUTILS)
+ set(HAVE_GSTREAMER TRUE)
+ set(GSTREAMER_BASE_VERSION ${ALIASOF_gstreamer-base-1.0_VERSION})
+ set(GSTREAMER_VIDEO_VERSION ${ALIASOF_gstreamer-video-1.0_VERSION})
+ set(GSTREAMER_APP_VERSION ${ALIASOF_gstreamer-app-1.0_VERSION})
+ set(GSTREAMER_RIFF_VERSION ${ALIASOF_gstreamer-riff-1.0_VERSION})
+ set(GSTREAMER_PBUTILS_VERSION ${ALIASOF_gstreamer-pbutils-1.0_VERSION})
endif()
-endif(WITH_GSTREAMER)
+
+endif(WITH_GSTREAMER_1_X OR NOT HAVE_GSTREAMER)
# --- unicap ---
ocv_clear_vars(HAVE_UNICAP)
--- /dev/null
- CreateWindow(NULL /*lpClassName*/, NULL /*lpWindowName*/, 0 /*dwStyle*/, 0 /*x*/,
- 0 /*y*/, 0 /*nWidth*/, 0 /*nHeight*/, NULL /*hWndParent*/, NULL /*hMenu*/,
- NULL /*hInstance*/, NULL /*lpParam*/);
- DeleteDC(NULL);
+ #include <windows.h>
+
+ int main(int argc, char** argv)
+ {
- return 0;
++ CreateWindow(NULL /*lpClassName*/, NULL /*lpWindowName*/, 0 /*dwStyle*/, 0 /*x*/,
++ 0 /*y*/, 0 /*nWidth*/, 0 /*nHeight*/, NULL /*hWndParent*/, NULL /*hMenu*/,
++ NULL /*hInstance*/, NULL /*lpParam*/);
++ DeleteDC(NULL);
+
++ return 0;
+ }
Application Development with Async Initialization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Using async initialization is a **recommended** way for application development. It uses the OpenCV
+Using async initialization is a **recommended** way for application development. It uses the OpenCV
Manager to access OpenCV libraries externally installed in the target system.
-#. Add OpenCV library project to your workspace. Use menu
+#. Add OpenCV library project to your workspace. Use menu
:guilabel:`File -> Import -> Existing project in your workspace`.
- Press :guilabel:`Browse` button and locate OpenCV4Android SDK
+ Press :guilabel:`Browse` button and locate OpenCV4Android SDK
- (:file:`OpenCV-2.4.4-android-sdk/sdk`).
+ (:file:`OpenCV-2.4.5-android-sdk/sdk`).
.. image:: images/eclipse_opencv_dependency0.png
:alt: Add dependency from OpenCV library
:align: center
-#. In application project add a reference to the OpenCV Java SDK in
+#. In application project add a reference to the OpenCV Java SDK in
- :guilabel:`Project -> Properties -> Android -> Library -> Add` select ``OpenCV Library - 2.4.4``.
+ :guilabel:`Project -> Properties -> Android -> Library -> Add` select ``OpenCV Library - 2.4.5``.
.. image:: images/eclipse_opencv_dependency1.png
:alt: Add dependency from OpenCV library
Application Development with Static Initialization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-According to this approach all OpenCV binaries are included into your application package. It is
-designed mostly for development purposes. This approach is deprecated for the production code,
-release package is recommended to communicate with OpenCV Manager via the async initialization
+According to this approach all OpenCV binaries are included into your application package. It is
+designed mostly for development purposes. This approach is deprecated for the production code,
+release package is recommended to communicate with OpenCV Manager via the async initialization
described above.
-#. Add the OpenCV library project to your workspace the same way as for the async initialization
- above. Use menu :guilabel:`File -> Import -> Existing project in your workspace`,
- press :guilabel:`Browse` button and select OpenCV SDK path
+#. Add the OpenCV library project to your workspace the same way as for the async initialization
+ above. Use menu :guilabel:`File -> Import -> Existing project in your workspace`,
+ press :guilabel:`Browse` button and select OpenCV SDK path
- (:file:`OpenCV-2.4.4-android-sdk/sdk`).
+ (:file:`OpenCV-2.4.5-android-sdk/sdk`).
.. image:: images/eclipse_opencv_dependency0.png
:alt: Add dependency from OpenCV library
:align: center
-#. In the application project add a reference to the OpenCV4Android SDK in
+#. In the application project add a reference to the OpenCV4Android SDK in
- :guilabel:`Project -> Properties -> Android -> Library -> Add` select ``OpenCV Library - 2.4.4``;
+ :guilabel:`Project -> Properties -> Android -> Library -> Add` select ``OpenCV Library - 2.4.5``;
.. image:: images/eclipse_opencv_dependency1.png
:alt: Add dependency from OpenCV library
:align: center
-#. If your application project **doesn't have a JNI part**, just copy the corresponding OpenCV
+#. If your application project **doesn't have a JNI part**, just copy the corresponding OpenCV
- native libs from :file:`<OpenCV-2.4.4-android-sdk>/sdk/native/libs/<target_arch>` to your
+ native libs from :file:`<OpenCV-2.4.5-android-sdk>/sdk/native/libs/<target_arch>` to your
project directory to folder :file:`libs/<target_arch>`.
- In case of the application project **with a JNI part**, instead of manual libraries copying you
+ In case of the application project **with a JNI part**, instead of manual libraries copying you
need to modify your ``Android.mk`` file:
- add the following two code lines after the ``"include $(CLEAR_VARS)"`` and before
+ add the following two code lines after the ``"include $(CLEAR_VARS)"`` and before
- ``"include path_to_OpenCV-2.4.4-android-sdk/sdk/native/jni/OpenCV.mk"``
+ ``"include path_to_OpenCV-2.4.5-android-sdk/sdk/native/jni/OpenCV.mk"``
.. code-block:: make
:linenos:
//
//M*/
-#ifndef __OPENCV_CONTRIB_HPP__
-#define __OPENCV_CONTRIB_HPP__
-
-#include "opencv2/core/core.hpp"
-#include "opencv2/imgproc/imgproc.hpp"
-#include "opencv2/features2d/features2d.hpp"
-#include "opencv2/objdetect/objdetect.hpp"
-
-#ifdef __cplusplus
-
-/****************************************************************************************\
-* Adaptive Skin Detector *
-\****************************************************************************************/
-
-class CV_EXPORTS CvAdaptiveSkinDetector
-{
-private:
- enum {
- GSD_HUE_LT = 3,
- GSD_HUE_UT = 33,
- GSD_INTENSITY_LT = 15,
- GSD_INTENSITY_UT = 250
- };
-
- class CV_EXPORTS Histogram
- {
- private:
- enum {
- HistogramSize = (GSD_HUE_UT - GSD_HUE_LT + 1)
- };
-
- protected:
- int findCoverageIndex(double surfaceToCover, int defaultValue = 0);
-
- public:
- CvHistogram *fHistogram;
- Histogram();
- virtual ~Histogram();
-
- void findCurveThresholds(int &x1, int &x2, double percent = 0.05);
- void mergeWith(Histogram *source, double weight);
- };
-
- int nStartCounter, nFrameCount, nSkinHueLowerBound, nSkinHueUpperBound, nMorphingMethod, nSamplingDivider;
- double fHistogramMergeFactor, fHuePercentCovered;
- Histogram histogramHueMotion, skinHueHistogram;
- IplImage *imgHueFrame, *imgSaturationFrame, *imgLastGrayFrame, *imgMotionFrame, *imgFilteredFrame;
- IplImage *imgShrinked, *imgTemp, *imgGrayFrame, *imgHSVFrame;
-
-protected:
- void initData(IplImage *src, int widthDivider, int heightDivider);
- void adaptiveFilter();
-
-public:
-
- enum {
- MORPHING_METHOD_NONE = 0,
- MORPHING_METHOD_ERODE = 1,
- MORPHING_METHOD_ERODE_ERODE = 2,
- MORPHING_METHOD_ERODE_DILATE = 3
- };
-
- CvAdaptiveSkinDetector(int samplingDivider = 1, int morphingMethod = MORPHING_METHOD_NONE);
- virtual ~CvAdaptiveSkinDetector();
-
- virtual void process(IplImage *inputBGRImage, IplImage *outputHueMask);
-};
-
-
-/****************************************************************************************\
- * Fuzzy MeanShift Tracker *
- \****************************************************************************************/
-
-class CV_EXPORTS CvFuzzyPoint {
-public:
- double x, y, value;
-
- CvFuzzyPoint(double _x, double _y);
-};
-
-class CV_EXPORTS CvFuzzyCurve {
-private:
- std::vector<CvFuzzyPoint> points;
- double value, centre;
-
- bool between(double x, double x1, double x2);
-
-public:
- CvFuzzyCurve();
- ~CvFuzzyCurve();
-
- void setCentre(double _centre);
- double getCentre();
- void clear();
- void addPoint(double x, double y);
- double calcValue(double param);
- double getValue();
- void setValue(double _value);
-};
-
-class CV_EXPORTS CvFuzzyFunction {
-public:
- std::vector<CvFuzzyCurve> curves;
-
- CvFuzzyFunction();
- ~CvFuzzyFunction();
- void addCurve(CvFuzzyCurve *curve, double value = 0);
- void resetValues();
- double calcValue();
- CvFuzzyCurve *newCurve();
-};
-
-class CV_EXPORTS CvFuzzyRule {
-private:
- CvFuzzyCurve *fuzzyInput1, *fuzzyInput2;
- CvFuzzyCurve *fuzzyOutput;
-public:
- CvFuzzyRule();
- ~CvFuzzyRule();
- void setRule(CvFuzzyCurve *c1, CvFuzzyCurve *c2, CvFuzzyCurve *o1);
- double calcValue(double param1, double param2);
- CvFuzzyCurve *getOutputCurve();
-};
-
-class CV_EXPORTS CvFuzzyController {
-private:
- std::vector<CvFuzzyRule*> rules;
-public:
- CvFuzzyController();
- ~CvFuzzyController();
- void addRule(CvFuzzyCurve *c1, CvFuzzyCurve *c2, CvFuzzyCurve *o1);
- double calcOutput(double param1, double param2);
-};
-
-class CV_EXPORTS CvFuzzyMeanShiftTracker
-{
-private:
- class FuzzyResizer
- {
- private:
- CvFuzzyFunction iInput, iOutput;
- CvFuzzyController fuzzyController;
- public:
- FuzzyResizer();
- int calcOutput(double edgeDensity, double density);
- };
-
- class SearchWindow
- {
- public:
- FuzzyResizer *fuzzyResizer;
- int x, y;
- int width, height, maxWidth, maxHeight, ellipseHeight, ellipseWidth;
- int ldx, ldy, ldw, ldh, numShifts, numIters;
- int xGc, yGc;
- long m00, m01, m10, m11, m02, m20;
- double ellipseAngle;
- double density;
- unsigned int depthLow, depthHigh;
- int verticalEdgeLeft, verticalEdgeRight, horizontalEdgeTop, horizontalEdgeBottom;
-
- SearchWindow();
- ~SearchWindow();
- void setSize(int _x, int _y, int _width, int _height);
- void initDepthValues(IplImage *maskImage, IplImage *depthMap);
- bool shift();
- void extractInfo(IplImage *maskImage, IplImage *depthMap, bool initDepth);
- void getResizeAttribsEdgeDensityLinear(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);
- void getResizeAttribsInnerDensity(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);
- void getResizeAttribsEdgeDensityFuzzy(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);
- bool meanShift(IplImage *maskImage, IplImage *depthMap, int maxIteration, bool initDepth);
- };
-
-public:
- enum TrackingState
- {
- tsNone = 0,
- tsSearching = 1,
- tsTracking = 2,
- tsSetWindow = 3,
- tsDisabled = 10
- };
-
- enum ResizeMethod {
- rmEdgeDensityLinear = 0,
- rmEdgeDensityFuzzy = 1,
- rmInnerDensity = 2
- };
-
- enum {
- MinKernelMass = 1000
- };
-
- SearchWindow kernel;
- int searchMode;
-
-private:
- enum
- {
- MaxMeanShiftIteration = 5,
- MaxSetSizeIteration = 5
- };
-
- void findOptimumSearchWindow(SearchWindow &searchWindow, IplImage *maskImage, IplImage *depthMap, int maxIteration, int resizeMethod, bool initDepth);
-
-public:
- CvFuzzyMeanShiftTracker();
- ~CvFuzzyMeanShiftTracker();
-
- void track(IplImage *maskImage, IplImage *depthMap, int resizeMethod, bool resetSearch, int minKernelMass = MinKernelMass);
-};
-
-
-namespace cv
-{
-
- class CV_EXPORTS Octree
- {
- public:
- struct Node
- {
- Node() {}
- int begin, end;
- float x_min, x_max, y_min, y_max, z_min, z_max;
- int maxLevels;
- bool isLeaf;
- int children[8];
- };
-
- Octree();
- Octree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 );
- virtual ~Octree();
-
- virtual void buildTree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 );
- virtual void getPointsWithinSphere( const Point3f& center, float radius,
- vector<Point3f>& points ) const;
- const vector<Node>& getNodes() const { return nodes; }
- private:
- int minPoints;
- vector<Point3f> points;
- vector<Node> nodes;
-
- virtual void buildNext(size_t node_ind);
- };
-
-
- class CV_EXPORTS Mesh3D
- {
- public:
- struct EmptyMeshException {};
-
- Mesh3D();
- Mesh3D(const vector<Point3f>& vtx);
- ~Mesh3D();
-
- void buildOctree();
- void clearOctree();
- float estimateResolution(float tryRatio = 0.1f);
- void computeNormals(float normalRadius, int minNeighbors = 20);
- void computeNormals(const vector<int>& subset, float normalRadius, int minNeighbors = 20);
-
- void writeAsVrml(const String& file, const vector<Scalar>& colors = vector<Scalar>()) const;
-
- vector<Point3f> vtx;
- vector<Point3f> normals;
- float resolution;
- Octree octree;
-
- const static Point3f allzero;
- };
-
- class CV_EXPORTS SpinImageModel
- {
- public:
-
- /* model parameters, leave unset for default or auto estimate */
- float normalRadius;
- int minNeighbors;
-
- float binSize;
- int imageWidth;
-
- float lambda;
- float gamma;
-
- float T_GeometriccConsistency;
- float T_GroupingCorespondances;
-
- /* public interface */
- SpinImageModel();
- explicit SpinImageModel(const Mesh3D& mesh);
- ~SpinImageModel();
-
- void setLogger(std::ostream* log);
- void selectRandomSubset(float ratio);
- void setSubset(const vector<int>& subset);
- void compute();
-
- void match(const SpinImageModel& scene, vector< vector<Vec2i> >& result);
-
- Mat packRandomScaledSpins(bool separateScale = false, size_t xCount = 10, size_t yCount = 10) const;
-
- size_t getSpinCount() const { return spinImages.rows; }
- Mat getSpinImage(size_t index) const { return spinImages.row((int)index); }
- const Point3f& getSpinVertex(size_t index) const { return mesh.vtx[subset[index]]; }
- const Point3f& getSpinNormal(size_t index) const { return mesh.normals[subset[index]]; }
-
- const Mesh3D& getMesh() const { return mesh; }
- Mesh3D& getMesh() { return mesh; }
-
- /* static utility functions */
- static bool spinCorrelation(const Mat& spin1, const Mat& spin2, float lambda, float& result);
-
- static Point2f calcSpinMapCoo(const Point3f& point, const Point3f& vertex, const Point3f& normal);
-
- static float geometricConsistency(const Point3f& pointScene1, const Point3f& normalScene1,
- const Point3f& pointModel1, const Point3f& normalModel1,
- const Point3f& pointScene2, const Point3f& normalScene2,
- const Point3f& pointModel2, const Point3f& normalModel2);
-
- static float groupingCreteria(const Point3f& pointScene1, const Point3f& normalScene1,
- const Point3f& pointModel1, const Point3f& normalModel1,
- const Point3f& pointScene2, const Point3f& normalScene2,
- const Point3f& pointModel2, const Point3f& normalModel2,
- float gamma);
- protected:
- void defaultParams();
-
- void matchSpinToModel(const Mat& spin, vector<int>& indeces,
- vector<float>& corrCoeffs, bool useExtremeOutliers = true) const;
-
- void repackSpinImages(const vector<uchar>& mask, Mat& spinImages, bool reAlloc = true) const;
-
- vector<int> subset;
- Mesh3D mesh;
- Mat spinImages;
- std::ostream* out;
- };
-
- class CV_EXPORTS TickMeter
- {
- public:
- TickMeter();
- void start();
- void stop();
-
- int64 getTimeTicks() const;
- double getTimeMicro() const;
- double getTimeMilli() const;
- double getTimeSec() const;
- int64 getCounter() const;
-
- void reset();
- private:
- int64 counter;
- int64 sumTime;
- int64 startTime;
- };
-
- CV_EXPORTS std::ostream& operator<<(std::ostream& out, const TickMeter& tm);
-
- class CV_EXPORTS SelfSimDescriptor
- {
- public:
- SelfSimDescriptor();
- SelfSimDescriptor(int _ssize, int _lsize,
- int _startDistanceBucket=DEFAULT_START_DISTANCE_BUCKET,
- int _numberOfDistanceBuckets=DEFAULT_NUM_DISTANCE_BUCKETS,
- int _nangles=DEFAULT_NUM_ANGLES);
- SelfSimDescriptor(const SelfSimDescriptor& ss);
- virtual ~SelfSimDescriptor();
- SelfSimDescriptor& operator = (const SelfSimDescriptor& ss);
-
- size_t getDescriptorSize() const;
- Size getGridSize( Size imgsize, Size winStride ) const;
-
- virtual void compute(const Mat& img, vector<float>& descriptors, Size winStride=Size(),
- const vector<Point>& locations=vector<Point>()) const;
- virtual void computeLogPolarMapping(Mat& mappingMask) const;
- virtual void SSD(const Mat& img, Point pt, Mat& ssd) const;
-
- int smallSize;
- int largeSize;
- int startDistanceBucket;
- int numberOfDistanceBuckets;
- int numberOfAngles;
-
- enum { DEFAULT_SMALL_SIZE = 5, DEFAULT_LARGE_SIZE = 41,
- DEFAULT_NUM_ANGLES = 20, DEFAULT_START_DISTANCE_BUCKET = 3,
- DEFAULT_NUM_DISTANCE_BUCKETS = 7 };
- };
-
-
- typedef bool (*BundleAdjustCallback)(int iteration, double norm_error, void* user_data);
-
- class CV_EXPORTS LevMarqSparse {
- public:
- LevMarqSparse();
- LevMarqSparse(int npoints, // number of points
- int ncameras, // number of cameras
- int nPointParams, // number of params per one point (3 in case of 3D points)
- int nCameraParams, // number of parameters per one camera
- int nErrParams, // number of parameters in measurement vector
- // for 1 point at one camera (2 in case of 2D projections)
- Mat& visibility, // visibility matrix. rows correspond to points, columns correspond to cameras
- // 1 - point is visible for the camera, 0 - invisible
- Mat& P0, // starting vector of parameters, first cameras then points
- Mat& X, // measurements, in order of visibility. non visible cases are skipped
- TermCriteria criteria, // termination criteria
-
- // callback for estimation of Jacobian matrices
- void (CV_CDECL * fjac)(int i, int j, Mat& point_params,
- Mat& cam_params, Mat& A, Mat& B, void* data),
- // callback for estimation of backprojection errors
- void (CV_CDECL * func)(int i, int j, Mat& point_params,
- Mat& cam_params, Mat& estim, void* data),
- void* data, // user-specific data passed to the callbacks
- BundleAdjustCallback cb, void* user_data
- );
-
- virtual ~LevMarqSparse();
-
- virtual void run( int npoints, // number of points
- int ncameras, // number of cameras
- int nPointParams, // number of params per one point (3 in case of 3D points)
- int nCameraParams, // number of parameters per one camera
- int nErrParams, // number of parameters in measurement vector
- // for 1 point at one camera (2 in case of 2D projections)
- Mat& visibility, // visibility matrix. rows correspond to points, columns correspond to cameras
- // 1 - point is visible for the camera, 0 - invisible
- Mat& P0, // starting vector of parameters, first cameras then points
- Mat& X, // measurements, in order of visibility. non visible cases are skipped
- TermCriteria criteria, // termination criteria
-
- // callback for estimation of Jacobian matrices
- void (CV_CDECL * fjac)(int i, int j, Mat& point_params,
- Mat& cam_params, Mat& A, Mat& B, void* data),
- // callback for estimation of backprojection errors
- void (CV_CDECL * func)(int i, int j, Mat& point_params,
- Mat& cam_params, Mat& estim, void* data),
- void* data // user-specific data passed to the callbacks
- );
-
- virtual void clear();
-
- // useful function to do simple bundle adjustment tasks
- static void bundleAdjust(vector<Point3d>& points, // positions of points in global coordinate system (input and output)
- const vector<vector<Point2d> >& imagePoints, // projections of 3d points for every camera
- const vector<vector<int> >& visibility, // visibility of 3d points for every camera
- vector<Mat>& cameraMatrix, // intrinsic matrices of all cameras (input and output)
- vector<Mat>& R, // rotation matrices of all cameras (input and output)
- vector<Mat>& T, // translation vector of all cameras (input and output)
- vector<Mat>& distCoeffs, // distortion coefficients of all cameras (input and output)
- const TermCriteria& criteria=
- TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON),
- BundleAdjustCallback cb = 0, void* user_data = 0);
-
- public:
- virtual void optimize(CvMat &_vis); //main function that runs minimization
-
- //iteratively asks for measurement for visible camera-point pairs
- void ask_for_proj(CvMat &_vis,bool once=false);
- //iteratively asks for Jacobians for every camera_point pair
- void ask_for_projac(CvMat &_vis);
-
- CvMat* err; //error X-hX
- double prevErrNorm, errNorm;
- double lambda;
- CvTermCriteria criteria;
- int iters;
-
- CvMat** U; //size of array is equal to number of cameras
- CvMat** V; //size of array is equal to number of points
- CvMat** inv_V_star; //inverse of V*
-
- CvMat** A;
- CvMat** B;
- CvMat** W;
-
- CvMat* X; //measurement
- CvMat* hX; //current measurement extimation given new parameter vector
-
- CvMat* prevP; //current already accepted parameter.
- CvMat* P; // parameters used to evaluate function with new params
- // this parameters may be rejected
-
- CvMat* deltaP; //computed increase of parameters (result of normal system solution )
-
- CvMat** ea; // sum_i AijT * e_ij , used as right part of normal equation
- // length of array is j = number of cameras
- CvMat** eb; // sum_j BijT * e_ij , used as right part of normal equation
- // length of array is i = number of points
-
- CvMat** Yj; //length of array is i = num_points
-
- CvMat* S; //big matrix of block Sjk , each block has size num_cam_params x num_cam_params
-
- CvMat* JtJ_diag; //diagonal of JtJ, used to backup diagonal elements before augmentation
-
- CvMat* Vis_index; // matrix which element is index of measurement for point i and camera j
-
- int num_cams;
- int num_points;
- int num_err_param;
- int num_cam_param;
- int num_point_param;
-
- //target function and jacobian pointers, which needs to be initialized
- void (*fjac)(int i, int j, Mat& point_params, Mat& cam_params, Mat& A, Mat& B, void* data);
- void (*func)(int i, int j, Mat& point_params, Mat& cam_params, Mat& estim, void* data);
-
- void* data;
-
- BundleAdjustCallback cb;
- void* user_data;
- };
-
- CV_EXPORTS_W int chamerMatching( Mat& img, Mat& templ,
- CV_OUT vector<vector<Point> >& results, CV_OUT vector<float>& cost,
- double templScale=1, int maxMatches = 20,
- double minMatchDistance = 1.0, int padX = 3,
- int padY = 3, int scales = 5, double minScale = 0.6, double maxScale = 1.6,
- double orientationWeight = 0.5, double truncate = 20);
-
-
- class CV_EXPORTS_W StereoVar
- {
- public:
- // Flags
- enum {USE_INITIAL_DISPARITY = 1, USE_EQUALIZE_HIST = 2, USE_SMART_ID = 4, USE_AUTO_PARAMS = 8, USE_MEDIAN_FILTERING = 16};
- enum {CYCLE_O, CYCLE_V};
- enum {PENALIZATION_TICHONOV, PENALIZATION_CHARBONNIER, PENALIZATION_PERONA_MALIK};
-
- //! the default constructor
- CV_WRAP StereoVar();
-
- //! the full constructor taking all the necessary algorithm parameters
- CV_WRAP StereoVar(int levels, double pyrScale, int nIt, int minDisp, int maxDisp, int poly_n, double poly_sigma, float fi, float lambda, int penalization, int cycle, int flags);
-
- //! the destructor
- virtual ~StereoVar();
-
- //! the stereo correspondence operator that computes disparity map for the specified rectified stereo pair
- CV_WRAP_AS(compute) virtual void operator()(const Mat& left, const Mat& right, CV_OUT Mat& disp);
-
- CV_PROP_RW int levels;
- CV_PROP_RW double pyrScale;
- CV_PROP_RW int nIt;
- CV_PROP_RW int minDisp;
- CV_PROP_RW int maxDisp;
- CV_PROP_RW int poly_n;
- CV_PROP_RW double poly_sigma;
- CV_PROP_RW float fi;
- CV_PROP_RW float lambda;
- CV_PROP_RW int penalization;
- CV_PROP_RW int cycle;
- CV_PROP_RW int flags;
-
- private:
- void autoParams();
- void FMG(Mat &I1, Mat &I2, Mat &I2x, Mat &u, int level);
- void VCycle_MyFAS(Mat &I1_h, Mat &I2_h, Mat &I2x_h, Mat &u_h, int level);
- void VariationalSolver(Mat &I1_h, Mat &I2_h, Mat &I2x_h, Mat &u_h, int level);
- };
-
- CV_EXPORTS void polyfit(const Mat& srcx, const Mat& srcy, Mat& dst, int order);
-
- class CV_EXPORTS Directory
- {
- public:
- static std::vector<std::string> GetListFiles ( const std::string& path, const std::string & exten = "*", bool addPath = true );
- static std::vector<std::string> GetListFilesR ( const std::string& path, const std::string & exten = "*", bool addPath = true );
- static std::vector<std::string> GetListFolders( const std::string& path, const std::string & exten = "*", bool addPath = true );
- };
-
- /*
- * Generation of a set of different colors by the following way:
- * 1) generate more then need colors (in "factor" times) in RGB,
- * 2) convert them to Lab,
- * 3) choose the needed count of colors from the set that are more different from
- * each other,
- * 4) convert the colors back to RGB
- */
- CV_EXPORTS void generateColors( std::vector<Scalar>& colors, size_t count, size_t factor=100 );
-
-
- /*
- * Estimate the rigid body motion from frame0 to frame1. The method is based on the paper
- * "Real-Time Visual Odometry from Dense RGB-D Images", F. Steinbucker, J. Strum, D. Cremers, ICCV, 2011.
- */
- enum { ROTATION = 1,
- TRANSLATION = 2,
- RIGID_BODY_MOTION = 4
- };
- CV_EXPORTS bool RGBDOdometry( Mat& Rt, const Mat& initRt,
- const Mat& image0, const Mat& depth0, const Mat& mask0,
- const Mat& image1, const Mat& depth1, const Mat& mask1,
- const Mat& cameraMatrix, float minDepth=0.f, float maxDepth=4.f, float maxDepthDiff=0.07f,
- const std::vector<int>& iterCounts=std::vector<int>(),
- const std::vector<float>& minGradientMagnitudes=std::vector<float>(),
- int transformType=RIGID_BODY_MOTION );
-
- /**
- *Bilinear interpolation technique.
- *
- *The value of a desired cortical pixel is obtained through a bilinear interpolation of the values
- *of the four nearest neighbouring Cartesian pixels to the center of the RF.
- *The same principle is applied to the inverse transformation.
- *
- *More details can be found in http://dx.doi.org/10.1007/978-3-642-23968-7_5
- */
- class CV_EXPORTS LogPolar_Interp
- {
- public:
-
- LogPolar_Interp() {}
-
- /**
- *Constructor
- *\param w the width of the input image
- *\param h the height of the input image
- *\param center the transformation center: where the output precision is maximal
- *\param R the number of rings of the cortical image (default value 70 pixel)
- *\param ro0 the radius of the blind spot (default value 3 pixel)
- *\param full \a 1 (default value) means that the retinal image (the inverse transform) is computed within the circumscribing circle.
- * \a 0 means that the retinal image is computed within the inscribed circle.
- *\param S the number of sectors of the cortical image (default value 70 pixel).
- * Its value is usually internally computed to obtain a pixel aspect ratio equals to 1.
- *\param sp \a 1 (default value) means that the parameter \a S is internally computed.
- * \a 0 means that the parameter \a S is provided by the user.
- */
- LogPolar_Interp(int w, int h, Point2i center, int R=70, double ro0=3.0,
- int interp=INTER_LINEAR, int full=1, int S=117, int sp=1);
- /**
- *Transformation from Cartesian image to cortical (log-polar) image.
- *\param source the Cartesian image
- *\return the transformed image (cortical image)
- */
- const Mat to_cortical(const Mat &source);
- /**
- *Transformation from cortical image to retinal (inverse log-polar) image.
- *\param source the cortical image
- *\return the transformed image (retinal image)
- */
- const Mat to_cartesian(const Mat &source);
- /**
- *Destructor
- */
- ~LogPolar_Interp();
-
- protected:
-
- Mat Rsri;
- Mat Csri;
-
- int S, R, M, N;
- int top, bottom,left,right;
- double ro0, romax, a, q;
- int interp;
-
- Mat ETAyx;
- Mat CSIyx;
-
- void create_map(int M, int N, int R, int S, double ro0);
- };
-
- /**
- *Overlapping circular receptive fields technique
- *
- *The Cartesian plane is divided in two regions: the fovea and the periphery.
- *The fovea (oversampling) is handled by using the bilinear interpolation technique described above, whereas in
- *the periphery we use the overlapping Gaussian circular RFs.
- *
- *More details can be found in http://dx.doi.org/10.1007/978-3-642-23968-7_5
- */
- class CV_EXPORTS LogPolar_Overlapping
- {
- public:
- LogPolar_Overlapping() {}
-
- /**
- *Constructor
- *\param w the width of the input image
- *\param h the height of the input image
- *\param center the transformation center: where the output precision is maximal
- *\param R the number of rings of the cortical image (default value 70 pixel)
- *\param ro0 the radius of the blind spot (default value 3 pixel)
- *\param full \a 1 (default value) means that the retinal image (the inverse transform) is computed within the circumscribing circle.
- * \a 0 means that the retinal image is computed within the inscribed circle.
- *\param S the number of sectors of the cortical image (default value 70 pixel).
- * Its value is usually internally computed to obtain a pixel aspect ratio equals to 1.
- *\param sp \a 1 (default value) means that the parameter \a S is internally computed.
- * \a 0 means that the parameter \a S is provided by the user.
- */
- LogPolar_Overlapping(int w, int h, Point2i center, int R=70,
- double ro0=3.0, int full=1, int S=117, int sp=1);
- /**
- *Transformation from Cartesian image to cortical (log-polar) image.
- *\param source the Cartesian image
- *\return the transformed image (cortical image)
- */
- const Mat to_cortical(const Mat &source);
- /**
- *Transformation from cortical image to retinal (inverse log-polar) image.
- *\param source the cortical image
- *\return the transformed image (retinal image)
- */
- const Mat to_cartesian(const Mat &source);
- /**
- *Destructor
- */
- ~LogPolar_Overlapping();
-
- protected:
-
- Mat Rsri;
- Mat Csri;
- vector<int> Rsr;
- vector<int> Csr;
- vector<double> Wsr;
-
- int S, R, M, N, ind1;
- int top, bottom,left,right;
- double ro0, romax, a, q;
-
- struct kernel
- {
- kernel() { w = 0; }
- vector<double> weights;
- int w;
- };
-
- Mat ETAyx;
- Mat CSIyx;
- vector<kernel> w_ker_2D;
-
- void create_map(int M, int N, int R, int S, double ro0);
- };
-
- /**
- * Adjacent receptive fields technique
- *
- *All the Cartesian pixels, whose coordinates in the cortical domain share the same integer part, are assigned to the same RF.
- *The precision of the boundaries of the RF can be improved by breaking each pixel into subpixels and assigning each of them to the correct RF.
- *This technique is implemented from: Traver, V., Pla, F.: Log-polar mapping template design: From task-level requirements
- *to geometry parameters. Image Vision Comput. 26(10) (2008) 1354-1370
- *
- *More details can be found in http://dx.doi.org/10.1007/978-3-642-23968-7_5
- */
- class CV_EXPORTS LogPolar_Adjacent
- {
- public:
- LogPolar_Adjacent() {}
-
- /**
- *Constructor
- *\param w the width of the input image
- *\param h the height of the input image
- *\param center the transformation center: where the output precision is maximal
- *\param R the number of rings of the cortical image (default value 70 pixel)
- *\param ro0 the radius of the blind spot (default value 3 pixel)
- *\param smin the size of the subpixel (default value 0.25 pixel)
- *\param full \a 1 (default value) means that the retinal image (the inverse transform) is computed within the circumscribing circle.
- * \a 0 means that the retinal image is computed within the inscribed circle.
- *\param S the number of sectors of the cortical image (default value 70 pixel).
- * Its value is usually internally computed to obtain a pixel aspect ratio equals to 1.
- *\param sp \a 1 (default value) means that the parameter \a S is internally computed.
- * \a 0 means that the parameter \a S is provided by the user.
- */
- LogPolar_Adjacent(int w, int h, Point2i center, int R=70, double ro0=3.0, double smin=0.25, int full=1, int S=117, int sp=1);
- /**
- *Transformation from Cartesian image to cortical (log-polar) image.
- *\param source the Cartesian image
- *\return the transformed image (cortical image)
- */
- const Mat to_cortical(const Mat &source);
- /**
- *Transformation from cortical image to retinal (inverse log-polar) image.
- *\param source the cortical image
- *\return the transformed image (retinal image)
- */
- const Mat to_cartesian(const Mat &source);
- /**
- *Destructor
- */
- ~LogPolar_Adjacent();
-
- protected:
- struct pixel
- {
- pixel() { u = v = 0; a = 0.; }
- int u;
- int v;
- double a;
- };
- int S, R, M, N;
- int top, bottom,left,right;
- double ro0, romax, a, q;
- vector<vector<pixel> > L;
- vector<double> A;
-
- void subdivide_recursively(double x, double y, int i, int j, double length, double smin);
- bool get_uv(double x, double y, int&u, int&v);
- void create_map(int M, int N, int R, int S, double ro0, double smin);
- };
-
- CV_EXPORTS Mat subspaceProject(InputArray W, InputArray mean, InputArray src);
- CV_EXPORTS Mat subspaceReconstruct(InputArray W, InputArray mean, InputArray src);
-
- class CV_EXPORTS LDA
- {
- public:
- // Initializes a LDA with num_components (default 0) and specifies how
- // samples are aligned (default dataAsRow=true).
- LDA(int num_components = 0) :
- _num_components(num_components) {};
-
- // Initializes and performs a Discriminant Analysis with Fisher's
- // Optimization Criterion on given data in src and corresponding labels
- // in labels. If 0 (or less) number of components are given, they are
- // automatically determined for given data in computation.
- LDA(const Mat& src, vector<int> labels,
- int num_components = 0) :
- _num_components(num_components)
- {
- this->compute(src, labels); //! compute eigenvectors and eigenvalues
- }
-
- // Initializes and performs a Discriminant Analysis with Fisher's
- // Optimization Criterion on given data in src and corresponding labels
- // in labels. If 0 (or less) number of components are given, they are
- // automatically determined for given data in computation.
- LDA(InputArrayOfArrays src, InputArray labels,
- int num_components = 0) :
- _num_components(num_components)
- {
- this->compute(src, labels); //! compute eigenvectors and eigenvalues
- }
-
- // Serializes this object to a given filename.
- void save(const string& filename) const;
-
- // Deserializes this object from a given filename.
- void load(const string& filename);
-
- // Serializes this object to a given cv::FileStorage.
- void save(FileStorage& fs) const;
-
- // Deserializes this object from a given cv::FileStorage.
- void load(const FileStorage& node);
-
- // Destructor.
- ~LDA() {}
-
- //! Compute the discriminants for data in src and labels.
- void compute(InputArrayOfArrays src, InputArray labels);
-
- // Projects samples into the LDA subspace.
- Mat project(InputArray src);
-
- // Reconstructs projections from the LDA subspace.
- Mat reconstruct(InputArray src);
-
- // Returns the eigenvectors of this LDA.
- Mat eigenvectors() const { return _eigenvectors; };
-
- // Returns the eigenvalues of this LDA.
- Mat eigenvalues() const { return _eigenvalues; }
-
- protected:
- bool _dataAsRow;
- int _num_components;
- Mat _eigenvectors;
- Mat _eigenvalues;
-
- void lda(InputArrayOfArrays src, InputArray labels);
- };
-
- class CV_EXPORTS_W FaceRecognizer : public Algorithm
- {
- public:
- //! virtual destructor
- virtual ~FaceRecognizer() {}
-
- // Trains a FaceRecognizer.
- CV_WRAP virtual void train(InputArrayOfArrays src, InputArray labels) = 0;
-
- // Updates a FaceRecognizer.
- CV_WRAP void update(InputArrayOfArrays src, InputArray labels);
-
- // Gets a prediction from a FaceRecognizer.
- virtual int predict(InputArray src) const = 0;
-
- // Predicts the label and confidence for a given sample.
- CV_WRAP virtual void predict(InputArray src, CV_OUT int &label, CV_OUT double &confidence) const = 0;
-
- // Serializes this object to a given filename.
- CV_WRAP virtual void save(const string& filename) const;
-
- // Deserializes this object from a given filename.
- CV_WRAP virtual void load(const string& filename);
-
- // Serializes this object to a given cv::FileStorage.
- virtual void save(FileStorage& fs) const = 0;
-
- // Deserializes this object from a given cv::FileStorage.
- virtual void load(const FileStorage& fs) = 0;
-
- };
-
- CV_EXPORTS_W Ptr<FaceRecognizer> createEigenFaceRecognizer(int num_components = 0, double threshold = DBL_MAX);
- CV_EXPORTS_W Ptr<FaceRecognizer> createFisherFaceRecognizer(int num_components = 0, double threshold = DBL_MAX);
- CV_EXPORTS_W Ptr<FaceRecognizer> createLBPHFaceRecognizer(int radius=1, int neighbors=8,
- int grid_x=8, int grid_y=8, double threshold = DBL_MAX);
-
- enum
- {
- COLORMAP_AUTUMN = 0,
- COLORMAP_BONE = 1,
- COLORMAP_JET = 2,
- COLORMAP_WINTER = 3,
- COLORMAP_RAINBOW = 4,
- COLORMAP_OCEAN = 5,
- COLORMAP_SUMMER = 6,
- COLORMAP_SPRING = 7,
- COLORMAP_COOL = 8,
- COLORMAP_HSV = 9,
- COLORMAP_PINK = 10,
- COLORMAP_HOT = 11
- };
-
- CV_EXPORTS_W void applyColorMap(InputArray src, OutputArray dst, int colormap);
-
- CV_EXPORTS bool initModule_contrib();
-}
-
-#include "opencv2/contrib/retina.hpp"
-
-#include "opencv2/contrib/openfabmap.hpp"
-
-#endif
-
+#ifdef __OPENCV_BUILD
+#error this is a compatibility header which should not be used inside the OpenCV library
#endif
- #include "opencv2/contrib.hpp"
++#include "opencv2/contrib.hpp"
}
//fill camera params
//R.clear();T.clear();cameraMatrix.clear();
+ Mat levmarP = cv::cvarrToMat(levmar.P);
for( int i = 0; i < num_cameras; i++ ) {
//rotation
- Mat rot_vec = Mat(levmar.P).rowRange(i*num_cam_param, i*num_cam_param+3);
+ Mat rot_vec = levmarP.rowRange(i*num_cam_param, i*num_cam_param+3);
Rodrigues( rot_vec, R[i] );
//translation
- T[i] = levmarP.rowRange(i*num_cam_param + 3, i*num_cam_param+6);
- Mat(levmar.P).rowRange(i*num_cam_param + 3, i*num_cam_param+6).copyTo(T[i]);
++ levmarP.rowRange(i*num_cam_param + 3, i*num_cam_param+6).copyTo(T[i]);
//intrinsic camera matrix
double* intr_data = (double*)cameraMatrix[i].data;
//
//M*/
-#ifndef __OPENCV_CORE_HPP__
-#define __OPENCV_CORE_HPP__
-
-#include "opencv2/core/types_c.h"
-#include "opencv2/core/version.hpp"
-
-#ifdef __cplusplus
-
-#ifndef SKIP_INCLUDES
-#include <limits.h>
-#include <algorithm>
-#include <cmath>
-#include <cstddef>
-#include <complex>
-#include <map>
-#include <new>
-#include <string>
-#include <vector>
-#include <sstream>
-#endif // SKIP_INCLUDES
-
-/*! \namespace cv
- Namespace where all the C++ OpenCV functionality resides
-*/
-namespace cv {
-
-#undef abs
-#undef min
-#undef max
-#undef Complex
-
-using std::vector;
-using std::string;
-using std::ptrdiff_t;
-
-template<typename _Tp> class CV_EXPORTS Size_;
-template<typename _Tp> class CV_EXPORTS Point_;
-template<typename _Tp> class CV_EXPORTS Rect_;
-template<typename _Tp, int cn> class CV_EXPORTS Vec;
-template<typename _Tp, int m, int n> class CV_EXPORTS Matx;
-
-typedef std::string String;
-
-class Mat;
-class SparseMat;
-typedef Mat MatND;
-
-namespace ogl {
- class Buffer;
- class Texture2D;
- class Arrays;
-}
-
-// < Deprecated
-class GlBuffer;
-class GlTexture;
-class GlArrays;
-class GlCamera;
-// >
-
-namespace gpu {
- class GpuMat;
-}
-
-class CV_EXPORTS MatExpr;
-class CV_EXPORTS MatOp_Base;
-class CV_EXPORTS MatArg;
-class CV_EXPORTS MatConstIterator;
-
-template<typename _Tp> class CV_EXPORTS Mat_;
-template<typename _Tp> class CV_EXPORTS MatIterator_;
-template<typename _Tp> class CV_EXPORTS MatConstIterator_;
-template<typename _Tp> class CV_EXPORTS MatCommaInitializer_;
-
-#if !defined(ANDROID) || (defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_WCHAR_T)
-typedef std::basic_string<wchar_t> WString;
-
-CV_EXPORTS string fromUtf16(const WString& str);
-CV_EXPORTS WString toUtf16(const string& str);
-#endif
-
-CV_EXPORTS string format( const char* fmt, ... );
-CV_EXPORTS string tempfile( const char* suffix CV_DEFAULT(0));
-
-// matrix decomposition types
-enum { DECOMP_LU=0, DECOMP_SVD=1, DECOMP_EIG=2, DECOMP_CHOLESKY=3, DECOMP_QR=4, DECOMP_NORMAL=16 };
-enum { NORM_INF=1, NORM_L1=2, NORM_L2=4, NORM_L2SQR=5, NORM_HAMMING=6, NORM_HAMMING2=7, NORM_TYPE_MASK=7, NORM_RELATIVE=8, NORM_MINMAX=32 };
-enum { CMP_EQ=0, CMP_GT=1, CMP_GE=2, CMP_LT=3, CMP_LE=4, CMP_NE=5 };
-enum { GEMM_1_T=1, GEMM_2_T=2, GEMM_3_T=4 };
-enum { DFT_INVERSE=1, DFT_SCALE=2, DFT_ROWS=4, DFT_COMPLEX_OUTPUT=16, DFT_REAL_OUTPUT=32,
- DCT_INVERSE = DFT_INVERSE, DCT_ROWS=DFT_ROWS };
-
-
-/*!
- The standard OpenCV exception class.
- Instances of the class are thrown by various functions and methods in the case of critical errors.
- */
-class CV_EXPORTS Exception : public std::exception
-{
-public:
- /*!
- Default constructor
- */
- Exception();
- /*!
- Full constructor. Normally the constuctor is not called explicitly.
- Instead, the macros CV_Error(), CV_Error_() and CV_Assert() are used.
- */
- Exception(int _code, const string& _err, const string& _func, const string& _file, int _line);
- virtual ~Exception() throw();
-
- /*!
- \return the error description and the context as a text string.
- */
- virtual const char *what() const throw();
- void formatMessage();
-
- string msg; ///< the formatted error message
-
- int code; ///< error code @see CVStatus
- string err; ///< error description
- string func; ///< function name. Available only when the compiler supports __func__ macro
- string file; ///< source file name where the error has occured
- int line; ///< line number in the source file where the error has occured
-};
-
-
-//! Signals an error and raises the exception.
-
-/*!
- By default the function prints information about the error to stderr,
- then it either stops if setBreakOnError() had been called before or raises the exception.
- It is possible to alternate error processing by using redirectError().
-
- \param exc the exception raisen.
- */
-CV_EXPORTS void error( const Exception& exc );
-
-//! Sets/resets the break-on-error mode.
-
-/*!
- When the break-on-error mode is set, the default error handler
- issues a hardware exception, which can make debugging more convenient.
-
- \return the previous state
- */
-CV_EXPORTS bool setBreakOnError(bool flag);
-
-typedef int (CV_CDECL *ErrorCallback)( int status, const char* func_name,
- const char* err_msg, const char* file_name,
- int line, void* userdata );
-
-//! Sets the new error handler and the optional user data.
-
-/*!
- The function sets the new error handler, called from cv::error().
-
- \param errCallback the new error handler. If NULL, the default error handler is used.
- \param userdata the optional user data pointer, passed to the callback.
- \param prevUserdata the optional output parameter where the previous user data pointer is stored
-
- \return the previous error handler
-*/
-CV_EXPORTS ErrorCallback redirectError( ErrorCallback errCallback,
- void* userdata=0, void** prevUserdata=0);
-
-#ifdef __GNUC__
-#define CV_Error( code, msg ) cv::error( cv::Exception(code, msg, __func__, __FILE__, __LINE__) )
-#define CV_Error_( code, args ) cv::error( cv::Exception(code, cv::format args, __func__, __FILE__, __LINE__) )
-#define CV_Assert( expr ) if(!!(expr)) ; else cv::error( cv::Exception(CV_StsAssert, #expr, __func__, __FILE__, __LINE__) )
-#else
-#define CV_Error( code, msg ) cv::error( cv::Exception(code, msg, "", __FILE__, __LINE__) )
-#define CV_Error_( code, args ) cv::error( cv::Exception(code, cv::format args, "", __FILE__, __LINE__) )
-#define CV_Assert( expr ) if(!!(expr)) ; else cv::error( cv::Exception(CV_StsAssert, #expr, "", __FILE__, __LINE__) )
-#endif
-
-#ifdef _DEBUG
-#define CV_DbgAssert(expr) CV_Assert(expr)
-#else
-#define CV_DbgAssert(expr)
-#endif
-
-CV_EXPORTS void setNumThreads(int nthreads);
-CV_EXPORTS int getNumThreads();
-CV_EXPORTS int getThreadNum();
-
-CV_EXPORTS_W const string& getBuildInformation();
-
-//! Returns the number of ticks.
-
-/*!
- The function returns the number of ticks since the certain event (e.g. when the machine was turned on).
- It can be used to initialize cv::RNG or to measure a function execution time by reading the tick count
- before and after the function call. The granularity of ticks depends on the hardware and OS used. Use
- cv::getTickFrequency() to convert ticks to seconds.
-*/
-CV_EXPORTS_W int64 getTickCount();
-
-/*!
- Returns the number of ticks per seconds.
-
- The function returns the number of ticks (as returned by cv::getTickCount()) per second.
- The following code computes the execution time in milliseconds:
-
- \code
- double exec_time = (double)getTickCount();
- // do something ...
- exec_time = ((double)getTickCount() - exec_time)*1000./getTickFrequency();
- \endcode
-*/
-CV_EXPORTS_W double getTickFrequency();
-
-/*!
- Returns the number of CPU ticks.
-
- On platforms where the feature is available, the function returns the number of CPU ticks
- since the certain event (normally, the system power-on moment). Using this function
- one can accurately measure the execution time of very small code fragments,
- for which cv::getTickCount() granularity is not enough.
-*/
-CV_EXPORTS_W int64 getCPUTickCount();
-
-/*!
- Returns SSE etc. support status
-
- The function returns true if certain hardware features are available.
- Currently, the following features are recognized:
- - CV_CPU_MMX - MMX
- - CV_CPU_SSE - SSE
- - CV_CPU_SSE2 - SSE 2
- - CV_CPU_SSE3 - SSE 3
- - CV_CPU_SSSE3 - SSSE 3
- - CV_CPU_SSE4_1 - SSE 4.1
- - CV_CPU_SSE4_2 - SSE 4.2
- - CV_CPU_POPCNT - POPCOUNT
- - CV_CPU_AVX - AVX
-
- \note {Note that the function output is not static. Once you called cv::useOptimized(false),
- most of the hardware acceleration is disabled and thus the function will returns false,
- until you call cv::useOptimized(true)}
-*/
-CV_EXPORTS_W bool checkHardwareSupport(int feature);
-
-//! returns the number of CPUs (including hyper-threading)
-CV_EXPORTS_W int getNumberOfCPUs();
-
-/*!
- Allocates memory buffer
-
- This is specialized OpenCV memory allocation function that returns properly aligned memory buffers.
- The usage is identical to malloc(). The allocated buffers must be freed with cv::fastFree().
- If there is not enough memory, the function calls cv::error(), which raises an exception.
-
- \param bufSize buffer size in bytes
- \return the allocated memory buffer.
-*/
-CV_EXPORTS void* fastMalloc(size_t bufSize);
-
-/*!
- Frees the memory allocated with cv::fastMalloc
-
- This is the corresponding deallocation function for cv::fastMalloc().
- When ptr==NULL, the function has no effect.
-*/
-CV_EXPORTS void fastFree(void* ptr);
-
-template<typename _Tp> static inline _Tp* allocate(size_t n)
-{
- return new _Tp[n];
-}
-
-template<typename _Tp> static inline void deallocate(_Tp* ptr, size_t)
-{
- delete[] ptr;
-}
-
-/*!
- Aligns pointer by the certain number of bytes
-
- This small inline function aligns the pointer by the certian number of bytes by shifting
- it forward by 0 or a positive offset.
-*/
-template<typename _Tp> static inline _Tp* alignPtr(_Tp* ptr, int n=(int)sizeof(_Tp))
-{
- return (_Tp*)(((size_t)ptr + n-1) & -n);
-}
-
-/*!
- Aligns buffer size by the certain number of bytes
-
- This small inline function aligns a buffer size by the certian number of bytes by enlarging it.
-*/
-static inline size_t alignSize(size_t sz, int n)
-{
- return (sz + n-1) & -n;
-}
-
-/*!
- Turns on/off available optimization
-
- The function turns on or off the optimized code in OpenCV. Some optimization can not be enabled
- or disabled, but, for example, most of SSE code in OpenCV can be temporarily turned on or off this way.
-
- \note{Since optimization may imply using special data structures, it may be unsafe
- to call this function anywhere in the code. Instead, call it somewhere at the top level.}
-*/
-CV_EXPORTS_W void setUseOptimized(bool onoff);
-
-/*!
- Returns the current optimization status
-
- The function returns the current optimization status, which is controlled by cv::setUseOptimized().
-*/
-CV_EXPORTS_W bool useOptimized();
-
-/*!
- The STL-compilant memory Allocator based on cv::fastMalloc() and cv::fastFree()
-*/
-template<typename _Tp> class CV_EXPORTS Allocator
-{
-public:
- typedef _Tp value_type;
- typedef value_type* pointer;
- typedef const value_type* const_pointer;
- typedef value_type& reference;
- typedef const value_type& const_reference;
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- template<typename U> class rebind { typedef Allocator<U> other; };
-
- explicit Allocator() {}
- ~Allocator() {}
- explicit Allocator(Allocator const&) {}
- template<typename U>
- explicit Allocator(Allocator<U> const&) {}
-
- // address
- pointer address(reference r) { return &r; }
- const_pointer address(const_reference r) { return &r; }
-
- pointer allocate(size_type count, const void* =0)
- { return reinterpret_cast<pointer>(fastMalloc(count * sizeof (_Tp))); }
-
- void deallocate(pointer p, size_type) {fastFree(p); }
-
- size_type max_size() const
- { return max(static_cast<_Tp>(-1)/sizeof(_Tp), 1); }
-
- void construct(pointer p, const _Tp& v) { new(static_cast<void*>(p)) _Tp(v); }
- void destroy(pointer p) { p->~_Tp(); }
-};
-
-/////////////////////// Vec (used as element of multi-channel images /////////////////////
-
-/*!
- A helper class for cv::DataType
-
- The class is specialized for each fundamental numerical data type supported by OpenCV.
- It provides DataDepth<T>::value constant.
-*/
-template<typename _Tp> class CV_EXPORTS DataDepth {};
-
-template<> class DataDepth<bool> { public: enum { value = CV_8U, fmt=(int)'u' }; };
-template<> class DataDepth<uchar> { public: enum { value = CV_8U, fmt=(int)'u' }; };
-template<> class DataDepth<schar> { public: enum { value = CV_8S, fmt=(int)'c' }; };
-template<> class DataDepth<char> { public: enum { value = CV_8S, fmt=(int)'c' }; };
-template<> class DataDepth<ushort> { public: enum { value = CV_16U, fmt=(int)'w' }; };
-template<> class DataDepth<short> { public: enum { value = CV_16S, fmt=(int)'s' }; };
-template<> class DataDepth<int> { public: enum { value = CV_32S, fmt=(int)'i' }; };
-// this is temporary solution to support 32-bit unsigned integers
-template<> class DataDepth<unsigned> { public: enum { value = CV_32S, fmt=(int)'i' }; };
-template<> class DataDepth<float> { public: enum { value = CV_32F, fmt=(int)'f' }; };
-template<> class DataDepth<double> { public: enum { value = CV_64F, fmt=(int)'d' }; };
-template<typename _Tp> class DataDepth<_Tp*> { public: enum { value = CV_USRTYPE1, fmt=(int)'r' }; };
-
-
-////////////////////////////// Small Matrix ///////////////////////////
-
-/*!
- A short numerical vector.
-
- This template class represents short numerical vectors (of 1, 2, 3, 4 ... elements)
- on which you can perform basic arithmetical operations, access individual elements using [] operator etc.
- The vectors are allocated on stack, as opposite to std::valarray, std::vector, cv::Mat etc.,
- which elements are dynamically allocated in the heap.
-
- The template takes 2 parameters:
- -# _Tp element type
- -# cn the number of elements
-
- In addition to the universal notation like Vec<float, 3>, you can use shorter aliases
- for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec<float, 3>.
- */
-
-struct CV_EXPORTS Matx_AddOp {};
-struct CV_EXPORTS Matx_SubOp {};
-struct CV_EXPORTS Matx_ScaleOp {};
-struct CV_EXPORTS Matx_MulOp {};
-struct CV_EXPORTS Matx_MatMulOp {};
-struct CV_EXPORTS Matx_TOp {};
-
-template<typename _Tp, int m, int n> class CV_EXPORTS Matx
-{
-public:
- typedef _Tp value_type;
- typedef Matx<_Tp, (m < n ? m : n), 1> diag_type;
- typedef Matx<_Tp, m, n> mat_type;
- enum { depth = DataDepth<_Tp>::value, rows = m, cols = n, channels = rows*cols,
- type = CV_MAKETYPE(depth, channels) };
-
- //! default constructor
- Matx();
-
- Matx(_Tp v0); //!< 1x1 matrix
- Matx(_Tp v0, _Tp v1); //!< 1x2 or 2x1 matrix
- Matx(_Tp v0, _Tp v1, _Tp v2); //!< 1x3 or 3x1 matrix
- Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 1x4, 2x2 or 4x1 matrix
- Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 1x5 or 5x1 matrix
- Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 1x6, 2x3, 3x2 or 6x1 matrix
- Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 1x7 or 7x1 matrix
- Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 1x8, 2x4, 4x2 or 8x1 matrix
- Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 1x9, 3x3 or 9x1 matrix
- Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 1x10, 2x5 or 5x2 or 10x1 matrix
- Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
- _Tp v4, _Tp v5, _Tp v6, _Tp v7,
- _Tp v8, _Tp v9, _Tp v10, _Tp v11); //!< 1x12, 2x6, 3x4, 4x3, 6x2 or 12x1 matrix
- Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
- _Tp v4, _Tp v5, _Tp v6, _Tp v7,
- _Tp v8, _Tp v9, _Tp v10, _Tp v11,
- _Tp v12, _Tp v13, _Tp v14, _Tp v15); //!< 1x16, 4x4 or 16x1 matrix
- explicit Matx(const _Tp* vals); //!< initialize from a plain array
-
- static Matx all(_Tp alpha);
- static Matx zeros();
- static Matx ones();
- static Matx eye();
- static Matx diag(const diag_type& d);
- static Matx randu(_Tp a, _Tp b);
- static Matx randn(_Tp a, _Tp b);
-
- //! dot product computed with the default precision
- _Tp dot(const Matx<_Tp, m, n>& v) const;
-
- //! dot product computed in double-precision arithmetics
- double ddot(const Matx<_Tp, m, n>& v) const;
-
- //! convertion to another data type
- template<typename T2> operator Matx<T2, m, n>() const;
-
- //! change the matrix shape
- template<int m1, int n1> Matx<_Tp, m1, n1> reshape() const;
-
- //! extract part of the matrix
- template<int m1, int n1> Matx<_Tp, m1, n1> get_minor(int i, int j) const;
-
- //! extract the matrix row
- Matx<_Tp, 1, n> row(int i) const;
-
- //! extract the matrix column
- Matx<_Tp, m, 1> col(int i) const;
-
- //! extract the matrix diagonal
- diag_type diag() const;
-
- //! transpose the matrix
- Matx<_Tp, n, m> t() const;
-
- //! invert matrix the matrix
- Matx<_Tp, n, m> inv(int method=DECOMP_LU) const;
-
- //! solve linear system
- template<int l> Matx<_Tp, n, l> solve(const Matx<_Tp, m, l>& rhs, int flags=DECOMP_LU) const;
- Vec<_Tp, n> solve(const Vec<_Tp, m>& rhs, int method) const;
-
- //! multiply two matrices element-wise
- Matx<_Tp, m, n> mul(const Matx<_Tp, m, n>& a) const;
-
- //! element access
- const _Tp& operator ()(int i, int j) const;
- _Tp& operator ()(int i, int j);
-
- //! 1D element access
- const _Tp& operator ()(int i) const;
- _Tp& operator ()(int i);
-
- Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp);
- Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp);
- template<typename _T2> Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp);
- Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp);
- template<int l> Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp);
- Matx(const Matx<_Tp, n, m>& a, Matx_TOp);
-
- _Tp val[m*n]; //< matrix elements
-};
-
-
-typedef Matx<float, 1, 2> Matx12f;
-typedef Matx<double, 1, 2> Matx12d;
-typedef Matx<float, 1, 3> Matx13f;
-typedef Matx<double, 1, 3> Matx13d;
-typedef Matx<float, 1, 4> Matx14f;
-typedef Matx<double, 1, 4> Matx14d;
-typedef Matx<float, 1, 6> Matx16f;
-typedef Matx<double, 1, 6> Matx16d;
-
-typedef Matx<float, 2, 1> Matx21f;
-typedef Matx<double, 2, 1> Matx21d;
-typedef Matx<float, 3, 1> Matx31f;
-typedef Matx<double, 3, 1> Matx31d;
-typedef Matx<float, 4, 1> Matx41f;
-typedef Matx<double, 4, 1> Matx41d;
-typedef Matx<float, 6, 1> Matx61f;
-typedef Matx<double, 6, 1> Matx61d;
-
-typedef Matx<float, 2, 2> Matx22f;
-typedef Matx<double, 2, 2> Matx22d;
-typedef Matx<float, 2, 3> Matx23f;
-typedef Matx<double, 2, 3> Matx23d;
-typedef Matx<float, 3, 2> Matx32f;
-typedef Matx<double, 3, 2> Matx32d;
-
-typedef Matx<float, 3, 3> Matx33f;
-typedef Matx<double, 3, 3> Matx33d;
-
-typedef Matx<float, 3, 4> Matx34f;
-typedef Matx<double, 3, 4> Matx34d;
-typedef Matx<float, 4, 3> Matx43f;
-typedef Matx<double, 4, 3> Matx43d;
-
-typedef Matx<float, 4, 4> Matx44f;
-typedef Matx<double, 4, 4> Matx44d;
-typedef Matx<float, 6, 6> Matx66f;
-typedef Matx<double, 6, 6> Matx66d;
-
-
-/*!
- A short numerical vector.
-
- This template class represents short numerical vectors (of 1, 2, 3, 4 ... elements)
- on which you can perform basic arithmetical operations, access individual elements using [] operator etc.
- The vectors are allocated on stack, as opposite to std::valarray, std::vector, cv::Mat etc.,
- which elements are dynamically allocated in the heap.
-
- The template takes 2 parameters:
- -# _Tp element type
- -# cn the number of elements
-
- In addition to the universal notation like Vec<float, 3>, you can use shorter aliases
- for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec<float, 3>.
-*/
-template<typename _Tp, int cn> class CV_EXPORTS Vec : public Matx<_Tp, cn, 1>
-{
-public:
- typedef _Tp value_type;
- enum { depth = DataDepth<_Tp>::value, channels = cn, type = CV_MAKETYPE(depth, channels) };
-
- //! default constructor
- Vec();
-
- Vec(_Tp v0); //!< 1-element vector constructor
- Vec(_Tp v0, _Tp v1); //!< 2-element vector constructor
- Vec(_Tp v0, _Tp v1, _Tp v2); //!< 3-element vector constructor
- Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 4-element vector constructor
- Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 5-element vector constructor
- Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 6-element vector constructor
- Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 7-element vector constructor
- Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 8-element vector constructor
- Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 9-element vector constructor
- Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 10-element vector constructor
- explicit Vec(const _Tp* values);
-
- Vec(const Vec<_Tp, cn>& v);
-
- static Vec all(_Tp alpha);
-
- //! per-element multiplication
- Vec mul(const Vec<_Tp, cn>& v) const;
-
- //! conjugation (makes sense for complex numbers and quaternions)
- Vec conj() const;
-
- /*!
- cross product of the two 3D vectors.
-
- For other dimensionalities the exception is raised
- */
- Vec cross(const Vec& v) const;
- //! convertion to another data type
- template<typename T2> operator Vec<T2, cn>() const;
- //! conversion to 4-element CvScalar.
- operator CvScalar() const;
-
- /*! element access */
- const _Tp& operator [](int i) const;
- _Tp& operator[](int i);
- const _Tp& operator ()(int i) const;
- _Tp& operator ()(int i);
-
- Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp);
- Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp);
- template<typename _T2> Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp);
-};
-
-
-/* \typedef
-
- Shorter aliases for the most popular specializations of Vec<T,n>
-*/
-typedef Vec<uchar, 2> Vec2b;
-typedef Vec<uchar, 3> Vec3b;
-typedef Vec<uchar, 4> Vec4b;
-
-typedef Vec<short, 2> Vec2s;
-typedef Vec<short, 3> Vec3s;
-typedef Vec<short, 4> Vec4s;
-
-typedef Vec<ushort, 2> Vec2w;
-typedef Vec<ushort, 3> Vec3w;
-typedef Vec<ushort, 4> Vec4w;
-
-typedef Vec<int, 2> Vec2i;
-typedef Vec<int, 3> Vec3i;
-typedef Vec<int, 4> Vec4i;
-typedef Vec<int, 6> Vec6i;
-typedef Vec<int, 8> Vec8i;
-
-typedef Vec<float, 2> Vec2f;
-typedef Vec<float, 3> Vec3f;
-typedef Vec<float, 4> Vec4f;
-typedef Vec<float, 6> Vec6f;
-
-typedef Vec<double, 2> Vec2d;
-typedef Vec<double, 3> Vec3d;
-typedef Vec<double, 4> Vec4d;
-typedef Vec<double, 6> Vec6d;
-
-
-//////////////////////////////// Complex //////////////////////////////
-
-/*!
- A complex number class.
-
- The template class is similar and compatible with std::complex, however it provides slightly
- more convenient access to the real and imaginary parts using through the simple field access, as opposite
- to std::complex::real() and std::complex::imag().
-*/
-template<typename _Tp> class CV_EXPORTS Complex
-{
-public:
-
- //! constructors
- Complex();
- Complex( _Tp _re, _Tp _im=0 );
- Complex( const std::complex<_Tp>& c );
-
- //! conversion to another data type
- template<typename T2> operator Complex<T2>() const;
- //! conjugation
- Complex conj() const;
- //! conversion to std::complex
- operator std::complex<_Tp>() const;
-
- _Tp re, im; //< the real and the imaginary parts
-};
-
-
-/*!
- \typedef
-*/
-typedef Complex<float> Complexf;
-typedef Complex<double> Complexd;
-
-
-//////////////////////////////// Point_ ////////////////////////////////
-
-/*!
- template 2D point class.
-
- The class defines a point in 2D space. Data type of the point coordinates is specified
- as a template parameter. There are a few shorter aliases available for user convenience.
- See cv::Point, cv::Point2i, cv::Point2f and cv::Point2d.
-*/
-template<typename _Tp> class CV_EXPORTS Point_
-{
-public:
- typedef _Tp value_type;
-
- // various constructors
- Point_();
- Point_(_Tp _x, _Tp _y);
- Point_(const Point_& pt);
- Point_(const CvPoint& pt);
- Point_(const CvPoint2D32f& pt);
- Point_(const Size_<_Tp>& sz);
- Point_(const Vec<_Tp, 2>& v);
-
- Point_& operator = (const Point_& pt);
- //! conversion to another data type
- template<typename _Tp2> operator Point_<_Tp2>() const;
-
- //! conversion to the old-style C structures
- operator CvPoint() const;
- operator CvPoint2D32f() const;
- operator Vec<_Tp, 2>() const;
-
- //! dot product
- _Tp dot(const Point_& pt) const;
- //! dot product computed in double-precision arithmetics
- double ddot(const Point_& pt) const;
- //! cross-product
- double cross(const Point_& pt) const;
- //! checks whether the point is inside the specified rectangle
- bool inside(const Rect_<_Tp>& r) const;
-
- _Tp x, y; //< the point coordinates
-};
-
-/*!
- template 3D point class.
-
- The class defines a point in 3D space. Data type of the point coordinates is specified
- as a template parameter.
-
- \see cv::Point3i, cv::Point3f and cv::Point3d
-*/
-template<typename _Tp> class CV_EXPORTS Point3_
-{
-public:
- typedef _Tp value_type;
-
- // various constructors
- Point3_();
- Point3_(_Tp _x, _Tp _y, _Tp _z);
- Point3_(const Point3_& pt);
- explicit Point3_(const Point_<_Tp>& pt);
- Point3_(const CvPoint3D32f& pt);
- Point3_(const Vec<_Tp, 3>& v);
-
- Point3_& operator = (const Point3_& pt);
- //! conversion to another data type
- template<typename _Tp2> operator Point3_<_Tp2>() const;
- //! conversion to the old-style CvPoint...
- operator CvPoint3D32f() const;
- //! conversion to cv::Vec<>
- operator Vec<_Tp, 3>() const;
-
- //! dot product
- _Tp dot(const Point3_& pt) const;
- //! dot product computed in double-precision arithmetics
- double ddot(const Point3_& pt) const;
- //! cross product of the 2 3D points
- Point3_ cross(const Point3_& pt) const;
-
- _Tp x, y, z; //< the point coordinates
-};
-
-//////////////////////////////// Size_ ////////////////////////////////
-
-/*!
- The 2D size class
-
- The class represents the size of a 2D rectangle, image size, matrix size etc.
- Normally, cv::Size ~ cv::Size_<int> is used.
-*/
-template<typename _Tp> class CV_EXPORTS Size_
-{
-public:
- typedef _Tp value_type;
-
- //! various constructors
- Size_();
- Size_(_Tp _width, _Tp _height);
- Size_(const Size_& sz);
- Size_(const CvSize& sz);
- Size_(const CvSize2D32f& sz);
- Size_(const Point_<_Tp>& pt);
-
- Size_& operator = (const Size_& sz);
- //! the area (width*height)
- _Tp area() const;
-
- //! conversion of another data type.
- template<typename _Tp2> operator Size_<_Tp2>() const;
-
- //! conversion to the old-style OpenCV types
- operator CvSize() const;
- operator CvSize2D32f() const;
-
- _Tp width, height; // the width and the height
-};
-
-//////////////////////////////// Rect_ ////////////////////////////////
-
-/*!
- The 2D up-right rectangle class
-
- The class represents a 2D rectangle with coordinates of the specified data type.
- Normally, cv::Rect ~ cv::Rect_<int> is used.
-*/
-template<typename _Tp> class CV_EXPORTS Rect_
-{
-public:
- typedef _Tp value_type;
-
- //! various constructors
- Rect_();
- Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
- Rect_(const Rect_& r);
- Rect_(const CvRect& r);
- Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz);
- Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2);
-
- Rect_& operator = ( const Rect_& r );
- //! the top-left corner
- Point_<_Tp> tl() const;
- //! the bottom-right corner
- Point_<_Tp> br() const;
-
- //! size (width, height) of the rectangle
- Size_<_Tp> size() const;
- //! area (width*height) of the rectangle
- _Tp area() const;
-
- //! conversion to another data type
- template<typename _Tp2> operator Rect_<_Tp2>() const;
- //! conversion to the old-style CvRect
- operator CvRect() const;
-
- //! checks whether the rectangle contains the point
- bool contains(const Point_<_Tp>& pt) const;
-
- _Tp x, y, width, height; //< the top-left corner, as well as width and height of the rectangle
-};
-
-
-/*!
- \typedef
-
- shorter aliases for the most popular cv::Point_<>, cv::Size_<> and cv::Rect_<> specializations
-*/
-typedef Point_<int> Point2i;
-typedef Point2i Point;
-typedef Size_<int> Size2i;
-typedef Size2i Size;
-typedef Rect_<int> Rect;
-typedef Point_<float> Point2f;
-typedef Point_<double> Point2d;
-typedef Size_<float> Size2f;
-typedef Point3_<int> Point3i;
-typedef Point3_<float> Point3f;
-typedef Point3_<double> Point3d;
-
-
-/*!
- The rotated 2D rectangle.
-
- The class represents rotated (i.e. not up-right) rectangles on a plane.
- Each rectangle is described by the center point (mass center), length of each side
- (represented by cv::Size2f structure) and the rotation angle in degrees.
-*/
-class CV_EXPORTS RotatedRect
-{
-public:
- //! various constructors
- RotatedRect();
- RotatedRect(const Point2f& center, const Size2f& size, float angle);
- RotatedRect(const CvBox2D& box);
-
- //! returns 4 vertices of the rectangle
- void points(Point2f pts[]) const;
- //! returns the minimal up-right rectangle containing the rotated rectangle
- Rect boundingRect() const;
- //! conversion to the old-style CvBox2D structure
- operator CvBox2D() const;
-
- Point2f center; //< the rectangle mass center
- Size2f size; //< width and height of the rectangle
- float angle; //< the rotation angle. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle.
-};
-
-//////////////////////////////// Scalar_ ///////////////////////////////
-
-/*!
- The template scalar class.
-
- This is partially specialized cv::Vec class with the number of elements = 4, i.e. a short vector of four elements.
- Normally, cv::Scalar ~ cv::Scalar_<double> is used.
-*/
-template<typename _Tp> class CV_EXPORTS Scalar_ : public Vec<_Tp, 4>
-{
-public:
- //! various constructors
- Scalar_();
- Scalar_(_Tp v0, _Tp v1, _Tp v2=0, _Tp v3=0);
- Scalar_(const CvScalar& s);
- Scalar_(_Tp v0);
-
- //! returns a scalar with all elements set to v0
- static Scalar_<_Tp> all(_Tp v0);
- //! conversion to the old-style CvScalar
- operator CvScalar() const;
-
- //! conversion to another data type
- template<typename T2> operator Scalar_<T2>() const;
-
- //! per-element product
- Scalar_<_Tp> mul(const Scalar_<_Tp>& t, double scale=1 ) const;
-
- // returns (v0, -v1, -v2, -v3)
- Scalar_<_Tp> conj() const;
-
- // returns true iff v1 == v2 == v3 == 0
- bool isReal() const;
-};
-
-typedef Scalar_<double> Scalar;
-
-CV_EXPORTS void scalarToRawData(const Scalar& s, void* buf, int type, int unroll_to=0);
-
-//////////////////////////////// Range /////////////////////////////////
-
-/*!
- The 2D range class
-
- This is the class used to specify a continuous subsequence, i.e. part of a contour, or a column span in a matrix.
-*/
-class CV_EXPORTS Range
-{
-public:
- Range();
- Range(int _start, int _end);
- Range(const CvSlice& slice);
- int size() const;
- bool empty() const;
- static Range all();
- operator CvSlice() const;
-
- int start, end;
-};
-
-/////////////////////////////// DataType ////////////////////////////////
-
-/*!
- Informative template class for OpenCV "scalars".
-
- The class is specialized for each primitive numerical type supported by OpenCV (such as unsigned char or float),
- as well as for more complex types, like cv::Complex<>, std::complex<>, cv::Vec<> etc.
- The common property of all such types (called "scalars", do not confuse it with cv::Scalar_)
- is that each of them is basically a tuple of numbers of the same type. Each "scalar" can be represented
- by the depth id (CV_8U ... CV_64F) and the number of channels.
- OpenCV matrices, 2D or nD, dense or sparse, can store "scalars",
- as long as the number of channels does not exceed CV_CN_MAX.
-*/
-template<typename _Tp> class DataType
-{
-public:
- typedef _Tp value_type;
- typedef value_type work_type;
- typedef value_type channel_type;
- typedef value_type vec_type;
- enum { generic_type = 1, depth = -1, channels = 1, fmt=0,
- type = CV_MAKETYPE(depth, channels) };
-};
-
-template<> class DataType<bool>
-{
-public:
- typedef bool value_type;
- typedef int work_type;
- typedef value_type channel_type;
- typedef value_type vec_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 1,
- fmt=DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
-};
-
-template<> class DataType<uchar>
-{
-public:
- typedef uchar value_type;
- typedef int work_type;
- typedef value_type channel_type;
- typedef value_type vec_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 1,
- fmt=DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
-};
-
-template<> class DataType<schar>
-{
-public:
- typedef schar value_type;
- typedef int work_type;
- typedef value_type channel_type;
- typedef value_type vec_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 1,
- fmt=DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
-};
-
-template<> class DataType<char>
-{
-public:
- typedef schar value_type;
- typedef int work_type;
- typedef value_type channel_type;
- typedef value_type vec_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 1,
- fmt=DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
-};
-
-template<> class DataType<ushort>
-{
-public:
- typedef ushort value_type;
- typedef int work_type;
- typedef value_type channel_type;
- typedef value_type vec_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 1,
- fmt=DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
-};
-
-template<> class DataType<short>
-{
-public:
- typedef short value_type;
- typedef int work_type;
- typedef value_type channel_type;
- typedef value_type vec_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 1,
- fmt=DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
-};
-
-template<> class DataType<int>
-{
-public:
- typedef int value_type;
- typedef value_type work_type;
- typedef value_type channel_type;
- typedef value_type vec_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 1,
- fmt=DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
-};
-
-template<> class DataType<float>
-{
-public:
- typedef float value_type;
- typedef value_type work_type;
- typedef value_type channel_type;
- typedef value_type vec_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 1,
- fmt=DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
-};
-
-template<> class DataType<double>
-{
-public:
- typedef double value_type;
- typedef value_type work_type;
- typedef value_type channel_type;
- typedef value_type vec_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 1,
- fmt=DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
-};
-
-template<typename _Tp, int m, int n> class DataType<Matx<_Tp, m, n> >
-{
-public:
- typedef Matx<_Tp, m, n> value_type;
- typedef Matx<typename DataType<_Tp>::work_type, m, n> work_type;
- typedef _Tp channel_type;
- typedef value_type vec_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = m*n,
- fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
-};
-
-template<typename _Tp, int cn> class DataType<Vec<_Tp, cn> >
-{
-public:
- typedef Vec<_Tp, cn> value_type;
- typedef Vec<typename DataType<_Tp>::work_type, cn> work_type;
- typedef _Tp channel_type;
- typedef value_type vec_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = cn,
- fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
-};
-
-template<typename _Tp> class DataType<std::complex<_Tp> >
-{
-public:
- typedef std::complex<_Tp> value_type;
- typedef value_type work_type;
- typedef _Tp channel_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 2,
- fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
- typedef Vec<channel_type, channels> vec_type;
-};
-
-template<typename _Tp> class DataType<Complex<_Tp> >
-{
-public:
- typedef Complex<_Tp> value_type;
- typedef value_type work_type;
- typedef _Tp channel_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 2,
- fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
- typedef Vec<channel_type, channels> vec_type;
-};
-
-template<typename _Tp> class DataType<Point_<_Tp> >
-{
-public:
- typedef Point_<_Tp> value_type;
- typedef Point_<typename DataType<_Tp>::work_type> work_type;
- typedef _Tp channel_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 2,
- fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
- typedef Vec<channel_type, channels> vec_type;
-};
-
-template<typename _Tp> class DataType<Point3_<_Tp> >
-{
-public:
- typedef Point3_<_Tp> value_type;
- typedef Point3_<typename DataType<_Tp>::work_type> work_type;
- typedef _Tp channel_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 3,
- fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
- typedef Vec<channel_type, channels> vec_type;
-};
-
-template<typename _Tp> class DataType<Size_<_Tp> >
-{
-public:
- typedef Size_<_Tp> value_type;
- typedef Size_<typename DataType<_Tp>::work_type> work_type;
- typedef _Tp channel_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 2,
- fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
- typedef Vec<channel_type, channels> vec_type;
-};
-
-template<typename _Tp> class DataType<Rect_<_Tp> >
-{
-public:
- typedef Rect_<_Tp> value_type;
- typedef Rect_<typename DataType<_Tp>::work_type> work_type;
- typedef _Tp channel_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 4,
- fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
- typedef Vec<channel_type, channels> vec_type;
-};
-
-template<typename _Tp> class DataType<Scalar_<_Tp> >
-{
-public:
- typedef Scalar_<_Tp> value_type;
- typedef Scalar_<typename DataType<_Tp>::work_type> work_type;
- typedef _Tp channel_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 4,
- fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
- typedef Vec<channel_type, channels> vec_type;
-};
-
-template<> class DataType<Range>
-{
-public:
- typedef Range value_type;
- typedef value_type work_type;
- typedef int channel_type;
- enum { generic_type = 0, depth = DataDepth<channel_type>::value, channels = 2,
- fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
- type = CV_MAKETYPE(depth, channels) };
- typedef Vec<channel_type, channels> vec_type;
-};
-
-//////////////////// generic_type ref-counting pointer class for C/C++ objects ////////////////////////
-
-/*!
- Smart pointer to dynamically allocated objects.
-
- This is template pointer-wrapping class that stores the associated reference counter along with the
- object pointer. The class is similar to std::smart_ptr<> from the recent addons to the C++ standard,
- but is shorter to write :) and self-contained (i.e. does add any dependency on the compiler or an external library).
-
- Basically, you can use "Ptr<MyObjectType> ptr" (or faster "const Ptr<MyObjectType>& ptr" for read-only access)
- everywhere instead of "MyObjectType* ptr", where MyObjectType is some C structure or a C++ class.
- To make it all work, you need to specialize Ptr<>::delete_obj(), like:
-
- \code
- template<> void Ptr<MyObjectType>::delete_obj() { call_destructor_func(obj); }
- \endcode
-
- \note{if MyObjectType is a C++ class with a destructor, you do not need to specialize delete_obj(),
- since the default implementation calls "delete obj;"}
-
- \note{Another good property of the class is that the operations on the reference counter are atomic,
- i.e. it is safe to use the class in multi-threaded applications}
-*/
-template<typename _Tp> class CV_EXPORTS Ptr
-{
-public:
- //! empty constructor
- Ptr();
- //! take ownership of the pointer. The associated reference counter is allocated and set to 1
- Ptr(_Tp* _obj);
- //! calls release()
- ~Ptr();
- //! copy constructor. Copies the members and calls addref()
- Ptr(const Ptr& ptr);
- template<typename _Tp2> Ptr(const Ptr<_Tp2>& ptr);
- //! copy operator. Calls ptr.addref() and release() before copying the members
- Ptr& operator = (const Ptr& ptr);
- //! increments the reference counter
- void addref();
- //! decrements the reference counter. If it reaches 0, delete_obj() is called
- void release();
- //! deletes the object. Override if needed
- void delete_obj();
- //! returns true iff obj==NULL
- bool empty() const;
-
- //! cast pointer to another type
- template<typename _Tp2> Ptr<_Tp2> ptr();
- template<typename _Tp2> const Ptr<_Tp2> ptr() const;
-
- //! helper operators making "Ptr<T> ptr" use very similar to "T* ptr".
- _Tp* operator -> ();
- const _Tp* operator -> () const;
-
- operator _Tp* ();
- operator const _Tp*() const;
-
- _Tp* obj; //< the object pointer.
- int* refcount; //< the associated reference counter
-};
-
-
-//////////////////////// Input/Output Array Arguments /////////////////////////////////
-
-/*!
- Proxy datatype for passing Mat's and vector<>'s as input parameters
- */
-class CV_EXPORTS _InputArray
-{
-public:
- enum {
- KIND_SHIFT = 16,
- FIXED_TYPE = 0x8000 << KIND_SHIFT,
- FIXED_SIZE = 0x4000 << KIND_SHIFT,
- KIND_MASK = ~(FIXED_TYPE|FIXED_SIZE) - (1 << KIND_SHIFT) + 1,
-
- NONE = 0 << KIND_SHIFT,
- MAT = 1 << KIND_SHIFT,
- MATX = 2 << KIND_SHIFT,
- STD_VECTOR = 3 << KIND_SHIFT,
- STD_VECTOR_VECTOR = 4 << KIND_SHIFT,
- STD_VECTOR_MAT = 5 << KIND_SHIFT,
- EXPR = 6 << KIND_SHIFT,
- OPENGL_BUFFER = 7 << KIND_SHIFT,
- OPENGL_TEXTURE = 8 << KIND_SHIFT,
- GPU_MAT = 9 << KIND_SHIFT
- };
- _InputArray();
-
- _InputArray(const Mat& m);
- _InputArray(const MatExpr& expr);
- template<typename _Tp> _InputArray(const _Tp* vec, int n);
- template<typename _Tp> _InputArray(const vector<_Tp>& vec);
- template<typename _Tp> _InputArray(const vector<vector<_Tp> >& vec);
- _InputArray(const vector<Mat>& vec);
- template<typename _Tp> _InputArray(const vector<Mat_<_Tp> >& vec);
- template<typename _Tp> _InputArray(const Mat_<_Tp>& m);
- template<typename _Tp, int m, int n> _InputArray(const Matx<_Tp, m, n>& matx);
- _InputArray(const Scalar& s);
- _InputArray(const double& val);
- // < Deprecated
- _InputArray(const GlBuffer& buf);
- _InputArray(const GlTexture& tex);
- // >
- _InputArray(const gpu::GpuMat& d_mat);
- _InputArray(const ogl::Buffer& buf);
- _InputArray(const ogl::Texture2D& tex);
-
- virtual Mat getMat(int i=-1) const;
- virtual void getMatVector(vector<Mat>& mv) const;
- // < Deprecated
- virtual GlBuffer getGlBuffer() const;
- virtual GlTexture getGlTexture() const;
- // >
- virtual gpu::GpuMat getGpuMat() const;
- /*virtual*/ ogl::Buffer getOGlBuffer() const;
- /*virtual*/ ogl::Texture2D getOGlTexture2D() const;
-
- virtual int kind() const;
- virtual Size size(int i=-1) const;
- virtual size_t total(int i=-1) const;
- virtual int type(int i=-1) const;
- virtual int depth(int i=-1) const;
- virtual int channels(int i=-1) const;
- virtual bool empty() const;
-
-#ifdef OPENCV_CAN_BREAK_BINARY_COMPATIBILITY
- virtual ~_InputArray();
-#endif
-
- int flags;
- void* obj;
- Size sz;
-};
-
-
-enum
-{
- DEPTH_MASK_8U = 1 << CV_8U,
- DEPTH_MASK_8S = 1 << CV_8S,
- DEPTH_MASK_16U = 1 << CV_16U,
- DEPTH_MASK_16S = 1 << CV_16S,
- DEPTH_MASK_32S = 1 << CV_32S,
- DEPTH_MASK_32F = 1 << CV_32F,
- DEPTH_MASK_64F = 1 << CV_64F,
- DEPTH_MASK_ALL = (DEPTH_MASK_64F<<1)-1,
- DEPTH_MASK_ALL_BUT_8S = DEPTH_MASK_ALL & ~DEPTH_MASK_8S,
- DEPTH_MASK_FLT = DEPTH_MASK_32F + DEPTH_MASK_64F
-};
-
-
-/*!
- Proxy datatype for passing Mat's and vector<>'s as input parameters
- */
-class CV_EXPORTS _OutputArray : public _InputArray
-{
-public:
- _OutputArray();
-
- _OutputArray(Mat& m);
- template<typename _Tp> _OutputArray(vector<_Tp>& vec);
- template<typename _Tp> _OutputArray(vector<vector<_Tp> >& vec);
- _OutputArray(vector<Mat>& vec);
- template<typename _Tp> _OutputArray(vector<Mat_<_Tp> >& vec);
- template<typename _Tp> _OutputArray(Mat_<_Tp>& m);
- template<typename _Tp, int m, int n> _OutputArray(Matx<_Tp, m, n>& matx);
- template<typename _Tp> _OutputArray(_Tp* vec, int n);
- _OutputArray(gpu::GpuMat& d_mat);
- _OutputArray(ogl::Buffer& buf);
- _OutputArray(ogl::Texture2D& tex);
-
- _OutputArray(const Mat& m);
- template<typename _Tp> _OutputArray(const vector<_Tp>& vec);
- template<typename _Tp> _OutputArray(const vector<vector<_Tp> >& vec);
- _OutputArray(const vector<Mat>& vec);
- template<typename _Tp> _OutputArray(const vector<Mat_<_Tp> >& vec);
- template<typename _Tp> _OutputArray(const Mat_<_Tp>& m);
- template<typename _Tp, int m, int n> _OutputArray(const Matx<_Tp, m, n>& matx);
- template<typename _Tp> _OutputArray(const _Tp* vec, int n);
- _OutputArray(const gpu::GpuMat& d_mat);
- _OutputArray(const ogl::Buffer& buf);
- _OutputArray(const ogl::Texture2D& tex);
-
- virtual bool fixedSize() const;
- virtual bool fixedType() const;
- virtual bool needed() const;
- virtual Mat& getMatRef(int i=-1) const;
- /*virtual*/ gpu::GpuMat& getGpuMatRef() const;
- /*virtual*/ ogl::Buffer& getOGlBufferRef() const;
- /*virtual*/ ogl::Texture2D& getOGlTexture2DRef() const;
- virtual void create(Size sz, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
- virtual void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
- virtual void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
- virtual void release() const;
- virtual void clear() const;
-
-#ifdef OPENCV_CAN_BREAK_BINARY_COMPATIBILITY
- virtual ~_OutputArray();
+#ifdef __OPENCV_BUILD
+#error this is a compatibility header which should not be used inside the OpenCV library
#endif
-};
-
-typedef const _InputArray& InputArray;
-typedef InputArray InputArrayOfArrays;
-typedef const _OutputArray& OutputArray;
-typedef OutputArray OutputArrayOfArrays;
-typedef OutputArray InputOutputArray;
-typedef OutputArray InputOutputArrayOfArrays;
-
-CV_EXPORTS OutputArray noArray();
-
-/////////////////////////////////////// Mat ///////////////////////////////////////////
-
-enum { MAGIC_MASK=0xFFFF0000, TYPE_MASK=0x00000FFF, DEPTH_MASK=7 };
-
-static inline size_t getElemSize(int type) { return CV_ELEM_SIZE(type); }
-
-/*!
- Custom array allocator
-
-*/
-class CV_EXPORTS MatAllocator
-{
-public:
- MatAllocator() {}
- virtual ~MatAllocator() {}
- virtual void allocate(int dims, const int* sizes, int type, int*& refcount,
- uchar*& datastart, uchar*& data, size_t* step) = 0;
- virtual void deallocate(int* refcount, uchar* datastart, uchar* data) = 0;
-};
-
-/*!
- The n-dimensional matrix class.
-
- The class represents an n-dimensional dense numerical array that can act as
- a matrix, image, optical flow map, 3-focal tensor etc.
- It is very similar to CvMat and CvMatND types from earlier versions of OpenCV,
- and similarly to those types, the matrix can be multi-channel. It also fully supports ROI mechanism.
-
- There are many different ways to create cv::Mat object. Here are the some popular ones:
- <ul>
- <li> using cv::Mat::create(nrows, ncols, type) method or
- the similar constructor cv::Mat::Mat(nrows, ncols, type[, fill_value]) constructor.
- A new matrix of the specified size and specifed type will be allocated.
- "type" has the same meaning as in cvCreateMat function,
- e.g. CV_8UC1 means 8-bit single-channel matrix, CV_32FC2 means 2-channel (i.e. complex)
- floating-point matrix etc:
-
- \code
- // make 7x7 complex matrix filled with 1+3j.
- cv::Mat M(7,7,CV_32FC2,Scalar(1,3));
- // and now turn M to 100x60 15-channel 8-bit matrix.
- // The old content will be deallocated
- M.create(100,60,CV_8UC(15));
- \endcode
-
- As noted in the introduction of this chapter, Mat::create()
- will only allocate a new matrix when the current matrix dimensionality
- or type are different from the specified.
-
- <li> by using a copy constructor or assignment operator, where on the right side it can
- be a matrix or expression, see below. Again, as noted in the introduction,
- matrix assignment is O(1) operation because it only copies the header
- and increases the reference counter. cv::Mat::clone() method can be used to get a full
- (a.k.a. deep) copy of the matrix when you need it.
-
- <li> by constructing a header for a part of another matrix. It can be a single row, single column,
- several rows, several columns, rectangular region in the matrix (called a minor in algebra) or
- a diagonal. Such operations are also O(1), because the new header will reference the same data.
- You can actually modify a part of the matrix using this feature, e.g.
-
- \code
- // add 5-th row, multiplied by 3 to the 3rd row
- M.row(3) = M.row(3) + M.row(5)*3;
-
- // now copy 7-th column to the 1-st column
- // M.col(1) = M.col(7); // this will not work
- Mat M1 = M.col(1);
- M.col(7).copyTo(M1);
-
- // create new 320x240 image
- cv::Mat img(Size(320,240),CV_8UC3);
- // select a roi
- cv::Mat roi(img, Rect(10,10,100,100));
- // fill the ROI with (0,255,0) (which is green in RGB space);
- // the original 320x240 image will be modified
- roi = Scalar(0,255,0);
- \endcode
-
- Thanks to the additional cv::Mat::datastart and cv::Mat::dataend members, it is possible to
- compute the relative sub-matrix position in the main "container" matrix using cv::Mat::locateROI():
-
- \code
- Mat A = Mat::eye(10, 10, CV_32S);
- // extracts A columns, 1 (inclusive) to 3 (exclusive).
- Mat B = A(Range::all(), Range(1, 3));
- // extracts B rows, 5 (inclusive) to 9 (exclusive).
- // that is, C ~ A(Range(5, 9), Range(1, 3))
- Mat C = B(Range(5, 9), Range::all());
- Size size; Point ofs;
- C.locateROI(size, ofs);
- // size will be (width=10,height=10) and the ofs will be (x=1, y=5)
- \endcode
-
- As in the case of whole matrices, if you need a deep copy, use cv::Mat::clone() method
- of the extracted sub-matrices.
-
- <li> by making a header for user-allocated-data. It can be useful for
- <ol>
- <li> processing "foreign" data using OpenCV (e.g. when you implement
- a DirectShow filter or a processing module for gstreamer etc.), e.g.
-
- \code
- void process_video_frame(const unsigned char* pixels,
- int width, int height, int step)
- {
- cv::Mat img(height, width, CV_8UC3, pixels, step);
- cv::GaussianBlur(img, img, cv::Size(7,7), 1.5, 1.5);
- }
- \endcode
-
- <li> for quick initialization of small matrices and/or super-fast element access
-
- \code
- double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}};
- cv::Mat M = cv::Mat(3, 3, CV_64F, m).inv();
- \endcode
- </ol>
-
- partial yet very common cases of this "user-allocated data" case are conversions
- from CvMat and IplImage to cv::Mat. For this purpose there are special constructors
- taking pointers to CvMat or IplImage and the optional
- flag indicating whether to copy the data or not.
-
- Backward conversion from cv::Mat to CvMat or IplImage is provided via cast operators
- cv::Mat::operator CvMat() an cv::Mat::operator IplImage().
- The operators do not copy the data.
-
-
- \code
- IplImage* img = cvLoadImage("greatwave.jpg", 1);
- Mat mtx(img); // convert IplImage* -> cv::Mat
- CvMat oldmat = mtx; // convert cv::Mat -> CvMat
- CV_Assert(oldmat.cols == img->width && oldmat.rows == img->height &&
- oldmat.data.ptr == (uchar*)img->imageData && oldmat.step == img->widthStep);
- \endcode
-
- <li> by using MATLAB-style matrix initializers, cv::Mat::zeros(), cv::Mat::ones(), cv::Mat::eye(), e.g.:
-
- \code
- // create a double-precision identity martix and add it to M.
- M += Mat::eye(M.rows, M.cols, CV_64F);
- \endcode
-
- <li> by using comma-separated initializer:
-
- \code
- // create 3x3 double-precision identity matrix
- Mat M = (Mat_<double>(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);
- \endcode
-
- here we first call constructor of cv::Mat_ class (that we describe further) with the proper matrix,
- and then we just put "<<" operator followed by comma-separated values that can be constants,
- variables, expressions etc. Also, note the extra parentheses that are needed to avoid compiler errors.
-
- </ul>
-
- Once matrix is created, it will be automatically managed by using reference-counting mechanism
- (unless the matrix header is built on top of user-allocated data,
- in which case you should handle the data by yourself).
- The matrix data will be deallocated when no one points to it;
- if you want to release the data pointed by a matrix header before the matrix destructor is called,
- use cv::Mat::release().
-
- The next important thing to learn about the matrix class is element access. Here is how the matrix is stored.
- The elements are stored in row-major order (row by row). The cv::Mat::data member points to the first element of the first row,
- cv::Mat::rows contains the number of matrix rows and cv::Mat::cols - the number of matrix columns. There is yet another member,
- cv::Mat::step that is used to actually compute address of a matrix element. cv::Mat::step is needed because the matrix can be
- a part of another matrix or because there can some padding space in the end of each row for a proper alignment.
-
- \image html roi.png
-
- Given these parameters, address of the matrix element M_{ij} is computed as following:
-
- addr(M_{ij})=M.data + M.step*i + j*M.elemSize()
-
- if you know the matrix element type, e.g. it is float, then you can use cv::Mat::at() method:
-
- addr(M_{ij})=&M.at<float>(i,j)
-
- (where & is used to convert the reference returned by cv::Mat::at() to a pointer).
- if you need to process a whole row of matrix, the most efficient way is to get
- the pointer to the row first, and then just use plain C operator []:
-
- \code
- // compute sum of positive matrix elements
- // (assuming that M is double-precision matrix)
- double sum=0;
- for(int i = 0; i < M.rows; i++)
- {
- const double* Mi = M.ptr<double>(i);
- for(int j = 0; j < M.cols; j++)
- sum += std::max(Mi[j], 0.);
- }
- \endcode
-
- Some operations, like the above one, do not actually depend on the matrix shape,
- they just process elements of a matrix one by one (or elements from multiple matrices
- that are sitting in the same place, e.g. matrix addition). Such operations are called
- element-wise and it makes sense to check whether all the input/output matrices are continuous,
- i.e. have no gaps in the end of each row, and if yes, process them as a single long row:
-
- \code
- // compute sum of positive matrix elements, optimized variant
- double sum=0;
- int cols = M.cols, rows = M.rows;
- if(M.isContinuous())
- {
- cols *= rows;
- rows = 1;
- }
- for(int i = 0; i < rows; i++)
- {
- const double* Mi = M.ptr<double>(i);
- for(int j = 0; j < cols; j++)
- sum += std::max(Mi[j], 0.);
- }
- \endcode
- in the case of continuous matrix the outer loop body will be executed just once,
- so the overhead will be smaller, which will be especially noticeable in the case of small matrices.
-
- Finally, there are STL-style iterators that are smart enough to skip gaps between successive rows:
- \code
- // compute sum of positive matrix elements, iterator-based variant
- double sum=0;
- MatConstIterator_<double> it = M.begin<double>(), it_end = M.end<double>();
- for(; it != it_end; ++it)
- sum += std::max(*it, 0.);
- \endcode
-
- The matrix iterators are random-access iterators, so they can be passed
- to any STL algorithm, including std::sort().
-*/
-class CV_EXPORTS Mat
-{
-public:
- //! default constructor
- Mat();
- //! constructs 2D matrix of the specified size and type
- // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
- Mat(int rows, int cols, int type);
- Mat(Size size, int type);
- //! constucts 2D matrix and fills it with the specified value _s.
- Mat(int rows, int cols, int type, const Scalar& s);
- Mat(Size size, int type, const Scalar& s);
-
- //! constructs n-dimensional matrix
- Mat(int ndims, const int* sizes, int type);
- Mat(int ndims, const int* sizes, int type, const Scalar& s);
-
- //! copy constructor
- Mat(const Mat& m);
- //! constructor for matrix headers pointing to user-allocated data
- Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP);
- Mat(Size size, int type, void* data, size_t step=AUTO_STEP);
- Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0);
-
- //! creates a matrix header for a part of the bigger matrix
- Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all());
- Mat(const Mat& m, const Rect& roi);
- Mat(const Mat& m, const Range* ranges);
- //! converts old-style CvMat to the new matrix; the data is not copied by default
- Mat(const CvMat* m, bool copyData=false);
- //! converts old-style CvMatND to the new matrix; the data is not copied by default
- Mat(const CvMatND* m, bool copyData=false);
- //! converts old-style IplImage to the new matrix; the data is not copied by default
- Mat(const IplImage* img, bool copyData=false);
- //! builds matrix from std::vector with or without copying the data
- template<typename _Tp> explicit Mat(const vector<_Tp>& vec, bool copyData=false);
- //! builds matrix from cv::Vec; the data is copied by default
- template<typename _Tp, int n> explicit Mat(const Vec<_Tp, n>& vec, bool copyData=true);
- //! builds matrix from cv::Matx; the data is copied by default
- template<typename _Tp, int m, int n> explicit Mat(const Matx<_Tp, m, n>& mtx, bool copyData=true);
- //! builds matrix from a 2D point
- template<typename _Tp> explicit Mat(const Point_<_Tp>& pt, bool copyData=true);
- //! builds matrix from a 3D point
- template<typename _Tp> explicit Mat(const Point3_<_Tp>& pt, bool copyData=true);
- //! builds matrix from comma initializer
- template<typename _Tp> explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer);
-
- //! download data from GpuMat
- explicit Mat(const gpu::GpuMat& m);
-
- //! destructor - calls release()
- ~Mat();
- //! assignment operators
- Mat& operator = (const Mat& m);
- Mat& operator = (const MatExpr& expr);
-
- //! returns a new matrix header for the specified row
- Mat row(int y) const;
- //! returns a new matrix header for the specified column
- Mat col(int x) const;
- //! ... for the specified row span
- Mat rowRange(int startrow, int endrow) const;
- Mat rowRange(const Range& r) const;
- //! ... for the specified column span
- Mat colRange(int startcol, int endcol) const;
- Mat colRange(const Range& r) const;
- //! ... for the specified diagonal
- // (d=0 - the main diagonal,
- // >0 - a diagonal from the lower half,
- // <0 - a diagonal from the upper half)
- Mat diag(int d=0) const;
- //! constructs a square diagonal matrix which main diagonal is vector "d"
- static Mat diag(const Mat& d);
-
- //! returns deep copy of the matrix, i.e. the data is copied
- Mat clone() const;
- //! copies the matrix content to "m".
- // It calls m.create(this->size(), this->type()).
- void copyTo( OutputArray m ) const;
- //! copies those matrix elements to "m" that are marked with non-zero mask elements.
- void copyTo( OutputArray m, InputArray mask ) const;
- //! converts matrix to another datatype with optional scalng. See cvConvertScale.
- void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;
-
- void assignTo( Mat& m, int type=-1 ) const;
-
- //! sets every matrix element to s
- Mat& operator = (const Scalar& s);
- //! sets some of the matrix elements to s, according to the mask
- Mat& setTo(InputArray value, InputArray mask=noArray());
- //! creates alternative matrix header for the same data, with different
- // number of channels and/or different number of rows. see cvReshape.
- Mat reshape(int cn, int rows=0) const;
- Mat reshape(int cn, int newndims, const int* newsz) const;
-
- //! matrix transposition by means of matrix expressions
- MatExpr t() const;
- //! matrix inversion by means of matrix expressions
- MatExpr inv(int method=DECOMP_LU) const;
- //! per-element matrix multiplication by means of matrix expressions
- MatExpr mul(InputArray m, double scale=1) const;
-
- //! computes cross-product of 2 3D vectors
- Mat cross(InputArray m) const;
- //! computes dot-product
- double dot(InputArray m) const;
-
- //! Matlab-style matrix initialization
- static MatExpr zeros(int rows, int cols, int type);
- static MatExpr zeros(Size size, int type);
- static MatExpr zeros(int ndims, const int* sz, int type);
- static MatExpr ones(int rows, int cols, int type);
- static MatExpr ones(Size size, int type);
- static MatExpr ones(int ndims, const int* sz, int type);
- static MatExpr eye(int rows, int cols, int type);
- static MatExpr eye(Size size, int type);
-
- //! allocates new matrix data unless the matrix already has specified size and type.
- // previous data is unreferenced if needed.
- void create(int rows, int cols, int type);
- void create(Size size, int type);
- void create(int ndims, const int* sizes, int type);
-
- //! increases the reference counter; use with care to avoid memleaks
- void addref();
- //! decreases reference counter;
- // deallocates the data when reference counter reaches 0.
- void release();
-
- //! deallocates the matrix data
- void deallocate();
- //! internal use function; properly re-allocates _size, _step arrays
- void copySize(const Mat& m);
-
- //! reserves enough space to fit sz hyper-planes
- void reserve(size_t sz);
- //! resizes matrix to the specified number of hyper-planes
- void resize(size_t sz);
- //! resizes matrix to the specified number of hyper-planes; initializes the newly added elements
- void resize(size_t sz, const Scalar& s);
- //! internal function
- void push_back_(const void* elem);
- //! adds element to the end of 1d matrix (or possibly multiple elements when _Tp=Mat)
- template<typename _Tp> void push_back(const _Tp& elem);
- template<typename _Tp> void push_back(const Mat_<_Tp>& elem);
- void push_back(const Mat& m);
- //! removes several hyper-planes from bottom of the matrix
- void pop_back(size_t nelems=1);
-
- //! locates matrix header within a parent matrix. See below
- void locateROI( Size& wholeSize, Point& ofs ) const;
- //! moves/resizes the current matrix ROI inside the parent matrix.
- Mat& adjustROI( int dtop, int dbottom, int dleft, int dright );
- //! extracts a rectangular sub-matrix
- // (this is a generalized form of row, rowRange etc.)
- Mat operator()( Range rowRange, Range colRange ) const;
- Mat operator()( const Rect& roi ) const;
- Mat operator()( const Range* ranges ) const;
-
- //! converts header to CvMat; no data is copied
- operator CvMat() const;
- //! converts header to CvMatND; no data is copied
- operator CvMatND() const;
- //! converts header to IplImage; no data is copied
- operator IplImage() const;
-
- template<typename _Tp> operator vector<_Tp>() const;
- template<typename _Tp, int n> operator Vec<_Tp, n>() const;
- template<typename _Tp, int m, int n> operator Matx<_Tp, m, n>() const;
-
- //! returns true iff the matrix data is continuous
- // (i.e. when there are no gaps between successive rows).
- // similar to CV_IS_MAT_CONT(cvmat->type)
- bool isContinuous() const;
-
- //! returns true if the matrix is a submatrix of another matrix
- bool isSubmatrix() const;
-
- //! returns element size in bytes,
- // similar to CV_ELEM_SIZE(cvmat->type)
- size_t elemSize() const;
- //! returns the size of element channel in bytes.
- size_t elemSize1() const;
- //! returns element type, similar to CV_MAT_TYPE(cvmat->type)
- int type() const;
- //! returns element type, similar to CV_MAT_DEPTH(cvmat->type)
- int depth() const;
- //! returns element type, similar to CV_MAT_CN(cvmat->type)
- int channels() const;
- //! returns step/elemSize1()
- size_t step1(int i=0) const;
- //! returns true if matrix data is NULL
- bool empty() const;
- //! returns the total number of matrix elements
- size_t total() const;
-
- //! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise
- int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const;
-
- //! returns pointer to i0-th submatrix along the dimension #0
- uchar* ptr(int i0=0);
- const uchar* ptr(int i0=0) const;
-
- //! returns pointer to (i0,i1) submatrix along the dimensions #0 and #1
- uchar* ptr(int i0, int i1);
- const uchar* ptr(int i0, int i1) const;
-
- //! returns pointer to (i0,i1,i3) submatrix along the dimensions #0, #1, #2
- uchar* ptr(int i0, int i1, int i2);
- const uchar* ptr(int i0, int i1, int i2) const;
-
- //! returns pointer to the matrix element
- uchar* ptr(const int* idx);
- //! returns read-only pointer to the matrix element
- const uchar* ptr(const int* idx) const;
-
- template<int n> uchar* ptr(const Vec<int, n>& idx);
- template<int n> const uchar* ptr(const Vec<int, n>& idx) const;
-
- //! template version of the above method
- template<typename _Tp> _Tp* ptr(int i0=0);
- template<typename _Tp> const _Tp* ptr(int i0=0) const;
-
- template<typename _Tp> _Tp* ptr(int i0, int i1);
- template<typename _Tp> const _Tp* ptr(int i0, int i1) const;
-
- template<typename _Tp> _Tp* ptr(int i0, int i1, int i2);
- template<typename _Tp> const _Tp* ptr(int i0, int i1, int i2) const;
-
- template<typename _Tp> _Tp* ptr(const int* idx);
- template<typename _Tp> const _Tp* ptr(const int* idx) const;
-
- template<typename _Tp, int n> _Tp* ptr(const Vec<int, n>& idx);
- template<typename _Tp, int n> const _Tp* ptr(const Vec<int, n>& idx) const;
-
- //! the same as above, with the pointer dereferencing
- template<typename _Tp> _Tp& at(int i0=0);
- template<typename _Tp> const _Tp& at(int i0=0) const;
-
- template<typename _Tp> _Tp& at(int i0, int i1);
- template<typename _Tp> const _Tp& at(int i0, int i1) const;
-
- template<typename _Tp> _Tp& at(int i0, int i1, int i2);
- template<typename _Tp> const _Tp& at(int i0, int i1, int i2) const;
-
- template<typename _Tp> _Tp& at(const int* idx);
- template<typename _Tp> const _Tp& at(const int* idx) const;
-
- template<typename _Tp, int n> _Tp& at(const Vec<int, n>& idx);
- template<typename _Tp, int n> const _Tp& at(const Vec<int, n>& idx) const;
-
- //! special versions for 2D arrays (especially convenient for referencing image pixels)
- template<typename _Tp> _Tp& at(Point pt);
- template<typename _Tp> const _Tp& at(Point pt) const;
-
- //! template methods for iteration over matrix elements.
- // the iterators take care of skipping gaps in the end of rows (if any)
- template<typename _Tp> MatIterator_<_Tp> begin();
- template<typename _Tp> MatIterator_<_Tp> end();
- template<typename _Tp> MatConstIterator_<_Tp> begin() const;
- template<typename _Tp> MatConstIterator_<_Tp> end() const;
-
- enum { MAGIC_VAL=0x42FF0000, AUTO_STEP=0, CONTINUOUS_FLAG=CV_MAT_CONT_FLAG, SUBMATRIX_FLAG=CV_SUBMAT_FLAG };
-
- /*! includes several bit-fields:
- - the magic signature
- - continuity flag
- - depth
- - number of channels
- */
- int flags;
- //! the matrix dimensionality, >= 2
- int dims;
- //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
- int rows, cols;
- //! pointer to the data
- uchar* data;
-
- //! pointer to the reference counter;
- // when matrix points to user-allocated data, the pointer is NULL
- int* refcount;
-
- //! helper fields used in locateROI and adjustROI
- uchar* datastart;
- uchar* dataend;
- uchar* datalimit;
-
- //! custom allocator
- MatAllocator* allocator;
-
- struct CV_EXPORTS MSize
- {
- MSize(int* _p);
- Size operator()() const;
- const int& operator[](int i) const;
- int& operator[](int i);
- operator const int*() const;
- bool operator == (const MSize& sz) const;
- bool operator != (const MSize& sz) const;
-
- int* p;
- };
-
- struct CV_EXPORTS MStep
- {
- MStep();
- MStep(size_t s);
- const size_t& operator[](int i) const;
- size_t& operator[](int i);
- operator size_t() const;
- MStep& operator = (size_t s);
-
- size_t* p;
- size_t buf[2];
- protected:
- MStep& operator = (const MStep&);
- };
-
- MSize size;
- MStep step;
-
-protected:
- void initEmpty();
-};
-
-
-/*!
- Random Number Generator
-
- The class implements RNG using Multiply-with-Carry algorithm
-*/
-class CV_EXPORTS RNG
-{
-public:
- enum { UNIFORM=0, NORMAL=1 };
-
- RNG();
- RNG(uint64 state);
- //! updates the state and returns the next 32-bit unsigned integer random number
- unsigned next();
-
- operator uchar();
- operator schar();
- operator ushort();
- operator short();
- operator unsigned();
- //! returns a random integer sampled uniformly from [0, N).
- unsigned operator ()(unsigned N);
- unsigned operator ()();
- operator int();
- operator float();
- operator double();
- //! returns uniformly distributed integer random number from [a,b) range
- int uniform(int a, int b);
- //! returns uniformly distributed floating-point random number from [a,b) range
- float uniform(float a, float b);
- //! returns uniformly distributed double-precision floating-point random number from [a,b) range
- double uniform(double a, double b);
- void fill( InputOutputArray mat, int distType, InputArray a, InputArray b, bool saturateRange=false );
- //! returns Gaussian random variate with mean zero.
- double gaussian(double sigma);
-
- uint64 state;
-};
-
-
-/*!
- Termination criteria in iterative algorithms
- */
-class CV_EXPORTS TermCriteria
-{
-public:
- enum
- {
- COUNT=1, //!< the maximum number of iterations or elements to compute
- MAX_ITER=COUNT, //!< ditto
- EPS=2 //!< the desired accuracy or change in parameters at which the iterative algorithm stops
- };
-
- //! default constructor
- TermCriteria();
- //! full constructor
- TermCriteria(int type, int maxCount, double epsilon);
- //! conversion from CvTermCriteria
- TermCriteria(const CvTermCriteria& criteria);
- //! conversion to CvTermCriteria
- operator CvTermCriteria() const;
-
- int type; //!< the type of termination criteria: COUNT, EPS or COUNT + EPS
- int maxCount; // the maximum number of iterations/elements
- double epsilon; // the desired accuracy
-};
-
-
-typedef void (*BinaryFunc)(const uchar* src1, size_t step1,
- const uchar* src2, size_t step2,
- uchar* dst, size_t step, Size sz,
- void*);
-
-CV_EXPORTS BinaryFunc getConvertFunc(int sdepth, int ddepth);
-CV_EXPORTS BinaryFunc getConvertScaleFunc(int sdepth, int ddepth);
-CV_EXPORTS BinaryFunc getCopyMaskFunc(size_t esz);
-
-//! swaps two matrices
-CV_EXPORTS void swap(Mat& a, Mat& b);
-
-//! converts array (CvMat or IplImage) to cv::Mat
-CV_EXPORTS Mat cvarrToMat(const CvArr* arr, bool copyData=false,
- bool allowND=true, int coiMode=0);
-//! extracts Channel of Interest from CvMat or IplImage and makes cv::Mat out of it.
-CV_EXPORTS void extractImageCOI(const CvArr* arr, OutputArray coiimg, int coi=-1);
-//! inserts single-channel cv::Mat into a multi-channel CvMat or IplImage
-CV_EXPORTS void insertImageCOI(InputArray coiimg, CvArr* arr, int coi=-1);
-
-//! adds one matrix to another (dst = src1 + src2)
-CV_EXPORTS_W void add(InputArray src1, InputArray src2, OutputArray dst,
- InputArray mask=noArray(), int dtype=-1);
-//! subtracts one matrix from another (dst = src1 - src2)
-CV_EXPORTS_W void subtract(InputArray src1, InputArray src2, OutputArray dst,
- InputArray mask=noArray(), int dtype=-1);
-
-//! computes element-wise weighted product of the two arrays (dst = scale*src1*src2)
-CV_EXPORTS_W void multiply(InputArray src1, InputArray src2,
- OutputArray dst, double scale=1, int dtype=-1);
-
-//! computes element-wise weighted quotient of the two arrays (dst = scale*src1/src2)
-CV_EXPORTS_W void divide(InputArray src1, InputArray src2, OutputArray dst,
- double scale=1, int dtype=-1);
-
-//! computes element-wise weighted reciprocal of an array (dst = scale/src2)
-CV_EXPORTS_W void divide(double scale, InputArray src2,
- OutputArray dst, int dtype=-1);
-
-//! adds scaled array to another one (dst = alpha*src1 + src2)
-CV_EXPORTS_W void scaleAdd(InputArray src1, double alpha, InputArray src2, OutputArray dst);
-
-//! computes weighted sum of two arrays (dst = alpha*src1 + beta*src2 + gamma)
-CV_EXPORTS_W void addWeighted(InputArray src1, double alpha, InputArray src2,
- double beta, double gamma, OutputArray dst, int dtype=-1);
-
-//! scales array elements, computes absolute values and converts the results to 8-bit unsigned integers: dst(i)=saturate_cast<uchar>abs(src(i)*alpha+beta)
-CV_EXPORTS_W void convertScaleAbs(InputArray src, OutputArray dst,
- double alpha=1, double beta=0);
-//! transforms array of numbers using a lookup table: dst(i)=lut(src(i))
-CV_EXPORTS_W void LUT(InputArray src, InputArray lut, OutputArray dst,
- int interpolation=0);
-
-//! computes sum of array elements
-CV_EXPORTS_AS(sumElems) Scalar sum(InputArray src);
-//! computes the number of nonzero array elements
-CV_EXPORTS_W int countNonZero( InputArray src );
-//! returns the list of locations of non-zero pixels
-CV_EXPORTS_W void findNonZero( InputArray src, OutputArray idx );
-
-//! computes mean value of selected array elements
-CV_EXPORTS_W Scalar mean(InputArray src, InputArray mask=noArray());
-//! computes mean value and standard deviation of all or selected array elements
-CV_EXPORTS_W void meanStdDev(InputArray src, OutputArray mean, OutputArray stddev,
- InputArray mask=noArray());
-//! computes norm of the selected array part
-CV_EXPORTS_W double norm(InputArray src1, int normType=NORM_L2, InputArray mask=noArray());
-//! computes norm of selected part of the difference between two arrays
-CV_EXPORTS_W double norm(InputArray src1, InputArray src2,
- int normType=NORM_L2, InputArray mask=noArray());
-
-//! naive nearest neighbor finder
-CV_EXPORTS_W void batchDistance(InputArray src1, InputArray src2,
- OutputArray dist, int dtype, OutputArray nidx,
- int normType=NORM_L2, int K=0,
- InputArray mask=noArray(), int update=0,
- bool crosscheck=false);
-
-//! scales and shifts array elements so that either the specified norm (alpha) or the minimum (alpha) and maximum (beta) array values get the specified values
-CV_EXPORTS_W void normalize( InputArray src, OutputArray dst, double alpha=1, double beta=0,
- int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray());
-
-//! finds global minimum and maximum array elements and returns their values and their locations
-CV_EXPORTS_W void minMaxLoc(InputArray src, CV_OUT double* minVal,
- CV_OUT double* maxVal=0, CV_OUT Point* minLoc=0,
- CV_OUT Point* maxLoc=0, InputArray mask=noArray());
-CV_EXPORTS void minMaxIdx(InputArray src, double* minVal, double* maxVal,
- int* minIdx=0, int* maxIdx=0, InputArray mask=noArray());
-
-//! transforms 2D matrix to 1D row or column vector by taking sum, minimum, maximum or mean value over all the rows
-CV_EXPORTS_W void reduce(InputArray src, OutputArray dst, int dim, int rtype, int dtype=-1);
-
-//! makes multi-channel array out of several single-channel arrays
-CV_EXPORTS void merge(const Mat* mv, size_t count, OutputArray dst);
-CV_EXPORTS void merge(const vector<Mat>& mv, OutputArray dst );
-
-//! makes multi-channel array out of several single-channel arrays
-CV_EXPORTS_W void merge(InputArrayOfArrays mv, OutputArray dst);
-
-//! copies each plane of a multi-channel array to a dedicated array
-CV_EXPORTS void split(const Mat& src, Mat* mvbegin);
-CV_EXPORTS void split(const Mat& m, vector<Mat>& mv );
-
-//! copies each plane of a multi-channel array to a dedicated array
-CV_EXPORTS_W void split(InputArray m, OutputArrayOfArrays mv);
-
-//! copies selected channels from the input arrays to the selected channels of the output arrays
-CV_EXPORTS void mixChannels(const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts,
- const int* fromTo, size_t npairs);
-CV_EXPORTS void mixChannels(const vector<Mat>& src, vector<Mat>& dst,
- const int* fromTo, size_t npairs);
-CV_EXPORTS_W void mixChannels(InputArrayOfArrays src, InputArrayOfArrays dst,
- const vector<int>& fromTo);
-
-//! extracts a single channel from src (coi is 0-based index)
-CV_EXPORTS_W void extractChannel(InputArray src, OutputArray dst, int coi);
-
-//! inserts a single channel to dst (coi is 0-based index)
-CV_EXPORTS_W void insertChannel(InputArray src, InputOutputArray dst, int coi);
-
-//! reverses the order of the rows, columns or both in a matrix
-CV_EXPORTS_W void flip(InputArray src, OutputArray dst, int flipCode);
-
-//! replicates the input matrix the specified number of times in the horizontal and/or vertical direction
-CV_EXPORTS_W void repeat(InputArray src, int ny, int nx, OutputArray dst);
-CV_EXPORTS Mat repeat(const Mat& src, int ny, int nx);
-
-CV_EXPORTS void hconcat(const Mat* src, size_t nsrc, OutputArray dst);
-CV_EXPORTS void hconcat(InputArray src1, InputArray src2, OutputArray dst);
-CV_EXPORTS_W void hconcat(InputArrayOfArrays src, OutputArray dst);
-
-CV_EXPORTS void vconcat(const Mat* src, size_t nsrc, OutputArray dst);
-CV_EXPORTS void vconcat(InputArray src1, InputArray src2, OutputArray dst);
-CV_EXPORTS_W void vconcat(InputArrayOfArrays src, OutputArray dst);
-
-//! computes bitwise conjunction of the two arrays (dst = src1 & src2)
-CV_EXPORTS_W void bitwise_and(InputArray src1, InputArray src2,
- OutputArray dst, InputArray mask=noArray());
-//! computes bitwise disjunction of the two arrays (dst = src1 | src2)
-CV_EXPORTS_W void bitwise_or(InputArray src1, InputArray src2,
- OutputArray dst, InputArray mask=noArray());
-//! computes bitwise exclusive-or of the two arrays (dst = src1 ^ src2)
-CV_EXPORTS_W void bitwise_xor(InputArray src1, InputArray src2,
- OutputArray dst, InputArray mask=noArray());
-//! inverts each bit of array (dst = ~src)
-CV_EXPORTS_W void bitwise_not(InputArray src, OutputArray dst,
- InputArray mask=noArray());
-//! computes element-wise absolute difference of two arrays (dst = abs(src1 - src2))
-CV_EXPORTS_W void absdiff(InputArray src1, InputArray src2, OutputArray dst);
-//! set mask elements for those array elements which are within the element-specific bounding box (dst = lowerb <= src && src < upperb)
-CV_EXPORTS_W void inRange(InputArray src, InputArray lowerb,
- InputArray upperb, OutputArray dst);
-//! compares elements of two arrays (dst = src1 <cmpop> src2)
-CV_EXPORTS_W void compare(InputArray src1, InputArray src2, OutputArray dst, int cmpop);
-//! computes per-element minimum of two arrays (dst = min(src1, src2))
-CV_EXPORTS_W void min(InputArray src1, InputArray src2, OutputArray dst);
-//! computes per-element maximum of two arrays (dst = max(src1, src2))
-CV_EXPORTS_W void max(InputArray src1, InputArray src2, OutputArray dst);
-
-//! computes per-element minimum of two arrays (dst = min(src1, src2))
-CV_EXPORTS void min(const Mat& src1, const Mat& src2, Mat& dst);
-//! computes per-element minimum of array and scalar (dst = min(src1, src2))
-CV_EXPORTS void min(const Mat& src1, double src2, Mat& dst);
-//! computes per-element maximum of two arrays (dst = max(src1, src2))
-CV_EXPORTS void max(const Mat& src1, const Mat& src2, Mat& dst);
-//! computes per-element maximum of array and scalar (dst = max(src1, src2))
-CV_EXPORTS void max(const Mat& src1, double src2, Mat& dst);
-
-//! computes square root of each matrix element (dst = src**0.5)
-CV_EXPORTS_W void sqrt(InputArray src, OutputArray dst);
-//! raises the input matrix elements to the specified power (b = a**power)
-CV_EXPORTS_W void pow(InputArray src, double power, OutputArray dst);
-//! computes exponent of each matrix element (dst = e**src)
-CV_EXPORTS_W void exp(InputArray src, OutputArray dst);
-//! computes natural logarithm of absolute value of each matrix element: dst = log(abs(src))
-CV_EXPORTS_W void log(InputArray src, OutputArray dst);
-//! computes cube root of the argument
-CV_EXPORTS_W float cubeRoot(float val);
-//! computes the angle in degrees (0..360) of the vector (x,y)
-CV_EXPORTS_W float fastAtan2(float y, float x);
-
-CV_EXPORTS void exp(const float* src, float* dst, int n);
-CV_EXPORTS void log(const float* src, float* dst, int n);
-CV_EXPORTS void fastAtan2(const float* y, const float* x, float* dst, int n, bool angleInDegrees);
-CV_EXPORTS void magnitude(const float* x, const float* y, float* dst, int n);
-
-//! converts polar coordinates to Cartesian
-CV_EXPORTS_W void polarToCart(InputArray magnitude, InputArray angle,
- OutputArray x, OutputArray y, bool angleInDegrees=false);
-//! converts Cartesian coordinates to polar
-CV_EXPORTS_W void cartToPolar(InputArray x, InputArray y,
- OutputArray magnitude, OutputArray angle,
- bool angleInDegrees=false);
-//! computes angle (angle(i)) of each (x(i), y(i)) vector
-CV_EXPORTS_W void phase(InputArray x, InputArray y, OutputArray angle,
- bool angleInDegrees=false);
-//! computes magnitude (magnitude(i)) of each (x(i), y(i)) vector
-CV_EXPORTS_W void magnitude(InputArray x, InputArray y, OutputArray magnitude);
-//! checks that each matrix element is within the specified range.
-CV_EXPORTS_W bool checkRange(InputArray a, bool quiet=true, CV_OUT Point* pos=0,
- double minVal=-DBL_MAX, double maxVal=DBL_MAX);
-//! converts NaN's to the given number
-CV_EXPORTS_W void patchNaNs(InputOutputArray a, double val=0);
-
-//! implements generalized matrix product algorithm GEMM from BLAS
-CV_EXPORTS_W void gemm(InputArray src1, InputArray src2, double alpha,
- InputArray src3, double gamma, OutputArray dst, int flags=0);
-//! multiplies matrix by its transposition from the left or from the right
-CV_EXPORTS_W void mulTransposed( InputArray src, OutputArray dst, bool aTa,
- InputArray delta=noArray(),
- double scale=1, int dtype=-1 );
-//! transposes the matrix
-CV_EXPORTS_W void transpose(InputArray src, OutputArray dst);
-//! performs affine transformation of each element of multi-channel input matrix
-CV_EXPORTS_W void transform(InputArray src, OutputArray dst, InputArray m );
-//! performs perspective transformation of each element of multi-channel input matrix
-CV_EXPORTS_W void perspectiveTransform(InputArray src, OutputArray dst, InputArray m );
-
-//! extends the symmetrical matrix from the lower half or from the upper half
-CV_EXPORTS_W void completeSymm(InputOutputArray mtx, bool lowerToUpper=false);
-//! initializes scaled identity matrix
-CV_EXPORTS_W void setIdentity(InputOutputArray mtx, const Scalar& s=Scalar(1));
-//! computes determinant of a square matrix
-CV_EXPORTS_W double determinant(InputArray mtx);
-//! computes trace of a matrix
-CV_EXPORTS_W Scalar trace(InputArray mtx);
-//! computes inverse or pseudo-inverse matrix
-CV_EXPORTS_W double invert(InputArray src, OutputArray dst, int flags=DECOMP_LU);
-//! solves linear system or a least-square problem
-CV_EXPORTS_W bool solve(InputArray src1, InputArray src2,
- OutputArray dst, int flags=DECOMP_LU);
-
-enum
-{
- SORT_EVERY_ROW=0,
- SORT_EVERY_COLUMN=1,
- SORT_ASCENDING=0,
- SORT_DESCENDING=16
-};
-
-//! sorts independently each matrix row or each matrix column
-CV_EXPORTS_W void sort(InputArray src, OutputArray dst, int flags);
-//! sorts independently each matrix row or each matrix column
-CV_EXPORTS_W void sortIdx(InputArray src, OutputArray dst, int flags);
-//! finds real roots of a cubic polynomial
-CV_EXPORTS_W int solveCubic(InputArray coeffs, OutputArray roots);
-//! finds real and complex roots of a polynomial
-CV_EXPORTS_W double solvePoly(InputArray coeffs, OutputArray roots, int maxIters=300);
-//! finds eigenvalues of a symmetric matrix
-CV_EXPORTS bool eigen(InputArray src, OutputArray eigenvalues, int lowindex=-1,
- int highindex=-1);
-//! finds eigenvalues and eigenvectors of a symmetric matrix
-CV_EXPORTS bool eigen(InputArray src, OutputArray eigenvalues,
- OutputArray eigenvectors,
- int lowindex=-1, int highindex=-1);
-CV_EXPORTS_W bool eigen(InputArray src, bool computeEigenvectors,
- OutputArray eigenvalues, OutputArray eigenvectors);
-
-enum
-{
- COVAR_SCRAMBLED=0,
- COVAR_NORMAL=1,
- COVAR_USE_AVG=2,
- COVAR_SCALE=4,
- COVAR_ROWS=8,
- COVAR_COLS=16
-};
-
-//! computes covariation matrix of a set of samples
-CV_EXPORTS void calcCovarMatrix( const Mat* samples, int nsamples, Mat& covar, Mat& mean,
- int flags, int ctype=CV_64F);
-//! computes covariation matrix of a set of samples
-CV_EXPORTS_W void calcCovarMatrix( InputArray samples, OutputArray covar,
- OutputArray mean, int flags, int ctype=CV_64F);
-
-/*!
- Principal Component Analysis
-
- The class PCA is used to compute the special basis for a set of vectors.
- The basis will consist of eigenvectors of the covariance matrix computed
- from the input set of vectors. After PCA is performed, vectors can be transformed from
- the original high-dimensional space to the subspace formed by a few most
- prominent eigenvectors (called the principal components),
- corresponding to the largest eigenvalues of the covariation matrix.
- Thus the dimensionality of the vector and the correlation between the coordinates is reduced.
-
- The following sample is the function that takes two matrices. The first one stores the set
- of vectors (a row per vector) that is used to compute PCA, the second one stores another
- "test" set of vectors (a row per vector) that are first compressed with PCA,
- then reconstructed back and then the reconstruction error norm is computed and printed for each vector.
-
- \code
- using namespace cv;
-
- PCA compressPCA(const Mat& pcaset, int maxComponents,
- const Mat& testset, Mat& compressed)
- {
- PCA pca(pcaset, // pass the data
- Mat(), // we do not have a pre-computed mean vector,
- // so let the PCA engine to compute it
- CV_PCA_DATA_AS_ROW, // indicate that the vectors
- // are stored as matrix rows
- // (use CV_PCA_DATA_AS_COL if the vectors are
- // the matrix columns)
- maxComponents // specify, how many principal components to retain
- );
- // if there is no test data, just return the computed basis, ready-to-use
- if( !testset.data )
- return pca;
- CV_Assert( testset.cols == pcaset.cols );
-
- compressed.create(testset.rows, maxComponents, testset.type());
-
- Mat reconstructed;
- for( int i = 0; i < testset.rows; i++ )
- {
- Mat vec = testset.row(i), coeffs = compressed.row(i), reconstructed;
- // compress the vector, the result will be stored
- // in the i-th row of the output matrix
- pca.project(vec, coeffs);
- // and then reconstruct it
- pca.backProject(coeffs, reconstructed);
- // and measure the error
- printf("%d. diff = %g\n", i, norm(vec, reconstructed, NORM_L2));
- }
- return pca;
- }
- \endcode
-*/
-class CV_EXPORTS PCA
-{
-public:
- //! default constructor
- PCA();
- //! the constructor that performs PCA
- PCA(InputArray data, InputArray mean, int flags, int maxComponents=0);
- PCA(InputArray data, InputArray mean, int flags, double retainedVariance);
- //! operator that performs PCA. The previously stored data, if any, is released
- PCA& operator()(InputArray data, InputArray mean, int flags, int maxComponents=0);
- PCA& computeVar(InputArray data, InputArray mean, int flags, double retainedVariance);
- //! projects vector from the original space to the principal components subspace
- Mat project(InputArray vec) const;
- //! projects vector from the original space to the principal components subspace
- void project(InputArray vec, OutputArray result) const;
- //! reconstructs the original vector from the projection
- Mat backProject(InputArray vec) const;
- //! reconstructs the original vector from the projection
- void backProject(InputArray vec, OutputArray result) const;
-
- Mat eigenvectors; //!< eigenvectors of the covariation matrix
- Mat eigenvalues; //!< eigenvalues of the covariation matrix
- Mat mean; //!< mean value subtracted before the projection and added after the back projection
-};
-
-CV_EXPORTS_W void PCACompute(InputArray data, CV_OUT InputOutputArray mean,
- OutputArray eigenvectors, int maxComponents=0);
-
-CV_EXPORTS_W void PCAComputeVar(InputArray data, CV_OUT InputOutputArray mean,
- OutputArray eigenvectors, double retainedVariance);
-
-CV_EXPORTS_W void PCAProject(InputArray data, InputArray mean,
- InputArray eigenvectors, OutputArray result);
-
-CV_EXPORTS_W void PCABackProject(InputArray data, InputArray mean,
- InputArray eigenvectors, OutputArray result);
-
-
-/*!
- Singular Value Decomposition class
-
- The class is used to compute Singular Value Decomposition of a floating-point matrix and then
- use it to solve least-square problems, under-determined linear systems, invert matrices,
- compute condition numbers etc.
-
- For a bit faster operation you can pass flags=SVD::MODIFY_A|... to modify the decomposed matrix
- when it is not necessarily to preserve it. If you want to compute condition number of a matrix
- or absolute value of its determinant - you do not need SVD::u or SVD::vt,
- so you can pass flags=SVD::NO_UV|... . Another flag SVD::FULL_UV indicates that the full-size SVD::u and SVD::vt
- must be computed, which is not necessary most of the time.
-*/
-class CV_EXPORTS SVD
-{
-public:
- enum { MODIFY_A=1, NO_UV=2, FULL_UV=4 };
- //! the default constructor
- SVD();
- //! the constructor that performs SVD
- SVD( InputArray src, int flags=0 );
- //! the operator that performs SVD. The previously allocated SVD::u, SVD::w are SVD::vt are released.
- SVD& operator ()( InputArray src, int flags=0 );
-
- //! decomposes matrix and stores the results to user-provided matrices
- static void compute( InputArray src, OutputArray w,
- OutputArray u, OutputArray vt, int flags=0 );
- //! computes singular values of a matrix
- static void compute( InputArray src, OutputArray w, int flags=0 );
- //! performs back substitution
- static void backSubst( InputArray w, InputArray u,
- InputArray vt, InputArray rhs,
- OutputArray dst );
-
- template<typename _Tp, int m, int n, int nm> static void compute( const Matx<_Tp, m, n>& a,
- Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt );
- template<typename _Tp, int m, int n, int nm> static void compute( const Matx<_Tp, m, n>& a,
- Matx<_Tp, nm, 1>& w );
- template<typename _Tp, int m, int n, int nm, int nb> static void backSubst( const Matx<_Tp, nm, 1>& w,
- const Matx<_Tp, m, nm>& u, const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs, Matx<_Tp, n, nb>& dst );
-
- //! finds dst = arg min_{|dst|=1} |m*dst|
- static void solveZ( InputArray src, OutputArray dst );
- //! performs back substitution, so that dst is the solution or pseudo-solution of m*dst = rhs, where m is the decomposed matrix
- void backSubst( InputArray rhs, OutputArray dst ) const;
-
- Mat u, w, vt;
-};
-
-//! computes SVD of src
-CV_EXPORTS_W void SVDecomp( InputArray src, CV_OUT OutputArray w,
- CV_OUT OutputArray u, CV_OUT OutputArray vt, int flags=0 );
-
-//! performs back substitution for the previously computed SVD
-CV_EXPORTS_W void SVBackSubst( InputArray w, InputArray u, InputArray vt,
- InputArray rhs, CV_OUT OutputArray dst );
-
-//! computes Mahalanobis distance between two vectors: sqrt((v1-v2)'*icovar*(v1-v2)), where icovar is the inverse covariation matrix
-CV_EXPORTS_W double Mahalanobis(InputArray v1, InputArray v2, InputArray icovar);
-//! a synonym for Mahalanobis
-CV_EXPORTS double Mahalonobis(InputArray v1, InputArray v2, InputArray icovar);
-
-//! performs forward or inverse 1D or 2D Discrete Fourier Transformation
-CV_EXPORTS_W void dft(InputArray src, OutputArray dst, int flags=0, int nonzeroRows=0);
-//! performs inverse 1D or 2D Discrete Fourier Transformation
-CV_EXPORTS_W void idft(InputArray src, OutputArray dst, int flags=0, int nonzeroRows=0);
-//! performs forward or inverse 1D or 2D Discrete Cosine Transformation
-CV_EXPORTS_W void dct(InputArray src, OutputArray dst, int flags=0);
-//! performs inverse 1D or 2D Discrete Cosine Transformation
-CV_EXPORTS_W void idct(InputArray src, OutputArray dst, int flags=0);
-//! computes element-wise product of the two Fourier spectrums. The second spectrum can optionally be conjugated before the multiplication
-CV_EXPORTS_W void mulSpectrums(InputArray a, InputArray b, OutputArray c,
- int flags, bool conjB=false);
-//! computes the minimal vector size vecsize1 >= vecsize so that the dft() of the vector of length vecsize1 can be computed efficiently
-CV_EXPORTS_W int getOptimalDFTSize(int vecsize);
-
-/*!
- Various k-Means flags
-*/
-enum
-{
- KMEANS_RANDOM_CENTERS=0, // Chooses random centers for k-Means initialization
- KMEANS_PP_CENTERS=2, // Uses k-Means++ algorithm for initialization
- KMEANS_USE_INITIAL_LABELS=1 // Uses the user-provided labels for K-Means initialization
-};
-//! clusters the input data using k-Means algorithm
-CV_EXPORTS_W double kmeans( InputArray data, int K, CV_OUT InputOutputArray bestLabels,
- TermCriteria criteria, int attempts,
- int flags, OutputArray centers=noArray() );
-
-//! returns the thread-local Random number generator
-CV_EXPORTS RNG& theRNG();
-
-//! returns the next unifomly-distributed random number of the specified type
-template<typename _Tp> static inline _Tp randu() { return (_Tp)theRNG(); }
-
-//! fills array with uniformly-distributed random numbers from the range [low, high)
-CV_EXPORTS_W void randu(InputOutputArray dst, InputArray low, InputArray high);
-
-//! fills array with normally-distributed random numbers with the specified mean and the standard deviation
-CV_EXPORTS_W void randn(InputOutputArray dst, InputArray mean, InputArray stddev);
-
-//! shuffles the input array elements
-CV_EXPORTS void randShuffle(InputOutputArray dst, double iterFactor=1., RNG* rng=0);
-CV_EXPORTS_AS(randShuffle) void randShuffle_(InputOutputArray dst, double iterFactor=1.);
-
-//! draws the line segment (pt1, pt2) in the image
-CV_EXPORTS_W void line(CV_IN_OUT Mat& img, Point pt1, Point pt2, const Scalar& color,
- int thickness=1, int lineType=8, int shift=0);
-
-//! draws the rectangle outline or a solid rectangle with the opposite corners pt1 and pt2 in the image
-CV_EXPORTS_W void rectangle(CV_IN_OUT Mat& img, Point pt1, Point pt2,
- const Scalar& color, int thickness=1,
- int lineType=8, int shift=0);
-
-//! draws the rectangle outline or a solid rectangle covering rec in the image
-CV_EXPORTS void rectangle(CV_IN_OUT Mat& img, Rect rec,
- const Scalar& color, int thickness=1,
- int lineType=8, int shift=0);
-
-//! draws the circle outline or a solid circle in the image
-CV_EXPORTS_W void circle(CV_IN_OUT Mat& img, Point center, int radius,
- const Scalar& color, int thickness=1,
- int lineType=8, int shift=0);
-
-//! draws an elliptic arc, ellipse sector or a rotated ellipse in the image
-CV_EXPORTS_W void ellipse(CV_IN_OUT Mat& img, Point center, Size axes,
- double angle, double startAngle, double endAngle,
- const Scalar& color, int thickness=1,
- int lineType=8, int shift=0);
-
-//! draws a rotated ellipse in the image
-CV_EXPORTS_W void ellipse(CV_IN_OUT Mat& img, const RotatedRect& box, const Scalar& color,
- int thickness=1, int lineType=8);
-
-//! draws a filled convex polygon in the image
-CV_EXPORTS void fillConvexPoly(Mat& img, const Point* pts, int npts,
- const Scalar& color, int lineType=8,
- int shift=0);
-CV_EXPORTS_W void fillConvexPoly(InputOutputArray img, InputArray points,
- const Scalar& color, int lineType=8,
- int shift=0);
-
-//! fills an area bounded by one or more polygons
-CV_EXPORTS void fillPoly(Mat& img, const Point** pts,
- const int* npts, int ncontours,
- const Scalar& color, int lineType=8, int shift=0,
- Point offset=Point() );
-
-CV_EXPORTS_W void fillPoly(InputOutputArray img, InputArrayOfArrays pts,
- const Scalar& color, int lineType=8, int shift=0,
- Point offset=Point() );
-
-//! draws one or more polygonal curves
-CV_EXPORTS void polylines(Mat& img, const Point** pts, const int* npts,
- int ncontours, bool isClosed, const Scalar& color,
- int thickness=1, int lineType=8, int shift=0 );
-
-CV_EXPORTS_W void polylines(InputOutputArray img, InputArrayOfArrays pts,
- bool isClosed, const Scalar& color,
- int thickness=1, int lineType=8, int shift=0 );
-
-//! clips the line segment by the rectangle Rect(0, 0, imgSize.width, imgSize.height)
-CV_EXPORTS bool clipLine(Size imgSize, CV_IN_OUT Point& pt1, CV_IN_OUT Point& pt2);
-
-//! clips the line segment by the rectangle imgRect
-CV_EXPORTS_W bool clipLine(Rect imgRect, CV_OUT CV_IN_OUT Point& pt1, CV_OUT CV_IN_OUT Point& pt2);
-
-/*!
- Line iterator class
-
- The class is used to iterate over all the pixels on the raster line
- segment connecting two specified points.
-*/
-class CV_EXPORTS LineIterator
-{
-public:
- //! intializes the iterator
- LineIterator( const Mat& img, Point pt1, Point pt2,
- int connectivity=8, bool leftToRight=false );
- //! returns pointer to the current pixel
- uchar* operator *();
- //! prefix increment operator (++it). shifts iterator to the next pixel
- LineIterator& operator ++();
- //! postfix increment operator (it++). shifts iterator to the next pixel
- LineIterator operator ++(int);
- //! returns coordinates of the current pixel
- Point pos() const;
-
- uchar* ptr;
- const uchar* ptr0;
- int step, elemSize;
- int err, count;
- int minusDelta, plusDelta;
- int minusStep, plusStep;
-};
-
-//! converts elliptic arc to a polygonal curve
-CV_EXPORTS_W void ellipse2Poly( Point center, Size axes, int angle,
- int arcStart, int arcEnd, int delta,
- CV_OUT vector<Point>& pts );
-
-enum
-{
- FONT_HERSHEY_SIMPLEX = 0,
- FONT_HERSHEY_PLAIN = 1,
- FONT_HERSHEY_DUPLEX = 2,
- FONT_HERSHEY_COMPLEX = 3,
- FONT_HERSHEY_TRIPLEX = 4,
- FONT_HERSHEY_COMPLEX_SMALL = 5,
- FONT_HERSHEY_SCRIPT_SIMPLEX = 6,
- FONT_HERSHEY_SCRIPT_COMPLEX = 7,
- FONT_ITALIC = 16
-};
-
-//! renders text string in the image
-CV_EXPORTS_W void putText( Mat& img, const string& text, Point org,
- int fontFace, double fontScale, Scalar color,
- int thickness=1, int lineType=8,
- bool bottomLeftOrigin=false );
-
-//! returns bounding box of the text string
-CV_EXPORTS_W Size getTextSize(const string& text, int fontFace,
- double fontScale, int thickness,
- CV_OUT int* baseLine);
-
-///////////////////////////////// Mat_<_Tp> ////////////////////////////////////
-
-/*!
- Template matrix class derived from Mat
-
- The class Mat_ is a "thin" template wrapper on top of cv::Mat. It does not have any extra data fields,
- nor it or cv::Mat have any virtual methods and thus references or pointers to these two classes
- can be safely converted one to another. But do it with care, for example:
-
- \code
- // create 100x100 8-bit matrix
- Mat M(100,100,CV_8U);
- // this will compile fine. no any data conversion will be done.
- Mat_<float>& M1 = (Mat_<float>&)M;
- // the program will likely crash at the statement below
- M1(99,99) = 1.f;
- \endcode
-
- While cv::Mat is sufficient in most cases, cv::Mat_ can be more convenient if you use a lot of element
- access operations and if you know matrix type at compile time.
- Note that cv::Mat::at<_Tp>(int y, int x) and cv::Mat_<_Tp>::operator ()(int y, int x) do absolutely the
- same thing and run at the same speed, but the latter is certainly shorter:
-
- \code
- Mat_<double> M(20,20);
- for(int i = 0; i < M.rows; i++)
- for(int j = 0; j < M.cols; j++)
- M(i,j) = 1./(i+j+1);
- Mat E, V;
- eigen(M,E,V);
- cout << E.at<double>(0,0)/E.at<double>(M.rows-1,0);
- \endcode
-
- It is easy to use Mat_ for multi-channel images/matrices - just pass cv::Vec as cv::Mat_ template parameter:
-
- \code
- // allocate 320x240 color image and fill it with green (in RGB space)
- Mat_<Vec3b> img(240, 320, Vec3b(0,255,0));
- // now draw a diagonal white line
- for(int i = 0; i < 100; i++)
- img(i,i)=Vec3b(255,255,255);
- // and now modify the 2nd (red) channel of each pixel
- for(int i = 0; i < img.rows; i++)
- for(int j = 0; j < img.cols; j++)
- img(i,j)[2] ^= (uchar)(i ^ j); // img(y,x)[c] accesses c-th channel of the pixel (x,y)
- \endcode
-*/
-template<typename _Tp> class CV_EXPORTS Mat_ : public Mat
-{
-public:
- typedef _Tp value_type;
- typedef typename DataType<_Tp>::channel_type channel_type;
- typedef MatIterator_<_Tp> iterator;
- typedef MatConstIterator_<_Tp> const_iterator;
-
- //! default constructor
- Mat_();
- //! equivalent to Mat(_rows, _cols, DataType<_Tp>::type)
- Mat_(int _rows, int _cols);
- //! constructor that sets each matrix element to specified value
- Mat_(int _rows, int _cols, const _Tp& value);
- //! equivalent to Mat(_size, DataType<_Tp>::type)
- explicit Mat_(Size _size);
- //! constructor that sets each matrix element to specified value
- Mat_(Size _size, const _Tp& value);
- //! n-dim array constructor
- Mat_(int _ndims, const int* _sizes);
- //! n-dim array constructor that sets each matrix element to specified value
- Mat_(int _ndims, const int* _sizes, const _Tp& value);
- //! copy/conversion contructor. If m is of different type, it's converted
- Mat_(const Mat& m);
- //! copy constructor
- Mat_(const Mat_& m);
- //! constructs a matrix on top of user-allocated data. step is in bytes(!!!), regardless of the type
- Mat_(int _rows, int _cols, _Tp* _data, size_t _step=AUTO_STEP);
- //! constructs n-dim matrix on top of user-allocated data. steps are in bytes(!!!), regardless of the type
- Mat_(int _ndims, const int* _sizes, _Tp* _data, const size_t* _steps=0);
- //! selects a submatrix
- Mat_(const Mat_& m, const Range& rowRange, const Range& colRange=Range::all());
- //! selects a submatrix
- Mat_(const Mat_& m, const Rect& roi);
- //! selects a submatrix, n-dim version
- Mat_(const Mat_& m, const Range* ranges);
- //! from a matrix expression
- explicit Mat_(const MatExpr& e);
- //! makes a matrix out of Vec, std::vector, Point_ or Point3_. The matrix will have a single column
- explicit Mat_(const vector<_Tp>& vec, bool copyData=false);
- template<int n> explicit Mat_(const Vec<typename DataType<_Tp>::channel_type, n>& vec, bool copyData=true);
- template<int m, int n> explicit Mat_(const Matx<typename DataType<_Tp>::channel_type, m, n>& mtx, bool copyData=true);
- explicit Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData=true);
- explicit Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData=true);
- explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer);
-
- Mat_& operator = (const Mat& m);
- Mat_& operator = (const Mat_& m);
- //! set all the elements to s.
- Mat_& operator = (const _Tp& s);
- //! assign a matrix expression
- Mat_& operator = (const MatExpr& e);
-
- //! iterators; they are smart enough to skip gaps in the end of rows
- iterator begin();
- iterator end();
- const_iterator begin() const;
- const_iterator end() const;
-
- //! equivalent to Mat::create(_rows, _cols, DataType<_Tp>::type)
- void create(int _rows, int _cols);
- //! equivalent to Mat::create(_size, DataType<_Tp>::type)
- void create(Size _size);
- //! equivalent to Mat::create(_ndims, _sizes, DatType<_Tp>::type)
- void create(int _ndims, const int* _sizes);
- //! cross-product
- Mat_ cross(const Mat_& m) const;
- //! data type conversion
- template<typename T2> operator Mat_<T2>() const;
- //! overridden forms of Mat::row() etc.
- Mat_ row(int y) const;
- Mat_ col(int x) const;
- Mat_ diag(int d=0) const;
- Mat_ clone() const;
-
- //! overridden forms of Mat::elemSize() etc.
- size_t elemSize() const;
- size_t elemSize1() const;
- int type() const;
- int depth() const;
- int channels() const;
- size_t step1(int i=0) const;
- //! returns step()/sizeof(_Tp)
- size_t stepT(int i=0) const;
-
- //! overridden forms of Mat::zeros() etc. Data type is omitted, of course
- static MatExpr zeros(int rows, int cols);
- static MatExpr zeros(Size size);
- static MatExpr zeros(int _ndims, const int* _sizes);
- static MatExpr ones(int rows, int cols);
- static MatExpr ones(Size size);
- static MatExpr ones(int _ndims, const int* _sizes);
- static MatExpr eye(int rows, int cols);
- static MatExpr eye(Size size);
-
- //! some more overriden methods
- Mat_& adjustROI( int dtop, int dbottom, int dleft, int dright );
- Mat_ operator()( const Range& rowRange, const Range& colRange ) const;
- Mat_ operator()( const Rect& roi ) const;
- Mat_ operator()( const Range* ranges ) const;
-
- //! more convenient forms of row and element access operators
- _Tp* operator [](int y);
- const _Tp* operator [](int y) const;
-
- //! returns reference to the specified element
- _Tp& operator ()(const int* idx);
- //! returns read-only reference to the specified element
- const _Tp& operator ()(const int* idx) const;
-
- //! returns reference to the specified element
- template<int n> _Tp& operator ()(const Vec<int, n>& idx);
- //! returns read-only reference to the specified element
- template<int n> const _Tp& operator ()(const Vec<int, n>& idx) const;
-
- //! returns reference to the specified element (1D case)
- _Tp& operator ()(int idx0);
- //! returns read-only reference to the specified element (1D case)
- const _Tp& operator ()(int idx0) const;
- //! returns reference to the specified element (2D case)
- _Tp& operator ()(int idx0, int idx1);
- //! returns read-only reference to the specified element (2D case)
- const _Tp& operator ()(int idx0, int idx1) const;
- //! returns reference to the specified element (3D case)
- _Tp& operator ()(int idx0, int idx1, int idx2);
- //! returns read-only reference to the specified element (3D case)
- const _Tp& operator ()(int idx0, int idx1, int idx2) const;
-
- _Tp& operator ()(Point pt);
- const _Tp& operator ()(Point pt) const;
-
- //! conversion to vector.
- operator vector<_Tp>() const;
- //! conversion to Vec
- template<int n> operator Vec<typename DataType<_Tp>::channel_type, n>() const;
- //! conversion to Matx
- template<int m, int n> operator Matx<typename DataType<_Tp>::channel_type, m, n>() const;
-};
-
-typedef Mat_<uchar> Mat1b;
-typedef Mat_<Vec2b> Mat2b;
-typedef Mat_<Vec3b> Mat3b;
-typedef Mat_<Vec4b> Mat4b;
-
-typedef Mat_<short> Mat1s;
-typedef Mat_<Vec2s> Mat2s;
-typedef Mat_<Vec3s> Mat3s;
-typedef Mat_<Vec4s> Mat4s;
-
-typedef Mat_<ushort> Mat1w;
-typedef Mat_<Vec2w> Mat2w;
-typedef Mat_<Vec3w> Mat3w;
-typedef Mat_<Vec4w> Mat4w;
-
-typedef Mat_<int> Mat1i;
-typedef Mat_<Vec2i> Mat2i;
-typedef Mat_<Vec3i> Mat3i;
-typedef Mat_<Vec4i> Mat4i;
-
-typedef Mat_<float> Mat1f;
-typedef Mat_<Vec2f> Mat2f;
-typedef Mat_<Vec3f> Mat3f;
-typedef Mat_<Vec4f> Mat4f;
-
-typedef Mat_<double> Mat1d;
-typedef Mat_<Vec2d> Mat2d;
-typedef Mat_<Vec3d> Mat3d;
-typedef Mat_<Vec4d> Mat4d;
-
-//////////// Iterators & Comma initializers //////////////////
-
-class CV_EXPORTS MatConstIterator
-{
-public:
- typedef uchar* value_type;
- typedef ptrdiff_t difference_type;
- typedef const uchar** pointer;
- typedef uchar* reference;
- typedef std::random_access_iterator_tag iterator_category;
-
- //! default constructor
- MatConstIterator();
- //! constructor that sets the iterator to the beginning of the matrix
- MatConstIterator(const Mat* _m);
- //! constructor that sets the iterator to the specified element of the matrix
- MatConstIterator(const Mat* _m, int _row, int _col=0);
- //! constructor that sets the iterator to the specified element of the matrix
- MatConstIterator(const Mat* _m, Point _pt);
- //! constructor that sets the iterator to the specified element of the matrix
- MatConstIterator(const Mat* _m, const int* _idx);
- //! copy constructor
- MatConstIterator(const MatConstIterator& it);
-
- //! copy operator
- MatConstIterator& operator = (const MatConstIterator& it);
- //! returns the current matrix element
- uchar* operator *() const;
- //! returns the i-th matrix element, relative to the current
- uchar* operator [](ptrdiff_t i) const;
-
- //! shifts the iterator forward by the specified number of elements
- MatConstIterator& operator += (ptrdiff_t ofs);
- //! shifts the iterator backward by the specified number of elements
- MatConstIterator& operator -= (ptrdiff_t ofs);
- //! decrements the iterator
- MatConstIterator& operator --();
- //! decrements the iterator
- MatConstIterator operator --(int);
- //! increments the iterator
- MatConstIterator& operator ++();
- //! increments the iterator
- MatConstIterator operator ++(int);
- //! returns the current iterator position
- Point pos() const;
- //! returns the current iterator position
- void pos(int* _idx) const;
- ptrdiff_t lpos() const;
- void seek(ptrdiff_t ofs, bool relative=false);
- void seek(const int* _idx, bool relative=false);
-
- const Mat* m;
- size_t elemSize;
- uchar* ptr;
- uchar* sliceStart;
- uchar* sliceEnd;
-};
-
-/*!
- Matrix read-only iterator
-
- */
-template<typename _Tp>
-class CV_EXPORTS MatConstIterator_ : public MatConstIterator
-{
-public:
- typedef _Tp value_type;
- typedef ptrdiff_t difference_type;
- typedef const _Tp* pointer;
- typedef const _Tp& reference;
- typedef std::random_access_iterator_tag iterator_category;
-
- //! default constructor
- MatConstIterator_();
- //! constructor that sets the iterator to the beginning of the matrix
- MatConstIterator_(const Mat_<_Tp>* _m);
- //! constructor that sets the iterator to the specified element of the matrix
- MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col=0);
- //! constructor that sets the iterator to the specified element of the matrix
- MatConstIterator_(const Mat_<_Tp>* _m, Point _pt);
- //! constructor that sets the iterator to the specified element of the matrix
- MatConstIterator_(const Mat_<_Tp>* _m, const int* _idx);
- //! copy constructor
- MatConstIterator_(const MatConstIterator_& it);
-
- //! copy operator
- MatConstIterator_& operator = (const MatConstIterator_& it);
- //! returns the current matrix element
- _Tp operator *() const;
- //! returns the i-th matrix element, relative to the current
- _Tp operator [](ptrdiff_t i) const;
-
- //! shifts the iterator forward by the specified number of elements
- MatConstIterator_& operator += (ptrdiff_t ofs);
- //! shifts the iterator backward by the specified number of elements
- MatConstIterator_& operator -= (ptrdiff_t ofs);
- //! decrements the iterator
- MatConstIterator_& operator --();
- //! decrements the iterator
- MatConstIterator_ operator --(int);
- //! increments the iterator
- MatConstIterator_& operator ++();
- //! increments the iterator
- MatConstIterator_ operator ++(int);
- //! returns the current iterator position
- Point pos() const;
-};
-
-
-/*!
- Matrix read-write iterator
-
-*/
-template<typename _Tp>
-class CV_EXPORTS MatIterator_ : public MatConstIterator_<_Tp>
-{
-public:
- typedef _Tp* pointer;
- typedef _Tp& reference;
- typedef std::random_access_iterator_tag iterator_category;
-
- //! the default constructor
- MatIterator_();
- //! constructor that sets the iterator to the beginning of the matrix
- MatIterator_(Mat_<_Tp>* _m);
- //! constructor that sets the iterator to the specified element of the matrix
- MatIterator_(Mat_<_Tp>* _m, int _row, int _col=0);
- //! constructor that sets the iterator to the specified element of the matrix
- MatIterator_(const Mat_<_Tp>* _m, Point _pt);
- //! constructor that sets the iterator to the specified element of the matrix
- MatIterator_(const Mat_<_Tp>* _m, const int* _idx);
- //! copy constructor
- MatIterator_(const MatIterator_& it);
- //! copy operator
- MatIterator_& operator = (const MatIterator_<_Tp>& it );
-
- //! returns the current matrix element
- _Tp& operator *() const;
- //! returns the i-th matrix element, relative to the current
- _Tp& operator [](ptrdiff_t i) const;
-
- //! shifts the iterator forward by the specified number of elements
- MatIterator_& operator += (ptrdiff_t ofs);
- //! shifts the iterator backward by the specified number of elements
- MatIterator_& operator -= (ptrdiff_t ofs);
- //! decrements the iterator
- MatIterator_& operator --();
- //! decrements the iterator
- MatIterator_ operator --(int);
- //! increments the iterator
- MatIterator_& operator ++();
- //! increments the iterator
- MatIterator_ operator ++(int);
-};
-
-template<typename _Tp> class CV_EXPORTS MatOp_Iter_;
-
-/*!
- Comma-separated Matrix Initializer
-
- The class instances are usually not created explicitly.
- Instead, they are created on "matrix << firstValue" operator.
-
- The sample below initializes 2x2 rotation matrix:
-
- \code
- double angle = 30, a = cos(angle*CV_PI/180), b = sin(angle*CV_PI/180);
- Mat R = (Mat_<double>(2,2) << a, -b, b, a);
- \endcode
-*/
-template<typename _Tp> class CV_EXPORTS MatCommaInitializer_
-{
-public:
- //! the constructor, created by "matrix << firstValue" operator, where matrix is cv::Mat
- MatCommaInitializer_(Mat_<_Tp>* _m);
- //! the operator that takes the next value and put it to the matrix
- template<typename T2> MatCommaInitializer_<_Tp>& operator , (T2 v);
- //! another form of conversion operator
- Mat_<_Tp> operator *() const;
- operator Mat_<_Tp>() const;
-protected:
- MatIterator_<_Tp> it;
-};
-
-
-template<typename _Tp, int m, int n> class CV_EXPORTS MatxCommaInitializer
-{
-public:
- MatxCommaInitializer(Matx<_Tp, m, n>* _mtx);
- template<typename T2> MatxCommaInitializer<_Tp, m, n>& operator , (T2 val);
- Matx<_Tp, m, n> operator *() const;
-
- Matx<_Tp, m, n>* dst;
- int idx;
-};
-
-template<typename _Tp, int m> class CV_EXPORTS VecCommaInitializer : public MatxCommaInitializer<_Tp, m, 1>
-{
-public:
- VecCommaInitializer(Vec<_Tp, m>* _vec);
- template<typename T2> VecCommaInitializer<_Tp, m>& operator , (T2 val);
- Vec<_Tp, m> operator *() const;
-};
-
-/*!
- Automatically Allocated Buffer Class
-
- The class is used for temporary buffers in functions and methods.
- If a temporary buffer is usually small (a few K's of memory),
- but its size depends on the parameters, it makes sense to create a small
- fixed-size array on stack and use it if it's large enough. If the required buffer size
- is larger than the fixed size, another buffer of sufficient size is allocated dynamically
- and released after the processing. Therefore, in typical cases, when the buffer size is small,
- there is no overhead associated with malloc()/free().
- At the same time, there is no limit on the size of processed data.
-
- This is what AutoBuffer does. The template takes 2 parameters - type of the buffer elements and
- the number of stack-allocated elements. Here is how the class is used:
-
- \code
- void my_func(const cv::Mat& m)
- {
- cv::AutoBuffer<float, 1000> buf; // create automatic buffer containing 1000 floats
-
- buf.allocate(m.rows); // if m.rows <= 1000, the pre-allocated buffer is used,
- // otherwise the buffer of "m.rows" floats will be allocated
- // dynamically and deallocated in cv::AutoBuffer destructor
- ...
- }
- \endcode
-*/
-template<typename _Tp, size_t fixed_size=4096/sizeof(_Tp)+8> class CV_EXPORTS AutoBuffer
-{
-public:
- typedef _Tp value_type;
- enum { buffer_padding = (int)((16 + sizeof(_Tp) - 1)/sizeof(_Tp)) };
-
- //! the default contructor
- AutoBuffer();
- //! constructor taking the real buffer size
- AutoBuffer(size_t _size);
- //! destructor. calls deallocate()
- ~AutoBuffer();
-
- //! allocates the new buffer of size _size. if the _size is small enough, stack-allocated buffer is used
- void allocate(size_t _size);
- //! deallocates the buffer if it was dynamically allocated
- void deallocate();
- //! returns pointer to the real buffer, stack-allocated or head-allocated
- operator _Tp* ();
- //! returns read-only pointer to the real buffer, stack-allocated or head-allocated
- operator const _Tp* () const;
-
-protected:
- //! pointer to the real buffer, can point to buf if the buffer is small enough
- _Tp* ptr;
- //! size of the real buffer
- size_t size;
- //! pre-allocated buffer
- _Tp buf[fixed_size+buffer_padding];
-};
-
-/////////////////////////// multi-dimensional dense matrix //////////////////////////
-
-/*!
- n-Dimensional Dense Matrix Iterator Class.
-
- The class cv::NAryMatIterator is used for iterating over one or more n-dimensional dense arrays (cv::Mat's).
-
- The iterator is completely different from cv::Mat_ and cv::SparseMat_ iterators.
- It iterates through the slices (or planes), not the elements, where "slice" is a continuous part of the arrays.
-
- Here is the example on how the iterator can be used to normalize 3D histogram:
-
- \code
- void normalizeColorHist(Mat& hist)
- {
- #if 1
- // intialize iterator (the style is different from STL).
- // after initialization the iterator will contain
- // the number of slices or planes
- // the iterator will go through
- Mat* arrays[] = { &hist, 0 };
- Mat planes[1];
- NAryMatIterator it(arrays, planes);
- double s = 0;
- // iterate through the matrix. on each iteration
- // it.planes[i] (of type Mat) will be set to the current plane of
- // i-th n-dim matrix passed to the iterator constructor.
- for(int p = 0; p < it.nplanes; p++, ++it)
- s += sum(it.planes[0])[0];
- it = NAryMatIterator(hist);
- s = 1./s;
- for(int p = 0; p < it.nplanes; p++, ++it)
- it.planes[0] *= s;
- #elif 1
- // this is a shorter implementation of the above
- // using built-in operations on Mat
- double s = sum(hist)[0];
- hist.convertTo(hist, hist.type(), 1./s, 0);
- #else
- // and this is even shorter one
- // (assuming that the histogram elements are non-negative)
- normalize(hist, hist, 1, 0, NORM_L1);
- #endif
- }
- \endcode
-
- You can iterate through several matrices simultaneously as long as they have the same geometry
- (dimensionality and all the dimension sizes are the same), which is useful for binary
- and n-ary operations on such matrices. Just pass those matrices to cv::MatNDIterator.
- Then, during the iteration it.planes[0], it.planes[1], ... will
- be the slices of the corresponding matrices
-*/
-class CV_EXPORTS NAryMatIterator
-{
-public:
- //! the default constructor
- NAryMatIterator();
- //! the full constructor taking arbitrary number of n-dim matrices
- NAryMatIterator(const Mat** arrays, uchar** ptrs, int narrays=-1);
- //! the full constructor taking arbitrary number of n-dim matrices
- NAryMatIterator(const Mat** arrays, Mat* planes, int narrays=-1);
- //! the separate iterator initialization method
- void init(const Mat** arrays, Mat* planes, uchar** ptrs, int narrays=-1);
-
- //! proceeds to the next plane of every iterated matrix
- NAryMatIterator& operator ++();
- //! proceeds to the next plane of every iterated matrix (postfix increment operator)
- NAryMatIterator operator ++(int);
-
- //! the iterated arrays
- const Mat** arrays;
- //! the current planes
- Mat* planes;
- //! data pointers
- uchar** ptrs;
- //! the number of arrays
- int narrays;
- //! the number of hyper-planes that the iterator steps through
- size_t nplanes;
- //! the size of each segment (in elements)
- size_t size;
-protected:
- int iterdepth;
- size_t idx;
-};
-
-//typedef NAryMatIterator NAryMatNDIterator;
-
-typedef void (*ConvertData)(const void* from, void* to, int cn);
-typedef void (*ConvertScaleData)(const void* from, void* to, int cn, double alpha, double beta);
-
-//! returns the function for converting pixels from one data type to another
-CV_EXPORTS ConvertData getConvertElem(int fromType, int toType);
-//! returns the function for converting pixels from one data type to another with the optional scaling
-CV_EXPORTS ConvertScaleData getConvertScaleElem(int fromType, int toType);
-
-
-/////////////////////////// multi-dimensional sparse matrix //////////////////////////
-
-class SparseMatIterator;
-class SparseMatConstIterator;
-template<typename _Tp> class SparseMatIterator_;
-template<typename _Tp> class SparseMatConstIterator_;
-
-/*!
- Sparse matrix class.
-
- The class represents multi-dimensional sparse numerical arrays. Such a sparse array can store elements
- of any type that cv::Mat is able to store. "Sparse" means that only non-zero elements
- are stored (though, as a result of some operations on a sparse matrix, some of its stored elements
- can actually become 0. It's user responsibility to detect such elements and delete them using cv::SparseMat::erase().
- The non-zero elements are stored in a hash table that grows when it's filled enough,
- so that the search time remains O(1) in average. Elements can be accessed using the following methods:
-
- <ol>
- <li>Query operations: cv::SparseMat::ptr() and the higher-level cv::SparseMat::ref(),
- cv::SparseMat::value() and cv::SparseMat::find, for example:
- \code
- const int dims = 5;
- int size[] = {10, 10, 10, 10, 10};
- SparseMat sparse_mat(dims, size, CV_32F);
- for(int i = 0; i < 1000; i++)
- {
- int idx[dims];
- for(int k = 0; k < dims; k++)
- idx[k] = rand()%sparse_mat.size(k);
- sparse_mat.ref<float>(idx) += 1.f;
- }
- \endcode
-
- <li>Sparse matrix iterators. Like cv::Mat iterators and unlike cv::Mat iterators, the sparse matrix iterators are STL-style,
- that is, the iteration is done as following:
- \code
- // prints elements of a sparse floating-point matrix and the sum of elements.
- SparseMatConstIterator_<float>
- it = sparse_mat.begin<float>(),
- it_end = sparse_mat.end<float>();
- double s = 0;
- int dims = sparse_mat.dims();
- for(; it != it_end; ++it)
- {
- // print element indices and the element value
- const Node* n = it.node();
- printf("(")
- for(int i = 0; i < dims; i++)
- printf("%3d%c", n->idx[i], i < dims-1 ? ',' : ')');
- printf(": %f\n", *it);
- s += *it;
- }
- printf("Element sum is %g\n", s);
- \endcode
- If you run this loop, you will notice that elements are enumerated
- in no any logical order (lexicographical etc.),
- they come in the same order as they stored in the hash table, i.e. semi-randomly.
-
- You may collect pointers to the nodes and sort them to get the proper ordering.
- Note, however, that pointers to the nodes may become invalid when you add more
- elements to the matrix; this is because of possible buffer reallocation.
-
- <li>A combination of the above 2 methods when you need to process 2 or more sparse
- matrices simultaneously, e.g. this is how you can compute unnormalized
- cross-correlation of the 2 floating-point sparse matrices:
- \code
- double crossCorr(const SparseMat& a, const SparseMat& b)
- {
- const SparseMat *_a = &a, *_b = &b;
- // if b contains less elements than a,
- // it's faster to iterate through b
- if(_a->nzcount() > _b->nzcount())
- std::swap(_a, _b);
- SparseMatConstIterator_<float> it = _a->begin<float>(),
- it_end = _a->end<float>();
- double ccorr = 0;
- for(; it != it_end; ++it)
- {
- // take the next element from the first matrix
- float avalue = *it;
- const Node* anode = it.node();
- // and try to find element with the same index in the second matrix.
- // since the hash value depends only on the element index,
- // we reuse hashvalue stored in the node
- float bvalue = _b->value<float>(anode->idx,&anode->hashval);
- ccorr += avalue*bvalue;
- }
- return ccorr;
- }
- \endcode
- </ol>
-*/
-class CV_EXPORTS SparseMat
-{
-public:
- typedef SparseMatIterator iterator;
- typedef SparseMatConstIterator const_iterator;
-
- //! the sparse matrix header
- struct CV_EXPORTS Hdr
- {
- Hdr(int _dims, const int* _sizes, int _type);
- void clear();
- int refcount;
- int dims;
- int valueOffset;
- size_t nodeSize;
- size_t nodeCount;
- size_t freeList;
- vector<uchar> pool;
- vector<size_t> hashtab;
- int size[CV_MAX_DIM];
- };
-
- //! sparse matrix node - element of a hash table
- struct CV_EXPORTS Node
- {
- //! hash value
- size_t hashval;
- //! index of the next node in the same hash table entry
- size_t next;
- //! index of the matrix element
- int idx[CV_MAX_DIM];
- };
-
- //! default constructor
- SparseMat();
- //! creates matrix of the specified size and type
- SparseMat(int dims, const int* _sizes, int _type);
- //! copy constructor
- SparseMat(const SparseMat& m);
- //! converts dense 2d matrix to the sparse form
- /*!
- \param m the input matrix
- \param try1d if true and m is a single-column matrix (Nx1),
- then the sparse matrix will be 1-dimensional.
- */
- explicit SparseMat(const Mat& m);
- //! converts old-style sparse matrix to the new-style. All the data is copied
- SparseMat(const CvSparseMat* m);
- //! the destructor
- ~SparseMat();
-
- //! assignment operator. This is O(1) operation, i.e. no data is copied
- SparseMat& operator = (const SparseMat& m);
- //! equivalent to the corresponding constructor
- SparseMat& operator = (const Mat& m);
-
- //! creates full copy of the matrix
- SparseMat clone() const;
-
- //! copies all the data to the destination matrix. All the previous content of m is erased
- void copyTo( SparseMat& m ) const;
- //! converts sparse matrix to dense matrix.
- void copyTo( Mat& m ) const;
- //! multiplies all the matrix elements by the specified scale factor alpha and converts the results to the specified data type
- void convertTo( SparseMat& m, int rtype, double alpha=1 ) const;
- //! converts sparse matrix to dense n-dim matrix with optional type conversion and scaling.
- /*!
- \param rtype The output matrix data type. When it is =-1, the output array will have the same data type as (*this)
- \param alpha The scale factor
- \param beta The optional delta added to the scaled values before the conversion
- */
- void convertTo( Mat& m, int rtype, double alpha=1, double beta=0 ) const;
-
- // not used now
- void assignTo( SparseMat& m, int type=-1 ) const;
-
- //! reallocates sparse matrix.
- /*!
- If the matrix already had the proper size and type,
- it is simply cleared with clear(), otherwise,
- the old matrix is released (using release()) and the new one is allocated.
- */
- void create(int dims, const int* _sizes, int _type);
- //! sets all the sparse matrix elements to 0, which means clearing the hash table.
- void clear();
- //! manually increments the reference counter to the header.
- void addref();
- // decrements the header reference counter. When the counter reaches 0, the header and all the underlying data are deallocated.
- void release();
-
- //! converts sparse matrix to the old-style representation; all the elements are copied.
- operator CvSparseMat*() const;
- //! returns the size of each element in bytes (not including the overhead - the space occupied by SparseMat::Node elements)
- size_t elemSize() const;
- //! returns elemSize()/channels()
- size_t elemSize1() const;
-
- //! returns type of sparse matrix elements
- int type() const;
- //! returns the depth of sparse matrix elements
- int depth() const;
- //! returns the number of channels
- int channels() const;
-
- //! returns the array of sizes, or NULL if the matrix is not allocated
- const int* size() const;
- //! returns the size of i-th matrix dimension (or 0)
- int size(int i) const;
- //! returns the matrix dimensionality
- int dims() const;
- //! returns the number of non-zero elements (=the number of hash table nodes)
- size_t nzcount() const;
-
- //! computes the element hash value (1D case)
- size_t hash(int i0) const;
- //! computes the element hash value (2D case)
- size_t hash(int i0, int i1) const;
- //! computes the element hash value (3D case)
- size_t hash(int i0, int i1, int i2) const;
- //! computes the element hash value (nD case)
- size_t hash(const int* idx) const;
-
- //@{
- /*!
- specialized variants for 1D, 2D, 3D cases and the generic_type one for n-D case.
-
- return pointer to the matrix element.
- <ul>
- <li>if the element is there (it's non-zero), the pointer to it is returned
- <li>if it's not there and createMissing=false, NULL pointer is returned
- <li>if it's not there and createMissing=true, then the new element
- is created and initialized with 0. Pointer to it is returned
- <li>if the optional hashval pointer is not NULL, the element hash value is
- not computed, but *hashval is taken instead.
- </ul>
- */
- //! returns pointer to the specified element (1D case)
- uchar* ptr(int i0, bool createMissing, size_t* hashval=0);
- //! returns pointer to the specified element (2D case)
- uchar* ptr(int i0, int i1, bool createMissing, size_t* hashval=0);
- //! returns pointer to the specified element (3D case)
- uchar* ptr(int i0, int i1, int i2, bool createMissing, size_t* hashval=0);
- //! returns pointer to the specified element (nD case)
- uchar* ptr(const int* idx, bool createMissing, size_t* hashval=0);
- //@}
-
- //@{
- /*!
- return read-write reference to the specified sparse matrix element.
-
- ref<_Tp>(i0,...[,hashval]) is equivalent to *(_Tp*)ptr(i0,...,true[,hashval]).
- The methods always return a valid reference.
- If the element did not exist, it is created and initialiazed with 0.
- */
- //! returns reference to the specified element (1D case)
- template<typename _Tp> _Tp& ref(int i0, size_t* hashval=0);
- //! returns reference to the specified element (2D case)
- template<typename _Tp> _Tp& ref(int i0, int i1, size_t* hashval=0);
- //! returns reference to the specified element (3D case)
- template<typename _Tp> _Tp& ref(int i0, int i1, int i2, size_t* hashval=0);
- //! returns reference to the specified element (nD case)
- template<typename _Tp> _Tp& ref(const int* idx, size_t* hashval=0);
- //@}
-
- //@{
- /*!
- return value of the specified sparse matrix element.
-
- value<_Tp>(i0,...[,hashval]) is equivalent
-
- \code
- { const _Tp* p = find<_Tp>(i0,...[,hashval]); return p ? *p : _Tp(); }
- \endcode
-
- That is, if the element did not exist, the methods return 0.
- */
- //! returns value of the specified element (1D case)
- template<typename _Tp> _Tp value(int i0, size_t* hashval=0) const;
- //! returns value of the specified element (2D case)
- template<typename _Tp> _Tp value(int i0, int i1, size_t* hashval=0) const;
- //! returns value of the specified element (3D case)
- template<typename _Tp> _Tp value(int i0, int i1, int i2, size_t* hashval=0) const;
- //! returns value of the specified element (nD case)
- template<typename _Tp> _Tp value(const int* idx, size_t* hashval=0) const;
- //@}
-
- //@{
- /*!
- Return pointer to the specified sparse matrix element if it exists
-
- find<_Tp>(i0,...[,hashval]) is equivalent to (_const Tp*)ptr(i0,...false[,hashval]).
-
- If the specified element does not exist, the methods return NULL.
- */
- //! returns pointer to the specified element (1D case)
- template<typename _Tp> const _Tp* find(int i0, size_t* hashval=0) const;
- //! returns pointer to the specified element (2D case)
- template<typename _Tp> const _Tp* find(int i0, int i1, size_t* hashval=0) const;
- //! returns pointer to the specified element (3D case)
- template<typename _Tp> const _Tp* find(int i0, int i1, int i2, size_t* hashval=0) const;
- //! returns pointer to the specified element (nD case)
- template<typename _Tp> const _Tp* find(const int* idx, size_t* hashval=0) const;
-
- //! erases the specified element (2D case)
- void erase(int i0, int i1, size_t* hashval=0);
- //! erases the specified element (3D case)
- void erase(int i0, int i1, int i2, size_t* hashval=0);
- //! erases the specified element (nD case)
- void erase(const int* idx, size_t* hashval=0);
-
- //@{
- /*!
- return the sparse matrix iterator pointing to the first sparse matrix element
- */
- //! returns the sparse matrix iterator at the matrix beginning
- SparseMatIterator begin();
- //! returns the sparse matrix iterator at the matrix beginning
- template<typename _Tp> SparseMatIterator_<_Tp> begin();
- //! returns the read-only sparse matrix iterator at the matrix beginning
- SparseMatConstIterator begin() const;
- //! returns the read-only sparse matrix iterator at the matrix beginning
- template<typename _Tp> SparseMatConstIterator_<_Tp> begin() const;
- //@}
- /*!
- return the sparse matrix iterator pointing to the element following the last sparse matrix element
- */
- //! returns the sparse matrix iterator at the matrix end
- SparseMatIterator end();
- //! returns the read-only sparse matrix iterator at the matrix end
- SparseMatConstIterator end() const;
- //! returns the typed sparse matrix iterator at the matrix end
- template<typename _Tp> SparseMatIterator_<_Tp> end();
- //! returns the typed read-only sparse matrix iterator at the matrix end
- template<typename _Tp> SparseMatConstIterator_<_Tp> end() const;
-
- //! returns the value stored in the sparse martix node
- template<typename _Tp> _Tp& value(Node* n);
- //! returns the value stored in the sparse martix node
- template<typename _Tp> const _Tp& value(const Node* n) const;
-
- ////////////// some internal-use methods ///////////////
- Node* node(size_t nidx);
- const Node* node(size_t nidx) const;
-
- uchar* newNode(const int* idx, size_t hashval);
- void removeNode(size_t hidx, size_t nidx, size_t previdx);
- void resizeHashTab(size_t newsize);
-
- enum { MAGIC_VAL=0x42FD0000, MAX_DIM=CV_MAX_DIM, HASH_SCALE=0x5bd1e995, HASH_BIT=0x80000000 };
-
- int flags;
- Hdr* hdr;
-};
-
-//! finds global minimum and maximum sparse array elements and returns their values and their locations
-CV_EXPORTS void minMaxLoc(const SparseMat& a, double* minVal,
- double* maxVal, int* minIdx=0, int* maxIdx=0);
-//! computes norm of a sparse matrix
-CV_EXPORTS double norm( const SparseMat& src, int normType );
-//! scales and shifts array elements so that either the specified norm (alpha) or the minimum (alpha) and maximum (beta) array values get the specified values
-CV_EXPORTS void normalize( const SparseMat& src, SparseMat& dst, double alpha, int normType );
-
-/*!
- Read-Only Sparse Matrix Iterator.
- Here is how to use the iterator to compute the sum of floating-point sparse matrix elements:
-
- \code
- SparseMatConstIterator it = m.begin(), it_end = m.end();
- double s = 0;
- CV_Assert( m.type() == CV_32F );
- for( ; it != it_end; ++it )
- s += it.value<float>();
- \endcode
-*/
-class CV_EXPORTS SparseMatConstIterator
-{
-public:
- //! the default constructor
- SparseMatConstIterator();
- //! the full constructor setting the iterator to the first sparse matrix element
- SparseMatConstIterator(const SparseMat* _m);
- //! the copy constructor
- SparseMatConstIterator(const SparseMatConstIterator& it);
-
- //! the assignment operator
- SparseMatConstIterator& operator = (const SparseMatConstIterator& it);
-
- //! template method returning the current matrix element
- template<typename _Tp> const _Tp& value() const;
- //! returns the current node of the sparse matrix. it.node->idx is the current element index
- const SparseMat::Node* node() const;
-
- //! moves iterator to the previous element
- SparseMatConstIterator& operator --();
- //! moves iterator to the previous element
- SparseMatConstIterator operator --(int);
- //! moves iterator to the next element
- SparseMatConstIterator& operator ++();
- //! moves iterator to the next element
- SparseMatConstIterator operator ++(int);
-
- //! moves iterator to the element after the last element
- void seekEnd();
-
- const SparseMat* m;
- size_t hashidx;
- uchar* ptr;
-};
-
-/*!
- Read-write Sparse Matrix Iterator
-
- The class is similar to cv::SparseMatConstIterator,
- but can be used for in-place modification of the matrix elements.
-*/
-class CV_EXPORTS SparseMatIterator : public SparseMatConstIterator
-{
-public:
- //! the default constructor
- SparseMatIterator();
- //! the full constructor setting the iterator to the first sparse matrix element
- SparseMatIterator(SparseMat* _m);
- //! the full constructor setting the iterator to the specified sparse matrix element
- SparseMatIterator(SparseMat* _m, const int* idx);
- //! the copy constructor
- SparseMatIterator(const SparseMatIterator& it);
-
- //! the assignment operator
- SparseMatIterator& operator = (const SparseMatIterator& it);
- //! returns read-write reference to the current sparse matrix element
- template<typename _Tp> _Tp& value() const;
- //! returns pointer to the current sparse matrix node. it.node->idx is the index of the current element (do not modify it!)
- SparseMat::Node* node() const;
-
- //! moves iterator to the next element
- SparseMatIterator& operator ++();
- //! moves iterator to the next element
- SparseMatIterator operator ++(int);
-};
-
-/*!
- The Template Sparse Matrix class derived from cv::SparseMat
-
- The class provides slightly more convenient operations for accessing elements.
-
- \code
- SparseMat m;
- ...
- SparseMat_<int> m_ = (SparseMat_<int>&)m;
- m_.ref(1)++; // equivalent to m.ref<int>(1)++;
- m_.ref(2) += m_(3); // equivalent to m.ref<int>(2) += m.value<int>(3);
- \endcode
-*/
-template<typename _Tp> class CV_EXPORTS SparseMat_ : public SparseMat
-{
-public:
- typedef SparseMatIterator_<_Tp> iterator;
- typedef SparseMatConstIterator_<_Tp> const_iterator;
-
- //! the default constructor
- SparseMat_();
- //! the full constructor equivelent to SparseMat(dims, _sizes, DataType<_Tp>::type)
- SparseMat_(int dims, const int* _sizes);
- //! the copy constructor. If DataType<_Tp>.type != m.type(), the m elements are converted
- SparseMat_(const SparseMat& m);
- //! the copy constructor. This is O(1) operation - no data is copied
- SparseMat_(const SparseMat_& m);
- //! converts dense matrix to the sparse form
- SparseMat_(const Mat& m);
- //! converts the old-style sparse matrix to the C++ class. All the elements are copied
- SparseMat_(const CvSparseMat* m);
- //! the assignment operator. If DataType<_Tp>.type != m.type(), the m elements are converted
- SparseMat_& operator = (const SparseMat& m);
- //! the assignment operator. This is O(1) operation - no data is copied
- SparseMat_& operator = (const SparseMat_& m);
- //! converts dense matrix to the sparse form
- SparseMat_& operator = (const Mat& m);
-
- //! makes full copy of the matrix. All the elements are duplicated
- SparseMat_ clone() const;
- //! equivalent to cv::SparseMat::create(dims, _sizes, DataType<_Tp>::type)
- void create(int dims, const int* _sizes);
- //! converts sparse matrix to the old-style CvSparseMat. All the elements are copied
- operator CvSparseMat*() const;
-
- //! returns type of the matrix elements
- int type() const;
- //! returns depth of the matrix elements
- int depth() const;
- //! returns the number of channels in each matrix element
- int channels() const;
-
- //! equivalent to SparseMat::ref<_Tp>(i0, hashval)
- _Tp& ref(int i0, size_t* hashval=0);
- //! equivalent to SparseMat::ref<_Tp>(i0, i1, hashval)
- _Tp& ref(int i0, int i1, size_t* hashval=0);
- //! equivalent to SparseMat::ref<_Tp>(i0, i1, i2, hashval)
- _Tp& ref(int i0, int i1, int i2, size_t* hashval=0);
- //! equivalent to SparseMat::ref<_Tp>(idx, hashval)
- _Tp& ref(const int* idx, size_t* hashval=0);
-
- //! equivalent to SparseMat::value<_Tp>(i0, hashval)
- _Tp operator()(int i0, size_t* hashval=0) const;
- //! equivalent to SparseMat::value<_Tp>(i0, i1, hashval)
- _Tp operator()(int i0, int i1, size_t* hashval=0) const;
- //! equivalent to SparseMat::value<_Tp>(i0, i1, i2, hashval)
- _Tp operator()(int i0, int i1, int i2, size_t* hashval=0) const;
- //! equivalent to SparseMat::value<_Tp>(idx, hashval)
- _Tp operator()(const int* idx, size_t* hashval=0) const;
-
- //! returns sparse matrix iterator pointing to the first sparse matrix element
- SparseMatIterator_<_Tp> begin();
- //! returns read-only sparse matrix iterator pointing to the first sparse matrix element
- SparseMatConstIterator_<_Tp> begin() const;
- //! returns sparse matrix iterator pointing to the element following the last sparse matrix element
- SparseMatIterator_<_Tp> end();
- //! returns read-only sparse matrix iterator pointing to the element following the last sparse matrix element
- SparseMatConstIterator_<_Tp> end() const;
-};
-
-
-/*!
- Template Read-Only Sparse Matrix Iterator Class.
-
- This is the derived from SparseMatConstIterator class that
- introduces more convenient operator *() for accessing the current element.
-*/
-template<typename _Tp> class CV_EXPORTS SparseMatConstIterator_ : public SparseMatConstIterator
-{
-public:
- typedef std::forward_iterator_tag iterator_category;
-
- //! the default constructor
- SparseMatConstIterator_();
- //! the full constructor setting the iterator to the first sparse matrix element
- SparseMatConstIterator_(const SparseMat_<_Tp>* _m);
- SparseMatConstIterator_(const SparseMat* _m);
- //! the copy constructor
- SparseMatConstIterator_(const SparseMatConstIterator_& it);
-
- //! the assignment operator
- SparseMatConstIterator_& operator = (const SparseMatConstIterator_& it);
- //! the element access operator
- const _Tp& operator *() const;
-
- //! moves iterator to the next element
- SparseMatConstIterator_& operator ++();
- //! moves iterator to the next element
- SparseMatConstIterator_ operator ++(int);
-};
-
-/*!
- Template Read-Write Sparse Matrix Iterator Class.
-
- This is the derived from cv::SparseMatConstIterator_ class that
- introduces more convenient operator *() for accessing the current element.
-*/
-template<typename _Tp> class CV_EXPORTS SparseMatIterator_ : public SparseMatConstIterator_<_Tp>
-{
-public:
- typedef std::forward_iterator_tag iterator_category;
-
- //! the default constructor
- SparseMatIterator_();
- //! the full constructor setting the iterator to the first sparse matrix element
- SparseMatIterator_(SparseMat_<_Tp>* _m);
- SparseMatIterator_(SparseMat* _m);
- //! the copy constructor
- SparseMatIterator_(const SparseMatIterator_& it);
-
- //! the assignment operator
- SparseMatIterator_& operator = (const SparseMatIterator_& it);
- //! returns the reference to the current element
- _Tp& operator *() const;
-
- //! moves the iterator to the next element
- SparseMatIterator_& operator ++();
- //! moves the iterator to the next element
- SparseMatIterator_ operator ++(int);
-};
-
-//////////////////// Fast Nearest-Neighbor Search Structure ////////////////////
-
-/*!
- Fast Nearest Neighbor Search Class.
-
- The class implements D. Lowe BBF (Best-Bin-First) algorithm for the last
- approximate (or accurate) nearest neighbor search in multi-dimensional spaces.
-
- First, a set of vectors is passed to KDTree::KDTree() constructor
- or KDTree::build() method, where it is reordered.
-
- Then arbitrary vectors can be passed to KDTree::findNearest() methods, which
- find the K nearest neighbors among the vectors from the initial set.
- The user can balance between the speed and accuracy of the search by varying Emax
- parameter, which is the number of leaves that the algorithm checks.
- The larger parameter values yield more accurate results at the expense of lower processing speed.
-
- \code
- KDTree T(points, false);
- const int K = 3, Emax = INT_MAX;
- int idx[K];
- float dist[K];
- T.findNearest(query_vec, K, Emax, idx, 0, dist);
- CV_Assert(dist[0] <= dist[1] && dist[1] <= dist[2]);
- \endcode
-*/
-class CV_EXPORTS_W KDTree
-{
-public:
- /*!
- The node of the search tree.
- */
- struct Node
- {
- Node() : idx(-1), left(-1), right(-1), boundary(0.f) {}
- Node(int _idx, int _left, int _right, float _boundary)
- : idx(_idx), left(_left), right(_right), boundary(_boundary) {}
- //! split dimension; >=0 for nodes (dim), < 0 for leaves (index of the point)
- int idx;
- //! node indices of the left and the right branches
- int left, right;
- //! go to the left if query_vec[node.idx]<=node.boundary, otherwise go to the right
- float boundary;
- };
-
- //! the default constructor
- CV_WRAP KDTree();
- //! the full constructor that builds the search tree
- CV_WRAP KDTree(InputArray points, bool copyAndReorderPoints=false);
- //! the full constructor that builds the search tree
- CV_WRAP KDTree(InputArray points, InputArray _labels,
- bool copyAndReorderPoints=false);
- //! builds the search tree
- CV_WRAP void build(InputArray points, bool copyAndReorderPoints=false);
- //! builds the search tree
- CV_WRAP void build(InputArray points, InputArray labels,
- bool copyAndReorderPoints=false);
- //! finds the K nearest neighbors of "vec" while looking at Emax (at most) leaves
- CV_WRAP int findNearest(InputArray vec, int K, int Emax,
- OutputArray neighborsIdx,
- OutputArray neighbors=noArray(),
- OutputArray dist=noArray(),
- OutputArray labels=noArray()) const;
- //! finds all the points from the initial set that belong to the specified box
- CV_WRAP void findOrthoRange(InputArray minBounds,
- InputArray maxBounds,
- OutputArray neighborsIdx,
- OutputArray neighbors=noArray(),
- OutputArray labels=noArray()) const;
- //! returns vectors with the specified indices
- CV_WRAP void getPoints(InputArray idx, OutputArray pts,
- OutputArray labels=noArray()) const;
- //! return a vector with the specified index
- const float* getPoint(int ptidx, int* label=0) const;
- //! returns the search space dimensionality
- CV_WRAP int dims() const;
-
- vector<Node> nodes; //!< all the tree nodes
- CV_PROP Mat points; //!< all the points. It can be a reordered copy of the input vector set or the original vector set.
- CV_PROP vector<int> labels; //!< the parallel array of labels.
- CV_PROP int maxDepth; //!< maximum depth of the search tree. Do not modify it
- CV_PROP_RW int normType; //!< type of the distance (cv::NORM_L1 or cv::NORM_L2) used for search. Initially set to cv::NORM_L2, but you can modify it
-};
-
-//////////////////////////////////////// XML & YAML I/O ////////////////////////////////////
-
-class CV_EXPORTS FileNode;
-
-/*!
- XML/YAML File Storage Class.
-
- The class describes an object associated with XML or YAML file.
- It can be used to store data to such a file or read and decode the data.
-
- The storage is organized as a tree of nested sequences (or lists) and mappings.
- Sequence is a heterogenious array, which elements are accessed by indices or sequentially using an iterator.
- Mapping is analogue of std::map or C structure, which elements are accessed by names.
- The most top level structure is a mapping.
- Leaves of the file storage tree are integers, floating-point numbers and text strings.
-
- For example, the following code:
-
- \code
- // open file storage for writing. Type of the file is determined from the extension
- FileStorage fs("test.yml", FileStorage::WRITE);
- fs << "test_int" << 5 << "test_real" << 3.1 << "test_string" << "ABCDEFGH";
- fs << "test_mat" << Mat::eye(3,3,CV_32F);
-
- fs << "test_list" << "[" << 0.0000000000001 << 2 << CV_PI << -3435345 << "2-502 2-029 3egegeg" <<
- "{:" << "month" << 12 << "day" << 31 << "year" << 1969 << "}" << "]";
- fs << "test_map" << "{" << "x" << 1 << "y" << 2 << "width" << 100 << "height" << 200 << "lbp" << "[:";
-
- const uchar arr[] = {0, 1, 1, 0, 1, 1, 0, 1};
- fs.writeRaw("u", arr, (int)(sizeof(arr)/sizeof(arr[0])));
-
- fs << "]" << "}";
- \endcode
-
- will produce the following file:
-
- \verbatim
- %YAML:1.0
- test_int: 5
- test_real: 3.1000000000000001e+00
- test_string: ABCDEFGH
- test_mat: !!opencv-matrix
- rows: 3
- cols: 3
- dt: f
- data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1. ]
- test_list:
- - 1.0000000000000000e-13
- - 2
- - 3.1415926535897931e+00
- - -3435345
- - "2-502 2-029 3egegeg"
- - { month:12, day:31, year:1969 }
- test_map:
- x: 1
- y: 2
- width: 100
- height: 200
- lbp: [ 0, 1, 1, 0, 1, 1, 0, 1 ]
- \endverbatim
-
- and to read the file above, the following code can be used:
-
- \code
- // open file storage for reading.
- // Type of the file is determined from the content, not the extension
- FileStorage fs("test.yml", FileStorage::READ);
- int test_int = (int)fs["test_int"];
- double test_real = (double)fs["test_real"];
- string test_string = (string)fs["test_string"];
-
- Mat M;
- fs["test_mat"] >> M;
-
- FileNode tl = fs["test_list"];
- CV_Assert(tl.type() == FileNode::SEQ && tl.size() == 6);
- double tl0 = (double)tl[0];
- int tl1 = (int)tl[1];
- double tl2 = (double)tl[2];
- int tl3 = (int)tl[3];
- string tl4 = (string)tl[4];
- CV_Assert(tl[5].type() == FileNode::MAP && tl[5].size() == 3);
-
- int month = (int)tl[5]["month"];
- int day = (int)tl[5]["day"];
- int year = (int)tl[5]["year"];
-
- FileNode tm = fs["test_map"];
-
- int x = (int)tm["x"];
- int y = (int)tm["y"];
- int width = (int)tm["width"];
- int height = (int)tm["height"];
-
- int lbp_val = 0;
- FileNodeIterator it = tm["lbp"].begin();
-
- for(int k = 0; k < 8; k++, ++it)
- lbp_val |= ((int)*it) << k;
- \endcode
-*/
-class CV_EXPORTS_W FileStorage
-{
-public:
- //! file storage mode
- enum
- {
- READ=0, //! read mode
- WRITE=1, //! write mode
- APPEND=2, //! append mode
- MEMORY=4,
- FORMAT_MASK=(7<<3),
- FORMAT_AUTO=0,
- FORMAT_XML=(1<<3),
- FORMAT_YAML=(2<<3)
- };
- enum
- {
- UNDEFINED=0,
- VALUE_EXPECTED=1,
- NAME_EXPECTED=2,
- INSIDE_MAP=4
- };
- //! the default constructor
- CV_WRAP FileStorage();
- //! the full constructor that opens file storage for reading or writing
- CV_WRAP FileStorage(const string& source, int flags, const string& encoding=string());
- //! the constructor that takes pointer to the C FileStorage structure
- FileStorage(CvFileStorage* fs);
- //! the destructor. calls release()
- virtual ~FileStorage();
-
- //! opens file storage for reading or writing. The previous storage is closed with release()
- CV_WRAP virtual bool open(const string& filename, int flags, const string& encoding=string());
- //! returns true if the object is associated with currently opened file.
- CV_WRAP virtual bool isOpened() const;
- //! closes the file and releases all the memory buffers
- CV_WRAP virtual void release();
- //! closes the file, releases all the memory buffers and returns the text string
- CV_WRAP string releaseAndGetString();
-
- //! returns the first element of the top-level mapping
- CV_WRAP FileNode getFirstTopLevelNode() const;
- //! returns the top-level mapping. YAML supports multiple streams
- CV_WRAP FileNode root(int streamidx=0) const;
- //! returns the specified element of the top-level mapping
- FileNode operator[](const string& nodename) const;
- //! returns the specified element of the top-level mapping
- CV_WRAP FileNode operator[](const char* nodename) const;
-
- //! returns pointer to the underlying C FileStorage structure
- CvFileStorage* operator *() { return fs; }
- //! returns pointer to the underlying C FileStorage structure
- const CvFileStorage* operator *() const { return fs; }
- //! writes one or more numbers of the specified format to the currently written structure
- void writeRaw( const string& fmt, const uchar* vec, size_t len );
- //! writes the registered C structure (CvMat, CvMatND, CvSeq). See cvWrite()
- void writeObj( const string& name, const void* obj );
-
- //! returns the normalized object name for the specified file name
- static string getDefaultObjectName(const string& filename);
-
- Ptr<CvFileStorage> fs; //!< the underlying C FileStorage structure
- string elname; //!< the currently written element
- vector<char> structs; //!< the stack of written structures
- int state; //!< the writer state
-};
-
-class CV_EXPORTS FileNodeIterator;
-
-/*!
- File Storage Node class
-
- The node is used to store each and every element of the file storage opened for reading -
- from the primitive objects, such as numbers and text strings, to the complex nodes:
- sequences, mappings and the registered objects.
-
- Note that file nodes are only used for navigating file storages opened for reading.
- When a file storage is opened for writing, no data is stored in memory after it is written.
-*/
-class CV_EXPORTS_W_SIMPLE FileNode
-{
-public:
- //! type of the file storage node
- enum
- {
- NONE=0, //!< empty node
- INT=1, //!< an integer
- REAL=2, //!< floating-point number
- FLOAT=REAL, //!< synonym or REAL
- STR=3, //!< text string in UTF-8 encoding
- STRING=STR, //!< synonym for STR
- REF=4, //!< integer of size size_t. Typically used for storing complex dynamic structures where some elements reference the others
- SEQ=5, //!< sequence
- MAP=6, //!< mapping
- TYPE_MASK=7,
- FLOW=8, //!< compact representation of a sequence or mapping. Used only by YAML writer
- USER=16, //!< a registered object (e.g. a matrix)
- EMPTY=32, //!< empty structure (sequence or mapping)
- NAMED=64 //!< the node has a name (i.e. it is element of a mapping)
- };
- //! the default constructor
- CV_WRAP FileNode();
- //! the full constructor wrapping CvFileNode structure.
- FileNode(const CvFileStorage* fs, const CvFileNode* node);
- //! the copy constructor
- FileNode(const FileNode& node);
- //! returns element of a mapping node
- FileNode operator[](const string& nodename) const;
- //! returns element of a mapping node
- CV_WRAP FileNode operator[](const char* nodename) const;
- //! returns element of a sequence node
- CV_WRAP FileNode operator[](int i) const;
- //! returns type of the node
- CV_WRAP int type() const;
-
- //! returns true if the node is empty
- CV_WRAP bool empty() const;
- //! returns true if the node is a "none" object
- CV_WRAP bool isNone() const;
- //! returns true if the node is a sequence
- CV_WRAP bool isSeq() const;
- //! returns true if the node is a mapping
- CV_WRAP bool isMap() const;
- //! returns true if the node is an integer
- CV_WRAP bool isInt() const;
- //! returns true if the node is a floating-point number
- CV_WRAP bool isReal() const;
- //! returns true if the node is a text string
- CV_WRAP bool isString() const;
- //! returns true if the node has a name
- CV_WRAP bool isNamed() const;
- //! returns the node name or an empty string if the node is nameless
- CV_WRAP string name() const;
- //! returns the number of elements in the node, if it is a sequence or mapping, or 1 otherwise.
- CV_WRAP size_t size() const;
- //! returns the node content as an integer. If the node stores floating-point number, it is rounded.
- operator int() const;
- //! returns the node content as float
- operator float() const;
- //! returns the node content as double
- operator double() const;
- //! returns the node content as text string
- operator string() const;
-
- //! returns pointer to the underlying file node
- CvFileNode* operator *();
- //! returns pointer to the underlying file node
- const CvFileNode* operator* () const;
-
- //! returns iterator pointing to the first node element
- FileNodeIterator begin() const;
- //! returns iterator pointing to the element following the last node element
- FileNodeIterator end() const;
-
- //! reads node elements to the buffer with the specified format
- void readRaw( const string& fmt, uchar* vec, size_t len ) const;
- //! reads the registered object and returns pointer to it
- void* readObj() const;
-
- // do not use wrapper pointer classes for better efficiency
- const CvFileStorage* fs;
- const CvFileNode* node;
-};
-
-
-/*!
- File Node Iterator
-
- The class is used for iterating sequences (usually) and mappings.
- */
-class CV_EXPORTS FileNodeIterator
-{
-public:
- //! the default constructor
- FileNodeIterator();
- //! the full constructor set to the ofs-th element of the node
- FileNodeIterator(const CvFileStorage* fs, const CvFileNode* node, size_t ofs=0);
- //! the copy constructor
- FileNodeIterator(const FileNodeIterator& it);
- //! returns the currently observed element
- FileNode operator *() const;
- //! accesses the currently observed element methods
- FileNode operator ->() const;
-
- //! moves iterator to the next node
- FileNodeIterator& operator ++ ();
- //! moves iterator to the next node
- FileNodeIterator operator ++ (int);
- //! moves iterator to the previous node
- FileNodeIterator& operator -- ();
- //! moves iterator to the previous node
- FileNodeIterator operator -- (int);
- //! moves iterator forward by the specified offset (possibly negative)
- FileNodeIterator& operator += (int ofs);
- //! moves iterator backward by the specified offset (possibly negative)
- FileNodeIterator& operator -= (int ofs);
-
- //! reads the next maxCount elements (or less, if the sequence/mapping last element occurs earlier) to the buffer with the specified format
- FileNodeIterator& readRaw( const string& fmt, uchar* vec,
- size_t maxCount=(size_t)INT_MAX );
-
- const CvFileStorage* fs;
- const CvFileNode* container;
- CvSeqReader reader;
- size_t remaining;
-};
-
-////////////// convenient wrappers for operating old-style dynamic structures //////////////
-
-template<typename _Tp> class SeqIterator;
-
-typedef Ptr<CvMemStorage> MemStorage;
-
-/*!
- Template Sequence Class derived from CvSeq
-
- The class provides more convenient access to sequence elements,
- STL-style operations and iterators.
-
- \note The class is targeted for simple data types,
- i.e. no constructors or destructors
- are called for the sequence elements.
-*/
-template<typename _Tp> class CV_EXPORTS Seq
-{
-public:
- typedef SeqIterator<_Tp> iterator;
- typedef SeqIterator<_Tp> const_iterator;
-
- //! the default constructor
- Seq();
- //! the constructor for wrapping CvSeq structure. The real element type in CvSeq should match _Tp.
- Seq(const CvSeq* seq);
- //! creates the empty sequence that resides in the specified storage
- Seq(MemStorage& storage, int headerSize = sizeof(CvSeq));
- //! returns read-write reference to the specified element
- _Tp& operator [](int idx);
- //! returns read-only reference to the specified element
- const _Tp& operator[](int idx) const;
- //! returns iterator pointing to the beginning of the sequence
- SeqIterator<_Tp> begin() const;
- //! returns iterator pointing to the element following the last sequence element
- SeqIterator<_Tp> end() const;
- //! returns the number of elements in the sequence
- size_t size() const;
- //! returns the type of sequence elements (CV_8UC1 ... CV_64FC(CV_CN_MAX) ...)
- int type() const;
- //! returns the depth of sequence elements (CV_8U ... CV_64F)
- int depth() const;
- //! returns the number of channels in each sequence element
- int channels() const;
- //! returns the size of each sequence element
- size_t elemSize() const;
- //! returns index of the specified sequence element
- size_t index(const _Tp& elem) const;
- //! appends the specified element to the end of the sequence
- void push_back(const _Tp& elem);
- //! appends the specified element to the front of the sequence
- void push_front(const _Tp& elem);
- //! appends zero or more elements to the end of the sequence
- void push_back(const _Tp* elems, size_t count);
- //! appends zero or more elements to the front of the sequence
- void push_front(const _Tp* elems, size_t count);
- //! inserts the specified element to the specified position
- void insert(int idx, const _Tp& elem);
- //! inserts zero or more elements to the specified position
- void insert(int idx, const _Tp* elems, size_t count);
- //! removes element at the specified position
- void remove(int idx);
- //! removes the specified subsequence
- void remove(const Range& r);
-
- //! returns reference to the first sequence element
- _Tp& front();
- //! returns read-only reference to the first sequence element
- const _Tp& front() const;
- //! returns reference to the last sequence element
- _Tp& back();
- //! returns read-only reference to the last sequence element
- const _Tp& back() const;
- //! returns true iff the sequence contains no elements
- bool empty() const;
-
- //! removes all the elements from the sequence
- void clear();
- //! removes the first element from the sequence
- void pop_front();
- //! removes the last element from the sequence
- void pop_back();
- //! removes zero or more elements from the beginning of the sequence
- void pop_front(_Tp* elems, size_t count);
- //! removes zero or more elements from the end of the sequence
- void pop_back(_Tp* elems, size_t count);
-
- //! copies the whole sequence or the sequence slice to the specified vector
- void copyTo(vector<_Tp>& vec, const Range& range=Range::all()) const;
- //! returns the vector containing all the sequence elements
- operator vector<_Tp>() const;
-
- CvSeq* seq;
-};
-
-
-/*!
- STL-style Sequence Iterator inherited from the CvSeqReader structure
-*/
-template<typename _Tp> class CV_EXPORTS SeqIterator : public CvSeqReader
-{
-public:
- //! the default constructor
- SeqIterator();
- //! the constructor setting the iterator to the beginning or to the end of the sequence
- SeqIterator(const Seq<_Tp>& seq, bool seekEnd=false);
- //! positions the iterator within the sequence
- void seek(size_t pos);
- //! reports the current iterator position
- size_t tell() const;
- //! returns reference to the current sequence element
- _Tp& operator *();
- //! returns read-only reference to the current sequence element
- const _Tp& operator *() const;
- //! moves iterator to the next sequence element
- SeqIterator& operator ++();
- //! moves iterator to the next sequence element
- SeqIterator operator ++(int) const;
- //! moves iterator to the previous sequence element
- SeqIterator& operator --();
- //! moves iterator to the previous sequence element
- SeqIterator operator --(int) const;
-
- //! moves iterator forward by the specified offset (possibly negative)
- SeqIterator& operator +=(int);
- //! moves iterator backward by the specified offset (possibly negative)
- SeqIterator& operator -=(int);
-
- // this is index of the current element module seq->total*2
- // (to distinguish between 0 and seq->total)
- int index;
-};
-
-
-class CV_EXPORTS Algorithm;
-class CV_EXPORTS AlgorithmInfo;
-struct CV_EXPORTS AlgorithmInfoData;
-
-template<typename _Tp> struct ParamType {};
-
-/*!
- Base class for high-level OpenCV algorithms
-*/
-class CV_EXPORTS_W Algorithm
-{
-public:
- Algorithm();
- virtual ~Algorithm();
- string name() const;
-
- template<typename _Tp> typename ParamType<_Tp>::member_type get(const string& name) const;
- template<typename _Tp> typename ParamType<_Tp>::member_type get(const char* name) const;
-
- CV_WRAP int getInt(const string& name) const;
- CV_WRAP double getDouble(const string& name) const;
- CV_WRAP bool getBool(const string& name) const;
- CV_WRAP string getString(const string& name) const;
- CV_WRAP Mat getMat(const string& name) const;
- CV_WRAP vector<Mat> getMatVector(const string& name) const;
- CV_WRAP Ptr<Algorithm> getAlgorithm(const string& name) const;
-
- void set(const string& name, int value);
- void set(const string& name, double value);
- void set(const string& name, bool value);
- void set(const string& name, const string& value);
- void set(const string& name, const Mat& value);
- void set(const string& name, const vector<Mat>& value);
- void set(const string& name, const Ptr<Algorithm>& value);
- template<typename _Tp> void set(const string& name, const Ptr<_Tp>& value);
-
- CV_WRAP void setInt(const string& name, int value);
- CV_WRAP void setDouble(const string& name, double value);
- CV_WRAP void setBool(const string& name, bool value);
- CV_WRAP void setString(const string& name, const string& value);
- CV_WRAP void setMat(const string& name, const Mat& value);
- CV_WRAP void setMatVector(const string& name, const vector<Mat>& value);
- CV_WRAP void setAlgorithm(const string& name, const Ptr<Algorithm>& value);
- template<typename _Tp> void setAlgorithm(const string& name, const Ptr<_Tp>& value);
-
- void set(const char* name, int value);
- void set(const char* name, double value);
- void set(const char* name, bool value);
- void set(const char* name, const string& value);
- void set(const char* name, const Mat& value);
- void set(const char* name, const vector<Mat>& value);
- void set(const char* name, const Ptr<Algorithm>& value);
- template<typename _Tp> void set(const char* name, const Ptr<_Tp>& value);
-
- void setInt(const char* name, int value);
- void setDouble(const char* name, double value);
- void setBool(const char* name, bool value);
- void setString(const char* name, const string& value);
- void setMat(const char* name, const Mat& value);
- void setMatVector(const char* name, const vector<Mat>& value);
- void setAlgorithm(const char* name, const Ptr<Algorithm>& value);
- template<typename _Tp> void setAlgorithm(const char* name, const Ptr<_Tp>& value);
-
- CV_WRAP string paramHelp(const string& name) const;
- int paramType(const char* name) const;
- CV_WRAP int paramType(const string& name) const;
- CV_WRAP void getParams(CV_OUT vector<string>& names) const;
-
-
- virtual void write(FileStorage& fs) const;
- virtual void read(const FileNode& fn);
-
- typedef Algorithm* (*Constructor)(void);
- typedef int (Algorithm::*Getter)() const;
- typedef void (Algorithm::*Setter)(int);
-
- CV_WRAP static void getList(CV_OUT vector<string>& algorithms);
- CV_WRAP static Ptr<Algorithm> _create(const string& name);
- template<typename _Tp> static Ptr<_Tp> create(const string& name);
-
- virtual AlgorithmInfo* info() const /* TODO: make it = 0;*/ { return 0; }
-};
-
-
-class CV_EXPORTS AlgorithmInfo
-{
-public:
- friend class Algorithm;
- AlgorithmInfo(const string& name, Algorithm::Constructor create);
- ~AlgorithmInfo();
- void get(const Algorithm* algo, const char* name, int argType, void* value) const;
- void addParam_(Algorithm& algo, const char* name, int argType,
- void* value, bool readOnly,
- Algorithm::Getter getter, Algorithm::Setter setter,
- const string& help=string());
- string paramHelp(const char* name) const;
- int paramType(const char* name) const;
- void getParams(vector<string>& names) const;
-
- void write(const Algorithm* algo, FileStorage& fs) const;
- void read(Algorithm* algo, const FileNode& fn) const;
- string name() const;
-
- void addParam(Algorithm& algo, const char* name,
- int& value, bool readOnly=false,
- int (Algorithm::*getter)()=0,
- void (Algorithm::*setter)(int)=0,
- const string& help=string());
- void addParam(Algorithm& algo, const char* name,
- short& value, bool readOnly=false,
- int (Algorithm::*getter)()=0,
- void (Algorithm::*setter)(int)=0,
- const string& help=string());
- void addParam(Algorithm& algo, const char* name,
- bool& value, bool readOnly=false,
- int (Algorithm::*getter)()=0,
- void (Algorithm::*setter)(int)=0,
- const string& help=string());
- void addParam(Algorithm& algo, const char* name,
- double& value, bool readOnly=false,
- double (Algorithm::*getter)()=0,
- void (Algorithm::*setter)(double)=0,
- const string& help=string());
- void addParam(Algorithm& algo, const char* name,
- string& value, bool readOnly=false,
- string (Algorithm::*getter)()=0,
- void (Algorithm::*setter)(const string&)=0,
- const string& help=string());
- void addParam(Algorithm& algo, const char* name,
- Mat& value, bool readOnly=false,
- Mat (Algorithm::*getter)()=0,
- void (Algorithm::*setter)(const Mat&)=0,
- const string& help=string());
- void addParam(Algorithm& algo, const char* name,
- vector<Mat>& value, bool readOnly=false,
- vector<Mat> (Algorithm::*getter)()=0,
- void (Algorithm::*setter)(const vector<Mat>&)=0,
- const string& help=string());
- void addParam(Algorithm& algo, const char* name,
- Ptr<Algorithm>& value, bool readOnly=false,
- Ptr<Algorithm> (Algorithm::*getter)()=0,
- void (Algorithm::*setter)(const Ptr<Algorithm>&)=0,
- const string& help=string());
- void addParam(Algorithm& algo, const char* name,
- float& value, bool readOnly=false,
- float (Algorithm::*getter)()=0,
- void (Algorithm::*setter)(float)=0,
- const string& help=string());
- void addParam(Algorithm& algo, const char* name,
- unsigned int& value, bool readOnly=false,
- unsigned int (Algorithm::*getter)()=0,
- void (Algorithm::*setter)(unsigned int)=0,
- const string& help=string());
- void addParam(Algorithm& algo, const char* name,
- uint64& value, bool readOnly=false,
- uint64 (Algorithm::*getter)()=0,
- void (Algorithm::*setter)(uint64)=0,
- const string& help=string());
- void addParam(Algorithm& algo, const char* name,
- uchar& value, bool readOnly=false,
- uchar (Algorithm::*getter)()=0,
- void (Algorithm::*setter)(uchar)=0,
- const string& help=string());
- template<typename _Tp, typename _Base> void addParam(Algorithm& algo, const char* name,
- Ptr<_Tp>& value, bool readOnly=false,
- Ptr<_Tp> (Algorithm::*getter)()=0,
- void (Algorithm::*setter)(const Ptr<_Tp>&)=0,
- const string& help=string());
- template<typename _Tp> void addParam(Algorithm& algo, const char* name,
- Ptr<_Tp>& value, bool readOnly=false,
- Ptr<_Tp> (Algorithm::*getter)()=0,
- void (Algorithm::*setter)(const Ptr<_Tp>&)=0,
- const string& help=string());
-protected:
- AlgorithmInfoData* data;
- void set(Algorithm* algo, const char* name, int argType,
- const void* value, bool force=false) const;
-};
-
-
-struct CV_EXPORTS Param
-{
- enum { INT=0, BOOLEAN=1, REAL=2, STRING=3, MAT=4, MAT_VECTOR=5, ALGORITHM=6, FLOAT=7, UNSIGNED_INT=8, UINT64=9, SHORT=10, UCHAR=11 };
-
- Param();
- Param(int _type, bool _readonly, int _offset,
- Algorithm::Getter _getter=0,
- Algorithm::Setter _setter=0,
- const string& _help=string());
- int type;
- int offset;
- bool readonly;
- Algorithm::Getter getter;
- Algorithm::Setter setter;
- string help;
-};
-
-template<> struct ParamType<bool>
-{
- typedef bool const_param_type;
- typedef bool member_type;
-
- enum { type = Param::BOOLEAN };
-};
-
-template<> struct ParamType<int>
-{
- typedef int const_param_type;
- typedef int member_type;
-
- enum { type = Param::INT };
-};
-
-template<> struct ParamType<short>
-{
- typedef int const_param_type;
- typedef int member_type;
-
- enum { type = Param::SHORT };
-};
-
-template<> struct ParamType<double>
-{
- typedef double const_param_type;
- typedef double member_type;
-
- enum { type = Param::REAL };
-};
-
-template<> struct ParamType<string>
-{
- typedef const string& const_param_type;
- typedef string member_type;
-
- enum { type = Param::STRING };
-};
-
-template<> struct ParamType<Mat>
-{
- typedef const Mat& const_param_type;
- typedef Mat member_type;
-
- enum { type = Param::MAT };
-};
-
-template<> struct ParamType<vector<Mat> >
-{
- typedef const vector<Mat>& const_param_type;
- typedef vector<Mat> member_type;
-
- enum { type = Param::MAT_VECTOR };
-};
-
-template<> struct ParamType<Algorithm>
-{
- typedef const Ptr<Algorithm>& const_param_type;
- typedef Ptr<Algorithm> member_type;
-
- enum { type = Param::ALGORITHM };
-};
-
-template<> struct ParamType<float>
-{
- typedef float const_param_type;
- typedef float member_type;
-
- enum { type = Param::FLOAT };
-};
-
-template<> struct ParamType<unsigned>
-{
- typedef unsigned const_param_type;
- typedef unsigned member_type;
-
- enum { type = Param::UNSIGNED_INT };
-};
-
-template<> struct ParamType<uint64>
-{
- typedef uint64 const_param_type;
- typedef uint64 member_type;
-
- enum { type = Param::UINT64 };
-};
-
-template<> struct ParamType<uchar>
-{
- typedef uchar const_param_type;
- typedef uchar member_type;
-
- enum { type = Param::UCHAR };
-};
-
-/*!
-"\nThe CommandLineParser class is designed for command line arguments parsing\n"
- "Keys map: \n"
- "Before you start to work with CommandLineParser you have to create a map for keys.\n"
- " It will look like this\n"
- " const char* keys =\n"
- " {\n"
- " { s| string| 123asd |string parameter}\n"
- " { d| digit | 100 |digit parameter }\n"
- " { c|noCamera|false |without camera }\n"
- " { 1| |some text|help }\n"
- " { 2| |333 |another help }\n"
- " };\n"
- "Usage syntax: \n"
- " \"{\" - start of parameter string.\n"
- " \"}\" - end of parameter string\n"
- " \"|\" - separator between short name, full name, default value and help\n"
- "Supported syntax: \n"
- " --key1=arg1 <If a key with '--' must has an argument\n"
- " you have to assign it through '=' sign.> \n"
- "<If the key with '--' doesn't have any argument, it means that it is a bool key>\n"
- " -key2=arg2 <If a key with '-' must has an argument \n"
- " you have to assign it through '=' sign.> \n"
- "If the key with '-' doesn't have any argument, it means that it is a bool key\n"
- " key3 <This key can't has any parameter> \n"
- "Usage: \n"
- " Imagine that the input parameters are next:\n"
- " -s=string_value --digit=250 --noCamera lena.jpg 10000\n"
- " CommandLineParser parser(argc, argv, keys) - create a parser object\n"
- " parser.get<string>(\"s\" or \"string\") will return you first parameter value\n"
- " parser.get<string>(\"s\", false or \"string\", false) will return you first parameter value\n"
- " without spaces in end and begin\n"
- " parser.get<int>(\"d\" or \"digit\") will return you second parameter value.\n"
- " It also works with 'unsigned int', 'double', and 'float' types>\n"
- " parser.get<bool>(\"c\" or \"noCamera\") will return you true .\n"
- " If you enter this key in commandline>\n"
- " It return you false otherwise.\n"
- " parser.get<string>(\"1\") will return you the first argument without parameter (lena.jpg) \n"
- " parser.get<int>(\"2\") will return you the second argument without parameter (10000)\n"
- " It also works with 'unsigned int', 'double', and 'float' types \n"
-*/
-class CV_EXPORTS CommandLineParser
-{
- public:
-
- //! the default constructor
- CommandLineParser(int argc, const char* const argv[], const char* key_map);
-
- //! get parameter, you can choose: delete spaces in end and begin or not
- template<typename _Tp>
- _Tp get(const std::string& name, bool space_delete=true)
- {
- if (!has(name))
- {
- return _Tp();
- }
- std::string str = getString(name);
- return analyzeValue<_Tp>(str, space_delete);
- }
-
- //! print short name, full name, current value and help for all params
- void printParams();
-
- protected:
- std::map<std::string, std::vector<std::string> > data;
- std::string getString(const std::string& name);
-
- bool has(const std::string& keys);
-
- template<typename _Tp>
- _Tp analyzeValue(const std::string& str, bool space_delete=false);
-
- template<typename _Tp>
- static _Tp getData(const std::string& str)
- {
- _Tp res = _Tp();
- std::stringstream s1(str);
- s1 >> res;
- return res;
- }
-
- template<typename _Tp>
- _Tp fromStringNumber(const std::string& str);//the default conversion function for numbers
-
- };
-
-template<> CV_EXPORTS
-bool CommandLineParser::get<bool>(const std::string& name, bool space_delete);
-
-template<> CV_EXPORTS
-std::string CommandLineParser::analyzeValue<std::string>(const std::string& str, bool space_delete);
-
-template<> CV_EXPORTS
-int CommandLineParser::analyzeValue<int>(const std::string& str, bool space_delete);
-
-template<> CV_EXPORTS
-unsigned int CommandLineParser::analyzeValue<unsigned int>(const std::string& str, bool space_delete);
-
-template<> CV_EXPORTS
-uint64 CommandLineParser::analyzeValue<uint64>(const std::string& str, bool space_delete);
-
-template<> CV_EXPORTS
-float CommandLineParser::analyzeValue<float>(const std::string& str, bool space_delete);
-
-template<> CV_EXPORTS
-double CommandLineParser::analyzeValue<double>(const std::string& str, bool space_delete);
-
-
-/////////////////////////////// Parallel Primitives //////////////////////////////////
-
-// a base body class
-class CV_EXPORTS ParallelLoopBody
-{
-public:
- virtual ~ParallelLoopBody();
- virtual void operator() (const Range& range) const = 0;
-};
-
-CV_EXPORTS void parallel_for_(const Range& range, const ParallelLoopBody& body, double nstripes=-1.);
-
-/////////////////////////// Synchronization Primitives ///////////////////////////////
-
-class CV_EXPORTS Mutex
-{
-public:
- Mutex();
- ~Mutex();
- Mutex(const Mutex& m);
- Mutex& operator = (const Mutex& m);
-
- void lock();
- bool trylock();
- void unlock();
-
- struct Impl;
-protected:
- Impl* impl;
-};
-
-class CV_EXPORTS AutoLock
-{
-public:
- AutoLock(Mutex& m) : mutex(&m) { mutex->lock(); }
- ~AutoLock() { mutex->unlock(); }
-protected:
- Mutex* mutex;
-};
-
-}
-
-#endif // __cplusplus
-
-#include "opencv2/core/operations.hpp"
-#include "opencv2/core/mat.hpp"
- #include "opencv2/core.hpp"
-#endif /*__OPENCV_CORE_HPP__*/
++#include "opencv2/core.hpp"
--- /dev/null
- // while this is not IEEE754-compliant rounding, it's usually a good enough approximation
- return (int)(value + (value >= 0 ? 0.5 : -0.5));
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_CORE_CVDEF_H__
+#define __OPENCV_CORE_CVDEF_H__
+
+#if !defined _CRT_SECURE_NO_DEPRECATE && defined _MSC_VER && _MSC_VER > 1300
+# define _CRT_SECURE_NO_DEPRECATE /* to avoid multiple Visual Studio warnings */
+#endif
+
+// undef problematic defines sometimes defined by system headers (windows.h in particular)
+#undef small
+#undef min
+#undef max
+#undef abs
+#undef Complex
+
+#if defined __ICL
+# define CV_ICC __ICL
+#elif defined __ICC
+# define CV_ICC __ICC
+#elif defined __ECL
+# define CV_ICC __ECL
+#elif defined __ECC
+# define CV_ICC __ECC
+#elif defined __INTEL_COMPILER
+# define CV_ICC __INTEL_COMPILER
+#endif
+
+#if defined CV_ICC && !defined CV_ENABLE_UNROLLED
+# define CV_ENABLE_UNROLLED 0
+#else
+# define CV_ENABLE_UNROLLED 1
+#endif
+
+#if (defined WIN32 || defined _WIN32 || defined WINCE) && defined CVAPI_EXPORTS
+# define CV_EXPORTS __declspec(dllexport)
+#else
+# define CV_EXPORTS
+#endif
+
+#ifndef CV_INLINE
+# if defined __cplusplus
+# define CV_INLINE static inline
+# elif (defined WIN32 || defined _WIN32 || defined WINCE) && !defined __GNUC__
+# define CV_INLINE __inline
+# else
+# define CV_INLINE static
+# endif
+#endif
+
+#ifndef CV_EXTERN_C
+# ifdef __cplusplus
+# define CV_EXTERN_C extern "C"
+# else
+# define CV_EXTERN_C
+# endif
+#endif
+
+/* CPU features and intrinsics support */
+#define CV_CPU_NONE 0
+#define CV_CPU_MMX 1
+#define CV_CPU_SSE 2
+#define CV_CPU_SSE2 3
+#define CV_CPU_SSE3 4
+#define CV_CPU_SSSE3 5
+#define CV_CPU_SSE4_1 6
+#define CV_CPU_SSE4_2 7
+#define CV_CPU_POPCNT 8
+#define CV_CPU_AVX 10
+#define CV_CPU_NEON 11
+#define CV_HARDWARE_MAX_FEATURE 255
+
+// do not include SSE/AVX/NEON headers for NVCC compiler
+#ifndef __CUDACC__
+
+#if defined __SSE2__ || defined _M_X64 || (defined _M_IX86_FP && _M_IX86_FP >= 2)
+# include <emmintrin.h>
+# define CV_SSE 1
+# define CV_SSE2 1
+# if defined __SSE3__ || (defined _MSC_VER && _MSC_VER >= 1500)
+# include <pmmintrin.h>
+# define CV_SSE3 1
+# endif
+# if defined __SSSE3__ || (defined _MSC_VER && _MSC_VER >= 1500)
+# include <tmmintrin.h>
+# define CV_SSSE3 1
+# endif
+# if defined __SSE4_1__ || (defined _MSC_VER && _MSC_VER >= 1500)
+# include <smmintrin.h>
+# define CV_SSE4_1 1
+# endif
+# if defined __SSE4_2__ || (defined _MSC_VER && _MSC_VER >= 1500)
+# include <nmmintrin.h>
+# define CV_SSE4_2 1
+# endif
+# if defined __AVX__ || (defined _MSC_FULL_VER && _MSC_FULL_VER >= 160040219)
+// MS Visual Studio 2010 (2012?) has no macro pre-defined to identify the use of /arch:AVX
+// See: http://connect.microsoft.com/VisualStudio/feedback/details/605858/arch-avx-should-define-a-predefined-macro-in-x64-and-set-a-unique-value-for-m-ix86-fp-in-win32
+# include <immintrin.h>
+# define CV_AVX 1
+# if defined(_XCR_XFEATURE_ENABLED_MASK)
+# define __xgetbv() _xgetbv(_XCR_XFEATURE_ENABLED_MASK)
+# else
+# define __xgetbv() 0
+# endif
+# endif
+#endif
+
+#ifdef __ARM_NEON__
+# include <arm_neon.h>
+# define CV_NEON 1
+#endif
+
+#endif // __CUDACC__
+
+#ifndef CV_SSE
+# define CV_SSE 0
+#endif
+#ifndef CV_SSE2
+# define CV_SSE2 0
+#endif
+#ifndef CV_SSE3
+# define CV_SSE3 0
+#endif
+#ifndef CV_SSSE3
+# define CV_SSSE3 0
+#endif
+#ifndef CV_SSE4_1
+# define CV_SSE4_1 0
+#endif
+#ifndef CV_SSE4_2
+# define CV_SSE4_2 0
+#endif
+#ifndef CV_AVX
+# define CV_AVX 0
+#endif
+#ifndef CV_NEON
+# define CV_NEON 0
+#endif
+
+/* primitive types */
+/*
+ schar - signed 1 byte integer
+ uchar - unsigned 1 byte integer
+ short - signed 2 byte integer
+ ushort - unsigned 2 byte integer
+ int - signed 4 byte integer
+ uint - unsigned 4 byte integer
+ int64 - signed 8 byte integer
+ uint64 - unsigned 8 byte integer
+*/
+
+#if !defined _MSC_VER && !defined __BORLANDC__
+# if defined __cplusplus && __cplusplus >= 201103L
+# include <cstdint>
+# else
+# include <stdint.h>
+# endif
+#else
+ typedef unsigned uint;
+#endif
+
+typedef signed char schar;
+
+#ifndef __IPL_H__
+ typedef unsigned char uchar;
+ typedef unsigned short ushort;
+#endif
+
+#if defined _MSC_VER || defined __BORLANDC__
+ typedef __int64 int64;
+ typedef unsigned __int64 uint64;
+# define CV_BIG_INT(n) n##I64
+# define CV_BIG_UINT(n) n##UI64
+#else
+ typedef int64_t int64;
+ typedef uint64_t uint64;
+# define CV_BIG_INT(n) n##LL
+# define CV_BIG_UINT(n) n##ULL
+#endif
+
+/* special informative macros for wrapper generators */
+#define CV_EXPORTS_W CV_EXPORTS
+#define CV_EXPORTS_W_SIMPLE CV_EXPORTS
+#define CV_EXPORTS_AS(synonym) CV_EXPORTS
+#define CV_EXPORTS_W_MAP CV_EXPORTS
+#define CV_IN_OUT
+#define CV_OUT
+#define CV_PROP
+#define CV_PROP_RW
+#define CV_WRAP
+#define CV_WRAP_AS(synonym)
+
+/* fundamental constants */
+#define CV_PI 3.1415926535897932384626433832795
+#define CV_LOG2 0.69314718055994530941723212145818
+
+/****************************************************************************************\
+* Matrix type (Mat) *
+\****************************************************************************************/
+
+#define CV_CN_MAX 512
+#define CV_CN_SHIFT 3
+#define CV_DEPTH_MAX (1 << CV_CN_SHIFT)
+
+#define CV_8U 0
+#define CV_8S 1
+#define CV_16U 2
+#define CV_16S 3
+#define CV_32S 4
+#define CV_32F 5
+#define CV_64F 6
+#define CV_USRTYPE1 7
+
+#define CV_MAT_DEPTH_MASK (CV_DEPTH_MAX - 1)
+#define CV_MAT_DEPTH(flags) ((flags) & CV_MAT_DEPTH_MASK)
+
+#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))
+#define CV_MAKE_TYPE CV_MAKETYPE
+
+#define CV_8UC1 CV_MAKETYPE(CV_8U,1)
+#define CV_8UC2 CV_MAKETYPE(CV_8U,2)
+#define CV_8UC3 CV_MAKETYPE(CV_8U,3)
+#define CV_8UC4 CV_MAKETYPE(CV_8U,4)
+#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n))
+
+#define CV_8SC1 CV_MAKETYPE(CV_8S,1)
+#define CV_8SC2 CV_MAKETYPE(CV_8S,2)
+#define CV_8SC3 CV_MAKETYPE(CV_8S,3)
+#define CV_8SC4 CV_MAKETYPE(CV_8S,4)
+#define CV_8SC(n) CV_MAKETYPE(CV_8S,(n))
+
+#define CV_16UC1 CV_MAKETYPE(CV_16U,1)
+#define CV_16UC2 CV_MAKETYPE(CV_16U,2)
+#define CV_16UC3 CV_MAKETYPE(CV_16U,3)
+#define CV_16UC4 CV_MAKETYPE(CV_16U,4)
+#define CV_16UC(n) CV_MAKETYPE(CV_16U,(n))
+
+#define CV_16SC1 CV_MAKETYPE(CV_16S,1)
+#define CV_16SC2 CV_MAKETYPE(CV_16S,2)
+#define CV_16SC3 CV_MAKETYPE(CV_16S,3)
+#define CV_16SC4 CV_MAKETYPE(CV_16S,4)
+#define CV_16SC(n) CV_MAKETYPE(CV_16S,(n))
+
+#define CV_32SC1 CV_MAKETYPE(CV_32S,1)
+#define CV_32SC2 CV_MAKETYPE(CV_32S,2)
+#define CV_32SC3 CV_MAKETYPE(CV_32S,3)
+#define CV_32SC4 CV_MAKETYPE(CV_32S,4)
+#define CV_32SC(n) CV_MAKETYPE(CV_32S,(n))
+
+#define CV_32FC1 CV_MAKETYPE(CV_32F,1)
+#define CV_32FC2 CV_MAKETYPE(CV_32F,2)
+#define CV_32FC3 CV_MAKETYPE(CV_32F,3)
+#define CV_32FC4 CV_MAKETYPE(CV_32F,4)
+#define CV_32FC(n) CV_MAKETYPE(CV_32F,(n))
+
+#define CV_64FC1 CV_MAKETYPE(CV_64F,1)
+#define CV_64FC2 CV_MAKETYPE(CV_64F,2)
+#define CV_64FC3 CV_MAKETYPE(CV_64F,3)
+#define CV_64FC4 CV_MAKETYPE(CV_64F,4)
+#define CV_64FC(n) CV_MAKETYPE(CV_64F,(n))
+
+#define CV_MAT_CN_MASK ((CV_CN_MAX - 1) << CV_CN_SHIFT)
+#define CV_MAT_CN(flags) ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1)
+#define CV_MAT_TYPE_MASK (CV_DEPTH_MAX*CV_CN_MAX - 1)
+#define CV_MAT_TYPE(flags) ((flags) & CV_MAT_TYPE_MASK)
+#define CV_MAT_CONT_FLAG_SHIFT 14
+#define CV_MAT_CONT_FLAG (1 << CV_MAT_CONT_FLAG_SHIFT)
+#define CV_IS_MAT_CONT(flags) ((flags) & CV_MAT_CONT_FLAG)
+#define CV_IS_CONT_MAT CV_IS_MAT_CONT
+#define CV_SUBMAT_FLAG_SHIFT 15
+#define CV_SUBMAT_FLAG (1 << CV_SUBMAT_FLAG_SHIFT)
+#define CV_IS_SUBMAT(flags) ((flags) & CV_MAT_SUBMAT_FLAG)
+
+/* Size of each channel item,
+ 0x124489 = 1000 0100 0100 0010 0010 0001 0001 ~ array of sizeof(arr_type_elem) */
+#define CV_ELEM_SIZE1(type) \
+ ((((sizeof(size_t)<<28)|0x8442211) >> CV_MAT_DEPTH(type)*4) & 15)
+
+/* 0x3a50 = 11 10 10 01 01 00 00 ~ array of log2(sizeof(arr_type_elem)) */
+#define CV_ELEM_SIZE(type) \
+ (CV_MAT_CN(type) << ((((sizeof(size_t)/4+1)*16384|0x3a50) >> CV_MAT_DEPTH(type)*2) & 3))
+
+
+/****************************************************************************************\
+* fast math *
+\****************************************************************************************/
+
+#if defined __BORLANDC__
+# include <fastmath.h>
+#elif defined __cplusplus
+# include <cmath>
+#else
+# include <math.h>
+#endif
+
+#ifndef MIN
+# define MIN(a,b) ((a) > (b) ? (b) : (a))
+#endif
+
+#ifndef MAX
+# define MAX(a,b) ((a) < (b) ? (b) : (a))
+#endif
+
+#ifdef HAVE_TEGRA_OPTIMIZATION
+# include "tegra_round.hpp"
+#endif
+
+CV_INLINE int cvRound( double value )
+{
+#if ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__)
+ __m128d t = _mm_set_sd( value );
+ return _mm_cvtsd_si32(t);
+#elif defined _MSC_VER && defined _M_IX86
+ int t;
+ __asm
+ {
+ fld value;
+ fistp t;
+ }
+ return t;
++#elif defined _MSC_VER && defined _M_ARM && defined HAVE_TEGRA_OPTIMIZATION
++ TEGRA_ROUND(value);
+#elif defined HAVE_LRINT || defined CV_ICC || defined __GNUC__
+# ifdef HAVE_TEGRA_OPTIMIZATION
+ TEGRA_ROUND(value);
+# else
+ return (int)lrint(value);
+# endif
+#else
++ double intpart, fractpart;
++ fractpart = modf(value, &intpart);
++ if ((fabs(fractpart) != 0.5) || ((((int)intpart) % 2) != 0))
++ return (int)(value + (value >= 0 ? 0.5 : -0.5));
++ else
++ return (int)intpart;
+#endif
+}
+
+CV_INLINE int cvFloor( double value )
+{
+#if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__)
+ __m128d t = _mm_set_sd( value );
+ int i = _mm_cvtsd_si32(t);
+ return i - _mm_movemask_pd(_mm_cmplt_sd(t, _mm_cvtsi32_sd(t,i)));
+#elif defined __GNUC__
+ int i = (int)value;
+ return i - (i > value);
+#else
+ int i = cvRound(value);
+ float diff = (float)(value - i);
+ return i - (diff < 0);
+#endif
+}
+
+CV_INLINE int cvCeil( double value )
+{
+#if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__&& !defined __APPLE__)) && !defined(__CUDACC__)
+ __m128d t = _mm_set_sd( value );
+ int i = _mm_cvtsd_si32(t);
+ return i + _mm_movemask_pd(_mm_cmplt_sd(_mm_cvtsi32_sd(t,i), t));
+#elif defined __GNUC__
+ int i = (int)value;
+ return i + (i < value);
+#else
+ int i = cvRound(value);
+ float diff = (float)(i - value);
+ return i + (diff < 0);
+#endif
+}
+
+CV_INLINE int cvIsNaN( double value )
+{
+ union { uint64 u; double f; } ieee754;
+ ieee754.f = value;
+ return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) +
+ ((unsigned)ieee754.u != 0) > 0x7ff00000;
+}
+
+CV_INLINE int cvIsInf( double value )
+{
+ union { uint64 u; double f; } ieee754;
+ ieee754.f = value;
+ return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
+ (unsigned)ieee754.u == 0;
+}
+
+/****************************************************************************************\
+* exchange-add operation for atomic operations on reference counters *
+\****************************************************************************************/
+
+#if defined __INTEL_COMPILER && !(defined WIN32 || defined _WIN32)
+ // atomic increment on the linux version of the Intel(tm) compiler
+# define CV_XADD(addr, delta) (int)_InterlockedExchangeAdd(const_cast<void*>(reinterpret_cast<volatile void*>(addr)), delta)
+#elif defined __GNUC__
+# if defined __clang__ && __clang_major__ >= 3 && !defined __ANDROID__
+# ifdef __ATOMIC_ACQ_REL
+# define CV_XADD(addr, delta) __c11_atomic_fetch_add((_Atomic(int)*)(addr), delta, __ATOMIC_ACQ_REL)
+# else
+# define CV_XADD(addr, delta) __atomic_fetch_add((_Atomic(int)*)(addr), delta, 4)
+# endif
+# else
+# if defined __ATOMIC_ACQ_REL && !defined __clang__
+ // version for gcc >= 4.7
+# define CV_XADD(addr, delta) __atomic_fetch_add(addr, delta, __ATOMIC_ACQ_REL)
+# else
+# define CV_XADD(addr, delta) __sync_fetch_and_add(addr, delta)
+# endif
+# endif
+#elif (defined WIN32 || defined _WIN32 || defined WINCE) && (!defined RC_INVOKED)
+# if !defined(_M_AMD64) && !defined(_M_IA64) && !defined(_M_ARM)
+ CV_EXTERN_C __declspec(dllimport) long __stdcall InterlockedExchangeAdd(long volatile *Addend, long Value);
+# define CV_XADD(addr, delta) (int)InterlockedExchangeAdd((long volatile*)addr, delta)
+# else
+ CV_EXTERN_C long _InterlockedExchangeAdd (long volatile *Addend, long Value);
+# pragma intrinsic(_InterlockedExchangeAdd)
+# define CV_XADD(addr, delta) (int)_InterlockedExchangeAdd((long volatile*)addr, delta)
+# endif
+#else
+ CV_INLINE CV_XADD(int* addr, int delta) { int tmp = *addr; *addr += delta; return tmp; }
+#endif
+
+#endif // __OPENCV_CORE_CVDEF_H__
//
//M*/
-#ifndef __OPENCV_CORE_MATRIX_OPERATIONS_HPP__
-#define __OPENCV_CORE_MATRIX_OPERATIONS_HPP__
+#ifndef __OPENCV_CORE_MAT_HPP__
+#define __OPENCV_CORE_MAT_HPP__
-#ifndef SKIP_INCLUDES
-#include <limits.h>
-#include <string.h>
-#endif // SKIP_INCLUDES
-
-#ifdef __cplusplus
-
-namespace cv
-{
+#ifndef __cplusplus
+# error mat.hpp header must be compiled as C++
+#endif
-//////////////////////////////// Mat ////////////////////////////////
+#include "opencv2/core/matx.hpp"
+#include "opencv2/core/types.hpp"
-inline void Mat::initEmpty()
-{
- flags = MAGIC_VAL;
- dims = rows = cols = 0;
- data = datastart = dataend = datalimit = 0;
- refcount = 0;
- allocator = 0;
-}
-
-inline Mat::Mat() : size(&rows)
-{
- initEmpty();
-}
-inline Mat::Mat(int _rows, int _cols, int _type) : size(&rows)
+namespace cv
{
- initEmpty();
- create(_rows, _cols, _type);
-}
-inline Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s) : size(&rows)
-{
- initEmpty();
- create(_rows, _cols, _type);
- *this = _s;
-}
+//////////////////////// Input/Output Array Arguments /////////////////////////////////
-inline Mat::Mat(Size _sz, int _type) : size(&rows)
+/*!
+ Proxy datatype for passing Mat's and vector<>'s as input parameters
+ */
+class CV_EXPORTS _InputArray
{
- initEmpty();
- create( _sz.height, _sz.width, _type );
-}
+public:
+ enum {
+ KIND_SHIFT = 16,
+ FIXED_TYPE = 0x8000 << KIND_SHIFT,
+ FIXED_SIZE = 0x4000 << KIND_SHIFT,
+ KIND_MASK = ~(FIXED_TYPE|FIXED_SIZE) - (1 << KIND_SHIFT) + 1,
+
+ NONE = 0 << KIND_SHIFT,
+ MAT = 1 << KIND_SHIFT,
+ MATX = 2 << KIND_SHIFT,
+ STD_VECTOR = 3 << KIND_SHIFT,
+ STD_VECTOR_VECTOR = 4 << KIND_SHIFT,
+ STD_VECTOR_MAT = 5 << KIND_SHIFT,
+ EXPR = 6 << KIND_SHIFT,
+ OPENGL_BUFFER = 7 << KIND_SHIFT,
+ OPENGL_TEXTURE = 8 << KIND_SHIFT,
+ GPU_MAT = 9 << KIND_SHIFT
+ };
+
+ _InputArray();
+ _InputArray(const Mat& m);
+ _InputArray(const MatExpr& expr);
+ _InputArray(const std::vector<Mat>& vec);
+ template<typename _Tp> _InputArray(const Mat_<_Tp>& m);
+ template<typename _Tp> _InputArray(const std::vector<_Tp>& vec);
+ template<typename _Tp> _InputArray(const std::vector<std::vector<_Tp> >& vec);
+ template<typename _Tp> _InputArray(const std::vector<Mat_<_Tp> >& vec);
+ template<typename _Tp> _InputArray(const _Tp* vec, int n);
+ template<typename _Tp, int m, int n> _InputArray(const Matx<_Tp, m, n>& matx);
+ _InputArray(const double& val);
+ _InputArray(const gpu::GpuMat& d_mat);
+ _InputArray(const ogl::Buffer& buf);
+ _InputArray(const ogl::Texture2D& tex);
+
+ virtual Mat getMat(int i=-1) const;
+ virtual void getMatVector(std::vector<Mat>& mv) const;
+ virtual gpu::GpuMat getGpuMat() const;
+ virtual ogl::Buffer getOGlBuffer() const;
+ virtual ogl::Texture2D getOGlTexture2D() const;
+
+ virtual int kind() const;
+ virtual Size size(int i=-1) const;
+ virtual size_t total(int i=-1) const;
+ virtual int type(int i=-1) const;
+ virtual int depth(int i=-1) const;
+ virtual int channels(int i=-1) const;
+ virtual bool empty() const;
+
+ virtual ~_InputArray();
-inline Mat::Mat(Size _sz, int _type, const Scalar& _s) : size(&rows)
-{
- initEmpty();
- create(_sz.height, _sz.width, _type);
- *this = _s;
-}
+ int flags;
+ void* obj;
+ Size sz;
+};
-inline Mat::Mat(int _dims, const int* _sz, int _type) : size(&rows)
-{
- initEmpty();
- create(_dims, _sz, _type);
-}
-inline Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s) : size(&rows)
-{
- initEmpty();
- create(_dims, _sz, _type);
- *this = _s;
-}
-
-inline Mat::Mat(const Mat& m)
- : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
- refcount(m.refcount), datastart(m.datastart), dataend(m.dataend),
- datalimit(m.datalimit), allocator(m.allocator), size(&rows)
-{
- if( refcount )
- CV_XADD(refcount, 1);
- if( m.dims <= 2 )
- {
- step[0] = m.step[0]; step[1] = m.step[1];
- }
- else
- {
- dims = 0;
- copySize(m);
- }
-}
-
-inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
- : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_rows), cols(_cols),
- data((uchar*)_data), refcount(0), datastart((uchar*)_data), dataend(0),
- datalimit(0), allocator(0), size(&rows)
-{
- size_t esz = CV_ELEM_SIZE(_type), minstep = cols*esz;
- if( _step == AUTO_STEP )
- {
- _step = minstep;
- flags |= CONTINUOUS_FLAG;
- }
- else
- {
- if( rows == 1 ) _step = minstep;
- CV_DbgAssert( _step >= minstep );
- flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
- }
- step[0] = _step; step[1] = esz;
- datalimit = datastart + _step*rows;
- dataend = datalimit - _step + minstep;
-}
-
-inline Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
- : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_sz.height), cols(_sz.width),
- data((uchar*)_data), refcount(0), datastart((uchar*)_data), dataend(0),
- datalimit(0), allocator(0), size(&rows)
-{
- size_t esz = CV_ELEM_SIZE(_type), minstep = cols*esz;
- if( _step == AUTO_STEP )
- {
- _step = minstep;
- flags |= CONTINUOUS_FLAG;
- }
- else
- {
- if( rows == 1 ) _step = minstep;
- CV_DbgAssert( _step >= minstep );
- flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
- }
- step[0] = _step; step[1] = esz;
- datalimit = datastart + _step*rows;
- dataend = datalimit - _step + minstep;
-}
-
-
-template<typename _Tp> inline Mat::Mat(const vector<_Tp>& vec, bool copyData)
- : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
- dims(2), rows((int)vec.size()), cols(1), data(0), refcount(0),
- datastart(0), dataend(0), allocator(0), size(&rows)
+/*!
+ Proxy datatype for passing Mat's and vector<>'s as input parameters
+ */
+class CV_EXPORTS _OutputArray : public _InputArray
{
- if(vec.empty())
- return;
- if( !copyData )
- {
- step[0] = step[1] = sizeof(_Tp);
- data = datastart = (uchar*)&vec[0];
- datalimit = dataend = datastart + rows*step[0];
- }
- else
- Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
-}
-
-
-template<typename _Tp, int n> inline Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
- : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
- dims(2), rows(n), cols(1), data(0), refcount(0),
- datastart(0), dataend(0), allocator(0), size(&rows)
-{
- if( !copyData )
- {
- step[0] = step[1] = sizeof(_Tp);
- data = datastart = (uchar*)vec.val;
- datalimit = dataend = datastart + rows*step[0];
- }
- else
- Mat(n, 1, DataType<_Tp>::type, (void*)vec.val).copyTo(*this);
-}
-
-
-template<typename _Tp, int m, int n> inline Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
- : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
- dims(2), rows(m), cols(n), data(0), refcount(0),
- datastart(0), dataend(0), allocator(0), size(&rows)
-{
- if( !copyData )
- {
- step[0] = cols*sizeof(_Tp);
- step[1] = sizeof(_Tp);
- data = datastart = (uchar*)M.val;
- datalimit = dataend = datastart + rows*step[0];
- }
- else
- Mat(m, n, DataType<_Tp>::type, (uchar*)M.val).copyTo(*this);
-}
-
-
-template<typename _Tp> inline Mat::Mat(const Point_<_Tp>& pt, bool copyData)
- : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
- dims(2), rows(2), cols(1), data(0), refcount(0),
- datastart(0), dataend(0), allocator(0), size(&rows)
-{
- if( !copyData )
- {
- step[0] = step[1] = sizeof(_Tp);
- data = datastart = (uchar*)&pt.x;
- datalimit = dataend = datastart + rows*step[0];
- }
- else
+public:
+ enum
{
- create(2, 1, DataType<_Tp>::type);
- ((_Tp*)data)[0] = pt.x;
- ((_Tp*)data)[1] = pt.y;
- }
-}
-
+ DEPTH_MASK_8U = 1 << CV_8U,
+ DEPTH_MASK_8S = 1 << CV_8S,
+ DEPTH_MASK_16U = 1 << CV_16U,
+ DEPTH_MASK_16S = 1 << CV_16S,
+ DEPTH_MASK_32S = 1 << CV_32S,
+ DEPTH_MASK_32F = 1 << CV_32F,
+ DEPTH_MASK_64F = 1 << CV_64F,
+ DEPTH_MASK_ALL = (DEPTH_MASK_64F<<1)-1,
+ DEPTH_MASK_ALL_BUT_8S = DEPTH_MASK_ALL & ~DEPTH_MASK_8S,
+ DEPTH_MASK_FLT = DEPTH_MASK_32F + DEPTH_MASK_64F
+ };
+
+ _OutputArray();
+ _OutputArray(Mat& m);
+ _OutputArray(std::vector<Mat>& vec);
+ _OutputArray(gpu::GpuMat& d_mat);
+ _OutputArray(ogl::Buffer& buf);
+ _OutputArray(ogl::Texture2D& tex);
+ template<typename _Tp> _OutputArray(std::vector<_Tp>& vec);
+ template<typename _Tp> _OutputArray(std::vector<std::vector<_Tp> >& vec);
+ template<typename _Tp> _OutputArray(std::vector<Mat_<_Tp> >& vec);
+ template<typename _Tp> _OutputArray(Mat_<_Tp>& m);
+ template<typename _Tp> _OutputArray(_Tp* vec, int n);
+ template<typename _Tp, int m, int n> _OutputArray(Matx<_Tp, m, n>& matx);
+
+ _OutputArray(const Mat& m);
+ _OutputArray(const std::vector<Mat>& vec);
+ _OutputArray(const gpu::GpuMat& d_mat);
+ _OutputArray(const ogl::Buffer& buf);
+ _OutputArray(const ogl::Texture2D& tex);
+ template<typename _Tp> _OutputArray(const std::vector<_Tp>& vec);
+ template<typename _Tp> _OutputArray(const std::vector<std::vector<_Tp> >& vec);
+ template<typename _Tp> _OutputArray(const std::vector<Mat_<_Tp> >& vec);
+ template<typename _Tp> _OutputArray(const Mat_<_Tp>& m);
+ template<typename _Tp> _OutputArray(const _Tp* vec, int n);
+ template<typename _Tp, int m, int n> _OutputArray(const Matx<_Tp, m, n>& matx);
+
+ virtual bool fixedSize() const;
+ virtual bool fixedType() const;
+ virtual bool needed() const;
+ virtual Mat& getMatRef(int i=-1) const;
+ virtual gpu::GpuMat& getGpuMatRef() const;
+ virtual ogl::Buffer& getOGlBufferRef() const;
+ virtual ogl::Texture2D& getOGlTexture2DRef() const;
+ virtual void create(Size sz, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
+ virtual void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
+ virtual void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
+ virtual void release() const;
+ virtual void clear() const;
+
+ virtual ~_OutputArray();
+};
-template<typename _Tp> inline Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
- : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
- dims(2), rows(3), cols(1), data(0), refcount(0),
- datastart(0), dataend(0), allocator(0), size(&rows)
-{
- if( !copyData )
- {
- step[0] = step[1] = sizeof(_Tp);
- data = datastart = (uchar*)&pt.x;
- datalimit = dataend = datastart + rows*step[0];
- }
- else
- {
- create(3, 1, DataType<_Tp>::type);
- ((_Tp*)data)[0] = pt.x;
- ((_Tp*)data)[1] = pt.y;
- ((_Tp*)data)[2] = pt.z;
- }
-}
-
-
-template<typename _Tp> inline Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer)
- : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
- dims(0), rows(0), cols(0), data(0), refcount(0),
- datastart(0), dataend(0), allocator(0), size(&rows)
-{
- *this = *commaInitializer;
-}
+typedef const _InputArray& InputArray;
+typedef InputArray InputArrayOfArrays;
+typedef const _OutputArray& OutputArray;
+typedef OutputArray OutputArrayOfArrays;
+typedef OutputArray InputOutputArray;
+typedef OutputArray InputOutputArrayOfArrays;
-inline Mat::~Mat()
-{
- release();
- if( step.p != step.buf )
- fastFree(step.p);
-}
+CV_EXPORTS OutputArray noArray();
-inline Mat& Mat::operator = (const Mat& m)
-{
- if( this != &m )
- {
- if( m.refcount )
- CV_XADD(m.refcount, 1);
- release();
- flags = m.flags;
- if( dims <= 2 && m.dims <= 2 )
- {
- dims = m.dims;
- rows = m.rows;
- cols = m.cols;
- step[0] = m.step[0];
- step[1] = m.step[1];
- }
- else
- copySize(m);
- data = m.data;
- datastart = m.datastart;
- dataend = m.dataend;
- datalimit = m.datalimit;
- refcount = m.refcount;
- allocator = m.allocator;
- }
- return *this;
-}
-
-inline Mat Mat::row(int y) const { return Mat(*this, Range(y, y+1), Range::all()); }
-inline Mat Mat::col(int x) const { return Mat(*this, Range::all(), Range(x, x+1)); }
-inline Mat Mat::rowRange(int startrow, int endrow) const
- { return Mat(*this, Range(startrow, endrow), Range::all()); }
-inline Mat Mat::rowRange(const Range& r) const
- { return Mat(*this, r, Range::all()); }
-inline Mat Mat::colRange(int startcol, int endcol) const
- { return Mat(*this, Range::all(), Range(startcol, endcol)); }
-inline Mat Mat::colRange(const Range& r) const
- { return Mat(*this, Range::all(), r); }
-
-inline Mat Mat::diag(const Mat& d)
-{
- CV_Assert( d.cols == 1 || d.rows == 1 );
- int len = d.rows + d.cols - 1;
- Mat m(len, len, d.type(), Scalar(0)), md = m.diag();
- if( d.cols == 1 )
- d.copyTo(md);
- else
- transpose(d, md);
- return m;
-}
-
-inline Mat Mat::clone() const
-{
- Mat m;
- copyTo(m);
- return m;
-}
-inline void Mat::assignTo( Mat& m, int _type ) const
-{
- if( _type < 0 )
- m = *this;
- else
- convertTo(m, _type);
-}
-inline void Mat::create(int _rows, int _cols, int _type)
-{
- _type &= TYPE_MASK;
- if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data )
- return;
- int sz[] = {_rows, _cols};
- create(2, sz, _type);
-}
-
-inline void Mat::create(Size _sz, int _type)
-{
- create(_sz.height, _sz.width, _type);
-}
+/////////////////////////////////// MatAllocator //////////////////////////////////////
-inline void Mat::addref()
-{ if( refcount ) CV_XADD(refcount, 1); }
+/*!
+ Custom array allocator
-inline void Mat::release()
+*/
+class CV_EXPORTS MatAllocator
{
- if( refcount && CV_XADD(refcount, -1) == 1 )
- deallocate();
- data = datastart = dataend = datalimit = 0;
- size.p[0] = 0;
- refcount = 0;
-}
-
-inline Mat Mat::operator()( Range _rowRange, Range _colRange ) const
-{
- return Mat(*this, _rowRange, _colRange);
-}
-
-inline Mat Mat::operator()( const Rect& roi ) const
-{ return Mat(*this, roi); }
+public:
+ MatAllocator() {}
+ virtual ~MatAllocator() {}
+ virtual void allocate(int dims, const int* sizes, int type, int*& refcount,
+ uchar*& datastart, uchar*& data, size_t* step) = 0;
+ virtual void deallocate(int* refcount, uchar* datastart, uchar* data) = 0;
+};
-inline Mat Mat::operator()(const Range* ranges) const
-{
- return Mat(*this, ranges);
-}
-inline Mat::operator CvMat() const
-{
- CV_DbgAssert(dims <= 2);
- CvMat m = cvMat(rows, dims == 1 ? 1 : cols, type(), data);
- m.step = (int)step[0];
- m.type = (m.type & ~CONTINUOUS_FLAG) | (flags & CONTINUOUS_FLAG);
- return m;
-}
-
-inline bool Mat::isContinuous() const { return (flags & CONTINUOUS_FLAG) != 0; }
-inline bool Mat::isSubmatrix() const { return (flags & SUBMATRIX_FLAG) != 0; }
-inline size_t Mat::elemSize() const { return dims > 0 ? step.p[dims-1] : 0; }
-inline size_t Mat::elemSize1() const { return CV_ELEM_SIZE1(flags); }
-inline int Mat::type() const { return CV_MAT_TYPE(flags); }
-inline int Mat::depth() const { return CV_MAT_DEPTH(flags); }
-inline int Mat::channels() const { return CV_MAT_CN(flags); }
-inline size_t Mat::step1(int i) const { return step.p[i]/elemSize1(); }
-inline bool Mat::empty() const { return data == 0 || total() == 0; }
-inline size_t Mat::total() const
-{
- if( dims <= 2 )
- return (size_t)rows*cols;
- size_t p = 1;
- for( int i = 0; i < dims; i++ )
- p *= size[i];
- return p;
-}
-
-inline uchar* Mat::ptr(int y)
-{
- CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
- return data + step.p[0]*y;
-}
-inline const uchar* Mat::ptr(int y) const
-{
- CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
- return data + step.p[0]*y;
-}
+//////////////////////////////// MatCommaInitializer //////////////////////////////////
-template<typename _Tp> inline _Tp* Mat::ptr(int y)
-{
- CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
- return (_Tp*)(data + step.p[0]*y);
-}
+/*!
+ Comma-separated Matrix Initializer
-template<typename _Tp> inline const _Tp* Mat::ptr(int y) const
-{
- CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
- return (const _Tp*)(data + step.p[0]*y);
-}
+ The class instances are usually not created explicitly.
+ Instead, they are created on "matrix << firstValue" operator.
+ The sample below initializes 2x2 rotation matrix:
-inline uchar* Mat::ptr(int i0, int i1)
+ \code
+ double angle = 30, a = cos(angle*CV_PI/180), b = sin(angle*CV_PI/180);
+ Mat R = (Mat_<double>(2,2) << a, -b, b, a);
+ \endcode
+*/
+template<typename _Tp> class MatCommaInitializer_
{
- CV_DbgAssert( dims >= 2 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] );
- return data + i0*step.p[0] + i1*step.p[1];
-}
+public:
+ //! the constructor, created by "matrix << firstValue" operator, where matrix is cv::Mat
+ MatCommaInitializer_(Mat_<_Tp>* _m);
+ //! the operator that takes the next value and put it to the matrix
+ template<typename T2> MatCommaInitializer_<_Tp>& operator , (T2 v);
+ //! another form of conversion operator
+ operator Mat_<_Tp>() const;
+protected:
+ MatIterator_<_Tp> it;
+};
-inline const uchar* Mat::ptr(int i0, int i1) const
-{
- CV_DbgAssert( dims >= 2 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] );
- return data + i0*step.p[0] + i1*step.p[1];
-}
-template<typename _Tp> inline _Tp* Mat::ptr(int i0, int i1)
-{
- CV_DbgAssert( dims >= 2 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] );
- return (_Tp*)(data + i0*step.p[0] + i1*step.p[1]);
-}
-template<typename _Tp> inline const _Tp* Mat::ptr(int i0, int i1) const
-{
- CV_DbgAssert( dims >= 2 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] );
- return (const _Tp*)(data + i0*step.p[0] + i1*step.p[1]);
-}
-inline uchar* Mat::ptr(int i0, int i1, int i2)
-{
- CV_DbgAssert( dims >= 3 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] &&
- (unsigned)i2 < (unsigned)size.p[2] );
- return data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2];
-}
-
-inline const uchar* Mat::ptr(int i0, int i1, int i2) const
-{
- CV_DbgAssert( dims >= 3 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] &&
- (unsigned)i2 < (unsigned)size.p[2] );
- return data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2];
-}
-
-template<typename _Tp> inline _Tp* Mat::ptr(int i0, int i1, int i2)
+/////////////////////////////////////// Mat ///////////////////////////////////////////
+
+/*!
+ The n-dimensional matrix class.
+
+ The class represents an n-dimensional dense numerical array that can act as
+ a matrix, image, optical flow map, 3-focal tensor etc.
+ It is very similar to CvMat and CvMatND types from earlier versions of OpenCV,
+ and similarly to those types, the matrix can be multi-channel. It also fully supports ROI mechanism.
+
+ There are many different ways to create cv::Mat object. Here are the some popular ones:
+ <ul>
+ <li> using cv::Mat::create(nrows, ncols, type) method or
+ the similar constructor cv::Mat::Mat(nrows, ncols, type[, fill_value]) constructor.
+ A new matrix of the specified size and specifed type will be allocated.
+ "type" has the same meaning as in cvCreateMat function,
+ e.g. CV_8UC1 means 8-bit single-channel matrix, CV_32FC2 means 2-channel (i.e. complex)
+ floating-point matrix etc:
+
+ \code
+ // make 7x7 complex matrix filled with 1+3j.
+ cv::Mat M(7,7,CV_32FC2,Scalar(1,3));
+ // and now turn M to 100x60 15-channel 8-bit matrix.
+ // The old content will be deallocated
+ M.create(100,60,CV_8UC(15));
+ \endcode
+
+ As noted in the introduction of this chapter, Mat::create()
+ will only allocate a new matrix when the current matrix dimensionality
+ or type are different from the specified.
+
+ <li> by using a copy constructor or assignment operator, where on the right side it can
+ be a matrix or expression, see below. Again, as noted in the introduction,
+ matrix assignment is O(1) operation because it only copies the header
+ and increases the reference counter. cv::Mat::clone() method can be used to get a full
+ (a.k.a. deep) copy of the matrix when you need it.
+
+ <li> by constructing a header for a part of another matrix. It can be a single row, single column,
+ several rows, several columns, rectangular region in the matrix (called a minor in algebra) or
+ a diagonal. Such operations are also O(1), because the new header will reference the same data.
+ You can actually modify a part of the matrix using this feature, e.g.
+
+ \code
+ // add 5-th row, multiplied by 3 to the 3rd row
+ M.row(3) = M.row(3) + M.row(5)*3;
+
+ // now copy 7-th column to the 1-st column
+ // M.col(1) = M.col(7); // this will not work
+ Mat M1 = M.col(1);
+ M.col(7).copyTo(M1);
+
+ // create new 320x240 image
+ cv::Mat img(Size(320,240),CV_8UC3);
+ // select a roi
+ cv::Mat roi(img, Rect(10,10,100,100));
+ // fill the ROI with (0,255,0) (which is green in RGB space);
+ // the original 320x240 image will be modified
+ roi = Scalar(0,255,0);
+ \endcode
+
+ Thanks to the additional cv::Mat::datastart and cv::Mat::dataend members, it is possible to
+ compute the relative sub-matrix position in the main "container" matrix using cv::Mat::locateROI():
+
+ \code
+ Mat A = Mat::eye(10, 10, CV_32S);
+ // extracts A columns, 1 (inclusive) to 3 (exclusive).
+ Mat B = A(Range::all(), Range(1, 3));
+ // extracts B rows, 5 (inclusive) to 9 (exclusive).
+ // that is, C ~ A(Range(5, 9), Range(1, 3))
+ Mat C = B(Range(5, 9), Range::all());
+ Size size; Point ofs;
+ C.locateROI(size, ofs);
+ // size will be (width=10,height=10) and the ofs will be (x=1, y=5)
+ \endcode
+
+ As in the case of whole matrices, if you need a deep copy, use cv::Mat::clone() method
+ of the extracted sub-matrices.
+
+ <li> by making a header for user-allocated-data. It can be useful for
+ <ol>
+ <li> processing "foreign" data using OpenCV (e.g. when you implement
+ a DirectShow filter or a processing module for gstreamer etc.), e.g.
+
+ \code
+ void process_video_frame(const unsigned char* pixels,
+ int width, int height, int step)
+ {
+ cv::Mat img(height, width, CV_8UC3, pixels, step);
+ cv::GaussianBlur(img, img, cv::Size(7,7), 1.5, 1.5);
+ }
+ \endcode
+
+ <li> for quick initialization of small matrices and/or super-fast element access
+
+ \code
+ double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}};
+ cv::Mat M = cv::Mat(3, 3, CV_64F, m).inv();
+ \endcode
+ </ol>
+
+ partial yet very common cases of this "user-allocated data" case are conversions
+ from CvMat and IplImage to cv::Mat. For this purpose there are special constructors
+ taking pointers to CvMat or IplImage and the optional
+ flag indicating whether to copy the data or not.
+
+ Backward conversion from cv::Mat to CvMat or IplImage is provided via cast operators
+ cv::Mat::operator CvMat() an cv::Mat::operator IplImage().
+ The operators do not copy the data.
+
+
+ \code
+ IplImage* img = cvLoadImage("greatwave.jpg", 1);
+ Mat mtx(img); // convert IplImage* -> cv::Mat
+ CvMat oldmat = mtx; // convert cv::Mat -> CvMat
+ CV_Assert(oldmat.cols == img->width && oldmat.rows == img->height &&
+ oldmat.data.ptr == (uchar*)img->imageData && oldmat.step == img->widthStep);
+ \endcode
+
+ <li> by using MATLAB-style matrix initializers, cv::Mat::zeros(), cv::Mat::ones(), cv::Mat::eye(), e.g.:
+
+ \code
+ // create a double-precision identity martix and add it to M.
+ M += Mat::eye(M.rows, M.cols, CV_64F);
+ \endcode
+
+ <li> by using comma-separated initializer:
+
+ \code
+ // create 3x3 double-precision identity matrix
+ Mat M = (Mat_<double>(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);
+ \endcode
+
+ here we first call constructor of cv::Mat_ class (that we describe further) with the proper matrix,
+ and then we just put "<<" operator followed by comma-separated values that can be constants,
+ variables, expressions etc. Also, note the extra parentheses that are needed to avoid compiler errors.
+
+ </ul>
+
+ Once matrix is created, it will be automatically managed by using reference-counting mechanism
+ (unless the matrix header is built on top of user-allocated data,
+ in which case you should handle the data by yourself).
+ The matrix data will be deallocated when no one points to it;
+ if you want to release the data pointed by a matrix header before the matrix destructor is called,
+ use cv::Mat::release().
+
+ The next important thing to learn about the matrix class is element access. Here is how the matrix is stored.
+ The elements are stored in row-major order (row by row). The cv::Mat::data member points to the first element of the first row,
+ cv::Mat::rows contains the number of matrix rows and cv::Mat::cols - the number of matrix columns. There is yet another member,
+ cv::Mat::step that is used to actually compute address of a matrix element. cv::Mat::step is needed because the matrix can be
+ a part of another matrix or because there can some padding space in the end of each row for a proper alignment.
+
+ \image html roi.png
+
+ Given these parameters, address of the matrix element M_{ij} is computed as following:
+
+ addr(M_{ij})=M.data + M.step*i + j*M.elemSize()
+
+ if you know the matrix element type, e.g. it is float, then you can use cv::Mat::at() method:
+
+ addr(M_{ij})=&M.at<float>(i,j)
+
+ (where & is used to convert the reference returned by cv::Mat::at() to a pointer).
+ if you need to process a whole row of matrix, the most efficient way is to get
+ the pointer to the row first, and then just use plain C operator []:
+
+ \code
+ // compute sum of positive matrix elements
+ // (assuming that M is double-precision matrix)
+ double sum=0;
+ for(int i = 0; i < M.rows; i++)
+ {
+ const double* Mi = M.ptr<double>(i);
+ for(int j = 0; j < M.cols; j++)
+ sum += std::max(Mi[j], 0.);
+ }
+ \endcode
+
+ Some operations, like the above one, do not actually depend on the matrix shape,
+ they just process elements of a matrix one by one (or elements from multiple matrices
+ that are sitting in the same place, e.g. matrix addition). Such operations are called
+ element-wise and it makes sense to check whether all the input/output matrices are continuous,
+ i.e. have no gaps in the end of each row, and if yes, process them as a single long row:
+
+ \code
+ // compute sum of positive matrix elements, optimized variant
+ double sum=0;
+ int cols = M.cols, rows = M.rows;
+ if(M.isContinuous())
+ {
+ cols *= rows;
+ rows = 1;
+ }
+ for(int i = 0; i < rows; i++)
+ {
+ const double* Mi = M.ptr<double>(i);
+ for(int j = 0; j < cols; j++)
+ sum += std::max(Mi[j], 0.);
+ }
+ \endcode
+ in the case of continuous matrix the outer loop body will be executed just once,
+ so the overhead will be smaller, which will be especially noticeable in the case of small matrices.
+
+ Finally, there are STL-style iterators that are smart enough to skip gaps between successive rows:
+ \code
+ // compute sum of positive matrix elements, iterator-based variant
+ double sum=0;
+ MatConstIterator_<double> it = M.begin<double>(), it_end = M.end<double>();
+ for(; it != it_end; ++it)
+ sum += std::max(*it, 0.);
+ \endcode
+
+ The matrix iterators are random-access iterators, so they can be passed
+ to any STL algorithm, including std::sort().
+*/
+class CV_EXPORTS Mat
{
- CV_DbgAssert( dims >= 3 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] &&
- (unsigned)i2 < (unsigned)size.p[2] );
- return (_Tp*)(data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2]);
-}
-
-template<typename _Tp> inline const _Tp* Mat::ptr(int i0, int i1, int i2) const
-{
- CV_DbgAssert( dims >= 3 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] &&
- (unsigned)i2 < (unsigned)size.p[2] );
- return (const _Tp*)(data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2]);
-}
-
-inline uchar* Mat::ptr(const int* idx)
-{
- int i, d = dims;
- uchar* p = data;
- CV_DbgAssert( d >= 1 && p );
- for( i = 0; i < d; i++ )
+public:
+ //! default constructor
+ Mat();
+ //! constructs 2D matrix of the specified size and type
+ // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
+ Mat(int rows, int cols, int type);
+ Mat(Size size, int type);
+ //! constucts 2D matrix and fills it with the specified value _s.
+ Mat(int rows, int cols, int type, const Scalar& s);
+ Mat(Size size, int type, const Scalar& s);
+
+ //! constructs n-dimensional matrix
+ Mat(int ndims, const int* sizes, int type);
+ Mat(int ndims, const int* sizes, int type, const Scalar& s);
+
+ //! copy constructor
+ Mat(const Mat& m);
+ //! constructor for matrix headers pointing to user-allocated data
+ Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP);
+ Mat(Size size, int type, void* data, size_t step=AUTO_STEP);
+ Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0);
+
+ //! creates a matrix header for a part of the bigger matrix
+ Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all());
+ Mat(const Mat& m, const Rect& roi);
+ Mat(const Mat& m, const Range* ranges);
+ //! builds matrix from std::vector with or without copying the data
+ template<typename _Tp> explicit Mat(const std::vector<_Tp>& vec, bool copyData=false);
+ //! builds matrix from cv::Vec; the data is copied by default
+ template<typename _Tp, int n> explicit Mat(const Vec<_Tp, n>& vec, bool copyData=true);
+ //! builds matrix from cv::Matx; the data is copied by default
+ template<typename _Tp, int m, int n> explicit Mat(const Matx<_Tp, m, n>& mtx, bool copyData=true);
+ //! builds matrix from a 2D point
+ template<typename _Tp> explicit Mat(const Point_<_Tp>& pt, bool copyData=true);
+ //! builds matrix from a 3D point
+ template<typename _Tp> explicit Mat(const Point3_<_Tp>& pt, bool copyData=true);
+ //! builds matrix from comma initializer
+ template<typename _Tp> explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer);
+
+ // //! converts old-style CvMat to the new matrix; the data is not copied by default
+ // Mat(const CvMat* m, bool copyData=false);
+ // //! converts old-style CvMatND to the new matrix; the data is not copied by default
+ // Mat(const CvMatND* m, bool copyData=false);
+ // //! converts old-style IplImage to the new matrix; the data is not copied by default
+ // Mat(const IplImage* img, bool copyData=false);
+ //Mat(const void* img, bool copyData=false);
+
+ //! download data from GpuMat
+ explicit Mat(const gpu::GpuMat& m);
+
+ //! destructor - calls release()
+ ~Mat();
+ //! assignment operators
+ Mat& operator = (const Mat& m);
+ Mat& operator = (const MatExpr& expr);
+
+ //! returns a new matrix header for the specified row
+ Mat row(int y) const;
+ //! returns a new matrix header for the specified column
+ Mat col(int x) const;
+ //! ... for the specified row span
+ Mat rowRange(int startrow, int endrow) const;
+ Mat rowRange(const Range& r) const;
+ //! ... for the specified column span
+ Mat colRange(int startcol, int endcol) const;
+ Mat colRange(const Range& r) const;
+ //! ... for the specified diagonal
+ // (d=0 - the main diagonal,
+ // >0 - a diagonal from the lower half,
+ // <0 - a diagonal from the upper half)
+ Mat diag(int d=0) const;
+ //! constructs a square diagonal matrix which main diagonal is vector "d"
+ static Mat diag(const Mat& d);
+
+ //! returns deep copy of the matrix, i.e. the data is copied
+ Mat clone() const;
+ //! copies the matrix content to "m".
+ // It calls m.create(this->size(), this->type()).
+ void copyTo( OutputArray m ) const;
+ //! copies those matrix elements to "m" that are marked with non-zero mask elements.
+ void copyTo( OutputArray m, InputArray mask ) const;
+ //! converts matrix to another datatype with optional scalng. See cvConvertScale.
+ void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;
+
+ void assignTo( Mat& m, int type=-1 ) const;
+
+ //! sets every matrix element to s
+ Mat& operator = (const Scalar& s);
+ //! sets some of the matrix elements to s, according to the mask
+ Mat& setTo(InputArray value, InputArray mask=noArray());
+ //! creates alternative matrix header for the same data, with different
+ // number of channels and/or different number of rows. see cvReshape.
+ Mat reshape(int cn, int rows=0) const;
+ Mat reshape(int cn, int newndims, const int* newsz) const;
+
+ //! matrix transposition by means of matrix expressions
+ MatExpr t() const;
+ //! matrix inversion by means of matrix expressions
+ MatExpr inv(int method=DECOMP_LU) const;
+ //! per-element matrix multiplication by means of matrix expressions
+ MatExpr mul(InputArray m, double scale=1) const;
+
+ //! computes cross-product of 2 3D vectors
+ Mat cross(InputArray m) const;
+ //! computes dot-product
+ double dot(InputArray m) const;
+
+ //! Matlab-style matrix initialization
+ static MatExpr zeros(int rows, int cols, int type);
+ static MatExpr zeros(Size size, int type);
+ static MatExpr zeros(int ndims, const int* sz, int type);
+ static MatExpr ones(int rows, int cols, int type);
+ static MatExpr ones(Size size, int type);
+ static MatExpr ones(int ndims, const int* sz, int type);
+ static MatExpr eye(int rows, int cols, int type);
+ static MatExpr eye(Size size, int type);
+
+ //! allocates new matrix data unless the matrix already has specified size and type.
+ // previous data is unreferenced if needed.
+ void create(int rows, int cols, int type);
+ void create(Size size, int type);
+ void create(int ndims, const int* sizes, int type);
+
+ //! increases the reference counter; use with care to avoid memleaks
+ void addref();
+ //! decreases reference counter;
+ // deallocates the data when reference counter reaches 0.
+ void release();
+
+ //! deallocates the matrix data
+ void deallocate();
+ //! internal use function; properly re-allocates _size, _step arrays
+ void copySize(const Mat& m);
+
+ //! reserves enough space to fit sz hyper-planes
+ void reserve(size_t sz);
+ //! resizes matrix to the specified number of hyper-planes
+ void resize(size_t sz);
+ //! resizes matrix to the specified number of hyper-planes; initializes the newly added elements
+ void resize(size_t sz, const Scalar& s);
+ //! internal function
+ void push_back_(const void* elem);
+ //! adds element to the end of 1d matrix (or possibly multiple elements when _Tp=Mat)
+ template<typename _Tp> void push_back(const _Tp& elem);
+ template<typename _Tp> void push_back(const Mat_<_Tp>& elem);
+ void push_back(const Mat& m);
+ //! removes several hyper-planes from bottom of the matrix
+ void pop_back(size_t nelems=1);
+
+ //! locates matrix header within a parent matrix. See below
+ void locateROI( Size& wholeSize, Point& ofs ) const;
+ //! moves/resizes the current matrix ROI inside the parent matrix.
+ Mat& adjustROI( int dtop, int dbottom, int dleft, int dright );
+ //! extracts a rectangular sub-matrix
+ // (this is a generalized form of row, rowRange etc.)
+ Mat operator()( Range rowRange, Range colRange ) const;
+ Mat operator()( const Rect& roi ) const;
+ Mat operator()( const Range* ranges ) const;
+
+ // //! converts header to CvMat; no data is copied
+ // operator CvMat() const;
+ // //! converts header to CvMatND; no data is copied
+ // operator CvMatND() const;
+ // //! converts header to IplImage; no data is copied
+ // operator IplImage() const;
+
+ template<typename _Tp> operator std::vector<_Tp>() const;
+ template<typename _Tp, int n> operator Vec<_Tp, n>() const;
+ template<typename _Tp, int m, int n> operator Matx<_Tp, m, n>() const;
+
+ //! returns true iff the matrix data is continuous
+ // (i.e. when there are no gaps between successive rows).
+ // similar to CV_IS_MAT_CONT(cvmat->type)
+ bool isContinuous() const;
+
+ //! returns true if the matrix is a submatrix of another matrix
+ bool isSubmatrix() const;
+
+ //! returns element size in bytes,
+ // similar to CV_ELEM_SIZE(cvmat->type)
+ size_t elemSize() const;
+ //! returns the size of element channel in bytes.
+ size_t elemSize1() const;
+ //! returns element type, similar to CV_MAT_TYPE(cvmat->type)
+ int type() const;
+ //! returns element type, similar to CV_MAT_DEPTH(cvmat->type)
+ int depth() const;
+ //! returns element type, similar to CV_MAT_CN(cvmat->type)
+ int channels() const;
+ //! returns step/elemSize1()
+ size_t step1(int i=0) const;
+ //! returns true if matrix data is NULL
+ bool empty() const;
+ //! returns the total number of matrix elements
+ size_t total() const;
+
+ //! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise
+ int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const;
+
+ //! returns pointer to i0-th submatrix along the dimension #0
+ uchar* ptr(int i0=0);
+ const uchar* ptr(int i0=0) const;
+
+ //! returns pointer to (i0,i1) submatrix along the dimensions #0 and #1
+ uchar* ptr(int i0, int i1);
+ const uchar* ptr(int i0, int i1) const;
+
+ //! returns pointer to (i0,i1,i3) submatrix along the dimensions #0, #1, #2
+ uchar* ptr(int i0, int i1, int i2);
+ const uchar* ptr(int i0, int i1, int i2) const;
+
+ //! returns pointer to the matrix element
+ uchar* ptr(const int* idx);
+ //! returns read-only pointer to the matrix element
+ const uchar* ptr(const int* idx) const;
+
+ template<int n> uchar* ptr(const Vec<int, n>& idx);
+ template<int n> const uchar* ptr(const Vec<int, n>& idx) const;
+
+ //! template version of the above method
+ template<typename _Tp> _Tp* ptr(int i0=0);
+ template<typename _Tp> const _Tp* ptr(int i0=0) const;
+
+ template<typename _Tp> _Tp* ptr(int i0, int i1);
+ template<typename _Tp> const _Tp* ptr(int i0, int i1) const;
+
+ template<typename _Tp> _Tp* ptr(int i0, int i1, int i2);
+ template<typename _Tp> const _Tp* ptr(int i0, int i1, int i2) const;
+
+ template<typename _Tp> _Tp* ptr(const int* idx);
+ template<typename _Tp> const _Tp* ptr(const int* idx) const;
+
+ template<typename _Tp, int n> _Tp* ptr(const Vec<int, n>& idx);
+ template<typename _Tp, int n> const _Tp* ptr(const Vec<int, n>& idx) const;
+
+ //! the same as above, with the pointer dereferencing
+ template<typename _Tp> _Tp& at(int i0=0);
+ template<typename _Tp> const _Tp& at(int i0=0) const;
+
+ template<typename _Tp> _Tp& at(int i0, int i1);
+ template<typename _Tp> const _Tp& at(int i0, int i1) const;
+
+ template<typename _Tp> _Tp& at(int i0, int i1, int i2);
+ template<typename _Tp> const _Tp& at(int i0, int i1, int i2) const;
+
+ template<typename _Tp> _Tp& at(const int* idx);
+ template<typename _Tp> const _Tp& at(const int* idx) const;
+
+ template<typename _Tp, int n> _Tp& at(const Vec<int, n>& idx);
+ template<typename _Tp, int n> const _Tp& at(const Vec<int, n>& idx) const;
+
+ //! special versions for 2D arrays (especially convenient for referencing image pixels)
+ template<typename _Tp> _Tp& at(Point pt);
+ template<typename _Tp> const _Tp& at(Point pt) const;
+
+ //! template methods for iteration over matrix elements.
+ // the iterators take care of skipping gaps in the end of rows (if any)
+ template<typename _Tp> MatIterator_<_Tp> begin();
+ template<typename _Tp> MatIterator_<_Tp> end();
+ template<typename _Tp> MatConstIterator_<_Tp> begin() const;
+ template<typename _Tp> MatConstIterator_<_Tp> end() const;
+
+ enum { MAGIC_VAL=0x42FF0000, AUTO_STEP=0, CONTINUOUS_FLAG=CV_MAT_CONT_FLAG, SUBMATRIX_FLAG=CV_SUBMAT_FLAG };
+ enum { MAGIC_MASK=0xFFFF0000, TYPE_MASK=0x00000FFF, DEPTH_MASK=7 };
+
+ /*! includes several bit-fields:
+ - the magic signature
+ - continuity flag
+ - depth
+ - number of channels
+ */
+ int flags;
+ //! the matrix dimensionality, >= 2
+ int dims;
+ //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
+ int rows, cols;
+ //! pointer to the data
+ uchar* data;
+
+ //! pointer to the reference counter;
+ // when matrix points to user-allocated data, the pointer is NULL
+ int* refcount;
+
+ //! helper fields used in locateROI and adjustROI
+ uchar* datastart;
+ uchar* dataend;
+ uchar* datalimit;
+
+ //! custom allocator
+ MatAllocator* allocator;
+
+ struct CV_EXPORTS MSize
{
- CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
- p += idx[i]*step.p[i];
- }
- return p;
-}
-
-inline const uchar* Mat::ptr(const int* idx) const
-{
- int i, d = dims;
- uchar* p = data;
- CV_DbgAssert( d >= 1 && p );
- for( i = 0; i < d; i++ )
+ MSize(int* _p);
+ Size operator()() const;
+ const int& operator[](int i) const;
+ int& operator[](int i);
+ operator const int*() const;
+ bool operator == (const MSize& sz) const;
+ bool operator != (const MSize& sz) const;
+
+ int* p;
+ };
+
+ struct CV_EXPORTS MStep
{
- CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
- p += idx[i]*step.p[i];
- }
- return p;
-}
-
-template<typename _Tp> inline _Tp& Mat::at(int i0, int i1)
-{
- CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
- CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
- return ((_Tp*)(data + step.p[0]*i0))[i1];
-}
-
-template<typename _Tp> inline const _Tp& Mat::at(int i0, int i1) const
-{
- CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
- CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
- return ((const _Tp*)(data + step.p[0]*i0))[i1];
-}
-
-template<typename _Tp> inline _Tp& Mat::at(Point pt)
-{
- CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
- (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
- CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
- return ((_Tp*)(data + step.p[0]*pt.y))[pt.x];
-}
-
-template<typename _Tp> inline const _Tp& Mat::at(Point pt) const
-{
- CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
- (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
- CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
- return ((const _Tp*)(data + step.p[0]*pt.y))[pt.x];
-}
-
-template<typename _Tp> inline _Tp& Mat::at(int i0)
-{
- CV_DbgAssert( dims <= 2 && data &&
- (unsigned)i0 < (unsigned)(size.p[0]*size.p[1]) &&
- elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
- if( isContinuous() || size.p[0] == 1 )
- return ((_Tp*)data)[i0];
- if( size.p[1] == 1 )
- return *(_Tp*)(data + step.p[0]*i0);
- int i = i0/cols, j = i0 - i*cols;
- return ((_Tp*)(data + step.p[0]*i))[j];
-}
-
-template<typename _Tp> inline const _Tp& Mat::at(int i0) const
-{
- CV_DbgAssert( dims <= 2 && data &&
- (unsigned)i0 < (unsigned)(size.p[0]*size.p[1]) &&
- elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
- if( isContinuous() || size.p[0] == 1 )
- return ((const _Tp*)data)[i0];
- if( size.p[1] == 1 )
- return *(const _Tp*)(data + step.p[0]*i0);
- int i = i0/cols, j = i0 - i*cols;
- return ((const _Tp*)(data + step.p[0]*i))[j];
-}
-
-template<typename _Tp> inline _Tp& Mat::at(int i0, int i1, int i2)
-{
- CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
- return *(_Tp*)ptr(i0, i1, i2);
-}
-template<typename _Tp> inline const _Tp& Mat::at(int i0, int i1, int i2) const
-{
- CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
- return *(const _Tp*)ptr(i0, i1, i2);
-}
-template<typename _Tp> inline _Tp& Mat::at(const int* idx)
-{
- CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
- return *(_Tp*)ptr(idx);
-}
-template<typename _Tp> inline const _Tp& Mat::at(const int* idx) const
-{
- CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
- return *(const _Tp*)ptr(idx);
-}
-template<typename _Tp, int n> _Tp& Mat::at(const Vec<int, n>& idx)
-{
- CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
- return *(_Tp*)ptr(idx.val);
-}
-template<typename _Tp, int n> inline const _Tp& Mat::at(const Vec<int, n>& idx) const
-{
- CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
- return *(const _Tp*)ptr(idx.val);
-}
-
-
-template<typename _Tp> inline MatConstIterator_<_Tp> Mat::begin() const
-{
- CV_DbgAssert( elemSize() == sizeof(_Tp) );
- return MatConstIterator_<_Tp>((const Mat_<_Tp>*)this);
-}
-
-template<typename _Tp> inline MatConstIterator_<_Tp> Mat::end() const
-{
- CV_DbgAssert( elemSize() == sizeof(_Tp) );
- MatConstIterator_<_Tp> it((const Mat_<_Tp>*)this);
- it += total();
- return it;
-}
-
-template<typename _Tp> inline MatIterator_<_Tp> Mat::begin()
-{
- CV_DbgAssert( elemSize() == sizeof(_Tp) );
- return MatIterator_<_Tp>((Mat_<_Tp>*)this);
-}
+ MStep();
+ MStep(size_t s);
+ const size_t& operator[](int i) const;
+ size_t& operator[](int i);
+ operator size_t() const;
+ MStep& operator = (size_t s);
+
+ size_t* p;
+ size_t buf[2];
+ protected:
+ MStep& operator = (const MStep&);
+ };
+
+ MSize size;
+ MStep step;
+
+protected:
+};
-template<typename _Tp> inline MatIterator_<_Tp> Mat::end()
-{
- CV_DbgAssert( elemSize() == sizeof(_Tp) );
- MatIterator_<_Tp> it((Mat_<_Tp>*)this);
- it += total();
- return it;
-}
-template<typename _Tp> inline Mat::operator vector<_Tp>() const
-{
- vector<_Tp> v;
- copyTo(v);
- return v;
-}
+///////////////////////////////// Mat_<_Tp> ////////////////////////////////////
-template<typename _Tp, int n> inline Mat::operator Vec<_Tp, n>() const
+/*!
+ Template matrix class derived from Mat
+
+ The class Mat_ is a "thin" template wrapper on top of cv::Mat. It does not have any extra data fields,
+ nor it or cv::Mat have any virtual methods and thus references or pointers to these two classes
+ can be safely converted one to another. But do it with care, for example:
+
+ \code
+ // create 100x100 8-bit matrix
+ Mat M(100,100,CV_8U);
+ // this will compile fine. no any data conversion will be done.
+ Mat_<float>& M1 = (Mat_<float>&)M;
+ // the program will likely crash at the statement below
+ M1(99,99) = 1.f;
+ \endcode
+
+ While cv::Mat is sufficient in most cases, cv::Mat_ can be more convenient if you use a lot of element
+ access operations and if you know matrix type at compile time.
+ Note that cv::Mat::at<_Tp>(int y, int x) and cv::Mat_<_Tp>::operator ()(int y, int x) do absolutely the
+ same thing and run at the same speed, but the latter is certainly shorter:
+
+ \code
+ Mat_<double> M(20,20);
+ for(int i = 0; i < M.rows; i++)
+ for(int j = 0; j < M.cols; j++)
+ M(i,j) = 1./(i+j+1);
+ Mat E, V;
+ eigen(M,E,V);
+ cout << E.at<double>(0,0)/E.at<double>(M.rows-1,0);
+ \endcode
+
+ It is easy to use Mat_ for multi-channel images/matrices - just pass cv::Vec as cv::Mat_ template parameter:
+
+ \code
+ // allocate 320x240 color image and fill it with green (in RGB space)
+ Mat_<Vec3b> img(240, 320, Vec3b(0,255,0));
+ // now draw a diagonal white line
+ for(int i = 0; i < 100; i++)
+ img(i,i)=Vec3b(255,255,255);
+ // and now modify the 2nd (red) channel of each pixel
+ for(int i = 0; i < img.rows; i++)
+ for(int j = 0; j < img.cols; j++)
+ img(i,j)[2] ^= (uchar)(i ^ j); // img(y,x)[c] accesses c-th channel of the pixel (x,y)
+ \endcode
+*/
+template<typename _Tp> class CV_EXPORTS Mat_ : public Mat
{
- CV_Assert( data && dims <= 2 && (rows == 1 || cols == 1) &&
- rows + cols - 1 == n && channels() == 1 );
-
- if( isContinuous() && type() == DataType<_Tp>::type )
- return Vec<_Tp, n>((_Tp*)data);
- Vec<_Tp, n> v; Mat tmp(rows, cols, DataType<_Tp>::type, v.val);
- convertTo(tmp, tmp.type());
- return v;
-}
+public:
+ typedef _Tp value_type;
+ typedef typename DataType<_Tp>::channel_type channel_type;
+ typedef MatIterator_<_Tp> iterator;
+ typedef MatConstIterator_<_Tp> const_iterator;
+
+ //! default constructor
+ Mat_();
+ //! equivalent to Mat(_rows, _cols, DataType<_Tp>::type)
+ Mat_(int _rows, int _cols);
+ //! constructor that sets each matrix element to specified value
+ Mat_(int _rows, int _cols, const _Tp& value);
+ //! equivalent to Mat(_size, DataType<_Tp>::type)
+ explicit Mat_(Size _size);
+ //! constructor that sets each matrix element to specified value
+ Mat_(Size _size, const _Tp& value);
+ //! n-dim array constructor
+ Mat_(int _ndims, const int* _sizes);
+ //! n-dim array constructor that sets each matrix element to specified value
+ Mat_(int _ndims, const int* _sizes, const _Tp& value);
+ //! copy/conversion contructor. If m is of different type, it's converted
+ Mat_(const Mat& m);
+ //! copy constructor
+ Mat_(const Mat_& m);
+ //! constructs a matrix on top of user-allocated data. step is in bytes(!!!), regardless of the type
+ Mat_(int _rows, int _cols, _Tp* _data, size_t _step=AUTO_STEP);
+ //! constructs n-dim matrix on top of user-allocated data. steps are in bytes(!!!), regardless of the type
+ Mat_(int _ndims, const int* _sizes, _Tp* _data, const size_t* _steps=0);
+ //! selects a submatrix
+ Mat_(const Mat_& m, const Range& rowRange, const Range& colRange=Range::all());
+ //! selects a submatrix
+ Mat_(const Mat_& m, const Rect& roi);
+ //! selects a submatrix, n-dim version
+ Mat_(const Mat_& m, const Range* ranges);
+ //! from a matrix expression
+ explicit Mat_(const MatExpr& e);
+ //! makes a matrix out of Vec, std::vector, Point_ or Point3_. The matrix will have a single column
+ explicit Mat_(const std::vector<_Tp>& vec, bool copyData=false);
+ template<int n> explicit Mat_(const Vec<typename DataType<_Tp>::channel_type, n>& vec, bool copyData=true);
+ template<int m, int n> explicit Mat_(const Matx<typename DataType<_Tp>::channel_type, m, n>& mtx, bool copyData=true);
+ explicit Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData=true);
+ explicit Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData=true);
+ explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer);
+
+ Mat_& operator = (const Mat& m);
+ Mat_& operator = (const Mat_& m);
+ //! set all the elements to s.
+ Mat_& operator = (const _Tp& s);
+ //! assign a matrix expression
+ Mat_& operator = (const MatExpr& e);
+
+ //! iterators; they are smart enough to skip gaps in the end of rows
+ iterator begin();
+ iterator end();
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ //! equivalent to Mat::create(_rows, _cols, DataType<_Tp>::type)
+ void create(int _rows, int _cols);
+ //! equivalent to Mat::create(_size, DataType<_Tp>::type)
+ void create(Size _size);
+ //! equivalent to Mat::create(_ndims, _sizes, DatType<_Tp>::type)
+ void create(int _ndims, const int* _sizes);
+ //! cross-product
+ Mat_ cross(const Mat_& m) const;
+ //! data type conversion
+ template<typename T2> operator Mat_<T2>() const;
+ //! overridden forms of Mat::row() etc.
+ Mat_ row(int y) const;
+ Mat_ col(int x) const;
+ Mat_ diag(int d=0) const;
+ Mat_ clone() const;
+
+ //! overridden forms of Mat::elemSize() etc.
+ size_t elemSize() const;
+ size_t elemSize1() const;
+ int type() const;
+ int depth() const;
+ int channels() const;
+ size_t step1(int i=0) const;
+ //! returns step()/sizeof(_Tp)
+ size_t stepT(int i=0) const;
+
+ //! overridden forms of Mat::zeros() etc. Data type is omitted, of course
+ static MatExpr zeros(int rows, int cols);
+ static MatExpr zeros(Size size);
+ static MatExpr zeros(int _ndims, const int* _sizes);
+ static MatExpr ones(int rows, int cols);
+ static MatExpr ones(Size size);
+ static MatExpr ones(int _ndims, const int* _sizes);
+ static MatExpr eye(int rows, int cols);
+ static MatExpr eye(Size size);
+
+ //! some more overriden methods
+ Mat_& adjustROI( int dtop, int dbottom, int dleft, int dright );
+ Mat_ operator()( const Range& rowRange, const Range& colRange ) const;
+ Mat_ operator()( const Rect& roi ) const;
+ Mat_ operator()( const Range* ranges ) const;
+
+ //! more convenient forms of row and element access operators
+ _Tp* operator [](int y);
+ const _Tp* operator [](int y) const;
+
+ //! returns reference to the specified element
+ _Tp& operator ()(const int* idx);
+ //! returns read-only reference to the specified element
+ const _Tp& operator ()(const int* idx) const;
+
+ //! returns reference to the specified element
+ template<int n> _Tp& operator ()(const Vec<int, n>& idx);
+ //! returns read-only reference to the specified element
+ template<int n> const _Tp& operator ()(const Vec<int, n>& idx) const;
+
+ //! returns reference to the specified element (1D case)
+ _Tp& operator ()(int idx0);
+ //! returns read-only reference to the specified element (1D case)
+ const _Tp& operator ()(int idx0) const;
+ //! returns reference to the specified element (2D case)
+ _Tp& operator ()(int idx0, int idx1);
+ //! returns read-only reference to the specified element (2D case)
+ const _Tp& operator ()(int idx0, int idx1) const;
+ //! returns reference to the specified element (3D case)
+ _Tp& operator ()(int idx0, int idx1, int idx2);
+ //! returns read-only reference to the specified element (3D case)
+ const _Tp& operator ()(int idx0, int idx1, int idx2) const;
+
+ _Tp& operator ()(Point pt);
+ const _Tp& operator ()(Point pt) const;
+
+ //! conversion to vector.
+ operator std::vector<_Tp>() const;
+ //! conversion to Vec
+ template<int n> operator Vec<typename DataType<_Tp>::channel_type, n>() const;
+ //! conversion to Matx
+ template<int m, int n> operator Matx<typename DataType<_Tp>::channel_type, m, n>() const;
+};
-template<typename _Tp, int m, int n> inline Mat::operator Matx<_Tp, m, n>() const
+typedef Mat_<uchar> Mat1b;
+typedef Mat_<Vec2b> Mat2b;
+typedef Mat_<Vec3b> Mat3b;
+typedef Mat_<Vec4b> Mat4b;
+
+typedef Mat_<short> Mat1s;
+typedef Mat_<Vec2s> Mat2s;
+typedef Mat_<Vec3s> Mat3s;
+typedef Mat_<Vec4s> Mat4s;
+
+typedef Mat_<ushort> Mat1w;
+typedef Mat_<Vec2w> Mat2w;
+typedef Mat_<Vec3w> Mat3w;
+typedef Mat_<Vec4w> Mat4w;
+
+typedef Mat_<int> Mat1i;
+typedef Mat_<Vec2i> Mat2i;
+typedef Mat_<Vec3i> Mat3i;
+typedef Mat_<Vec4i> Mat4i;
+
+typedef Mat_<float> Mat1f;
+typedef Mat_<Vec2f> Mat2f;
+typedef Mat_<Vec3f> Mat3f;
+typedef Mat_<Vec4f> Mat4f;
+
+typedef Mat_<double> Mat1d;
+typedef Mat_<Vec2d> Mat2d;
+typedef Mat_<Vec3d> Mat3d;
+typedef Mat_<Vec4d> Mat4d;
+
+
+
+/////////////////////////// multi-dimensional sparse matrix //////////////////////////
+
+/*!
+ Sparse matrix class.
+
+ The class represents multi-dimensional sparse numerical arrays. Such a sparse array can store elements
+ of any type that cv::Mat is able to store. "Sparse" means that only non-zero elements
+ are stored (though, as a result of some operations on a sparse matrix, some of its stored elements
+ can actually become 0. It's user responsibility to detect such elements and delete them using cv::SparseMat::erase().
+ The non-zero elements are stored in a hash table that grows when it's filled enough,
+ so that the search time remains O(1) in average. Elements can be accessed using the following methods:
+
+ <ol>
+ <li>Query operations: cv::SparseMat::ptr() and the higher-level cv::SparseMat::ref(),
+ cv::SparseMat::value() and cv::SparseMat::find, for example:
+ \code
+ const int dims = 5;
+ int size[] = {10, 10, 10, 10, 10};
+ SparseMat sparse_mat(dims, size, CV_32F);
+ for(int i = 0; i < 1000; i++)
+ {
+ int idx[dims];
+ for(int k = 0; k < dims; k++)
+ idx[k] = rand()%sparse_mat.size(k);
+ sparse_mat.ref<float>(idx) += 1.f;
+ }
+ \endcode
+
+ <li>Sparse matrix iterators. Like cv::Mat iterators and unlike cv::Mat iterators, the sparse matrix iterators are STL-style,
+ that is, the iteration is done as following:
+ \code
+ // prints elements of a sparse floating-point matrix and the sum of elements.
+ SparseMatConstIterator_<float>
+ it = sparse_mat.begin<float>(),
+ it_end = sparse_mat.end<float>();
+ double s = 0;
+ int dims = sparse_mat.dims();
+ for(; it != it_end; ++it)
+ {
+ // print element indices and the element value
+ const Node* n = it.node();
+ printf("(")
+ for(int i = 0; i < dims; i++)
+ printf("%3d%c", n->idx[i], i < dims-1 ? ',' : ')');
+ printf(": %f\n", *it);
+ s += *it;
+ }
+ printf("Element sum is %g\n", s);
+ \endcode
+ If you run this loop, you will notice that elements are enumerated
+ in no any logical order (lexicographical etc.),
+ they come in the same order as they stored in the hash table, i.e. semi-randomly.
+
+ You may collect pointers to the nodes and sort them to get the proper ordering.
+ Note, however, that pointers to the nodes may become invalid when you add more
+ elements to the matrix; this is because of possible buffer reallocation.
+
+ <li>A combination of the above 2 methods when you need to process 2 or more sparse
+ matrices simultaneously, e.g. this is how you can compute unnormalized
+ cross-correlation of the 2 floating-point sparse matrices:
+ \code
+ double crossCorr(const SparseMat& a, const SparseMat& b)
+ {
+ const SparseMat *_a = &a, *_b = &b;
+ // if b contains less elements than a,
+ // it's faster to iterate through b
+ if(_a->nzcount() > _b->nzcount())
+ std::swap(_a, _b);
+ SparseMatConstIterator_<float> it = _a->begin<float>(),
+ it_end = _a->end<float>();
+ double ccorr = 0;
+ for(; it != it_end; ++it)
+ {
+ // take the next element from the first matrix
+ float avalue = *it;
+ const Node* anode = it.node();
+ // and try to find element with the same index in the second matrix.
+ // since the hash value depends only on the element index,
+ // we reuse hashvalue stored in the node
+ float bvalue = _b->value<float>(anode->idx,&anode->hashval);
+ ccorr += avalue*bvalue;
+ }
+ return ccorr;
+ }
+ \endcode
+ </ol>
+*/
+class CV_EXPORTS SparseMat
{
- CV_Assert( data && dims <= 2 && rows == m && cols == n && channels() == 1 );
-
- if( isContinuous() && type() == DataType<_Tp>::type )
- return Matx<_Tp, m, n>((_Tp*)data);
- Matx<_Tp, m, n> mtx; Mat tmp(rows, cols, DataType<_Tp>::type, mtx.val);
- convertTo(tmp, tmp.type());
- return mtx;
-}
+public:
+ typedef SparseMatIterator iterator;
+ typedef SparseMatConstIterator const_iterator;
+ enum { MAGIC_VAL=0x42FD0000, MAX_DIM=32, HASH_SCALE=0x5bd1e995, HASH_BIT=0x80000000 };
-template<typename _Tp> inline void Mat::push_back(const _Tp& elem)
-{
- if( !data )
+ //! the sparse matrix header
+ struct CV_EXPORTS Hdr
{
- *this = Mat(1, 1, DataType<_Tp>::type, (void*)&elem).clone();
- return;
- }
- CV_Assert(DataType<_Tp>::type == type() && cols == 1
- /* && dims == 2 (cols == 1 implies dims == 2) */);
- uchar* tmp = dataend + step[0];
- if( !isSubmatrix() && isContinuous() && tmp <= datalimit )
+ Hdr(int _dims, const int* _sizes, int _type);
+ void clear();
+ int refcount;
+ int dims;
+ int valueOffset;
+ size_t nodeSize;
+ size_t nodeCount;
+ size_t freeList;
+ std::vector<uchar> pool;
+ std::vector<size_t> hashtab;
+ int size[MAX_DIM];
+ };
+
+ //! sparse matrix node - element of a hash table
+ struct CV_EXPORTS Node
{
- *(_Tp*)(data + (size.p[0]++)*step.p[0]) = elem;
- dataend = tmp;
- }
- else
- push_back_(&elem);
-}
-
-template<typename _Tp> inline void Mat::push_back(const Mat_<_Tp>& m)
-{
- push_back((const Mat&)m);
-}
-
-inline Mat::MSize::MSize(int* _p) : p(_p) {}
-inline Size Mat::MSize::operator()() const
-{
- CV_DbgAssert(p[-1] <= 2);
- return Size(p[1], p[0]);
-}
-inline const int& Mat::MSize::operator[](int i) const { return p[i]; }
-inline int& Mat::MSize::operator[](int i) { return p[i]; }
-inline Mat::MSize::operator const int*() const { return p; }
-
-inline bool Mat::MSize::operator == (const MSize& sz) const
-{
- int d = p[-1], dsz = sz.p[-1];
- if( d != dsz )
- return false;
- if( d == 2 )
- return p[0] == sz.p[0] && p[1] == sz.p[1];
-
- for( int i = 0; i < d; i++ )
- if( p[i] != sz.p[i] )
- return false;
- return true;
-}
-
-inline bool Mat::MSize::operator != (const MSize& sz) const
-{
- return !(*this == sz);
-}
-
-inline Mat::MStep::MStep() { p = buf; p[0] = p[1] = 0; }
-inline Mat::MStep::MStep(size_t s) { p = buf; p[0] = s; p[1] = 0; }
-inline const size_t& Mat::MStep::operator[](int i) const { return p[i]; }
-inline size_t& Mat::MStep::operator[](int i) { return p[i]; }
-inline Mat::MStep::operator size_t() const
-{
- CV_DbgAssert( p == buf );
- return buf[0];
-}
-inline Mat::MStep& Mat::MStep::operator = (size_t s)
-{
- CV_DbgAssert( p == buf );
- buf[0] = s;
- return *this;
-}
-
-static inline Mat cvarrToMatND(const CvArr* arr, bool copyData=false, int coiMode=0)
-{
- return cvarrToMat(arr, copyData, true, coiMode);
-}
-
-///////////////////////////////////////////// SVD //////////////////////////////////////////////////////
-
-inline SVD::SVD() {}
-inline SVD::SVD( InputArray m, int flags ) { operator ()(m, flags); }
-inline void SVD::solveZ( InputArray m, OutputArray _dst )
-{
- Mat mtx = m.getMat();
- SVD svd(mtx, (mtx.rows >= mtx.cols ? 0 : SVD::FULL_UV));
- _dst.create(svd.vt.cols, 1, svd.vt.type());
- Mat dst = _dst.getMat();
- svd.vt.row(svd.vt.rows-1).reshape(1,svd.vt.cols).copyTo(dst);
-}
-
-template<typename _Tp, int m, int n, int nm> inline void
- SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt )
-{
- assert( nm == MIN(m, n));
- Mat _a(a, false), _u(u, false), _w(w, false), _vt(vt, false);
- SVD::compute(_a, _w, _u, _vt);
- CV_Assert(_w.data == (uchar*)&w.val[0] && _u.data == (uchar*)&u.val[0] && _vt.data == (uchar*)&vt.val[0]);
-}
-
-template<typename _Tp, int m, int n, int nm> inline void
-SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w )
-{
- assert( nm == MIN(m, n));
- Mat _a(a, false), _w(w, false);
- SVD::compute(_a, _w);
- CV_Assert(_w.data == (uchar*)&w.val[0]);
-}
-
-template<typename _Tp, int m, int n, int nm, int nb> inline void
-SVD::backSubst( const Matx<_Tp, nm, 1>& w, const Matx<_Tp, m, nm>& u,
- const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs,
- Matx<_Tp, n, nb>& dst )
-{
- assert( nm == MIN(m, n));
- Mat _u(u, false), _w(w, false), _vt(vt, false), _rhs(rhs, false), _dst(dst, false);
- SVD::backSubst(_w, _u, _vt, _rhs, _dst);
- CV_Assert(_dst.data == (uchar*)&dst.val[0]);
-}
-
-///////////////////////////////// Mat_<_Tp> ////////////////////////////////////
-
-template<typename _Tp> inline Mat_<_Tp>::Mat_()
- : Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; }
-
-template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols)
- : Mat(_rows, _cols, DataType<_Tp>::type) {}
-
-template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value)
- : Mat(_rows, _cols, DataType<_Tp>::type) { *this = value; }
-
-template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _sz)
- : Mat(_sz.height, _sz.width, DataType<_Tp>::type) {}
-
-template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _sz, const _Tp& value)
- : Mat(_sz.height, _sz.width, DataType<_Tp>::type) { *this = value; }
-
-template<typename _Tp> inline Mat_<_Tp>::Mat_(int _dims, const int* _sz)
- : Mat(_dims, _sz, DataType<_Tp>::type) {}
-
-template<typename _Tp> inline Mat_<_Tp>::Mat_(int _dims, const int* _sz, const _Tp& _s)
- : Mat(_dims, _sz, DataType<_Tp>::type, Scalar(_s)) {}
-
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const Range* ranges)
- : Mat(m, ranges) {}
-
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat& m)
- : Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; *this = m; }
-
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m)
- : Mat(m) {}
-
-template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t steps)
- : Mat(_rows, _cols, DataType<_Tp>::type, _data, steps) {}
-
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Range& _rowRange, const Range& _colRange)
- : Mat(m, _rowRange, _colRange) {}
+ //! hash value
+ size_t hashval;
+ //! index of the next node in the same hash table entry
+ size_t next;
+ //! index of the matrix element
+ int idx[MAX_DIM];
+ };
+
+ //! default constructor
+ SparseMat();
+ //! creates matrix of the specified size and type
+ SparseMat(int dims, const int* _sizes, int _type);
+ //! copy constructor
+ SparseMat(const SparseMat& m);
+ //! converts dense 2d matrix to the sparse form
+ /*!
+ \param m the input matrix
+ \param try1d if true and m is a single-column matrix (Nx1),
+ then the sparse matrix will be 1-dimensional.
+ */
+ explicit SparseMat(const Mat& m);
+ //! converts old-style sparse matrix to the new-style. All the data is copied
+ //SparseMat(const CvSparseMat* m);
+ //! the destructor
+ ~SparseMat();
+
+ //! assignment operator. This is O(1) operation, i.e. no data is copied
+ SparseMat& operator = (const SparseMat& m);
+ //! equivalent to the corresponding constructor
+ SparseMat& operator = (const Mat& m);
+
+ //! creates full copy of the matrix
+ SparseMat clone() const;
+
+ //! copies all the data to the destination matrix. All the previous content of m is erased
+ void copyTo( SparseMat& m ) const;
+ //! converts sparse matrix to dense matrix.
+ void copyTo( Mat& m ) const;
+ //! multiplies all the matrix elements by the specified scale factor alpha and converts the results to the specified data type
+ void convertTo( SparseMat& m, int rtype, double alpha=1 ) const;
+ //! converts sparse matrix to dense n-dim matrix with optional type conversion and scaling.
+ /*!
+ \param rtype The output matrix data type. When it is =-1, the output array will have the same data type as (*this)
+ \param alpha The scale factor
+ \param beta The optional delta added to the scaled values before the conversion
+ */
+ void convertTo( Mat& m, int rtype, double alpha=1, double beta=0 ) const;
+
+ // not used now
+ void assignTo( SparseMat& m, int type=-1 ) const;
+
+ //! reallocates sparse matrix.
+ /*!
+ If the matrix already had the proper size and type,
+ it is simply cleared with clear(), otherwise,
+ the old matrix is released (using release()) and the new one is allocated.
+ */
+ void create(int dims, const int* _sizes, int _type);
+ //! sets all the sparse matrix elements to 0, which means clearing the hash table.
+ void clear();
+ //! manually increments the reference counter to the header.
+ void addref();
+ // decrements the header reference counter. When the counter reaches 0, the header and all the underlying data are deallocated.
+ void release();
+
+ //! converts sparse matrix to the old-style representation; all the elements are copied.
+ //operator CvSparseMat*() const;
+ //! returns the size of each element in bytes (not including the overhead - the space occupied by SparseMat::Node elements)
+ size_t elemSize() const;
+ //! returns elemSize()/channels()
+ size_t elemSize1() const;
+
+ //! returns type of sparse matrix elements
+ int type() const;
+ //! returns the depth of sparse matrix elements
+ int depth() const;
+ //! returns the number of channels
+ int channels() const;
+
+ //! returns the array of sizes, or NULL if the matrix is not allocated
+ const int* size() const;
+ //! returns the size of i-th matrix dimension (or 0)
+ int size(int i) const;
+ //! returns the matrix dimensionality
+ int dims() const;
+ //! returns the number of non-zero elements (=the number of hash table nodes)
+ size_t nzcount() const;
+
+ //! computes the element hash value (1D case)
+ size_t hash(int i0) const;
+ //! computes the element hash value (2D case)
+ size_t hash(int i0, int i1) const;
+ //! computes the element hash value (3D case)
+ size_t hash(int i0, int i1, int i2) const;
+ //! computes the element hash value (nD case)
+ size_t hash(const int* idx) const;
+
+ //@{
+ /*!
+ specialized variants for 1D, 2D, 3D cases and the generic_type one for n-D case.
+
+ return pointer to the matrix element.
+ <ul>
+ <li>if the element is there (it's non-zero), the pointer to it is returned
+ <li>if it's not there and createMissing=false, NULL pointer is returned
+ <li>if it's not there and createMissing=true, then the new element
+ is created and initialized with 0. Pointer to it is returned
+ <li>if the optional hashval pointer is not NULL, the element hash value is
+ not computed, but *hashval is taken instead.
+ </ul>
+ */
+ //! returns pointer to the specified element (1D case)
+ uchar* ptr(int i0, bool createMissing, size_t* hashval=0);
+ //! returns pointer to the specified element (2D case)
+ uchar* ptr(int i0, int i1, bool createMissing, size_t* hashval=0);
+ //! returns pointer to the specified element (3D case)
+ uchar* ptr(int i0, int i1, int i2, bool createMissing, size_t* hashval=0);
+ //! returns pointer to the specified element (nD case)
+ uchar* ptr(const int* idx, bool createMissing, size_t* hashval=0);
+ //@}
+
+ //@{
+ /*!
+ return read-write reference to the specified sparse matrix element.
+
+ ref<_Tp>(i0,...[,hashval]) is equivalent to *(_Tp*)ptr(i0,...,true[,hashval]).
+ The methods always return a valid reference.
+ If the element did not exist, it is created and initialiazed with 0.
+ */
+ //! returns reference to the specified element (1D case)
+ template<typename _Tp> _Tp& ref(int i0, size_t* hashval=0);
+ //! returns reference to the specified element (2D case)
+ template<typename _Tp> _Tp& ref(int i0, int i1, size_t* hashval=0);
+ //! returns reference to the specified element (3D case)
+ template<typename _Tp> _Tp& ref(int i0, int i1, int i2, size_t* hashval=0);
+ //! returns reference to the specified element (nD case)
+ template<typename _Tp> _Tp& ref(const int* idx, size_t* hashval=0);
+ //@}
+
+ //@{
+ /*!
+ return value of the specified sparse matrix element.
+
+ value<_Tp>(i0,...[,hashval]) is equivalent
+
+ \code
+ { const _Tp* p = find<_Tp>(i0,...[,hashval]); return p ? *p : _Tp(); }
+ \endcode
+
+ That is, if the element did not exist, the methods return 0.
+ */
+ //! returns value of the specified element (1D case)
+ template<typename _Tp> _Tp value(int i0, size_t* hashval=0) const;
+ //! returns value of the specified element (2D case)
+ template<typename _Tp> _Tp value(int i0, int i1, size_t* hashval=0) const;
+ //! returns value of the specified element (3D case)
+ template<typename _Tp> _Tp value(int i0, int i1, int i2, size_t* hashval=0) const;
+ //! returns value of the specified element (nD case)
+ template<typename _Tp> _Tp value(const int* idx, size_t* hashval=0) const;
+ //@}
+
+ //@{
+ /*!
+ Return pointer to the specified sparse matrix element if it exists
+
+ find<_Tp>(i0,...[,hashval]) is equivalent to (_const Tp*)ptr(i0,...false[,hashval]).
+
+ If the specified element does not exist, the methods return NULL.
+ */
+ //! returns pointer to the specified element (1D case)
+ template<typename _Tp> const _Tp* find(int i0, size_t* hashval=0) const;
+ //! returns pointer to the specified element (2D case)
+ template<typename _Tp> const _Tp* find(int i0, int i1, size_t* hashval=0) const;
+ //! returns pointer to the specified element (3D case)
+ template<typename _Tp> const _Tp* find(int i0, int i1, int i2, size_t* hashval=0) const;
+ //! returns pointer to the specified element (nD case)
+ template<typename _Tp> const _Tp* find(const int* idx, size_t* hashval=0) const;
+
+ //! erases the specified element (2D case)
+ void erase(int i0, int i1, size_t* hashval=0);
+ //! erases the specified element (3D case)
+ void erase(int i0, int i1, int i2, size_t* hashval=0);
+ //! erases the specified element (nD case)
+ void erase(const int* idx, size_t* hashval=0);
+
+ //@{
+ /*!
+ return the sparse matrix iterator pointing to the first sparse matrix element
+ */
+ //! returns the sparse matrix iterator at the matrix beginning
+ SparseMatIterator begin();
+ //! returns the sparse matrix iterator at the matrix beginning
+ template<typename _Tp> SparseMatIterator_<_Tp> begin();
+ //! returns the read-only sparse matrix iterator at the matrix beginning
+ SparseMatConstIterator begin() const;
+ //! returns the read-only sparse matrix iterator at the matrix beginning
+ template<typename _Tp> SparseMatConstIterator_<_Tp> begin() const;
+ //@}
+ /*!
+ return the sparse matrix iterator pointing to the element following the last sparse matrix element
+ */
+ //! returns the sparse matrix iterator at the matrix end
+ SparseMatIterator end();
+ //! returns the read-only sparse matrix iterator at the matrix end
+ SparseMatConstIterator end() const;
+ //! returns the typed sparse matrix iterator at the matrix end
+ template<typename _Tp> SparseMatIterator_<_Tp> end();
+ //! returns the typed read-only sparse matrix iterator at the matrix end
+ template<typename _Tp> SparseMatConstIterator_<_Tp> end() const;
+
+ //! returns the value stored in the sparse martix node
+ template<typename _Tp> _Tp& value(Node* n);
+ //! returns the value stored in the sparse martix node
+ template<typename _Tp> const _Tp& value(const Node* n) const;
+
+ ////////////// some internal-use methods ///////////////
+ Node* node(size_t nidx);
+ const Node* node(size_t nidx) const;
+
+ uchar* newNode(const int* idx, size_t hashval);
+ void removeNode(size_t hidx, size_t nidx, size_t previdx);
+ void resizeHashTab(size_t newsize);
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
- : Mat(m, roi) {}
+ int flags;
+ Hdr* hdr;
+};
-template<typename _Tp> template<int n> inline
- Mat_<_Tp>::Mat_(const Vec<typename DataType<_Tp>::channel_type, n>& vec, bool copyData)
- : Mat(n/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&vec)
-{
- CV_Assert(n%DataType<_Tp>::channels == 0);
- if( copyData )
- *this = clone();
-}
-
-template<typename _Tp> template<int m, int n> inline
- Mat_<_Tp>::Mat_(const Matx<typename DataType<_Tp>::channel_type,m,n>& M, bool copyData)
- : Mat(m, n/DataType<_Tp>::channels, DataType<_Tp>::type, (void*)&M)
-{
- CV_Assert(n % DataType<_Tp>::channels == 0);
- if( copyData )
- *this = clone();
-}
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
- : Mat(2/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
-{
- CV_Assert(2 % DataType<_Tp>::channels == 0);
- if( copyData )
- *this = clone();
-}
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
- : Mat(3/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
-{
- CV_Assert(3 % DataType<_Tp>::channels == 0);
- if( copyData )
- *this = clone();
-}
+///////////////////////////////// SparseMat_<_Tp> ////////////////////////////////////
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const MatCommaInitializer_<_Tp>& commaInitializer)
- : Mat(commaInitializer) {}
+/*!
+ The Template Sparse Matrix class derived from cv::SparseMat
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const vector<_Tp>& vec, bool copyData)
- : Mat(vec, copyData) {}
+ The class provides slightly more convenient operations for accessing elements.
-template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m)
-{
- if( DataType<_Tp>::type == m.type() )
- {
- Mat::operator = (m);
- return *this;
- }
- if( DataType<_Tp>::depth == m.depth() )
- {
- return (*this = m.reshape(DataType<_Tp>::channels, m.dims, 0));
- }
- CV_DbgAssert(DataType<_Tp>::channels == m.channels());
- m.convertTo(*this, type());
- return *this;
-}
-
-template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat_& m)
+ \code
+ SparseMat m;
+ ...
+ SparseMat_<int> m_ = (SparseMat_<int>&)m;
+ m_.ref(1)++; // equivalent to m.ref<int>(1)++;
+ m_.ref(2) += m_(3); // equivalent to m.ref<int>(2) += m.value<int>(3);
+ \endcode
+*/
+template<typename _Tp> class CV_EXPORTS SparseMat_ : public SparseMat
{
- Mat::operator=(m);
- return *this;
-}
+public:
+ typedef SparseMatIterator_<_Tp> iterator;
+ typedef SparseMatConstIterator_<_Tp> const_iterator;
+
+ //! the default constructor
+ SparseMat_();
+ //! the full constructor equivelent to SparseMat(dims, _sizes, DataType<_Tp>::type)
+ SparseMat_(int dims, const int* _sizes);
+ //! the copy constructor. If DataType<_Tp>.type != m.type(), the m elements are converted
+ SparseMat_(const SparseMat& m);
+ //! the copy constructor. This is O(1) operation - no data is copied
+ SparseMat_(const SparseMat_& m);
+ //! converts dense matrix to the sparse form
+ SparseMat_(const Mat& m);
+ //! converts the old-style sparse matrix to the C++ class. All the elements are copied
+ //SparseMat_(const CvSparseMat* m);
+ //! the assignment operator. If DataType<_Tp>.type != m.type(), the m elements are converted
+ SparseMat_& operator = (const SparseMat& m);
+ //! the assignment operator. This is O(1) operation - no data is copied
+ SparseMat_& operator = (const SparseMat_& m);
+ //! converts dense matrix to the sparse form
+ SparseMat_& operator = (const Mat& m);
+
+ //! makes full copy of the matrix. All the elements are duplicated
+ SparseMat_ clone() const;
+ //! equivalent to cv::SparseMat::create(dims, _sizes, DataType<_Tp>::type)
+ void create(int dims, const int* _sizes);
+ //! converts sparse matrix to the old-style CvSparseMat. All the elements are copied
+ //operator CvSparseMat*() const;
+
+ //! returns type of the matrix elements
+ int type() const;
+ //! returns depth of the matrix elements
+ int depth() const;
+ //! returns the number of channels in each matrix element
+ int channels() const;
+
+ //! equivalent to SparseMat::ref<_Tp>(i0, hashval)
+ _Tp& ref(int i0, size_t* hashval=0);
+ //! equivalent to SparseMat::ref<_Tp>(i0, i1, hashval)
+ _Tp& ref(int i0, int i1, size_t* hashval=0);
+ //! equivalent to SparseMat::ref<_Tp>(i0, i1, i2, hashval)
+ _Tp& ref(int i0, int i1, int i2, size_t* hashval=0);
+ //! equivalent to SparseMat::ref<_Tp>(idx, hashval)
+ _Tp& ref(const int* idx, size_t* hashval=0);
+
+ //! equivalent to SparseMat::value<_Tp>(i0, hashval)
+ _Tp operator()(int i0, size_t* hashval=0) const;
+ //! equivalent to SparseMat::value<_Tp>(i0, i1, hashval)
+ _Tp operator()(int i0, int i1, size_t* hashval=0) const;
+ //! equivalent to SparseMat::value<_Tp>(i0, i1, i2, hashval)
+ _Tp operator()(int i0, int i1, int i2, size_t* hashval=0) const;
+ //! equivalent to SparseMat::value<_Tp>(idx, hashval)
+ _Tp operator()(const int* idx, size_t* hashval=0) const;
+
+ //! returns sparse matrix iterator pointing to the first sparse matrix element
+ SparseMatIterator_<_Tp> begin();
+ //! returns read-only sparse matrix iterator pointing to the first sparse matrix element
+ SparseMatConstIterator_<_Tp> begin() const;
+ //! returns sparse matrix iterator pointing to the element following the last sparse matrix element
+ SparseMatIterator_<_Tp> end();
+ //! returns read-only sparse matrix iterator pointing to the element following the last sparse matrix element
+ SparseMatConstIterator_<_Tp> end() const;
+};
-template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const _Tp& s)
-{
- typedef typename DataType<_Tp>::vec_type VT;
- Mat::operator=(Scalar((const VT&)s));
- return *this;
-}
-template<typename _Tp> inline void Mat_<_Tp>::create(int _rows, int _cols)
-{
- Mat::create(_rows, _cols, DataType<_Tp>::type);
-}
-template<typename _Tp> inline void Mat_<_Tp>::create(Size _sz)
-{
- Mat::create(_sz, DataType<_Tp>::type);
-}
+////////////////////////////////// MatConstIterator //////////////////////////////////
-template<typename _Tp> inline void Mat_<_Tp>::create(int _dims, const int* _sz)
+class CV_EXPORTS MatConstIterator
{
- Mat::create(_dims, _sz, DataType<_Tp>::type);
-}
+public:
+ typedef uchar* value_type;
+ typedef ptrdiff_t difference_type;
+ typedef const uchar** pointer;
+ typedef uchar* reference;
+#ifndef OPENCV_NOSTL
+ typedef std::random_access_iterator_tag iterator_category;
+#endif
-template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const
-{ return Mat_<_Tp>(Mat::cross(m)); }
+ //! default constructor
+ MatConstIterator();
+ //! constructor that sets the iterator to the beginning of the matrix
+ MatConstIterator(const Mat* _m);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatConstIterator(const Mat* _m, int _row, int _col=0);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatConstIterator(const Mat* _m, Point _pt);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatConstIterator(const Mat* _m, const int* _idx);
+ //! copy constructor
+ MatConstIterator(const MatConstIterator& it);
+
+ //! copy operator
+ MatConstIterator& operator = (const MatConstIterator& it);
+ //! returns the current matrix element
+ uchar* operator *() const;
+ //! returns the i-th matrix element, relative to the current
+ uchar* operator [](ptrdiff_t i) const;
+
+ //! shifts the iterator forward by the specified number of elements
+ MatConstIterator& operator += (ptrdiff_t ofs);
+ //! shifts the iterator backward by the specified number of elements
+ MatConstIterator& operator -= (ptrdiff_t ofs);
+ //! decrements the iterator
+ MatConstIterator& operator --();
+ //! decrements the iterator
+ MatConstIterator operator --(int);
+ //! increments the iterator
+ MatConstIterator& operator ++();
+ //! increments the iterator
+ MatConstIterator operator ++(int);
+ //! returns the current iterator position
+ Point pos() const;
+ //! returns the current iterator position
+ void pos(int* _idx) const;
+
+ ptrdiff_t lpos() const;
+ void seek(ptrdiff_t ofs, bool relative = false);
+ void seek(const int* _idx, bool relative = false);
+
+ const Mat* m;
+ size_t elemSize;
+ uchar* ptr;
+ uchar* sliceStart;
+ uchar* sliceEnd;
+};
-template<typename _Tp> template<typename T2> inline Mat_<_Tp>::operator Mat_<T2>() const
-{ return Mat_<T2>(*this); }
-template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::row(int y) const
-{ return Mat_(*this, Range(y, y+1), Range::all()); }
-template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::col(int x) const
-{ return Mat_(*this, Range::all(), Range(x, x+1)); }
-template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::diag(int d) const
-{ return Mat_(Mat::diag(d)); }
-template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::clone() const
-{ return Mat_(Mat::clone()); }
-template<typename _Tp> inline size_t Mat_<_Tp>::elemSize() const
-{
- CV_DbgAssert( Mat::elemSize() == sizeof(_Tp) );
- return sizeof(_Tp);
-}
+////////////////////////////////// MatConstIterator_ /////////////////////////////////
-template<typename _Tp> inline size_t Mat_<_Tp>::elemSize1() const
+/*!
+ Matrix read-only iterator
+ */
+template<typename _Tp>
+class MatConstIterator_ : public MatConstIterator
{
- CV_DbgAssert( Mat::elemSize1() == sizeof(_Tp)/DataType<_Tp>::channels );
- return sizeof(_Tp)/DataType<_Tp>::channels;
-}
-template<typename _Tp> inline int Mat_<_Tp>::type() const
-{
- CV_DbgAssert( Mat::type() == DataType<_Tp>::type );
- return DataType<_Tp>::type;
-}
-template<typename _Tp> inline int Mat_<_Tp>::depth() const
-{
- CV_DbgAssert( Mat::depth() == DataType<_Tp>::depth );
- return DataType<_Tp>::depth;
-}
-template<typename _Tp> inline int Mat_<_Tp>::channels() const
-{
- CV_DbgAssert( Mat::channels() == DataType<_Tp>::channels );
- return DataType<_Tp>::channels;
-}
-template<typename _Tp> inline size_t Mat_<_Tp>::stepT(int i) const { return step.p[i]/elemSize(); }
-template<typename _Tp> inline size_t Mat_<_Tp>::step1(int i) const { return step.p[i]/elemSize1(); }
+public:
+ typedef _Tp value_type;
+ typedef ptrdiff_t difference_type;
+ typedef const _Tp* pointer;
+ typedef const _Tp& reference;
-template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::adjustROI( int dtop, int dbottom, int dleft, int dright )
-{ return (Mat_<_Tp>&)(Mat::adjustROI(dtop, dbottom, dleft, dright)); }
+#ifndef OPENCV_NOSTL
+ typedef std::random_access_iterator_tag iterator_category;
+#endif
-template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range& _rowRange, const Range& _colRange ) const
-{ return Mat_<_Tp>(*this, _rowRange, _colRange); }
+ //! default constructor
+ MatConstIterator_();
+ //! constructor that sets the iterator to the beginning of the matrix
+ MatConstIterator_(const Mat_<_Tp>* _m);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col=0);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatConstIterator_(const Mat_<_Tp>* _m, Point _pt);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatConstIterator_(const Mat_<_Tp>* _m, const int* _idx);
+ //! copy constructor
+ MatConstIterator_(const MatConstIterator_& it);
+
+ //! copy operator
+ MatConstIterator_& operator = (const MatConstIterator_& it);
+ //! returns the current matrix element
+ _Tp operator *() const;
+ //! returns the i-th matrix element, relative to the current
+ _Tp operator [](ptrdiff_t i) const;
+
+ //! shifts the iterator forward by the specified number of elements
+ MatConstIterator_& operator += (ptrdiff_t ofs);
+ //! shifts the iterator backward by the specified number of elements
+ MatConstIterator_& operator -= (ptrdiff_t ofs);
+ //! decrements the iterator
+ MatConstIterator_& operator --();
+ //! decrements the iterator
+ MatConstIterator_ operator --(int);
+ //! increments the iterator
+ MatConstIterator_& operator ++();
+ //! increments the iterator
+ MatConstIterator_ operator ++(int);
+ //! returns the current iterator position
+ Point pos() const;
+};
-template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const
-{ return Mat_<_Tp>(*this, roi); }
-template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range* ranges ) const
-{ return Mat_<_Tp>(*this, ranges); }
-template<typename _Tp> inline _Tp* Mat_<_Tp>::operator [](int y)
-{ return (_Tp*)ptr(y); }
-template<typename _Tp> inline const _Tp* Mat_<_Tp>::operator [](int y) const
-{ return (const _Tp*)ptr(y); }
+//////////////////////////////////// MatIterator_ ////////////////////////////////////
-template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0, int i1)
-{
- CV_DbgAssert( dims <= 2 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] &&
- type() == DataType<_Tp>::type );
- return ((_Tp*)(data + step.p[0]*i0))[i1];
-}
-
-template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0, int i1) const
-{
- CV_DbgAssert( dims <= 2 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] &&
- type() == DataType<_Tp>::type );
- return ((const _Tp*)(data + step.p[0]*i0))[i1];
-}
-
-template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(Point pt)
+/*!
+ Matrix read-write iterator
+*/
+template<typename _Tp>
+class MatIterator_ : public MatConstIterator_<_Tp>
{
- CV_DbgAssert( dims <= 2 && data &&
- (unsigned)pt.y < (unsigned)size.p[0] &&
- (unsigned)pt.x < (unsigned)size.p[1] &&
- type() == DataType<_Tp>::type );
- return ((_Tp*)(data + step.p[0]*pt.y))[pt.x];
-}
-
-template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(Point pt) const
-{
- CV_DbgAssert( dims <= 2 && data &&
- (unsigned)pt.y < (unsigned)size.p[0] &&
- (unsigned)pt.x < (unsigned)size.p[1] &&
- type() == DataType<_Tp>::type );
- return ((const _Tp*)(data + step.p[0]*pt.y))[pt.x];
-}
-
-template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(const int* idx)
-{
- return Mat::at<_Tp>(idx);
-}
+public:
+ typedef _Tp* pointer;
+ typedef _Tp& reference;
-template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(const int* idx) const
-{
- return Mat::at<_Tp>(idx);
-}
+#ifndef OPENCV_NOSTL
+ typedef std::random_access_iterator_tag iterator_category;
+#endif
-template<typename _Tp> template<int n> inline _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx)
-{
- return Mat::at<_Tp>(idx);
-}
+ //! the default constructor
+ MatIterator_();
+ //! constructor that sets the iterator to the beginning of the matrix
+ MatIterator_(Mat_<_Tp>* _m);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatIterator_(Mat_<_Tp>* _m, int _row, int _col=0);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatIterator_(const Mat_<_Tp>* _m, Point _pt);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatIterator_(const Mat_<_Tp>* _m, const int* _idx);
+ //! copy constructor
+ MatIterator_(const MatIterator_& it);
+ //! copy operator
+ MatIterator_& operator = (const MatIterator_<_Tp>& it );
+
+ //! returns the current matrix element
+ _Tp& operator *() const;
+ //! returns the i-th matrix element, relative to the current
+ _Tp& operator [](ptrdiff_t i) const;
+
+ //! shifts the iterator forward by the specified number of elements
+ MatIterator_& operator += (ptrdiff_t ofs);
+ //! shifts the iterator backward by the specified number of elements
+ MatIterator_& operator -= (ptrdiff_t ofs);
+ //! decrements the iterator
+ MatIterator_& operator --();
+ //! decrements the iterator
+ MatIterator_ operator --(int);
+ //! increments the iterator
+ MatIterator_& operator ++();
+ //! increments the iterator
+ MatIterator_ operator ++(int);
+};
-template<typename _Tp> template<int n> inline const _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx) const
-{
- return Mat::at<_Tp>(idx);
-}
-template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0)
-{
- return this->at<_Tp>(i0);
-}
-template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0) const
-{
- return this->at<_Tp>(i0);
-}
+/////////////////////////////// SparseMatConstIterator ///////////////////////////////
-template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2)
-{
- return this->at<_Tp>(i0, i1, i2);
-}
+/*!
+ Read-Only Sparse Matrix Iterator.
+ Here is how to use the iterator to compute the sum of floating-point sparse matrix elements:
-template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2) const
+ \code
+ SparseMatConstIterator it = m.begin(), it_end = m.end();
+ double s = 0;
+ CV_Assert( m.type() == CV_32F );
+ for( ; it != it_end; ++it )
+ s += it.value<float>();
+ \endcode
+*/
+class CV_EXPORTS SparseMatConstIterator
{
- return this->at<_Tp>(i0, i1, i2);
-}
+public:
+ //! the default constructor
+ SparseMatConstIterator();
+ //! the full constructor setting the iterator to the first sparse matrix element
+ SparseMatConstIterator(const SparseMat* _m);
+ //! the copy constructor
+ SparseMatConstIterator(const SparseMatConstIterator& it);
+
+ //! the assignment operator
+ SparseMatConstIterator& operator = (const SparseMatConstIterator& it);
+
+ //! template method returning the current matrix element
+ template<typename _Tp> const _Tp& value() const;
+ //! returns the current node of the sparse matrix. it.node->idx is the current element index
+ const SparseMat::Node* node() const;
+
+ //! moves iterator to the previous element
+ SparseMatConstIterator& operator --();
+ //! moves iterator to the previous element
+ SparseMatConstIterator operator --(int);
+ //! moves iterator to the next element
+ SparseMatConstIterator& operator ++();
+ //! moves iterator to the next element
+ SparseMatConstIterator operator ++(int);
+
+ //! moves iterator to the element after the last element
+ void seekEnd();
+
+ const SparseMat* m;
+ size_t hashidx;
+ uchar* ptr;
+};
-template<typename _Tp> inline Mat_<_Tp>::operator vector<_Tp>() const
-{
- vector<_Tp> v;
- copyTo(v);
- return v;
-}
-template<typename _Tp> template<int n> inline Mat_<_Tp>::operator Vec<typename DataType<_Tp>::channel_type, n>() const
-{
- CV_Assert(n % DataType<_Tp>::channels == 0);
- return this->Mat::operator Vec<typename DataType<_Tp>::channel_type, n>();
-}
+////////////////////////////////// SparseMatIterator /////////////////////////////////
-template<typename _Tp> template<int m, int n> inline Mat_<_Tp>::operator Matx<typename DataType<_Tp>::channel_type, m, n>() const
-{
- CV_Assert(n % DataType<_Tp>::channels == 0);
- return this->Mat::operator Matx<typename DataType<_Tp>::channel_type, m, n>();
-}
+/*!
+ Read-write Sparse Matrix Iterator
-template<typename T1, typename T2, typename Op> inline void
-process( const Mat_<T1>& m1, Mat_<T2>& m2, Op op )
+ The class is similar to cv::SparseMatConstIterator,
+ but can be used for in-place modification of the matrix elements.
+*/
+class CV_EXPORTS SparseMatIterator : public SparseMatConstIterator
{
- int y, x, rows = m1.rows, cols = m1.cols;
+public:
+ //! the default constructor
+ SparseMatIterator();
+ //! the full constructor setting the iterator to the first sparse matrix element
+ SparseMatIterator(SparseMat* _m);
+ //! the full constructor setting the iterator to the specified sparse matrix element
+ SparseMatIterator(SparseMat* _m, const int* idx);
+ //! the copy constructor
+ SparseMatIterator(const SparseMatIterator& it);
+
+ //! the assignment operator
+ SparseMatIterator& operator = (const SparseMatIterator& it);
+ //! returns read-write reference to the current sparse matrix element
+ template<typename _Tp> _Tp& value() const;
+ //! returns pointer to the current sparse matrix node. it.node->idx is the index of the current element (do not modify it!)
+ SparseMat::Node* node() const;
+
+ //! moves iterator to the next element
+ SparseMatIterator& operator ++();
+ //! moves iterator to the next element
+ SparseMatIterator operator ++(int);
+};
- CV_DbgAssert( m1.size() == m2.size() );
- for( y = 0; y < rows; y++ )
- {
- const T1* src = m1[y];
- T2* dst = m2[y];
- for( x = 0; x < cols; x++ )
- dst[x] = op(src[x]);
- }
-}
+/////////////////////////////// SparseMatConstIterator_ //////////////////////////////
-template<typename T1, typename T2, typename T3, typename Op> inline void
-process( const Mat_<T1>& m1, const Mat_<T2>& m2, Mat_<T3>& m3, Op op )
-{
- int y, x, rows = m1.rows, cols = m1.cols;
+/*!
+ Template Read-Only Sparse Matrix Iterator Class.
- CV_DbgAssert( m1.size() == m2.size() );
+ This is the derived from SparseMatConstIterator class that
+ introduces more convenient operator *() for accessing the current element.
+*/
+template<typename _Tp> class SparseMatConstIterator_ : public SparseMatConstIterator
+{
+public:
- for( y = 0; y < rows; y++ )
- {
- const T1* src1 = m1[y];
- const T2* src2 = m2[y];
- T3* dst = m3[y];
+#ifndef OPENCV_NOSTL
+ typedef std::forward_iterator_tag iterator_category;
+#endif
- for( x = 0; x < cols; x++ )
- dst[x] = op( src1[x], src2[x] );
- }
-}
+ //! the default constructor
+ SparseMatConstIterator_();
+ //! the full constructor setting the iterator to the first sparse matrix element
+ SparseMatConstIterator_(const SparseMat_<_Tp>* _m);
++ SparseMatConstIterator_(const SparseMat* _m);
+ //! the copy constructor
+ SparseMatConstIterator_(const SparseMatConstIterator_& it);
+
+ //! the assignment operator
+ SparseMatConstIterator_& operator = (const SparseMatConstIterator_& it);
+ //! the element access operator
+ const _Tp& operator *() const;
+
+ //! moves iterator to the next element
+ SparseMatConstIterator_& operator ++();
+ //! moves iterator to the next element
+ SparseMatConstIterator_ operator ++(int);
+};
-/////////////////////////////// Input/Output Arrays /////////////////////////////////
-template<typename _Tp> inline _InputArray::_InputArray(const vector<_Tp>& vec)
- : flags(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type), obj((void*)&vec) {}
+///////////////////////////////// SparseMatIterator_ /////////////////////////////////
-template<typename _Tp> inline _InputArray::_InputArray(const vector<vector<_Tp> >& vec)
- : flags(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type), obj((void*)&vec) {}
+/*!
+ Template Read-Write Sparse Matrix Iterator Class.
-template<typename _Tp> inline _InputArray::_InputArray(const vector<Mat_<_Tp> >& vec)
- : flags(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type), obj((void*)&vec) {}
+ This is the derived from cv::SparseMatConstIterator_ class that
+ introduces more convenient operator *() for accessing the current element.
+*/
+template<typename _Tp> class CV_EXPORTS SparseMatIterator_ : public SparseMatConstIterator_<_Tp>
+{
+public:
-template<typename _Tp, int m, int n> inline _InputArray::_InputArray(const Matx<_Tp, m, n>& mtx)
- : flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)&mtx), sz(n, m) {}
+#ifndef OPENCV_NOSTL
+ typedef std::forward_iterator_tag iterator_category;
+#endif
-template<typename _Tp> inline _InputArray::_InputArray(const _Tp* vec, int n)
- : flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)vec), sz(n, 1) {}
+ //! the default constructor
+ SparseMatIterator_();
+ //! the full constructor setting the iterator to the first sparse matrix element
+ SparseMatIterator_(SparseMat_<_Tp>* _m);
++ SparseMatIterator_(SparseMat* _m);
+ //! the copy constructor
+ SparseMatIterator_(const SparseMatIterator_& it);
+
+ //! the assignment operator
+ SparseMatIterator_& operator = (const SparseMatIterator_& it);
+ //! returns the reference to the current element
+ _Tp& operator *() const;
+
+ //! moves the iterator to the next element
+ SparseMatIterator_& operator ++();
+ //! moves the iterator to the next element
+ SparseMatIterator_ operator ++(int);
+};
-inline _InputArray::_InputArray(const Scalar& s)
- : flags(FIXED_TYPE + FIXED_SIZE + MATX + CV_64F), obj((void*)&s), sz(1, 4) {}
-template<typename _Tp> inline _InputArray::_InputArray(const Mat_<_Tp>& m)
- : flags(FIXED_TYPE + MAT + DataType<_Tp>::type), obj((void*)&m) {}
-template<typename _Tp> inline _OutputArray::_OutputArray(vector<_Tp>& vec)
- : _InputArray(vec) {}
-template<typename _Tp> inline _OutputArray::_OutputArray(vector<vector<_Tp> >& vec)
- : _InputArray(vec) {}
-template<typename _Tp> inline _OutputArray::_OutputArray(vector<Mat_<_Tp> >& vec)
- : _InputArray(vec) {}
-template<typename _Tp> inline _OutputArray::_OutputArray(Mat_<_Tp>& m)
- : _InputArray(m) {}
-template<typename _Tp, int m, int n> inline _OutputArray::_OutputArray(Matx<_Tp, m, n>& mtx)
- : _InputArray(mtx) {}
-template<typename _Tp> inline _OutputArray::_OutputArray(_Tp* vec, int n)
- : _InputArray(vec, n) {}
+/////////////////////////////////// NAryMatIterator //////////////////////////////////
+
+/*!
+ n-Dimensional Dense Matrix Iterator Class.
+
+ The class cv::NAryMatIterator is used for iterating over one or more n-dimensional dense arrays (cv::Mat's).
+
+ The iterator is completely different from cv::Mat_ and cv::SparseMat_ iterators.
+ It iterates through the slices (or planes), not the elements, where "slice" is a continuous part of the arrays.
+
+ Here is the example on how the iterator can be used to normalize 3D histogram:
+
+ \code
+ void normalizeColorHist(Mat& hist)
+ {
+ #if 1
+ // intialize iterator (the style is different from STL).
+ // after initialization the iterator will contain
+ // the number of slices or planes
+ // the iterator will go through
+ Mat* arrays[] = { &hist, 0 };
+ Mat planes[1];
+ NAryMatIterator it(arrays, planes);
+ double s = 0;
+ // iterate through the matrix. on each iteration
+ // it.planes[i] (of type Mat) will be set to the current plane of
+ // i-th n-dim matrix passed to the iterator constructor.
+ for(int p = 0; p < it.nplanes; p++, ++it)
+ s += sum(it.planes[0])[0];
+ it = NAryMatIterator(hist);
+ s = 1./s;
+ for(int p = 0; p < it.nplanes; p++, ++it)
+ it.planes[0] *= s;
+ #elif 1
+ // this is a shorter implementation of the above
+ // using built-in operations on Mat
+ double s = sum(hist)[0];
+ hist.convertTo(hist, hist.type(), 1./s, 0);
+ #else
+ // and this is even shorter one
+ // (assuming that the histogram elements are non-negative)
+ normalize(hist, hist, 1, 0, NORM_L1);
+ #endif
+ }
+ \endcode
+
+ You can iterate through several matrices simultaneously as long as they have the same geometry
+ (dimensionality and all the dimension sizes are the same), which is useful for binary
+ and n-ary operations on such matrices. Just pass those matrices to cv::MatNDIterator.
+ Then, during the iteration it.planes[0], it.planes[1], ... will
+ be the slices of the corresponding matrices
+*/
+class CV_EXPORTS NAryMatIterator
+{
+public:
+ //! the default constructor
+ NAryMatIterator();
+ //! the full constructor taking arbitrary number of n-dim matrices
+ NAryMatIterator(const Mat** arrays, uchar** ptrs, int narrays=-1);
+ //! the full constructor taking arbitrary number of n-dim matrices
+ NAryMatIterator(const Mat** arrays, Mat* planes, int narrays=-1);
+ //! the separate iterator initialization method
+ void init(const Mat** arrays, Mat* planes, uchar** ptrs, int narrays=-1);
+
+ //! proceeds to the next plane of every iterated matrix
+ NAryMatIterator& operator ++();
+ //! proceeds to the next plane of every iterated matrix (postfix increment operator)
+ NAryMatIterator operator ++(int);
+
+ //! the iterated arrays
+ const Mat** arrays;
+ //! the current planes
+ Mat* planes;
+ //! data pointers
+ uchar** ptrs;
+ //! the number of arrays
+ int narrays;
+ //! the number of hyper-planes that the iterator steps through
+ size_t nplanes;
+ //! the size of each segment (in elements)
+ size_t size;
+protected:
+ int iterdepth;
+ size_t idx;
+};
-template<typename _Tp> inline _OutputArray::_OutputArray(const vector<_Tp>& vec)
- : _InputArray(vec) {flags |= FIXED_SIZE;}
-template<typename _Tp> inline _OutputArray::_OutputArray(const vector<vector<_Tp> >& vec)
- : _InputArray(vec) {flags |= FIXED_SIZE;}
-template<typename _Tp> inline _OutputArray::_OutputArray(const vector<Mat_<_Tp> >& vec)
- : _InputArray(vec) {flags |= FIXED_SIZE;}
-template<typename _Tp> inline _OutputArray::_OutputArray(const Mat_<_Tp>& m)
- : _InputArray(m) {flags |= FIXED_SIZE;}
-template<typename _Tp, int m, int n> inline _OutputArray::_OutputArray(const Matx<_Tp, m, n>& mtx)
- : _InputArray(mtx) {}
-template<typename _Tp> inline _OutputArray::_OutputArray(const _Tp* vec, int n)
- : _InputArray(vec, n) {}
-//////////////////////////////////// Matrix Expressions /////////////////////////////////////////
+///////////////////////////////// Matrix Expressions /////////////////////////////////
class CV_EXPORTS MatOp
{
--- /dev/null
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_CORE_MATRIX_OPERATIONS_HPP__
+#define __OPENCV_CORE_MATRIX_OPERATIONS_HPP__
+
+#ifndef __cplusplus
+# error mat.inl.hpp header must be compiled as C++
+#endif
+
+namespace cv
+{
+
+//////////////////////// Input/Output Arrays ////////////////////////
+
+template<typename _Tp> inline
+_InputArray::_InputArray(const std::vector<_Tp>& vec)
+ : flags(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type), obj((void*)&vec)
+{}
+
+template<typename _Tp> inline
+_InputArray::_InputArray(const std::vector<std::vector<_Tp> >& vec)
+ : flags(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type), obj((void*)&vec)
+{}
+
+template<typename _Tp> inline
+_InputArray::_InputArray(const std::vector<Mat_<_Tp> >& vec)
+ : flags(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type), obj((void*)&vec)
+{}
+
+template<typename _Tp, int m, int n> inline
+_InputArray::_InputArray(const Matx<_Tp, m, n>& mtx)
+ : flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)&mtx), sz(n, m)
+{}
+
+template<typename _Tp> inline
+_InputArray::_InputArray(const _Tp* vec, int n)
+ : flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)vec), sz(n, 1)
+{}
+
+template<typename _Tp> inline
+_InputArray::_InputArray(const Mat_<_Tp>& m)
+ : flags(FIXED_TYPE + MAT + DataType<_Tp>::type), obj((void*)&m)
+{}
+
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(std::vector<_Tp>& vec)
+ : _InputArray(vec)
+{}
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(std::vector<std::vector<_Tp> >& vec)
+ : _InputArray(vec)
+{}
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(std::vector<Mat_<_Tp> >& vec)
+ : _InputArray(vec)
+{}
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(Mat_<_Tp>& m)
+ : _InputArray(m)
+{}
+
+template<typename _Tp, int m, int n> inline
+_OutputArray::_OutputArray(Matx<_Tp, m, n>& mtx)
+ : _InputArray(mtx)
+{}
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(_Tp* vec, int n)
+ : _InputArray(vec, n)
+{}
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(const std::vector<_Tp>& vec)
+ : _InputArray(vec)
+{
+ flags |= FIXED_SIZE;
+}
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(const std::vector<std::vector<_Tp> >& vec)
+ : _InputArray(vec)
+{
+ flags |= FIXED_SIZE;
+}
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(const std::vector<Mat_<_Tp> >& vec)
+ : _InputArray(vec)
+{
+ flags |= FIXED_SIZE;
+}
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(const Mat_<_Tp>& m)
+ : _InputArray(m)
+{
+ flags |= FIXED_SIZE;
+}
+
+template<typename _Tp, int m, int n> inline
+_OutputArray::_OutputArray(const Matx<_Tp, m, n>& mtx)
+ : _InputArray(mtx)
+{}
+
+template<typename _Tp> inline
+_OutputArray::_OutputArray(const _Tp* vec, int n)
+ : _InputArray(vec, n)
+{}
+
+
+
+//////////////////////////////// Mat ////////////////////////////////
+
+inline
+Mat::Mat()
+ : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), refcount(0), datastart(0), dataend(0),
+ datalimit(0), allocator(0), size(&rows)
+{}
+
+inline
+Mat::Mat(int _rows, int _cols, int _type)
+ : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), refcount(0), datastart(0), dataend(0),
+ datalimit(0), allocator(0), size(&rows)
+{
+ create(_rows, _cols, _type);
+}
+
+inline
+Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
+ : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), refcount(0), datastart(0), dataend(0),
+ datalimit(0), allocator(0), size(&rows)
+{
+ create(_rows, _cols, _type);
+ *this = _s;
+}
+
+inline
+Mat::Mat(Size _sz, int _type)
+ : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), refcount(0), datastart(0), dataend(0),
+ datalimit(0), allocator(0), size(&rows)
+{
+ create( _sz.height, _sz.width, _type );
+}
+
+inline
+Mat::Mat(Size _sz, int _type, const Scalar& _s)
+ : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), refcount(0), datastart(0), dataend(0),
+ datalimit(0), allocator(0), size(&rows)
+{
+ create(_sz.height, _sz.width, _type);
+ *this = _s;
+}
+
+inline
+Mat::Mat(int _dims, const int* _sz, int _type)
+ : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), refcount(0), datastart(0), dataend(0),
+ datalimit(0), allocator(0), size(&rows)
+{
+ create(_dims, _sz, _type);
+}
+
+inline
+Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s)
+ : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), refcount(0), datastart(0), dataend(0),
+ datalimit(0), allocator(0), size(&rows)
+{
+ create(_dims, _sz, _type);
+ *this = _s;
+}
+
+inline
+Mat::Mat(const Mat& m)
+ : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data), refcount(m.refcount),
+ datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit), allocator(m.allocator),
+ size(&rows)
+{
+ if( refcount )
+ CV_XADD(refcount, 1);
+ if( m.dims <= 2 )
+ {
+ step[0] = m.step[0]; step[1] = m.step[1];
+ }
+ else
+ {
+ dims = 0;
+ copySize(m);
+ }
+}
+
+inline
+Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
+ : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_rows), cols(_cols),
+ data((uchar*)_data), refcount(0), datastart((uchar*)_data), dataend(0), datalimit(0),
+ allocator(0), size(&rows)
+{
+ size_t esz = CV_ELEM_SIZE(_type);
+ size_t minstep = cols * esz;
+ if( _step == AUTO_STEP )
+ {
+ _step = minstep;
+ flags |= CONTINUOUS_FLAG;
+ }
+ else
+ {
+ if( rows == 1 ) _step = minstep;
+ CV_DbgAssert( _step >= minstep );
+ flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
+ }
+ step[0] = _step;
+ step[1] = esz;
+ datalimit = datastart + _step * rows;
+ dataend = datalimit - _step + minstep;
+}
+
+inline
+Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
+ : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_sz.height), cols(_sz.width),
+ data((uchar*)_data), refcount(0), datastart((uchar*)_data), dataend(0), datalimit(0),
+ allocator(0), size(&rows)
+{
+ size_t esz = CV_ELEM_SIZE(_type);
+ size_t minstep = cols*esz;
+ if( _step == AUTO_STEP )
+ {
+ _step = minstep;
+ flags |= CONTINUOUS_FLAG;
+ }
+ else
+ {
+ if( rows == 1 ) _step = minstep;
+ CV_DbgAssert( _step >= minstep );
+ flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
+ }
+ step[0] = _step;
+ step[1] = esz;
+ datalimit = datastart + _step*rows;
+ dataend = datalimit - _step + minstep;
+}
+
+template<typename _Tp> inline
+Mat::Mat(const std::vector<_Tp>& vec, bool copyData)
+ : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
+ cols(1), data(0), refcount(0), datastart(0), dataend(0), allocator(0), size(&rows)
+{
+ if(vec.empty())
+ return;
+ if( !copyData )
+ {
+ step[0] = step[1] = sizeof(_Tp);
+ data = datastart = (uchar*)&vec[0];
+ datalimit = dataend = datastart + rows * step[0];
+ }
+ else
+ Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
+}
+
+template<typename _Tp, int n> inline
+Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
+ : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(n), cols(1), data(0),
+ refcount(0), datastart(0), dataend(0), allocator(0), size(&rows)
+{
+ if( !copyData )
+ {
+ step[0] = step[1] = sizeof(_Tp);
+ data = datastart = (uchar*)vec.val;
+ datalimit = dataend = datastart + rows * step[0];
+ }
+ else
+ Mat(n, 1, DataType<_Tp>::type, (void*)vec.val).copyTo(*this);
+}
+
+
+template<typename _Tp, int m, int n> inline
+Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
+ : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(m), cols(n), data(0),
+ refcount(0), datastart(0), dataend(0), allocator(0), size(&rows)
+{
+ if( !copyData )
+ {
+ step[0] = cols * sizeof(_Tp);
+ step[1] = sizeof(_Tp);
+ data = datastart = (uchar*)M.val;
+ datalimit = dataend = datastart + rows * step[0];
+ }
+ else
+ Mat(m, n, DataType<_Tp>::type, (uchar*)M.val).copyTo(*this);
+}
+
+template<typename _Tp> inline
+Mat::Mat(const Point_<_Tp>& pt, bool copyData)
+ : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(2), cols(1), data(0),
+ refcount(0), datastart(0), dataend(0), allocator(0), size(&rows)
+{
+ if( !copyData )
+ {
+ step[0] = step[1] = sizeof(_Tp);
+ data = datastart = (uchar*)&pt.x;
+ datalimit = dataend = datastart + rows * step[0];
+ }
+ else
+ {
+ create(2, 1, DataType<_Tp>::type);
+ ((_Tp*)data)[0] = pt.x;
+ ((_Tp*)data)[1] = pt.y;
+ }
+}
+
+template<typename _Tp> inline
+Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
+ : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(3), cols(1), data(0),
+ refcount(0), datastart(0), dataend(0), allocator(0), size(&rows)
+{
+ if( !copyData )
+ {
+ step[0] = step[1] = sizeof(_Tp);
+ data = datastart = (uchar*)&pt.x;
+ datalimit = dataend = datastart + rows * step[0];
+ }
+ else
+ {
+ create(3, 1, DataType<_Tp>::type);
+ ((_Tp*)data)[0] = pt.x;
+ ((_Tp*)data)[1] = pt.y;
+ ((_Tp*)data)[2] = pt.z;
+ }
+}
+
+template<typename _Tp> inline
+Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer)
+ : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(0), rows(0), cols(0), data(0),
+ refcount(0), datastart(0), dataend(0), allocator(0), size(&rows)
+{
+ *this = commaInitializer.operator Mat_<_Tp>();
+}
+
+inline
+Mat::~Mat()
+{
+ release();
+ if( step.p != step.buf )
+ fastFree(step.p);
+}
+
+inline
+Mat& Mat::operator = (const Mat& m)
+{
+ if( this != &m )
+ {
+ if( m.refcount )
+ CV_XADD(m.refcount, 1);
+ release();
+ flags = m.flags;
+ if( dims <= 2 && m.dims <= 2 )
+ {
+ dims = m.dims;
+ rows = m.rows;
+ cols = m.cols;
+ step[0] = m.step[0];
+ step[1] = m.step[1];
+ }
+ else
+ copySize(m);
+ data = m.data;
+ datastart = m.datastart;
+ dataend = m.dataend;
+ datalimit = m.datalimit;
+ refcount = m.refcount;
+ allocator = m.allocator;
+ }
+ return *this;
+}
+
+inline
+Mat Mat::row(int y) const
+{
+ return Mat(*this, Range(y, y + 1), Range::all());
+}
+
+inline
+Mat Mat::col(int x) const
+{
+ return Mat(*this, Range::all(), Range(x, x + 1));
+}
+
+inline
+Mat Mat::rowRange(int startrow, int endrow) const
+{
+ return Mat(*this, Range(startrow, endrow), Range::all());
+}
+
+inline
+Mat Mat::rowRange(const Range& r) const
+{
+ return Mat(*this, r, Range::all());
+}
+
+inline
+Mat Mat::colRange(int startcol, int endcol) const
+{
+ return Mat(*this, Range::all(), Range(startcol, endcol));
+}
+
+inline
+Mat Mat::colRange(const Range& r) const
+{
+ return Mat(*this, Range::all(), r);
+}
+
+inline
+Mat Mat::clone() const
+{
+ Mat m;
+ copyTo(m);
+ return m;
+}
+
+inline
+void Mat::assignTo( Mat& m, int _type ) const
+{
+ if( _type < 0 )
+ m = *this;
+ else
+ convertTo(m, _type);
+}
+
+inline
+void Mat::create(int _rows, int _cols, int _type)
+{
+ _type &= TYPE_MASK;
+ if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data )
+ return;
+ int sz[] = {_rows, _cols};
+ create(2, sz, _type);
+}
+
+inline
+void Mat::create(Size _sz, int _type)
+{
+ create(_sz.height, _sz.width, _type);
+}
+
+inline
+void Mat::addref()
+{
+ if( refcount )
+ CV_XADD(refcount, 1);
+}
+
+inline void Mat::release()
+{
+ if( refcount && CV_XADD(refcount, -1) == 1 )
+ deallocate();
+ data = datastart = dataend = datalimit = 0;
+ size.p[0] = 0;
+ refcount = 0;
+}
+
+inline
+Mat Mat::operator()( Range _rowRange, Range _colRange ) const
+{
+ return Mat(*this, _rowRange, _colRange);
+}
+
+inline
+Mat Mat::operator()( const Rect& roi ) const
+{
+ return Mat(*this, roi);
+}
+
+inline
+Mat Mat::operator()(const Range* ranges) const
+{
+ return Mat(*this, ranges);
+}
+
+inline
+bool Mat::isContinuous() const
+{
+ return (flags & CONTINUOUS_FLAG) != 0;
+}
+
+inline
+bool Mat::isSubmatrix() const
+{
+ return (flags & SUBMATRIX_FLAG) != 0;
+}
+
+inline
+size_t Mat::elemSize() const
+{
+ return dims > 0 ? step.p[dims - 1] : 0;
+}
+
+inline
+size_t Mat::elemSize1() const
+{
+ return CV_ELEM_SIZE1(flags);
+}
+
+inline
+int Mat::type() const
+{
+ return CV_MAT_TYPE(flags);
+}
+
+inline
+int Mat::depth() const
+{
+ return CV_MAT_DEPTH(flags);
+}
+
+inline
+int Mat::channels() const
+{
+ return CV_MAT_CN(flags);
+}
+
+inline
+size_t Mat::step1(int i) const
+{
+ return step.p[i] / elemSize1();
+}
+
+inline
+bool Mat::empty() const
+{
+ return data == 0 || total() == 0;
+}
+
+inline
+size_t Mat::total() const
+{
+ if( dims <= 2 )
+ return (size_t)rows * cols;
+ size_t p = 1;
+ for( int i = 0; i < dims; i++ )
+ p *= size[i];
+ return p;
+}
+
+inline
+uchar* Mat::ptr(int y)
+{
+ CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
+ return data + step.p[0] * y;
+}
+
+inline
+const uchar* Mat::ptr(int y) const
+{
+ CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
+ return data + step.p[0] * y;
+}
+
+template<typename _Tp> inline
+_Tp* Mat::ptr(int y)
+{
+ CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
+ return (_Tp*)(data + step.p[0] * y);
+}
+
+template<typename _Tp> inline
+const _Tp* Mat::ptr(int y) const
+{
+ CV_DbgAssert( y == 0 || (data && dims >= 1 && data && (unsigned)y < (unsigned)size.p[0]) );
+ return (const _Tp*)(data + step.p[0] * y);
+}
+
+inline
+uchar* Mat::ptr(int i0, int i1)
+{
+ CV_DbgAssert( dims >= 2 && data &&
+ (unsigned)i0 < (unsigned)size.p[0] &&
+ (unsigned)i1 < (unsigned)size.p[1] );
+ return data + i0 * step.p[0] + i1 * step.p[1];
+}
+
+inline
+const uchar* Mat::ptr(int i0, int i1) const
+{
+ CV_DbgAssert( dims >= 2 && data &&
+ (unsigned)i0 < (unsigned)size.p[0] &&
+ (unsigned)i1 < (unsigned)size.p[1] );
+ return data + i0 * step.p[0] + i1 * step.p[1];
+}
+
+template<typename _Tp> inline
+_Tp* Mat::ptr(int i0, int i1)
+{
+ CV_DbgAssert( dims >= 2 && data &&
+ (unsigned)i0 < (unsigned)size.p[0] &&
+ (unsigned)i1 < (unsigned)size.p[1] );
+ return (_Tp*)(data + i0 * step.p[0] + i1 * step.p[1]);
+}
+
+template<typename _Tp> inline
+const _Tp* Mat::ptr(int i0, int i1) const
+{
+ CV_DbgAssert( dims >= 2 && data &&
+ (unsigned)i0 < (unsigned)size.p[0] &&
+ (unsigned)i1 < (unsigned)size.p[1] );
+ return (const _Tp*)(data + i0 * step.p[0] + i1 * step.p[1]);
+}
+
+inline
+uchar* Mat::ptr(int i0, int i1, int i2)
+{
+ CV_DbgAssert( dims >= 3 && data &&
+ (unsigned)i0 < (unsigned)size.p[0] &&
+ (unsigned)i1 < (unsigned)size.p[1] &&
+ (unsigned)i2 < (unsigned)size.p[2] );
+ return data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2];
+}
+
+inline
+const uchar* Mat::ptr(int i0, int i1, int i2) const
+{
+ CV_DbgAssert( dims >= 3 && data &&
+ (unsigned)i0 < (unsigned)size.p[0] &&
+ (unsigned)i1 < (unsigned)size.p[1] &&
+ (unsigned)i2 < (unsigned)size.p[2] );
+ return data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2];
+}
+
+template<typename _Tp> inline
+_Tp* Mat::ptr(int i0, int i1, int i2)
+{
+ CV_DbgAssert( dims >= 3 && data &&
+ (unsigned)i0 < (unsigned)size.p[0] &&
+ (unsigned)i1 < (unsigned)size.p[1] &&
+ (unsigned)i2 < (unsigned)size.p[2] );
+ return (_Tp*)(data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2]);
+}
+
+template<typename _Tp> inline
+const _Tp* Mat::ptr(int i0, int i1, int i2) const
+{
+ CV_DbgAssert( dims >= 3 && data &&
+ (unsigned)i0 < (unsigned)size.p[0] &&
+ (unsigned)i1 < (unsigned)size.p[1] &&
+ (unsigned)i2 < (unsigned)size.p[2] );
+ return (const _Tp*)(data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2]);
+}
+
+inline
+uchar* Mat::ptr(const int* idx)
+{
+ int i, d = dims;
+ uchar* p = data;
+ CV_DbgAssert( d >= 1 && p );
+ for( i = 0; i < d; i++ )
+ {
+ CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
+ p += idx[i] * step.p[i];
+ }
+ return p;
+}
+
+inline
+const uchar* Mat::ptr(const int* idx) const
+{
+ int i, d = dims;
+ uchar* p = data;
+ CV_DbgAssert( d >= 1 && p );
+ for( i = 0; i < d; i++ )
+ {
+ CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
+ p += idx[i] * step.p[i];
+ }
+ return p;
+}
+
+template<typename _Tp> inline
+_Tp& Mat::at(int i0, int i1)
+{
+ CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
+ (unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()) &&
+ CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
+ return ((_Tp*)(data + step.p[0] * i0))[i1];
+}
+
+template<typename _Tp> inline
+const _Tp& Mat::at(int i0, int i1) const
+{
+ CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
+ (unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()) &&
+ CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
+ return ((const _Tp*)(data + step.p[0] * i0))[i1];
+}
+
+template<typename _Tp> inline
+_Tp& Mat::at(Point pt)
+{
+ CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
+ (unsigned)(pt.x * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()) &&
+ CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
+ return ((_Tp*)(data + step.p[0] * pt.y))[pt.x];
+}
+
+template<typename _Tp> inline
+const _Tp& Mat::at(Point pt) const
+{
+ CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
+ (unsigned)(pt.x * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()) &&
+ CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
+ return ((const _Tp*)(data + step.p[0] * pt.y))[pt.x];
+}
+
+template<typename _Tp> inline
+_Tp& Mat::at(int i0)
+{
+ CV_DbgAssert( dims <= 2 && data &&
+ (unsigned)i0 < (unsigned)(size.p[0] * size.p[1]) &&
+ elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
+ if( isContinuous() || size.p[0] == 1 )
+ return ((_Tp*)data)[i0];
+ if( size.p[1] == 1 )
+ return *(_Tp*)(data + step.p[0] * i0);
+ int i = i0 / cols, j = i0 - i * cols;
+ return ((_Tp*)(data + step.p[0] * i))[j];
+}
+
+template<typename _Tp> inline
+const _Tp& Mat::at(int i0) const
+{
+ CV_DbgAssert( dims <= 2 && data &&
+ (unsigned)i0 < (unsigned)(size.p[0] * size.p[1]) &&
+ elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
+ if( isContinuous() || size.p[0] == 1 )
+ return ((const _Tp*)data)[i0];
+ if( size.p[1] == 1 )
+ return *(const _Tp*)(data + step.p[0] * i0);
+ int i = i0 / cols, j = i0 - i * cols;
+ return ((const _Tp*)(data + step.p[0] * i))[j];
+}
+
+template<typename _Tp> inline
+_Tp& Mat::at(int i0, int i1, int i2)
+{
+ CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
+ return *(_Tp*)ptr(i0, i1, i2);
+}
+
+template<typename _Tp> inline
+const _Tp& Mat::at(int i0, int i1, int i2) const
+{
+ CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
+ return *(const _Tp*)ptr(i0, i1, i2);
+}
+
+template<typename _Tp> inline
+_Tp& Mat::at(const int* idx)
+{
+ CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
+ return *(_Tp*)ptr(idx);
+}
+
+template<typename _Tp> inline
+const _Tp& Mat::at(const int* idx) const
+{
+ CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
+ return *(const _Tp*)ptr(idx);
+}
+
+template<typename _Tp, int n> inline
+_Tp& Mat::at(const Vec<int, n>& idx)
+{
+ CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
+ return *(_Tp*)ptr(idx.val);
+}
+
+template<typename _Tp, int n> inline
+const _Tp& Mat::at(const Vec<int, n>& idx) const
+{
+ CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
+ return *(const _Tp*)ptr(idx.val);
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp> Mat::begin() const
+{
+ CV_DbgAssert( elemSize() == sizeof(_Tp) );
+ return MatConstIterator_<_Tp>((const Mat_<_Tp>*)this);
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp> Mat::end() const
+{
+ CV_DbgAssert( elemSize() == sizeof(_Tp) );
+ MatConstIterator_<_Tp> it((const Mat_<_Tp>*)this);
+ it += total();
+ return it;
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp> Mat::begin()
+{
+ CV_DbgAssert( elemSize() == sizeof(_Tp) );
+ return MatIterator_<_Tp>((Mat_<_Tp>*)this);
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp> Mat::end()
+{
+ CV_DbgAssert( elemSize() == sizeof(_Tp) );
+ MatIterator_<_Tp> it((Mat_<_Tp>*)this);
+ it += total();
+ return it;
+}
+
+template<typename _Tp> inline
+Mat::operator std::vector<_Tp>() const
+{
+ std::vector<_Tp> v;
+ copyTo(v);
+ return v;
+}
+
+template<typename _Tp, int n> inline
+Mat::operator Vec<_Tp, n>() const
+{
+ CV_Assert( data && dims <= 2 && (rows == 1 || cols == 1) &&
+ rows + cols - 1 == n && channels() == 1 );
+
+ if( isContinuous() && type() == DataType<_Tp>::type )
+ return Vec<_Tp, n>((_Tp*)data);
+ Vec<_Tp, n> v;
+ Mat tmp(rows, cols, DataType<_Tp>::type, v.val);
+ convertTo(tmp, tmp.type());
+ return v;
+}
+
+template<typename _Tp, int m, int n> inline
+Mat::operator Matx<_Tp, m, n>() const
+{
+ CV_Assert( data && dims <= 2 && rows == m && cols == n && channels() == 1 );
+
+ if( isContinuous() && type() == DataType<_Tp>::type )
+ return Matx<_Tp, m, n>((_Tp*)data);
+ Matx<_Tp, m, n> mtx;
+ Mat tmp(rows, cols, DataType<_Tp>::type, mtx.val);
+ convertTo(tmp, tmp.type());
+ return mtx;
+}
+
+template<typename _Tp> inline
+void Mat::push_back(const _Tp& elem)
+{
+ if( !data )
+ {
+ *this = Mat(1, 1, DataType<_Tp>::type, (void*)&elem).clone();
+ return;
+ }
+ CV_Assert(DataType<_Tp>::type == type() && cols == 1
+ /* && dims == 2 (cols == 1 implies dims == 2) */);
+ uchar* tmp = dataend + step[0];
+ if( !isSubmatrix() && isContinuous() && tmp <= datalimit )
+ {
+ *(_Tp*)(data + (size.p[0]++) * step.p[0]) = elem;
+ dataend = tmp;
+ }
+ else
+ push_back_(&elem);
+}
+
+template<typename _Tp> inline
+void Mat::push_back(const Mat_<_Tp>& m)
+{
+ push_back((const Mat&)m);
+}
+
+
+
+///////////////////////////// Mat::MSize ////////////////////////////
+
+inline
+Mat::MSize::MSize(int* _p)
+ : p(_p) {}
+
+inline
+Size Mat::MSize::operator()() const
+{
+ CV_DbgAssert(p[-1] <= 2);
+ return Size(p[1], p[0]);
+}
+
+inline
+const int& Mat::MSize::operator[](int i) const
+{
+ return p[i];
+}
+
+inline
+int& Mat::MSize::operator[](int i)
+{
+ return p[i];
+}
+
+inline
+Mat::MSize::operator const int*() const
+{
+ return p;
+}
+
+inline
+bool Mat::MSize::operator == (const MSize& sz) const
+{
+ int d = p[-1];
+ int dsz = sz.p[-1];
+ if( d != dsz )
+ return false;
+ if( d == 2 )
+ return p[0] == sz.p[0] && p[1] == sz.p[1];
+
+ for( int i = 0; i < d; i++ )
+ if( p[i] != sz.p[i] )
+ return false;
+ return true;
+}
+
+inline
+bool Mat::MSize::operator != (const MSize& sz) const
+{
+ return !(*this == sz);
+}
+
+
+
+///////////////////////////// Mat::MStep ////////////////////////////
+
+inline
+Mat::MStep::MStep()
+{
+ p = buf; p[0] = p[1] = 0;
+}
+
+inline
+Mat::MStep::MStep(size_t s)
+{
+ p = buf; p[0] = s; p[1] = 0;
+}
+
+inline
+const size_t& Mat::MStep::operator[](int i) const
+{
+ return p[i];
+}
+
+inline
+size_t& Mat::MStep::operator[](int i)
+{
+ return p[i];
+}
+
+inline Mat::MStep::operator size_t() const
+{
+ CV_DbgAssert( p == buf );
+ return buf[0];
+}
+
+inline Mat::MStep& Mat::MStep::operator = (size_t s)
+{
+ CV_DbgAssert( p == buf );
+ buf[0] = s;
+ return *this;
+}
+
+
+
+////////////////////////////// Mat_<_Tp> ////////////////////////////
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_()
+ : Mat()
+{
+ flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(int _rows, int _cols)
+ : Mat(_rows, _cols, DataType<_Tp>::type)
+{
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value)
+ : Mat(_rows, _cols, DataType<_Tp>::type)
+{
+ *this = value;
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(Size _sz)
+ : Mat(_sz.height, _sz.width, DataType<_Tp>::type)
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(Size _sz, const _Tp& value)
+ : Mat(_sz.height, _sz.width, DataType<_Tp>::type)
+{
+ *this = value;
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(int _dims, const int* _sz)
+ : Mat(_dims, _sz, DataType<_Tp>::type)
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(int _dims, const int* _sz, const _Tp& _s)
+ : Mat(_dims, _sz, DataType<_Tp>::type, Scalar(_s))
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const Range* ranges)
+ : Mat(m, ranges)
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const Mat& m)
+ : Mat()
+{
+ flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
+ *this = m;
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const Mat_& m)
+ : Mat(m)
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t steps)
+ : Mat(_rows, _cols, DataType<_Tp>::type, _data, steps)
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const Mat_& m, const Range& _rowRange, const Range& _colRange)
+ : Mat(m, _rowRange, _colRange)
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
+ : Mat(m, roi)
+{}
+
+template<typename _Tp> template<int n> inline
+Mat_<_Tp>::Mat_(const Vec<typename DataType<_Tp>::channel_type, n>& vec, bool copyData)
+ : Mat(n / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&vec)
+{
+ CV_Assert(n%DataType<_Tp>::channels == 0);
+ if( copyData )
+ *this = clone();
+}
+
+template<typename _Tp> template<int m, int n> inline
+Mat_<_Tp>::Mat_(const Matx<typename DataType<_Tp>::channel_type, m, n>& M, bool copyData)
+ : Mat(m, n / DataType<_Tp>::channels, DataType<_Tp>::type, (void*)&M)
+{
+ CV_Assert(n % DataType<_Tp>::channels == 0);
+ if( copyData )
+ *this = clone();
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
+ : Mat(2 / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
+{
+ CV_Assert(2 % DataType<_Tp>::channels == 0);
+ if( copyData )
+ *this = clone();
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
+ : Mat(3 / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
+{
+ CV_Assert(3 % DataType<_Tp>::channels == 0);
+ if( copyData )
+ *this = clone();
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const MatCommaInitializer_<_Tp>& commaInitializer)
+ : Mat(commaInitializer)
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const std::vector<_Tp>& vec, bool copyData)
+ : Mat(vec, copyData)
+{}
+
+template<typename _Tp> inline
+Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m)
+{
+ if( DataType<_Tp>::type == m.type() )
+ {
+ Mat::operator = (m);
+ return *this;
+ }
+ if( DataType<_Tp>::depth == m.depth() )
+ {
+ return (*this = m.reshape(DataType<_Tp>::channels, m.dims, 0));
+ }
+ CV_DbgAssert(DataType<_Tp>::channels == m.channels());
+ m.convertTo(*this, type());
+ return *this;
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat_& m)
+{
+ Mat::operator=(m);
+ return *this;
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>& Mat_<_Tp>::operator = (const _Tp& s)
+{
+ typedef typename DataType<_Tp>::vec_type VT;
+ Mat::operator=(Scalar((const VT&)s));
+ return *this;
+}
+
+template<typename _Tp> inline
+void Mat_<_Tp>::create(int _rows, int _cols)
+{
+ Mat::create(_rows, _cols, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+void Mat_<_Tp>::create(Size _sz)
+{
+ Mat::create(_sz, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+void Mat_<_Tp>::create(int _dims, const int* _sz)
+{
+ Mat::create(_dims, _sz, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const
+{
+ return Mat_<_Tp>(Mat::cross(m));
+}
+
+template<typename _Tp> template<typename T2> inline
+Mat_<_Tp>::operator Mat_<T2>() const
+{
+ return Mat_<T2>(*this);
+}
+
+template<typename _Tp> inline
+Mat_<_Tp> Mat_<_Tp>::row(int y) const
+{
+ return Mat_(*this, Range(y, y+1), Range::all());
+}
+
+template<typename _Tp> inline
+Mat_<_Tp> Mat_<_Tp>::col(int x) const
+{
+ return Mat_(*this, Range::all(), Range(x, x+1));
+}
+
+template<typename _Tp> inline
+Mat_<_Tp> Mat_<_Tp>::diag(int d) const
+{
+ return Mat_(Mat::diag(d));
+}
+
+template<typename _Tp> inline
+Mat_<_Tp> Mat_<_Tp>::clone() const
+{
+ return Mat_(Mat::clone());
+}
+
+template<typename _Tp> inline
+size_t Mat_<_Tp>::elemSize() const
+{
+ CV_DbgAssert( Mat::elemSize() == sizeof(_Tp) );
+ return sizeof(_Tp);
+}
+
+template<typename _Tp> inline
+size_t Mat_<_Tp>::elemSize1() const
+{
+ CV_DbgAssert( Mat::elemSize1() == sizeof(_Tp) / DataType<_Tp>::channels );
+ return sizeof(_Tp) / DataType<_Tp>::channels;
+}
+
+template<typename _Tp> inline
+int Mat_<_Tp>::type() const
+{
+ CV_DbgAssert( Mat::type() == DataType<_Tp>::type );
+ return DataType<_Tp>::type;
+}
+
+template<typename _Tp> inline
+int Mat_<_Tp>::depth() const
+{
+ CV_DbgAssert( Mat::depth() == DataType<_Tp>::depth );
+ return DataType<_Tp>::depth;
+}
+
+template<typename _Tp> inline
+int Mat_<_Tp>::channels() const
+{
+ CV_DbgAssert( Mat::channels() == DataType<_Tp>::channels );
+ return DataType<_Tp>::channels;
+}
+
+template<typename _Tp> inline
+size_t Mat_<_Tp>::stepT(int i) const
+{
+ return step.p[i] / elemSize();
+}
+
+template<typename _Tp> inline
+size_t Mat_<_Tp>::step1(int i) const
+{
+ return step.p[i] / elemSize1();
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>& Mat_<_Tp>::adjustROI( int dtop, int dbottom, int dleft, int dright )
+{
+ return (Mat_<_Tp>&)(Mat::adjustROI(dtop, dbottom, dleft, dright));
+}
+
+template<typename _Tp> inline
+Mat_<_Tp> Mat_<_Tp>::operator()( const Range& _rowRange, const Range& _colRange ) const
+{
+ return Mat_<_Tp>(*this, _rowRange, _colRange);
+}
+
+template<typename _Tp> inline
+Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const
+{
+ return Mat_<_Tp>(*this, roi);
+}
+
+template<typename _Tp> inline
+Mat_<_Tp> Mat_<_Tp>::operator()( const Range* ranges ) const
+{
+ return Mat_<_Tp>(*this, ranges);
+}
+
+template<typename _Tp> inline
+_Tp* Mat_<_Tp>::operator [](int y)
+{
+ return (_Tp*)ptr(y);
+}
+
+template<typename _Tp> inline
+const _Tp* Mat_<_Tp>::operator [](int y) const
+{
+ return (const _Tp*)ptr(y);
+}
+
+template<typename _Tp> inline
+_Tp& Mat_<_Tp>::operator ()(int i0, int i1)
+{
+ CV_DbgAssert( dims <= 2 && data &&
+ (unsigned)i0 < (unsigned)size.p[0] &&
+ (unsigned)i1 < (unsigned)size.p[1] &&
+ type() == DataType<_Tp>::type );
+ return ((_Tp*)(data + step.p[0] * i0))[i1];
+}
+
+template<typename _Tp> inline
+const _Tp& Mat_<_Tp>::operator ()(int i0, int i1) const
+{
+ CV_DbgAssert( dims <= 2 && data &&
+ (unsigned)i0 < (unsigned)size.p[0] &&
+ (unsigned)i1 < (unsigned)size.p[1] &&
+ type() == DataType<_Tp>::type );
+ return ((const _Tp*)(data + step.p[0] * i0))[i1];
+}
+
+template<typename _Tp> inline
+_Tp& Mat_<_Tp>::operator ()(Point pt)
+{
+ CV_DbgAssert( dims <= 2 && data &&
+ (unsigned)pt.y < (unsigned)size.p[0] &&
+ (unsigned)pt.x < (unsigned)size.p[1] &&
+ type() == DataType<_Tp>::type );
+ return ((_Tp*)(data + step.p[0] * pt.y))[pt.x];
+}
+
+template<typename _Tp> inline
+const _Tp& Mat_<_Tp>::operator ()(Point pt) const
+{
+ CV_DbgAssert( dims <= 2 && data &&
+ (unsigned)pt.y < (unsigned)size.p[0] &&
+ (unsigned)pt.x < (unsigned)size.p[1] &&
+ type() == DataType<_Tp>::type );
+ return ((const _Tp*)(data + step.p[0] * pt.y))[pt.x];
+}
+
+template<typename _Tp> inline
+_Tp& Mat_<_Tp>::operator ()(const int* idx)
+{
+ return Mat::at<_Tp>(idx);
+}
+
+template<typename _Tp> inline
+const _Tp& Mat_<_Tp>::operator ()(const int* idx) const
+{
+ return Mat::at<_Tp>(idx);
+}
+
+template<typename _Tp> template<int n> inline
+_Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx)
+{
+ return Mat::at<_Tp>(idx);
+}
+
+template<typename _Tp> template<int n> inline
+const _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx) const
+{
+ return Mat::at<_Tp>(idx);
+}
+
+template<typename _Tp> inline
+_Tp& Mat_<_Tp>::operator ()(int i0)
+{
+ return this->at<_Tp>(i0);
+}
+
+template<typename _Tp> inline
+const _Tp& Mat_<_Tp>::operator ()(int i0) const
+{
+ return this->at<_Tp>(i0);
+}
+
+template<typename _Tp> inline
+_Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2)
+{
+ return this->at<_Tp>(i0, i1, i2);
+}
+
+template<typename _Tp> inline
+const _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2) const
+{
+ return this->at<_Tp>(i0, i1, i2);
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::operator std::vector<_Tp>() const
+{
+ std::vector<_Tp> v;
+ copyTo(v);
+ return v;
+}
+
+template<typename _Tp> template<int n> inline
+Mat_<_Tp>::operator Vec<typename DataType<_Tp>::channel_type, n>() const
+{
+ CV_Assert(n % DataType<_Tp>::channels == 0);
+ return this->Mat::operator Vec<typename DataType<_Tp>::channel_type, n>();
+}
+
+template<typename _Tp> template<int m, int n> inline
+Mat_<_Tp>::operator Matx<typename DataType<_Tp>::channel_type, m, n>() const
+{
+ CV_Assert(n % DataType<_Tp>::channels == 0);
+ return this->Mat::operator Matx<typename DataType<_Tp>::channel_type, m, n>();
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp> Mat_<_Tp>::begin() const
+{
+ return Mat::begin<_Tp>();
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp> Mat_<_Tp>::end() const
+{
+ return Mat::end<_Tp>();
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp> Mat_<_Tp>::begin()
+{
+ return Mat::begin<_Tp>();
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp> Mat_<_Tp>::end()
+{
+ return Mat::end<_Tp>();
+}
+
+
+/*template<typename T1, typename T2, typename Op> inline
+void process( const Mat_<T1>& m1, Mat_<T2>& m2, Op op )
+{
+ int y, x, rows = m1.rows, cols = m1.cols;
+
+ CV_DbgAssert( m1.size() == m2.size() );
+
+ for( y = 0; y < rows; y++ )
+ {
+ const T1* src = m1[y];
+ T2* dst = m2[y];
+
+ for( x = 0; x < cols; x++ )
+ dst[x] = op(src[x]);
+ }
+}
+
+template<typename T1, typename T2, typename T3, typename Op> inline
+void process( const Mat_<T1>& m1, const Mat_<T2>& m2, Mat_<T3>& m3, Op op )
+{
+ int y, x, rows = m1.rows, cols = m1.cols;
+
+ CV_DbgAssert( m1.size() == m2.size() );
+
+ for( y = 0; y < rows; y++ )
+ {
+ const T1* src1 = m1[y];
+ const T2* src2 = m2[y];
+ T3* dst = m3[y];
+
+ for( x = 0; x < cols; x++ )
+ dst[x] = op( src1[x], src2[x] );
+ }
+}*/
+
+
+
+///////////////////////////// SparseMat /////////////////////////////
+
+inline
+SparseMat::SparseMat()
+ : flags(MAGIC_VAL), hdr(0)
+{}
+
+inline
+SparseMat::SparseMat(int _dims, const int* _sizes, int _type)
+ : flags(MAGIC_VAL), hdr(0)
+{
+ create(_dims, _sizes, _type);
+}
+
+inline
+SparseMat::SparseMat(const SparseMat& m)
+ : flags(m.flags), hdr(m.hdr)
+{
+ addref();
+}
+
+inline
+SparseMat::~SparseMat()
+{
+ release();
+}
+
+inline
+SparseMat& SparseMat::operator = (const SparseMat& m)
+{
+ if( this != &m )
+ {
+ if( m.hdr )
+ CV_XADD(&m.hdr->refcount, 1);
+ release();
+ flags = m.flags;
+ hdr = m.hdr;
+ }
+ return *this;
+}
+
+inline
+SparseMat& SparseMat::operator = (const Mat& m)
+{
+ return (*this = SparseMat(m));
+}
+
+inline
+SparseMat SparseMat::clone() const
+{
+ SparseMat temp;
+ this->copyTo(temp);
+ return temp;
+}
+
+inline
+void SparseMat::assignTo( SparseMat& m, int _type ) const
+{
+ if( _type < 0 )
+ m = *this;
+ else
+ convertTo(m, _type);
+}
+
+inline
+void SparseMat::addref()
+{
+ if( hdr )
+ CV_XADD(&hdr->refcount, 1);
+}
+
+inline
+void SparseMat::release()
+{
+ if( hdr && CV_XADD(&hdr->refcount, -1) == 1 )
+ delete hdr;
+ hdr = 0;
+}
+
+inline
+size_t SparseMat::elemSize() const
+{
+ return CV_ELEM_SIZE(flags);
+}
+
+inline
+size_t SparseMat::elemSize1() const
+{
+ return CV_ELEM_SIZE1(flags);
+}
+
+inline
+int SparseMat::type() const
+{
+ return CV_MAT_TYPE(flags);
+}
+
+inline
+int SparseMat::depth() const
+{
+ return CV_MAT_DEPTH(flags);
+}
+
+inline
+int SparseMat::channels() const
+{
+ return CV_MAT_CN(flags);
+}
+
+inline
+const int* SparseMat::size() const
+{
+ return hdr ? hdr->size : 0;
+}
+
+inline
+int SparseMat::size(int i) const
+{
+ if( hdr )
+ {
+ CV_DbgAssert((unsigned)i < (unsigned)hdr->dims);
+ return hdr->size[i];
+ }
+ return 0;
+}
+
+inline
+int SparseMat::dims() const
+{
+ return hdr ? hdr->dims : 0;
+}
+
+inline
+size_t SparseMat::nzcount() const
+{
+ return hdr ? hdr->nodeCount : 0;
+}
+
+inline
+size_t SparseMat::hash(int i0) const
+{
+ return (size_t)i0;
+}
+
+inline
+size_t SparseMat::hash(int i0, int i1) const
+{
+ return (size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1;
+}
+
+inline
+size_t SparseMat::hash(int i0, int i1, int i2) const
+{
+ return ((size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1) * HASH_SCALE + (unsigned)i2;
+}
+
+inline
+size_t SparseMat::hash(const int* idx) const
+{
+ size_t h = (unsigned)idx[0];
+ if( !hdr )
+ return 0;
+ int d = hdr->dims;
+ for(int i = 1; i < d; i++ )
+ h = h * HASH_SCALE + (unsigned)idx[i];
+ return h;
+}
+
+template<typename _Tp> inline
+_Tp& SparseMat::ref(int i0, size_t* hashval)
+{
+ return *(_Tp*)((SparseMat*)this)->ptr(i0, true, hashval);
+}
+
+template<typename _Tp> inline
+_Tp& SparseMat::ref(int i0, int i1, size_t* hashval)
+{
+ return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, true, hashval);
+}
+
+template<typename _Tp> inline
+_Tp& SparseMat::ref(int i0, int i1, int i2, size_t* hashval)
+{
+ return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, i2, true, hashval);
+}
+
+template<typename _Tp> inline
+_Tp& SparseMat::ref(const int* idx, size_t* hashval)
+{
+ return *(_Tp*)((SparseMat*)this)->ptr(idx, true, hashval);
+}
+
+template<typename _Tp> inline
+_Tp SparseMat::value(int i0, size_t* hashval) const
+{
+ const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
+ return p ? *p : _Tp();
+}
+
+template<typename _Tp> inline
+_Tp SparseMat::value(int i0, int i1, size_t* hashval) const
+{
+ const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
+ return p ? *p : _Tp();
+}
+
+template<typename _Tp> inline
+_Tp SparseMat::value(int i0, int i1, int i2, size_t* hashval) const
+{
+ const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval);
+ return p ? *p : _Tp();
+}
+
+template<typename _Tp> inline
+_Tp SparseMat::value(const int* idx, size_t* hashval) const
+{
+ const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval);
+ return p ? *p : _Tp();
+}
+
+template<typename _Tp> inline
+const _Tp* SparseMat::find(int i0, size_t* hashval) const
+{
+ return (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
+}
+
+template<typename _Tp> inline
+const _Tp* SparseMat::find(int i0, int i1, size_t* hashval) const
+{
+ return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
+}
+
+template<typename _Tp> inline
+const _Tp* SparseMat::find(int i0, int i1, int i2, size_t* hashval) const
+{
+ return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval);
+}
+
+template<typename _Tp> inline
+const _Tp* SparseMat::find(const int* idx, size_t* hashval) const
+{
+ return (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval);
+}
+
+template<typename _Tp> inline
+_Tp& SparseMat::value(Node* n)
+{
+ return *(_Tp*)((uchar*)n + hdr->valueOffset);
+}
+
+template<typename _Tp> inline
+const _Tp& SparseMat::value(const Node* n) const
+{
+ return *(const _Tp*)((const uchar*)n + hdr->valueOffset);
+}
+
+inline
+SparseMat::Node* SparseMat::node(size_t nidx)
+{
+ return (Node*)&hdr->pool[nidx];
+}
+
+inline
+const SparseMat::Node* SparseMat::node(size_t nidx) const
+{
+ return (const Node*)&hdr->pool[nidx];
+}
+
+inline
+SparseMatIterator SparseMat::begin()
+{
+ return SparseMatIterator(this);
+}
+
+inline
+SparseMatConstIterator SparseMat::begin() const
+{
+ return SparseMatConstIterator(this);
+}
+
+inline
+SparseMatIterator SparseMat::end()
+{
+ SparseMatIterator it(this);
+ it.seekEnd();
+ return it;
+}
+
+inline
+SparseMatConstIterator SparseMat::end() const
+{
+ SparseMatConstIterator it(this);
+ it.seekEnd();
+ return it;
+}
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp> SparseMat::begin()
+{
+ return SparseMatIterator_<_Tp>(this);
+}
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp> SparseMat::begin() const
+{
+ return SparseMatConstIterator_<_Tp>(this);
+}
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp> SparseMat::end()
+{
+ SparseMatIterator_<_Tp> it(this);
+ it.seekEnd();
+ return it;
+}
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp> SparseMat::end() const
+{
+ SparseMatConstIterator_<_Tp> it(this);
+ it.seekEnd();
+ return it;
+}
+
+
+
+///////////////////////////// SparseMat_ ////////////////////////////
+
+template<typename _Tp> inline
+SparseMat_<_Tp>::SparseMat_()
+{
+ flags = MAGIC_VAL | DataType<_Tp>::type;
+}
+
+template<typename _Tp> inline
+SparseMat_<_Tp>::SparseMat_(int _dims, const int* _sizes)
+ : SparseMat(_dims, _sizes, DataType<_Tp>::type)
+{}
+
+template<typename _Tp> inline
+SparseMat_<_Tp>::SparseMat_(const SparseMat& m)
+{
+ if( m.type() == DataType<_Tp>::type )
+ *this = (const SparseMat_<_Tp>&)m;
+ else
+ m.convertTo(this, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+SparseMat_<_Tp>::SparseMat_(const SparseMat_<_Tp>& m)
+{
+ this->flags = m.flags;
+ this->hdr = m.hdr;
+ if( this->hdr )
+ CV_XADD(&this->hdr->refcount, 1);
+}
+
+template<typename _Tp> inline
+SparseMat_<_Tp>::SparseMat_(const Mat& m)
+{
+ SparseMat sm(m);
+ *this = sm;
+}
+
+template<typename _Tp> inline
+SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const SparseMat_<_Tp>& m)
+{
+ if( this != &m )
+ {
+ if( m.hdr ) CV_XADD(&m.hdr->refcount, 1);
+ release();
+ flags = m.flags;
+ hdr = m.hdr;
+ }
+ return *this;
+}
+
+template<typename _Tp> inline
+SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const SparseMat& m)
+{
+ if( m.type() == DataType<_Tp>::type )
+ return (*this = (const SparseMat_<_Tp>&)m);
+ m.convertTo(*this, DataType<_Tp>::type);
+ return *this;
+}
+
+template<typename _Tp> inline
+SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const Mat& m)
+{
+ return (*this = SparseMat(m));
+}
+
+template<typename _Tp> inline
+SparseMat_<_Tp> SparseMat_<_Tp>::clone() const
+{
+ SparseMat_<_Tp> m;
+ this->copyTo(m);
+ return m;
+}
+
+template<typename _Tp> inline
+void SparseMat_<_Tp>::create(int _dims, const int* _sizes)
+{
+ SparseMat::create(_dims, _sizes, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+int SparseMat_<_Tp>::type() const
+{
+ return DataType<_Tp>::type;
+}
+
+template<typename _Tp> inline
+int SparseMat_<_Tp>::depth() const
+{
+ return DataType<_Tp>::depth;
+}
+
+template<typename _Tp> inline
+int SparseMat_<_Tp>::channels() const
+{
+ return DataType<_Tp>::channels;
+}
+
+template<typename _Tp> inline
+_Tp& SparseMat_<_Tp>::ref(int i0, size_t* hashval)
+{
+ return SparseMat::ref<_Tp>(i0, hashval);
+}
+
+template<typename _Tp> inline
+_Tp SparseMat_<_Tp>::operator()(int i0, size_t* hashval) const
+{
+ return SparseMat::value<_Tp>(i0, hashval);
+}
+
+template<typename _Tp> inline
+_Tp& SparseMat_<_Tp>::ref(int i0, int i1, size_t* hashval)
+{
+ return SparseMat::ref<_Tp>(i0, i1, hashval);
+}
+
+template<typename _Tp> inline
+_Tp SparseMat_<_Tp>::operator()(int i0, int i1, size_t* hashval) const
+{
+ return SparseMat::value<_Tp>(i0, i1, hashval);
+}
+
+template<typename _Tp> inline
+_Tp& SparseMat_<_Tp>::ref(int i0, int i1, int i2, size_t* hashval)
+{
+ return SparseMat::ref<_Tp>(i0, i1, i2, hashval);
+}
+
+template<typename _Tp> inline
+_Tp SparseMat_<_Tp>::operator()(int i0, int i1, int i2, size_t* hashval) const
+{
+ return SparseMat::value<_Tp>(i0, i1, i2, hashval);
+}
+
+template<typename _Tp> inline
+_Tp& SparseMat_<_Tp>::ref(const int* idx, size_t* hashval)
+{
+ return SparseMat::ref<_Tp>(idx, hashval);
+}
+
+template<typename _Tp> inline
+_Tp SparseMat_<_Tp>::operator()(const int* idx, size_t* hashval) const
+{
+ return SparseMat::value<_Tp>(idx, hashval);
+}
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp> SparseMat_<_Tp>::begin()
+{
+ return SparseMatIterator_<_Tp>(this);
+}
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::begin() const
+{
+ return SparseMatConstIterator_<_Tp>(this);
+}
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp> SparseMat_<_Tp>::end()
+{
+ SparseMatIterator_<_Tp> it(this);
+ it.seekEnd();
+ return it;
+}
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::end() const
+{
+ SparseMatConstIterator_<_Tp> it(this);
+ it.seekEnd();
+ return it;
+}
+
+
+
+////////////////////////// MatConstIterator /////////////////////////
+
+inline
+MatConstIterator::MatConstIterator()
+ : m(0), elemSize(0), ptr(0), sliceStart(0), sliceEnd(0)
+{}
+
+inline
+MatConstIterator::MatConstIterator(const Mat* _m)
+ : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
+{
+ if( m && m->isContinuous() )
+ {
+ sliceStart = m->data;
+ sliceEnd = sliceStart + m->total()*elemSize;
+ }
+ seek((const int*)0);
+}
+
+inline
+MatConstIterator::MatConstIterator(const Mat* _m, int _row, int _col)
+ : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
+{
+ CV_Assert(m && m->dims <= 2);
+ if( m->isContinuous() )
+ {
+ sliceStart = m->data;
+ sliceEnd = sliceStart + m->total()*elemSize;
+ }
+ int idx[] = {_row, _col};
+ seek(idx);
+}
+
+inline
+MatConstIterator::MatConstIterator(const Mat* _m, Point _pt)
+ : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
+{
+ CV_Assert(m && m->dims <= 2);
+ if( m->isContinuous() )
+ {
+ sliceStart = m->data;
+ sliceEnd = sliceStart + m->total()*elemSize;
+ }
+ int idx[] = {_pt.y, _pt.x};
+ seek(idx);
+}
+
+inline
+MatConstIterator::MatConstIterator(const MatConstIterator& it)
+ : m(it.m), elemSize(it.elemSize), ptr(it.ptr), sliceStart(it.sliceStart), sliceEnd(it.sliceEnd)
+{}
+
+inline
+MatConstIterator& MatConstIterator::operator = (const MatConstIterator& it )
+{
+ m = it.m; elemSize = it.elemSize; ptr = it.ptr;
+ sliceStart = it.sliceStart; sliceEnd = it.sliceEnd;
+ return *this;
+}
+
+inline
+uchar* MatConstIterator::operator *() const
+{
+ return ptr;
+}
+
+inline MatConstIterator& MatConstIterator::operator += (ptrdiff_t ofs)
+{
+ if( !m || ofs == 0 )
+ return *this;
+ ptrdiff_t ofsb = ofs*elemSize;
+ ptr += ofsb;
+ if( ptr < sliceStart || sliceEnd <= ptr )
+ {
+ ptr -= ofsb;
+ seek(ofs, true);
+ }
+ return *this;
+}
+
+inline
+MatConstIterator& MatConstIterator::operator -= (ptrdiff_t ofs)
+{
+ return (*this += -ofs);
+}
+
+inline
+MatConstIterator& MatConstIterator::operator --()
+{
+ if( m && (ptr -= elemSize) < sliceStart )
+ {
+ ptr += elemSize;
+ seek(-1, true);
+ }
+ return *this;
+}
+
+inline
+MatConstIterator MatConstIterator::operator --(int)
+{
+ MatConstIterator b = *this;
+ *this += -1;
+ return b;
+}
+
+inline
+MatConstIterator& MatConstIterator::operator ++()
+{
+ if( m && (ptr += elemSize) >= sliceEnd )
+ {
+ ptr -= elemSize;
+ seek(1, true);
+ }
+ return *this;
+}
+
+inline MatConstIterator MatConstIterator::operator ++(int)
+{
+ MatConstIterator b = *this;
+ *this += 1;
+ return b;
+}
+
+
+static inline
+bool operator == (const MatConstIterator& a, const MatConstIterator& b)
+{
+ return a.m == b.m && a.ptr == b.ptr;
+}
+
+static inline
+bool operator != (const MatConstIterator& a, const MatConstIterator& b)
+{
+ return !(a == b);
+}
+
+static inline
+bool operator < (const MatConstIterator& a, const MatConstIterator& b)
+{
+ return a.ptr < b.ptr;
+}
+
+static inline
+bool operator > (const MatConstIterator& a, const MatConstIterator& b)
+{
+ return a.ptr > b.ptr;
+}
+
+static inline
+bool operator <= (const MatConstIterator& a, const MatConstIterator& b)
+{
+ return a.ptr <= b.ptr;
+}
+
+static inline
+bool operator >= (const MatConstIterator& a, const MatConstIterator& b)
+{
+ return a.ptr >= b.ptr;
+}
+
+static inline
+ptrdiff_t operator - (const MatConstIterator& b, const MatConstIterator& a)
+{
+ if( a.m != b.m )
+ return ((size_t)(-1) >> 1);
+ if( a.sliceEnd == b.sliceEnd )
+ return (b.ptr - a.ptr)/b.elemSize;
+
+ return b.lpos() - a.lpos();
+}
+
+static inline
+MatConstIterator operator + (const MatConstIterator& a, ptrdiff_t ofs)
+{
+ MatConstIterator b = a;
+ return b += ofs;
+}
+
+static inline
+MatConstIterator operator + (ptrdiff_t ofs, const MatConstIterator& a)
+{
+ MatConstIterator b = a;
+ return b += ofs;
+}
+
+static inline
+MatConstIterator operator - (const MatConstIterator& a, ptrdiff_t ofs)
+{
+ MatConstIterator b = a;
+ return b += -ofs;
+}
+
+
+inline
+uchar* MatConstIterator::operator [](ptrdiff_t i) const
+{
+ return *(*this + i);
+}
+
+
+
+///////////////////////// MatConstIterator_ /////////////////////////
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>::MatConstIterator_()
+{}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m)
+ : MatConstIterator(_m)
+{}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col)
+ : MatConstIterator(_m, _row, _col)
+{}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m, Point _pt)
+ : MatConstIterator(_m, _pt)
+{}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>::MatConstIterator_(const MatConstIterator_& it)
+ : MatConstIterator(it)
+{}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator = (const MatConstIterator_& it )
+{
+ MatConstIterator::operator = (it);
+ return *this;
+}
+
+template<typename _Tp> inline
+_Tp MatConstIterator_<_Tp>::operator *() const
+{
+ return *(_Tp*)(this->ptr);
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator += (ptrdiff_t ofs)
+{
+ MatConstIterator::operator += (ofs);
+ return *this;
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator -= (ptrdiff_t ofs)
+{
+ return (*this += -ofs);
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator --()
+{
+ MatConstIterator::operator --();
+ return *this;
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator --(int)
+{
+ MatConstIterator_ b = *this;
+ MatConstIterator::operator --();
+ return b;
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator ++()
+{
+ MatConstIterator::operator ++();
+ return *this;
+}
+
+template<typename _Tp> inline
+MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator ++(int)
+{
+ MatConstIterator_ b = *this;
+ MatConstIterator::operator ++();
+ return b;
+}
+
+
+template<typename _Tp> inline
+Point MatConstIterator_<_Tp>::pos() const
+{
+ if( !m )
+ return Point();
+ CV_DbgAssert( m->dims <= 2 );
+ if( m->isContinuous() )
+ {
+ ptrdiff_t ofs = (const _Tp*)ptr - (const _Tp*)m->data;
+ int y = (int)(ofs / m->cols);
+ int x = (int)(ofs - (ptrdiff_t)y * m->cols);
+ return Point(x, y);
+ }
+ else
+ {
+ ptrdiff_t ofs = (uchar*)ptr - m->data;
+ int y = (int)(ofs / m->step);
+ int x = (int)((ofs - y * m->step)/sizeof(_Tp));
+ return Point(x, y);
+ }
+}
+
+
+template<typename _Tp> static inline
+bool operator == (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
+{
+ return a.m == b.m && a.ptr == b.ptr;
+}
+
+template<typename _Tp> static inline
+bool operator != (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
+{
+ return a.m != b.m || a.ptr != b.ptr;
+}
+
+template<typename _Tp> static inline
+MatConstIterator_<_Tp> operator + (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
+{
+ MatConstIterator t = (const MatConstIterator&)a + ofs;
+ return (MatConstIterator_<_Tp>&)t;
+}
+
+template<typename _Tp> static inline
+MatConstIterator_<_Tp> operator + (ptrdiff_t ofs, const MatConstIterator_<_Tp>& a)
+{
+ MatConstIterator t = (const MatConstIterator&)a + ofs;
+ return (MatConstIterator_<_Tp>&)t;
+}
+
+template<typename _Tp> static inline
+MatConstIterator_<_Tp> operator - (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
+{
+ MatConstIterator t = (const MatConstIterator&)a - ofs;
+ return (MatConstIterator_<_Tp>&)t;
+}
+
+template<typename _Tp> inline
+_Tp MatConstIterator_<_Tp>::operator [](ptrdiff_t i) const
+{
+ return *(_Tp*)MatConstIterator::operator [](i);
+}
+
+
+
+//////////////////////////// MatIterator_ ///////////////////////////
+
+template<typename _Tp> inline
+MatIterator_<_Tp>::MatIterator_()
+ : MatConstIterator_<_Tp>()
+{}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m)
+ : MatConstIterator_<_Tp>(_m)
+{}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, int _row, int _col)
+ : MatConstIterator_<_Tp>(_m, _row, _col)
+{}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, Point _pt)
+ : MatConstIterator_<_Tp>(_m, _pt)
+{}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, const int* _idx)
+ : MatConstIterator_<_Tp>(_m, _idx)
+{}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>::MatIterator_(const MatIterator_& it)
+ : MatConstIterator_<_Tp>(it)
+{}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>& MatIterator_<_Tp>::operator = (const MatIterator_<_Tp>& it )
+{
+ MatConstIterator::operator = (it);
+ return *this;
+}
+
+template<typename _Tp> inline
+_Tp& MatIterator_<_Tp>::operator *() const
+{
+ return *(_Tp*)(this->ptr);
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>& MatIterator_<_Tp>::operator += (ptrdiff_t ofs)
+{
+ MatConstIterator::operator += (ofs);
+ return *this;
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>& MatIterator_<_Tp>::operator -= (ptrdiff_t ofs)
+{
+ MatConstIterator::operator += (-ofs);
+ return *this;
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>& MatIterator_<_Tp>::operator --()
+{
+ MatConstIterator::operator --();
+ return *this;
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp> MatIterator_<_Tp>::operator --(int)
+{
+ MatIterator_ b = *this;
+ MatConstIterator::operator --();
+ return b;
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp>& MatIterator_<_Tp>::operator ++()
+{
+ MatConstIterator::operator ++();
+ return *this;
+}
+
+template<typename _Tp> inline
+MatIterator_<_Tp> MatIterator_<_Tp>::operator ++(int)
+{
+ MatIterator_ b = *this;
+ MatConstIterator::operator ++();
+ return b;
+}
+
+template<typename _Tp> inline
+_Tp& MatIterator_<_Tp>::operator [](ptrdiff_t i) const
+{
+ return *(*this + i);
+}
+
+
+template<typename _Tp> static inline
+bool operator == (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
+{
+ return a.m == b.m && a.ptr == b.ptr;
+}
+
+template<typename _Tp> static inline
+bool operator != (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
+{
+ return a.m != b.m || a.ptr != b.ptr;
+}
+
+template<typename _Tp> static inline
+MatIterator_<_Tp> operator + (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
+{
+ MatConstIterator t = (const MatConstIterator&)a + ofs;
+ return (MatIterator_<_Tp>&)t;
+}
+
+template<typename _Tp> static inline
+MatIterator_<_Tp> operator + (ptrdiff_t ofs, const MatIterator_<_Tp>& a)
+{
+ MatConstIterator t = (const MatConstIterator&)a + ofs;
+ return (MatIterator_<_Tp>&)t;
+}
+
+template<typename _Tp> static inline
+MatIterator_<_Tp> operator - (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
+{
+ MatConstIterator t = (const MatConstIterator&)a - ofs;
+ return (MatIterator_<_Tp>&)t;
+}
+
+
+
+/////////////////////// SparseMatConstIterator //////////////////////
+
+inline
+SparseMatConstIterator::SparseMatConstIterator()
+ : m(0), hashidx(0), ptr(0)
+{}
+
+inline
+SparseMatConstIterator::SparseMatConstIterator(const SparseMatConstIterator& it)
+ : m(it.m), hashidx(it.hashidx), ptr(it.ptr)
+{}
+
+inline SparseMatConstIterator& SparseMatConstIterator::operator = (const SparseMatConstIterator& it)
+{
+ if( this != &it )
+ {
+ m = it.m;
+ hashidx = it.hashidx;
+ ptr = it.ptr;
+ }
+ return *this;
+}
+
+template<typename _Tp> inline
+const _Tp& SparseMatConstIterator::value() const
+{
+ return *(_Tp*)ptr;
+}
+
+inline
+const SparseMat::Node* SparseMatConstIterator::node() const
+{
+ return (ptr && m && m->hdr) ? (const SparseMat::Node*)(ptr - m->hdr->valueOffset) : 0;
+}
+
+inline
+SparseMatConstIterator SparseMatConstIterator::operator ++(int)
+{
+ SparseMatConstIterator it = *this;
+ ++*this;
+ return it;
+}
+
+inline
+void SparseMatConstIterator::seekEnd()
+{
+ if( m && m->hdr )
+ {
+ hashidx = m->hdr->hashtab.size();
+ ptr = 0;
+ }
+}
+
+
+static inline
+bool operator == (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
+{
+ return it1.m == it2.m && it1.ptr == it2.ptr;
+}
+
+static inline
+bool operator != (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
+{
+ return !(it1 == it2);
+}
+
+
+
+///////////////////////// SparseMatIterator /////////////////////////
+
+inline
+SparseMatIterator::SparseMatIterator()
+{}
+
+inline
+SparseMatIterator::SparseMatIterator(SparseMat* _m)
+ : SparseMatConstIterator(_m)
+{}
+
+inline
+SparseMatIterator::SparseMatIterator(const SparseMatIterator& it)
+ : SparseMatConstIterator(it)
+{}
+
+inline
+SparseMatIterator& SparseMatIterator::operator = (const SparseMatIterator& it)
+{
+ (SparseMatConstIterator&)*this = it;
+ return *this;
+}
+
+template<typename _Tp> inline
+_Tp& SparseMatIterator::value() const
+{
+ return *(_Tp*)ptr;
+}
+
+inline
+SparseMat::Node* SparseMatIterator::node() const
+{
+ return (SparseMat::Node*)SparseMatConstIterator::node();
+}
+
+inline
+SparseMatIterator& SparseMatIterator::operator ++()
+{
+ SparseMatConstIterator::operator ++();
+ return *this;
+}
+
+inline
+SparseMatIterator SparseMatIterator::operator ++(int)
+{
+ SparseMatIterator it = *this;
+ ++*this;
+ return it;
+}
+
+
+
+////////////////////// SparseMatConstIterator_ //////////////////////
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp>::SparseMatConstIterator_()
+{}
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat_<_Tp>* _m)
+ : SparseMatConstIterator(_m)
+{}
+
+template<typename _Tp> inline
++SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat* _m)
++ : SparseMatConstIterator(_m)
++{
++ CV_Assert( _m->type() == DataType<_Tp>::type );
++}
++
++template<typename _Tp> inline
+SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMatConstIterator_<_Tp>& it)
+ : SparseMatConstIterator(it)
+{}
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp>& SparseMatConstIterator_<_Tp>::operator = (const SparseMatConstIterator_<_Tp>& it)
+{
+ return reinterpret_cast<SparseMatConstIterator_<_Tp>&>
+ (*reinterpret_cast<SparseMatConstIterator*>(this) =
+ reinterpret_cast<const SparseMatConstIterator&>(it));
+}
+
+template<typename _Tp> inline
+const _Tp& SparseMatConstIterator_<_Tp>::operator *() const
+{
+ return *(const _Tp*)this->ptr;
+}
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp>& SparseMatConstIterator_<_Tp>::operator ++()
+{
+ SparseMatConstIterator::operator ++();
+ return *this;
+}
+
+template<typename _Tp> inline
+SparseMatConstIterator_<_Tp> SparseMatConstIterator_<_Tp>::operator ++(int)
+{
+ SparseMatConstIterator it = *this;
+ SparseMatConstIterator::operator ++();
+ return it;
+}
+
+
+
+///////////////////////// SparseMatIterator_ ////////////////////////
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp>::SparseMatIterator_()
+{}
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat_<_Tp>* _m)
+ : SparseMatConstIterator_<_Tp>(_m)
+{}
+
+template<typename _Tp> inline
++SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat* _m)
++ : SparseMatConstIterator_<_Tp>(_m)
++{}
++
++template<typename _Tp> inline
+SparseMatIterator_<_Tp>::SparseMatIterator_(const SparseMatIterator_<_Tp>& it)
+ : SparseMatConstIterator_<_Tp>(it)
+{}
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp>& SparseMatIterator_<_Tp>::operator = (const SparseMatIterator_<_Tp>& it)
+{
+ return reinterpret_cast<SparseMatIterator_<_Tp>&>
+ (*reinterpret_cast<SparseMatConstIterator*>(this) =
+ reinterpret_cast<const SparseMatConstIterator&>(it));
+}
+
+template<typename _Tp> inline
+_Tp& SparseMatIterator_<_Tp>::operator *() const
+{
+ return *(_Tp*)this->ptr;
+}
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp>& SparseMatIterator_<_Tp>::operator ++()
+{
+ SparseMatConstIterator::operator ++();
+ return *this;
+}
+
+template<typename _Tp> inline
+SparseMatIterator_<_Tp> SparseMatIterator_<_Tp>::operator ++(int)
+{
+ SparseMatIterator it = *this;
+ SparseMatConstIterator::operator ++();
+ return it;
+}
+
+
+
+//////////////////////// MatCommaInitializer_ ///////////////////////
+
+template<typename _Tp> inline
+MatCommaInitializer_<_Tp>::MatCommaInitializer_(Mat_<_Tp>* _m)
+ : it(_m)
+{}
+
+template<typename _Tp> template<typename T2> inline
+MatCommaInitializer_<_Tp>& MatCommaInitializer_<_Tp>::operator , (T2 v)
+{
+ CV_DbgAssert( this->it < ((const Mat_<_Tp>*)this->it.m)->end() );
+ *this->it = _Tp(v);
+ ++this->it;
+ return *this;
+}
+
+template<typename _Tp> inline
+MatCommaInitializer_<_Tp>::operator Mat_<_Tp>() const
+{
+ CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
+ return Mat_<_Tp>(*this->it.m);
+}
+
+
+template<typename _Tp, typename T2> static inline
+MatCommaInitializer_<_Tp> operator << (const Mat_<_Tp>& m, T2 val)
+{
+ MatCommaInitializer_<_Tp> commaInitializer((Mat_<_Tp>*)&m);
+ return (commaInitializer, val);
+}
+
+
+
+///////////////////////// Matrix Expressions ////////////////////////
+
+inline
+Mat& Mat::operator = (const MatExpr& e)
+{
+ e.op->assign(e, *this);
+ return *this;
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>::Mat_(const MatExpr& e)
+{
+ e.op->assign(e, *this, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr& e)
+{
+ e.op->assign(e, *this, DataType<_Tp>::type);
+ return *this;
+}
+
+template<typename _Tp> inline
+MatExpr Mat_<_Tp>::zeros(int rows, int cols)
+{
+ return Mat::zeros(rows, cols, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+MatExpr Mat_<_Tp>::zeros(Size sz)
+{
+ return Mat::zeros(sz, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+MatExpr Mat_<_Tp>::ones(int rows, int cols)
+{
+ return Mat::ones(rows, cols, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+MatExpr Mat_<_Tp>::ones(Size sz)
+{
+ return Mat::ones(sz, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+MatExpr Mat_<_Tp>::eye(int rows, int cols)
+{
+ return Mat::eye(rows, cols, DataType<_Tp>::type);
+}
+
+template<typename _Tp> inline
+MatExpr Mat_<_Tp>::eye(Size sz)
+{
+ return Mat::eye(sz, DataType<_Tp>::type);
+}
+
+inline
+MatExpr::MatExpr()
+ : op(0), flags(0), a(Mat()), b(Mat()), c(Mat()), alpha(0), beta(0), s()
+{}
+
+inline
+MatExpr::MatExpr(const MatOp* _op, int _flags, const Mat& _a, const Mat& _b,
+ const Mat& _c, double _alpha, double _beta, const Scalar& _s)
+ : op(_op), flags(_flags), a(_a), b(_b), c(_c), alpha(_alpha), beta(_beta), s(_s)
+{}
+
+inline
+MatExpr::operator Mat() const
+{
+ Mat m;
+ op->assign(*this, m);
+ return m;
+}
+
+template<typename _Tp> inline
+MatExpr::operator Mat_<_Tp>() const
+{
+ Mat_<_Tp> m;
+ op->assign(*this, m, DataType<_Tp>::type);
+ return m;
+}
+
+
+template<typename _Tp> static inline
+MatExpr min(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
+{
+ return cv::min((const Mat&)a, (const Mat&)b);
+}
+
+template<typename _Tp> static inline
+MatExpr min(const Mat_<_Tp>& a, double s)
+{
+ return cv::min((const Mat&)a, s);
+}
+
+template<typename _Tp> static inline
+MatExpr min(double s, const Mat_<_Tp>& a)
+{
+ return cv::min((const Mat&)a, s);
+}
+
+template<typename _Tp> static inline
+MatExpr max(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
+{
+ return cv::max((const Mat&)a, (const Mat&)b);
+}
+
+template<typename _Tp> static inline
+MatExpr max(const Mat_<_Tp>& a, double s)
+{
+ return cv::max((const Mat&)a, s);
+}
+
+template<typename _Tp> static inline
+MatExpr max(double s, const Mat_<_Tp>& a)
+{
+ return cv::max((const Mat&)a, s);
+}
+
+template<typename _Tp> static inline
+MatExpr abs(const Mat_<_Tp>& m)
+{
+ return cv::abs((const Mat&)m);
+}
+
+
+static inline
+Mat& operator += (Mat& a, const MatExpr& b)
+{
+ b.op->augAssignAdd(b, a);
+ return a;
+}
+
+static inline
+const Mat& operator += (const Mat& a, const MatExpr& b)
+{
+ b.op->augAssignAdd(b, (Mat&)a);
+ return a;
+}
+
+template<typename _Tp> static inline
+Mat_<_Tp>& operator += (Mat_<_Tp>& a, const MatExpr& b)
+{
+ b.op->augAssignAdd(b, a);
+ return a;
+}
+
+template<typename _Tp> static inline
+const Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const MatExpr& b)
+{
+ b.op->augAssignAdd(b, (Mat&)a);
+ return a;
+}
+
+static inline
+Mat& operator -= (Mat& a, const MatExpr& b)
+{
+ b.op->augAssignSubtract(b, a);
+ return a;
+}
+
+static inline
+const Mat& operator -= (const Mat& a, const MatExpr& b)
+{
+ b.op->augAssignSubtract(b, (Mat&)a);
+ return a;
+}
+
+template<typename _Tp> static inline
+Mat_<_Tp>& operator -= (Mat_<_Tp>& a, const MatExpr& b)
+{
+ b.op->augAssignSubtract(b, a);
+ return a;
+}
+
+template<typename _Tp> static inline
+const Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const MatExpr& b)
+{
+ b.op->augAssignSubtract(b, (Mat&)a);
+ return a;
+}
+
+static inline
+Mat& operator *= (Mat& a, const MatExpr& b)
+{
+ b.op->augAssignMultiply(b, a);
+ return a;
+}
+
+static inline
+const Mat& operator *= (const Mat& a, const MatExpr& b)
+{
+ b.op->augAssignMultiply(b, (Mat&)a);
+ return a;
+}
+
+template<typename _Tp> static inline
+Mat_<_Tp>& operator *= (Mat_<_Tp>& a, const MatExpr& b)
+{
+ b.op->augAssignMultiply(b, a);
+ return a;
+}
+
+template<typename _Tp> static inline
+const Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const MatExpr& b)
+{
+ b.op->augAssignMultiply(b, (Mat&)a);
+ return a;
+}
+
+static inline
+Mat& operator /= (Mat& a, const MatExpr& b)
+{
+ b.op->augAssignDivide(b, a);
+ return a;
+}
+
+static inline
+const Mat& operator /= (const Mat& a, const MatExpr& b)
+{
+ b.op->augAssignDivide(b, (Mat&)a);
+ return a;
+}
+
+template<typename _Tp> static inline
+Mat_<_Tp>& operator /= (Mat_<_Tp>& a, const MatExpr& b)
+{
+ b.op->augAssignDivide(b, a);
+ return a;
+}
+
+template<typename _Tp> static inline
+const Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const MatExpr& b)
+{
+ b.op->augAssignDivide(b, (Mat&)a);
+ return a;
+}
+
+} //cv
+
+#endif
ASSERT_EQ(0, countNonZero(m1 - m2));
}
-}
+
+ TEST(Core_round, CvRound)
+ {
+ ASSERT_EQ(2, cvRound(2.0));
+ ASSERT_EQ(2, cvRound(2.1));
+ ASSERT_EQ(-2, cvRound(-2.1));
+ ASSERT_EQ(3, cvRound(2.8));
+ ASSERT_EQ(-3, cvRound(-2.8));
+ ASSERT_EQ(2, cvRound(2.5));
+ ASSERT_EQ(4, cvRound(3.5));
+ ASSERT_EQ(-2, cvRound(-2.5));
+ ASSERT_EQ(-4, cvRound(-3.5));
++}
};
// takes keypoints and culls them by the response
-void KeyPointsFilter::retainBest(vector<KeyPoint>& keypoints, int n_points)
+void KeyPointsFilter::retainBest(std::vector<KeyPoint>& keypoints, int n_points)
{
//this is only necessary if the keypoints size is greater than the number of desired points.
- if( n_points > 0 && keypoints.size() > (size_t)n_points )
+ if( n_points >= 0 && keypoints.size() > (size_t)n_points )
{
if (n_points==0)
{
//M*/
#include "test_precomp.hpp"
-#include "opencv2/highgui/highgui.hpp"
+#include "opencv2/highgui.hpp"
- #if defined HAVE_GTK || defined HAVE_QT || defined WIN32 || defined _WIN32 || defined HAVE_CARBON || defined HAVE_COCOA
+ #if defined HAVE_GTK || defined HAVE_QT || defined HAVE_WIN32UI || defined HAVE_CARBON || defined HAVE_COCOA
using namespace cv;
using namespace std;
#ifndef __OPENCV_TEST_PRECOMP_HPP__
#define __OPENCV_TEST_PRECOMP_HPP__
-#ifdef HAVE_CVCONFIG_H
-# include "cvconfig.h"
-#endif
-
-#include "opencv2/ts/ts.hpp"
-#include "opencv2/imgproc/imgproc.hpp"
-#include "opencv2/imgproc/imgproc_c.h"
#include <iostream>
+#include "opencv2/ts.hpp"
+#include "opencv2/imgproc.hpp"
+#include "opencv2/imgproc/imgproc_c.h"
+
+#include "opencv2/core/private.hpp"
- #if defined(HAVE_VIDEOINPUT) || \
+ #if defined(HAVE_DSHOW) || \
defined(HAVE_TYZX) || \
defined(HAVE_VFW) || \
defined(HAVE_LIBV4L) || \
#ifndef __OPENCV_TEST_PRECOMP_HPP__
#define __OPENCV_TEST_PRECOMP_HPP__
-#include "opencv2/ts/ts.hpp"
-#include "opencv2/imgproc/imgproc.hpp"
-#include "opencv2/highgui/highgui.hpp"
-#include "opencv2/nonfree/nonfree.hpp"
+#include <iostream>
+#include "opencv2/ts.hpp"
+#include "opencv2/imgproc.hpp"
+#include "opencv2/highgui.hpp"
+#include "opencv2/nonfree.hpp"
+ #include "opencv2/ts/gpu_test.hpp"
+
#include "opencv2/opencv_modules.hpp"
+
#ifdef HAVE_OPENCV_OCL
# include "opencv2/nonfree/ocl.hpp"
#endif
endif()
set(the_description "OpenCL-accelerated Computer Vision")
- ocv_define_module(ocl opencv_core opencv_imgproc opencv_objdetect opencv_video)
-ocv_define_module(ocl opencv_core opencv_imgproc opencv_features2d opencv_objdetect opencv_video)
++ocv_define_module(ocl opencv_core opencv_imgproc opencv_objdetect opencv_video opencv_features2d)
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wshadow)
--- /dev/null
- //#include "opencv2/features2d.hpp"
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved.
+// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
+// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other oclMaterials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_OCL_HPP__
+#define __OPENCV_OCL_HPP__
+
+#include <memory>
+#include <vector>
+
+#include "opencv2/core.hpp"
+#include "opencv2/imgproc.hpp"
+#include "opencv2/objdetect.hpp"
+
+namespace cv
+{
+ namespace ocl
+ {
+ enum
+ {
+ CVCL_DEVICE_TYPE_DEFAULT = (1 << 0),
+ CVCL_DEVICE_TYPE_CPU = (1 << 1),
+ CVCL_DEVICE_TYPE_GPU = (1 << 2),
+ CVCL_DEVICE_TYPE_ACCELERATOR = (1 << 3),
+ //CVCL_DEVICE_TYPE_CUSTOM = (1 << 4)
+ CVCL_DEVICE_TYPE_ALL = 0xFFFFFFFF
+ };
+
+ enum DevMemRW
+ {
+ DEVICE_MEM_R_W = 0,
+ DEVICE_MEM_R_ONLY,
+ DEVICE_MEM_W_ONLY
+ };
+
+ enum DevMemType
+ {
+ DEVICE_MEM_DEFAULT = 0,
+ DEVICE_MEM_AHP, //alloc host pointer
+ DEVICE_MEM_UHP, //use host pointer
+ DEVICE_MEM_CHP, //copy host pointer
+ DEVICE_MEM_PM //persistent memory
+ };
+
+ //Get the global device memory and read/write type
+ //return 1 if unified memory system supported, otherwise return 0
+ CV_EXPORTS int getDevMemType(DevMemRW& rw_type, DevMemType& mem_type);
+
+ //Set the global device memory and read/write type,
+ //the newly generated oclMat will all use this type
+ //return -1 if the target type is unsupported, otherwise return 0
+ CV_EXPORTS int setDevMemType(DevMemRW rw_type = DEVICE_MEM_R_W, DevMemType mem_type = DEVICE_MEM_DEFAULT);
+
+ //this class contains ocl runtime information
+ class CV_EXPORTS Info
+ {
+ public:
+ struct Impl;
+ Impl *impl;
+
+ Info();
+ Info(const Info &m);
+ ~Info();
+ void release();
+ Info &operator = (const Info &m);
+ std::vector<String> DeviceName;
+ };
+ //////////////////////////////// Initialization & Info ////////////////////////
+ //this function may be obsoleted
+ //CV_EXPORTS cl_device_id getDevice();
+ //the function must be called before any other cv::ocl::functions, it initialize ocl runtime
+ //each Info relates to an OpenCL platform
+ //there is one or more devices in each platform, each one has a separate name
+ CV_EXPORTS int getDevice(std::vector<Info> &oclinfo, int devicetype = CVCL_DEVICE_TYPE_GPU);
+
+ //set device you want to use, optional function after getDevice be called
+ //the devnum is the index of the selected device in DeviceName vector of INfo
+ CV_EXPORTS void setDevice(Info &oclinfo, int devnum = 0);
+
+ //optional function, if you want save opencl binary kernel to the file, set its path
+ CV_EXPORTS void setBinpath(const char *path);
+
+ //The two functions below enable other opencl program to use ocl module's cl_context and cl_command_queue
+ CV_EXPORTS void* getoclContext();
+
+ CV_EXPORTS void* getoclCommandQueue();
+
++ //explicit call clFinish. The global command queue will be used.
++ CV_EXPORTS void finish();
++
+ //this function enable ocl module to use customized cl_context and cl_command_queue
+ //getDevice also need to be called before this function
+ CV_EXPORTS void setDeviceEx(Info &oclinfo, void *ctx, void *qu, int devnum = 0);
+
+ //////////////////////////////// Error handling ////////////////////////
+ CV_EXPORTS void error(const char *error_string, const char *file, const int line, const char *func);
+
+ //////////////////////////////// OpenCL context ////////////////////////
+ //This is a global singleton class used to represent a OpenCL context.
+ class CV_EXPORTS Context
+ {
+ protected:
+ Context();
+ friend class std::auto_ptr<Context>;
+
+ private:
+ static std::auto_ptr<Context> clCxt;
+ static int val;
+ public:
+ ~Context();
+ void release();
+ Info::Impl* impl;
+
+ static Context *getContext();
+ static void setContext(Info &oclinfo);
+
+ enum {CL_DOUBLE, CL_UNIFIED_MEM};
+ bool supportsFeature(int ftype);
+ size_t computeUnits();
+ size_t maxWorkGroupSize();
+ void* oclContext();
+ void* oclCommandQueue();
+ };
+
+ //! Calls a kernel, by string. Pass globalThreads = NULL, and cleanUp = true, to finally clean-up without executing.
+ CV_EXPORTS double openCLExecuteKernelInterop(Context *clCxt ,
+ const char **source, String kernelName,
+ size_t globalThreads[3], size_t localThreads[3],
+ std::vector< std::pair<size_t, const void *> > &args,
+ int channels, int depth, const char *build_options,
+ bool finish = true, bool measureKernelTime = false,
+ bool cleanUp = true);
+
+ //! Calls a kernel, by file. Pass globalThreads = NULL, and cleanUp = true, to finally clean-up without executing.
+ CV_EXPORTS double openCLExecuteKernelInterop(Context *clCxt ,
+ const char **fileName, const int numFiles, String kernelName,
+ size_t globalThreads[3], size_t localThreads[3],
+ std::vector< std::pair<size_t, const void *> > &args,
+ int channels, int depth, const char *build_options,
+ bool finish = true, bool measureKernelTime = false,
+ bool cleanUp = true);
+
+ class CV_EXPORTS oclMatExpr;
+ //////////////////////////////// oclMat ////////////////////////////////
+ class CV_EXPORTS oclMat
+ {
+ public:
+ //! default constructor
+ oclMat();
+ //! constructs oclMatrix of the specified size and type (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
+ oclMat(int rows, int cols, int type);
+ oclMat(Size size, int type);
+ //! constucts oclMatrix and fills it with the specified value _s.
+ oclMat(int rows, int cols, int type, const Scalar &s);
+ oclMat(Size size, int type, const Scalar &s);
+ //! copy constructor
+ oclMat(const oclMat &m);
+
+ //! constructor for oclMatrix headers pointing to user-allocated data
+ oclMat(int rows, int cols, int type, void *data, size_t step = Mat::AUTO_STEP);
+ oclMat(Size size, int type, void *data, size_t step = Mat::AUTO_STEP);
+
+ //! creates a matrix header for a part of the bigger matrix
+ oclMat(const oclMat &m, const Range &rowRange, const Range &colRange);
+ oclMat(const oclMat &m, const Rect &roi);
+
+ //! builds oclMat from Mat. Perfom blocking upload to device.
+ explicit oclMat (const Mat &m);
+
+ //! destructor - calls release()
+ ~oclMat();
+
+ //! assignment operators
+ oclMat &operator = (const oclMat &m);
+ //! assignment operator. Perfom blocking upload to device.
+ oclMat &operator = (const Mat &m);
+ oclMat &operator = (const oclMatExpr& expr);
+
+ //! pefroms blocking upload data to oclMat.
+ void upload(const cv::Mat &m);
+
+
+ //! downloads data from device to host memory. Blocking calls.
+ operator Mat() const;
+ void download(cv::Mat &m) const;
+
+
+ //! returns a new oclMatrix header for the specified row
+ oclMat row(int y) const;
+ //! returns a new oclMatrix header for the specified column
+ oclMat col(int x) const;
+ //! ... for the specified row span
+ oclMat rowRange(int startrow, int endrow) const;
+ oclMat rowRange(const Range &r) const;
+ //! ... for the specified column span
+ oclMat colRange(int startcol, int endcol) const;
+ oclMat colRange(const Range &r) const;
+
+ //! returns deep copy of the oclMatrix, i.e. the data is copied
+ oclMat clone() const;
+ //! copies the oclMatrix content to "m".
+ // It calls m.create(this->size(), this->type()).
+ // It supports any data type
+ void copyTo( oclMat &m ) const;
+ //! copies those oclMatrix elements to "m" that are marked with non-zero mask elements.
+ //It supports 8UC1 8UC4 32SC1 32SC4 32FC1 32FC4
+ void copyTo( oclMat &m, const oclMat &mask ) const;
+ //! converts oclMatrix to another datatype with optional scalng. See cvConvertScale.
+ //It supports 8UC1 8UC4 32SC1 32SC4 32FC1 32FC4
+ void convertTo( oclMat &m, int rtype, double alpha = 1, double beta = 0 ) const;
+
+ void assignTo( oclMat &m, int type = -1 ) const;
+
+ //! sets every oclMatrix element to s
+ //It supports 8UC1 8UC4 32SC1 32SC4 32FC1 32FC4
+ oclMat& operator = (const Scalar &s);
+ //! sets some of the oclMatrix elements to s, according to the mask
+ //It supports 8UC1 8UC4 32SC1 32SC4 32FC1 32FC4
+ oclMat& setTo(const Scalar &s, const oclMat &mask = oclMat());
+ //! creates alternative oclMatrix header for the same data, with different
+ // number of channels and/or different number of rows. see cvReshape.
+ oclMat reshape(int cn, int rows = 0) const;
+
+ //! allocates new oclMatrix data unless the oclMatrix already has specified size and type.
+ // previous data is unreferenced if needed.
+ void create(int rows, int cols, int type);
+ void create(Size size, int type);
+
+ //! allocates new oclMatrix with specified device memory type.
+ void createEx(int rows, int cols, int type, DevMemRW rw_type, DevMemType mem_type);
+ void createEx(Size size, int type, DevMemRW rw_type, DevMemType mem_type);
+
+ //! decreases reference counter;
+ // deallocate the data when reference counter reaches 0.
+ void release();
+
+ //! swaps with other smart pointer
+ void swap(oclMat &mat);
+
+ //! locates oclMatrix header within a parent oclMatrix. See below
+ void locateROI( Size &wholeSize, Point &ofs ) const;
+ //! moves/resizes the current oclMatrix ROI inside the parent oclMatrix.
+ oclMat& adjustROI( int dtop, int dbottom, int dleft, int dright );
+ //! extracts a rectangular sub-oclMatrix
+ // (this is a generalized form of row, rowRange etc.)
+ oclMat operator()( Range rowRange, Range colRange ) const;
+ oclMat operator()( const Rect &roi ) const;
+
+ oclMat& operator+=( const oclMat& m );
+ oclMat& operator-=( const oclMat& m );
+ oclMat& operator*=( const oclMat& m );
+ oclMat& operator/=( const oclMat& m );
+
+ //! returns true if the oclMatrix data is continuous
+ // (i.e. when there are no gaps between successive rows).
+ // similar to CV_IS_oclMat_CONT(cvoclMat->type)
+ bool isContinuous() const;
+ //! returns element size in bytes,
+ // similar to CV_ELEM_SIZE(cvMat->type)
+ size_t elemSize() const;
+ //! returns the size of element channel in bytes.
+ size_t elemSize1() const;
+ //! returns element type, similar to CV_MAT_TYPE(cvMat->type)
+ int type() const;
+ //! returns element type, i.e. 8UC3 returns 8UC4 because in ocl
+ //! 3 channels element actually use 4 channel space
+ int ocltype() const;
+ //! returns element type, similar to CV_MAT_DEPTH(cvMat->type)
+ int depth() const;
+ //! returns element type, similar to CV_MAT_CN(cvMat->type)
+ int channels() const;
+ //! returns element type, return 4 for 3 channels element,
+ //!becuase 3 channels element actually use 4 channel space
+ int oclchannels() const;
+ //! returns step/elemSize1()
+ size_t step1() const;
+ //! returns oclMatrix size:
+ // width == number of columns, height == number of rows
+ Size size() const;
+ //! returns true if oclMatrix data is NULL
+ bool empty() const;
+
+ //! returns pointer to y-th row
+ uchar* ptr(int y = 0);
+ const uchar *ptr(int y = 0) const;
+
+ //! template version of the above method
+ template<typename _Tp> _Tp *ptr(int y = 0);
+ template<typename _Tp> const _Tp *ptr(int y = 0) const;
+
+ //! matrix transposition
+ oclMat t() const;
+
+ /*! includes several bit-fields:
+ - the magic signature
+ - continuity flag
+ - depth
+ - number of channels
+ */
+ int flags;
+ //! the number of rows and columns
+ int rows, cols;
+ //! a distance between successive rows in bytes; includes the gap if any
+ size_t step;
+ //! pointer to the data(OCL memory object)
+ uchar *data;
+
+ //! pointer to the reference counter;
+ // when oclMatrix points to user-allocated data, the pointer is NULL
+ int *refcount;
+
+ //! helper fields used in locateROI and adjustROI
+ //datastart and dataend are not used in current version
+ uchar *datastart;
+ uchar *dataend;
+
+ //! OpenCL context associated with the oclMat object.
+ Context *clCxt;
+ //add offset for handle ROI, calculated in byte
+ int offset;
+ //add wholerows and wholecols for the whole matrix, datastart and dataend are no longer used
+ int wholerows;
+ int wholecols;
+ };
+
+
+ ///////////////////// mat split and merge /////////////////////////////////
+ //! Compose a multi-channel array from several single-channel arrays
+ // Support all types
+ CV_EXPORTS void merge(const oclMat *src, size_t n, oclMat &dst);
+ CV_EXPORTS void merge(const std::vector<oclMat> &src, oclMat &dst);
+
+ //! Divides multi-channel array into several single-channel arrays
+ // Support all types
+ CV_EXPORTS void split(const oclMat &src, oclMat *dst);
+ CV_EXPORTS void split(const oclMat &src, std::vector<oclMat> &dst);
+
+ ////////////////////////////// Arithmetics ///////////////////////////////////
+ //#if defined DOUBLE_SUPPORT
+ //typedef double F;
+ //#else
+ //typedef float F;
+ //#endif
+ // CV_EXPORTS void addWeighted(const oclMat& a,F alpha, const oclMat& b,F beta,F gama, oclMat& c);
+ CV_EXPORTS void addWeighted(const oclMat &a, double alpha, const oclMat &b, double beta, double gama, oclMat &c);
+ //! adds one matrix to another (c = a + b)
+ // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+ CV_EXPORTS void add(const oclMat &a, const oclMat &b, oclMat &c);
+ //! adds one matrix to another (c = a + b)
+ // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+ CV_EXPORTS void add(const oclMat &a, const oclMat &b, oclMat &c, const oclMat &mask);
+ //! adds scalar to a matrix (c = a + s)
+ // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+ CV_EXPORTS void add(const oclMat &a, const Scalar &sc, oclMat &c, const oclMat &mask = oclMat());
+ //! subtracts one matrix from another (c = a - b)
+ // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+ CV_EXPORTS void subtract(const oclMat &a, const oclMat &b, oclMat &c);
+ //! subtracts one matrix from another (c = a - b)
+ // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+ CV_EXPORTS void subtract(const oclMat &a, const oclMat &b, oclMat &c, const oclMat &mask);
+ //! subtracts scalar from a matrix (c = a - s)
+ // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+ CV_EXPORTS void subtract(const oclMat &a, const Scalar &sc, oclMat &c, const oclMat &mask = oclMat());
+ //! subtracts scalar from a matrix (c = a - s)
+ // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+ CV_EXPORTS void subtract(const Scalar &sc, const oclMat &a, oclMat &c, const oclMat &mask = oclMat());
+ //! computes element-wise product of the two arrays (c = a * b)
+ // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+ CV_EXPORTS void multiply(const oclMat &a, const oclMat &b, oclMat &c, double scale = 1);
+ //! computes element-wise quotient of the two arrays (c = a / b)
+ // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+ CV_EXPORTS void divide(const oclMat &a, const oclMat &b, oclMat &c, double scale = 1);
+ //! computes element-wise quotient of the two arrays (c = a / b)
+ // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+ CV_EXPORTS void divide(double scale, const oclMat &b, oclMat &c);
+
+ //! compares elements of two arrays (c = a <cmpop> b)
+ // supports except CV_8SC1,CV_8SC2,CV8SC3,CV_8SC4 types
+ CV_EXPORTS void compare(const oclMat &a, const oclMat &b, oclMat &c, int cmpop);
+
+ //! transposes the matrix
+ // supports CV_8UC1, 8UC4, 8SC4, 16UC2, 16SC2, 32SC1 and 32FC1.(the same as cuda)
+ CV_EXPORTS void transpose(const oclMat &src, oclMat &dst);
+
+ //! computes element-wise absolute difference of two arrays (c = abs(a - b))
+ // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+ CV_EXPORTS void absdiff(const oclMat &a, const oclMat &b, oclMat &c);
+ //! computes element-wise absolute difference of array and scalar (c = abs(a - s))
+ // supports all types except CV_8SC1,CV_8SC2,CV8SC3 and CV_8SC4
+ CV_EXPORTS void absdiff(const oclMat &a, const Scalar &s, oclMat &c);
+
+ //! computes mean value and standard deviation of all or selected array elements
+ // supports except CV_32F,CV_64F
+ CV_EXPORTS void meanStdDev(const oclMat &mtx, Scalar &mean, Scalar &stddev);
+
+ //! computes norm of array
+ // supports NORM_INF, NORM_L1, NORM_L2
+ // supports only CV_8UC1 type
+ CV_EXPORTS double norm(const oclMat &src1, int normType = NORM_L2);
+
+ //! computes norm of the difference between two arrays
+ // supports NORM_INF, NORM_L1, NORM_L2
+ // supports only CV_8UC1 type
+ CV_EXPORTS double norm(const oclMat &src1, const oclMat &src2, int normType = NORM_L2);
+
+ //! reverses the order of the rows, columns or both in a matrix
+ // supports all types
+ CV_EXPORTS void flip(const oclMat &a, oclMat &b, int flipCode);
+
+ //! computes sum of array elements
+ // disabled until fix crash
+ // support all types
+ CV_EXPORTS Scalar sum(const oclMat &m);
+ CV_EXPORTS Scalar absSum(const oclMat &m);
+ CV_EXPORTS Scalar sqrSum(const oclMat &m);
+
+ //! finds global minimum and maximum array elements and returns their values
+ // support all C1 types
+
+ CV_EXPORTS void minMax(const oclMat &src, double *minVal, double *maxVal = 0, const oclMat &mask = oclMat());
+
+ //! finds global minimum and maximum array elements and returns their values with locations
+ // support all C1 types
+
+ CV_EXPORTS void minMaxLoc(const oclMat &src, double *minVal, double *maxVal = 0, Point *minLoc = 0, Point *maxLoc = 0,
+ const oclMat &mask = oclMat());
+
+ //! counts non-zero array elements
+ // support all types
+ CV_EXPORTS int countNonZero(const oclMat &src);
+
+ //! transforms 8-bit unsigned integers using lookup table: dst(i)=lut(src(i))
+ // destination array will have the depth type as lut and the same channels number as source
+ //It supports 8UC1 8UC4 only
+ CV_EXPORTS void LUT(const oclMat &src, const oclMat &lut, oclMat &dst);
+
+ //! only 8UC1 and 256 bins is supported now
+ CV_EXPORTS void calcHist(const oclMat &mat_src, oclMat &mat_hist);
+ //! only 8UC1 and 256 bins is supported now
+ CV_EXPORTS void equalizeHist(const oclMat &mat_src, oclMat &mat_dst);
+ //! bilateralFilter
+ // supports 8UC1 8UC4
+ CV_EXPORTS void bilateralFilter(const oclMat& src, oclMat& dst, int d, double sigmaColor, double sigmaSpave, int borderType=BORDER_DEFAULT);
+ //! computes exponent of each matrix element (b = e**a)
+ // supports only CV_32FC1 type
+ CV_EXPORTS void exp(const oclMat &a, oclMat &b);
+
+ //! computes natural logarithm of absolute value of each matrix element: b = log(abs(a))
+ // supports only CV_32FC1 type
+ CV_EXPORTS void log(const oclMat &a, oclMat &b);
+
+ //! computes magnitude of each (x(i), y(i)) vector
+ // supports only CV_32F CV_64F type
+ CV_EXPORTS void magnitude(const oclMat &x, const oclMat &y, oclMat &magnitude);
+ CV_EXPORTS void magnitudeSqr(const oclMat &x, const oclMat &y, oclMat &magnitude);
+
+ CV_EXPORTS void magnitudeSqr(const oclMat &x, oclMat &magnitude);
+
+ //! computes angle (angle(i)) of each (x(i), y(i)) vector
+ // supports only CV_32F CV_64F type
+ CV_EXPORTS void phase(const oclMat &x, const oclMat &y, oclMat &angle, bool angleInDegrees = false);
+
+ //! the function raises every element of tne input array to p
+ //! support only CV_32F CV_64F type
+ CV_EXPORTS void pow(const oclMat &x, double p, oclMat &y);
+
+ //! converts Cartesian coordinates to polar
+ // supports only CV_32F CV_64F type
+ CV_EXPORTS void cartToPolar(const oclMat &x, const oclMat &y, oclMat &magnitude, oclMat &angle, bool angleInDegrees = false);
+
+ //! converts polar coordinates to Cartesian
+ // supports only CV_32F CV_64F type
+ CV_EXPORTS void polarToCart(const oclMat &magnitude, const oclMat &angle, oclMat &x, oclMat &y, bool angleInDegrees = false);
+
+ //! perfroms per-elements bit-wise inversion
+ // supports all types
+ CV_EXPORTS void bitwise_not(const oclMat &src, oclMat &dst);
+ //! calculates per-element bit-wise disjunction of two arrays
+ // supports all types
+ CV_EXPORTS void bitwise_or(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask = oclMat());
+ CV_EXPORTS void bitwise_or(const oclMat &src1, const Scalar &s, oclMat &dst, const oclMat &mask = oclMat());
+ //! calculates per-element bit-wise conjunction of two arrays
+ // supports all types
+ CV_EXPORTS void bitwise_and(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask = oclMat());
+ CV_EXPORTS void bitwise_and(const oclMat &src1, const Scalar &s, oclMat &dst, const oclMat &mask = oclMat());
+ //! calculates per-element bit-wise "exclusive or" operation
+ // supports all types
+ CV_EXPORTS void bitwise_xor(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask = oclMat());
+ CV_EXPORTS void bitwise_xor(const oclMat &src1, const Scalar &s, oclMat &dst, const oclMat &mask = oclMat());
+
+ //! Logical operators
+ CV_EXPORTS oclMat operator ~ (const oclMat &);
+ CV_EXPORTS oclMat operator | (const oclMat &, const oclMat &);
+ CV_EXPORTS oclMat operator & (const oclMat &, const oclMat &);
+ CV_EXPORTS oclMat operator ^ (const oclMat &, const oclMat &);
+
+
+ //! Mathematics operators
+ CV_EXPORTS oclMatExpr operator + (const oclMat &src1, const oclMat &src2);
+ CV_EXPORTS oclMatExpr operator - (const oclMat &src1, const oclMat &src2);
+ CV_EXPORTS oclMatExpr operator * (const oclMat &src1, const oclMat &src2);
+ CV_EXPORTS oclMatExpr operator / (const oclMat &src1, const oclMat &src2);
+
+ //! computes convolution of two images
+ //! support only CV_32FC1 type
+ CV_EXPORTS void convolve(const oclMat &image, const oclMat &temp1, oclMat &result);
+
+ CV_EXPORTS void cvtColor(const oclMat &src, oclMat &dst, int code , int dcn = 0);
+
+ //////////////////////////////// Filter Engine ////////////////////////////////
+
+ /*!
+ The Base Class for 1D or Row-wise Filters
+
+ This is the base class for linear or non-linear filters that process 1D data.
+ In particular, such filters are used for the "horizontal" filtering parts in separable filters.
+ */
+ class CV_EXPORTS BaseRowFilter_GPU
+ {
+ public:
+ BaseRowFilter_GPU(int ksize_, int anchor_, int bordertype_) : ksize(ksize_), anchor(anchor_), bordertype(bordertype_) {}
+ virtual ~BaseRowFilter_GPU() {}
+ virtual void operator()(const oclMat &src, oclMat &dst) = 0;
+ int ksize, anchor, bordertype;
+ };
+
+ /*!
+ The Base Class for Column-wise Filters
+
+ This is the base class for linear or non-linear filters that process columns of 2D arrays.
+ Such filters are used for the "vertical" filtering parts in separable filters.
+ */
+ class CV_EXPORTS BaseColumnFilter_GPU
+ {
+ public:
+ BaseColumnFilter_GPU(int ksize_, int anchor_, int bordertype_) : ksize(ksize_), anchor(anchor_), bordertype(bordertype_) {}
+ virtual ~BaseColumnFilter_GPU() {}
+ virtual void operator()(const oclMat &src, oclMat &dst) = 0;
+ int ksize, anchor, bordertype;
+ };
+
+ /*!
+ The Base Class for Non-Separable 2D Filters.
+
+ This is the base class for linear or non-linear 2D filters.
+ */
+ class CV_EXPORTS BaseFilter_GPU
+ {
+ public:
+ BaseFilter_GPU(const Size &ksize_, const Point &anchor_, const int &borderType_)
+ : ksize(ksize_), anchor(anchor_), borderType(borderType_) {}
+ virtual ~BaseFilter_GPU() {}
+ virtual void operator()(const oclMat &src, oclMat &dst) = 0;
+ Size ksize;
+ Point anchor;
+ int borderType;
+ };
+
+ /*!
+ The Base Class for Filter Engine.
+
+ The class can be used to apply an arbitrary filtering operation to an image.
+ It contains all the necessary intermediate buffers.
+ */
+ class CV_EXPORTS FilterEngine_GPU
+ {
+ public:
+ virtual ~FilterEngine_GPU() {}
+
+ virtual void apply(const oclMat &src, oclMat &dst, Rect roi = Rect(0, 0, -1, -1)) = 0;
+ };
+
+ //! returns the non-separable filter engine with the specified filter
+ CV_EXPORTS Ptr<FilterEngine_GPU> createFilter2D_GPU(const Ptr<BaseFilter_GPU> filter2D);
+
+ //! returns the primitive row filter with the specified kernel
+ CV_EXPORTS Ptr<BaseRowFilter_GPU> getLinearRowFilter_GPU(int srcType, int bufType, const Mat &rowKernel,
+ int anchor = -1, int bordertype = BORDER_DEFAULT);
+
+ //! returns the primitive column filter with the specified kernel
+ CV_EXPORTS Ptr<BaseColumnFilter_GPU> getLinearColumnFilter_GPU(int bufType, int dstType, const Mat &columnKernel,
+ int anchor = -1, int bordertype = BORDER_DEFAULT, double delta = 0.0);
+
+ //! returns the separable linear filter engine
+ CV_EXPORTS Ptr<FilterEngine_GPU> createSeparableLinearFilter_GPU(int srcType, int dstType, const Mat &rowKernel,
+ const Mat &columnKernel, const Point &anchor = Point(-1, -1), double delta = 0.0, int bordertype = BORDER_DEFAULT);
+
+ //! returns the separable filter engine with the specified filters
+ CV_EXPORTS Ptr<FilterEngine_GPU> createSeparableFilter_GPU(const Ptr<BaseRowFilter_GPU> &rowFilter,
+ const Ptr<BaseColumnFilter_GPU> &columnFilter);
+
+ //! returns the Gaussian filter engine
+ CV_EXPORTS Ptr<FilterEngine_GPU> createGaussianFilter_GPU(int type, Size ksize, double sigma1, double sigma2 = 0, int bordertype = BORDER_DEFAULT);
+
+ //! returns filter engine for the generalized Sobel operator
+ CV_EXPORTS Ptr<FilterEngine_GPU> createDerivFilter_GPU( int srcType, int dstType, int dx, int dy, int ksize, int borderType = BORDER_DEFAULT );
+
+ //! applies Laplacian operator to the image
+ // supports only ksize = 1 and ksize = 3 8UC1 8UC4 32FC1 32FC4 data type
+ CV_EXPORTS void Laplacian(const oclMat &src, oclMat &dst, int ddepth, int ksize = 1, double scale = 1);
+
+ //! returns 2D box filter
+ // supports CV_8UC1 and CV_8UC4 source type, dst type must be the same as source type
+ CV_EXPORTS Ptr<BaseFilter_GPU> getBoxFilter_GPU(int srcType, int dstType,
+ const Size &ksize, Point anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
+
+ //! returns box filter engine
+ CV_EXPORTS Ptr<FilterEngine_GPU> createBoxFilter_GPU(int srcType, int dstType, const Size &ksize,
+ const Point &anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
+
+ //! returns 2D filter with the specified kernel
+ // supports CV_8UC1 and CV_8UC4 types
+ CV_EXPORTS Ptr<BaseFilter_GPU> getLinearFilter_GPU(int srcType, int dstType, const Mat &kernel, const Size &ksize,
+ Point anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
+
+ //! returns the non-separable linear filter engine
+ CV_EXPORTS Ptr<FilterEngine_GPU> createLinearFilter_GPU(int srcType, int dstType, const Mat &kernel,
+ const Point &anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
+
+ //! smooths the image using the normalized box filter
+ // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
+ // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101,BORDER_WRAP
+ CV_EXPORTS void boxFilter(const oclMat &src, oclMat &dst, int ddepth, Size ksize,
+ Point anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
+
+ //! returns 2D morphological filter
+ //! only MORPH_ERODE and MORPH_DILATE are supported
+ // supports CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 types
+ // kernel must have CV_8UC1 type, one rows and cols == ksize.width * ksize.height
+ CV_EXPORTS Ptr<BaseFilter_GPU> getMorphologyFilter_GPU(int op, int type, const Mat &kernel, const Size &ksize,
+ Point anchor = Point(-1, -1));
+
+ //! returns morphological filter engine. Only MORPH_ERODE and MORPH_DILATE are supported.
+ CV_EXPORTS Ptr<FilterEngine_GPU> createMorphologyFilter_GPU(int op, int type, const Mat &kernel,
+ const Point &anchor = Point(-1, -1), int iterations = 1);
+
+ //! a synonym for normalized box filter
+ // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
+ // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101
+ static inline void blur(const oclMat &src, oclMat &dst, Size ksize, Point anchor = Point(-1, -1),
+ int borderType = BORDER_CONSTANT)
+ {
+ boxFilter(src, dst, -1, ksize, anchor, borderType);
+ }
+
+ //! applies non-separable 2D linear filter to the image
+ CV_EXPORTS void filter2D(const oclMat &src, oclMat &dst, int ddepth, const Mat &kernel,
+ Point anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
+
+ //! applies separable 2D linear filter to the image
+ CV_EXPORTS void sepFilter2D(const oclMat &src, oclMat &dst, int ddepth, const Mat &kernelX, const Mat &kernelY,
+ Point anchor = Point(-1, -1), double delta = 0.0, int bordertype = BORDER_DEFAULT);
+
+ //! applies generalized Sobel operator to the image
+ // dst.type must equalize src.type
+ // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
+ // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101
+ CV_EXPORTS void Sobel(const oclMat &src, oclMat &dst, int ddepth, int dx, int dy, int ksize = 3, double scale = 1, double delta = 0.0, int bordertype = BORDER_DEFAULT);
+
+ //! applies the vertical or horizontal Scharr operator to the image
+ // dst.type must equalize src.type
+ // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
+ // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101
+ CV_EXPORTS void Scharr(const oclMat &src, oclMat &dst, int ddepth, int dx, int dy, double scale = 1, double delta = 0.0, int bordertype = BORDER_DEFAULT);
+
+ //! smooths the image using Gaussian filter.
+ // dst.type must equalize src.type
+ // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
+ // supports border type: BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT,BORDER_REFLECT_101
+ CV_EXPORTS void GaussianBlur(const oclMat &src, oclMat &dst, Size ksize, double sigma1, double sigma2 = 0, int bordertype = BORDER_DEFAULT);
+
+ //! erodes the image (applies the local minimum operator)
+ // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
+ CV_EXPORTS void erode( const oclMat &src, oclMat &dst, const Mat &kernel, Point anchor = Point(-1, -1), int iterations = 1,
+
+ int borderType = BORDER_CONSTANT, const Scalar &borderValue = morphologyDefaultBorderValue());
+
+
+ //! dilates the image (applies the local maximum operator)
+ // supports data type: CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4
+ CV_EXPORTS void dilate( const oclMat &src, oclMat &dst, const Mat &kernel, Point anchor = Point(-1, -1), int iterations = 1,
+
+ int borderType = BORDER_CONSTANT, const Scalar &borderValue = morphologyDefaultBorderValue());
+
+
+ //! applies an advanced morphological operation to the image
+ CV_EXPORTS void morphologyEx( const oclMat &src, oclMat &dst, int op, const Mat &kernel, Point anchor = Point(-1, -1), int iterations = 1,
+
+ int borderType = BORDER_CONSTANT, const Scalar &borderValue = morphologyDefaultBorderValue());
+
+
+ ////////////////////////////// Image processing //////////////////////////////
+ //! Does mean shift filtering on GPU.
+ CV_EXPORTS void meanShiftFiltering(const oclMat &src, oclMat &dst, int sp, int sr,
+ TermCriteria criteria = TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 5, 1));
+
+ //! Does mean shift procedure on GPU.
+ CV_EXPORTS void meanShiftProc(const oclMat &src, oclMat &dstr, oclMat &dstsp, int sp, int sr,
+ TermCriteria criteria = TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 5, 1));
+
+ //! Does mean shift segmentation with elimiation of small regions.
+ CV_EXPORTS void meanShiftSegmentation(const oclMat &src, Mat &dst, int sp, int sr, int minsize,
+ TermCriteria criteria = TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 5, 1));
+
+ //! applies fixed threshold to the image.
+ // supports CV_8UC1 and CV_32FC1 data type
+ // supports threshold type: THRESH_BINARY, THRESH_BINARY_INV, THRESH_TRUNC, THRESH_TOZERO, THRESH_TOZERO_INV
+ CV_EXPORTS double threshold(const oclMat &src, oclMat &dst, double thresh, double maxVal, int type = THRESH_TRUNC);
+
+ //! resizes the image
+ // Supports INTER_NEAREST, INTER_LINEAR
+ // supports CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 types
+ CV_EXPORTS void resize(const oclMat &src, oclMat &dst, Size dsize, double fx = 0, double fy = 0, int interpolation = INTER_LINEAR);
+
+ //! Applies a generic geometrical transformation to an image.
+
+ // Supports INTER_NEAREST, INTER_LINEAR.
+
+ // Map1 supports CV_16SC2, CV_32FC2 types.
+
+ // Src supports CV_8UC1, CV_8UC2, CV_8UC4.
+
+ CV_EXPORTS void remap(const oclMat &src, oclMat &dst, oclMat &map1, oclMat &map2, int interpolation, int bordertype, const Scalar &value = Scalar());
+
+ //! copies 2D array to a larger destination array and pads borders with user-specifiable constant
+ // supports CV_8UC1, CV_8UC4, CV_32SC1 types
+ CV_EXPORTS void copyMakeBorder(const oclMat &src, oclMat &dst, int top, int bottom, int left, int right, int boardtype, const Scalar &value = Scalar());
+
+ //! Smoothes image using median filter
+ // The source 1- or 4-channel image. When m is 3 or 5, the image depth should be CV 8U or CV 32F.
+ CV_EXPORTS void medianFilter(const oclMat &src, oclMat &dst, int m);
+
+ //! warps the image using affine transformation
+ // Supports INTER_NEAREST, INTER_LINEAR, INTER_CUBIC
+ // supports CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 types
+ CV_EXPORTS void warpAffine(const oclMat &src, oclMat &dst, const Mat &M, Size dsize, int flags = INTER_LINEAR);
+
+ //! warps the image using perspective transformation
+ // Supports INTER_NEAREST, INTER_LINEAR, INTER_CUBIC
+ // supports CV_8UC1, CV_8UC4, CV_32FC1 and CV_32FC4 types
+ CV_EXPORTS void warpPerspective(const oclMat &src, oclMat &dst, const Mat &M, Size dsize, int flags = INTER_LINEAR);
+
+ //! computes the integral image and integral for the squared image
+ // sum will have CV_32S type, sqsum - CV32F type
+ // supports only CV_8UC1 source type
+ CV_EXPORTS void integral(const oclMat &src, oclMat &sum, oclMat &sqsum);
+ CV_EXPORTS void integral(const oclMat &src, oclMat &sum);
+ CV_EXPORTS void cornerHarris(const oclMat &src, oclMat &dst, int blockSize, int ksize, double k, int bordertype = cv::BORDER_DEFAULT);
+ CV_EXPORTS void cornerMinEigenVal(const oclMat &src, oclMat &dst, int blockSize, int ksize, int bordertype = cv::BORDER_DEFAULT);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////CascadeClassifier//////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ class CV_EXPORTS_W OclCascadeClassifier : public cv::CascadeClassifier
+ {
+ public:
+ OclCascadeClassifier() {};
+ ~OclCascadeClassifier() {};
+
+ CvSeq* oclHaarDetectObjects(oclMat &gimg, CvMemStorage *storage, double scaleFactor,
+ int minNeighbors, int flags, CvSize minSize = cvSize(0, 0), CvSize maxSize = cvSize(0, 0));
+ };
+
+
+
+ /////////////////////////////// Pyramid /////////////////////////////////////
+ CV_EXPORTS void pyrDown(const oclMat &src, oclMat &dst);
+
+ //! upsamples the source image and then smoothes it
+ CV_EXPORTS void pyrUp(const oclMat &src, oclMat &dst);
+
+ //! performs linear blending of two images
+ //! to avoid accuracy errors sum of weigths shouldn't be very close to zero
+ // supports only CV_8UC1 source type
+ CV_EXPORTS void blendLinear(const oclMat &img1, const oclMat &img2, const oclMat &weights1, const oclMat &weights2, oclMat &result);
+
+ //! computes vertical sum, supports only CV_32FC1 images
+ CV_EXPORTS void columnSum(const oclMat &src, oclMat &sum);
+
+ ///////////////////////////////////////// match_template /////////////////////////////////////////////////////////////
+ struct CV_EXPORTS MatchTemplateBuf
+ {
+ Size user_block_size;
+ oclMat imagef, templf;
+ std::vector<oclMat> images;
+ std::vector<oclMat> image_sums;
+ std::vector<oclMat> image_sqsums;
+ };
+
+
+ //! computes the proximity map for the raster template and the image where the template is searched for
+ // Supports TM_SQDIFF, TM_SQDIFF_NORMED, TM_CCORR, TM_CCORR_NORMED, TM_CCOEFF, TM_CCOEFF_NORMED for type 8UC1 and 8UC4
+ // Supports TM_SQDIFF, TM_CCORR for type 32FC1 and 32FC4
+ CV_EXPORTS void matchTemplate(const oclMat &image, const oclMat &templ, oclMat &result, int method);
+
+ //! computes the proximity map for the raster template and the image where the template is searched for
+ // Supports TM_SQDIFF, TM_SQDIFF_NORMED, TM_CCORR, TM_CCORR_NORMED, TM_CCOEFF, TM_CCOEFF_NORMED for type 8UC1 and 8UC4
+ // Supports TM_SQDIFF, TM_CCORR for type 32FC1 and 32FC4
+ CV_EXPORTS void matchTemplate(const oclMat &image, const oclMat &templ, oclMat &result, int method, MatchTemplateBuf &buf);
+
+
+
+ ///////////////////////////////////////////// Canny /////////////////////////////////////////////
+
+ struct CV_EXPORTS CannyBuf;
+
+
+
+ //! compute edges of the input image using Canny operator
+
+ // Support CV_8UC1 only
+
+ CV_EXPORTS void Canny(const oclMat &image, oclMat &edges, double low_thresh, double high_thresh, int apperture_size = 3, bool L2gradient = false);
+
+ CV_EXPORTS void Canny(const oclMat &image, CannyBuf &buf, oclMat &edges, double low_thresh, double high_thresh, int apperture_size = 3, bool L2gradient = false);
+
+ CV_EXPORTS void Canny(const oclMat &dx, const oclMat &dy, oclMat &edges, double low_thresh, double high_thresh, bool L2gradient = false);
+
+ CV_EXPORTS void Canny(const oclMat &dx, const oclMat &dy, CannyBuf &buf, oclMat &edges, double low_thresh, double high_thresh, bool L2gradient = false);
+
+
+
+ struct CV_EXPORTS CannyBuf
+
+ {
+
+ CannyBuf() : counter(NULL) {}
+
+ ~CannyBuf()
+ {
+ release();
+ }
+
+ explicit CannyBuf(const Size &image_size, int apperture_size = 3) : counter(NULL)
+
+ {
+
+ create(image_size, apperture_size);
+
+ }
+
+ CannyBuf(const oclMat &dx_, const oclMat &dy_);
+
+
+
+ void create(const Size &image_size, int apperture_size = 3);
+
+
+
+ void release();
+
+
+
+ oclMat dx, dy;
+
+ oclMat dx_buf, dy_buf;
+
+ oclMat edgeBuf;
+
+ oclMat trackBuf1, trackBuf2;
+
+ void *counter;
+
+ Ptr<FilterEngine_GPU> filterDX, filterDY;
+
+ };
+
+ ///////////////////////////////////////// Hough Transform /////////////////////////////////////////
+ //! HoughCircles
+ struct HoughCirclesBuf
+ {
+ oclMat edges;
+ oclMat accum;
+ oclMat srcPoints;
+ oclMat centers;
+ CannyBuf cannyBuf;
+ };
+
+ CV_EXPORTS void HoughCircles(const oclMat& src, oclMat& circles, int method, float dp, float minDist, int cannyThreshold, int votesThreshold, int minRadius, int maxRadius, int maxCircles = 4096);
+ CV_EXPORTS void HoughCircles(const oclMat& src, oclMat& circles, HoughCirclesBuf& buf, int method, float dp, float minDist, int cannyThreshold, int votesThreshold, int minRadius, int maxRadius, int maxCircles = 4096);
+ CV_EXPORTS void HoughCirclesDownload(const oclMat& d_circles, OutputArray h_circles);
+
+
+ ///////////////////////////////////////// clAmdFft related /////////////////////////////////////////
+ //! Performs a forward or inverse discrete Fourier transform (1D or 2D) of floating point matrix.
+ //! Param dft_size is the size of DFT transform.
+ //!
+ //! For complex-to-real transform it is assumed that the source matrix is packed in CLFFT's format.
+ // support src type of CV32FC1, CV32FC2
+ // support flags: DFT_INVERSE, DFT_REAL_OUTPUT, DFT_COMPLEX_OUTPUT, DFT_ROWS
+ // dft_size is the size of original input, which is used for transformation from complex to real.
+ // dft_size must be powers of 2, 3 and 5
+ // real to complex dft requires at least v1.8 clAmdFft
+ // real to complex dft output is not the same with cpu version
+ // real to complex and complex to real does not support DFT_ROWS
+ CV_EXPORTS void dft(const oclMat &src, oclMat &dst, Size dft_size = Size(0, 0), int flags = 0);
+
+ //! implements generalized matrix product algorithm GEMM from BLAS
+ // The functionality requires clAmdBlas library
+ // only support type CV_32FC1
+ // flag GEMM_3_T is not supported
+ CV_EXPORTS void gemm(const oclMat &src1, const oclMat &src2, double alpha,
+ const oclMat &src3, double beta, oclMat &dst, int flags = 0);
+
+ //////////////// HOG (Histogram-of-Oriented-Gradients) Descriptor and Object Detector //////////////
+
+ struct CV_EXPORTS HOGDescriptor
+
+ {
+
+ enum { DEFAULT_WIN_SIGMA = -1 };
+
+ enum { DEFAULT_NLEVELS = 64 };
+
+ enum { DESCR_FORMAT_ROW_BY_ROW, DESCR_FORMAT_COL_BY_COL };
+
+
+
+ HOGDescriptor(Size win_size = Size(64, 128), Size block_size = Size(16, 16),
+
+ Size block_stride = Size(8, 8), Size cell_size = Size(8, 8),
+
+ int nbins = 9, double win_sigma = DEFAULT_WIN_SIGMA,
+
+ double threshold_L2hys = 0.2, bool gamma_correction = true,
+
+ int nlevels = DEFAULT_NLEVELS);
+
+
+
+ size_t getDescriptorSize() const;
+
+ size_t getBlockHistogramSize() const;
+
+
+
+ void setSVMDetector(const std::vector<float> &detector);
+
+
+
+ static std::vector<float> getDefaultPeopleDetector();
+
+ static std::vector<float> getPeopleDetector48x96();
+
+ static std::vector<float> getPeopleDetector64x128();
+
+
+
+ void detect(const oclMat &img, std::vector<Point> &found_locations,
+
+ double hit_threshold = 0, Size win_stride = Size(),
+
+ Size padding = Size());
+
+
+
+ void detectMultiScale(const oclMat &img, std::vector<Rect> &found_locations,
+
+ double hit_threshold = 0, Size win_stride = Size(),
+
+ Size padding = Size(), double scale0 = 1.05,
+
+ int group_threshold = 2);
+
+
+
+ void getDescriptors(const oclMat &img, Size win_stride,
+
+ oclMat &descriptors,
+
+ int descr_format = DESCR_FORMAT_COL_BY_COL);
+
+
+
+ Size win_size;
+
+ Size block_size;
+
+ Size block_stride;
+
+ Size cell_size;
+
+ int nbins;
+
+ double win_sigma;
+
+ double threshold_L2hys;
+
+ bool gamma_correction;
+
+ int nlevels;
+
+
+
+ protected:
+
+ // initialize buffers; only need to do once in case of multiscale detection
+
+ void init_buffer(const oclMat &img, Size win_stride);
+
+
+
+ void computeBlockHistograms(const oclMat &img);
+
+ void computeGradient(const oclMat &img, oclMat &grad, oclMat &qangle);
+
+
+
+ double getWinSigma() const;
+
+ bool checkDetectorSize() const;
+
+
+
+ static int numPartsWithin(int size, int part_size, int stride);
+
+ static Size numPartsWithin(Size size, Size part_size, Size stride);
+
+
+
+ // Coefficients of the separating plane
+
+ float free_coef;
+
+ oclMat detector;
+
+
+
+ // Results of the last classification step
+
+ oclMat labels;
+
+ Mat labels_host;
+
+
+
+ // Results of the last histogram evaluation step
+
+ oclMat block_hists;
+
+
+
+ // Gradients conputation results
+
+ oclMat grad, qangle;
+
+
+
+ // scaled image
+
+ oclMat image_scale;
+
+
+
+ // effect size of input image (might be different from original size after scaling)
+
+ Size effect_size;
+
+ };
+
+
+ ////////////////////////feature2d_ocl/////////////////
+ /****************************************************************************************\
+ * Distance *
+ \****************************************************************************************/
+
+ template<typename T>
+ struct CV_EXPORTS Accumulator
+ {
+ typedef T Type;
+ };
+
+ template<> struct Accumulator<unsigned char>
+ {
+ typedef float Type;
+ };
+ template<> struct Accumulator<unsigned short>
+ {
+ typedef float Type;
+ };
+ template<> struct Accumulator<char>
+ {
+ typedef float Type;
+ };
+ template<> struct Accumulator<short>
+ {
+ typedef float Type;
+ };
+
+ /*
+ * Manhattan distance (city block distance) functor
+ */
+ template<class T>
+ struct CV_EXPORTS L1
+ {
+ enum { normType = NORM_L1 };
+ typedef T ValueType;
+ typedef typename Accumulator<T>::Type ResultType;
+
+ ResultType operator()( const T *a, const T *b, int size ) const
+ {
+ return normL1<ValueType, ResultType>(a, b, size);
+ }
+ };
+
+ /*
+ * Euclidean distance functor
+ */
+ template<class T>
+ struct CV_EXPORTS L2
+ {
+ enum { normType = NORM_L2 };
+ typedef T ValueType;
+ typedef typename Accumulator<T>::Type ResultType;
+
+ ResultType operator()( const T *a, const T *b, int size ) const
+ {
+ return (ResultType)std::sqrt((double)normL2Sqr<ValueType, ResultType>(a, b, size));
+ }
+ };
+
+ /*
+ * Hamming distance functor - counts the bit differences between two strings - useful for the Brief descriptor
+ * bit count of A exclusive XOR'ed with B
+ */
+ struct CV_EXPORTS Hamming
+ {
+ enum { normType = NORM_HAMMING };
+ typedef unsigned char ValueType;
+ typedef int ResultType;
+
+ /** this will count the bits in a ^ b
+ */
+ ResultType operator()( const unsigned char *a, const unsigned char *b, int size ) const
+ {
+ return normHamming(a, b, size);
+ }
+ };
+
+ ////////////////////////////////// BruteForceMatcher //////////////////////////////////
+
+ class CV_EXPORTS BruteForceMatcher_OCL_base
+ {
+ public:
+ enum DistType {L1Dist = 0, L2Dist, HammingDist};
+
+ explicit BruteForceMatcher_OCL_base(DistType distType = L2Dist);
+
+
+
+ // Add descriptors to train descriptor collection
+
+ void add(const std::vector<oclMat> &descCollection);
+
+
+
+ // Get train descriptors collection
+
+ const std::vector<oclMat> &getTrainDescriptors() const;
+
+
+
+ // Clear train descriptors collection
+
+ void clear();
+
+
+
+ // Return true if there are not train descriptors in collection
+
+ bool empty() const;
+
+
+
+ // Return true if the matcher supports mask in match methods
+
+ bool isMaskSupported() const;
+
+
+
+ // Find one best match for each query descriptor
+
+ void matchSingle(const oclMat &query, const oclMat &train,
+
+ oclMat &trainIdx, oclMat &distance,
+
+ const oclMat &mask = oclMat());
+
+
+
+ // Download trainIdx and distance and convert it to CPU vector with DMatch
+
+ static void matchDownload(const oclMat &trainIdx, const oclMat &distance, std::vector<DMatch> &matches);
+
+ // Convert trainIdx and distance to vector with DMatch
+
+ static void matchConvert(const Mat &trainIdx, const Mat &distance, std::vector<DMatch> &matches);
+
+
+
+ // Find one best match for each query descriptor
+
+ void match(const oclMat &query, const oclMat &train, std::vector<DMatch> &matches, const oclMat &mask = oclMat());
+
+
+
+ // Make gpu collection of trains and masks in suitable format for matchCollection function
+
+ void makeGpuCollection(oclMat &trainCollection, oclMat &maskCollection, const std::vector<oclMat> &masks = std::vector<oclMat>());
+
+
+
+ // Find one best match from train collection for each query descriptor
+
+ void matchCollection(const oclMat &query, const oclMat &trainCollection,
+
+ oclMat &trainIdx, oclMat &imgIdx, oclMat &distance,
+
+ const oclMat &masks = oclMat());
+
+
+
+ // Download trainIdx, imgIdx and distance and convert it to vector with DMatch
+
+ static void matchDownload(const oclMat &trainIdx, const oclMat &imgIdx, const oclMat &distance, std::vector<DMatch> &matches);
+
+ // Convert trainIdx, imgIdx and distance to vector with DMatch
+
+ static void matchConvert(const Mat &trainIdx, const Mat &imgIdx, const Mat &distance, std::vector<DMatch> &matches);
+
+
+
+ // Find one best match from train collection for each query descriptor.
+
+ void match(const oclMat &query, std::vector<DMatch> &matches, const std::vector<oclMat> &masks = std::vector<oclMat>());
+
+
+
+ // Find k best matches for each query descriptor (in increasing order of distances)
+
+ void knnMatchSingle(const oclMat &query, const oclMat &train,
+
+ oclMat &trainIdx, oclMat &distance, oclMat &allDist, int k,
+
+ const oclMat &mask = oclMat());
+
+
+
+ // Download trainIdx and distance and convert it to vector with DMatch
+
+ // compactResult is used when mask is not empty. If compactResult is false matches
+
+ // vector will have the same size as queryDescriptors rows. If compactResult is true
+
+ // matches vector will not contain matches for fully masked out query descriptors.
+
+ static void knnMatchDownload(const oclMat &trainIdx, const oclMat &distance,
+
+ std::vector< std::vector<DMatch> > &matches, bool compactResult = false);
+
+ // Convert trainIdx and distance to vector with DMatch
+
+ static void knnMatchConvert(const Mat &trainIdx, const Mat &distance,
+
+ std::vector< std::vector<DMatch> > &matches, bool compactResult = false);
+
+
+
+ // Find k best matches for each query descriptor (in increasing order of distances).
+
+ // compactResult is used when mask is not empty. If compactResult is false matches
+
+ // vector will have the same size as queryDescriptors rows. If compactResult is true
+
+ // matches vector will not contain matches for fully masked out query descriptors.
+
+ void knnMatch(const oclMat &query, const oclMat &train,
+
+ std::vector< std::vector<DMatch> > &matches, int k, const oclMat &mask = oclMat(),
+
+ bool compactResult = false);
+
+
+
+ // Find k best matches from train collection for each query descriptor (in increasing order of distances)
+
+ void knnMatch2Collection(const oclMat &query, const oclMat &trainCollection,
+
+ oclMat &trainIdx, oclMat &imgIdx, oclMat &distance,
+
+ const oclMat &maskCollection = oclMat());
+
+
+
+ // Download trainIdx and distance and convert it to vector with DMatch
+
+ // compactResult is used when mask is not empty. If compactResult is false matches
+
+ // vector will have the same size as queryDescriptors rows. If compactResult is true
+
+ // matches vector will not contain matches for fully masked out query descriptors.
+
+ static void knnMatch2Download(const oclMat &trainIdx, const oclMat &imgIdx, const oclMat &distance,
+
+ std::vector< std::vector<DMatch> > &matches, bool compactResult = false);
+
+ // Convert trainIdx and distance to vector with DMatch
+
+ static void knnMatch2Convert(const Mat &trainIdx, const Mat &imgIdx, const Mat &distance,
+
+ std::vector< std::vector<DMatch> > &matches, bool compactResult = false);
+
+
+
+ // Find k best matches for each query descriptor (in increasing order of distances).
+
+ // compactResult is used when mask is not empty. If compactResult is false matches
+
+ // vector will have the same size as queryDescriptors rows. If compactResult is true
+
+ // matches vector will not contain matches for fully masked out query descriptors.
+
+ void knnMatch(const oclMat &query, std::vector< std::vector<DMatch> > &matches, int k,
+
+ const std::vector<oclMat> &masks = std::vector<oclMat>(), bool compactResult = false);
+
+
+
+ // Find best matches for each query descriptor which have distance less than maxDistance.
+
+ // nMatches.at<int>(0, queryIdx) will contain matches count for queryIdx.
+
+ // carefully nMatches can be greater than trainIdx.cols - it means that matcher didn't find all matches,
+
+ // because it didn't have enough memory.
+
+ // If trainIdx is empty, then trainIdx and distance will be created with size nQuery x max((nTrain / 100), 10),
+
+ // otherwize user can pass own allocated trainIdx and distance with size nQuery x nMaxMatches
+
+ // Matches doesn't sorted.
+
+ void radiusMatchSingle(const oclMat &query, const oclMat &train,
+
+ oclMat &trainIdx, oclMat &distance, oclMat &nMatches, float maxDistance,
+
+ const oclMat &mask = oclMat());
+
+
+
+ // Download trainIdx, nMatches and distance and convert it to vector with DMatch.
+
+ // matches will be sorted in increasing order of distances.
+
+ // compactResult is used when mask is not empty. If compactResult is false matches
+
+ // vector will have the same size as queryDescriptors rows. If compactResult is true
+
+ // matches vector will not contain matches for fully masked out query descriptors.
+
+ static void radiusMatchDownload(const oclMat &trainIdx, const oclMat &distance, const oclMat &nMatches,
+
+ std::vector< std::vector<DMatch> > &matches, bool compactResult = false);
+
+ // Convert trainIdx, nMatches and distance to vector with DMatch.
+
+ static void radiusMatchConvert(const Mat &trainIdx, const Mat &distance, const Mat &nMatches,
+
+ std::vector< std::vector<DMatch> > &matches, bool compactResult = false);
+
+
+
+ // Find best matches for each query descriptor which have distance less than maxDistance
+
+ // in increasing order of distances).
+
+ void radiusMatch(const oclMat &query, const oclMat &train,
+
+ std::vector< std::vector<DMatch> > &matches, float maxDistance,
+
+ const oclMat &mask = oclMat(), bool compactResult = false);
+
+
+
+ // Find best matches for each query descriptor which have distance less than maxDistance.
+
+ // If trainIdx is empty, then trainIdx and distance will be created with size nQuery x max((nQuery / 100), 10),
+
+ // otherwize user can pass own allocated trainIdx and distance with size nQuery x nMaxMatches
+
+ // Matches doesn't sorted.
+
+ void radiusMatchCollection(const oclMat &query, oclMat &trainIdx, oclMat &imgIdx, oclMat &distance, oclMat &nMatches, float maxDistance,
+
+ const std::vector<oclMat> &masks = std::vector<oclMat>());
+
+
+
+ // Download trainIdx, imgIdx, nMatches and distance and convert it to vector with DMatch.
+
+ // matches will be sorted in increasing order of distances.
+
+ // compactResult is used when mask is not empty. If compactResult is false matches
+
+ // vector will have the same size as queryDescriptors rows. If compactResult is true
+
+ // matches vector will not contain matches for fully masked out query descriptors.
+
+ static void radiusMatchDownload(const oclMat &trainIdx, const oclMat &imgIdx, const oclMat &distance, const oclMat &nMatches,
+
+ std::vector< std::vector<DMatch> > &matches, bool compactResult = false);
+
+ // Convert trainIdx, nMatches and distance to vector with DMatch.
+
+ static void radiusMatchConvert(const Mat &trainIdx, const Mat &imgIdx, const Mat &distance, const Mat &nMatches,
+
+ std::vector< std::vector<DMatch> > &matches, bool compactResult = false);
+
+
+
+ // Find best matches from train collection for each query descriptor which have distance less than
+
+ // maxDistance (in increasing order of distances).
+
+ void radiusMatch(const oclMat &query, std::vector< std::vector<DMatch> > &matches, float maxDistance,
+
+ const std::vector<oclMat> &masks = std::vector<oclMat>(), bool compactResult = false);
+
+
+
+ DistType distType;
+
+
+
+ private:
+
+ std::vector<oclMat> trainDescCollection;
+
+ };
+
+
+
+ template <class Distance>
+
+ class CV_EXPORTS BruteForceMatcher_OCL;
+
+
+
+ template <typename T>
+
+ class CV_EXPORTS BruteForceMatcher_OCL< L1<T> > : public BruteForceMatcher_OCL_base
+
+ {
+
+ public:
+
+ explicit BruteForceMatcher_OCL() : BruteForceMatcher_OCL_base(L1Dist) {}
+
+ explicit BruteForceMatcher_OCL(L1<T> /*d*/) : BruteForceMatcher_OCL_base(L1Dist) {}
+
+ };
+
+ template <typename T>
+
+ class CV_EXPORTS BruteForceMatcher_OCL< L2<T> > : public BruteForceMatcher_OCL_base
+
+ {
+
+ public:
+
+ explicit BruteForceMatcher_OCL() : BruteForceMatcher_OCL_base(L2Dist) {}
+
+ explicit BruteForceMatcher_OCL(L2<T> /*d*/) : BruteForceMatcher_OCL_base(L2Dist) {}
+
+ };
+
+ template <> class CV_EXPORTS BruteForceMatcher_OCL< Hamming > : public BruteForceMatcher_OCL_base
+
+ {
+
+ public:
+
+ explicit BruteForceMatcher_OCL() : BruteForceMatcher_OCL_base(HammingDist) {}
+
+ explicit BruteForceMatcher_OCL(Hamming /*d*/) : BruteForceMatcher_OCL_base(HammingDist) {}
+
+ };
+
+
+
+ /////////////////////////////// PyrLKOpticalFlow /////////////////////////////////////
+
+ class CV_EXPORTS PyrLKOpticalFlow
+
+ {
+
+ public:
+
+ PyrLKOpticalFlow()
+
+ {
+
+ winSize = Size(21, 21);
+
+ maxLevel = 3;
+
+ iters = 30;
+
+ derivLambda = 0.5;
+
+ useInitialFlow = false;
+
+ minEigThreshold = 1e-4f;
+
+ getMinEigenVals = false;
+
+ isDeviceArch11_ = false;
+
+ }
+
+
+
+ void sparse(const oclMat &prevImg, const oclMat &nextImg, const oclMat &prevPts, oclMat &nextPts,
+
+ oclMat &status, oclMat *err = 0);
+
+
+
+ void dense(const oclMat &prevImg, const oclMat &nextImg, oclMat &u, oclMat &v, oclMat *err = 0);
+
+
+
+ Size winSize;
+
+ int maxLevel;
+
+ int iters;
+
+ double derivLambda;
+
+ bool useInitialFlow;
+
+ float minEigThreshold;
+
+ bool getMinEigenVals;
+
+
+
+ void releaseMemory()
+
+ {
+
+ dx_calcBuf_.release();
+
+ dy_calcBuf_.release();
+
+
+
+ prevPyr_.clear();
+
+ nextPyr_.clear();
+
+
+
+ dx_buf_.release();
+
+ dy_buf_.release();
+
+ }
+
+
+
+ private:
+
+ void calcSharrDeriv(const oclMat &src, oclMat &dx, oclMat &dy);
+
+
+
+ void buildImagePyramid(const oclMat &img0, std::vector<oclMat> &pyr, bool withBorder);
+
+
+
+ oclMat dx_calcBuf_;
+
+ oclMat dy_calcBuf_;
+
+
+
+ std::vector<oclMat> prevPyr_;
+
+ std::vector<oclMat> nextPyr_;
+
+
+
+ oclMat dx_buf_;
+
+ oclMat dy_buf_;
+
+
+
+ oclMat uPyr_[2];
+
+ oclMat vPyr_[2];
+
+
+
+ bool isDeviceArch11_;
+
+ };
+ //////////////// build warping maps ////////////////////
+ //! builds plane warping maps
+ CV_EXPORTS void buildWarpPlaneMaps(Size src_size, Rect dst_roi, const Mat &K, const Mat &R, const Mat &T, float scale, oclMat &map_x, oclMat &map_y);
+ //! builds cylindrical warping maps
+ CV_EXPORTS void buildWarpCylindricalMaps(Size src_size, Rect dst_roi, const Mat &K, const Mat &R, float scale, oclMat &map_x, oclMat &map_y);
+ //! builds spherical warping maps
+ CV_EXPORTS void buildWarpSphericalMaps(Size src_size, Rect dst_roi, const Mat &K, const Mat &R, float scale, oclMat &map_x, oclMat &map_y);
+ //! builds Affine warping maps
+ CV_EXPORTS void buildWarpAffineMaps(const Mat &M, bool inverse, Size dsize, oclMat &xmap, oclMat &ymap);
+
+ //! builds Perspective warping maps
+ CV_EXPORTS void buildWarpPerspectiveMaps(const Mat &M, bool inverse, Size dsize, oclMat &xmap, oclMat &ymap);
+
+ ///////////////////////////////////// interpolate frames //////////////////////////////////////////////
+ //! Interpolate frames (images) using provided optical flow (displacement field).
+ //! frame0 - frame 0 (32-bit floating point images, single channel)
+ //! frame1 - frame 1 (the same type and size)
+ //! fu - forward horizontal displacement
+ //! fv - forward vertical displacement
+ //! bu - backward horizontal displacement
+ //! bv - backward vertical displacement
+ //! pos - new frame position
+ //! newFrame - new frame
+ //! buf - temporary buffer, will have width x 6*height size, CV_32FC1 type and contain 6 oclMat;
+ //! occlusion masks 0, occlusion masks 1,
+ //! interpolated forward flow 0, interpolated forward flow 1,
+ //! interpolated backward flow 0, interpolated backward flow 1
+ //!
+ CV_EXPORTS void interpolateFrames(const oclMat &frame0, const oclMat &frame1,
+ const oclMat &fu, const oclMat &fv,
+ const oclMat &bu, const oclMat &bv,
+ float pos, oclMat &newFrame, oclMat &buf);
+
+ //! computes moments of the rasterized shape or a vector of points
+ CV_EXPORTS Moments ocl_moments(InputArray _array, bool binaryImage);
+
+ class CV_EXPORTS StereoBM_OCL
+ {
+ public:
+ enum { BASIC_PRESET = 0, PREFILTER_XSOBEL = 1 };
+
+ enum { DEFAULT_NDISP = 64, DEFAULT_WINSZ = 19 };
+
+ //! the default constructor
+ StereoBM_OCL();
+ //! the full constructor taking the camera-specific preset, number of disparities and the SAD window size. ndisparities must be multiple of 8.
+ StereoBM_OCL(int preset, int ndisparities = DEFAULT_NDISP, int winSize = DEFAULT_WINSZ);
+
+ //! the stereo correspondence operator. Finds the disparity for the specified rectified stereo pair
+ //! Output disparity has CV_8U type.
+ void operator() ( const oclMat &left, const oclMat &right, oclMat &disparity);
+
+ //! Some heuristics that tries to estmate
+ // if current GPU will be faster then CPU in this algorithm.
+ // It queries current active device.
+ static bool checkIfGpuCallReasonable();
+
+ int preset;
+ int ndisp;
+ int winSize;
+
+ // If avergeTexThreshold == 0 => post procesing is disabled
+ // If avergeTexThreshold != 0 then disparity is set 0 in each point (x,y) where for left image
+ // SumOfHorizontalGradiensInWindow(x, y, winSize) < (winSize * winSize) * avergeTexThreshold
+ // i.e. input left image is low textured.
+ float avergeTexThreshold;
+ private:
+ oclMat minSSD, leBuf, riBuf;
+ };
++ class CV_EXPORTS StereoBeliefPropagation
++ {
++ public:
++ enum { DEFAULT_NDISP = 64 };
++ enum { DEFAULT_ITERS = 5 };
++ enum { DEFAULT_LEVELS = 5 };
++ static void estimateRecommendedParams(int width, int height, int &ndisp, int &iters, int &levels);
++ explicit StereoBeliefPropagation(int ndisp = DEFAULT_NDISP,
++ int iters = DEFAULT_ITERS,
++ int levels = DEFAULT_LEVELS,
++ int msg_type = CV_16S);
++ StereoBeliefPropagation(int ndisp, int iters, int levels,
++ float max_data_term, float data_weight,
++ float max_disc_term, float disc_single_jump,
++ int msg_type = CV_32F);
++ void operator()(const oclMat &left, const oclMat &right, oclMat &disparity);
++ void operator()(const oclMat &data, oclMat &disparity);
++ int ndisp;
++ int iters;
++ int levels;
++ float max_data_term;
++ float data_weight;
++ float max_disc_term;
++ float disc_single_jump;
++ int msg_type;
++ private:
++ oclMat u, d, l, r, u2, d2, l2, r2;
++ std::vector<oclMat> datas;
++ oclMat out;
++ };
+ }
+}
+#if defined _MSC_VER && _MSC_VER >= 1200
+# pragma warning( push)
+# pragma warning( disable: 4267)
+#endif
+#include "opencv2/ocl/matrix_operations.hpp"
+#if defined _MSC_VER && _MSC_VER >= 1200
+# pragma warning( pop)
+#endif
+
+#endif /* __OPENCV_OCL_HPP__ */
#include "precomp.hpp"
- #ifdef HAVE_OPENCL
+ int main(int argc, const char *argv[])
+ {
+ vector<ocl::Info> oclinfo;
+ int num_devices = getDevice(oclinfo);
- using namespace std;
- using namespace cv;
- using namespace cv::ocl;
- using namespace cvtest;
- using namespace testing;
+ if (num_devices < 1)
+ {
+ cerr << "no device found\n";
+ return -1;
+ }
+
+ int devidx = 0;
+
+ for (size_t i = 0; i < oclinfo.size(); i++)
+ {
+ for (size_t j = 0; j < oclinfo[i].DeviceName.size(); j++)
+ {
+ printf("device %d: %s\n", devidx++, oclinfo[i].DeviceName[j].c_str());
+ }
+ }
+
+ redirectError(cvErrorCallback);
- void print_info()
- {
- printf("\n");
- #if defined _WIN32
- # if defined _WIN64
- puts("OS: Windows 64");
- # else
- puts("OS: Windows 32");
- # endif
- #elif defined linux
- # if defined _LP64
- puts("OS: Linux 64");
- # else
- puts("OS: Linux 32");
- # endif
- #elif defined __APPLE__
- # if defined _LP64
- puts("OS: Apple 64");
- # else
- puts("OS: Apple 32");
- # endif
- #endif
-
- }
- std::string workdir;
- int main(int argc, char **argv)
- {
- TS::ptr()->init("ocl");
- InitGoogleTest(&argc, argv);
const char *keys =
- "{ h | false | print help message }"
- "{ w | ../../../samples/c/| set working directory i.e. -w=C:\\}"
- "{ t | gpu | set device type:i.e. -t=cpu or gpu}"
- "{ p | 0 | set platform id i.e. -p=0}"
- "{ d | 0 | set device id i.e. -d=0}";
- "{ h | help | false | print help message }"
- "{ f | filter | | filter for test }"
- "{ w | workdir | | set working directory }"
- "{ l | list | false | show all tests }"
- "{ d | device | 0 | device id }"
- "{ i | iters | 10 | iteration count }"
- "{ m | warmup | 1 | gpu warm up iteration count}"
- "{ t | xtop | 1.1 | xfactor top boundary}"
- "{ b | xbottom | 0.9 | xfactor bottom boundary}"
- "{ v | verify | false | only run gpu once to verify if problems occur}";
++ "{ h help | false | print help message }"
++ "{ f filter | | filter for test }"
++ "{ w workdir | | set working directory }"
++ "{ l list | false | show all tests }"
++ "{ d device | 0 | device id }"
++ "{ i iters | 10 | iteration count }"
++ "{ m warmup | 1 | gpu warm up iteration count}"
++ "{ t xtop | 1.1 | xfactor top boundary}"
++ "{ b xbottom | 0.9 | xfactor bottom boundary}"
++ "{ v verify | false | only run gpu once to verify if problems occur}";
CommandLineParser cmd(argc, argv, keys);
- if (cmd.get<string>("h")=="true")
+
- if (cmd.get<bool>("help"))
++ if (cmd.has("help"))
{
- cout << "Avaible options besides goole test option:" << endl;
+ cout << "Avaible options:" << endl;
- cmd.printParams();
+ cmd.printMessage();
return 0;
}
- workdir = cmd.get<string>("w");
- string type = cmd.get<string>("t");
- unsigned int pid = cmd.get<unsigned int>("p");
- int device = cmd.get<int>("d");
- print_info();
- // int flag = CVCL_DEVICE_TYPE_GPU;
-
- // if(type == "cpu")
- // {
- // flag = CVCL_DEVICE_TYPE_CPU;
- // }
- std::vector<cv::ocl::Info> oclinfo;
- int devnums = getDevice(oclinfo);
- if(devnums <= device || device < 0)
+
+ int device = cmd.get<int>("device");
+
+ if (device < 0 || device >= num_devices)
{
- std::cout << "device invalid\n";
+ cerr << "Invalid device ID" << endl;
return -1;
}
- if(pid >= oclinfo.size())
+ if (cmd.get<bool>("verify"))
{
- std::cout << "platform invalid\n";
- return -1;
+ TestSystem::instance().setNumIters(1);
+ TestSystem::instance().setGPUWarmupIters(0);
+ TestSystem::instance().setCPUIters(0);
}
- if(pid != 0 || device != 0)
+ devidx = 0;
+
+ for (size_t i = 0; i < oclinfo.size(); i++)
{
- setDevice(oclinfo[pid], device);
+ for (size_t j = 0; j < oclinfo[i].DeviceName.size(); j++, devidx++)
+ {
+ if (device == devidx)
+ {
+ ocl::setDevice(oclinfo[i], (int)j);
+ TestSystem::instance().setRecordName(oclinfo[i].DeviceName[j]);
+ printf("\nuse %d: %s\n", devidx, oclinfo[i].DeviceName[j].c_str());
+ goto END_DEV;
+ }
+ }
}
- cout << "Device type:" << type << endl << "Device name:" << oclinfo[pid].DeviceName[device] << endl;
- setBinpath(CLBINPATH);
- return RUN_ALL_TESTS();
- }
+ END_DEV:
- #else // DON'T HAVE_OPENCL
+ string filter = cmd.get<string>("filter");
+ string workdir = cmd.get<string>("workdir");
- bool list = cmd.get<bool>("list");
++ bool list = cmd.has("list");
+ int iters = cmd.get<int>("iters");
+ int wu_iters = cmd.get<int>("warmup");
+ double x_top = cmd.get<double>("xtop");
+ double x_bottom = cmd.get<double>("xbottom");
- int main()
- {
- printf("OpenCV was built without OpenCL support\n");
- return 0;
- }
+ TestSystem::instance().setTopThreshold(x_top);
+ TestSystem::instance().setBottomThreshold(x_bottom);
+
+ if (!filter.empty())
+ {
+ TestSystem::instance().setTestFilter(filter);
+ }
+
+ if (!workdir.empty())
+ {
+ if (workdir[workdir.size() - 1] != '/' && workdir[workdir.size() - 1] != '\\')
+ {
+ workdir += '/';
+ }
+
+ TestSystem::instance().setWorkingDir(workdir);
+ }
+
+ if (list)
+ {
+ TestSystem::instance().setListMode(true);
+ }
+ TestSystem::instance().setNumIters(iters);
+ TestSystem::instance().setGPUWarmupIters(wu_iters);
- #endif // HAVE_OPENCL
+ TestSystem::instance().run();
+
+ return 0;
+ }
#include "precomp.hpp"
- if(msg != "CL_INVALID_BUFFER_SIZE")
- {
- cout << TAB << "[error: " << msg << "] " << cur_subtest_description_.str() << endl;
- }
+ // This program test most of the functions in ocl module and generate data metrix of x-factor in .csv files
+ // All images needed in this test are in samples/gpu folder.
+ // For haar template, haarcascade_frontalface_alt.xml shouold be in working directory
+ void TestSystem::run()
+ {
+ if (is_list_mode_)
+ {
+ for (vector<Runnable *>::iterator it = tests_.begin(); it != tests_.end(); ++it)
+ {
+ cout << (*it)->name() << endl;
+ }
+
+ return;
+ }
+
+ // Run test initializers
+ for (vector<Runnable *>::iterator it = inits_.begin(); it != inits_.end(); ++it)
+ {
+ if ((*it)->name().find(test_filter_, 0) != string::npos)
+ {
+ (*it)->run();
+ }
+ }
+
+ printHeading();
+ writeHeading();
+
+ // Run tests
+ for (vector<Runnable *>::iterator it = tests_.begin(); it != tests_.end(); ++it)
+ {
+ try
+ {
+ if ((*it)->name().find(test_filter_, 0) != string::npos)
+ {
+ cout << endl << (*it)->name() << ":\n";
+
+ setCurrentTest((*it)->name());
+ //fprintf(record_,"%s\n",(*it)->name().c_str());
+
+ (*it)->run();
+ finishCurrentSubtest();
+ }
+ }
+ catch (const Exception &)
+ {
+ // Message is printed via callback
+ resetCurrentSubtest();
+ }
+ catch (const runtime_error &e)
+ {
+ printError(e.what());
+ resetCurrentSubtest();
+ }
+ }
+
+ printSummary();
+ writeSummary();
+ }
+
+
+ void TestSystem::finishCurrentSubtest()
+ {
+ if (cur_subtest_is_empty_)
+ // There is no need to print subtest statistics
+ {
+ return;
+ }
+
+ double cpu_time = cpu_elapsed_ / getTickFrequency() * 1000.0;
+ double gpu_time = gpu_elapsed_ / getTickFrequency() * 1000.0;
+ double gpu_full_time = gpu_full_elapsed_ / getTickFrequency() * 1000.0;
+
+ double speedup = static_cast<double>(cpu_elapsed_) / std::max(1.0, gpu_elapsed_);
+ speedup_total_ += speedup;
+
+ double fullspeedup = static_cast<double>(cpu_elapsed_) / std::max(1.0, gpu_full_elapsed_);
+ speedup_full_total_ += fullspeedup;
+
+ if (speedup > top_)
+ {
+ speedup_faster_count_++;
+ }
+ else if (speedup < bottom_)
+ {
+ speedup_slower_count_++;
+ }
+ else
+ {
+ speedup_equal_count_++;
+ }
+
+ if (fullspeedup > top_)
+ {
+ speedup_full_faster_count_++;
+ }
+ else if (fullspeedup < bottom_)
+ {
+ speedup_full_slower_count_++;
+ }
+ else
+ {
+ speedup_full_equal_count_++;
+ }
+
+ // compute min, max and
+ std::sort(gpu_times_.begin(), gpu_times_.end());
+ double gpu_min = gpu_times_.front() / getTickFrequency() * 1000.0;
+ double gpu_max = gpu_times_.back() / getTickFrequency() * 1000.0;
+ double deviation = 0;
+
+ if (gpu_times_.size() > 1)
+ {
+ double sum = 0;
+
+ for (size_t i = 0; i < gpu_times_.size(); i++)
+ {
+ int64 diff = gpu_times_[i] - static_cast<int64>(gpu_elapsed_);
+ double diff_time = diff * 1000 / getTickFrequency();
+ sum += diff_time * diff_time;
+ }
+
+ deviation = std::sqrt(sum / gpu_times_.size());
+ }
+
+ printMetrics(cpu_time, gpu_time, gpu_full_time, speedup, fullspeedup);
+ writeMetrics(cpu_time, gpu_time, gpu_full_time, speedup, fullspeedup, gpu_min, gpu_max, deviation);
+
+ num_subtests_called_++;
+ resetCurrentSubtest();
+ }
+
+
+ double TestSystem::meanTime(const vector<int64> &samples)
+ {
+ double sum = accumulate(samples.begin(), samples.end(), 0.);
+ return sum / samples.size();
+ }
+
+
+ void TestSystem::printHeading()
+ {
+ cout << endl;
+ cout << setiosflags(ios_base::left);
+ cout << TAB << setw(10) << "CPU, ms" << setw(10) << "GPU, ms"
+ << setw(14) << "SPEEDUP" << setw(14) << "GPUTOTAL, ms" << setw(14) << "TOTALSPEEDUP"
+ << "DESCRIPTION\n";
+
+ cout << resetiosflags(ios_base::left);
+ }
+
+ void TestSystem::writeHeading()
+ {
+ if (!record_)
+ {
+ recordname_ += "_OCL.csv";
+ record_ = fopen(recordname_.c_str(), "w");
+ }
+
+ fprintf(record_, "NAME,DESCRIPTION,CPU (ms),GPU (ms),SPEEDUP,GPUTOTAL (ms),TOTALSPEEDUP,GPU Min (ms),GPU Max (ms), Standard deviation (ms)\n");
+
+ fflush(record_);
+ }
+
+ void TestSystem::printSummary()
+ {
+ cout << setiosflags(ios_base::fixed);
+ cout << "\naverage GPU speedup: x"
+ << setprecision(3) << speedup_total_ / std::max(1, num_subtests_called_)
+ << endl;
+ cout << "\nGPU exceeded: "
+ << setprecision(3) << speedup_faster_count_
+ << "\nGPU passed: "
+ << setprecision(3) << speedup_equal_count_
+ << "\nGPU failed: "
+ << setprecision(3) << speedup_slower_count_
+ << endl;
+ cout << "\nGPU exceeded rate: "
+ << setprecision(3) << (float)speedup_faster_count_ / std::max(1, num_subtests_called_) * 100
+ << "%"
+ << "\nGPU passed rate: "
+ << setprecision(3) << (float)speedup_equal_count_ / std::max(1, num_subtests_called_) * 100
+ << "%"
+ << "\nGPU failed rate: "
+ << setprecision(3) << (float)speedup_slower_count_ / std::max(1, num_subtests_called_) * 100
+ << "%"
+ << endl;
+ cout << "\naverage GPUTOTAL speedup: x"
+ << setprecision(3) << speedup_full_total_ / std::max(1, num_subtests_called_)
+ << endl;
+ cout << "\nGPUTOTAL exceeded: "
+ << setprecision(3) << speedup_full_faster_count_
+ << "\nGPUTOTAL passed: "
+ << setprecision(3) << speedup_full_equal_count_
+ << "\nGPUTOTAL failed: "
+ << setprecision(3) << speedup_full_slower_count_
+ << endl;
+ cout << "\nGPUTOTAL exceeded rate: "
+ << setprecision(3) << (float)speedup_full_faster_count_ / std::max(1, num_subtests_called_) * 100
+ << "%"
+ << "\nGPUTOTAL passed rate: "
+ << setprecision(3) << (float)speedup_full_equal_count_ / std::max(1, num_subtests_called_) * 100
+ << "%"
+ << "\nGPUTOTAL failed rate: "
+ << setprecision(3) << (float)speedup_full_slower_count_ / std::max(1, num_subtests_called_) * 100
+ << "%"
+ << endl;
+ cout << resetiosflags(ios_base::fixed);
+ }
+
+
+ void TestSystem::printMetrics(double cpu_time, double gpu_time, double gpu_full_time, double speedup, double fullspeedup)
+ {
+ cout << TAB << setiosflags(ios_base::left);
+ stringstream stream;
+
+ stream << cpu_time;
+ cout << setw(10) << stream.str();
+
+ stream.str("");
+ stream << gpu_time;
+ cout << setw(10) << stream.str();
+
+ stream.str("");
+ stream << "x" << setprecision(3) << speedup;
+ cout << setw(14) << stream.str();
+
+ stream.str("");
+ stream << gpu_full_time;
+ cout << setw(14) << stream.str();
+
+ stream.str("");
+ stream << "x" << setprecision(3) << fullspeedup;
+ cout << setw(14) << stream.str();
+
+ cout << cur_subtest_description_.str();
+ cout << resetiosflags(ios_base::left) << endl;
+ }
+
+ void TestSystem::writeMetrics(double cpu_time, double gpu_time, double gpu_full_time, double speedup, double fullspeedup, double gpu_min, double gpu_max, double std_dev)
+ {
+ if (!record_)
+ {
+ recordname_ += ".csv";
+ record_ = fopen(recordname_.c_str(), "w");
+ }
+
+ fprintf(record_, "%s,%s,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f\n", itname_changed_ ? itname_.c_str() : "",
+ cur_subtest_description_.str().c_str(),
+ cpu_time, gpu_time, speedup, gpu_full_time, fullspeedup,
+ gpu_min, gpu_max, std_dev);
+
+ if (itname_changed_)
+ {
+ itname_changed_ = false;
+ }
+
+ fflush(record_);
+ }
+
+ void TestSystem::writeSummary()
+ {
+ if (!record_)
+ {
+ recordname_ += ".csv";
+ record_ = fopen(recordname_.c_str(), "w");
+ }
+
+ fprintf(record_, "\nAverage GPU speedup: %.3f\n"
+ "exceeded: %d (%.3f%%)\n"
+ "passed: %d (%.3f%%)\n"
+ "failed: %d (%.3f%%)\n"
+ "\nAverage GPUTOTAL speedup: %.3f\n"
+ "exceeded: %d (%.3f%%)\n"
+ "passed: %d (%.3f%%)\n"
+ "failed: %d (%.3f%%)\n",
+ speedup_total_ / std::max(1, num_subtests_called_),
+ speedup_faster_count_, (float)speedup_faster_count_ / std::max(1, num_subtests_called_) * 100,
+ speedup_equal_count_, (float)speedup_equal_count_ / std::max(1, num_subtests_called_) * 100,
+ speedup_slower_count_, (float)speedup_slower_count_ / std::max(1, num_subtests_called_) * 100,
+ speedup_full_total_ / std::max(1, num_subtests_called_),
+ speedup_full_faster_count_, (float)speedup_full_faster_count_ / std::max(1, num_subtests_called_) * 100,
+ speedup_full_equal_count_, (float)speedup_full_equal_count_ / std::max(1, num_subtests_called_) * 100,
+ speedup_full_slower_count_, (float)speedup_full_slower_count_ / std::max(1, num_subtests_called_) * 100
+ );
+ fflush(record_);
+ }
+
+ void TestSystem::printError(const std::string &msg)
+ {
++ if(msg != "CL_INVALID_BUFFER_SIZE")
++ {
++ cout << TAB << "[error: " << msg << "] " << cur_subtest_description_.str() << endl;
++ }
+ }
+
+ void gen(Mat &mat, int rows, int cols, int type, Scalar low, Scalar high)
+ {
+ mat.create(rows, cols, type);
+ RNG rng(0);
+ rng.fill(mat, RNG::UNIFORM, low, high);
+ }
+
+
+ string abspath(const string &relpath)
+ {
+ return TestSystem::instance().workingDir() + relpath;
+ }
+
+
+ int CV_CDECL cvErrorCallback(int /*status*/, const char * /*func_name*/,
+ const char *err_msg, const char * /*file_name*/,
+ int /*line*/, void * /*userdata*/)
+ {
+ TestSystem::instance().printError(err_msg);
+ return 0;
+ }
+
//
//M*/
- #ifdef __GNUC__
- # pragma GCC diagnostic ignored "-Wmissing-declarations"
- # if defined __clang__ || defined __APPLE__
- # pragma GCC diagnostic ignored "-Wmissing-prototypes"
- # pragma GCC diagnostic ignored "-Wextra"
- # endif
- #endif
-
- #ifndef __OPENCV_TEST_PRECOMP_HPP__
- #define __OPENCV_TEST_PRECOMP_HPP__
-
- #include <cmath>
- #include <cstdio>
- #include <iostream>
- #include <fstream>
- #include <sstream>
+ #include <iomanip>
+ #include <stdexcept>
#include <string>
- #include <limits>
- #include <algorithm>
- #include <iterator>
- #include <string>
- #include <cstdarg>
- #include "opencv2/highgui.hpp"
+ #include <iostream>
+ #include <cstdio>
+ #include <vector>
+ #include <numeric>
-#include "opencv2/core/core.hpp"
-#include "opencv2/imgproc/imgproc.hpp"
-#include "opencv2/highgui/highgui.hpp"
-#include "opencv2/video/video.hpp"
-#include "opencv2/objdetect/objdetect.hpp"
-#include "opencv2/features2d/features2d.hpp"
-#include "opencv2/ocl/ocl.hpp"
++#include "opencv2/core.hpp"
+#include "opencv2/imgproc.hpp"
++#include "opencv2/highgui.hpp"
+#include "opencv2/video.hpp"
- #include "opencv2/ts.hpp"
++#include "opencv2/objdetect.hpp"
++#include "opencv2/features2d.hpp"
+#include "opencv2/ocl.hpp"
- #include "utility.hpp"
- #include "interpolation.hpp"
+ #define Min_Size 1000
+ #define Max_Size 4000
+ #define Multiple 2
+ #define TAB " "
+
+ using namespace std;
+ using namespace cv;
+
+ void gen(Mat &mat, int rows, int cols, int type, Scalar low, Scalar high);
+ string abspath(const string &relpath);
+ int CV_CDECL cvErrorCallback(int, const char *, const char *, const char *, int, void *);
+ typedef struct
+ {
+ short x;
+ short y;
+ } COOR;
+ COOR do_meanShift(int x0, int y0, uchar *sptr, uchar *dptr, int sstep,
+ cv::Size size, int sp, int sr, int maxIter, float eps, int *tab);
+ void meanShiftProc_(const Mat &src_roi, Mat &dst_roi, Mat &dstCoor_roi,
+ int sp, int sr, cv::TermCriteria crit);
+
+ class Runnable
+ {
+ public:
+ explicit Runnable(const std::string &runname): name_(runname) {}
+ virtual ~Runnable() {}
+
+ const std::string &name() const
+ {
+ return name_;
+ }
+
+ virtual void run() = 0;
+
+ private:
+ std::string name_;
+ };
+
+ class TestSystem
+ {
+ public:
+ static TestSystem &instance()
+ {
+ static TestSystem me;
+ return me;
+ }
+
+ void setWorkingDir(const std::string &val)
+ {
+ working_dir_ = val;
+ }
+ const std::string &workingDir() const
+ {
+ return working_dir_;
+ }
+
+ void setTestFilter(const std::string &val)
+ {
+ test_filter_ = val;
+ }
+ const std::string &testFilter() const
+ {
+ return test_filter_;
+ }
+
+ void setNumIters(int num_iters)
+ {
+ num_iters_ = num_iters;
+ }
+ void setGPUWarmupIters(int num_iters)
+ {
+ gpu_warmup_iters_ = num_iters;
+ }
+ void setCPUIters(int num_iters)
+ {
+ cpu_num_iters_ = num_iters;
+ }
+
+ void setTopThreshold(double top)
+ {
+ top_ = top;
+ }
+ void setBottomThreshold(double bottom)
+ {
+ bottom_ = bottom;
+ }
+
+ void addInit(Runnable *init)
+ {
+ inits_.push_back(init);
+ }
+ void addTest(Runnable *test)
+ {
+ tests_.push_back(test);
+ }
+ void run();
+
+ // It's public because OpenCV callback uses it
+ void printError(const std::string &msg);
+
+ std::stringstream &startNewSubtest()
+ {
+ finishCurrentSubtest();
+ return cur_subtest_description_;
+ }
+
+ bool stop() const
+ {
+ return cur_iter_idx_ >= num_iters_;
+ }
+
+ bool cpu_stop() const
+ {
+ return cur_iter_idx_ >= cpu_num_iters_;
+ }
+
+ bool warmupStop()
+ {
+ return cur_warmup_idx_++ >= gpu_warmup_iters_;
+ }
+
+ void warmupComplete()
+ {
+ cur_warmup_idx_ = 0;
+ }
+
+ void cpuOn()
+ {
+ cpu_started_ = cv::getTickCount();
+ }
+ void cpuOff()
+ {
+ int64 delta = cv::getTickCount() - cpu_started_;
+ cpu_times_.push_back(delta);
+ ++cur_iter_idx_;
+ }
+ void cpuComplete()
+ {
+ cpu_elapsed_ += meanTime(cpu_times_);
+ cur_subtest_is_empty_ = false;
+ cur_iter_idx_ = 0;
+ }
+
+ void gpuOn()
+ {
+ gpu_started_ = cv::getTickCount();
+ }
+ void gpuOff()
+ {
+ int64 delta = cv::getTickCount() - gpu_started_;
+ gpu_times_.push_back(delta);
+ ++cur_iter_idx_;
+ }
+ void gpuComplete()
+ {
+ gpu_elapsed_ += meanTime(gpu_times_);
+ cur_subtest_is_empty_ = false;
+ cur_iter_idx_ = 0;
+ }
+
+ void gpufullOn()
+ {
+ gpu_full_started_ = cv::getTickCount();
+ }
+ void gpufullOff()
+ {
+ int64 delta = cv::getTickCount() - gpu_full_started_;
+ gpu_full_times_.push_back(delta);
+ ++cur_iter_idx_;
+ }
+ void gpufullComplete()
+ {
+ gpu_full_elapsed_ += meanTime(gpu_full_times_);
+ cur_subtest_is_empty_ = false;
+ cur_iter_idx_ = 0;
+ }
+
+ bool isListMode() const
+ {
+ return is_list_mode_;
+ }
+ void setListMode(bool value)
+ {
+ is_list_mode_ = value;
+ }
+
+ void setRecordName(const std::string &name)
+ {
+ recordname_ = name;
+ }
+
+ void setCurrentTest(const std::string &name)
+ {
+ itname_ = name;
+ itname_changed_ = true;
+ }
+
+ private:
+ TestSystem():
+ cur_subtest_is_empty_(true), cpu_elapsed_(0),
+ gpu_elapsed_(0), gpu_full_elapsed_(0), speedup_total_(0.0),
+ num_subtests_called_(0),
+ speedup_faster_count_(0), speedup_slower_count_(0), speedup_equal_count_(0),
+ speedup_full_faster_count_(0), speedup_full_slower_count_(0), speedup_full_equal_count_(0), is_list_mode_(false),
+ num_iters_(10), cpu_num_iters_(2),
+ gpu_warmup_iters_(1), cur_iter_idx_(0), cur_warmup_idx_(0),
+ record_(0), recordname_("performance"), itname_changed_(true)
+ {
+ cpu_times_.reserve(num_iters_);
+ gpu_times_.reserve(num_iters_);
+ gpu_full_times_.reserve(num_iters_);
+ }
+
+ void finishCurrentSubtest();
+ void resetCurrentSubtest()
+ {
+ cpu_elapsed_ = 0;
+ gpu_elapsed_ = 0;
+ gpu_full_elapsed_ = 0;
+ cur_subtest_description_.str("");
+ cur_subtest_is_empty_ = true;
+ cur_iter_idx_ = 0;
+ cpu_times_.clear();
+ gpu_times_.clear();
+ gpu_full_times_.clear();
+ }
+
+ double meanTime(const std::vector<int64> &samples);
+
+ void printHeading();
+ void printSummary();
+ void printMetrics(double cpu_time, double gpu_time = 0.0f, double gpu_full_time = 0.0f, double speedup = 0.0f, double fullspeedup = 0.0f);
+
+ void writeHeading();
+ void writeSummary();
+ void writeMetrics(double cpu_time, double gpu_time = 0.0f, double gpu_full_time = 0.0f,
+ double speedup = 0.0f, double fullspeedup = 0.0f,
+ double gpu_min = 0.0f, double gpu_max = 0.0f, double std_dev = 0.0f);
+
+ std::string working_dir_;
+ std::string test_filter_;
+
+ std::vector<Runnable *> inits_;
+ std::vector<Runnable *> tests_;
+
+ std::stringstream cur_subtest_description_;
+ bool cur_subtest_is_empty_;
+
+ int64 cpu_started_;
+ int64 gpu_started_;
+ int64 gpu_full_started_;
+ double cpu_elapsed_;
+ double gpu_elapsed_;
+ double gpu_full_elapsed_;
+
+ double speedup_total_;
+ double speedup_full_total_;
+ int num_subtests_called_;
+
+ int speedup_faster_count_;
+ int speedup_slower_count_;
+ int speedup_equal_count_;
+
+ int speedup_full_faster_count_;
+ int speedup_full_slower_count_;
+ int speedup_full_equal_count_;
+
+ bool is_list_mode_;
+
+ double top_;
+ double bottom_;
+
+ int num_iters_;
- int cpu_num_iters_; //there's no need to set cpu running same times with gpu
- int gpu_warmup_iters_; //gpu warm up times, default is 1
++ int cpu_num_iters_; //there's no need to set cpu running same times with gpu
++ int gpu_warmup_iters_; //gpu warm up times, default is 1
+ int cur_iter_idx_;
- int cur_warmup_idx_; //current gpu warm up times
++ int cur_warmup_idx_; //current gpu warm up times
+ std::vector<int64> cpu_times_;
+ std::vector<int64> gpu_times_;
+ std::vector<int64> gpu_full_times_;
+
+ FILE *record_;
+ std::string recordname_;
+ std::string itname_;
+ bool itname_changed_;
+ };
+
+
+ #define GLOBAL_INIT(name) \
+ struct name##_init: Runnable { \
- name##_init(): Runnable(#name) { \
- TestSystem::instance().addInit(this); \
++ name##_init(): Runnable(#name) { \
++ TestSystem::instance().addInit(this); \
+ } \
- void run(); \
++ void run(); \
+ } name##_init_instance; \
- void name##_init::run()
++ void name##_init::run()
+
+
+ #define TEST(name) \
+ struct name##_test: Runnable { \
- name##_test(): Runnable(#name) { \
- TestSystem::instance().addTest(this); \
++ name##_test(): Runnable(#name) { \
++ TestSystem::instance().addTest(this); \
+ } \
- void run(); \
++ void run(); \
+ } name##_test_instance; \
- void name##_test::run()
++ void name##_test::run()
+
+ #define SUBTEST TestSystem::instance().startNewSubtest()
+
+ #define CPU_ON \
- while (!TestSystem::instance().cpu_stop()) { \
- TestSystem::instance().cpuOn()
++ while (!TestSystem::instance().cpu_stop()) { \
++ TestSystem::instance().cpuOn()
+ #define CPU_OFF \
- TestSystem::instance().cpuOff(); \
- } TestSystem::instance().cpuComplete()
++ TestSystem::instance().cpuOff(); \
++ } TestSystem::instance().cpuComplete()
- #include "opencv2/core/private.hpp"
+ #define GPU_ON \
- while (!TestSystem::instance().stop()) { \
- TestSystem::instance().gpuOn()
++ while (!TestSystem::instance().stop()) { \
++ TestSystem::instance().gpuOn()
+ #define GPU_OFF \
+ ocl::finish(); \
- TestSystem::instance().gpuOff(); \
- } TestSystem::instance().gpuComplete()
++ TestSystem::instance().gpuOff(); \
++ } TestSystem::instance().gpuComplete()
- #endif
+ #define GPU_FULL_ON \
- while (!TestSystem::instance().stop()) { \
- TestSystem::instance().gpufullOn()
++ while (!TestSystem::instance().stop()) { \
++ TestSystem::instance().gpufullOn()
+ #define GPU_FULL_OFF \
- TestSystem::instance().gpufullOff(); \
- } TestSystem::instance().gpufullComplete()
++ TestSystem::instance().gpufullOff(); \
++ } TestSystem::instance().gpufullComplete()
- while (!TestSystem::instance().warmupStop()) {
+ #define WARMUP_ON \
- } TestSystem::instance().warmupComplete()
++ while (!TestSystem::instance().warmupStop()) {
+ #define WARMUP_OFF \
+ ocl::finish(); \
++ } TestSystem::instance().warmupComplete()
}
/////////////////////////////OpenCL initialization/////////////////
- auto_ptr<Context> Context::clCxt;
+ std::auto_ptr<Context> Context::clCxt;
int Context::val = 0;
static Mutex cs;
- Context *Context::getContext()
+ static volatile int context_tear_down = 0;
+ Context* Context::getContext()
{
if(*((volatile int*)&val) != 1)
{
AutoLock al(cs);
if(*((volatile int*)&val) != 1)
{
+ if (context_tear_down)
+ return clCxt.get();
if( 0 == clCxt.get())
- clCxt.reset(new Context);
+ clCxt.reset(new Context);
-
std::vector<Info> oclinfo;
CV_Assert(getDevice(oclinfo, CVCL_DEVICE_TYPE_ALL) > 0);
oclinfo[0].impl->setDevice(0, 0, 0);
const size_t regin[3] = {mat.cols * mat.elemSize(), mat.rows, 1};
clEnqueueCopyBufferRect((cl_command_queue)mat.clCxt->oclCommandQueue(), (cl_mem)mat.data, devData, origin, origin,
regin, mat.step, 0, mat.cols * mat.elemSize(), 0, 0, NULL, NULL);
- }
- clFlush((cl_command_queue)mat.clCxt->oclCommandQueue());
++ clFlush((cl_command_queue)mat.clCxt->oclCommandQueue());
+ }
else
{
devData = (cl_mem)mat.data;
if (x < cols && y < rows)
{
x = x << 2;
-
+
+ #ifdef dst_align
+ #undef dst_align
+ #endif
#define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int dst_start = mad24(y, dst_step, dst_offset);
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset -( dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset -( dst_align << 1));
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset -( dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset -( dst_align << 1));
x = x << 2;
- #define bitOfInt (sizeof(int)== 4 ? 2: 3)
+ #define bitOfInt (sizeof(int)== 4 ? 2: 3)
-
+
- #define dst_align ((dst_offset >> bitOfInt) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> bitOfInt) & 3)
int src1_index = mad24(y, src1_step, (x << bitOfInt) + src1_offset - (dst_align << bitOfInt));
int src2_index = mad24(y, src2_step, (x << bitOfInt) + src2_offset - (dst_align << bitOfInt));
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 2) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 2) & 3)
int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2));
int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2));
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 3) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 3) & 3)
int src1_index = mad24(y, src1_step, (x << 3) + src1_offset - (dst_align << 3));
int src2_index = mad24(y, src2_step, (x << 3) + src2_offset - (dst_align << 3));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int src2_index = mad24(y, src2_step, (x * 3) + src2_offset - (dst_align * 3));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int src2_index = mad24(y, src2_step, (x * 6) + src2_offset - (dst_align * 6));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align ((dst_offset >> 1) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 1)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 3 ) & 3)
int src1_index = mad24(y, src1_step, (x * 3) + src1_offset - (dst_align * 3));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 1;
-
+
- #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset % dst_step) / 6 ) & 1)
int src1_index = mad24(y, src1_step, (x * 6) + src1_offset - (dst_align * 6));
int mask_index = mad24(y, mask_step, x + mask_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1)& 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1)& 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1)& 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1)& 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 2)& 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 2)& 3)
int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2));
int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 2)& 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 2)& 3)
int src1_index = mad24(y, src1_step, (x << 2) + src1_offset - (dst_align << 2));
int src2_index = mad24(y, src2_step, (x << 2) + src2_offset - (dst_align << 2));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 3)& 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 3)& 3)
int src1_index = mad24(y, src1_step, (x << 3) + src1_offset - (dst_align << 3));
int src2_index = mad24(y, src2_step, (x << 3) + src2_offset - (dst_align << 3));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1)& 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1)& 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1)& 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1)& 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
__global uchar *dst, int dst_step, int dst_offset,
int rows, int cols, int dst_step1, F scalar)
{
- int x = get_global_id(0);
- int y = get_global_id(1);
+ int2 coor = (int2)(get_global_id(0), get_global_id(1));
- if (x < cols && y < rows)
+ if (coor.x < cols && coor.y < rows)
{
- x = x << 2;
+ coor.x = coor.x << 2;
-
+
- #define dst_align (dst_offset & 3)
- int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
- int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
+ int2 src_index = (int2)(mad24(coor.y, src1_step, coor.x + src1_offset - dst_align),
+ mad24(coor.y, src2_step, coor.x + src2_offset - dst_align));
- int dst_start = mad24(y, dst_step, dst_offset);
- int dst_end = mad24(y, dst_step, dst_offset + dst_step1);
- int dst_index = mad24(y, dst_step, dst_offset + x & (int)0xfffffffc);
+ int4 dst_args = (int4)(mad24(coor.y, dst_step, dst_offset),
+ mad24(coor.y, dst_step, dst_offset + dst_step1),
+ mad24(coor.y, dst_step, dst_offset + coor.x & (int)0xfffffffc),
+ 0);
- uchar4 src1_data = vload4(0, src1 + src1_index);
- uchar4 src2_data = vload4(0, src2 + src2_index);
- uchar4 dst_data = *((__global uchar4 *)(dst + dst_index));
+ uchar4 src1_data = vload4(0, src1 + src_index.x);
+ uchar4 src2_data = vload4(0, src2 + src_index.y);
+ uchar4 dst_data = *((__global uchar4 *)(dst + dst_args.z));
F4 tmp = convert_F4(src1_data) * scalar;
-
uchar4 tmp_data;
- tmp_data.x = ((tmp.x == 0) || (src2_data.x == 0)) ? 0 : round2_uchar(tmp.x / (F)src2_data.x);
- tmp_data.y = ((tmp.y == 0) || (src2_data.y == 0)) ? 0 : round2_uchar(tmp.y / (F)src2_data.y);
- tmp_data.z = ((tmp.z == 0) || (src2_data.z == 0)) ? 0 : round2_uchar(tmp.z / (F)src2_data.z);
- tmp_data.w = ((tmp.w == 0) || (src2_data.w == 0)) ? 0 : round2_uchar(tmp.w / (F)src2_data.w);
+ tmp_data.x = ((tmp.x == 0) || (src2_data.x == 0)) ? 0 : round2_uchar(tmp.x / src2_data.x);
+ tmp_data.y = ((tmp.y == 0) || (src2_data.y == 0)) ? 0 : round2_uchar(tmp.y / src2_data.y);
+ tmp_data.z = ((tmp.z == 0) || (src2_data.z == 0)) ? 0 : round2_uchar(tmp.z / src2_data.z);
+ tmp_data.w = ((tmp.w == 0) || (src2_data.w == 0)) ? 0 : round2_uchar(tmp.w / src2_data.w);
- dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x;
- dst_data.y = ((dst_index + 1 >= dst_start) && (dst_index + 1 < dst_end)) ? tmp_data.y : dst_data.y;
- dst_data.z = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.z : dst_data.z;
- dst_data.w = ((dst_index + 3 >= dst_start) && (dst_index + 3 < dst_end)) ? tmp_data.w : dst_data.w;
+ dst_data.x = ((dst_args.z + 0 >= dst_args.x) && (dst_args.z + 0 < dst_args.y)) ? tmp_data.x : dst_data.x;
+ dst_data.y = ((dst_args.z + 1 >= dst_args.x) && (dst_args.z + 1 < dst_args.y)) ? tmp_data.y : dst_data.y;
+ dst_data.z = ((dst_args.z + 2 >= dst_args.x) && (dst_args.z + 2 < dst_args.y)) ? tmp_data.z : dst_data.z;
+ dst_data.w = ((dst_args.z + 3 >= dst_args.x) && (dst_args.z + 3 < dst_args.y)) ? tmp_data.w : dst_data.w;
- *((__global uchar4 *)(dst + dst_index)) = dst_data;
+ *((__global uchar4 *)(dst + dst_args.z)) = dst_data;
}
}
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src_index = mad24(y, src_step, x + src_offset - dst_align);
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src_index = mad24(y, src_step, (x << 1) + src_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src_index = mad24(y, src_step, (x << 1) + src_offset - (dst_align << 1));
int dst_start = mad24(y, dst_step, dst_offset);
if (x < cols && y < thread_rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src_index_0 = mad24(y, src_step, x + src_offset - dst_align);
int src_index_1 = mad24(rows - y - 1, src_step, x + src_offset - dst_align);
if (x < cols && y < thread_rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src_index_0 = mad24(y, src_step, x + src_offset - dst_align);
int src_index_1 = mad24(rows - y - 1, src_step, x + src_offset - dst_align);
if (x < cols && y < thread_rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset >> 1) & 3) << 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset >> 1) & 3) << 1)
int src_index_0 = mad24(y, src_step, (x << 1) + src_offset - dst_align);
int src_index_1 = mad24(rows - y - 1, src_step, (x << 1) + src_offset - dst_align);
if (x < cols && y < thread_rows)
{
x = x << 2;
-
+
- #define dst_align (((dst_offset >> 1) & 3) << 1)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (((dst_offset >> 1) & 3) << 1)
int src_index_0 = mad24(y, src_step, (x << 1) + src_offset - dst_align);
int src_index_1 = mad24(rows - y - 1, src_step, (x << 1) + src_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align (dst_offset & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align (dst_offset & 3)
int src1_index = mad24(y, src1_step, x + src1_offset - dst_align);
int src2_index = mad24(y, src2_step, x + src2_offset - dst_align);
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
if (x < cols && y < rows)
{
x = x << 2;
-
+
- #define dst_align ((dst_offset >> 1) & 3)
+ #ifdef dst_align
+ #undef dst_align
+ #endif
+ #define dst_align ((dst_offset >> 1) & 3)
int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1));
int src2_index = mad24(y, src2_step, (x << 1) + src2_offset - (dst_align << 1));
--- /dev/null
- return convert_short_sat_rte(v);
+ /*M///////////////////////////////////////////////////////////////////////////////////////
+ //
+ // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+ //
+ // By downloading, copying, installing or using the software you agree to this license.
+ // If you do not agree to this license, do not download, install,
+ // copy or use the software.
+ //
+ //
+ // License Agreement
+ // For Open Source Computer Vision Library
+ // Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
+ // Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved.
+ // Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
+ // Third party copyrights are property of their respective owners.
+ //
+ // @Authors
+ // Jia Haipeng, jiahaipeng95@gmail.com
+ // Peng Xiao, pengxiao@outlook.com
+ //
+ // Redistribution and use in source and binary forms, with or without modification,
+ // are permitted provided that the following conditions are met:
+ //
+ // * Redistribution's of source code must retain the above copyright notice,
+ // this list of conditions and the following disclaimer.
+ //
+ // * Redistribution's in binary form must reproduce the above copyright notice,
+ // this list of conditions and the following disclaimer in the documentation
+ // and/or other GpuMaterials provided with the distribution.
+ //
+ // * The name of the copyright holders may not be used to endorse or promote products
+ // derived from this software without specific prior written permission.
+ //
+ // This software is provided by the copyright holders and contributors as is and
+ // any express or implied warranties, including, but not limited to, the implied
+ // warranties of merchantability and fitness for a particular purpose are disclaimed.
+ // In no event shall the Intel Corporation or contributors be liable for any direct,
+ // indirect, incidental, special, exemplary, or consequential damages
+ // (including, but not limited to, procurement of substitute goods or services;
+ // loss of use, data, or profits; or business interruption) however caused
+ // and on any theory of liability, whether in contract, strict liability,
+ // or tort (including negligence or otherwise) arising in any way out of
+ // the use of this software, even if advised of the possibility of such damage.
+ //
+ //M*/
+
+ #if defined (DOUBLE_SUPPORT)
+
+ #ifdef cl_khr_fp64
+ #pragma OPENCL EXTENSION cl_khr_fp64:enable
+ #elif defined (cl_amd_fp64)
+ #pragma OPENCL EXTENSION cl_amd_fp64:enable
+ #endif
+
+ #endif
+
+ #ifdef T_FLOAT
+ #define T float
+ #else
+ #define T short
+ #endif
+
+ ///////////////////////////////////////////////////////////////
+ /////////////////common///////////////////////////////////////
+ /////////////////////////////////////////////////////////////
+ T saturate_cast(float v){
+ #ifdef T_SHORT
- return abs((int)(*ls) - *rs);
++ return convert_short_sat_rte(v);
+ #else
+ return v;
+ #endif
+ }
+
+ #define FLOAT_MAX 3.402823466e+38f
+ typedef struct
+ {
+ int cndisp;
+ float cmax_data_term;
+ float cdata_weight;
+ float cmax_disc_term;
+ float cdisc_single_jump;
+ }con_srtuct_t;
+ ///////////////////////////////////////////////////////////////
+ ////////////////////////// comp data //////////////////////////
+ ///////////////////////////////////////////////////////////////
+
+ float pix_diff_1(__global const uchar *ls, __global const uchar *rs)
+ {
- ds[disp * disp_step] = saturate_cast(fmin(con_st -> cdata_weight * val,
++ return abs((int)(*ls) - *rs);
+ }
+
+ float pix_diff_3(__global const uchar *ls, __global const uchar *rs)
+ {
+ const float tr = 0.299f;
+ const float tg = 0.587f;
+ const float tb = 0.114f;
+
+ float val;
+
+ val = tb * abs((int)ls[0] - rs[0]);
+ val += tg * abs((int)ls[1] - rs[1]);
+ val += tr * abs((int)ls[2] - rs[2]);
+
+ return val;
+ }
+ float pix_diff_4(__global const uchar *ls, __global const uchar *rs)
+ {
+ uchar4 l, r;
+ l = *((__global uchar4 *)ls);
+ r = *((__global uchar4 *)rs);
+
+ const float tr = 0.299f;
+ const float tg = 0.587f;
+ const float tb = 0.114f;
+
+ float val;
+
+ val = tb * abs((int)l.x - r.x);
+ val += tg * abs((int)l.y - r.y);
+ val += tr * abs((int)l.z - r.z);
+
+ return val;
+ }
+
+
+ #ifndef CN
+ #define CN 4
+ #endif
+
+ #define CAT(X,Y) X##Y
+ #define CAT2(X,Y) CAT(X,Y)
+
+ #define PIX_DIFF CAT2(pix_diff_, CN)
+
+ __kernel void comp_data(__global uchar *left, int left_rows, int left_cols, int left_step,
+ __global uchar *right, int right_step,
+ __global T *data, int data_step,
+ __constant con_srtuct_t *con_st)
+ {
+ int x = get_global_id(0);
+ int y = get_global_id(1);
+
+ if (y > 0 && y < (left_rows - 1) && x > 0 && x < (left_cols - 1))
+ {
+ data_step /= sizeof(T);
+ const __global uchar* ls = left + y * left_step + x * CN;
+ const __global uchar* rs = right + y * right_step + x * CN;
+
+ __global T *ds = data + y * data_step + x;
+
+ const unsigned int disp_step = data_step * left_rows;
+
+ for (int disp = 0; disp < con_st -> cndisp; disp++)
+ {
+ if (x - disp >= 1)
+ {
+ float val = 0;
+ val = PIX_DIFF(ls, rs - disp * CN);
-__kernel void data_step_down(__global T *src, int src_rows,
- __global T *dst, int dst_rows, int dst_cols,
++ ds[disp * disp_step] = saturate_cast(fmin(con_st -> cdata_weight * val,
+ con_st -> cdata_weight * con_st -> cmax_data_term));
+ }
+ else
+ {
+ ds[disp * disp_step] = saturate_cast(con_st -> cdata_weight * con_st -> cmax_data_term);
+ }
+ }
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////
+ //////////////////////// data step down ///////////////////////
+ ///////////////////////////////////////////////////////////////
-void calc_min_linear_penalty(__global T * dst, int disp_step,
++__kernel void data_step_down(__global T *src, int src_rows,
++ __global T *dst, int dst_rows, int dst_cols,
+ int src_step, int dst_step,
+ int cndisp)
+ {
+ const int x = get_global_id(0);
+ const int y = get_global_id(1);
+
+ if (x < dst_cols && y < dst_rows)
+ {
+ src_step /= sizeof(T);
+ dst_step /= sizeof(T);
+ for (int d = 0; d < cndisp; ++d)
+ {
+ float dst_reg;
+ dst_reg = src[(d * src_rows + (2*y+0)) * src_step + 2*x+0];
+ dst_reg += src[(d * src_rows + (2*y+1)) * src_step + 2*x+0];
+ dst_reg += src[(d * src_rows + (2*y+0)) * src_step + 2*x+1];
+ dst_reg += src[(d * src_rows + (2*y+1)) * src_step + 2*x+1];
+
+ dst[(d * dst_rows + y) * dst_step + x] = saturate_cast(dst_reg);
+ }
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////
+ /////////////////// level up messages ////////////////////////
+ ///////////////////////////////////////////////////////////////
+ __kernel void level_up_message(__global T *src, int src_rows, int src_step,
+ __global T *dst, int dst_rows, int dst_cols, int dst_step,
+ int cndisp)
+ {
+ const int x = get_global_id(0);
+ const int y = get_global_id(1);
+
+ if (x < dst_cols && y < dst_rows)
+ {
+ src_step /= sizeof(T);
+ dst_step /= sizeof(T);
+
+ const int dst_disp_step = dst_step * dst_rows;
+ const int src_disp_step = src_step * src_rows;
+
+ __global T *dstr = dst + y * dst_step + x;
+ __global const T *srcr = src + (y / 2 * src_step) + (x / 2);
+
+ for (int d = 0; d < cndisp; ++d)
+ dstr[d * dst_disp_step] = srcr[d * src_disp_step];
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////
+ //////////////////// calc all iterations /////////////////////
+ ///////////////////////////////////////////////////////////////
- int t, int cols, int rows,
++void calc_min_linear_penalty(__global T * dst, int disp_step,
+ int cndisp, float cdisc_single_jump)
+ {
+ float prev = dst[0];
+ float cur;
+
+ for (int disp = 1; disp < cndisp; ++disp)
+ {
+ prev += cdisc_single_jump;
+ cur = dst[disp_step * disp];
+
+ if (prev < cur)
+ {
+ cur = prev;
+ dst[disp_step * disp] = saturate_cast(prev);
+ }
+
+ prev = cur;
+ }
+
+ prev = dst[(cndisp - 1) * disp_step];
+ for (int disp = cndisp - 2; disp >= 0; disp--)
+ {
+ prev += cdisc_single_jump;
+ cur = dst[disp_step * disp];
+
+ if (prev < cur)
+ {
+ cur = prev;
+ dst[disp_step * disp] = saturate_cast(prev);
+ }
+ prev = cur;
+ }
+ }
+ void message(const __global T *msg1, const __global T *msg2,
+ const __global T *msg3, const __global T *data, __global T *dst,
+ int msg_disp_step, int data_disp_step, int cndisp, float cmax_disc_term, float cdisc_single_jump)
+ {
+ float minimum = FLOAT_MAX;
+
+ for(int i = 0; i < cndisp; ++i)
+ {
+ float dst_reg;
+ dst_reg = msg1[msg_disp_step * i];
+ dst_reg += msg2[msg_disp_step * i];
+ dst_reg += msg3[msg_disp_step * i];
+ dst_reg += data[data_disp_step * i];
+
+ if (dst_reg < minimum)
+ minimum = dst_reg;
+
+ dst[msg_disp_step * i] = saturate_cast(dst_reg);
+ }
+
+ calc_min_linear_penalty(dst, msg_disp_step, cndisp, cdisc_single_jump);
+
+ minimum += cmax_disc_term;
+
+ float sum = 0;
+ for(int i = 0; i < cndisp; ++i)
+ {
+ float dst_reg = dst[msg_disp_step * i];
+ if (dst_reg > minimum)
+ {
+ dst_reg = minimum;
+ dst[msg_disp_step * i] = saturate_cast(minimum);
+ }
+ sum += dst_reg;
+ }
+ sum /= cndisp;
+
+ for(int i = 0; i < cndisp; ++i)
+ dst[msg_disp_step * i] -= sum;
+ }
+ __kernel void one_iteration(__global T *u, int u_step,
+ __global T *data, int data_step,
+ __global T *d, __global T *l, __global T *r,
- message(us + u_step, ls + 1, rs - 1, dt, us, msg_disp_step, data_disp_step, cndisp,
++ int t, int cols, int rows,
+ int cndisp, float cmax_disc_term, float cdisc_single_jump)
+ {
+ const int y = get_global_id(1);
+ const int x = ((get_global_id(0)) << 1) + ((y + t) & 1);
+
+ if ((y > 0) && (y < rows - 1) && (x > 0) && (x < cols - 1))
+ {
+ u_step /= sizeof(T);
+ data_step /= sizeof(T);
+
+ __global T *us = u + y * u_step + x;
+ __global T *ds = d + y * u_step + x;
+ __global T *ls = l + y * u_step + x;
+ __global T *rs = r + y * u_step + x;
+ const __global T *dt = data + y * data_step + x;
+
+ int msg_disp_step = u_step * rows;
+ int data_disp_step = data_step * rows;
+
++ message(us + u_step, ls + 1, rs - 1, dt, us, msg_disp_step, data_disp_step, cndisp,
+ cmax_disc_term, cdisc_single_jump);
+ message(ds - u_step, ls + 1, rs - 1, dt, ds, msg_disp_step, data_disp_step, cndisp,
+ cmax_disc_term, cdisc_single_jump);
+
+ message(us + u_step, ds - u_step, rs - 1, dt, rs, msg_disp_step, data_disp_step, cndisp,
+ cmax_disc_term, cdisc_single_jump);
+ message(us + u_step, ds - u_step, ls + 1, dt, ls, msg_disp_step, data_disp_step, cndisp,
+ cmax_disc_term, cdisc_single_jump);
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////
+ /////////////////////////// output ////////////////////////////
+ ///////////////////////////////////////////////////////////////
+ __kernel void output(const __global T *u, int u_step,
+ const __global T *d, const __global T *l,
+ const __global T *r, const __global T *data,
+ __global T *disp, int disp_rows, int disp_cols, int disp_step,
+ int cndisp)
+ {
+ const int x = get_global_id(0);
+ const int y = get_global_id(1);
+
+ if (y > 0 && y < disp_rows - 1 && x > 0 && x < disp_cols - 1)
+ {
+ u_step /= sizeof(T);
+ disp_step /= sizeof(T);
+ const __global T *us = u + (y + 1) * u_step + x;
+ const __global T *ds = d + (y - 1) * u_step + x;
+ const __global T *ls = l + y * u_step + (x + 1);
+ const __global T *rs = r + y * u_step + (x - 1);
+ const __global T *dt = data + y * u_step + x;
+
+ int disp_steps = disp_rows * u_step;
+
+ int best = 0;
+ float best_val = FLOAT_MAX;
+ for (int d = 0; d < cndisp; ++d)
+ {
+ float val;
+ val = us[d * disp_steps];
+ val += ds[d * disp_steps];
+ val += ls[d * disp_steps];
+ val += rs[d * disp_steps];
+ val += dt[d * disp_steps];
+
+ if (val < best_val)
+ {
+ best_val = val;
+ best = d;
+ }
+ }
+
+ (disp + y * disp_step)[x] = convert_short_sat(best);
+ }
+ }
--- /dev/null
-using namespace std;
+ /*M///////////////////////////////////////////////////////////////////////////////////////
+ //
+ // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+ //
+ // By downloading, copying, installing or using the software you agree to this license.
+ // If you do not agree to this license, do not download, install,
+ // copy or use the software.
+ //
+ //
+ // License Agreement
+ // For Open Source Computer Vision Library
+ //
+ // Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
+ // Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved.
+ // Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
+ // Third party copyrights are property of their respective owners.
+ //
+ // @Authors
+ // Jia Haipeng, jiahaipeng95@gmail.com
+ // Peng Xiao, pengxiao@outlook.com
+ // Redistribution and use in source and binary forms, with or without modification,
+ // are permitted provided that the following conditions are met:
+ //
+ // * Redistribution's of source code must retain the above copyright notice,
+ // this list of conditions and the following disclaimer.
+ //
+ // * Redistribution's in binary form must reproduce the above copyright notice,
+ // this list of conditions and the following disclaimer in the documentation
+ // and/or other oclMaterials provided with the distribution.
+ //
+ // * The name of the copyright holders may not be used to endorse or promote products
+ // derived from this software without specific prior written permission.
+ //
+ // This software is provided by the copyright holders and contributors "as is" and
+ // any express or implied warranties, including, but not limited to, the implied
+ // warranties of merchantability and fitness for a particular purpose are disclaimed.
+ // In no event shall the Intel Corporation or contributors be liable for any direct,
+ // indirect, incidental, special, exemplary, or consequential damages
+ // (including, but not limited to, procurement of substitute goods or services;
+ // loss of use, data, or profits; or business interruption) however caused
+ // and on any theory of liability, whether in contract, strict liability,
+ // or tort (including negligence or otherwise) arising in any way out of
+ // the use of this software, even if advised of the possibility of such damage.
+ //
+ //M*/
+
+ #include "precomp.hpp"
+ #include <vector>
+ #include <cstdio>
+
+ using namespace cv;
+ using namespace cv::ocl;
- float /*cmax_data_term*/, float /*cdata_weight*/)
+
+ ////////////////////////////////////////////////////////////////////////
+ ///////////////// stereoBP /////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////
+
+ namespace cv
+ {
+ namespace ocl
+ {
+
+ ///////////////////////////OpenCL kernel strings///////////////////////////
+ extern const char *stereobp;
+ }
+
+ }
+ namespace cv
+ {
+ namespace ocl
+ {
+ namespace stereoBP
+ {
+ //////////////////////////////////////////////////////////////////////////
+ //////////////////////////////common////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////
+ typedef struct
+ {
+ int cndisp;
+ float cmax_data_term;
+ float cdata_weight;
+ float cmax_disc_term;
+ float cdisc_single_jump;
+ } con_struct_t;
+
+ cl_mem cl_con_struct = NULL;
+ static void load_constants(int ndisp, float max_data_term, float data_weight,
+ float max_disc_term, float disc_single_jump)
+ {
+ con_struct_t *con_struct = new con_struct_t;
+ con_struct -> cndisp = ndisp;
+ con_struct -> cmax_data_term = max_data_term;
+ con_struct -> cdata_weight = data_weight;
+ con_struct -> cmax_disc_term = max_disc_term;
+ con_struct -> cdisc_single_jump = disc_single_jump;
+
+ cl_con_struct = load_constant(*((cl_context*)getoclContext()), *((cl_command_queue*)getoclCommandQueue()), (void *)con_struct,
+ sizeof(con_struct_t));
+
+ delete con_struct;
+ }
+ static void release_constants()
+ {
+ openCLFree(cl_con_struct);
+ }
+ static inline int divUp(int total, int grain)
+ {
+ return (total + grain - 1) / grain;
+ }
+ /////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////comp data////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////
+ static void comp_data_call(const oclMat &left, const oclMat &right, oclMat &data, int /*disp*/,
- string kernelName = "comp_data";
++ float /*cmax_data_term*/, float /*cdata_weight*/)
+ {
+ Context *clCxt = left.clCxt;
+ int channels = left.oclchannels();
+ int data_type = data.type();
+
- vector<pair<size_t , const void *> > args;
++ String kernelName = "comp_data";
+
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&left.data));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&left.rows));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&left.cols));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&left.step));
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&right.data));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&right.step));
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&data.data));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&data.step));
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&cl_con_struct));
++ std::vector<std::pair<size_t , const void *> > args;
+
- sprintf( cn_opt, "%s -D CN=%d",
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&left.data));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&left.rows));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&left.cols));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&left.step));
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&right.data));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&right.step));
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&data.data));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&data.step));
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&cl_con_struct));
+
+ size_t gt[3] = {left.cols, left.rows, 1}, lt[3] = {16, 16, 1};
+
+ const int OPT_SIZE = 50;
+ char cn_opt [OPT_SIZE] = "";
- string kernelName = "data_step_down";
++ sprintf( cn_opt, "%s -D CN=%d",
+ (data_type == CV_16S ? "-D T_SHORT":"-D T_FLOAT"),
+ channels
+ );
+ openCLExecuteKernel(clCxt, &stereobp, kernelName, gt, lt, args, -1, -1, cn_opt);
+ }
+ ///////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////data set down////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////////////
+ static void data_step_down_call(int dst_cols, int dst_rows, int src_rows,
+ const oclMat &src, oclMat &dst, int disp)
+ {
+ Context *clCxt = src.clCxt;
+ int data_type = src.type();
+
- vector<pair<size_t , const void *> > args;
++ String kernelName = "data_step_down";
+
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&src_rows));
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_rows));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_cols));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&src.step));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.step));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&disp));
++ std::vector<std::pair<size_t , const void *> > args;
+
- string kernelName = "level_up_message";
- vector<pair<size_t , const void *> > args;
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&src.data));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src_rows));
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&dst.data));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst_rows));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst_cols));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.step));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst.step));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&disp));
+
+ size_t gt[3] = {dst_cols, dst_rows, 1}, lt[3] = {16, 16, 1};
+ const char* t_opt = data_type == CV_16S ? "-D T_SHORT":"-D T_FLOAT";
+ openCLExecuteKernel(clCxt, &stereobp, kernelName, gt, lt, args, -1, -1, t_opt);
+ }
+ /////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////live up message////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////////////
+ static void level_up_message_call(int dst_cols, int dst_rows, int src_rows,
+ oclMat &src, oclMat &dst, int ndisp)
+ {
+ Context *clCxt = src.clCxt;
+ int data_type = src.type();
+
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&src_rows));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&src.step));
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_rows));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_cols));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.step));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&ndisp));
++ String kernelName = "level_up_message";
++ std::vector<std::pair<size_t , const void *> > args;
+
- string kernelName = "one_iteration";
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&src.data));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src_rows));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.step));
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&dst.data));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst_rows));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst_cols));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst.step));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&ndisp));
+
+ size_t gt[3] = {dst_cols, dst_rows, 1}, lt[3] = {16, 16, 1};
+ const char* t_opt = data_type == CV_16S ? "-D T_SHORT":"-D T_FLOAT";
+ openCLExecuteKernel(clCxt, &stereobp, kernelName, gt, lt, args, -1, -1, t_opt);
+ }
+ static void level_up_messages_calls(int dst_idx, int dst_cols, int dst_rows, int src_rows,
+ oclMat *mus, oclMat *mds, oclMat *mls, oclMat *mrs,
+ int ndisp)
+ {
+ int src_idx = (dst_idx + 1) & 1;
+
+ level_up_message_call(dst_cols, dst_rows, src_rows,
+ mus[src_idx], mus[dst_idx], ndisp);
+
+ level_up_message_call(dst_cols, dst_rows, src_rows,
+ mds[src_idx], mds[dst_idx], ndisp);
+
+ level_up_message_call(dst_cols, dst_rows, src_rows,
+ mls[src_idx], mls[dst_idx], ndisp);
+
+ level_up_message_call(dst_cols, dst_rows, src_rows,
+ mrs[src_idx], mrs[dst_idx], ndisp);
+ }
+ //////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////cals_all_iterations_call///////////////////////////
+ /////////////////////////////////////////////////////////////////////////////////
+ static void calc_all_iterations_call(int cols, int rows, oclMat &u, oclMat &d,
+ oclMat &l, oclMat &r, oclMat &data,
+ int t, int cndisp, float cmax_disc_term,
+ float cdisc_single_jump)
+ {
+ Context *clCxt = l.clCxt;
+ int data_type = u.type();
+
- vector<pair<size_t , const void *> > args;
++ String kernelName = "one_iteration";
+
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&u.data));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&u.step));
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&data.data));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&data.step));
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&d.data));
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&l.data));
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&r.data));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&t));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&cols));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&rows));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&cndisp));
- args.push_back( make_pair( sizeof(cl_float) , (void *)&cmax_disc_term));
- args.push_back( make_pair( sizeof(cl_float) , (void *)&cdisc_single_jump));
++ std::vector<std::pair<size_t , const void *> > args;
+
- string kernelName = "output";
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&u.data));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&u.step));
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&data.data));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&data.step));
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&d.data));
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&l.data));
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&r.data));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&t));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&cols));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&rows));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&cndisp));
++ args.push_back( std::make_pair( sizeof(cl_float) , (void *)&cmax_disc_term));
++ args.push_back( std::make_pair( sizeof(cl_float) , (void *)&cdisc_single_jump));
+
+ size_t gt[3] = {cols, rows, 1}, lt[3] = {16, 16, 1};
+ const char* t_opt = data_type == CV_16S ? "-D T_SHORT":"-D T_FLOAT";
+ openCLExecuteKernel(clCxt, &stereobp, kernelName, gt, lt, args, -1, -1, t_opt);
+ }
+
+ static void calc_all_iterations_calls(int cols, int rows, int iters, oclMat &u,
+ oclMat &d, oclMat &l, oclMat &r,
+ oclMat &data, int cndisp, float cmax_disc_term,
+ float cdisc_single_jump)
+ {
+ for(int t = 0; t < iters; ++t)
+ calc_all_iterations_call(cols, rows, u, d, l, r, data, t, cndisp,
+ cmax_disc_term, cdisc_single_jump);
+ }
+ ///////////////////////////////////////////////////////////////////////////////
+ ///////////////////////output///////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ static void output_call(const oclMat &u, const oclMat &d, const oclMat l, const oclMat &r,
+ const oclMat &data, oclMat &disp, int ndisp)
+ {
+ Context *clCxt = u.clCxt;
+ int data_type = u.type();
+
- vector<pair<size_t , const void *> > args;
++ String kernelName = "output";
+
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&u.data));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&u.step));
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&d.data));
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&l.data));
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&r.data));
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&data.data));
- args.push_back( make_pair( sizeof(cl_mem) , (void *)&disp.data));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&disp.rows));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&disp.cols));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&disp.step));
- args.push_back( make_pair( sizeof(cl_int) , (void *)&ndisp));
++ std::vector<std::pair<size_t , const void *> > args;
+
- vector<oclMat> &datas_, oclMat &out_)
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&u.data));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&u.step));
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&d.data));
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&l.data));
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&r.data));
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&data.data));
++ args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&disp.data));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&disp.rows));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&disp.cols));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&disp.step));
++ args.push_back( std::make_pair( sizeof(cl_int) , (void *)&ndisp));
+
+ size_t gt[3] = {disp.cols, disp.rows, 1}, lt[3] = {16, 16, 1};
+ const char* t_opt = data_type == CV_16S ? "-D T_SHORT":"-D T_FLOAT";
+ openCLExecuteKernel(clCxt, &stereobp, kernelName, gt, lt, args, -1, -1, t_opt);
+ }
+ }
+ }
+ }
+ namespace
+ {
+ const float DEFAULT_MAX_DATA_TERM = 10.0f;
+ const float DEFAULT_DATA_WEIGHT = 0.07f;
+ const float DEFAULT_MAX_DISC_TERM = 1.7f;
+ const float DEFAULT_DISC_SINGLE_JUMP = 1.0f;
+ }
+
+ void cv::ocl::StereoBeliefPropagation::estimateRecommendedParams(int width, int height, int &ndisp, int &iters, int &levels)
+ {
+ ndisp = width / 4;
+ if ((ndisp & 1) != 0)
+ ndisp++;
+
+ int mm = ::max(width, height);
+ iters = mm / 100 + 2;
+
+ levels = (int)(::log(static_cast<double>(mm)) + 1) * 4 / 5;
+ if (levels == 0) levels++;
+ }
+
+ cv::ocl::StereoBeliefPropagation::StereoBeliefPropagation(int ndisp_, int iters_, int levels_, int msg_type_)
+ : ndisp(ndisp_), iters(iters_), levels(levels_),
+ max_data_term(DEFAULT_MAX_DATA_TERM), data_weight(DEFAULT_DATA_WEIGHT),
+ max_disc_term(DEFAULT_MAX_DISC_TERM), disc_single_jump(DEFAULT_DISC_SINGLE_JUMP),
+ msg_type(msg_type_), datas(levels_)
+ {
+ }
+
+ cv::ocl::StereoBeliefPropagation::StereoBeliefPropagation(int ndisp_, int iters_, int levels_, float max_data_term_, float data_weight_, float max_disc_term_, float disc_single_jump_, int msg_type_)
+ : ndisp(ndisp_), iters(iters_), levels(levels_),
+ max_data_term(max_data_term_), data_weight(data_weight_),
+ max_disc_term(max_disc_term_), disc_single_jump(disc_single_jump_),
+ msg_type(msg_type_), datas(levels_)
+ {
+ }
+
+ namespace
+ {
+ class StereoBeliefPropagationImpl
+ {
+ public:
+ StereoBeliefPropagationImpl(StereoBeliefPropagation &rthis_,
+ oclMat &u_, oclMat &d_, oclMat &l_, oclMat &r_,
+ oclMat &u2_, oclMat &d2_, oclMat &l2_, oclMat &r2_,
- CV_Assert(rthis.msg_type == CV_32F || (1 << (rthis.levels - 1)) * scale * rthis.max_data_term < numeric_limits<short>::max());
++ std::vector<oclMat> &datas_, oclMat &out_)
+ : rthis(rthis_), u(u_), d(d_), l(l_), r(r_), u2(u2_), d2(d2_), l2(l2_), r2(r2_), datas(datas_), out(out_),
+ zero(Scalar::all(0)), scale(rthis_.msg_type == CV_32F ? 1.0f : 10.0f)
+ {
+ CV_Assert(0 < rthis.ndisp && 0 < rthis.iters && 0 < rthis.levels);
+ CV_Assert(rthis.msg_type == CV_32F || rthis.msg_type == CV_16S);
- vector<oclMat> &datas;
++ CV_Assert(rthis.msg_type == CV_32F || (1 << (rthis.levels - 1)) * scale * rthis.max_data_term < std::numeric_limits<short>::max());
+ }
+
+ void operator()(const oclMat &left, const oclMat &right, oclMat &disp)
+ {
+ CV_Assert(left.size() == right.size() && left.type() == right.type());
+ CV_Assert(left.type() == CV_8UC1 || left.type() == CV_8UC3 || left.type() == CV_8UC4);
+
+ rows = left.rows;
+ cols = left.cols;
+
+ int divisor = (int)pow(2.f, rthis.levels - 1.0f);
+ int lowest_cols = cols / divisor;
+ int lowest_rows = rows / divisor;
+ const int min_image_dim_size = 2;
+ CV_Assert(min(lowest_cols, lowest_rows) > min_image_dim_size);
+
+ init();
+
+ datas[0].create(rows * rthis.ndisp, cols, rthis.msg_type);
+ datas[0].setTo(Scalar_<short>::all(0));
+
+ cv::ocl::stereoBP::comp_data_call(left, right, datas[0], rthis.ndisp, rthis.max_data_term, scale * rthis.data_weight);
+ calcBP(disp);
+ }
+
+ void operator()(const oclMat &data, oclMat &disp)
+ {
+ CV_Assert((data.type() == rthis.msg_type) && (data.rows % rthis.ndisp == 0));
+
+ rows = data.rows / rthis.ndisp;
+ cols = data.cols;
+
+ int divisor = (int)pow(2.f, rthis.levels - 1.0f);
+ int lowest_cols = cols / divisor;
+ int lowest_rows = rows / divisor;
+ const int min_image_dim_size = 2;
+ CV_Assert(min(lowest_cols, lowest_rows) > min_image_dim_size);
+
+ init();
+
+ datas[0] = data;
+
+ calcBP(disp);
+ }
+ private:
+ void init()
+ {
+ u.create(rows * rthis.ndisp, cols, rthis.msg_type);
+ d.create(rows * rthis.ndisp, cols, rthis.msg_type);
+ l.create(rows * rthis.ndisp, cols, rthis.msg_type);
+ r.create(rows * rthis.ndisp, cols, rthis.msg_type);
+
+ if (rthis.levels & 1)
+ {
+ //can clear less area
+ u = zero;
+ d = zero;
+ l = zero;
+ r = zero;
+ }
+
+ if (rthis.levels > 1)
+ {
+ int less_rows = (rows + 1) / 2;
+ int less_cols = (cols + 1) / 2;
+
+ u2.create(less_rows * rthis.ndisp, less_cols, rthis.msg_type);
+ d2.create(less_rows * rthis.ndisp, less_cols, rthis.msg_type);
+ l2.create(less_rows * rthis.ndisp, less_cols, rthis.msg_type);
+ r2.create(less_rows * rthis.ndisp, less_cols, rthis.msg_type);
+
+ if ((rthis.levels & 1) == 0)
+ {
+ u2 = zero;
+ d2 = zero;
+ l2 = zero;
+ r2 = zero;
+ }
+ }
+
+ cv::ocl::stereoBP::load_constants(rthis.ndisp, rthis.max_data_term, scale * rthis.data_weight,
+ scale * rthis.max_disc_term, scale * rthis.disc_single_jump);
+
+ datas.resize(rthis.levels);
+ cols_all.resize(rthis.levels);
+ rows_all.resize(rthis.levels);
+
+ cols_all[0] = cols;
+ rows_all[0] = rows;
+ }
+
+ void calcBP(oclMat &disp)
+ {
+ using namespace cv::ocl::stereoBP;
+
+ for (int i = 1; i < rthis.levels; ++i)
+ {
+ cols_all[i] = (cols_all[i - 1] + 1) / 2;
+ rows_all[i] = (rows_all[i - 1] + 1) / 2;
+
+ datas[i].create(rows_all[i] * rthis.ndisp, cols_all[i], rthis.msg_type);
+ datas[i].setTo(Scalar_<short>::all(0));
+
+ data_step_down_call(cols_all[i], rows_all[i], rows_all[i - 1],
+ datas[i - 1], datas[i], rthis.ndisp);
+ }
+
+ oclMat mus[] = {u, u2};
+ oclMat mds[] = {d, d2};
+ oclMat mrs[] = {r, r2};
+ oclMat mls[] = {l, l2};
+
+ int mem_idx = (rthis.levels & 1) ? 0 : 1;
+
+ for (int i = rthis.levels - 1; i >= 0; --i)
+ {
+ // for lower level we have already computed messages by setting to zero
+ if (i != rthis.levels - 1)
+ level_up_messages_calls(mem_idx, cols_all[i], rows_all[i], rows_all[i + 1],
+ mus, mds, mls, mrs, rthis.ndisp);
+
+ calc_all_iterations_calls(cols_all[i], rows_all[i], rthis.iters, mus[mem_idx],
+ mds[mem_idx], mls[mem_idx], mrs[mem_idx], datas[i],
+ rthis.ndisp, scale * rthis.max_disc_term,
+ scale * rthis.disc_single_jump);
+
+ mem_idx = (mem_idx + 1) & 1;
+ }
+ if (disp.empty())
+ disp.create(rows, cols, CV_16S);
+
+ out = ((disp.type() == CV_16S) ? disp : (out.create(rows, cols, CV_16S), out));
+ out = zero;
+
+ output_call(u, d, l, r, datas.front(), out, rthis.ndisp);
+
+ if (disp.type() != CV_16S)
+ out.convertTo(disp, disp.type());
+
+ release_constants();
+ }
+ StereoBeliefPropagationImpl& operator=(const StereoBeliefPropagationImpl&);
+
+ StereoBeliefPropagation &rthis;
+
+ oclMat &u;
+ oclMat &d;
+ oclMat &l;
+ oclMat &r;
+
+ oclMat &u2;
+ oclMat &d2;
+ oclMat &l2;
+ oclMat &r2;
+
- vector<int> cols_all, rows_all;
++ std::vector<oclMat> &datas;
+ oclMat &out;
+
+ const Scalar zero;
+ const float scale;
+
+ int rows, cols;
+
-
++ std::vector<int> cols_all, rows_all;
+ };
+ }
+
+ void cv::ocl::StereoBeliefPropagation::operator()(const oclMat &left, const oclMat &right, oclMat &disp)
+ {
+ ::StereoBeliefPropagationImpl impl(*this, u, d, l, r, u2, d2, l2, r2, datas, out);
+ impl(left, right, disp);
+ }
+
+ void cv::ocl::StereoBeliefPropagation::operator()(const oclMat &data, oclMat &disp)
+ {
+ ::StereoBeliefPropagationImpl impl(*this, u, d, l, r, u2, d2, l2, r2, datas, out);
+ impl(data, disp);
+ }
}
};
- TEST_P(StereoMatchBM, Accuracy)
- {
+ TEST_P(StereoMatchBM, Regression)
+ {
- Mat left_image = readImage(workdir + "../ocl/aloe-L.png", IMREAD_GRAYSCALE);
- Mat right_image = readImage(workdir + "../ocl/aloe-R.png", IMREAD_GRAYSCALE);
- Mat disp_gold = readImage(workdir + "../ocl/aloe-disp.png", IMREAD_GRAYSCALE);
+ Mat left_image = readImage("stereobm/aloe-L.png", IMREAD_GRAYSCALE);
+ Mat right_image = readImage("stereobm/aloe-R.png", IMREAD_GRAYSCALE);
+ Mat disp_gold = readImage("stereobm/aloe-disp.png", IMREAD_GRAYSCALE);
- ocl::oclMat d_left, d_right;
- ocl::oclMat d_disp(left_image.size(), CV_8U);
- Mat disp;
+ ocl::oclMat d_left, d_right;
+ ocl::oclMat d_disp(left_image.size(), CV_8U);
+ Mat disp;
ASSERT_FALSE(left_image.empty());
ASSERT_FALSE(right_image.empty());
EXPECT_MAT_SIMILAR(disp_gold, disp, 1e-3);
}
- INSTANTIATE_TEST_CASE_P(GPU_Calib3D, StereoMatchBM, testing::Combine(testing::Values(128),
+ INSTANTIATE_TEST_CASE_P(OCL_Calib3D, StereoMatchBM, testing::Combine(testing::Values(128),
- testing::Values(19)));
+ testing::Values(19)));
+ PARAM_TEST_CASE(StereoMatchBP, int, int, int, float, float, float, float)
+ {
+ int ndisp_;
+ int iters_;
+ int levels_;
+ float max_data_term_;
+ float data_weight_;
+ float max_disc_term_;
+ float disc_single_jump_;
+ virtual void SetUp()
+ {
+ ndisp_ = GET_PARAM(0);
+ iters_ = GET_PARAM(1);
+ levels_ = GET_PARAM(2);
+ max_data_term_ = GET_PARAM(3);
+ data_weight_ = GET_PARAM(4);
+ max_disc_term_ = GET_PARAM(5);
+ disc_single_jump_ = GET_PARAM(6);
+ }
+ };
+ TEST_P(StereoMatchBP, Regression)
+ {
+ Mat left_image = readImage("stereobp/aloe-L.png");
+ Mat right_image = readImage("stereobp/aloe-R.png");
+ Mat disp_gold = readImage("stereobp/aloe-disp.png", IMREAD_GRAYSCALE);
+ ocl::oclMat d_left, d_right;
+ ocl::oclMat d_disp;
+ Mat disp;
+ ASSERT_FALSE(left_image.empty());
+ ASSERT_FALSE(right_image.empty());
+ ASSERT_FALSE(disp_gold.empty());
+ d_left.upload(left_image);
+ d_right.upload(right_image);
+ ocl::StereoBeliefPropagation bp(ndisp_, iters_, levels_, max_data_term_, data_weight_,
+ max_disc_term_, disc_single_jump_, CV_16S);
+ bp(d_left, d_right, d_disp);
+ d_disp.download(disp);
+ disp.convertTo(disp, disp_gold.depth());
+ EXPECT_MAT_NEAR(disp_gold, disp, 0.0, "");
+ }
+ INSTANTIATE_TEST_CASE_P(OCL_Calib3D, StereoMatchBP, testing::Combine(testing::Values(64),
+ testing::Values(8),testing::Values(2),testing::Values(25.0f),
+ testing::Values(0.1f),testing::Values(15.0f),testing::Values(1.0f)));
#endif // HAVE_OPENCL
void SurfFeaturesFinder::find(const Mat &image, ImageFeatures &features)
{
Mat gray_image;
- CV_Assert(image.type() == CV_8UC3);
- cvtColor(image, gray_image, CV_BGR2GRAY);
+ CV_Assert((image.type() == CV_8UC3) || (image.type() == CV_8UC1));
+ if(image.type() == CV_8UC3)
+ {
+ cvtColor(image, gray_image, CV_BGR2GRAY);
+ }
+ else
+ {
+ gray_image = image;
+ }
- if (surf == 0)
+ if (surf.empty())
{
detector_->detect(gray_image, features.keypoints);
extractor_->compute(gray_image, features.keypoints, features.descriptors);
else
{
cerr << "Incorrect Optical Flow algorithm - " << name << endl;
- exit(-1);
}
-
- return Ptr<DenseOpticalFlowExt>();
++ return 0;
}
int main(int argc, const char* argv[])
--- /dev/null
- the image center. Swaps quadrant 1 with 3, and 2 with 4.
-
+ #/usr/bin/env python
+
+ import cv2
+ import numpy as np
+ import sys
+
+
+ def shift_dft(src, dst=None):
+ '''
+ Rearrange the quadrants of Fourier image so that the origin is at
-
++ the image center. Swaps quadrant 1 with 3, and 2 with 4.
++
+ src and dst arrays must be equal size & type
+ '''
-
++
+ if dst is None:
+ dst = np.empty(src.shape, src.dtype)
+ elif src.shape != dst.shape:
+ raise ValueError("src and dst must have equal sizes")
+ elif src.dtype != dst.dtype:
+ raise TypeError("src and dst must have equal types")
-
++
+ if src is dst:
+ ret = np.empty(src.shape, src.dtype)
+ else:
+ ret = dst
-
++
+ h, w = src.shape[:2]
-
++
+ cx1 = cx2 = w/2
+ cy1 = cy2 = h/2
- cy2 += 1
-
++
+ # if the size is odd, then adjust the bottom/right quadrants
+ if w % 2 != 0:
+ cx2 += 1
+ if h % 2 != 0:
-
++ cy2 += 1
++
+ # swap quadrants
-
++
+ # swap q1 and q3
+ ret[h-cy1:, w-cx1:] = src[0:cy1 , 0:cx1 ] # q1 -> q3
+ ret[0:cy2 , 0:cx2 ] = src[h-cy2:, w-cx2:] # q3 -> q1
-
++
+ # swap q2 and q4
+ ret[0:cy2 , w-cx2:] = src[h-cy2:, 0:cx2 ] # q2 -> q4
+ ret[h-cy1:, 0:cx1 ] = src[0:cy1 , w-cx1:] # q4 -> q2
-
++
+ if src is dst:
+ dst[:,:] = ret
-
++
+ return dst
+
+ if __name__ == "__main__":
-
++
+ if len(sys.argv)>1:
+ im = cv2.imread(sys.argv[1])
+ else :
+ im = cv2.imread('../c/baboon.jpg')
+ print "usage : python dft.py <image_file>"
+
+ # convert to grayscale
+ im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
+ h, w = im.shape[:2]
-
++
+ realInput = im.astype(np.float64)
-
++
+ # perform an optimally sized dft
+ dft_M = cv2.getOptimalDFTSize(w)
+ dft_N = cv2.getOptimalDFTSize(h)
+
+ # copy A to dft_A and pad dft_A with zeros
+ dft_A = np.zeros((dft_N, dft_M, 2), dtype=np.float64)
+ dft_A[:h, :w, 0] = realInput
-
++
+ # no need to pad bottom part of dft_A with zeros because of
+ # use of nonzeroRows parameter in cv2.dft()
+ cv2.dft(dft_A, dst=dft_A, nonzeroRows=h)
-
++
+ cv2.imshow("win", im)
-
++
+ # Split fourier into real and imaginary parts
+ image_Re, image_Im = cv2.split(dft_A)
-
++
+ # Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2)
+ magnitude = cv2.sqrt(image_Re**2.0 + image_Im**2.0)
-
++
+ # Compute log(1 + Mag)
+ log_spectrum = cv2.log(1.0 + magnitude)
++
+ # Rearrange the quadrants of Fourier image so that the origin is at
+ # the image center
+ shift_dft(log_spectrum, log_spectrum)
+
+ # normalize and display the results as rgb
+ cv2.normalize(log_spectrum, log_spectrum, 0.0, 1.0, cv2.cv.CV_MINMAX)
+ cv2.imshow("magnitude", log_spectrum)
+
+ cv2.waitKey(0)
+ cv2.destroyAllWindows()