From 4632d658892d150fc38747a132612a1209ab1d2f Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Tue, 25 May 2010 14:57:10 +0000 Subject: [PATCH] doxygenated core and imgproc modules (C++ API only) --- modules/core/include/opencv2/core/core.hpp | 1506 ++++++++++++++--- .../core/include/opencv2/core/operations.hpp | 7 + modules/core/src/drawing.cpp | 4 + .../include/opencv2/imgproc/imgproc.hpp | 339 +++- 4 files changed, 1593 insertions(+), 263 deletions(-) diff --git a/modules/core/include/opencv2/core/core.hpp b/modules/core/include/opencv2/core/core.hpp index e529758a4..fb57d1be1 100644 --- a/modules/core/include/opencv2/core/core.hpp +++ b/modules/core/include/opencv2/core/core.hpp @@ -1538,19 +1538,31 @@ public: uint64 state; }; +/*! + Termination criteria in iterative algorithms + */ class CV_EXPORTS TermCriteria { public: - enum { COUNT=1, MAX_ITER=COUNT, EPS=2 }; + 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 from CvTermCriteria operator CvTermCriteria() const; - int type; - int maxCount; - double epsilon; + 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 }; //! converts array (CvMat or IplImage) to cv::Mat @@ -1573,7 +1585,7 @@ CV_EXPORTS void subtract(const Mat& a, const Mat& b, Mat& c); CV_EXPORTS void add(const Mat& a, const Scalar& s, Mat& c, const Mat& mask=Mat()); //! subtracts scalar from a matrix (c = a - s) CV_EXPORTS void subtract(const Mat& a, const Scalar& s, Mat& c, const Mat& mask=Mat()); -//! subtracts matrix from a scalar matrix (c = s - a) +//! subtracts matrix from scalar (c = s - a) CV_EXPORTS void subtract(const Scalar& s, const Mat& a, Mat& c, const Mat& mask=Mat()); //! computes element-wise weighted product of the two arrays (c = scale*a*b) @@ -1604,11 +1616,11 @@ CV_EXPORTS Scalar mean(const Mat& m); CV_EXPORTS Scalar mean(const Mat& m, const Mat& mask); //! computes mean value and standard deviation of all or selected array elements CV_EXPORTS void meanStdDev(const Mat& m, Scalar& mean, Scalar& stddev, const Mat& mask=Mat()); -//! computes norm of array elements +//! computes norm of array CV_EXPORTS double norm(const Mat& a, int normType=NORM_L2); //! computes norm of the difference between two arrays CV_EXPORTS double norm(const Mat& a, const Mat& b, int normType=NORM_L2); -//! computes norm of selected array elements +//! computes norm of the selected array part CV_EXPORTS double norm(const Mat& a, int normType, const Mat& mask); //! computes norm of selected part of the difference between two arrays CV_EXPORTS double norm(const Mat& a, const Mat& b, @@ -1617,13 +1629,13 @@ CV_EXPORTS double norm(const Mat& a, const Mat& b, CV_EXPORTS void normalize( const Mat& a, Mat& b, double alpha=1, double beta=0, int norm_type=NORM_L2, int rtype=-1, const Mat& mask=Mat()); -//! computes global minimum and maximum array elements and their locations +//! finds global minimum and maximum array elements and returns their values and their locations CV_EXPORTS void minMaxLoc(const Mat& a, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, const Mat& mask=Mat()); //! transforms 2D matrix to 1D row or column vector by taking sum, minimum, maximum or mean value over all the rows CV_EXPORTS void reduce(const Mat& m, Mat& dst, int dim, int rtype, int dtype=-1); -//! makes multi-channel array out of several single channel arrays +//! makes multi-channel array out of several single-channel arrays CV_EXPORTS void merge(const Mat* mv, size_t count, Mat& dst); //! copies each plane of a multi-channel array to a dedicated array CV_EXPORTS void split(const Mat& m, Mat* mvbegin); @@ -1658,7 +1670,7 @@ CV_EXPORTS void bitwise_xor(const Mat& a, const Scalar& s, Mat& c, const Mat& ma CV_EXPORTS void bitwise_not(const Mat& a, Mat& c); //! computes element-wise absolute difference of two arrays (c = abs(a - b)) CV_EXPORTS void absdiff(const Mat& a, const Mat& b, Mat& c); -//! computes element-wise absolute difference of array and a scalar (c = abs(a - s)) +//! computes element-wise absolute difference of array and scalar (c = abs(a - s)) CV_EXPORTS void absdiff(const Mat& a, const Scalar& s, Mat& c); //! set mask elements for those array elements which are within the element-specific bounding box (dst = lowerb <= src && src < upperb) CV_EXPORTS void inRange(const Mat& src, const Mat& lowerb, @@ -1668,24 +1680,24 @@ CV_EXPORTS void inRange(const Mat& src, const Scalar& lowerb, const Scalar& upperb, Mat& dst); //! compares elements of two arrays (c = a b) CV_EXPORTS void compare(const Mat& a, const Mat& b, Mat& c, int cmpop); -//! compares elements of array with a scalar (c = a s) +//! compares elements of array with scalar (c = a s) CV_EXPORTS void compare(const Mat& a, double s, Mat& c, int cmpop); //! computes per-element minimum of two arrays (c = min(a, b)) CV_EXPORTS void min(const Mat& a, const Mat& b, Mat& c); -//! computes per-element minimum of array and a scalar (c = min(a, alpha)) +//! computes per-element minimum of array and scalar (c = min(a, alpha)) CV_EXPORTS void min(const Mat& a, double alpha, Mat& c); //! computes per-element maximum of two arrays (c = max(a, b)) CV_EXPORTS void max(const Mat& a, const Mat& b, Mat& c); -//! computes per-element maximum of array and a scalar (c = max(a, alpha)) +//! computes per-element maximum of array and scalar (c = max(a, alpha)) CV_EXPORTS void max(const Mat& a, double alpha, Mat& c); -//! computes square root of each matrix element +//! computes square root of each matrix element (b = a**0.5) CV_EXPORTS void sqrt(const Mat& a, Mat& b); -//! raises the input matrix elements to the specified power +//! raises the input matrix elements to the specified power (b = a**power) CV_EXPORTS void pow(const Mat& a, double power, Mat& b); -//! computes exponent of each matrix element +//! computes exponent of each matrix element (b = e**a) CV_EXPORTS void exp(const Mat& a, Mat& b); -//! computes natural logarithm of each matrix element +//! computes natural logarithm of absolute value of each matrix element: b = log(abs(a)) CV_EXPORTS void log(const Mat& a, Mat& b); //! computes cube root of the argument CV_EXPORTS float cubeRoot(float val); @@ -1740,127 +1752,259 @@ CV_EXPORTS void sortIdx(const Mat& a, Mat& b, int flags); CV_EXPORTS int solveCubic(const Mat& coeffs, Mat& roots); //! finds real and complex roots of a polynomial CV_EXPORTS double solvePoly(const Mat& coeffs, Mat& roots, int maxIters=300); -//! +//! finds eigenvalues of a symmetric matrix CV_EXPORTS bool eigen(const Mat& a, Mat& eigenvalues, int lowindex=-1, int highindex=-1); +//! finds eigenvalues and eigenvectors of a symmetric matrix CV_EXPORTS bool eigen(const Mat& a, Mat& eigenvalues, Mat& eigenvectors, int lowindex=-1, int highindex=-1); - +//! 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 void calcCovarMatrix( const Mat& samples, Mat& covar, Mat& 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(const Mat& data, const Mat& mean, int flags, int maxComponents=0); + //! operator that performs PCA. The previously stored data, if any, is released PCA& operator()(const Mat& data, const Mat& mean, int flags, int maxComponents=0); + //! projects vector from the original space to the principal components subspace Mat project(const Mat& vec) const; + //! projects vector from the original space to the principal components subspace void project(const Mat& vec, Mat& result) const; + //! reconstructs the original vector from the projection Mat backProject(const Mat& vec) const; + //! reconstructs the original vector from the projection void backProject(const Mat& vec, Mat& result) const; - Mat eigenvectors; - Mat eigenvalues; - Mat mean; + 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 }; +/*! + 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( const Mat& m, int flags=0 ); + //! the operator that performs SVD. The previously allocated SVD::u, SVD::w are SVD::vt are released. SVD& operator ()( const Mat& m, int flags=0 ); + //! finds dst = arg min_{|dst|=1} |m*dst| static void solveZ( const Mat& m, Mat& 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( const Mat& rhs, Mat& dst ) const; Mat u, w, vt; }; +//! computes Mahalanobis distance between two vectors: sqrt((v1-v2)'*icovar*(v1-v2)), where icovar is the inverse covariation matrix CV_EXPORTS double Mahalanobis(const Mat& v1, const Mat& v2, const Mat& icovar); +//! a synonym for Mahalanobis static inline double Mahalonobis(const Mat& v1, const Mat& v2, const Mat& icovar) { return Mahalanobis(v1, v2, icovar); } +//! performs forward or inverse 1D or 2D Discrete Fourier Transformation CV_EXPORTS void dft(const Mat& src, Mat& dst, int flags=0, int nonzeroRows=0); +//! performs inverse 1D or 2D Discrete Fourier Transformation CV_EXPORTS void idft(const Mat& src, Mat& dst, int flags=0, int nonzeroRows=0); +//! performs forward or inverse 1D or 2D Discrete Cosine Transformation CV_EXPORTS void dct(const Mat& src, Mat& dst, int flags=0); +//! performs inverse 1D or 2D Discrete Cosine Transformation CV_EXPORTS void idct(const Mat& src, Mat& 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 void mulSpectrums(const Mat& a, const Mat& b, Mat& 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 int getOptimalDFTSize(int vecsize); -enum { KMEANS_RANDOM_CENTERS=0, KMEANS_PP_CENTERS=2, KMEANS_USE_INITIAL_LABELS=1 }; -CV_EXPORTS double kmeans( const Mat& data, int K, Mat& best_labels, +/*! + 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 double kmeans( const Mat& data, int K, Mat& bestLabels, TermCriteria criteria, int attempts, int flags, Mat* centers ); +//! returns the thread-local Random number generator CV_EXPORTS RNG& theRNG(); + +//! returns the next unifomly-distributed random number of the specified type template static inline _Tp randu() { return (_Tp)theRNG(); } +//! fills array with uniformly-distributed random numbers from the range [low, high) static inline void randu(Mat& dst, const Scalar& low, const Scalar& high) { theRNG().fill(dst, RNG::UNIFORM, low, high); } + +//! fills array with normally-distributed random numbers with the specified mean and the standard deviation static inline void randn(Mat& dst, const Scalar& mean, const Scalar& stddev) { theRNG().fill(dst, RNG::NORMAL, mean, stddev); } + +//! shuffles the input array elements CV_EXPORTS void randShuffle(Mat& dst, double iterFactor=1., RNG* rng=0); - +//! draws the line segment (pt1, pt2) in the image CV_EXPORTS void line(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 void rectangle(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(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 void circle(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 void ellipse(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 void ellipse(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); +//! 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() ); +//! 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 ); +//! clips the line segment by the rectangle Rect(0, 0, imgSize.width, imgSize.height) CV_EXPORTS bool clipLine(Size imgSize, Point& pt1, Point& pt2); -CV_EXPORTS bool clipLine(Rect img_rect, Point& pt1, Point& pt2); +//! clips the line segment by the rectangle imgRect +CV_EXPORTS bool clipLine(Rect imgRect, Point& pt1, 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 void ellipse2Poly( Point center, Size axes, int angle, int arcStart, int arcEnd, int delta, vector& pts ); @@ -1877,17 +2021,64 @@ enum FONT_ITALIC = 16 }; +//! renders text string in the image CV_EXPORTS 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 Size getTextSize(const string& text, int fontFace, double fontScale, int thickness, 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_& M1 = (Mat_&)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_ 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(0,0)/E.at(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_ 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 class CV_EXPORTS Mat_ : public Mat { public: @@ -1896,22 +2087,25 @@ public: 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); - //! other forms of the above constructor + //! 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); //! copy/conversion contructor. If m is of different type, it's converted Mat_(const Mat& m); //! copy constructor Mat_(const Mat_& m); - //! construct a matrix on top of user-allocated data. - // step is in bytes(!!!), regardless of the type + //! 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); - // minor selection + //! selects a submatrix Mat_(const Mat_& m, const Range& rowRange, const Range& colRange); + //! selects a submatrix Mat_(const Mat_& m, const Rect& roi); //! to support complex matrix expressions Mat_(const MatExpr_Base& expr); @@ -1934,6 +2128,7 @@ public: //! 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); //! cross-product Mat_ cross(const Mat_& m) const; @@ -1960,17 +2155,17 @@ public: mul(const MatExpr_ >, Mat>& m, double scale=1) const; - // overridden forms of Mat::elemSize() etc. + //! 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() const; - // returns step()/sizeof(_Tp) + //! returns step()/sizeof(_Tp) size_t stepT() const; - // overridden forms of Mat::zeros() etc. Data type is omitted, of course + //! overridden forms of Mat::zeros() etc. Data type is omitted, of course static MatExpr_Initializer zeros(int rows, int cols); static MatExpr_Initializer zeros(Size size); static MatExpr_Initializer ones(int rows, int cols); @@ -1978,13 +2173,13 @@ public: static MatExpr_Initializer eye(int rows, int cols); static MatExpr_Initializer eye(Size size); - // some more overriden methods + //! some more overriden methods Mat_ reshape(int _rows) const; 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; - // more convenient forms of row and element access operators + //! more convenient forms of row and element access operators _Tp* operator [](int y); const _Tp* operator [](int y) const; @@ -1995,10 +2190,10 @@ public: _Tp& operator ()(int i); const _Tp& operator ()(int i) const; - // to support matrix expressions + //! to support matrix expressions operator MatExpr_() const; - // conversion to vector. + //! conversion to vector. operator vector<_Tp>() const; }; @@ -2034,6 +2229,10 @@ typedef Mat_ Mat4d; //////////// Iterators & Comma initializers ////////////////// +/*! + Matrix read-only iterator + + */ template class CV_EXPORTS MatConstIterator_ { @@ -2041,22 +2240,37 @@ public: typedef _Tp value_type; typedef int difference_type; + //! 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); + //! copy constructor MatConstIterator_(const MatConstIterator_& it); - MatConstIterator_& operator = (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 [](int i) const; + //! shifts the iterator forward by the specified number of elements MatConstIterator_& operator += (int ofs); + //! shifts the iterator backward by the specified number of elements MatConstIterator_& operator -= (int 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; const Mat_<_Tp>* m; @@ -2065,6 +2279,10 @@ public: }; +/*! + Matrix read-write iterator + +*/ template class CV_EXPORTS MatIterator_ : public MatConstIterator_<_Tp> { @@ -2073,33 +2291,64 @@ public: 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); + //! 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 [](int i) const; + //! shifts the iterator forward by the specified number of elements MatIterator_& operator += (int ofs); + //! shifts the iterator backward by the specified number of elements MatIterator_& operator -= (int ofs); + //! decrements the iterator MatIterator_& operator --(); + //! decrements the iterator MatIterator_ operator --(int); + //! increments the iterator MatIterator_& operator ++(); + //! increments the iterator MatIterator_ operator ++(int); }; template 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_(2,2) << a, -b, b, a); + \endcode +*/ template class CV_EXPORTS MatCommaInitializer_ : public MatExpr_, Mat_<_Tp>, MatOp_Iter_<_Tp> >, Mat_<_Tp> > { 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 MatCommaInitializer_<_Tp>& operator , (T2 v); + //! the conversion operator operator Mat_<_Tp>() const; + //! another form of conversion operator Mat_<_Tp> operator *() const; void assignTo(Mat& m, int type=-1) const; }; @@ -2118,23 +2367,60 @@ public: }; #endif +/*! + 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 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 class CV_EXPORTS AutoBuffer { public: typedef _Tp value_type; + //! 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]; }; @@ -2143,99 +2429,160 @@ protected: class MatND; class SparseMat; +/*! + n-Dimensional Dense Matrix Class. + + The class cv::MatND describes n-dimensional dense numerical single-channel or multi-channel array. + This is a convenient representation for multi-dimensional histograms + (when they are not very sparse, otherwise cv::SparseMat will do better), + voxel volumes, stacked motion fields etc. The data layout of matrix M is defined by the array of M.step[], + so that the address of element (i_0,...,i_{M.dims-1}), where 0 <= i_k < M.size[k] is computed as: + + addr(M_{i_0,...,i_{M.dims-1}}) = M.data + M.step[0]*i_0 + M.step[1]*i_1 + ... + M.step[M.dims-1]*i_{M.dims-1} + + which is more general form of the respective formula for cv::Mat, wherein size[0] ~ rows, + size[1] ~ cols, step[0] was simply called step, and step[1] was not stored at all but computed as Mat::elemSize(). + + In other aspects cv::MatND is also very similar to cv::Mat, with the following limitations and differences: +
    +
  • much less operations are implemented for \texttt{MatND} +
  • currently, algebraic expressions with \texttt{MatND}'s are not supported +
  • the cv::MatND iterator is completely different from cv::Mat_ and cv::SparseMat_ iterators. + The latter are per-element iterators, while the former is per-slice iterator, see below. +
+ + Here is how you can use cv::MatND to compute NxNxN histogram of color 8bpp image + (i.e. each channel value ranges from 0..255 and we quantize it to 0..N-1): + + \code + void computeColorHist(const Mat& image, MatND& hist, int N) + { + const int histSize[] = {N, N, N}; + + // make sure that the histogram has proper size and type + hist.create(3, histSize, CV_32F); + + // and clear it + hist = Scalar(0); + + // the loop below assumes that the image + // is 8-bit 3-channel, so let's check it. + CV_Assert(image.type() == CV_8UC3); + MatConstIterator_ it = image.begin(), + it_end = image.end(); + for( ; it != it_end; ++it ) + { + const Vec3b& pix = *it; + + // we could have incremented the cells by 1.f/(image.rows*image.cols) + // instead of 1.f to make the histogram normalized. + hist.at(pix[0]*N/256, pix[1]*N/256, pix[2]*N/256) += 1.f; + } + } + \endcode +*/ class CV_EXPORTS MatND { public: - // default constructor + //! default constructor MatND(); - // constructs array with specific size and data type + //! constructs array with specific size and data type MatND(int _ndims, const int* _sizes, int _type); - // constructs array and fills it with the specified value + //! constructs array and fills it with the specified value MatND(int _ndims, const int* _sizes, int _type, const Scalar& _s); - // copy constructor. only the header is copied. + //! copy constructor. only the header is copied. MatND(const MatND& m); - // sub-array selection. only the header is copied + //! sub-array selection. only the header is copied MatND(const MatND& m, const Range* ranges); - // converts 2D matrix to ND matrix + //! converts 2D matrix to ND matrix explicit MatND(const Mat& m); - // converts old-style nd array to MatND; optionally, copies the data + //! converts old-style nd array to MatND; optionally, copies the data MatND(const CvMatND* m, bool copyData=false); + //! destructor ~MatND(); + //! the copy operator MatND& operator = (const MatND& m); + //! helper method for matrix expressions void assignTo( MatND& m, int type ) const; - // creates a complete copy of the matrix (all the data is copied) + //! creates a complete copy of the matrix (all the data is copied) MatND clone() const; - // sub-array selection; only the header is copied + //! sub-array selection; only the header is copied MatND operator()(const Range* ranges) const; - // copies the data to another matrix. - // Calls m.create(this->size(), this->type()) prior to - // copying the data + //! copies the data to another matrix. Calls m.create(this->size(), this->type()) prior to copying the data void copyTo( MatND& m ) const; - // copies only the selected elements to another matrix. + //! copies only the selected elements to another matrix. void copyTo( MatND& m, const MatND& mask ) const; - // converts data to the specified data type. - // calls m.create(this->size(), rtype) prior to the conversion + //! converts data to the specified data type. Calls m.create(this->size(), rtype) prior to the conversion void convertTo( MatND& m, int rtype, double alpha=1, double beta=0 ) const; - // assigns "s" to each array element. + //! assigns "s" to each array element. MatND& operator = (const Scalar& s); - // assigns "s" to the selected elements of array - // (or to all the elements if mask==MatND()) + //! assigns "s" to the selected elements of array (or to all the elements if mask==MatND()) MatND& setTo(const Scalar& s, const MatND& mask=MatND()); - // modifies geometry of array without copying the data + //! modifies geometry of array without copying the data MatND reshape(int _newcn, int _newndims=0, const int* _newsz=0) const; - // allocates a new buffer for the data unless the current one already - // has the specified size and type. + //! allocates a new buffer for the data unless the current one already has the specified size and type. void create(int _ndims, const int* _sizes, int _type); - // manually increment reference counter (use with care !!!) + //! manually increment reference counter (use with care !!!) void addref(); - // decrements the reference counter. Dealloctes the data when - // the reference counter reaches zero. + //! decrements the reference counter. Dealloctes the data when the reference counter reaches zero. void release(); - // converts the matrix to 2D Mat or to the old-style CvMatND. - // In either case the data is not copied. + //! converts the matrix to 2D Mat without copying the data operator Mat() const; + //! converts the matrix to CvMatND without copying the data operator CvMatND() const; - // returns true if the array data is stored continuously + //! returns true if the array data is stored continuously bool isContinuous() const; - // returns size of each element in bytes + //! returns size of each element in bytes size_t elemSize() const; - // returns size of each element channel in bytes + //! returns size of each element channel in bytes size_t elemSize1() const; - // returns OpenCV data type id (CV_8UC1, ... CV_64FC4,...) + //! returns OpenCV data type id (CV_8UC1, ... CV_64FC4,...) int type() const; - // returns depth (CV_8U ... CV_64F) + //! returns depth (CV_8U ... CV_64F) int depth() const; - // returns the number of channels + //! returns the number of channels int channels() const; - // step1() ~ step()/elemSize1() + //! returns step()/elemSize1() size_t step1(int i) const; - // return pointer to the element (versions for 1D, 2D, 3D and generic nD cases) + //! returns pointer to the element of 1D matrix uchar* ptr(int i0); + //! returns read-only pointer to the element of 1D matrix const uchar* ptr(int i0) const; + //! returns pointer to the element of 2D matrix uchar* ptr(int i0, int i1); + //! returns read-only pointer to the element of 2D matrix const uchar* ptr(int i0, int i1) const; + //! returns pointer to the element of 3D matrix uchar* ptr(int i0, int i1, int i2); + //! returns read-only pointer to the element of 3D matrix const uchar* ptr(int i0, int i1, int i2) const; + //! returns pointer to the element of nD matrix uchar* ptr(const int* idx); + //! returns read-only pointer to the element of nD matrix const uchar* ptr(const int* idx) const; - // convenient template methods for element access. - // note that _Tp must match the actual matrix type - - // the functions do not do any on-fly type conversion + //! returns reference to the element of 1D matrix template _Tp& at(int i0); + //! returns read-only reference to the element of 1D matrix template const _Tp& at(int i0) const; + //! returns reference to the element of 2D matrix template _Tp& at(int i0, int i1); + //! returns read-only reference to the element of 2D matrix template const _Tp& at(int i0, int i1) const; + //! returns reference to the element of 3D matrix template _Tp& at(int i0, int i1, int i2); + //! returns read-only reference to the element of 3D matrix template const _Tp& at(int i0, int i1, int i2) const; + //! returns reference to the element of nD matrix template _Tp& at(const int* idx); + //! returns read-only reference to the element of nD matrix template const _Tp& at(const int* idx) const; enum { MAGIC_VAL=0x42FE0000, AUTO_STEP=-1, @@ -2259,27 +2606,88 @@ public: size_t step[MAX_DIM]; }; +/*! + n-Dimensional Dense Matrix Iterator Class. + + The class cv::NAryMatNDIterator is used for iterating over one or more n-dimensional dense arrays (cv::MatND'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(MatND& 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 + MatNDIterator it(hist); + 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 = MatNDIterator(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 MatND + 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 NAryMatNDIterator { public: + //! the default constructor NAryMatNDIterator(); + //! the full constructor taking arbitrary number of n-dim matrices NAryMatNDIterator(const MatND* arrays, size_t count); + //! another form of the constructor taking pointers to the headers NAryMatNDIterator(const MatND** arrays, size_t count); - NAryMatNDIterator(const MatND& m1); - NAryMatNDIterator(const MatND& m1, const MatND& m2); - NAryMatNDIterator(const MatND& m1, const MatND& m2, const MatND& m3); - NAryMatNDIterator(const MatND& m1, const MatND& m2, const MatND& m3, const MatND& m4); - NAryMatNDIterator(const MatND& m1, const MatND& m2, const MatND& m3, - const MatND& m4, const MatND& m5); - NAryMatNDIterator(const MatND& m1, const MatND& m2, const MatND& m3, - const MatND& m4, const MatND& m5, const MatND& m6); - + //! the full constructor for iteration through a single n-dim matrix + NAryMatNDIterator(const MatND& m0); + //! the full constructor for iteration through 2 n-dim matrices + NAryMatNDIterator(const MatND& m0, const MatND& m1); + //! the full constructor for iteration through 3 n-dim matrices + NAryMatNDIterator(const MatND& m0, const MatND& m1, const MatND& m2); + //! the full constructor for iteration through 4 n-dim matrices + NAryMatNDIterator(const MatND& m0, const MatND& m1, const MatND& m2, const MatND& m3); + //! the full constructor for iteration through 5 n-dim matrices + NAryMatNDIterator(const MatND& m0, const MatND& m1, const MatND& m2, + const MatND& m3, const MatND& m4); + //! the full constructor for iteration through 6 n-dim matrices + NAryMatNDIterator(const MatND& m0, const MatND& m1, const MatND& m2, + const MatND& m3, const MatND& m4, const MatND& m5); + //! the separate iterator initialization method void init(const MatND** arrays, size_t count); + //! proceeds to the next plane of every iterated matrix NAryMatNDIterator& operator ++(); + //! proceeds to the next plane of every iterated matrix (postfix increment operator) NAryMatNDIterator operator ++(int); + //! the iterated arrays vector arrays; + //! the current planes vector planes; int nplanes; @@ -2287,113 +2695,215 @@ protected: int iterdepth, idx; }; +//! adds one n-dim array to another CV_EXPORTS void add(const MatND& a, const MatND& b, MatND& c, const MatND& mask); +//! subtracts one n-dim array from another CV_EXPORTS void subtract(const MatND& a, const MatND& b, MatND& c, const MatND& mask); +//! adds one n-dim array to another CV_EXPORTS void add(const MatND& a, const MatND& b, MatND& c); +//! subtracts one n-dim array from another CV_EXPORTS void subtract(const MatND& a, const MatND& b, MatND& c); +//! adds scalar to n-dim array CV_EXPORTS void add(const MatND& a, const Scalar& s, MatND& c, const MatND& mask=MatND()); - -CV_EXPORTS void multiply(const MatND& a, const MatND& b, MatND& c, double scale=1); -CV_EXPORTS void divide(const MatND& a, const MatND& b, MatND& c, double scale=1); -CV_EXPORTS void divide(double scale, const MatND& b, MatND& c); - +//! subtracts scalar from n-dim array CV_EXPORTS void subtract(const Scalar& s, const MatND& a, MatND& c, const MatND& mask=MatND()); +//! computes element-wise weighted product of the two n-dim arrays (c = scale*a*b) +CV_EXPORTS void multiply(const MatND& a, const MatND& b, MatND& c, double scale=1); +//! computes element-wise weighted quotient of the two n-dim arrays (c = scale*a/b) +CV_EXPORTS void divide(const MatND& a, const MatND& b, MatND& c, double scale=1); +//! computes element-wise weighted reciprocal of n-dim array (c = scale/b) +CV_EXPORTS void divide(double scale, const MatND& b, MatND& c); +//! adds weighted n-dim array to another (c = a*alpha + b) CV_EXPORTS void scaleAdd(const MatND& a, double alpha, const MatND& b, MatND& c); +//! computes weighted sum of 2 n-dim arrays (c = a*alpha + b*beta + gamma) CV_EXPORTS void addWeighted(const MatND& a, double alpha, const MatND& b, double beta, double gamma, MatND& c); - +//! computes the sum of n-dim array elements CV_EXPORTS Scalar sum(const MatND& m); +//! computes the number of non-zero elements of n-dim array CV_EXPORTS int countNonZero( const MatND& m ); - +//! computes mean value of n-dim array elements CV_EXPORTS Scalar mean(const MatND& m); +//! computes mean value of selected elements of n-dim array CV_EXPORTS Scalar mean(const MatND& m, const MatND& mask); +//! computes the mean and the standard deviation of n-dim array CV_EXPORTS void meanStdDev(const MatND& m, Scalar& mean, Scalar& stddev, const MatND& mask=MatND()); +//! computes norm of n-dim array CV_EXPORTS double norm(const MatND& a, int normType=NORM_L2, const MatND& mask=MatND()); +//! computes norm of the difference between 2 n-dim arrays CV_EXPORTS double norm(const MatND& a, const MatND& b, int normType=NORM_L2, const MatND& mask=MatND()); +//! 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 MatND& a, MatND& b, double alpha=1, double beta=0, int norm_type=NORM_L2, int rtype=-1, const MatND& mask=MatND()); - +//! finds global minimum and maximum array elements and returns their values and their locations CV_EXPORTS void minMaxLoc(const MatND& a, double* minVal, double* maxVal, int* minIdx=0, int* maxIdx=0, const MatND& mask=MatND()); - +//! makes multi-channel n-dim array out of several single-channel n-dim arrays CV_EXPORTS void merge(const MatND* mvbegin, size_t count, MatND& dst); +//! copies each plane of a multi-channel n-dim array to a dedicated array CV_EXPORTS void split(const MatND& m, MatND* mv); +//! copies selected channels from the input arrays to the selected channels of the output arrays CV_EXPORTS void mixChannels(const MatND* src, int nsrcs, MatND* dst, int ndsts, const int* fromTo, size_t npairs); - +//! computes bitwise conjunction of the two n-dim arrays (c = a & b) CV_EXPORTS void bitwise_and(const MatND& a, const MatND& b, MatND& c, const MatND& mask=MatND()); +//! computes bitwise disjunction of the two n-dim arrays (c = a | b) CV_EXPORTS void bitwise_or(const MatND& a, const MatND& b, MatND& c, const MatND& mask=MatND()); +//! computes bitwise exclusive-or of the two n-dim arrays (c = a ^ b) CV_EXPORTS void bitwise_xor(const MatND& a, const MatND& b, MatND& c, const MatND& mask=MatND()); +//! computes bitwise conjunction of n-dim array and scalar (c = a & s) CV_EXPORTS void bitwise_and(const MatND& a, const Scalar& s, MatND& c, const MatND& mask=MatND()); +//! computes bitwise disjunction of n-dim array and scalar (c = a | s) CV_EXPORTS void bitwise_or(const MatND& a, const Scalar& s, MatND& c, const MatND& mask=MatND()); +//! computes bitwise exclusive-or of n-dim array and scalar (c = a ^ s) CV_EXPORTS void bitwise_xor(const MatND& a, const Scalar& s, MatND& c, const MatND& mask=MatND()); +//! inverts each bit of each n-dim array element (c = ~a) CV_EXPORTS void bitwise_not(const MatND& a, MatND& c); +//! computes element-wise absolute difference of two n-dim arrays (c = abs(a - b)) CV_EXPORTS void absdiff(const MatND& a, const MatND& b, MatND& c); +//! computes element-wise absolute difference of n-dim array and scalar (c = abs(a - s)) CV_EXPORTS void absdiff(const MatND& a, const Scalar& s, MatND& c); +//! set mask elements for those n-dim array elements which are within the element-specific bounding box (dst = lowerb <= src && src < upperb) CV_EXPORTS void inRange(const MatND& src, const MatND& lowerb, const MatND& upperb, MatND& dst); +//! set mask elements for those n-dim array elements which are within the fixed bounding box (dst = lowerb <= src && src < upperb) CV_EXPORTS void inRange(const MatND& src, const Scalar& lowerb, const Scalar& upperb, MatND& dst); +//! compares elements of two arrays (c = a b) CV_EXPORTS void compare(const MatND& a, const MatND& b, MatND& c, int cmpop); +//! compares elements of two arrays (c = a b) CV_EXPORTS void compare(const MatND& a, double s, MatND& c, int cmpop); +//! computes per-element minimum of two n-dim arrays (c = min(a, b)) CV_EXPORTS void min(const MatND& a, const MatND& b, MatND& c); +//! computes per-element minimum of n-dim array and scalar (c = min(a, s)) CV_EXPORTS void min(const MatND& a, double alpha, MatND& c); +//! computes per-element maximum of two n-dim arrays (c = max(a, s)) CV_EXPORTS void max(const MatND& a, const MatND& b, MatND& c); +//! computes per-element maximum of n-dim array and scalar (c = min(a, s)) CV_EXPORTS void max(const MatND& a, double alpha, MatND& c); - +//! computes square root of each element of n-dim array (b = a**0.5) CV_EXPORTS void sqrt(const MatND& a, MatND& b); +//! raises each n-dim array element to the specific power (b = a**power) CV_EXPORTS void pow(const MatND& a, double power, MatND& b); +//! computes exponent of each n-dim array element (b = e**a) CV_EXPORTS void exp(const MatND& a, MatND& b); +//! computes natural logarithm of absolute value of each n-dim array element (b = log(abs(a))) CV_EXPORTS void log(const MatND& a, MatND& b); +//! checks that each matrix element is within the specified range. CV_EXPORTS bool checkRange(const MatND& a, bool quiet=true, int* idx=0, double minVal=-DBL_MAX, double maxVal=DBL_MAX); - + 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); +/*! + Template n-dimensional dense matrix class derived from cv::MatND + + The class relates to cv::MatND almost like cv::Mat_ relates to cv::Mat - it provides + a bit more convenient element access operations and adds no extra members + or virtual methods to the base class, thus references/pointers to cv::MatND_ and cv::MatND + can be easily converted one to another, e.g. + + \code + void computeColorHist(const Mat& image, MatND& hist, int N) + { + const int histSize[] = {N, N, N}; + + // make sure that the histogram has proper size and type + hist.create(3, histSize, CV_32F); + + // and clear it + hist = Scalar(0); + + // the loop below assumes that the image + // is 8-bit 3-channel, so let's check it. + CV_Assert(image.type() == CV_8UC3); + MatConstIterator_ it = image.begin(), + it_end = image.end(); + MatND_& hist_ = (MatND_&)hist; + + for( ; it != it_end; ++it ) + { + const Vec3b& pix = *it; + hist_(pix[0]*N/256, pix[1]*N/256, pix[2]*N/256) += 1.f; + } + } + \endcode +*/ template class CV_EXPORTS MatND_ : public MatND { public: typedef _Tp value_type; typedef typename DataType<_Tp>::channel_type channel_type; + //! the default constructor MatND_(); + //! the full constructor, equivalent to MatND(dims, _sizes, DataType<_Tp>::type) MatND_(int dims, const int* _sizes); + //! the full constructor that sets each matrix element to the specified value MatND_(int dims, const int* _sizes, const _Tp& _s); + //! the copy constructor. If m.type() != DataType<_Tp>::type, all the data is converted MatND_(const MatND& m); + //! the copy constructor. MatND_(const MatND_& m); + //! constructor for the specified subarray. The data is not copied! MatND_(const MatND_& m, const Range* ranges); + //! the conversion constructor MatND_(const CvMatND* m, bool copyData=false); + //! the assignment operator. If m.type() != DataType<_Tp>::type, all the data is converted MatND_& operator = (const MatND& m); + //! the assignment operator. No data is copied MatND_& operator = (const MatND_& m); + //! the assignment operator. All the elements are set to the specified value MatND_& operator = (const _Tp& s); + //! equivalent to create(dims, _sizes, DataType<_Tp>::type) void create(int dims, const int* _sizes); + //! conversion to another data type template operator MatND_() const; + //! creates full copy of the matrix, including the data MatND_ clone() const; + //! creates header for the specified submatrix. No data is copied MatND_ operator()(const Range* ranges) const; - + + //! returns the element size in bytes size_t elemSize() const; + //! returns the size of each element channel in bytes size_t elemSize1() const; + //! returns DataType<_Tp>::type int type() const; + //! returns DataType<_Tp>::depth int depth() const; + //! returns DataType<_Tp>::channels int channels() const; + //! returns step[i]/elemSize() size_t stepT(int i) const; + //! returns step[i]/elemSize1() size_t step1(int i) 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 (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; }; @@ -2404,12 +2914,98 @@ class SparseMatConstIterator; template class SparseMatIterator_; template 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 and cv::MatND are 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: + +
    +
  1. 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(idx) += 1.f; + } + \endcode + +
  2. Sparse matrix iterators. Like cv::Mat iterators and unlike cv::MatND 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_ + it = sparse_mat.begin(), + it_end = sparse_mat.end(); + 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. + +
  3. 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_ it = _a->begin(), + it_end = _a->end(); + 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(anode->idx,&anode->hashval); + ccorr += avalue*bvalue; + } + return ccorr; + } + \endcode +
+*/ 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); @@ -2425,184 +3021,235 @@ public: int size[CV_MAX_DIM]; }; - // sparse matrix node - element of a hash table + //! 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]; }; - ////////// constructors and destructor ////////// - // default constructor + //! default constructor SparseMat(); - // creates matrix of the specified size and type + //! creates matrix of the specified size and type SparseMat(int dims, const int* _sizes, int _type); - // copy constructor + //! copy constructor SparseMat(const SparseMat& m); - // converts dense 2d matrix to the sparse form, - // if try1d is true and matrix is a single-column matrix (Nx1), - // then the sparse matrix will be 1-dimensional. + //! 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. + */ SparseMat(const Mat& m, bool try1d=false); - // converts dense n-d matrix to the sparse form + //! converts dense n-dim array to the sparse form SparseMat(const MatND& m); - // converts old-style sparse matrix to the new-style. - // all the data is copied, so that "m" can be safely - // deleted after the conversion + //! converts old-style sparse matrix to the new-style. All the data is copied SparseMat(const CvSparseMat* m); - // destructor + //! the destructor ~SparseMat(); - ///////// assignment operations /////////// - - // this is O(1) operation; no data is copied + //! assignment operator. This is O(1) operation, i.e. no data is copied SparseMat& operator = (const SparseMat& m); - // (equivalent to the corresponding constructor with try1d=false) + //! equivalent to the corresponding constructor with try1d=false SparseMat& operator = (const Mat& m); + //! converts dense n-dim array to the sparse form SparseMat& operator = (const MatND& m); - // creates full copy of the matrix + //! creates full copy of the matrix SparseMat clone() const; - // copy all the data to the destination matrix. - // the destination will be reallocated if needed. + //! copies all the data to the destination matrix. All the previous content of m is erased void copyTo( SparseMat& m ) const; - // converts 1D or 2D sparse matrix to dense 2D matrix. - // If the sparse matrix is 1D, then the result will - // be a single-column matrix. + //! converts 1D or 2D sparse matrix to dense 2D matrix. If the sparse matrix is 1D, then the result will be a single-column matrix. void copyTo( Mat& m ) const; - // converts arbitrary sparse matrix to dense matrix. - // watch out the memory! + //! converts sparse matrix to the dense form. The output matrix may require a lot of memory! void copyTo( MatND& m ) const; - // multiplies all the matrix elements by the specified scalar + //! 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 matrix with optional type conversion and scaling. - // When rtype=-1, the destination element type will be the same - // as the sparse matrix element type. - // Otherwise rtype will specify the depth and - // the number of channels will remain the same is in the sparse matrix + //! 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; + //! converts sparse matrix to dense 2D 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( MatND& 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 it was already of 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. + //! 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 matrix elements to 0, which means clearing the hash table. + //! sets all the sparse matrix elements to 0, which means clearing the hash table. void clear(); - // manually increases reference counter to the header. + //! manually increments the reference counter to the header. void addref(); - // decreses the header reference counter, when it reaches 0, - // the header and all the underlying data are deallocated. + // 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. + //! converts sparse matrix to the old-style representation; all the elements are copied. operator CvSparseMat*() const; - // size of each element in bytes - // (the matrix nodes will be bigger because of - // element indices and other SparseMat::Node elements). + //! returns the size of each element in bytes (not including the overhead - the space occupied by SparseMat::Node elements) size_t elemSize() const; - // elemSize()/channels() + //! returns elemSize()/channels() size_t elemSize1() const; - // the same is in Mat and MatND + //! 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 and 0 if the matrix is not allocated + //! returns the array of sizes, or NULL if the matrix is not allocated const int* size() const; - // returns i-th size (or 0) + //! returns the size of i-th matrix dimension (or 0) int size(int i) const; - // returns the matrix dimensionality + //! returns the matrix dimensionality int dims() const; - // returns the number of non-zero elements + //! returns the number of non-zero elements (=the number of hash table nodes) size_t nzcount() const; - // compute element hash value from the element indices: - // 1D case + //! computes the element hash value (1D case) size_t hash(int i0) const; - // 2D case + //! computes the element hash value (2D case) size_t hash(int i0, int i1) const; - // 3D case + //! computes the element hash value (3D case) size_t hash(int i0, int i1, int i2) const; - // n-D case + //! computes the element hash value (nD case) size_t hash(const int* idx) const; - // low-level element-acccess functions, - // special variants for 1D, 2D, 3D cases and the generic one for n-D case. - // - // return pointer to the matrix element. - // if the element is there (it's non-zero), the pointer to it is returned - // if it's not there and createMissing=false, NULL pointer is returned - // if it's not there and createMissing=true, then the new element - // is created and initialized with 0. Pointer to it is returned - // If the optional hashval pointer is not NULL, the element hash value is - // not computed, but *hashval is taken instead. + //@{ + /*! + specialized variants for 1D, 2D, 3D cases and the generic one for n-D case. + + return pointer to the matrix element. +
    +
  • if the element is there (it's non-zero), the pointer to it is returned +
  • if it's not there and createMissing=false, NULL pointer is returned +
  • if it's not there and createMissing=true, then the new element + is created and initialized with 0. Pointer to it is returned +
  • if the optional hashval pointer is not NULL, the element hash value is + not computed, but *hashval is taken instead. +
+ */ + //! 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); + //@} - // higher-level element access functions: - // ref<_Tp>(i0,...[,hashval]) - equivalent to *(_Tp*)ptr(i0,...true[,hashval]). - // always return valid reference to the element. - // If it's did not exist, it is created. - // find<_Tp>(i0,...[,hashval]) - equivalent to (_const Tp*)ptr(i0,...false[,hashval]). - // return pointer to the element or NULL pointer if the element is not there. - // value<_Tp>(i0,...[,hashval]) - equivalent to - // { const _Tp* p = find<_Tp>(i0,...[,hashval]); return p ? *p : _Tp(); } - // that is, 0 is returned when the element is not there. - // note that _Tp must match the actual matrix type - - // the functions do not do any on-fly type conversion - - // 1D case + //@{ + /*! + 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 _Tp& ref(int i0, size_t* hashval=0); - template _Tp value(int i0, size_t* hashval=0) const; - template const _Tp* find(int i0, size_t* hashval=0) const; - - // 2D case + //! returns reference to the specified element (2D case) template _Tp& ref(int i0, int i1, size_t* hashval=0); - template _Tp value(int i0, int i1, size_t* hashval=0) const; - template const _Tp* find(int i0, int i1, size_t* hashval=0) const; - - // 3D case + //! returns reference to the specified element (3D case) template _Tp& ref(int i0, int i1, int i2, size_t* hashval=0); - template _Tp value(int i0, int i1, int i2, size_t* hashval=0) const; - template const _Tp* find(int i0, int i1, int i2, size_t* hashval=0) const; - - // n-D case + //! returns reference to the specified element (nD case) template _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 _Tp value(int i0, size_t* hashval=0) const; + //! returns value of the specified element (2D case) + template _Tp value(int i0, int i1, size_t* hashval=0) const; + //! returns value of the specified element (3D case) + template _Tp value(int i0, int i1, int i2, size_t* hashval=0) const; + //! returns value of the specified element (nD case) template _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 const _Tp* find(int i0, size_t* hashval=0) const; + //! returns pointer to the specified element (2D case) + template const _Tp* find(int i0, int i1, size_t* hashval=0) const; + //! returns pointer to the specified element (3D case) + template const _Tp* find(int i0, int i1, int i2, size_t* hashval=0) const; + //! returns pointer to the specified element (nD case) template const _Tp* find(const int* idx, size_t* hashval=0) const; - // erase the specified matrix element. - // When there is no such element, the methods do nothing + //! 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 matrix iterators, - // pointing to the first sparse matrix element, + //@{ + /*! + return the sparse matrix iterator pointing to the first sparse matrix element + */ + //! returns the sparse matrix iterator at the matrix beginning SparseMatIterator begin(); - SparseMatConstIterator begin() const; - // ... or to the point after the last sparse matrix element - SparseMatIterator end(); - SparseMatConstIterator end() const; - - // and the template forms of the above methods. - // _Tp must match the actual matrix type. + //! returns the sparse matrix iterator at the matrix beginning template 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 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 SparseMatIterator_<_Tp> end(); + //! returns the typed read-only sparse matrix iterator at the matrix end template SparseMatConstIterator_<_Tp> end() const; - // return value stored in the sparse martix node + //! returns the value stored in the sparse martix node template _Tp& value(Node* n); + //! returns the value stored in the sparse martix node template const _Tp& value(const Node* n) const; ////////////// some internal-use methods /////////////// @@ -2619,29 +3266,54 @@ public: 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(); + \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 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; @@ -2649,208 +3321,508 @@ public: 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 _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_ m_ = (SparseMat_&)m; + m_.ref(1)++; // equivalent to m.ref(1)++; + m_.ref(2) += m_(3); // equivalent to m.ref(2) += m.value(3); + \endcode +*/ template 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 2D matrix to the sparse form SparseMat_(const Mat& m); + //! converts dense n-dim matrix to the sparse form SparseMat_(const MatND& 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 2D matrix to the sparse form SparseMat_& operator = (const Mat& m); + //! converts dense n-dim matrix to the sparse form SparseMat_& operator = (const MatND& 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); - _Tp operator()(int i0, size_t* hashval=0) const; + //! equivalent to SparseMat::ref<_Tp>(i0, i1, hashval) _Tp& ref(int i0, int i1, size_t* hashval=0); - _Tp operator()(int i0, int i1, size_t* hashval=0) const; + //! equivalent to SparseMat::ref<_Tp>(i0, i1, i2, hashval) _Tp& ref(int i0, int i1, int i2, size_t* hashval=0); - _Tp operator()(int i0, int i1, int i2, size_t* hashval=0) const; + //! 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 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); + //! 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 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); + //! 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 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) {} - int idx; // split dimension; >=0 for nodes (dim), - // < 0 for leaves (index of the point) - int left, right; // node indices of left and right branches - float boundary; // left if vec[dim]<=boundary, otherwise right + //! 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 KDTree(); + //! the full constructor that builds the search tree KDTree(const Mat& _points, bool copyAndReorderPoints=false); + //! builds the search tree void build(const Mat& _points, bool copyAndReorderPoints=false); - + //! finds the K nearest neighbors of "vec" while looking at Emax (at most) leaves int findNearest(const float* vec, int K, int Emax, int* neighborsIdx, Mat* neighbors=0, float* dist=0) const; + //! finds the K nearest neighbors while looking at Emax (at most) leaves int findNearest(const float* vec, int K, int Emax, vector* neighborsIdx, Mat* neighbors=0, vector* dist=0) const; + //! finds all the points from the initial set that belong to the specified box void findOrthoRange(const float* minBounds, const float* maxBounds, vector* neighborsIdx, Mat* neighbors=0) const; + //! returns vectors with the specified indices void getPoints(const int* idx, size_t nidx, Mat& pts) const; + //! returns vectors with the specified indices void getPoints(const Mat& idxs, Mat& pts) const; + //! return a vector with the specified index const float* getPoint(int ptidx) const; + //! returns the search space dimensionality int dims() const; - vector nodes; - Mat points; - int maxDepth; - int normType; + vector nodes; //!< all the tree nodes + Mat points; //!< all the points. It can be a reordered copy of the input vector set or the original vector set. + int maxDepth; //!< maximum depth of the search tree. Do not modify it + 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 FileStorage { public: - enum { READ=0, WRITE=1, APPEND=2 }; - enum { UNDEFINED=0, VALUE_EXPECTED=1, NAME_EXPECTED=2, INSIDE_MAP=4 }; + //! file storage mode + enum + { + READ=0, //! read mode + WRITE=1, //! write mode + APPEND=2 //! append mode + }; + enum + { + UNDEFINED=0, + VALUE_EXPECTED=1, + NAME_EXPECTED=2, + INSIDE_MAP=4 + }; + //! the default constructor FileStorage(); + //! the full constructor that opens file storage for reading or writing FileStorage(const string& filename, int flags); + //! 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() virtual bool open(const string& filename, int flags); + //! returns true if the object is associated with currently opened file. virtual bool isOpened() const; + //! closes the file and releases all the memory buffers virtual void release(); + //! returns the first element of the top-level mapping FileNode getFirstTopLevelNode() const; + //! returns the top-level mapping. YAML supports multiple streams 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 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 fs; - string elname; - vector structs; - int state; + Ptr fs; //!< the underlying C FileStorage structure + string elname; //!< the currently written element + vector 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 FileNode { public: - enum { NONE=0, INT=1, REAL=2, FLOAT=REAL, STR=3, STRING=STR, REF=4, SEQ=5, MAP=6, TYPE_MASK=7, - FLOW=8, USER=16, EMPTY=32, NAMED=64 }; + //! 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 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 FileNode operator[](const char* nodename) const; + //! returns element of a sequence node FileNode operator[](int i) const; + //! returns type of the node int type() const; + int rawDataSize(const string& fmt) const; + //! returns true if the node is empty bool empty() const; + //! returns true if the node is a "none" object bool isNone() const; + //! returns true if the node is a sequence bool isSeq() const; + //! returns true if the node is a mapping bool isMap() const; + //! returns true if the node is an integer bool isInt() const; + //! returns true if the node is a floating-point number bool isReal() const; + //! returns true if the node is a text string bool isString() const; + //! returns true if the node has a name bool isNamed() const; + //! returns the node name or an empty string if the node is nameless string name() const; + //! returns the number of elements in the node, if it is a sequence or mapping, or 1 otherwise. 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 @@ -2858,25 +3830,43 @@ public: 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; - FileNodeIterator& operator ++(); - FileNodeIterator operator ++(int); - FileNodeIterator& operator --(); - FileNodeIterator operator --(int); + //! 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); + //! moves iterator backward by the specified offset (possibly negative) FileNodeIterator& operator -= (int); + //! 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; @@ -2885,74 +3875,130 @@ public: ////////////// convenient wrappers for operating old-style dynamic structures ////////////// -// !!! NOTE that the wrappers are "thin", i.e. they do not call -// any element constructors/destructors - template class SeqIterator; typedef Ptr 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 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_MAX_CN) ...) 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 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 diff --git a/modules/core/include/opencv2/core/operations.hpp b/modules/core/include/opencv2/core/operations.hpp index a15c7bfac..8e02a6816 100644 --- a/modules/core/include/opencv2/core/operations.hpp +++ b/modules/core/include/opencv2/core/operations.hpp @@ -1474,6 +1474,13 @@ inline LineIterator LineIterator::operator ++(int) ++(*this); return it; } +inline Point LineIterator::pos() const +{ + Point p; + p.y = (ptr - ptr0)/step; + p.x = ((ptr - ptr0) - p.y*step)/elemSize; + return p; +} #if 0 template inline VectorCommaInitializer_<_Tp>:: diff --git a/modules/core/src/drawing.cpp b/modules/core/src/drawing.cpp index 0cfd51659..11611f2ed 100644 --- a/modules/core/src/drawing.cpp +++ b/modules/core/src/drawing.cpp @@ -227,6 +227,10 @@ LineIterator::LineIterator(const Mat& img, Point pt1, Point pt2, minusStep = bt_pix; count = dx + dy + 1; } + + this->ptr0 = img.data; + this->step = (int)step; + this->elemSize = bt_pix; } static void diff --git a/modules/imgproc/include/opencv2/imgproc/imgproc.hpp b/modules/imgproc/include/opencv2/imgproc/imgproc.hpp index b1fcc2915..bac532af0 100644 --- a/modules/imgproc/include/opencv2/imgproc/imgproc.hpp +++ b/modules/imgproc/include/opencv2/imgproc/imgproc.hpp @@ -51,53 +51,172 @@ namespace cv { +//! various border interpolation methods enum { BORDER_REPLICATE=IPL_BORDER_REPLICATE, BORDER_CONSTANT=IPL_BORDER_CONSTANT, BORDER_REFLECT=IPL_BORDER_REFLECT, BORDER_REFLECT_101=IPL_BORDER_REFLECT_101, BORDER_REFLECT101=BORDER_REFLECT_101, BORDER_WRAP=IPL_BORDER_WRAP, BORDER_TRANSPARENT, BORDER_DEFAULT=BORDER_REFLECT_101, BORDER_ISOLATED=16 }; +//! 1D interpolation function: returns coordinate of the "donor" pixel for the specified location p. CV_EXPORTS int borderInterpolate( int p, int len, int borderType ); +/*! + 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. + + Several functions in OpenCV return Ptr for the specific types of filters, + and those pointers can be used directly or within cv::FilterEngine. +*/ class CV_EXPORTS BaseRowFilter { public: + //! the default constructor BaseRowFilter(); + //! the destructor virtual ~BaseRowFilter(); + //! the filtering operator. Must be overrided in the derived classes. The horizontal border interpolation is done outside of the class. virtual void operator()(const uchar* src, uchar* dst, int width, int cn) = 0; int ksize, anchor; }; +/*! + 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. + + Several functions in OpenCV return Ptr for the specific types of filters, + and those pointers can be used directly or within cv::FilterEngine. + + Unlike cv::BaseRowFilter, cv::BaseColumnFilter may have some context information, + i.e. box filter keeps the sliding sum of elements. To reset the state BaseColumnFilter::reset() + must be called (e.g. the method is called by cv::FilterEngine) + */ class CV_EXPORTS BaseColumnFilter { public: + //! the default constructor BaseColumnFilter(); + //! the destructor virtual ~BaseColumnFilter(); + //! the filtering operator. Must be overrided in the derived classes. The vertical border interpolation is done outside of the class. virtual void operator()(const uchar** src, uchar* dst, int dststep, int dstcount, int width) = 0; + //! resets the internal buffers, if any virtual void reset(); int ksize, anchor; }; - +/*! + The Base Class for Non-Separable 2D Filters. + + This is the base class for linear or non-linear 2D filters. + + Several functions in OpenCV return Ptr for the specific types of filters, + and those pointers can be used directly or within cv::FilterEngine. + + Similar to cv::BaseColumnFilter, the class may have some context information, + that should be reset using BaseFilter::reset() method before processing the new array. +*/ class CV_EXPORTS BaseFilter { public: + //! the default constructor BaseFilter(); + //! the destructor virtual ~BaseFilter(); + //! the filtering operator. The horizontal and the vertical border interpolation is done outside of the class. virtual void operator()(const uchar** src, uchar* dst, int dststep, int dstcount, int width, int cn) = 0; + //! resets the internal buffers, if any virtual void reset(); Size ksize; Point anchor; }; - +/*! + The Main Class for Image Filtering. + + The class can be used to apply an arbitrary filtering operation to an image. + It contains all the necessary intermediate buffers, it computes extrapolated values + of the "virtual" pixels outside of the image etc. + Pointers to the initialized cv::FilterEngine instances + are returned by various OpenCV functions, such as cv::createSeparableLinearFilter(), + cv::createLinearFilter(), cv::createGaussianFilter(), cv::createDerivFilter(), + cv::createBoxFilter() and cv::createMorphologyFilter(). + + Using the class you can process large images by parts and build complex pipelines + that include filtering as some of the stages. If all you need is to apply some pre-defined + filtering operation, you may use cv::filter2D(), cv::erode(), cv::dilate() etc. + functions that create FilterEngine internally. + + Here is the example on how to use the class to implement Laplacian operator, which is the sum of + second-order derivatives. More complex variant for different types is implemented in cv::Laplacian(). + + \code + void laplace_f(const Mat& src, Mat& dst) + { + CV_Assert( src.type() == CV_32F ); + // make sure the destination array has the proper size and type + dst.create(src.size(), src.type()); + + // get the derivative and smooth kernels for d2I/dx2. + // for d2I/dy2 we could use the same kernels, just swapped + Mat kd, ks; + getSobelKernels( kd, ks, 2, 0, ksize, false, ktype ); + + // let's process 10 source rows at once + int DELTA = std::min(10, src.rows); + Ptr Fxx = createSeparableLinearFilter(src.type(), + dst.type(), kd, ks, Point(-1,-1), 0, borderType, borderType, Scalar() ); + Ptr Fyy = createSeparableLinearFilter(src.type(), + dst.type(), ks, kd, Point(-1,-1), 0, borderType, borderType, Scalar() ); + + int y = Fxx->start(src), dsty = 0, dy = 0; + Fyy->start(src); + const uchar* sptr = src.data + y*src.step; + + // allocate the buffers for the spatial image derivatives; + // the buffers need to have more than DELTA rows, because at the + // last iteration the output may take max(kd.rows-1,ks.rows-1) + // rows more than the input. + Mat Ixx( DELTA + kd.rows - 1, src.cols, dst.type() ); + Mat Iyy( DELTA + kd.rows - 1, src.cols, dst.type() ); + + // inside the loop we always pass DELTA rows to the filter + // (note that the "proceed" method takes care of possibe overflow, since + // it was given the actual image height in the "start" method) + // on output we can get: + // * < DELTA rows (the initial buffer accumulation stage) + // * = DELTA rows (settled state in the middle) + // * > DELTA rows (then the input image is over, but we generate + // "virtual" rows using the border mode and filter them) + // this variable number of output rows is dy. + // dsty is the current output row. + // sptr is the pointer to the first input row in the portion to process + for( ; dsty < dst.rows; sptr += DELTA*src.step, dsty += dy ) + { + Fxx->proceed( sptr, (int)src.step, DELTA, Ixx.data, (int)Ixx.step ); + dy = Fyy->proceed( sptr, (int)src.step, DELTA, d2y.data, (int)Iyy.step ); + if( dy > 0 ) + { + Mat dstripe = dst.rowRange(dsty, dsty + dy); + add(Ixx.rowRange(0, dy), Iyy.rowRange(0, dy), dstripe); + } + } + } + \endcode +*/ class CV_EXPORTS FilterEngine { public: + //! the default constructor FilterEngine(); + //! the full constructor. Either _filter2D or both _rowFilter and _columnFilter must be non-empty. FilterEngine(const Ptr& _filter2D, const Ptr& _rowFilter, const Ptr& _columnFilter, @@ -105,23 +224,31 @@ public: int _rowBorderType=BORDER_REPLICATE, int _columnBorderType=-1, const Scalar& _borderValue=Scalar()); + //! the destructor virtual ~FilterEngine(); + //! reinitializes the engine. The previously assigned filters are released. void init(const Ptr& _filter2D, const Ptr& _rowFilter, const Ptr& _columnFilter, int srcType, int dstType, int bufType, int _rowBorderType=BORDER_REPLICATE, int _columnBorderType=-1, const Scalar& _borderValue=Scalar()); + //! starts filtering of the specified ROI of an image of size wholeSize. virtual int start(Size wholeSize, Rect roi, int maxBufRows=-1); + //! starts filtering of the specified ROI of the specified image. virtual int start(const Mat& src, const Rect& srcRoi=Rect(0,0,-1,-1), bool isolated=false, int maxBufRows=-1); + //! processes the next srcCount rows of the image. virtual int proceed(const uchar* src, int srcStep, int srcCount, uchar* dst, int dstStep); + //! applies filter to the specified ROI of the image. if srcRoi=(0,0,-1,-1), the whole image is filtered. virtual void apply( const Mat& src, Mat& dst, const Rect& srcRoi=Rect(0,0,-1,-1), Point dstOfs=Point(0,0), bool isolated=false); + //! returns true if the filter is separable bool isSeparable() const { return (const BaseFilter*)filter2D == 0; } + //! returns the number int remainingInputRows() const; int remainingOutputRows() const; @@ -147,25 +274,31 @@ public: Ptr columnFilter; }; +//! type of the kernel enum { KERNEL_GENERAL=0, KERNEL_SYMMETRICAL=1, KERNEL_ASYMMETRICAL=2, KERNEL_SMOOTH=4, KERNEL_INTEGER=8 }; +//! returns type (one of KERNEL_*) of 1D or 2D kernel specified by its coefficients. CV_EXPORTS int getKernelType(const Mat& kernel, Point anchor); +//! returns the primitive row filter with the specified kernel CV_EXPORTS Ptr getLinearRowFilter(int srcType, int bufType, const Mat& kernel, int anchor, int symmetryType); +//! returns the primitive column filter with the specified kernel CV_EXPORTS Ptr getLinearColumnFilter(int bufType, int dstType, const Mat& kernel, int anchor, int symmetryType, double delta=0, int bits=0); +//! returns 2D filter with the specified kernel CV_EXPORTS Ptr getLinearFilter(int srcType, int dstType, const Mat& kernel, Point anchor=Point(-1,-1), double delta=0, int bits=0); +//! returns the separable linear filter engine CV_EXPORTS Ptr createSeparableLinearFilter(int srcType, int dstType, const Mat& rowKernel, const Mat& columnKernel, Point _anchor=Point(-1,-1), double delta=0, @@ -173,69 +306,87 @@ CV_EXPORTS Ptr createSeparableLinearFilter(int srcType, int dstTyp int _columnBorderType=-1, const Scalar& _borderValue=Scalar()); +//! returns the non-separable linear filter engine CV_EXPORTS Ptr createLinearFilter(int srcType, int dstType, const Mat& kernel, Point _anchor=Point(-1,-1), double delta=0, int _rowBorderType=BORDER_DEFAULT, int _columnBorderType=-1, const Scalar& _borderValue=Scalar()); +//! returns the Gaussian kernel with the specified parameters CV_EXPORTS Mat getGaussianKernel( int ksize, double sigma, int ktype=CV_64F ); +//! returns the Gaussian filter engine CV_EXPORTS Ptr createGaussianFilter( int type, Size ksize, double sigma1, double sigma2=0, int borderType=BORDER_DEFAULT); - +//! initializes kernels of the generalized Sobel operator CV_EXPORTS void getDerivKernels( Mat& kx, Mat& ky, int dx, int dy, int ksize, bool normalize=false, int ktype=CV_32F ); - +//! returns filter engine for the generalized Sobel operator CV_EXPORTS Ptr createDerivFilter( int srcType, int dstType, int dx, int dy, int ksize, int borderType=BORDER_DEFAULT ); - +//! returns horizontal 1D box filter CV_EXPORTS Ptr getRowSumFilter(int srcType, int sumType, int ksize, int anchor=-1); +//! returns vertical 1D box filter CV_EXPORTS Ptr getColumnSumFilter(int sumType, int dstType, int ksize, int anchor=-1, double scale=1); +//! returns box filter engine CV_EXPORTS Ptr createBoxFilter( int srcType, int dstType, Size ksize, Point anchor=Point(-1,-1), bool normalize=true, int borderType=BORDER_DEFAULT); - +//! type of morphological operation enum { MORPH_ERODE=0, MORPH_DILATE=1, MORPH_OPEN=2, MORPH_CLOSE=3, MORPH_GRADIENT=4, MORPH_TOPHAT=5, MORPH_BLACKHAT=6 }; +//! returns horizontal 1D morphological filter CV_EXPORTS Ptr getMorphologyRowFilter(int op, int type, int ksize, int anchor=-1); +//! returns vertical 1D morphological filter CV_EXPORTS Ptr getMorphologyColumnFilter(int op, int type, int ksize, int anchor=-1); +//! returns 2D morphological filter CV_EXPORTS Ptr getMorphologyFilter(int op, int type, const Mat& kernel, Point anchor=Point(-1,-1)); - + +//! returns "magic" border value for erosion and dilation. It is automatically transformed to Scalar::all(-DBL_MAX) for dilation. static inline Scalar morphologyDefaultBorderValue() { return Scalar::all(DBL_MAX); } +//! returns morphological filter engine. Only MORPH_ERODE and MORPH_DILATE are supported. CV_EXPORTS Ptr createMorphologyFilter(int op, int type, const Mat& kernel, Point anchor=Point(-1,-1), int _rowBorderType=BORDER_CONSTANT, int _columnBorderType=-1, const Scalar& _borderValue=morphologyDefaultBorderValue()); +//! shape of the structuring element enum { MORPH_RECT=0, MORPH_CROSS=1, MORPH_ELLIPSE=2 }; +//! returns structuring element of the specified shape and size CV_EXPORTS Mat getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1)); template<> CV_EXPORTS void Ptr::delete_obj(); - + +//! copies 2D array to a larger destination array with extrapolation of the outer part of src using the specified border mode CV_EXPORTS void copyMakeBorder( const Mat& src, Mat& dst, int top, int bottom, int left, int right, int borderType, const Scalar& value=Scalar() ); +//! smooths the image using median filter. CV_EXPORTS void medianBlur( const Mat& src, Mat& dst, int ksize ); +//! smooths the image using Gaussian filter. CV_EXPORTS void GaussianBlur( const Mat& src, Mat& dst, Size ksize, double sigma1, double sigma2=0, int borderType=BORDER_DEFAULT ); +//! smooths the image using bilateral filter CV_EXPORTS void bilateralFilter( const Mat& src, Mat& dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT ); +//! smooths the image using the box filter. Each pixel is processed in O(1) time CV_EXPORTS void boxFilter( const Mat& src, Mat& dst, int ddepth, Size ksize, Point anchor=Point(-1,-1), bool normalize=true, int borderType=BORDER_DEFAULT ); +//! a synonym for normalized box filter static inline void blur( const Mat& src, Mat& dst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT ) @@ -243,94 +394,127 @@ static inline void blur( const Mat& src, Mat& dst, boxFilter( src, dst, -1, ksize, anchor, true, borderType ); } +//! applies non-separable 2D linear filter to the image CV_EXPORTS void filter2D( const Mat& src, Mat& dst, int ddepth, const Mat& kernel, Point anchor=Point(-1,-1), double delta=0, int borderType=BORDER_DEFAULT ); +//! applies separable 2D linear filter to the image CV_EXPORTS void sepFilter2D( const Mat& src, Mat& dst, int ddepth, const Mat& kernelX, const Mat& kernelY, Point anchor=Point(-1,-1), double delta=0, int borderType=BORDER_DEFAULT ); - + +//! applies generalized Sobel operator to the image CV_EXPORTS void Sobel( const Mat& src, Mat& dst, int ddepth, int dx, int dy, int ksize=3, double scale=1, double delta=0, int borderType=BORDER_DEFAULT ); +//! applies the vertical or horizontal Scharr operator to the image CV_EXPORTS void Scharr( const Mat& src, Mat& dst, int ddepth, int dx, int dy, double scale=1, double delta=0, int borderType=BORDER_DEFAULT ); +//! applies Laplacian operator to the image CV_EXPORTS void Laplacian( const Mat& src, Mat& dst, int ddepth, int ksize=1, double scale=1, double delta=0, int borderType=BORDER_DEFAULT ); +//! applies Canny edge detector and produces the edge map. CV_EXPORTS void Canny( const Mat& image, Mat& edges, double threshold1, double threshold2, int apertureSize=3, bool L2gradient=false ); +//! computes minimum eigen value of 2x2 derivative covariation matrix at each pixel - the cornerness criteria CV_EXPORTS void cornerMinEigenVal( const Mat& src, Mat& dst, int blockSize, int ksize=3, int borderType=BORDER_DEFAULT ); +//! computes Harris cornerness criteria at each image pixel CV_EXPORTS void cornerHarris( const Mat& src, Mat& dst, int blockSize, int ksize, double k, int borderType=BORDER_DEFAULT ); +//! computes both eigenvalues and the eigenvectors of 2x2 derivative covariation matrix at each pixel. The output is stored as 6-channel matrix. CV_EXPORTS void cornerEigenValsAndVecs( const Mat& src, Mat& dst, int blockSize, int ksize, int borderType=BORDER_DEFAULT ); +//! computes another complex cornerness criteria at each pixel CV_EXPORTS void preCornerDetect( const Mat& src, Mat& dst, int ksize, int borderType=BORDER_DEFAULT ); +//! adjusts the corner locations with sub-pixel accuracy to maximize the certain cornerness criteria CV_EXPORTS void cornerSubPix( const Mat& image, vector& corners, Size winSize, Size zeroZone, TermCriteria criteria ); +//! finds the strong enough corners where the cornerMinEigenVal() or cornerHarris() report the local maxima CV_EXPORTS void goodFeaturesToTrack( const Mat& image, vector& corners, int maxCorners, double qualityLevel, double minDistance, const Mat& mask=Mat(), int blockSize=3, bool useHarrisDetector=false, double k=0.04 ); +//! finds lines in the black-n-white image using the standard or pyramid Hough transform CV_EXPORTS void HoughLines( const Mat& image, vector& lines, double rho, double theta, int threshold, double srn=0, double stn=0 ); +//! finds line segments in the black-n-white image using probabalistic Hough transform CV_EXPORTS void HoughLinesP( Mat& image, vector& lines, double rho, double theta, int threshold, double minLineLength=0, double maxLineGap=0 ); +//! finds circles in the grayscale image using 2+1 gradient Hough transform CV_EXPORTS void HoughCircles( const Mat& image, vector& circles, int method, double dp, double minDist, double param1=100, double param2=100, int minRadius=0, int maxRadius=0 ); +//! erodes the image (applies the local minimum operator) CV_EXPORTS void erode( const Mat& src, Mat& 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) CV_EXPORTS void dilate( const Mat& src, Mat& 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 Mat& src, Mat& dst, int op, const Mat& kernel, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue() ); -enum { INTER_NEAREST=0, INTER_LINEAR=1, INTER_CUBIC=2, INTER_AREA=3, - INTER_LANCZOS4=4, INTER_MAX=7, WARP_INVERSE_MAP=16 }; +//! interpolation algorithm +enum +{ + INTER_NEAREST=0, //!< nearest neighbor interpolation + INTER_LINEAR=1, //!< bilinear interpolation + INTER_CUBIC=2, //!< bicubic interpolation + INTER_AREA=3, //!< area-based (or super) interpolation + INTER_LANCZOS4=4, //!< Lanczos interpolation over 8x8 neighborhood + INTER_MAX=7, + WARP_INVERSE_MAP=16 +}; +//! resizes the image CV_EXPORTS void resize( const Mat& src, Mat& dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR ); +//! warps the image using affine transformation CV_EXPORTS void warpAffine( const Mat& src, Mat& dst, const Mat& M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar()); + +//! warps the image using perspective transformation CV_EXPORTS void warpPerspective( const Mat& src, Mat& dst, const Mat& M, Size dsize, int flags=INTER_LINEAR, @@ -340,213 +524,302 @@ CV_EXPORTS void warpPerspective( const Mat& src, Mat& dst, enum { INTER_BITS=5, INTER_BITS2=INTER_BITS*2, INTER_TAB_SIZE=(1<& dst, int maxlevel ); - +//! corrects lens distortion for the given camera matrix and distortion coefficients CV_EXPORTS void undistort( const Mat& src, Mat& dst, const Mat& cameraMatrix, const Mat& distCoeffs, const Mat& newCameraMatrix=Mat() ); +//! initializes maps for cv::remap() to correct lens distortion and optionally rectify the image CV_EXPORTS void initUndistortRectifyMap( const Mat& cameraMatrix, const Mat& distCoeffs, const Mat& R, const Mat& newCameraMatrix, Size size, int m1type, Mat& map1, Mat& map2 ); +//! returns the default new camera matrix (by default it is the same as cameraMatrix unless centerPricipalPoint=true) CV_EXPORTS Mat getDefaultNewCameraMatrix( const Mat& cameraMatrix, Size imgsize=Size(), bool centerPrincipalPoint=false ); - +//! returns points' coordinates after lens distortion correction CV_EXPORTS void undistortPoints( const Mat& src, vector& dst, const Mat& cameraMatrix, const Mat& distCoeffs, const Mat& R=Mat(), const Mat& P=Mat()); +//! returns points' coordinates after lens distortion correction CV_EXPORTS void undistortPoints( const Mat& src, Mat& dst, const Mat& cameraMatrix, const Mat& distCoeffs, const Mat& R=Mat(), const Mat& P=Mat()); template<> CV_EXPORTS void Ptr::delete_obj(); +//! computes the joint dense histogram for a set of images. CV_EXPORTS void calcHist( const Mat* images, int nimages, const int* channels, const Mat& mask, MatND& hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false ); +//! computes the joint sparse histogram for a set of images. CV_EXPORTS void calcHist( const Mat* images, int nimages, const int* channels, const Mat& mask, SparseMat& hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false ); - + +//! computes back projection for the set of images CV_EXPORTS void calcBackProject( const Mat* images, int nimages, const int* channels, const MatND& hist, Mat& backProject, const float** ranges, double scale=1, bool uniform=true ); - + +//! computes back projection for the set of images CV_EXPORTS void calcBackProject( const Mat* images, int nimages, const int* channels, const SparseMat& hist, Mat& backProject, const float** ranges, double scale=1, bool uniform=true ); +//! compares two histograms stored in dense arrays CV_EXPORTS double compareHist( const MatND& H1, const MatND& H2, int method ); +//! compares two histograms stored in sparse arrays CV_EXPORTS double compareHist( const SparseMat& H1, const SparseMat& H2, int method ); +//! normalizes the grayscale image brightness and contrast by normalizing its histogram CV_EXPORTS void equalizeHist( const Mat& src, Mat& dst ); +//! segments the image using watershed algorithm CV_EXPORTS void watershed( const Mat& image, Mat& markers ); -enum { GC_BGD = 0, // background - GC_FGD = 1, // foreground - GC_PR_BGD = 2, // most probably background - GC_PR_FGD = 3 // most probably foreground +//! class of the pixel in GrabCut algorithm +enum { GC_BGD = 0, //!< background + GC_FGD = 1, //!< foreground + GC_PR_BGD = 2, //!< most probably background + GC_PR_FGD = 3 //!< most probably foreground }; +//! GrabCut algorithm flags enum { GC_INIT_WITH_RECT = 0, GC_INIT_WITH_MASK = 1, GC_EVAL = 2 }; +//! segments the image using GrabCut algorithm CV_EXPORTS void grabCut( const Mat& img, Mat& mask, Rect rect, Mat& bgdModel, Mat& fgdModel, int iterCount, int mode = GC_EVAL ); -enum { INPAINT_NS=0, INPAINT_TELEA=1 }; +//! the inpainting algorithm +enum +{ + INPAINT_NS=0, // Navier-Stokes algorithm + INPAINT_TELEA=1 // A. Telea algorithm +}; +//! restores the damaged image areas using one of the available intpainting algorithms CV_EXPORTS void inpaint( const Mat& src, const Mat& inpaintMask, Mat& dst, double inpaintRange, int flags ); +//! builds the discrete Voronoi diagram CV_EXPORTS void distanceTransform( const Mat& src, Mat& dst, Mat& labels, int distanceType, int maskSize ); +//! computes the distance transform map CV_EXPORTS void distanceTransform( const Mat& src, Mat& dst, int distanceType, int maskSize ); enum { FLOODFILL_FIXED_RANGE = 1 << 16, FLOODFILL_MASK_ONLY = 1 << 17 }; +//! fills the semi-uniform image region starting from the specified seed point CV_EXPORTS int floodFill( Mat& image, Point seedPoint, Scalar newVal, Rect* rect=0, Scalar loDiff=Scalar(), Scalar upDiff=Scalar(), int flags=4 ); +//! fills the semi-uniform image region and/or the mask starting from the specified seed point CV_EXPORTS int floodFill( Mat& image, Mat& mask, Point seedPoint, Scalar newVal, Rect* rect=0, Scalar loDiff=Scalar(), Scalar upDiff=Scalar(), int flags=4 ); +//! converts image from one color space to another CV_EXPORTS void cvtColor( const Mat& src, Mat& dst, int code, int dstCn=0 ); +//! raster image moments class CV_EXPORTS Moments { public: + //! the default constructor Moments(); + //! the full constructor Moments(double m00, double m10, double m01, double m20, double m11, double m02, double m30, double m21, double m12, double m03 ); + //! the conversion from CvMoments Moments( const CvMoments& moments ); + //! the conversion to CvMoments operator CvMoments() const; - double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03; // spatial moments - double mu20, mu11, mu02, mu30, mu21, mu12, mu03; // central moments - double nu20, nu11, nu02, nu30, nu21, nu12, nu03; // central normalized moments + //! spatial moments + double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03; + //! central moments + double mu20, mu11, mu02, mu30, mu21, mu12, mu03; + //! central normalized moments + double nu20, nu11, nu02, nu30, nu21, nu12, nu03; }; +//! computes moments of the rasterized shape or a vector of points CV_EXPORTS Moments moments( const Mat& array, bool binaryImage=false ); +//! computes 7 Hu invariants from the moments CV_EXPORTS void HuMoments( const Moments& moments, double hu[7] ); +//! type of the template matching operation enum { TM_SQDIFF=0, TM_SQDIFF_NORMED=1, TM_CCORR=2, TM_CCORR_NORMED=3, TM_CCOEFF=4, TM_CCOEFF_NORMED=5 }; +//! computes the proximity map for the raster template and the image where the template is searched for CV_EXPORTS void matchTemplate( const Mat& image, const Mat& templ, Mat& result, int method ); -enum { RETR_EXTERNAL=0, RETR_LIST=1, RETR_CCOMP=2, RETR_TREE=3 }; +//! mode of the contour retrieval algorithm +enum +{ + RETR_EXTERNAL=0, //!< retrieve only the most external (top-level) contours + RETR_LIST=1, //!< retrieve all the contours without any hierarchical information + RETR_CCOMP=2, //!< retrieve the connected components (that can possibly be nested) + RETR_TREE=3 //!< retrieve all the contours and the whole hierarchy +}; -enum { CHAIN_APPROX_NONE=0, CHAIN_APPROX_SIMPLE=1, - CHAIN_APPROX_TC89_L1=2, CHAIN_APPROX_TC89_KCOS=3 }; +//! the contour approximation algorithm +enum +{ + CHAIN_APPROX_NONE=0, + CHAIN_APPROX_SIMPLE=1, + CHAIN_APPROX_TC89_L1=2, + CHAIN_APPROX_TC89_KCOS=3 +}; +//! retrieves contours and the hierarchical information from black-n-white image. CV_EXPORTS void findContours( Mat& image, vector >& contours, vector& hierarchy, int mode, int method, Point offset=Point()); +//! retrieves contours from black-n-white image. CV_EXPORTS void findContours( Mat& image, vector >& contours, int mode, int method, Point offset=Point()); +//! draws contours in the image CV_EXPORTS void drawContours( Mat& image, const vector >& contours, int contourIdx, const Scalar& color, int thickness=1, int lineType=8, const vector& hierarchy=vector(), int maxLevel=INT_MAX, Point offset=Point() ); +//! approximates contour or a curve using Douglas-Peucker algorithm CV_EXPORTS void approxPolyDP( const Mat& curve, vector& approxCurve, double epsilon, bool closed ); +//! approximates contour or a curve using Douglas-Peucker algorithm CV_EXPORTS void approxPolyDP( const Mat& curve, vector& approxCurve, double epsilon, bool closed ); - +//! computes the contour perimeter (closed=true) or a curve length CV_EXPORTS double arcLength( const Mat& curve, bool closed ); +//! computes the bounding rectangle for a contour CV_EXPORTS Rect boundingRect( const Mat& points ); -CV_EXPORTS double contourArea( const Mat& contour, bool oriented=false ); +//! computes the contour area +CV_EXPORTS double contourArea( const Mat& contour, bool oriented=false ); +//! computes the minimal rotated rectangle for a set of points CV_EXPORTS RotatedRect minAreaRect( const Mat& points ); +//! computes the minimal enclosing circle for a set of points CV_EXPORTS void minEnclosingCircle( const Mat& points, Point2f& center, float& radius ); +//! matches two contours using one of the available algorithms CV_EXPORTS double matchShapes( const Mat& contour1, const Mat& contour2, int method, double parameter ); - +//! computes convex hull for a set of 2D points. CV_EXPORTS void convexHull( const Mat& points, vector& hull, bool clockwise=false ); +//! computes convex hull for a set of 2D points. CV_EXPORTS void convexHull( const Mat& points, vector& hull, bool clockwise=false ); +//! computes convex hull for a set of 2D points. CV_EXPORTS void convexHull( const Mat& points, vector& hull, bool clockwise=false ); +//! returns true iff the contour is convex. Does not support contours with self-intersection CV_EXPORTS bool isContourConvex( const Mat& contour ); +//! fits ellipse to the set of 2D points CV_EXPORTS RotatedRect fitEllipse( const Mat& points ); +//! fits line to the set of 2D points using M-estimator algorithm CV_EXPORTS void fitLine( const Mat& points, Vec4f& line, int distType, double param, double reps, double aeps ); +//! fits line to the set of 3D points using M-estimator algorithm CV_EXPORTS void fitLine( const Mat& points, Vec6f& line, int distType, double param, double reps, double aeps ); - +//! checks if the point is inside the contour. Optionally computes the signed distance from the point to the contour boundary CV_EXPORTS double pointPolygonTest( const Mat& contour, Point2f pt, bool measureDist ); - + +//! estimates the best-fit affine transformation that maps one 2D point set to another or one image to another. CV_EXPORTS Mat estimateRigidTransform( const Mat& A, const Mat& B, bool fullAffine ); +//! computes the best-fit affine transformation that maps one 3D point set to another (RANSAC algorithm is used) CV_EXPORTS int estimateAffine3D(const Mat& from, const Mat& to, Mat& out, vector& outliers, double param1 = 3.0, double param2 = 0.99);