diff --git a/modules/calib3d/test/test_posit.cpp b/modules/calib3d/test/test_posit.cpp index 34f3cc4d53..186c4f2d4c 100644 --- a/modules/calib3d/test/test_posit.cpp +++ b/modules/calib3d/test/test_posit.cpp @@ -189,13 +189,13 @@ void CV_POSITTest::run( int start_from ) rotation->data.fl, translation->data.fl ); cvReleasePOSITObject( &object ); - //Mat _rotation = cvarrToMat(rotation), _true_rotation = cvarrToMat(true_rotation); - //Mat _translation = cvarrToMat(translation), _true_translation = cvarrToMat(true_translation); - code = cvtest::cmpEps2( ts, rotation, true_rotation, flEpsilon, false, "rotation matrix" ); + Mat _rotation = cvarrToMat(rotation), _true_rotation = cvarrToMat(true_rotation); + Mat _translation = cvarrToMat(translation), _true_translation = cvarrToMat(true_translation); + code = cvtest::cmpEps2( ts, _rotation, _true_rotation, flEpsilon, false, "rotation matrix" ); if( code < 0 ) break; - code = cvtest::cmpEps2( ts, translation, true_translation, flEpsilon, false, "translation vector" ); + code = cvtest::cmpEps2( ts, _translation, _true_translation, flEpsilon, false, "translation vector" ); if( code < 0 ) break; } diff --git a/modules/calib3d/test/test_undistort.cpp b/modules/calib3d/test/test_undistort.cpp index 745daeaf6d..8823e1d517 100644 --- a/modules/calib3d/test/test_undistort.cpp +++ b/modules/calib3d/test/test_undistort.cpp @@ -855,8 +855,8 @@ void CV_InitUndistortRectifyMapTest::prepare_to_validation(int/* test_case_idx*/ //Applying precalculated undistort rectify map if (!useCPlus) { - mapx = cv::Mat(_mapx); - mapy = cv::Mat(_mapy); + mapx = cv::cvarrToMat(_mapx); + mapy = cv::cvarrToMat(_mapy); } cv::Mat map1,map2; cv::convertMaps(mapx,mapy,map1,map2,CV_32FC1); diff --git a/modules/calib3d/test/test_undistort_badarg.cpp b/modules/calib3d/test/test_undistort_badarg.cpp index 074d193731..37c080f6e0 100644 --- a/modules/calib3d/test/test_undistort_badarg.cpp +++ b/modules/calib3d/test/test_undistort_badarg.cpp @@ -243,27 +243,27 @@ void CV_UndistortPointsBadArgTest::run(int) //C++ tests useCPlus = true; - camera_mat = cv::Mat(&_camera_mat_orig); - distortion_coeffs = cv::Mat(&_distortion_coeffs_orig); - P = cv::Mat(&_P_orig); - R = cv::Mat(&_R_orig); - src_points = cv::Mat(&_src_points_orig); + camera_mat = cv::cvarrToMat(&_camera_mat_orig); + distortion_coeffs = cv::cvarrToMat(&_distortion_coeffs_orig); + P = cv::cvarrToMat(&_P_orig); + R = cv::cvarrToMat(&_R_orig); + src_points = cv::cvarrToMat(&_src_points_orig); temp = cvCreateMat(2,2,CV_32FC2); - src_points = cv::Mat(temp); + src_points = cv::cvarrToMat(temp); errcount += run_test_case( CV_StsAssert, "Invalid input data matrix size" ); - src_points = cv::Mat(&_src_points_orig); + src_points = cv::cvarrToMat(&_src_points_orig); cvReleaseMat(&temp); temp = cvCreateMat(1,4,CV_64FC2); - src_points = cv::Mat(temp); + src_points = cv::cvarrToMat(temp); errcount += run_test_case( CV_StsAssert, "Invalid input data matrix type" ); - src_points = cv::Mat(&_src_points_orig); + src_points = cv::cvarrToMat(&_src_points_orig); cvReleaseMat(&temp); src_points = cv::Mat(); errcount += run_test_case( CV_StsAssert, "Input data matrix is not continuous" ); - src_points = cv::Mat(&_src_points_orig); + src_points = cv::cvarrToMat(&_src_points_orig); cvReleaseMat(&temp); @@ -360,12 +360,12 @@ void CV_InitUndistortRectifyMapBadArgTest::run(int) //C++ tests useCPlus = true; - camera_mat = cv::Mat(&_camera_mat_orig); - distortion_coeffs = cv::Mat(&_distortion_coeffs_orig); - new_camera_mat = cv::Mat(&_new_camera_mat_orig); - R = cv::Mat(&_R_orig); - mapx = cv::Mat(&_mapx_orig); - mapy = cv::Mat(&_mapy_orig); + camera_mat = cv::cvarrToMat(&_camera_mat_orig); + distortion_coeffs = cv::cvarrToMat(&_distortion_coeffs_orig); + new_camera_mat = cv::cvarrToMat(&_new_camera_mat_orig); + R = cv::cvarrToMat(&_R_orig); + mapx = cv::cvarrToMat(&_mapx_orig); + mapy = cv::cvarrToMat(&_mapy_orig); mat_type = CV_64F; @@ -373,21 +373,21 @@ void CV_InitUndistortRectifyMapBadArgTest::run(int) mat_type = mat_type_orig; temp = cvCreateMat(3,2,CV_32FC1); - camera_mat = cv::Mat(temp); + camera_mat = cv::cvarrToMat(temp); errcount += run_test_case( CV_StsAssert, "Invalid camera data matrix size" ); - camera_mat = cv::Mat(&_camera_mat_orig); + camera_mat = cv::cvarrToMat(&_camera_mat_orig); cvReleaseMat(&temp); temp = cvCreateMat(4,3,CV_32FC1); - R = cv::Mat(temp); + R = cv::cvarrToMat(temp); errcount += run_test_case( CV_StsAssert, "Invalid R data matrix size" ); - R = cv::Mat(&_R_orig); + R = cv::cvarrToMat(&_R_orig); cvReleaseMat(&temp); temp = cvCreateMat(6,1,CV_32FC1); - distortion_coeffs = cv::Mat(temp); + distortion_coeffs = cv::cvarrToMat(temp); errcount += run_test_case( CV_StsAssert, "Invalid distortion coefficients data matrix size" ); - distortion_coeffs = cv::Mat(&_distortion_coeffs_orig); + distortion_coeffs = cv::cvarrToMat(&_distortion_coeffs_orig); cvReleaseMat(&temp); //------------ @@ -499,11 +499,11 @@ void CV_UndistortBadArgTest::run(int) //C++ tests useCPlus = true; - camera_mat = cv::Mat(&_camera_mat_orig); - distortion_coeffs = cv::Mat(&_distortion_coeffs_orig); - new_camera_mat = cv::Mat(&_new_camera_mat_orig); - src = cv::Mat(&_src_orig); - dst = cv::Mat(&_dst_orig); + camera_mat = cv::cvarrToMat(&_camera_mat_orig); + distortion_coeffs = cv::cvarrToMat(&_distortion_coeffs_orig); + new_camera_mat = cv::cvarrToMat(&_new_camera_mat_orig); + src = cv::cvarrToMat(&_src_orig); + dst = cv::cvarrToMat(&_dst_orig); //------------ delete[] arr_src; diff --git a/modules/contrib/src/ba.cpp b/modules/contrib/src/ba.cpp index 39acd45798..bf37dbfe03 100644 --- a/modules/contrib/src/ba.cpp +++ b/modules/contrib/src/ba.cpp @@ -359,7 +359,7 @@ void LevMarqSparse::ask_for_proj(CvMat &/*_vis*/,bool once) { cvGetSubRect( P, &cam_mat, cvRect( 0, j * num_cam_param, 1, num_cam_param )); CvMat measur_mat; cvGetSubRect( hX, &measur_mat, cvRect( 0, ind * num_err_param, 1, num_err_param )); - Mat _point_mat(&point_mat), _cam_mat(&cam_mat), _measur_mat(&measur_mat); + Mat _point_mat = cv::cvarrToMat(&point_mat), _cam_mat = cv::cvarrToMat(&cam_mat), _measur_mat = cv::cvarrToMat(&measur_mat); func( i, j, _point_mat, _cam_mat, _measur_mat, data); assert( ind*num_err_param == ((int*)(Vis_index->data.ptr + i * Vis_index->step))[j]); ind+=1; @@ -398,7 +398,7 @@ void LevMarqSparse::ask_for_projac(CvMat &/*_vis*/) //should be evaluated at p //CvMat* Bij = B_line[j]; //CvMat* Bij = ((CvMat**)(B->data.ptr + B->step * i))[j]; - Mat _point_mat(&point_mat), _cam_mat(&cam_mat), _Aij(Aij), _Bij(Bij); + Mat _point_mat = cv::cvarrToMat(&point_mat), _cam_mat = cv::cvarrToMat(&cam_mat), _Aij = cv::cvarrToMat(Aij), _Bij = cv::cvarrToMat(Bij); (*fjac)(i, j, _point_mat, _cam_mat, _Aij, _Bij, data); } } @@ -1100,16 +1100,17 @@ void LevMarqSparse::bundleAdjust( std::vector& points, //positions of p } //fill camera params //R.clear();T.clear();cameraMatrix.clear(); + Mat levmarP = cv::cvarrToMat(levmar.P); for( int i = 0; i < num_cameras; i++ ) { //rotation - Mat rot_vec = Mat(levmar.P).rowRange(i*num_cam_param, i*num_cam_param+3); + Mat rot_vec = levmarP.rowRange(i*num_cam_param, i*num_cam_param+3); Rodrigues( rot_vec, R[i] ); //translation - T[i] = Mat(levmar.P).rowRange(i*num_cam_param + 3, i*num_cam_param+6); + T[i] = levmarP.rowRange(i*num_cam_param + 3, i*num_cam_param+6); //intrinsic camera matrix double* intr_data = (double*)cameraMatrix[i].data; - double* intr = (double*)(Mat(levmar.P).data + Mat(levmar.P).step * (i*num_cam_param+6)); + double* intr = (double*)(levmarP.data +levmarP.step * (i*num_cam_param+6)); //focals intr_data[0] = intr[0]; //fx intr_data[4] = intr[1]; //fy @@ -1119,7 +1120,7 @@ void LevMarqSparse::bundleAdjust( std::vector& points, //positions of p //add distortion if exists if( distCoeffs.size() ) { - Mat(levmar.P).rowRange(i*num_cam_param + 10, i*num_cam_param+10+numdist).copyTo(distCoeffs[i]); + levmarP.rowRange(i*num_cam_param + 10, i*num_cam_param+10+numdist).copyTo(distCoeffs[i]); } } } diff --git a/modules/core/include/opencv2/core.hpp b/modules/core/include/opencv2/core.hpp index 1d4e7414aa..c533dd5ccd 100644 --- a/modules/core/include/opencv2/core.hpp +++ b/modules/core/include/opencv2/core.hpp @@ -55,6 +55,7 @@ #include "opencv2/core/traits.hpp" #include "opencv2/core/matx.hpp" #include "opencv2/core/types.hpp" +#include "opencv2/core/mat.hpp" #endif #include "opencv2/core/types_c.h" @@ -78,10 +79,8 @@ */ namespace cv { -class CV_EXPORTS MatExpr; class CV_EXPORTS MatOp_Base; class CV_EXPORTS MatArg; -class CV_EXPORTS MatConstIterator; template class CV_EXPORTS MatCommaInitializer_; @@ -135,698 +134,6 @@ CV_EXPORTS void error( const Exception& exc ); CV_EXPORTS void scalarToRawData(const Scalar& s, void* buf, int type, int unroll_to=0); -//////////////////////// Input/Output Array Arguments ///////////////////////////////// - -/*! - Proxy datatype for passing Mat's and vector<>'s as input parameters - */ -class CV_EXPORTS _InputArray -{ -public: - enum { - KIND_SHIFT = 16, - FIXED_TYPE = 0x8000 << KIND_SHIFT, - FIXED_SIZE = 0x4000 << KIND_SHIFT, - KIND_MASK = ~(FIXED_TYPE|FIXED_SIZE) - (1 << KIND_SHIFT) + 1, - - NONE = 0 << KIND_SHIFT, - MAT = 1 << KIND_SHIFT, - MATX = 2 << KIND_SHIFT, - STD_VECTOR = 3 << KIND_SHIFT, - STD_VECTOR_VECTOR = 4 << KIND_SHIFT, - STD_VECTOR_MAT = 5 << KIND_SHIFT, - EXPR = 6 << KIND_SHIFT, - OPENGL_BUFFER = 7 << KIND_SHIFT, - OPENGL_TEXTURE = 8 << KIND_SHIFT, - GPU_MAT = 9 << KIND_SHIFT - }; - _InputArray(); - - _InputArray(const Mat& m); - _InputArray(const MatExpr& expr); - template _InputArray(const _Tp* vec, int n); - template _InputArray(const std::vector<_Tp>& vec); - template _InputArray(const std::vector >& vec); - _InputArray(const std::vector& vec); - template _InputArray(const std::vector >& vec); - template _InputArray(const Mat_<_Tp>& m); - template _InputArray(const Matx<_Tp, m, n>& matx); - _InputArray(const Scalar& s); - _InputArray(const double& val); - _InputArray(const gpu::GpuMat& d_mat); - _InputArray(const ogl::Buffer& buf); - _InputArray(const ogl::Texture2D& tex); - - virtual Mat getMat(int i=-1) const; - virtual void getMatVector(std::vector& mv) const; - virtual gpu::GpuMat getGpuMat() const; - virtual ogl::Buffer getOGlBuffer() const; - virtual ogl::Texture2D getOGlTexture2D() const; - - virtual int kind() const; - virtual Size size(int i=-1) const; - virtual size_t total(int i=-1) const; - virtual int type(int i=-1) const; - virtual int depth(int i=-1) const; - virtual int channels(int i=-1) const; - virtual bool empty() const; - - virtual ~_InputArray(); - - int flags; - void* obj; - Size sz; -}; - - -enum -{ - DEPTH_MASK_8U = 1 << CV_8U, - DEPTH_MASK_8S = 1 << CV_8S, - DEPTH_MASK_16U = 1 << CV_16U, - DEPTH_MASK_16S = 1 << CV_16S, - DEPTH_MASK_32S = 1 << CV_32S, - DEPTH_MASK_32F = 1 << CV_32F, - DEPTH_MASK_64F = 1 << CV_64F, - DEPTH_MASK_ALL = (DEPTH_MASK_64F<<1)-1, - DEPTH_MASK_ALL_BUT_8S = DEPTH_MASK_ALL & ~DEPTH_MASK_8S, - DEPTH_MASK_FLT = DEPTH_MASK_32F + DEPTH_MASK_64F -}; - - -/*! - Proxy datatype for passing Mat's and vector<>'s as input parameters - */ -class CV_EXPORTS _OutputArray : public _InputArray -{ -public: - _OutputArray(); - - _OutputArray(Mat& m); - template _OutputArray(std::vector<_Tp>& vec); - template _OutputArray(std::vector >& vec); - _OutputArray(std::vector& vec); - template _OutputArray(std::vector >& vec); - template _OutputArray(Mat_<_Tp>& m); - template _OutputArray(Matx<_Tp, m, n>& matx); - template _OutputArray(_Tp* vec, int n); - _OutputArray(gpu::GpuMat& d_mat); - _OutputArray(ogl::Buffer& buf); - _OutputArray(ogl::Texture2D& tex); - - _OutputArray(const Mat& m); - template _OutputArray(const std::vector<_Tp>& vec); - template _OutputArray(const std::vector >& vec); - _OutputArray(const std::vector& vec); - template _OutputArray(const std::vector >& vec); - template _OutputArray(const Mat_<_Tp>& m); - template _OutputArray(const Matx<_Tp, m, n>& matx); - template _OutputArray(const _Tp* vec, int n); - _OutputArray(const gpu::GpuMat& d_mat); - _OutputArray(const ogl::Buffer& buf); - _OutputArray(const ogl::Texture2D& tex); - - virtual bool fixedSize() const; - virtual bool fixedType() const; - virtual bool needed() const; - virtual Mat& getMatRef(int i=-1) const; - virtual gpu::GpuMat& getGpuMatRef() const; - virtual ogl::Buffer& getOGlBufferRef() const; - virtual ogl::Texture2D& getOGlTexture2DRef() const; - virtual void create(Size sz, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const; - virtual void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const; - virtual void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const; - virtual void release() const; - virtual void clear() const; - - virtual ~_OutputArray(); -}; - -typedef const _InputArray& InputArray; -typedef InputArray InputArrayOfArrays; -typedef const _OutputArray& OutputArray; -typedef OutputArray OutputArrayOfArrays; -typedef OutputArray InputOutputArray; -typedef OutputArray InputOutputArrayOfArrays; - -CV_EXPORTS OutputArray noArray(); - -/////////////////////////////////////// Mat /////////////////////////////////////////// - -enum { MAGIC_MASK=0xFFFF0000, TYPE_MASK=0x00000FFF, DEPTH_MASK=7 }; - -/*! - Custom array allocator - -*/ -class CV_EXPORTS MatAllocator -{ -public: - MatAllocator() {} - virtual ~MatAllocator() {} - virtual void allocate(int dims, const int* sizes, int type, int*& refcount, - uchar*& datastart, uchar*& data, size_t* step) = 0; - virtual void deallocate(int* refcount, uchar* datastart, uchar* data) = 0; -}; - -/*! - The n-dimensional matrix class. - - The class represents an n-dimensional dense numerical array that can act as - a matrix, image, optical flow map, 3-focal tensor etc. - It is very similar to CvMat and CvMatND types from earlier versions of OpenCV, - and similarly to those types, the matrix can be multi-channel. It also fully supports ROI mechanism. - - There are many different ways to create cv::Mat object. Here are the some popular ones: -
    -
  • using cv::Mat::create(nrows, ncols, type) method or - the similar constructor cv::Mat::Mat(nrows, ncols, type[, fill_value]) constructor. - A new matrix of the specified size and specifed type will be allocated. - "type" has the same meaning as in cvCreateMat function, - e.g. CV_8UC1 means 8-bit single-channel matrix, CV_32FC2 means 2-channel (i.e. complex) - floating-point matrix etc: - - \code - // make 7x7 complex matrix filled with 1+3j. - cv::Mat M(7,7,CV_32FC2,Scalar(1,3)); - // and now turn M to 100x60 15-channel 8-bit matrix. - // The old content will be deallocated - M.create(100,60,CV_8UC(15)); - \endcode - - As noted in the introduction of this chapter, Mat::create() - will only allocate a new matrix when the current matrix dimensionality - or type are different from the specified. - -
  • by using a copy constructor or assignment operator, where on the right side it can - be a matrix or expression, see below. Again, as noted in the introduction, - matrix assignment is O(1) operation because it only copies the header - and increases the reference counter. cv::Mat::clone() method can be used to get a full - (a.k.a. deep) copy of the matrix when you need it. - -
  • by constructing a header for a part of another matrix. It can be a single row, single column, - several rows, several columns, rectangular region in the matrix (called a minor in algebra) or - a diagonal. Such operations are also O(1), because the new header will reference the same data. - You can actually modify a part of the matrix using this feature, e.g. - - \code - // add 5-th row, multiplied by 3 to the 3rd row - M.row(3) = M.row(3) + M.row(5)*3; - - // now copy 7-th column to the 1-st column - // M.col(1) = M.col(7); // this will not work - Mat M1 = M.col(1); - M.col(7).copyTo(M1); - - // create new 320x240 image - cv::Mat img(Size(320,240),CV_8UC3); - // select a roi - cv::Mat roi(img, Rect(10,10,100,100)); - // fill the ROI with (0,255,0) (which is green in RGB space); - // the original 320x240 image will be modified - roi = Scalar(0,255,0); - \endcode - - Thanks to the additional cv::Mat::datastart and cv::Mat::dataend members, it is possible to - compute the relative sub-matrix position in the main "container" matrix using cv::Mat::locateROI(): - - \code - Mat A = Mat::eye(10, 10, CV_32S); - // extracts A columns, 1 (inclusive) to 3 (exclusive). - Mat B = A(Range::all(), Range(1, 3)); - // extracts B rows, 5 (inclusive) to 9 (exclusive). - // that is, C ~ A(Range(5, 9), Range(1, 3)) - Mat C = B(Range(5, 9), Range::all()); - Size size; Point ofs; - C.locateROI(size, ofs); - // size will be (width=10,height=10) and the ofs will be (x=1, y=5) - \endcode - - As in the case of whole matrices, if you need a deep copy, use cv::Mat::clone() method - of the extracted sub-matrices. - -
  • by making a header for user-allocated-data. It can be useful for -
      -
    1. processing "foreign" data using OpenCV (e.g. when you implement - a DirectShow filter or a processing module for gstreamer etc.), e.g. - - \code - void process_video_frame(const unsigned char* pixels, - int width, int height, int step) - { - cv::Mat img(height, width, CV_8UC3, pixels, step); - cv::GaussianBlur(img, img, cv::Size(7,7), 1.5, 1.5); - } - \endcode - -
    2. for quick initialization of small matrices and/or super-fast element access - - \code - double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}}; - cv::Mat M = cv::Mat(3, 3, CV_64F, m).inv(); - \endcode -
    - - partial yet very common cases of this "user-allocated data" case are conversions - from CvMat and IplImage to cv::Mat. For this purpose there are special constructors - taking pointers to CvMat or IplImage and the optional - flag indicating whether to copy the data or not. - - Backward conversion from cv::Mat to CvMat or IplImage is provided via cast operators - cv::Mat::operator CvMat() an cv::Mat::operator IplImage(). - The operators do not copy the data. - - - \code - IplImage* img = cvLoadImage("greatwave.jpg", 1); - Mat mtx(img); // convert IplImage* -> cv::Mat - CvMat oldmat = mtx; // convert cv::Mat -> CvMat - CV_Assert(oldmat.cols == img->width && oldmat.rows == img->height && - oldmat.data.ptr == (uchar*)img->imageData && oldmat.step == img->widthStep); - \endcode - -
  • by using MATLAB-style matrix initializers, cv::Mat::zeros(), cv::Mat::ones(), cv::Mat::eye(), e.g.: - - \code - // create a double-precision identity martix and add it to M. - M += Mat::eye(M.rows, M.cols, CV_64F); - \endcode - -
  • by using comma-separated initializer: - - \code - // create 3x3 double-precision identity matrix - Mat M = (Mat_(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1); - \endcode - - here we first call constructor of cv::Mat_ class (that we describe further) with the proper matrix, - and then we just put "<<" operator followed by comma-separated values that can be constants, - variables, expressions etc. Also, note the extra parentheses that are needed to avoid compiler errors. - -
- - Once matrix is created, it will be automatically managed by using reference-counting mechanism - (unless the matrix header is built on top of user-allocated data, - in which case you should handle the data by yourself). - The matrix data will be deallocated when no one points to it; - if you want to release the data pointed by a matrix header before the matrix destructor is called, - use cv::Mat::release(). - - The next important thing to learn about the matrix class is element access. Here is how the matrix is stored. - The elements are stored in row-major order (row by row). The cv::Mat::data member points to the first element of the first row, - cv::Mat::rows contains the number of matrix rows and cv::Mat::cols - the number of matrix columns. There is yet another member, - cv::Mat::step that is used to actually compute address of a matrix element. cv::Mat::step is needed because the matrix can be - a part of another matrix or because there can some padding space in the end of each row for a proper alignment. - - \image html roi.png - - Given these parameters, address of the matrix element M_{ij} is computed as following: - - addr(M_{ij})=M.data + M.step*i + j*M.elemSize() - - if you know the matrix element type, e.g. it is float, then you can use cv::Mat::at() method: - - addr(M_{ij})=&M.at(i,j) - - (where & is used to convert the reference returned by cv::Mat::at() to a pointer). - if you need to process a whole row of matrix, the most efficient way is to get - the pointer to the row first, and then just use plain C operator []: - - \code - // compute sum of positive matrix elements - // (assuming that M is double-precision matrix) - double sum=0; - for(int i = 0; i < M.rows; i++) - { - const double* Mi = M.ptr(i); - for(int j = 0; j < M.cols; j++) - sum += std::max(Mi[j], 0.); - } - \endcode - - Some operations, like the above one, do not actually depend on the matrix shape, - they just process elements of a matrix one by one (or elements from multiple matrices - that are sitting in the same place, e.g. matrix addition). Such operations are called - element-wise and it makes sense to check whether all the input/output matrices are continuous, - i.e. have no gaps in the end of each row, and if yes, process them as a single long row: - - \code - // compute sum of positive matrix elements, optimized variant - double sum=0; - int cols = M.cols, rows = M.rows; - if(M.isContinuous()) - { - cols *= rows; - rows = 1; - } - for(int i = 0; i < rows; i++) - { - const double* Mi = M.ptr(i); - for(int j = 0; j < cols; j++) - sum += std::max(Mi[j], 0.); - } - \endcode - in the case of continuous matrix the outer loop body will be executed just once, - so the overhead will be smaller, which will be especially noticeable in the case of small matrices. - - Finally, there are STL-style iterators that are smart enough to skip gaps between successive rows: - \code - // compute sum of positive matrix elements, iterator-based variant - double sum=0; - MatConstIterator_ it = M.begin(), it_end = M.end(); - for(; it != it_end; ++it) - sum += std::max(*it, 0.); - \endcode - - The matrix iterators are random-access iterators, so they can be passed - to any STL algorithm, including std::sort(). -*/ -class CV_EXPORTS Mat -{ -public: - //! default constructor - Mat(); - //! constructs 2D matrix of the specified size and type - // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.) - Mat(int rows, int cols, int type); - Mat(Size size, int type); - //! constucts 2D matrix and fills it with the specified value _s. - Mat(int rows, int cols, int type, const Scalar& s); - Mat(Size size, int type, const Scalar& s); - - //! constructs n-dimensional matrix - Mat(int ndims, const int* sizes, int type); - Mat(int ndims, const int* sizes, int type, const Scalar& s); - - //! copy constructor - Mat(const Mat& m); - //! constructor for matrix headers pointing to user-allocated data - Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP); - Mat(Size size, int type, void* data, size_t step=AUTO_STEP); - Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0); - - //! creates a matrix header for a part of the bigger matrix - Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all()); - Mat(const Mat& m, const Rect& roi); - Mat(const Mat& m, const Range* ranges); - //! converts old-style CvMat to the new matrix; the data is not copied by default - Mat(const CvMat* m, bool copyData=false); - //! converts old-style CvMatND to the new matrix; the data is not copied by default - Mat(const CvMatND* m, bool copyData=false); - //! converts old-style IplImage to the new matrix; the data is not copied by default - Mat(const IplImage* img, bool copyData=false); - //! builds matrix from std::vector with or without copying the data - template explicit Mat(const std::vector<_Tp>& vec, bool copyData=false); - //! builds matrix from cv::Vec; the data is copied by default - template explicit Mat(const Vec<_Tp, n>& vec, bool copyData=true); - //! builds matrix from cv::Matx; the data is copied by default - template explicit Mat(const Matx<_Tp, m, n>& mtx, bool copyData=true); - //! builds matrix from a 2D point - template explicit Mat(const Point_<_Tp>& pt, bool copyData=true); - //! builds matrix from a 3D point - template explicit Mat(const Point3_<_Tp>& pt, bool copyData=true); - //! builds matrix from comma initializer - template explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer); - - //! download data from GpuMat - explicit Mat(const gpu::GpuMat& m); - - //! destructor - calls release() - ~Mat(); - //! assignment operators - Mat& operator = (const Mat& m); - Mat& operator = (const MatExpr& expr); - - //! returns a new matrix header for the specified row - Mat row(int y) const; - //! returns a new matrix header for the specified column - Mat col(int x) const; - //! ... for the specified row span - Mat rowRange(int startrow, int endrow) const; - Mat rowRange(const Range& r) const; - //! ... for the specified column span - Mat colRange(int startcol, int endcol) const; - Mat colRange(const Range& r) const; - //! ... for the specified diagonal - // (d=0 - the main diagonal, - // >0 - a diagonal from the lower half, - // <0 - a diagonal from the upper half) - Mat diag(int d=0) const; - //! constructs a square diagonal matrix which main diagonal is vector "d" - static Mat diag(const Mat& d); - - //! returns deep copy of the matrix, i.e. the data is copied - Mat clone() const; - //! copies the matrix content to "m". - // It calls m.create(this->size(), this->type()). - void copyTo( OutputArray m ) const; - //! copies those matrix elements to "m" that are marked with non-zero mask elements. - void copyTo( OutputArray m, InputArray mask ) const; - //! converts matrix to another datatype with optional scalng. See cvConvertScale. - void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const; - - void assignTo( Mat& m, int type=-1 ) const; - - //! sets every matrix element to s - Mat& operator = (const Scalar& s); - //! sets some of the matrix elements to s, according to the mask - Mat& setTo(InputArray value, InputArray mask=noArray()); - //! creates alternative matrix header for the same data, with different - // number of channels and/or different number of rows. see cvReshape. - Mat reshape(int cn, int rows=0) const; - Mat reshape(int cn, int newndims, const int* newsz) const; - - //! matrix transposition by means of matrix expressions - MatExpr t() const; - //! matrix inversion by means of matrix expressions - MatExpr inv(int method=DECOMP_LU) const; - //! per-element matrix multiplication by means of matrix expressions - MatExpr mul(InputArray m, double scale=1) const; - - //! computes cross-product of 2 3D vectors - Mat cross(InputArray m) const; - //! computes dot-product - double dot(InputArray m) const; - - //! Matlab-style matrix initialization - static MatExpr zeros(int rows, int cols, int type); - static MatExpr zeros(Size size, int type); - static MatExpr zeros(int ndims, const int* sz, int type); - static MatExpr ones(int rows, int cols, int type); - static MatExpr ones(Size size, int type); - static MatExpr ones(int ndims, const int* sz, int type); - static MatExpr eye(int rows, int cols, int type); - static MatExpr eye(Size size, int type); - - //! allocates new matrix data unless the matrix already has specified size and type. - // previous data is unreferenced if needed. - void create(int rows, int cols, int type); - void create(Size size, int type); - void create(int ndims, const int* sizes, int type); - - //! increases the reference counter; use with care to avoid memleaks - void addref(); - //! decreases reference counter; - // deallocates the data when reference counter reaches 0. - void release(); - - //! deallocates the matrix data - void deallocate(); - //! internal use function; properly re-allocates _size, _step arrays - void copySize(const Mat& m); - - //! reserves enough space to fit sz hyper-planes - void reserve(size_t sz); - //! resizes matrix to the specified number of hyper-planes - void resize(size_t sz); - //! resizes matrix to the specified number of hyper-planes; initializes the newly added elements - void resize(size_t sz, const Scalar& s); - //! internal function - void push_back_(const void* elem); - //! adds element to the end of 1d matrix (or possibly multiple elements when _Tp=Mat) - template void push_back(const _Tp& elem); - template void push_back(const Mat_<_Tp>& elem); - void push_back(const Mat& m); - //! removes several hyper-planes from bottom of the matrix - void pop_back(size_t nelems=1); - - //! locates matrix header within a parent matrix. See below - void locateROI( Size& wholeSize, Point& ofs ) const; - //! moves/resizes the current matrix ROI inside the parent matrix. - Mat& adjustROI( int dtop, int dbottom, int dleft, int dright ); - //! extracts a rectangular sub-matrix - // (this is a generalized form of row, rowRange etc.) - Mat operator()( Range rowRange, Range colRange ) const; - Mat operator()( const Rect& roi ) const; - Mat operator()( const Range* ranges ) const; - - //! converts header to CvMat; no data is copied - operator CvMat() const; - //! converts header to CvMatND; no data is copied - operator CvMatND() const; - //! converts header to IplImage; no data is copied - operator IplImage() const; - - template operator std::vector<_Tp>() const; - template operator Vec<_Tp, n>() const; - template operator Matx<_Tp, m, n>() const; - - //! returns true iff the matrix data is continuous - // (i.e. when there are no gaps between successive rows). - // similar to CV_IS_MAT_CONT(cvmat->type) - bool isContinuous() const; - - //! returns true if the matrix is a submatrix of another matrix - bool isSubmatrix() const; - - //! returns element size in bytes, - // similar to CV_ELEM_SIZE(cvmat->type) - size_t elemSize() const; - //! returns the size of element channel in bytes. - size_t elemSize1() const; - //! returns element type, similar to CV_MAT_TYPE(cvmat->type) - int type() const; - //! returns element type, similar to CV_MAT_DEPTH(cvmat->type) - int depth() const; - //! returns element type, similar to CV_MAT_CN(cvmat->type) - int channels() const; - //! returns step/elemSize1() - size_t step1(int i=0) const; - //! returns true if matrix data is NULL - bool empty() const; - //! returns the total number of matrix elements - size_t total() const; - - //! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise - int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const; - - //! returns pointer to i0-th submatrix along the dimension #0 - uchar* ptr(int i0=0); - const uchar* ptr(int i0=0) const; - - //! returns pointer to (i0,i1) submatrix along the dimensions #0 and #1 - uchar* ptr(int i0, int i1); - const uchar* ptr(int i0, int i1) const; - - //! returns pointer to (i0,i1,i3) submatrix along the dimensions #0, #1, #2 - uchar* ptr(int i0, int i1, int i2); - const uchar* ptr(int i0, int i1, int i2) const; - - //! returns pointer to the matrix element - uchar* ptr(const int* idx); - //! returns read-only pointer to the matrix element - const uchar* ptr(const int* idx) const; - - template uchar* ptr(const Vec& idx); - template const uchar* ptr(const Vec& idx) const; - - //! template version of the above method - template _Tp* ptr(int i0=0); - template const _Tp* ptr(int i0=0) const; - - template _Tp* ptr(int i0, int i1); - template const _Tp* ptr(int i0, int i1) const; - - template _Tp* ptr(int i0, int i1, int i2); - template const _Tp* ptr(int i0, int i1, int i2) const; - - template _Tp* ptr(const int* idx); - template const _Tp* ptr(const int* idx) const; - - template _Tp* ptr(const Vec& idx); - template const _Tp* ptr(const Vec& idx) const; - - //! the same as above, with the pointer dereferencing - template _Tp& at(int i0=0); - template const _Tp& at(int i0=0) const; - - template _Tp& at(int i0, int i1); - template const _Tp& at(int i0, int i1) const; - - template _Tp& at(int i0, int i1, int i2); - template const _Tp& at(int i0, int i1, int i2) const; - - template _Tp& at(const int* idx); - template const _Tp& at(const int* idx) const; - - template _Tp& at(const Vec& idx); - template const _Tp& at(const Vec& idx) const; - - //! special versions for 2D arrays (especially convenient for referencing image pixels) - template _Tp& at(Point pt); - template const _Tp& at(Point pt) const; - - //! template methods for iteration over matrix elements. - // the iterators take care of skipping gaps in the end of rows (if any) - template MatIterator_<_Tp> begin(); - template MatIterator_<_Tp> end(); - template MatConstIterator_<_Tp> begin() const; - template MatConstIterator_<_Tp> end() const; - - enum { MAGIC_VAL=0x42FF0000, AUTO_STEP=0, CONTINUOUS_FLAG=CV_MAT_CONT_FLAG, SUBMATRIX_FLAG=CV_SUBMAT_FLAG }; - - /*! includes several bit-fields: - - the magic signature - - continuity flag - - depth - - number of channels - */ - int flags; - //! the matrix dimensionality, >= 2 - int dims; - //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions - int rows, cols; - //! pointer to the data - uchar* data; - - //! pointer to the reference counter; - // when matrix points to user-allocated data, the pointer is NULL - int* refcount; - - //! helper fields used in locateROI and adjustROI - uchar* datastart; - uchar* dataend; - uchar* datalimit; - - //! custom allocator - MatAllocator* allocator; - - struct CV_EXPORTS MSize - { - MSize(int* _p); - Size operator()() const; - const int& operator[](int i) const; - int& operator[](int i); - operator const int*() const; - bool operator == (const MSize& sz) const; - bool operator != (const MSize& sz) const; - - int* p; - }; - - struct CV_EXPORTS MStep - { - MStep(); - MStep(size_t s); - const size_t& operator[](int i) const; - size_t& operator[](int i); - operator size_t() const; - MStep& operator = (size_t s); - - size_t* p; - size_t buf[2]; - protected: - MStep& operator = (const MStep&); - }; - - MSize size; - MStep step; - -protected: - void initEmpty(); -}; - - /*! Random Number Generator @@ -1488,222 +795,6 @@ CV_EXPORTS_W Size getTextSize(const String& text, int fontFace, double fontScale, int thickness, CV_OUT int* baseLine); -///////////////////////////////// Mat_<_Tp> //////////////////////////////////// - -/*! - Template matrix class derived from Mat - - The class Mat_ is a "thin" template wrapper on top of cv::Mat. It does not have any extra data fields, - nor it or cv::Mat have any virtual methods and thus references or pointers to these two classes - can be safely converted one to another. But do it with care, for example: - - \code - // create 100x100 8-bit matrix - Mat M(100,100,CV_8U); - // this will compile fine. no any data conversion will be done. - Mat_& 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: - typedef _Tp value_type; - typedef typename DataType<_Tp>::channel_type channel_type; - typedef MatIterator_<_Tp> iterator; - typedef MatConstIterator_<_Tp> const_iterator; - - //! default constructor - Mat_(); - //! equivalent to Mat(_rows, _cols, DataType<_Tp>::type) - Mat_(int _rows, int _cols); - //! constructor that sets each matrix element to specified value - Mat_(int _rows, int _cols, const _Tp& value); - //! equivalent to Mat(_size, DataType<_Tp>::type) - explicit Mat_(Size _size); - //! constructor that sets each matrix element to specified value - Mat_(Size _size, const _Tp& value); - //! n-dim array constructor - Mat_(int _ndims, const int* _sizes); - //! n-dim array constructor that sets each matrix element to specified value - Mat_(int _ndims, const int* _sizes, const _Tp& value); - //! copy/conversion contructor. If m is of different type, it's converted - Mat_(const Mat& m); - //! copy constructor - Mat_(const Mat_& m); - //! constructs a matrix on top of user-allocated data. step is in bytes(!!!), regardless of the type - Mat_(int _rows, int _cols, _Tp* _data, size_t _step=AUTO_STEP); - //! constructs n-dim matrix on top of user-allocated data. steps are in bytes(!!!), regardless of the type - Mat_(int _ndims, const int* _sizes, _Tp* _data, const size_t* _steps=0); - //! selects a submatrix - Mat_(const Mat_& m, const Range& rowRange, const Range& colRange=Range::all()); - //! selects a submatrix - Mat_(const Mat_& m, const Rect& roi); - //! selects a submatrix, n-dim version - Mat_(const Mat_& m, const Range* ranges); - //! from a matrix expression - explicit Mat_(const MatExpr& e); - //! makes a matrix out of Vec, std::vector, Point_ or Point3_. The matrix will have a single column - explicit Mat_(const std::vector<_Tp>& vec, bool copyData=false); - template explicit Mat_(const Vec::channel_type, n>& vec, bool copyData=true); - template explicit Mat_(const Matx::channel_type, m, n>& mtx, bool copyData=true); - explicit Mat_(const Point_::channel_type>& pt, bool copyData=true); - explicit Mat_(const Point3_::channel_type>& pt, bool copyData=true); - explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer); - - Mat_& operator = (const Mat& m); - Mat_& operator = (const Mat_& m); - //! set all the elements to s. - Mat_& operator = (const _Tp& s); - //! assign a matrix expression - Mat_& operator = (const MatExpr& e); - - //! iterators; they are smart enough to skip gaps in the end of rows - iterator begin(); - iterator end(); - const_iterator begin() const; - const_iterator end() const; - - //! equivalent to Mat::create(_rows, _cols, DataType<_Tp>::type) - void create(int _rows, int _cols); - //! equivalent to Mat::create(_size, DataType<_Tp>::type) - void create(Size _size); - //! equivalent to Mat::create(_ndims, _sizes, DatType<_Tp>::type) - void create(int _ndims, const int* _sizes); - //! cross-product - Mat_ cross(const Mat_& m) const; - //! data type conversion - template operator Mat_() const; - //! overridden forms of Mat::row() etc. - Mat_ row(int y) const; - Mat_ col(int x) const; - Mat_ diag(int d=0) const; - Mat_ clone() const; - - //! overridden forms of Mat::elemSize() etc. - size_t elemSize() const; - size_t elemSize1() const; - int type() const; - int depth() const; - int channels() const; - size_t step1(int i=0) const; - //! returns step()/sizeof(_Tp) - size_t stepT(int i=0) const; - - //! overridden forms of Mat::zeros() etc. Data type is omitted, of course - static MatExpr zeros(int rows, int cols); - static MatExpr zeros(Size size); - static MatExpr zeros(int _ndims, const int* _sizes); - static MatExpr ones(int rows, int cols); - static MatExpr ones(Size size); - static MatExpr ones(int _ndims, const int* _sizes); - static MatExpr eye(int rows, int cols); - static MatExpr eye(Size size); - - //! some more overriden methods - Mat_& adjustROI( int dtop, int dbottom, int dleft, int dright ); - Mat_ operator()( const Range& rowRange, const Range& colRange ) const; - Mat_ operator()( const Rect& roi ) const; - Mat_ operator()( const Range* ranges ) const; - - //! more convenient forms of row and element access operators - _Tp* operator [](int y); - const _Tp* operator [](int y) const; - - //! returns reference to the specified element - _Tp& operator ()(const int* idx); - //! returns read-only reference to the specified element - const _Tp& operator ()(const int* idx) const; - - //! returns reference to the specified element - template _Tp& operator ()(const Vec& idx); - //! returns read-only reference to the specified element - template const _Tp& operator ()(const Vec& idx) const; - - //! returns reference to the specified element (1D case) - _Tp& operator ()(int idx0); - //! returns read-only reference to the specified element (1D case) - const _Tp& operator ()(int idx0) const; - //! returns reference to the specified element (2D case) - _Tp& operator ()(int idx0, int idx1); - //! returns read-only reference to the specified element (2D case) - const _Tp& operator ()(int idx0, int idx1) const; - //! returns reference to the specified element (3D case) - _Tp& operator ()(int idx0, int idx1, int idx2); - //! returns read-only reference to the specified element (3D case) - const _Tp& operator ()(int idx0, int idx1, int idx2) const; - - _Tp& operator ()(Point pt); - const _Tp& operator ()(Point pt) const; - - //! conversion to vector. - operator std::vector<_Tp>() const; - //! conversion to Vec - template operator Vec::channel_type, n>() const; - //! conversion to Matx - template operator Matx::channel_type, m, n>() const; -}; - -typedef Mat_ Mat1b; -typedef Mat_ Mat2b; -typedef Mat_ Mat3b; -typedef Mat_ Mat4b; - -typedef Mat_ Mat1s; -typedef Mat_ Mat2s; -typedef Mat_ Mat3s; -typedef Mat_ Mat4s; - -typedef Mat_ Mat1w; -typedef Mat_ Mat2w; -typedef Mat_ Mat3w; -typedef Mat_ Mat4w; - -typedef Mat_ Mat1i; -typedef Mat_ Mat2i; -typedef Mat_ Mat3i; -typedef Mat_ Mat4i; - -typedef Mat_ Mat1f; -typedef Mat_ Mat2f; -typedef Mat_ Mat3f; -typedef Mat_ Mat4f; - -typedef Mat_ Mat1d; -typedef Mat_ Mat2d; -typedef Mat_ Mat3d; -typedef Mat_ Mat4d; - //////////// Iterators & Comma initializers ////////////////// class CV_EXPORTS MatConstIterator @@ -1861,32 +952,6 @@ public: 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: - //! 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); - //! another form of conversion operator - Mat_<_Tp> operator *() const; - operator Mat_<_Tp>() const; -protected: - MatIterator_<_Tp> it; -}; /////////////////////////// multi-dimensional dense matrix ////////////////////////// @@ -1984,353 +1049,6 @@ CV_EXPORTS ConvertData getConvertElem(int fromType, int toType); //! returns the function for converting pixels from one data type to another with the optional scaling CV_EXPORTS ConvertScaleData getConvertScaleElem(int fromType, int toType); - -/////////////////////////// multi-dimensional sparse matrix ////////////////////////// - -class SparseMatIterator; -class SparseMatConstIterator; -template 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 is able to store. "Sparse" means that only non-zero elements - are stored (though, as a result of some operations on a sparse matrix, some of its stored elements - can actually become 0. It's user responsibility to detect such elements and delete them using cv::SparseMat::erase(). - The non-zero elements are stored in a hash table that grows when it's filled enough, - so that the search time remains O(1) in average. Elements can be accessed using the following methods: - -
    -
  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::Mat iterators, the sparse matrix iterators are STL-style, - that is, the iteration is done as following: - \code - // prints elements of a sparse floating-point matrix and the sum of elements. - SparseMatConstIterator_ - 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); - void clear(); - int refcount; - int dims; - int valueOffset; - size_t nodeSize; - size_t nodeCount; - size_t freeList; - std::vector pool; - std::vector hashtab; - int size[CV_MAX_DIM]; - }; - - //! sparse matrix node - element of a hash table - struct CV_EXPORTS Node - { - //! hash value - size_t hashval; - //! index of the next node in the same hash table entry - size_t next; - //! index of the matrix element - int idx[CV_MAX_DIM]; - }; - - //! default constructor - SparseMat(); - //! creates matrix of the specified size and type - SparseMat(int dims, const int* _sizes, int _type); - //! copy constructor - SparseMat(const SparseMat& m); - //! converts dense 2d matrix to the sparse form - /*! - \param m the input matrix - \param try1d if true and m is a single-column matrix (Nx1), - then the sparse matrix will be 1-dimensional. - */ - explicit SparseMat(const Mat& m); - //! converts old-style sparse matrix to the new-style. All the data is copied - SparseMat(const CvSparseMat* m); - //! the destructor - ~SparseMat(); - - //! assignment operator. This is O(1) operation, i.e. no data is copied - SparseMat& operator = (const SparseMat& m); - //! equivalent to the corresponding constructor - SparseMat& operator = (const Mat& m); - - //! creates full copy of the matrix - SparseMat clone() const; - - //! copies all the data to the destination matrix. All the previous content of m is erased - void copyTo( SparseMat& m ) const; - //! converts sparse matrix to dense matrix. - void copyTo( Mat& m ) const; - //! multiplies all the matrix elements by the specified scale factor alpha and converts the results to the specified data type - void convertTo( SparseMat& m, int rtype, double alpha=1 ) const; - //! converts sparse matrix to dense n-dim matrix with optional type conversion and scaling. - /*! - \param rtype The output matrix data type. When it is =-1, the output array will have the same data type as (*this) - \param alpha The scale factor - \param beta The optional delta added to the scaled values before the conversion - */ - void convertTo( Mat& m, int rtype, double alpha=1, double beta=0 ) const; - - // not used now - void assignTo( SparseMat& m, int type=-1 ) const; - - //! reallocates sparse matrix. - /*! - If the matrix already had the proper size and type, - it is simply cleared with clear(), otherwise, - the old matrix is released (using release()) and the new one is allocated. - */ - void create(int dims, const int* _sizes, int _type); - //! sets all the sparse matrix elements to 0, which means clearing the hash table. - void clear(); - //! manually increments the reference counter to the header. - void addref(); - // decrements the header reference counter. When the counter reaches 0, the header and all the underlying data are deallocated. - void release(); - - //! converts sparse matrix to the old-style representation; all the elements are copied. - operator CvSparseMat*() const; - //! returns the size of each element in bytes (not including the overhead - the space occupied by SparseMat::Node elements) - size_t elemSize() const; - //! returns elemSize()/channels() - size_t elemSize1() const; - - //! returns type of sparse matrix elements - int type() const; - //! returns the depth of sparse matrix elements - int depth() const; - //! returns the number of channels - int channels() const; - - //! returns the array of sizes, or NULL if the matrix is not allocated - const int* size() const; - //! returns the size of i-th matrix dimension (or 0) - int size(int i) const; - //! returns the matrix dimensionality - int dims() const; - //! returns the number of non-zero elements (=the number of hash table nodes) - size_t nzcount() const; - - //! computes the element hash value (1D case) - size_t hash(int i0) const; - //! computes the element hash value (2D case) - size_t hash(int i0, int i1) const; - //! computes the element hash value (3D case) - size_t hash(int i0, int i1, int i2) const; - //! computes the element hash value (nD case) - size_t hash(const int* idx) const; - - //@{ - /*! - specialized variants for 1D, 2D, 3D cases and the generic_type one for n-D case. - - return pointer to the matrix element. -
    -
  • 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); - //@} - - //@{ - /*! - 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); - //! returns reference to the specified element (2D case) - template _Tp& ref(int i0, int i1, size_t* hashval=0); - //! returns reference to the specified element (3D case) - template _Tp& ref(int i0, int i1, int i2, size_t* hashval=0); - //! 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; - - //! erases the specified element (2D case) - void erase(int i0, int i1, size_t* hashval=0); - //! erases the specified element (3D case) - void erase(int i0, int i1, int i2, size_t* hashval=0); - //! erases the specified element (nD case) - void erase(const int* idx, size_t* hashval=0); - - //@{ - /*! - return the sparse matrix iterator pointing to the first sparse matrix element - */ - //! returns the sparse matrix iterator at the matrix beginning - SparseMatIterator begin(); - //! returns the sparse matrix iterator at the matrix beginning - template 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; - - //! 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 /////////////// - Node* node(size_t nidx); - const Node* node(size_t nidx) const; - - uchar* newNode(const int* idx, size_t hashval); - void removeNode(size_t hidx, size_t nidx, size_t previdx); - void resizeHashTab(size_t newsize); - - enum { MAGIC_VAL=0x42FD0000, MAX_DIM=CV_MAX_DIM, HASH_SCALE=0x5bd1e995, HASH_BIT=0x80000000 }; - - int flags; - Hdr* hdr; -}; - //! finds global minimum and maximum sparse array elements and returns their values and their locations CV_EXPORTS void minMaxLoc(const SparseMat& a, double* minVal, double* maxVal, int* minIdx=0, int* maxIdx=0); @@ -2417,86 +1135,6 @@ public: 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 matrix to the sparse form - SparseMat_(const Mat& m); - //! converts the old-style sparse matrix to the C++ class. All the elements are copied - SparseMat_(const CvSparseMat* m); - //! the assignment operator. If DataType<_Tp>.type != m.type(), the m elements are converted - SparseMat_& operator = (const SparseMat& m); - //! the assignment operator. This is O(1) operation - no data is copied - SparseMat_& operator = (const SparseMat_& m); - //! converts dense matrix to the sparse form - SparseMat_& operator = (const Mat& m); - - //! makes full copy of the matrix. All the elements are duplicated - SparseMat_ clone() const; - //! equivalent to cv::SparseMat::create(dims, _sizes, DataType<_Tp>::type) - void create(int dims, const int* _sizes); - //! converts sparse matrix to the old-style CvSparseMat. All the elements are copied - operator CvSparseMat*() const; - - //! returns type of the matrix elements - int type() const; - //! returns depth of the matrix elements - int depth() const; - //! returns the number of channels in each matrix element - int channels() const; - - //! equivalent to SparseMat::ref<_Tp>(i0, hashval) - _Tp& ref(int i0, size_t* hashval=0); - //! equivalent to SparseMat::ref<_Tp>(i0, i1, hashval) - _Tp& ref(int i0, int i1, size_t* hashval=0); - //! equivalent to SparseMat::ref<_Tp>(i0, i1, i2, hashval) - _Tp& ref(int i0, int i1, int i2, size_t* hashval=0); - //! equivalent to SparseMat::ref<_Tp>(idx, hashval) - _Tp& ref(const int* idx, size_t* hashval=0); - - //! equivalent to SparseMat::value<_Tp>(i0, hashval) - _Tp operator()(int i0, size_t* hashval=0) const; - //! equivalent to SparseMat::value<_Tp>(i0, i1, hashval) - _Tp operator()(int i0, int i1, size_t* hashval=0) const; - //! equivalent to SparseMat::value<_Tp>(i0, i1, i2, hashval) - _Tp operator()(int i0, int i1, int i2, size_t* hashval=0) const; - //! equivalent to SparseMat::value<_Tp>(idx, hashval) - _Tp operator()(const int* idx, size_t* hashval=0) const; - - //! returns sparse matrix iterator pointing to the first sparse matrix element - SparseMatIterator_<_Tp> begin(); - //! returns read-only sparse matrix iterator pointing to the first sparse matrix element - SparseMatConstIterator_<_Tp> begin() const; - //! returns sparse matrix iterator pointing to the element following the last sparse matrix element - SparseMatIterator_<_Tp> end(); - //! returns read-only sparse matrix iterator pointing to the element following the last sparse matrix element - SparseMatConstIterator_<_Tp> end() const; -}; - /*! Template Read-Only Sparse Matrix Iterator Class. diff --git a/modules/core/include/opencv2/core/base.hpp b/modules/core/include/opencv2/core/base.hpp index 0c5d91a9ea..65376be219 100644 --- a/modules/core/include/opencv2/core/base.hpp +++ b/modules/core/include/opencv2/core/base.hpp @@ -441,9 +441,18 @@ class CV_EXPORTS Mat; class CV_EXPORTS SparseMat; typedef Mat MatND; +class CV_EXPORTS MatExpr; + template class CV_EXPORTS Mat_; +template class CV_EXPORTS SparseMat_; + +class CV_EXPORTS MatConstIterator; +class CV_EXPORTS SparseMatIterator; +class CV_EXPORTS SparseMatConstIterator; template class CV_EXPORTS MatIterator_; template class CV_EXPORTS MatConstIterator_; +template class CV_EXPORTS SparseMatIterator_; +template class CV_EXPORTS SparseMatConstIterator_; namespace ogl { diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp new file mode 100644 index 0000000000..b1a3facce0 --- /dev/null +++ b/modules/core/include/opencv2/core/mat.hpp @@ -0,0 +1,1428 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_CORE_MAT_HPP__ +#define __OPENCV_CORE_MAT_HPP__ + +#include "opencv2/core/matx.hpp" +#include "opencv2/core/types.hpp" + + +namespace cv +{ + +//////////////////////// Input/Output Array Arguments ///////////////////////////////// + +/*! + Proxy datatype for passing Mat's and vector<>'s as input parameters + */ +class CV_EXPORTS _InputArray +{ +public: + enum { + KIND_SHIFT = 16, + FIXED_TYPE = 0x8000 << KIND_SHIFT, + FIXED_SIZE = 0x4000 << KIND_SHIFT, + KIND_MASK = ~(FIXED_TYPE|FIXED_SIZE) - (1 << KIND_SHIFT) + 1, + + NONE = 0 << KIND_SHIFT, + MAT = 1 << KIND_SHIFT, + MATX = 2 << KIND_SHIFT, + STD_VECTOR = 3 << KIND_SHIFT, + STD_VECTOR_VECTOR = 4 << KIND_SHIFT, + STD_VECTOR_MAT = 5 << KIND_SHIFT, + EXPR = 6 << KIND_SHIFT, + OPENGL_BUFFER = 7 << KIND_SHIFT, + OPENGL_TEXTURE = 8 << KIND_SHIFT, + GPU_MAT = 9 << KIND_SHIFT + }; + + _InputArray(); + _InputArray(const Mat& m); + _InputArray(const MatExpr& expr); + _InputArray(const std::vector& vec); + template _InputArray(const Mat_<_Tp>& m); + template _InputArray(const std::vector<_Tp>& vec); + template _InputArray(const std::vector >& vec); + template _InputArray(const std::vector >& vec); + template _InputArray(const _Tp* vec, int n); + template _InputArray(const Matx<_Tp, m, n>& matx); + _InputArray(const Scalar& s); + _InputArray(const double& val); + _InputArray(const gpu::GpuMat& d_mat); + _InputArray(const ogl::Buffer& buf); + _InputArray(const ogl::Texture2D& tex); + + virtual Mat getMat(int i=-1) const; + virtual void getMatVector(std::vector& mv) const; + virtual gpu::GpuMat getGpuMat() const; + virtual ogl::Buffer getOGlBuffer() const; + virtual ogl::Texture2D getOGlTexture2D() const; + + virtual int kind() const; + virtual Size size(int i=-1) const; + virtual size_t total(int i=-1) const; + virtual int type(int i=-1) const; + virtual int depth(int i=-1) const; + virtual int channels(int i=-1) const; + virtual bool empty() const; + + virtual ~_InputArray(); + + int flags; + void* obj; + Size sz; +}; + + +/*! + Proxy datatype for passing Mat's and vector<>'s as input parameters + */ +class CV_EXPORTS _OutputArray : public _InputArray +{ +public: + enum + { + DEPTH_MASK_8U = 1 << CV_8U, + DEPTH_MASK_8S = 1 << CV_8S, + DEPTH_MASK_16U = 1 << CV_16U, + DEPTH_MASK_16S = 1 << CV_16S, + DEPTH_MASK_32S = 1 << CV_32S, + DEPTH_MASK_32F = 1 << CV_32F, + DEPTH_MASK_64F = 1 << CV_64F, + DEPTH_MASK_ALL = (DEPTH_MASK_64F<<1)-1, + DEPTH_MASK_ALL_BUT_8S = DEPTH_MASK_ALL & ~DEPTH_MASK_8S, + DEPTH_MASK_FLT = DEPTH_MASK_32F + DEPTH_MASK_64F + }; + + _OutputArray(); + _OutputArray(Mat& m); + _OutputArray(std::vector& vec); + _OutputArray(gpu::GpuMat& d_mat); + _OutputArray(ogl::Buffer& buf); + _OutputArray(ogl::Texture2D& tex); + template _OutputArray(std::vector<_Tp>& vec); + template _OutputArray(std::vector >& vec); + template _OutputArray(std::vector >& vec); + template _OutputArray(Mat_<_Tp>& m); + template _OutputArray(_Tp* vec, int n); + template _OutputArray(Matx<_Tp, m, n>& matx); + + _OutputArray(const Mat& m); + _OutputArray(const std::vector& vec); + _OutputArray(const gpu::GpuMat& d_mat); + _OutputArray(const ogl::Buffer& buf); + _OutputArray(const ogl::Texture2D& tex); + template _OutputArray(const std::vector<_Tp>& vec); + template _OutputArray(const std::vector >& vec); + template _OutputArray(const std::vector >& vec); + template _OutputArray(const Mat_<_Tp>& m); + template _OutputArray(const _Tp* vec, int n); + template _OutputArray(const Matx<_Tp, m, n>& matx); + + virtual bool fixedSize() const; + virtual bool fixedType() const; + virtual bool needed() const; + virtual Mat& getMatRef(int i=-1) const; + virtual gpu::GpuMat& getGpuMatRef() const; + virtual ogl::Buffer& getOGlBufferRef() const; + virtual ogl::Texture2D& getOGlTexture2DRef() const; + virtual void create(Size sz, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const; + virtual void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const; + virtual void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const; + virtual void release() const; + virtual void clear() const; + + virtual ~_OutputArray(); +}; + +typedef const _InputArray& InputArray; +typedef InputArray InputArrayOfArrays; +typedef const _OutputArray& OutputArray; +typedef OutputArray OutputArrayOfArrays; +typedef OutputArray InputOutputArray; +typedef OutputArray InputOutputArrayOfArrays; + +CV_EXPORTS OutputArray noArray(); + + + +/////////////////////////////////// MatAllocator ////////////////////////////////////// + +/*! + Custom array allocator + +*/ +class CV_EXPORTS MatAllocator +{ +public: + MatAllocator() {} + virtual ~MatAllocator() {} + virtual void allocate(int dims, const int* sizes, int type, int*& refcount, + uchar*& datastart, uchar*& data, size_t* step) = 0; + virtual void deallocate(int* refcount, uchar* datastart, uchar* data) = 0; +}; + + + +//////////////////////////////// MatCommaInitializer ////////////////////////////////// + +/*! + 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 MatCommaInitializer_ +{ +public: + //! the constructor, created by "matrix << firstValue" operator, where matrix is cv::Mat + MatCommaInitializer_(Mat_<_Tp>* _m); + //! the operator that takes the next value and put it to the matrix + template MatCommaInitializer_<_Tp>& operator , (T2 v); + //! another form of conversion operator + Mat_<_Tp> operator *() const; + operator Mat_<_Tp>() const; +protected: + MatIterator_<_Tp> it; +}; + + + + +/////////////////////////////////////// Mat /////////////////////////////////////////// + +/*! + The n-dimensional matrix class. + + The class represents an n-dimensional dense numerical array that can act as + a matrix, image, optical flow map, 3-focal tensor etc. + It is very similar to CvMat and CvMatND types from earlier versions of OpenCV, + and similarly to those types, the matrix can be multi-channel. It also fully supports ROI mechanism. + + There are many different ways to create cv::Mat object. Here are the some popular ones: +
    +
  • using cv::Mat::create(nrows, ncols, type) method or + the similar constructor cv::Mat::Mat(nrows, ncols, type[, fill_value]) constructor. + A new matrix of the specified size and specifed type will be allocated. + "type" has the same meaning as in cvCreateMat function, + e.g. CV_8UC1 means 8-bit single-channel matrix, CV_32FC2 means 2-channel (i.e. complex) + floating-point matrix etc: + + \code + // make 7x7 complex matrix filled with 1+3j. + cv::Mat M(7,7,CV_32FC2,Scalar(1,3)); + // and now turn M to 100x60 15-channel 8-bit matrix. + // The old content will be deallocated + M.create(100,60,CV_8UC(15)); + \endcode + + As noted in the introduction of this chapter, Mat::create() + will only allocate a new matrix when the current matrix dimensionality + or type are different from the specified. + +
  • by using a copy constructor or assignment operator, where on the right side it can + be a matrix or expression, see below. Again, as noted in the introduction, + matrix assignment is O(1) operation because it only copies the header + and increases the reference counter. cv::Mat::clone() method can be used to get a full + (a.k.a. deep) copy of the matrix when you need it. + +
  • by constructing a header for a part of another matrix. It can be a single row, single column, + several rows, several columns, rectangular region in the matrix (called a minor in algebra) or + a diagonal. Such operations are also O(1), because the new header will reference the same data. + You can actually modify a part of the matrix using this feature, e.g. + + \code + // add 5-th row, multiplied by 3 to the 3rd row + M.row(3) = M.row(3) + M.row(5)*3; + + // now copy 7-th column to the 1-st column + // M.col(1) = M.col(7); // this will not work + Mat M1 = M.col(1); + M.col(7).copyTo(M1); + + // create new 320x240 image + cv::Mat img(Size(320,240),CV_8UC3); + // select a roi + cv::Mat roi(img, Rect(10,10,100,100)); + // fill the ROI with (0,255,0) (which is green in RGB space); + // the original 320x240 image will be modified + roi = Scalar(0,255,0); + \endcode + + Thanks to the additional cv::Mat::datastart and cv::Mat::dataend members, it is possible to + compute the relative sub-matrix position in the main "container" matrix using cv::Mat::locateROI(): + + \code + Mat A = Mat::eye(10, 10, CV_32S); + // extracts A columns, 1 (inclusive) to 3 (exclusive). + Mat B = A(Range::all(), Range(1, 3)); + // extracts B rows, 5 (inclusive) to 9 (exclusive). + // that is, C ~ A(Range(5, 9), Range(1, 3)) + Mat C = B(Range(5, 9), Range::all()); + Size size; Point ofs; + C.locateROI(size, ofs); + // size will be (width=10,height=10) and the ofs will be (x=1, y=5) + \endcode + + As in the case of whole matrices, if you need a deep copy, use cv::Mat::clone() method + of the extracted sub-matrices. + +
  • by making a header for user-allocated-data. It can be useful for +
      +
    1. processing "foreign" data using OpenCV (e.g. when you implement + a DirectShow filter or a processing module for gstreamer etc.), e.g. + + \code + void process_video_frame(const unsigned char* pixels, + int width, int height, int step) + { + cv::Mat img(height, width, CV_8UC3, pixels, step); + cv::GaussianBlur(img, img, cv::Size(7,7), 1.5, 1.5); + } + \endcode + +
    2. for quick initialization of small matrices and/or super-fast element access + + \code + double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}}; + cv::Mat M = cv::Mat(3, 3, CV_64F, m).inv(); + \endcode +
    + + partial yet very common cases of this "user-allocated data" case are conversions + from CvMat and IplImage to cv::Mat. For this purpose there are special constructors + taking pointers to CvMat or IplImage and the optional + flag indicating whether to copy the data or not. + + Backward conversion from cv::Mat to CvMat or IplImage is provided via cast operators + cv::Mat::operator CvMat() an cv::Mat::operator IplImage(). + The operators do not copy the data. + + + \code + IplImage* img = cvLoadImage("greatwave.jpg", 1); + Mat mtx(img); // convert IplImage* -> cv::Mat + CvMat oldmat = mtx; // convert cv::Mat -> CvMat + CV_Assert(oldmat.cols == img->width && oldmat.rows == img->height && + oldmat.data.ptr == (uchar*)img->imageData && oldmat.step == img->widthStep); + \endcode + +
  • by using MATLAB-style matrix initializers, cv::Mat::zeros(), cv::Mat::ones(), cv::Mat::eye(), e.g.: + + \code + // create a double-precision identity martix and add it to M. + M += Mat::eye(M.rows, M.cols, CV_64F); + \endcode + +
  • by using comma-separated initializer: + + \code + // create 3x3 double-precision identity matrix + Mat M = (Mat_(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1); + \endcode + + here we first call constructor of cv::Mat_ class (that we describe further) with the proper matrix, + and then we just put "<<" operator followed by comma-separated values that can be constants, + variables, expressions etc. Also, note the extra parentheses that are needed to avoid compiler errors. + +
+ + Once matrix is created, it will be automatically managed by using reference-counting mechanism + (unless the matrix header is built on top of user-allocated data, + in which case you should handle the data by yourself). + The matrix data will be deallocated when no one points to it; + if you want to release the data pointed by a matrix header before the matrix destructor is called, + use cv::Mat::release(). + + The next important thing to learn about the matrix class is element access. Here is how the matrix is stored. + The elements are stored in row-major order (row by row). The cv::Mat::data member points to the first element of the first row, + cv::Mat::rows contains the number of matrix rows and cv::Mat::cols - the number of matrix columns. There is yet another member, + cv::Mat::step that is used to actually compute address of a matrix element. cv::Mat::step is needed because the matrix can be + a part of another matrix or because there can some padding space in the end of each row for a proper alignment. + + \image html roi.png + + Given these parameters, address of the matrix element M_{ij} is computed as following: + + addr(M_{ij})=M.data + M.step*i + j*M.elemSize() + + if you know the matrix element type, e.g. it is float, then you can use cv::Mat::at() method: + + addr(M_{ij})=&M.at(i,j) + + (where & is used to convert the reference returned by cv::Mat::at() to a pointer). + if you need to process a whole row of matrix, the most efficient way is to get + the pointer to the row first, and then just use plain C operator []: + + \code + // compute sum of positive matrix elements + // (assuming that M is double-precision matrix) + double sum=0; + for(int i = 0; i < M.rows; i++) + { + const double* Mi = M.ptr(i); + for(int j = 0; j < M.cols; j++) + sum += std::max(Mi[j], 0.); + } + \endcode + + Some operations, like the above one, do not actually depend on the matrix shape, + they just process elements of a matrix one by one (or elements from multiple matrices + that are sitting in the same place, e.g. matrix addition). Such operations are called + element-wise and it makes sense to check whether all the input/output matrices are continuous, + i.e. have no gaps in the end of each row, and if yes, process them as a single long row: + + \code + // compute sum of positive matrix elements, optimized variant + double sum=0; + int cols = M.cols, rows = M.rows; + if(M.isContinuous()) + { + cols *= rows; + rows = 1; + } + for(int i = 0; i < rows; i++) + { + const double* Mi = M.ptr(i); + for(int j = 0; j < cols; j++) + sum += std::max(Mi[j], 0.); + } + \endcode + in the case of continuous matrix the outer loop body will be executed just once, + so the overhead will be smaller, which will be especially noticeable in the case of small matrices. + + Finally, there are STL-style iterators that are smart enough to skip gaps between successive rows: + \code + // compute sum of positive matrix elements, iterator-based variant + double sum=0; + MatConstIterator_ it = M.begin(), it_end = M.end(); + for(; it != it_end; ++it) + sum += std::max(*it, 0.); + \endcode + + The matrix iterators are random-access iterators, so they can be passed + to any STL algorithm, including std::sort(). +*/ +class CV_EXPORTS Mat +{ +public: + //! default constructor + Mat(); + //! constructs 2D matrix of the specified size and type + // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.) + Mat(int rows, int cols, int type); + Mat(Size size, int type); + //! constucts 2D matrix and fills it with the specified value _s. + Mat(int rows, int cols, int type, const Scalar& s); + Mat(Size size, int type, const Scalar& s); + + //! constructs n-dimensional matrix + Mat(int ndims, const int* sizes, int type); + Mat(int ndims, const int* sizes, int type, const Scalar& s); + + //! copy constructor + Mat(const Mat& m); + //! constructor for matrix headers pointing to user-allocated data + Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP); + Mat(Size size, int type, void* data, size_t step=AUTO_STEP); + Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0); + + //! creates a matrix header for a part of the bigger matrix + Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all()); + Mat(const Mat& m, const Rect& roi); + Mat(const Mat& m, const Range* ranges); + //! builds matrix from std::vector with or without copying the data + template explicit Mat(const std::vector<_Tp>& vec, bool copyData=false); + //! builds matrix from cv::Vec; the data is copied by default + template explicit Mat(const Vec<_Tp, n>& vec, bool copyData=true); + //! builds matrix from cv::Matx; the data is copied by default + template explicit Mat(const Matx<_Tp, m, n>& mtx, bool copyData=true); + //! builds matrix from a 2D point + template explicit Mat(const Point_<_Tp>& pt, bool copyData=true); + //! builds matrix from a 3D point + template explicit Mat(const Point3_<_Tp>& pt, bool copyData=true); + //! builds matrix from comma initializer + template explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer); + + // //! converts old-style CvMat to the new matrix; the data is not copied by default + // Mat(const CvMat* m, bool copyData=false); + // //! converts old-style CvMatND to the new matrix; the data is not copied by default + // Mat(const CvMatND* m, bool copyData=false); + // //! converts old-style IplImage to the new matrix; the data is not copied by default + // Mat(const IplImage* img, bool copyData=false); + //Mat(const void* img, bool copyData=false); + + //! download data from GpuMat + explicit Mat(const gpu::GpuMat& m); + + //! destructor - calls release() + ~Mat(); + //! assignment operators + Mat& operator = (const Mat& m); + Mat& operator = (const MatExpr& expr); + + //! returns a new matrix header for the specified row + Mat row(int y) const; + //! returns a new matrix header for the specified column + Mat col(int x) const; + //! ... for the specified row span + Mat rowRange(int startrow, int endrow) const; + Mat rowRange(const Range& r) const; + //! ... for the specified column span + Mat colRange(int startcol, int endcol) const; + Mat colRange(const Range& r) const; + //! ... for the specified diagonal + // (d=0 - the main diagonal, + // >0 - a diagonal from the lower half, + // <0 - a diagonal from the upper half) + Mat diag(int d=0) const; + //! constructs a square diagonal matrix which main diagonal is vector "d" + static Mat diag(const Mat& d); + + //! returns deep copy of the matrix, i.e. the data is copied + Mat clone() const; + //! copies the matrix content to "m". + // It calls m.create(this->size(), this->type()). + void copyTo( OutputArray m ) const; + //! copies those matrix elements to "m" that are marked with non-zero mask elements. + void copyTo( OutputArray m, InputArray mask ) const; + //! converts matrix to another datatype with optional scalng. See cvConvertScale. + void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const; + + void assignTo( Mat& m, int type=-1 ) const; + + //! sets every matrix element to s + Mat& operator = (const Scalar& s); + //! sets some of the matrix elements to s, according to the mask + Mat& setTo(InputArray value, InputArray mask=noArray()); + //! creates alternative matrix header for the same data, with different + // number of channels and/or different number of rows. see cvReshape. + Mat reshape(int cn, int rows=0) const; + Mat reshape(int cn, int newndims, const int* newsz) const; + + //! matrix transposition by means of matrix expressions + MatExpr t() const; + //! matrix inversion by means of matrix expressions + MatExpr inv(int method=DECOMP_LU) const; + //! per-element matrix multiplication by means of matrix expressions + MatExpr mul(InputArray m, double scale=1) const; + + //! computes cross-product of 2 3D vectors + Mat cross(InputArray m) const; + //! computes dot-product + double dot(InputArray m) const; + + //! Matlab-style matrix initialization + static MatExpr zeros(int rows, int cols, int type); + static MatExpr zeros(Size size, int type); + static MatExpr zeros(int ndims, const int* sz, int type); + static MatExpr ones(int rows, int cols, int type); + static MatExpr ones(Size size, int type); + static MatExpr ones(int ndims, const int* sz, int type); + static MatExpr eye(int rows, int cols, int type); + static MatExpr eye(Size size, int type); + + //! allocates new matrix data unless the matrix already has specified size and type. + // previous data is unreferenced if needed. + void create(int rows, int cols, int type); + void create(Size size, int type); + void create(int ndims, const int* sizes, int type); + + //! increases the reference counter; use with care to avoid memleaks + void addref(); + //! decreases reference counter; + // deallocates the data when reference counter reaches 0. + void release(); + + //! deallocates the matrix data + void deallocate(); + //! internal use function; properly re-allocates _size, _step arrays + void copySize(const Mat& m); + + //! reserves enough space to fit sz hyper-planes + void reserve(size_t sz); + //! resizes matrix to the specified number of hyper-planes + void resize(size_t sz); + //! resizes matrix to the specified number of hyper-planes; initializes the newly added elements + void resize(size_t sz, const Scalar& s); + //! internal function + void push_back_(const void* elem); + //! adds element to the end of 1d matrix (or possibly multiple elements when _Tp=Mat) + template void push_back(const _Tp& elem); + template void push_back(const Mat_<_Tp>& elem); + void push_back(const Mat& m); + //! removes several hyper-planes from bottom of the matrix + void pop_back(size_t nelems=1); + + //! locates matrix header within a parent matrix. See below + void locateROI( Size& wholeSize, Point& ofs ) const; + //! moves/resizes the current matrix ROI inside the parent matrix. + Mat& adjustROI( int dtop, int dbottom, int dleft, int dright ); + //! extracts a rectangular sub-matrix + // (this is a generalized form of row, rowRange etc.) + Mat operator()( Range rowRange, Range colRange ) const; + Mat operator()( const Rect& roi ) const; + Mat operator()( const Range* ranges ) const; + + // //! converts header to CvMat; no data is copied + // operator CvMat() const; + // //! converts header to CvMatND; no data is copied + // operator CvMatND() const; + // //! converts header to IplImage; no data is copied + // operator IplImage() const; + + template operator std::vector<_Tp>() const; + template operator Vec<_Tp, n>() const; + template operator Matx<_Tp, m, n>() const; + + //! returns true iff the matrix data is continuous + // (i.e. when there are no gaps between successive rows). + // similar to CV_IS_MAT_CONT(cvmat->type) + bool isContinuous() const; + + //! returns true if the matrix is a submatrix of another matrix + bool isSubmatrix() const; + + //! returns element size in bytes, + // similar to CV_ELEM_SIZE(cvmat->type) + size_t elemSize() const; + //! returns the size of element channel in bytes. + size_t elemSize1() const; + //! returns element type, similar to CV_MAT_TYPE(cvmat->type) + int type() const; + //! returns element type, similar to CV_MAT_DEPTH(cvmat->type) + int depth() const; + //! returns element type, similar to CV_MAT_CN(cvmat->type) + int channels() const; + //! returns step/elemSize1() + size_t step1(int i=0) const; + //! returns true if matrix data is NULL + bool empty() const; + //! returns the total number of matrix elements + size_t total() const; + + //! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise + int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const; + + //! returns pointer to i0-th submatrix along the dimension #0 + uchar* ptr(int i0=0); + const uchar* ptr(int i0=0) const; + + //! returns pointer to (i0,i1) submatrix along the dimensions #0 and #1 + uchar* ptr(int i0, int i1); + const uchar* ptr(int i0, int i1) const; + + //! returns pointer to (i0,i1,i3) submatrix along the dimensions #0, #1, #2 + uchar* ptr(int i0, int i1, int i2); + const uchar* ptr(int i0, int i1, int i2) const; + + //! returns pointer to the matrix element + uchar* ptr(const int* idx); + //! returns read-only pointer to the matrix element + const uchar* ptr(const int* idx) const; + + template uchar* ptr(const Vec& idx); + template const uchar* ptr(const Vec& idx) const; + + //! template version of the above method + template _Tp* ptr(int i0=0); + template const _Tp* ptr(int i0=0) const; + + template _Tp* ptr(int i0, int i1); + template const _Tp* ptr(int i0, int i1) const; + + template _Tp* ptr(int i0, int i1, int i2); + template const _Tp* ptr(int i0, int i1, int i2) const; + + template _Tp* ptr(const int* idx); + template const _Tp* ptr(const int* idx) const; + + template _Tp* ptr(const Vec& idx); + template const _Tp* ptr(const Vec& idx) const; + + //! the same as above, with the pointer dereferencing + template _Tp& at(int i0=0); + template const _Tp& at(int i0=0) const; + + template _Tp& at(int i0, int i1); + template const _Tp& at(int i0, int i1) const; + + template _Tp& at(int i0, int i1, int i2); + template const _Tp& at(int i0, int i1, int i2) const; + + template _Tp& at(const int* idx); + template const _Tp& at(const int* idx) const; + + template _Tp& at(const Vec& idx); + template const _Tp& at(const Vec& idx) const; + + //! special versions for 2D arrays (especially convenient for referencing image pixels) + template _Tp& at(Point pt); + template const _Tp& at(Point pt) const; + + //! template methods for iteration over matrix elements. + // the iterators take care of skipping gaps in the end of rows (if any) + template MatIterator_<_Tp> begin(); + template MatIterator_<_Tp> end(); + template MatConstIterator_<_Tp> begin() const; + template MatConstIterator_<_Tp> end() const; + + enum { MAGIC_VAL=0x42FF0000, AUTO_STEP=0, CONTINUOUS_FLAG=CV_MAT_CONT_FLAG, SUBMATRIX_FLAG=CV_SUBMAT_FLAG }; + enum { MAGIC_MASK=0xFFFF0000, TYPE_MASK=0x00000FFF, DEPTH_MASK=7 }; + + /*! includes several bit-fields: + - the magic signature + - continuity flag + - depth + - number of channels + */ + int flags; + //! the matrix dimensionality, >= 2 + int dims; + //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions + int rows, cols; + //! pointer to the data + uchar* data; + + //! pointer to the reference counter; + // when matrix points to user-allocated data, the pointer is NULL + int* refcount; + + //! helper fields used in locateROI and adjustROI + uchar* datastart; + uchar* dataend; + uchar* datalimit; + + //! custom allocator + MatAllocator* allocator; + + struct CV_EXPORTS MSize + { + MSize(int* _p); + Size operator()() const; + const int& operator[](int i) const; + int& operator[](int i); + operator const int*() const; + bool operator == (const MSize& sz) const; + bool operator != (const MSize& sz) const; + + int* p; + }; + + struct CV_EXPORTS MStep + { + MStep(); + MStep(size_t s); + const size_t& operator[](int i) const; + size_t& operator[](int i); + operator size_t() const; + MStep& operator = (size_t s); + + size_t* p; + size_t buf[2]; + protected: + MStep& operator = (const MStep&); + }; + + MSize size; + MStep step; + +protected: + void initEmpty(); +}; + + +///////////////////////////////// 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: + typedef _Tp value_type; + typedef typename DataType<_Tp>::channel_type channel_type; + typedef MatIterator_<_Tp> iterator; + typedef MatConstIterator_<_Tp> const_iterator; + + //! default constructor + Mat_(); + //! equivalent to Mat(_rows, _cols, DataType<_Tp>::type) + Mat_(int _rows, int _cols); + //! constructor that sets each matrix element to specified value + Mat_(int _rows, int _cols, const _Tp& value); + //! equivalent to Mat(_size, DataType<_Tp>::type) + explicit Mat_(Size _size); + //! constructor that sets each matrix element to specified value + Mat_(Size _size, const _Tp& value); + //! n-dim array constructor + Mat_(int _ndims, const int* _sizes); + //! n-dim array constructor that sets each matrix element to specified value + Mat_(int _ndims, const int* _sizes, const _Tp& value); + //! copy/conversion contructor. If m is of different type, it's converted + Mat_(const Mat& m); + //! copy constructor + Mat_(const Mat_& m); + //! constructs a matrix on top of user-allocated data. step is in bytes(!!!), regardless of the type + Mat_(int _rows, int _cols, _Tp* _data, size_t _step=AUTO_STEP); + //! constructs n-dim matrix on top of user-allocated data. steps are in bytes(!!!), regardless of the type + Mat_(int _ndims, const int* _sizes, _Tp* _data, const size_t* _steps=0); + //! selects a submatrix + Mat_(const Mat_& m, const Range& rowRange, const Range& colRange=Range::all()); + //! selects a submatrix + Mat_(const Mat_& m, const Rect& roi); + //! selects a submatrix, n-dim version + Mat_(const Mat_& m, const Range* ranges); + //! from a matrix expression + explicit Mat_(const MatExpr& e); + //! makes a matrix out of Vec, std::vector, Point_ or Point3_. The matrix will have a single column + explicit Mat_(const std::vector<_Tp>& vec, bool copyData=false); + template explicit Mat_(const Vec::channel_type, n>& vec, bool copyData=true); + template explicit Mat_(const Matx::channel_type, m, n>& mtx, bool copyData=true); + explicit Mat_(const Point_::channel_type>& pt, bool copyData=true); + explicit Mat_(const Point3_::channel_type>& pt, bool copyData=true); + explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer); + + Mat_& operator = (const Mat& m); + Mat_& operator = (const Mat_& m); + //! set all the elements to s. + Mat_& operator = (const _Tp& s); + //! assign a matrix expression + Mat_& operator = (const MatExpr& e); + + //! iterators; they are smart enough to skip gaps in the end of rows + iterator begin(); + iterator end(); + const_iterator begin() const; + const_iterator end() const; + + //! equivalent to Mat::create(_rows, _cols, DataType<_Tp>::type) + void create(int _rows, int _cols); + //! equivalent to Mat::create(_size, DataType<_Tp>::type) + void create(Size _size); + //! equivalent to Mat::create(_ndims, _sizes, DatType<_Tp>::type) + void create(int _ndims, const int* _sizes); + //! cross-product + Mat_ cross(const Mat_& m) const; + //! data type conversion + template operator Mat_() const; + //! overridden forms of Mat::row() etc. + Mat_ row(int y) const; + Mat_ col(int x) const; + Mat_ diag(int d=0) const; + Mat_ clone() const; + + //! overridden forms of Mat::elemSize() etc. + size_t elemSize() const; + size_t elemSize1() const; + int type() const; + int depth() const; + int channels() const; + size_t step1(int i=0) const; + //! returns step()/sizeof(_Tp) + size_t stepT(int i=0) const; + + //! overridden forms of Mat::zeros() etc. Data type is omitted, of course + static MatExpr zeros(int rows, int cols); + static MatExpr zeros(Size size); + static MatExpr zeros(int _ndims, const int* _sizes); + static MatExpr ones(int rows, int cols); + static MatExpr ones(Size size); + static MatExpr ones(int _ndims, const int* _sizes); + static MatExpr eye(int rows, int cols); + static MatExpr eye(Size size); + + //! some more overriden methods + Mat_& adjustROI( int dtop, int dbottom, int dleft, int dright ); + Mat_ operator()( const Range& rowRange, const Range& colRange ) const; + Mat_ operator()( const Rect& roi ) const; + Mat_ operator()( const Range* ranges ) const; + + //! more convenient forms of row and element access operators + _Tp* operator [](int y); + const _Tp* operator [](int y) const; + + //! returns reference to the specified element + _Tp& operator ()(const int* idx); + //! returns read-only reference to the specified element + const _Tp& operator ()(const int* idx) const; + + //! returns reference to the specified element + template _Tp& operator ()(const Vec& idx); + //! returns read-only reference to the specified element + template const _Tp& operator ()(const Vec& idx) const; + + //! returns reference to the specified element (1D case) + _Tp& operator ()(int idx0); + //! returns read-only reference to the specified element (1D case) + const _Tp& operator ()(int idx0) const; + //! returns reference to the specified element (2D case) + _Tp& operator ()(int idx0, int idx1); + //! returns read-only reference to the specified element (2D case) + const _Tp& operator ()(int idx0, int idx1) const; + //! returns reference to the specified element (3D case) + _Tp& operator ()(int idx0, int idx1, int idx2); + //! returns read-only reference to the specified element (3D case) + const _Tp& operator ()(int idx0, int idx1, int idx2) const; + + _Tp& operator ()(Point pt); + const _Tp& operator ()(Point pt) const; + + //! conversion to vector. + operator std::vector<_Tp>() const; + //! conversion to Vec + template operator Vec::channel_type, n>() const; + //! conversion to Matx + template operator Matx::channel_type, m, n>() const; +}; + +typedef Mat_ Mat1b; +typedef Mat_ Mat2b; +typedef Mat_ Mat3b; +typedef Mat_ Mat4b; + +typedef Mat_ Mat1s; +typedef Mat_ Mat2s; +typedef Mat_ Mat3s; +typedef Mat_ Mat4s; + +typedef Mat_ Mat1w; +typedef Mat_ Mat2w; +typedef Mat_ Mat3w; +typedef Mat_ Mat4w; + +typedef Mat_ Mat1i; +typedef Mat_ Mat2i; +typedef Mat_ Mat3i; +typedef Mat_ Mat4i; + +typedef Mat_ Mat1f; +typedef Mat_ Mat2f; +typedef Mat_ Mat3f; +typedef Mat_ Mat4f; + +typedef Mat_ Mat1d; +typedef Mat_ Mat2d; +typedef Mat_ Mat3d; +typedef Mat_ Mat4d; + + + +/////////////////////////// multi-dimensional sparse matrix ////////////////////////// + +/*! + Sparse matrix class. + + The class represents multi-dimensional sparse numerical arrays. Such a sparse array can store elements + of any type that cv::Mat is able to store. "Sparse" means that only non-zero elements + are stored (though, as a result of some operations on a sparse matrix, some of its stored elements + can actually become 0. It's user responsibility to detect such elements and delete them using cv::SparseMat::erase(). + The non-zero elements are stored in a hash table that grows when it's filled enough, + so that the search time remains O(1) in average. Elements can be accessed using the following methods: + +
    +
  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::Mat iterators, the sparse matrix iterators are STL-style, + that is, the iteration is done as following: + \code + // prints elements of a sparse floating-point matrix and the sum of elements. + SparseMatConstIterator_ + 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; + + enum { MAGIC_VAL=0x42FD0000, MAX_DIM=32, HASH_SCALE=0x5bd1e995, HASH_BIT=0x80000000 }; + + //! the sparse matrix header + struct CV_EXPORTS Hdr + { + Hdr(int _dims, const int* _sizes, int _type); + void clear(); + int refcount; + int dims; + int valueOffset; + size_t nodeSize; + size_t nodeCount; + size_t freeList; + std::vector pool; + std::vector hashtab; + int size[MAX_DIM]; + }; + + //! sparse matrix node - element of a hash table + struct CV_EXPORTS Node + { + //! hash value + size_t hashval; + //! index of the next node in the same hash table entry + size_t next; + //! index of the matrix element + int idx[MAX_DIM]; + }; + + //! default constructor + SparseMat(); + //! creates matrix of the specified size and type + SparseMat(int dims, const int* _sizes, int _type); + //! copy constructor + SparseMat(const SparseMat& m); + //! converts dense 2d matrix to the sparse form + /*! + \param m the input matrix + \param try1d if true and m is a single-column matrix (Nx1), + then the sparse matrix will be 1-dimensional. + */ + explicit SparseMat(const Mat& m); + //! converts old-style sparse matrix to the new-style. All the data is copied + //SparseMat(const CvSparseMat* m); + //! the destructor + ~SparseMat(); + + //! assignment operator. This is O(1) operation, i.e. no data is copied + SparseMat& operator = (const SparseMat& m); + //! equivalent to the corresponding constructor + SparseMat& operator = (const Mat& m); + + //! creates full copy of the matrix + SparseMat clone() const; + + //! copies all the data to the destination matrix. All the previous content of m is erased + void copyTo( SparseMat& m ) const; + //! converts sparse matrix to dense matrix. + void copyTo( Mat& m ) const; + //! multiplies all the matrix elements by the specified scale factor alpha and converts the results to the specified data type + void convertTo( SparseMat& m, int rtype, double alpha=1 ) const; + //! converts sparse matrix to dense n-dim matrix with optional type conversion and scaling. + /*! + \param rtype The output matrix data type. When it is =-1, the output array will have the same data type as (*this) + \param alpha The scale factor + \param beta The optional delta added to the scaled values before the conversion + */ + void convertTo( Mat& m, int rtype, double alpha=1, double beta=0 ) const; + + // not used now + void assignTo( SparseMat& m, int type=-1 ) const; + + //! reallocates sparse matrix. + /*! + If the matrix already had the proper size and type, + it is simply cleared with clear(), otherwise, + the old matrix is released (using release()) and the new one is allocated. + */ + void create(int dims, const int* _sizes, int _type); + //! sets all the sparse matrix elements to 0, which means clearing the hash table. + void clear(); + //! manually increments the reference counter to the header. + void addref(); + // decrements the header reference counter. When the counter reaches 0, the header and all the underlying data are deallocated. + void release(); + + //! converts sparse matrix to the old-style representation; all the elements are copied. + //operator CvSparseMat*() const; + //! returns the size of each element in bytes (not including the overhead - the space occupied by SparseMat::Node elements) + size_t elemSize() const; + //! returns elemSize()/channels() + size_t elemSize1() const; + + //! returns type of sparse matrix elements + int type() const; + //! returns the depth of sparse matrix elements + int depth() const; + //! returns the number of channels + int channels() const; + + //! returns the array of sizes, or NULL if the matrix is not allocated + const int* size() const; + //! returns the size of i-th matrix dimension (or 0) + int size(int i) const; + //! returns the matrix dimensionality + int dims() const; + //! returns the number of non-zero elements (=the number of hash table nodes) + size_t nzcount() const; + + //! computes the element hash value (1D case) + size_t hash(int i0) const; + //! computes the element hash value (2D case) + size_t hash(int i0, int i1) const; + //! computes the element hash value (3D case) + size_t hash(int i0, int i1, int i2) const; + //! computes the element hash value (nD case) + size_t hash(const int* idx) const; + + //@{ + /*! + specialized variants for 1D, 2D, 3D cases and the generic_type one for n-D case. + + return pointer to the matrix element. +
    +
  • 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); + //@} + + //@{ + /*! + 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); + //! returns reference to the specified element (2D case) + template _Tp& ref(int i0, int i1, size_t* hashval=0); + //! returns reference to the specified element (3D case) + template _Tp& ref(int i0, int i1, int i2, size_t* hashval=0); + //! 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; + + //! erases the specified element (2D case) + void erase(int i0, int i1, size_t* hashval=0); + //! erases the specified element (3D case) + void erase(int i0, int i1, int i2, size_t* hashval=0); + //! erases the specified element (nD case) + void erase(const int* idx, size_t* hashval=0); + + //@{ + /*! + return the sparse matrix iterator pointing to the first sparse matrix element + */ + //! returns the sparse matrix iterator at the matrix beginning + SparseMatIterator begin(); + //! returns the sparse matrix iterator at the matrix beginning + template 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; + + //! 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 /////////////// + Node* node(size_t nidx); + const Node* node(size_t nidx) const; + + uchar* newNode(const int* idx, size_t hashval); + void removeNode(size_t hidx, size_t nidx, size_t previdx); + void resizeHashTab(size_t newsize); + + int flags; + Hdr* hdr; +}; + + + +///////////////////////////////// Mat_<_Tp> //////////////////////////////////// + +/*! + 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 matrix to the sparse form + SparseMat_(const Mat& m); + //! converts the old-style sparse matrix to the C++ class. All the elements are copied + //SparseMat_(const CvSparseMat* m); + //! the assignment operator. If DataType<_Tp>.type != m.type(), the m elements are converted + SparseMat_& operator = (const SparseMat& m); + //! the assignment operator. This is O(1) operation - no data is copied + SparseMat_& operator = (const SparseMat_& m); + //! converts dense matrix to the sparse form + SparseMat_& operator = (const Mat& m); + + //! makes full copy of the matrix. All the elements are duplicated + SparseMat_ clone() const; + //! equivalent to cv::SparseMat::create(dims, _sizes, DataType<_Tp>::type) + void create(int dims, const int* _sizes); + //! converts sparse matrix to the old-style CvSparseMat. All the elements are copied + //operator CvSparseMat*() const; + + //! returns type of the matrix elements + int type() const; + //! returns depth of the matrix elements + int depth() const; + //! returns the number of channels in each matrix element + int channels() const; + + //! equivalent to SparseMat::ref<_Tp>(i0, hashval) + _Tp& ref(int i0, size_t* hashval=0); + //! equivalent to SparseMat::ref<_Tp>(i0, i1, hashval) + _Tp& ref(int i0, int i1, size_t* hashval=0); + //! equivalent to SparseMat::ref<_Tp>(i0, i1, i2, hashval) + _Tp& ref(int i0, int i1, int i2, size_t* hashval=0); + //! equivalent to SparseMat::ref<_Tp>(idx, hashval) + _Tp& ref(const int* idx, size_t* hashval=0); + + //! equivalent to SparseMat::value<_Tp>(i0, hashval) + _Tp operator()(int i0, size_t* hashval=0) const; + //! equivalent to SparseMat::value<_Tp>(i0, i1, hashval) + _Tp operator()(int i0, int i1, size_t* hashval=0) const; + //! equivalent to SparseMat::value<_Tp>(i0, i1, i2, hashval) + _Tp operator()(int i0, int i1, int i2, size_t* hashval=0) const; + //! equivalent to SparseMat::value<_Tp>(idx, hashval) + _Tp operator()(const int* idx, size_t* hashval=0) const; + + //! returns sparse matrix iterator pointing to the first sparse matrix element + SparseMatIterator_<_Tp> begin(); + //! returns read-only sparse matrix iterator pointing to the first sparse matrix element + SparseMatConstIterator_<_Tp> begin() const; + //! returns sparse matrix iterator pointing to the element following the last sparse matrix element + SparseMatIterator_<_Tp> end(); + //! returns read-only sparse matrix iterator pointing to the element following the last sparse matrix element + SparseMatConstIterator_<_Tp> end() const; +}; + +} // cv + +#endif // __OPENCV_CORE_MAT_HPP__ diff --git a/modules/core/include/opencv2/core/mat.inl.hpp b/modules/core/include/opencv2/core/mat.inl.hpp index 5353b42b4b..83b0dbc8a6 100644 --- a/modules/core/include/opencv2/core/mat.inl.hpp +++ b/modules/core/include/opencv2/core/mat.inl.hpp @@ -383,15 +383,6 @@ inline Mat Mat::operator()(const Range* ranges) const return Mat(*this, ranges); } -inline Mat::operator CvMat() const -{ - CV_DbgAssert(dims <= 2); - CvMat m = cvMat(rows, dims == 1 ? 1 : cols, type(), data); - m.step = (int)step[0]; - m.type = (m.type & ~CONTINUOUS_FLAG) | (flags & CONTINUOUS_FLAG); - return m; -} - inline bool Mat::isContinuous() const { return (flags & CONTINUOUS_FLAG) != 0; } inline bool Mat::isSubmatrix() const { return (flags & SUBMATRIX_FLAG) != 0; } inline size_t Mat::elemSize() const { return dims > 0 ? step.p[dims-1] : 0; } @@ -2411,11 +2402,11 @@ template inline SparseMat_<_Tp>::SparseMat_(const Mat& m) *this = sm; } -template inline SparseMat_<_Tp>::SparseMat_(const CvSparseMat* m) -{ - SparseMat sm(m); - *this = sm; -} +// template inline SparseMat_<_Tp>::SparseMat_(const CvSparseMat* m) +// { +// SparseMat sm(m); +// *this = sm; +// } template inline SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const SparseMat_<_Tp>& m) @@ -2457,11 +2448,11 @@ SparseMat_<_Tp>::create(int _dims, const int* _sizes) SparseMat::create(_dims, _sizes, DataType<_Tp>::type); } -template inline -SparseMat_<_Tp>::operator CvSparseMat*() const -{ - return SparseMat::operator CvSparseMat*(); -} +// template inline +// SparseMat_<_Tp>::operator CvSparseMat*() const +// { +// return SparseMat::operator CvSparseMat*(); +// } template inline int SparseMat_<_Tp>::type() const { return DataType<_Tp>::type; } diff --git a/modules/core/include/opencv2/core/types_c.h b/modules/core/include/opencv2/core/types_c.h index cd0df84e87..b2f157cd77 100644 --- a/modules/core/include/opencv2/core/types_c.h +++ b/modules/core/include/opencv2/core/types_c.h @@ -94,6 +94,7 @@ #ifdef __cplusplus # include "opencv2/core/types.hpp" +# include "opencv2/core/mat.hpp" #endif /* CvArr* is used to pass arbitrary @@ -307,6 +308,11 @@ typedef struct _IplImage char *imageDataOrigin; /* Pointer to very origin of image data (not necessarily aligned) - needed for correct deallocation */ + +#ifdef __cplusplus + _IplImage() {} + _IplImage(const cv::Mat& m); +#endif } IplImage; @@ -417,6 +423,12 @@ typedef struct CvMat int cols; #endif + +#ifdef __cplusplus + CvMat() {} + CvMat(const cv::Mat& m); +#endif + } CvMat; @@ -478,6 +490,16 @@ CV_INLINE CvMat cvMat( int rows, int cols, int type, void* data CV_DEFAULT(NULL) return m; } +#ifdef __cplusplus +inline CvMat::CvMat(const cv::Mat& m) +{ + CV_DbgAssert(m.dims <= 2); + *this = cvMat(m.rows, m.dims == 1 ? 1 : m.cols, m.type(), m.data); + step = (int)m.step[0]; + type = (type & ~cv::Mat::CONTINUOUS_FLAG) | (m.flags & cv::Mat::CONTINUOUS_FLAG); +} +#endif + #define CV_MAT_ELEM_PTR_FAST( mat, row, col, pix_size ) \ (assert( (unsigned)(row) < (unsigned)(mat).rows && \ @@ -567,6 +589,11 @@ typedef struct CvMatND int step; } dim[CV_MAX_DIM]; + +#ifdef __cplusplus + CvMatND() {} + CvMatND(const cv::Mat& m); +#endif } CvMatND; @@ -586,7 +613,7 @@ CvMatND; struct CvSet; -typedef struct CvSparseMat +typedef struct CV_EXPORTS CvSparseMat { int type; int dims; @@ -599,9 +626,17 @@ typedef struct CvSparseMat int valoffset; int idxoffset; int size[CV_MAX_DIM]; + +#ifdef __cplusplus + void copyToSparseMat(cv::SparseMat& m) const; +#endif } CvSparseMat; +#ifdef __cplusplus + CvSparseMat* cvCreateSparseMat(const cv::SparseMat& m); +#endif + #define CV_IS_SPARSE_MAT_HDR(mat) \ ((mat) != NULL && \ (((const CvSparseMat*)(mat))->type & CV_MAGIC_MASK) == CV_SPARSE_MAT_MAGIC_VAL) diff --git a/modules/core/src/array.cpp b/modules/core/src/array.cpp index b4511c0af6..c91a1dc7f6 100644 --- a/modules/core/src/array.cpp +++ b/modules/core/src/array.cpp @@ -305,7 +305,8 @@ cvCloneMatND( const CvMatND* src ) if( src->data.ptr ) { cvCreateData( dst ); - cv::Mat _src(src), _dst(dst); + cv::Mat _src = cv::cvarrToMat(src); + cv::Mat _dst = cv::cvarrToMat(dst); uchar* data0 = dst->data.ptr; _src.copyTo(_dst); CV_Assert(_dst.data == data0); diff --git a/modules/core/src/gpumat.cpp b/modules/core/src/gpumat.cpp index 02a4d61c76..09e1562d6d 100644 --- a/modules/core/src/gpumat.cpp +++ b/modules/core/src/gpumat.cpp @@ -544,7 +544,7 @@ cv::gpu::GpuMat::GpuMat(const GpuMat& m) } cv::gpu::GpuMat::GpuMat(int rows_, int cols_, int type_, void* data_, size_t step_) : - flags(Mat::MAGIC_VAL + (type_ & TYPE_MASK)), rows(rows_), cols(cols_), + flags(Mat::MAGIC_VAL + (type_ & Mat::TYPE_MASK)), rows(rows_), cols(cols_), step(step_), data((uchar*)data_), refcount(0), datastart((uchar*)data_), dataend((uchar*)data_) { @@ -568,7 +568,7 @@ cv::gpu::GpuMat::GpuMat(int rows_, int cols_, int type_, void* data_, size_t ste } cv::gpu::GpuMat::GpuMat(Size size_, int type_, void* data_, size_t step_) : - flags(Mat::MAGIC_VAL + (type_ & TYPE_MASK)), rows(size_.height), cols(size_.width), + flags(Mat::MAGIC_VAL + (type_ & Mat::TYPE_MASK)), rows(size_.height), cols(size_.width), step(step_), data((uchar*)data_), refcount(0), datastart((uchar*)data_), dataend((uchar*)data_) { @@ -1495,7 +1495,7 @@ GpuMat& cv::gpu::GpuMat::setTo(Scalar s, const GpuMat& mask) void cv::gpu::GpuMat::create(int _rows, int _cols, int _type) { - _type &= TYPE_MASK; + _type &= Mat::TYPE_MASK; if (rows == _rows && cols == _cols && type() == _type && data) return; diff --git a/modules/core/src/lapack.cpp b/modules/core/src/lapack.cpp index 53ea2d40eb..687b75e4b8 100644 --- a/modules/core/src/lapack.cpp +++ b/modules/core/src/lapack.cpp @@ -1689,7 +1689,6 @@ cvDet( const CvArr* arr ) if( rows == 3 ) return det3(Md); } - return cv::determinant(cv::Mat(mat)); } return cv::determinant(cv::cvarrToMat(arr)); } diff --git a/modules/core/src/mathfuncs.cpp b/modules/core/src/mathfuncs.cpp index 8e76d72355..2df111f0db 100644 --- a/modules/core/src/mathfuncs.cpp +++ b/modules/core/src/mathfuncs.cpp @@ -2350,7 +2350,7 @@ int cv::solveCubic( InputArray _coeffs, OutputArray _roots ) coeffs.size() == Size(1, n0) || coeffs.size() == Size(1, n0+1)) ); - _roots.create(n0, 1, ctype, -1, true, DEPTH_MASK_FLT); + _roots.create(n0, 1, ctype, -1, true, _OutputArray::DEPTH_MASK_FLT); Mat roots = _roots.getMat(); int i = -1, n = 0; @@ -2482,7 +2482,7 @@ double cv::solvePoly( InputArray _coeffs0, OutputArray _roots0, int maxIters ) int n = coeffs0.cols + coeffs0.rows - 2; - _roots0.create(n, 1, CV_MAKETYPE(cdepth, 2), -1, true, DEPTH_MASK_FLT); + _roots0.create(n, 1, CV_MAKETYPE(cdepth, 2), -1, true, _OutputArray::DEPTH_MASK_FLT); Mat roots0 = _roots0.getMat(); AutoBuffer buf(n*2+2); @@ -2550,7 +2550,9 @@ cvSolveCubic( const CvMat* coeffs, CvMat* roots ) void cvSolvePoly(const CvMat* a, CvMat *r, int maxiter, int) { - cv::Mat _a = cv::cvarrToMat(a), _r = cv::cvarrToMat(r), _r0 = r; + cv::Mat _a = cv::cvarrToMat(a); + cv::Mat _r = cv::cvarrToMat(r); + cv::Mat _r0 = _r; cv::solvePoly(_a, _r, maxiter); CV_Assert( _r.data == _r0.data ); // check that the array of roots was not reallocated } diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index 07a5d30a48..d833d30867 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -371,13 +371,14 @@ Mat::Mat(const Mat& m, const Range* ranges) : size(&rows) } -Mat::Mat(const CvMatND* m, bool copyData) : size(&rows) +static Mat cvMatNDToMat(const CvMatND* m, bool copyData) { - initEmpty(); + Mat thiz; + if( !m ) - return; - data = datastart = m->data.ptr; - flags |= CV_MAT_TYPE(m->type); + return thiz; + thiz.data = thiz.datastart = m->data.ptr; + thiz.flags |= CV_MAT_TYPE(m->type); int _sizes[CV_MAX_DIM]; size_t _steps[CV_MAX_DIM]; @@ -388,145 +389,141 @@ Mat::Mat(const CvMatND* m, bool copyData) : size(&rows) _steps[i] = m->dim[i].step; } - setSize(*this, d, _sizes, _steps); - finalizeHdr(*this); + setSize(thiz, d, _sizes, _steps); + finalizeHdr(thiz); if( copyData ) { - Mat temp(*this); - temp.copyTo(*this); - } -} - - -Mat Mat::diag(int d) const -{ - CV_Assert( dims <= 2 ); - Mat m = *this; - size_t esz = elemSize(); - int len; - - if( d >= 0 ) - { - len = std::min(cols - d, rows); - m.data += esz*d; - } - else - { - len = std::min(rows + d, cols); - m.data -= step[0]*d; + Mat temp(thiz); + thiz.release(); + temp.copyTo(thiz); } - CV_DbgAssert( len > 0 ); - - m.size[0] = m.rows = len; - m.size[1] = m.cols = 1; - m.step[0] += (len > 1 ? esz : 0); - - if( m.rows > 1 ) - m.flags &= ~CONTINUOUS_FLAG; - else - m.flags |= CONTINUOUS_FLAG; - - if( size() != Size(1,1) ) - m.flags |= SUBMATRIX_FLAG; - return m; + return thiz; } - -Mat::Mat(const CvMat* m, bool copyData) : size(&rows) +static Mat cvMatToMat(const CvMat* m, bool copyData) { - initEmpty(); + Mat thiz; if( !m ) - return; + return thiz; if( !copyData ) { - flags = MAGIC_VAL + (m->type & (CV_MAT_TYPE_MASK|CV_MAT_CONT_FLAG)); - dims = 2; - rows = m->rows; - cols = m->cols; - data = datastart = m->data.ptr; - size_t esz = CV_ELEM_SIZE(m->type), minstep = cols*esz, _step = m->step; + thiz.flags = Mat::MAGIC_VAL + (m->type & (CV_MAT_TYPE_MASK|CV_MAT_CONT_FLAG)); + thiz.dims = 2; + thiz.rows = m->rows; + thiz.cols = m->cols; + thiz.data = thiz.datastart = m->data.ptr; + size_t esz = CV_ELEM_SIZE(m->type), minstep = thiz.cols*esz, _step = m->step; if( _step == 0 ) _step = minstep; - datalimit = datastart + _step*rows; - dataend = datalimit - _step + minstep; - step[0] = _step; step[1] = esz; + thiz.datalimit = thiz.datastart + _step*thiz.rows; + thiz.dataend = thiz.datalimit - _step + minstep; + thiz.step[0] = _step; thiz.step[1] = esz; } else { - data = datastart = dataend = 0; - Mat(m->rows, m->cols, m->type, m->data.ptr, m->step).copyTo(*this); + thiz.data = thiz.datastart = thiz.dataend = 0; + Mat(m->rows, m->cols, m->type, m->data.ptr, m->step).copyTo(thiz); } + + return thiz; } -Mat::Mat(const IplImage* img, bool copyData) : size(&rows) +static Mat iplImageToMat(const IplImage* img, bool copyData) { - initEmpty(); + Mat m; if( !img ) - return; + return m; - dims = 2; + m.dims = 2; CV_DbgAssert(CV_IS_IMAGE(img) && img->imageData != 0); int imgdepth = IPL2CV_DEPTH(img->depth); size_t esz; - step[0] = img->widthStep; + m.step[0] = img->widthStep; if(!img->roi) { CV_Assert(img->dataOrder == IPL_DATA_ORDER_PIXEL); - flags = MAGIC_VAL + CV_MAKETYPE(imgdepth, img->nChannels); - rows = img->height; cols = img->width; - datastart = data = (uchar*)img->imageData; - esz = CV_ELEM_SIZE(flags); + m.flags = Mat::MAGIC_VAL + CV_MAKETYPE(imgdepth, img->nChannels); + m.rows = img->height; + m.cols = img->width; + m.datastart = m.data = (uchar*)img->imageData; + esz = CV_ELEM_SIZE(m.flags); } else { CV_Assert(img->dataOrder == IPL_DATA_ORDER_PIXEL || img->roi->coi != 0); bool selectedPlane = img->roi->coi && img->dataOrder == IPL_DATA_ORDER_PLANE; - flags = MAGIC_VAL + CV_MAKETYPE(imgdepth, selectedPlane ? 1 : img->nChannels); - rows = img->roi->height; cols = img->roi->width; - esz = CV_ELEM_SIZE(flags); - data = datastart = (uchar*)img->imageData + - (selectedPlane ? (img->roi->coi - 1)*step*img->height : 0) + - img->roi->yOffset*step[0] + img->roi->xOffset*esz; - } - datalimit = datastart + step.p[0]*rows; - dataend = datastart + step.p[0]*(rows-1) + esz*cols; - flags |= (cols*esz == step.p[0] || rows == 1 ? CONTINUOUS_FLAG : 0); - step[1] = esz; + m.flags = Mat::MAGIC_VAL + CV_MAKETYPE(imgdepth, selectedPlane ? 1 : img->nChannels); + m.rows = img->roi->height; + m.cols = img->roi->width; + esz = CV_ELEM_SIZE(m.flags); + m.data = m.datastart = (uchar*)img->imageData + + (selectedPlane ? (img->roi->coi - 1)*m.step*img->height : 0) + + img->roi->yOffset*m.step[0] + img->roi->xOffset*esz; + } + m.datalimit = m.datastart + m.step.p[0]*m.rows; + m.dataend = m.datastart + m.step.p[0]*(m.rows-1) + esz*m.cols; + m.flags |= (m.cols*esz == m.step.p[0] || m.rows == 1 ? Mat::CONTINUOUS_FLAG : 0); + m.step[1] = esz; if( copyData ) { - Mat m = *this; - release(); + Mat m2 = m; + m.release(); if( !img->roi || !img->roi->coi || img->dataOrder == IPL_DATA_ORDER_PLANE) - m.copyTo(*this); + m2.copyTo(m); else { int ch[] = {img->roi->coi - 1, 0}; - create(m.rows, m.cols, m.type()); - mixChannels(&m, 1, this, 1, ch, 1); + m.create(m2.rows, m2.cols, m2.type()); + mixChannels(&m2, 1, &m, 1, ch, 1); } } -} + return m; +} -Mat::operator IplImage() const +Mat Mat::diag(int d) const { CV_Assert( dims <= 2 ); - IplImage img; - cvInitImageHeader(&img, size(), cvIplDepth(flags), channels()); - cvSetData(&img, data, (int)step[0]); - return img; -} + Mat m = *this; + size_t esz = elemSize(); + int len; + if( d >= 0 ) + { + len = std::min(cols - d, rows); + m.data += esz*d; + } + else + { + len = std::min(rows + d, cols); + m.data -= step[0]*d; + } + CV_DbgAssert( len > 0 ); + + m.size[0] = m.rows = len; + m.size[1] = m.cols = 1; + m.step[0] += (len > 1 ? esz : 0); + + if( m.rows > 1 ) + m.flags &= ~CONTINUOUS_FLAG; + else + m.flags |= CONTINUOUS_FLAG; + + if( size() != Size(1,1) ) + m.flags |= SUBMATRIX_FLAG; + + return m; +} void Mat::pop_back(size_t nelems) { @@ -673,16 +670,16 @@ Mat cvarrToMat(const CvArr* arr, bool copyData, { if( !arr ) return Mat(); - if( CV_IS_MAT(arr) ) - return Mat((const CvMat*)arr, copyData ); + if( CV_IS_MAT_HDR_Z(arr) ) + return cvMatToMat((const CvMat*)arr, copyData); if( CV_IS_MATND(arr) ) - return Mat((const CvMatND*)arr, copyData ); + return cvMatNDToMat((const CvMatND*)arr, copyData ); if( CV_IS_IMAGE(arr) ) { const IplImage* iplimg = (const IplImage*)arr; if( coiMode == 0 && iplimg->roi && iplimg->roi->coi > 0 ) CV_Error(CV_BadCOI, "COI is not supported by the function"); - return Mat(iplimg, copyData); + return iplImageToMat(iplimg, copyData); } if( CV_IS_SEQ(arr) ) { @@ -2938,7 +2935,7 @@ CV_IMPL void cvTranspose( const CvArr* srcarr, CvArr* dstarr ) CV_IMPL void cvCompleteSymm( CvMat* matrix, int LtoR ) { - cv::Mat m(matrix); + cv::Mat m = cv::cvarrToMat(matrix); cv::completeSymm( m, LtoR != 0 ); } @@ -3109,17 +3106,6 @@ Mat Mat::reshape(int _cn, int _newndims, const int* _newsz) const return Mat(); } -Mat::operator CvMatND() const -{ - CvMatND mat; - cvInitMatNDHeader( &mat, dims, size, type(), data ); - int i, d = dims; - for( i = 0; i < d; i++ ) - mat.dim[i].step = (int)step[i]; - mat.type |= flags & CONTINUOUS_FLAG; - return mat; -} - NAryMatIterator::NAryMatIterator() : arrays(0), planes(0), ptrs(0), narrays(0), nplanes(0), size(0), iterdepth(0), idx(0) { @@ -3630,24 +3616,6 @@ SparseMat::SparseMat(const Mat& m) } } -SparseMat::SparseMat(const CvSparseMat* m) -: flags(MAGIC_VAL), hdr(0) -{ - CV_Assert(m); - create( m->dims, &m->size[0], m->type ); - - CvSparseMatIterator it; - CvSparseNode* n = cvInitSparseMatIterator(m, &it); - size_t esz = elemSize(); - - for( ; n != 0; n = cvGetNextSparseNode(&it) ) - { - const int* idx = CV_NODE_IDX(m, n); - uchar* to = newNode(idx, hash(idx)); - copyElem((const uchar*)CV_NODE_VAL(m, n), to, esz); - } -} - void SparseMat::create(int d, const int* _sizes, int _type) { int i; @@ -3795,24 +3763,6 @@ void SparseMat::clear() hdr->clear(); } -SparseMat::operator CvSparseMat*() const -{ - if( !hdr ) - return 0; - CvSparseMat* m = cvCreateSparseMat(hdr->dims, hdr->size, type()); - - SparseMatConstIterator from = begin(); - size_t i, N = nzcount(), esz = elemSize(); - - for( i = 0; i < N; i++, ++from ) - { - const Node* n = from.node(); - uchar* to = cvPtrND(m, n->idx, 0, -2, 0); - copyElem(from.ptr, to, esz); - } - return m; -} - uchar* SparseMat::ptr(int i0, bool createMissing, size_t* hashval) { CV_Assert( hdr && hdr->dims == 1 ); @@ -4266,4 +4216,58 @@ Rect RotatedRect::boundingRect() const } +// glue + +CvMatND::CvMatND(const cv::Mat& m) +{ + cvInitMatNDHeader(this, m.dims, m.size, m.type(), m.data ); + int i, d = m.dims; + for( i = 0; i < d; i++ ) + dim[i].step = (int)m.step[i]; + type |= m.flags & cv::Mat::CONTINUOUS_FLAG; +} + +_IplImage::_IplImage(const cv::Mat& m) +{ + CV_Assert( m.dims <= 2 ); + cvInitImageHeader(this, m.size(), cvIplDepth(m.flags), m.channels()); + cvSetData(this, m.data, (int)m.step[0]); +} + +CvSparseMat* cvCreateSparseMat(const cv::SparseMat& sm) +{ + if( !sm.hdr ) + return 0; + + CvSparseMat* m = cvCreateSparseMat(sm.hdr->dims, sm.hdr->size, sm.type()); + + cv::SparseMatConstIterator from = sm.begin(); + size_t i, N = sm.nzcount(), esz = sm.elemSize(); + + for( i = 0; i < N; i++, ++from ) + { + const cv::SparseMat::Node* n = from.node(); + uchar* to = cvPtrND(m, n->idx, 0, -2, 0); + cv::copyElem(from.ptr, to, esz); + } + return m; +} + +void CvSparseMat::copyToSparseMat(cv::SparseMat& m) const +{ + m.create( dims, &size[0], type ); + + CvSparseMatIterator it; + CvSparseNode* n = cvInitSparseMatIterator(this, &it); + size_t esz = m.elemSize(); + + for( ; n != 0; n = cvGetNextSparseNode(&it) ) + { + const int* idx = CV_NODE_IDX(this, n); + uchar* to = m.newNode(idx, m.hash(idx)); + cv::copyElem((const uchar*)CV_NODE_VAL(this, n), to, esz); + } +} + + /* End of file. */ diff --git a/modules/core/src/persistence.cpp b/modules/core/src/persistence.cpp index 52be883970..2f5523d3ed 100644 --- a/modules/core/src/persistence.cpp +++ b/modules/core/src/persistence.cpp @@ -5470,7 +5470,7 @@ void write( FileStorage& fs, const String& name, const Mat& value ) // TODO: the 4 functions below need to be implemented more efficiently void write( FileStorage& fs, const String& name, const SparseMat& value ) { - Ptr mat = (CvSparseMat*)value; + Ptr mat = cvCreateSparseMat(value); cvWrite( *fs, name.size() ? name.c_str() : 0, mat ); } @@ -5495,12 +5495,12 @@ void read( const FileNode& node, Mat& mat, const Mat& default_mat ) void* obj = cvRead((CvFileStorage*)node.fs, (CvFileNode*)*node); if(CV_IS_MAT_HDR_Z(obj)) { - Mat((const CvMat*)obj).copyTo(mat); + cvarrToMat(obj).copyTo(mat); cvReleaseMat((CvMat**)&obj); } else if(CV_IS_MATND_HDR(obj)) { - Mat((const CvMatND*)obj).copyTo(mat); + cvarrToMat(obj).copyTo(mat); cvReleaseMatND((CvMatND**)&obj); } else @@ -5519,7 +5519,7 @@ void read( const FileNode& node, SparseMat& mat, const SparseMat& default_mat ) } Ptr m = (CvSparseMat*)cvRead((CvFileStorage*)node.fs, (CvFileNode*)*node); CV_Assert(CV_IS_SPARSE_MAT(m.obj)); - SparseMat(m).copyTo(mat); + m->copyToSparseMat(mat); } void write(FileStorage& fs, const String& objname, const std::vector& keypoints) diff --git a/modules/core/test/test_arithm.cpp b/modules/core/test/test_arithm.cpp index ebc9eae640..9ea057d89a 100644 --- a/modules/core/test/test_arithm.cpp +++ b/modules/core/test/test_arithm.cpp @@ -35,7 +35,7 @@ struct BaseElemWiseOp virtual int getRandomType(RNG& rng) { - return cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, + return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, ninputs > 1 ? ARITHM_MAX_CHANNELS : 4); } @@ -425,7 +425,7 @@ struct CmpOp : public BaseElemWiseOp } int getRandomType(RNG& rng) { - return cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 1); + return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, 1); } double getMaxErr(int) @@ -455,7 +455,7 @@ struct CmpSOp : public BaseElemWiseOp } int getRandomType(RNG& rng) { - return cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 1); + return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, 1); } double getMaxErr(int) { @@ -478,7 +478,7 @@ struct CopyOp : public BaseElemWiseOp } int getRandomType(RNG& rng) { - return cvtest::randomType(rng, DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS); + return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS); } double getMaxErr(int) { @@ -501,7 +501,7 @@ struct SetOp : public BaseElemWiseOp } int getRandomType(RNG& rng) { - return cvtest::randomType(rng, DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS); + return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS); } double getMaxErr(int) { @@ -718,8 +718,8 @@ struct ConvertScaleOp : public BaseElemWiseOp } int getRandomType(RNG& rng) { - int srctype = cvtest::randomType(rng, DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS); - ddepth = cvtest::randomType(rng, DEPTH_MASK_ALL, 1, 1); + int srctype = cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS); + ddepth = cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1, 1); return srctype; } double getMaxErr(int) @@ -957,7 +957,7 @@ struct ExpOp : public BaseElemWiseOp ExpOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}; int getRandomType(RNG& rng) { - return cvtest::randomType(rng, DEPTH_MASK_FLT, 1, ARITHM_MAX_CHANNELS); + return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_FLT, 1, ARITHM_MAX_CHANNELS); } void getValueRange(int depth, double& minval, double& maxval) { @@ -984,7 +984,7 @@ struct LogOp : public BaseElemWiseOp LogOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {}; int getRandomType(RNG& rng) { - return cvtest::randomType(rng, DEPTH_MASK_FLT, 1, ARITHM_MAX_CHANNELS); + return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_FLT, 1, ARITHM_MAX_CHANNELS); } void getValueRange(int depth, double& minval, double& maxval) { @@ -1070,7 +1070,7 @@ struct CartToPolarToCartOp : public BaseElemWiseOp } int getRandomType(RNG& rng) { - return cvtest::randomType(rng, DEPTH_MASK_FLT, 1, 1); + return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_FLT, 1, 1); } void op(const vector& src, Mat& dst, const Mat&) { @@ -1157,7 +1157,7 @@ struct CountNonZeroOp : public BaseElemWiseOp {} int getRandomType(RNG& rng) { - return cvtest::randomType(rng, DEPTH_MASK_ALL, 1, 1); + return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL, 1, 1); } void op(const vector& src, Mat& dst, const Mat& mask) { @@ -1237,7 +1237,7 @@ struct NormOp : public BaseElemWiseOp }; int getRandomType(RNG& rng) { - int type = cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 4); + int type = cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, 4); for(;;) { normType = rng.uniform(1, 8); @@ -1283,7 +1283,7 @@ struct MinMaxLocOp : public BaseElemWiseOp }; int getRandomType(RNG& rng) { - return cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 1); + return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, 1); } void saveOutput(const vector& minidx, const vector& maxidx, double minval, double maxval, Mat& dst) diff --git a/modules/core/test/test_io.cpp b/modules/core/test/test_io.cpp index 64517af981..c574d514e3 100644 --- a/modules/core/test/test_io.cpp +++ b/modules/core/test/test_io.cpp @@ -211,7 +211,7 @@ protected: vector pt; if( !m || !CV_IS_MAT(m) || m->rows != test_mat.rows || m->cols != test_mat.cols || - cvtest::cmpEps( Mat(&stub1), Mat(&_test_stub1), &max_diff, 0, &pt, true) < 0 ) + cvtest::cmpEps( cv::cvarrToMat(&stub1), cv::cvarrToMat(&_test_stub1), &max_diff, 0, &pt, true) < 0 ) { ts->printf( cvtest::TS::LOG, "the read matrix is not correct: (%.20g vs %.20g) at (%d,%d)\n", cvGetReal2D(&stub1, pt[0], pt[1]), cvGetReal2D(&_test_stub1, pt[0], pt[1]), @@ -241,7 +241,7 @@ protected: if( !CV_ARE_TYPES_EQ(&stub, &_test_stub) || !CV_ARE_SIZES_EQ(&stub, &_test_stub) || //cvNorm(&stub, &_test_stub, CV_L2) != 0 ) - cvtest::cmpEps( Mat(&stub1), Mat(&_test_stub1), &max_diff, 0, &pt, true) < 0 ) + cvtest::cmpEps( cv::cvarrToMat(&stub1), cv::cvarrToMat(&_test_stub1), &max_diff, 0, &pt, true) < 0 ) { ts->printf( cvtest::TS::LOG, "readObj method: the read nd matrix is not correct: (%.20g vs %.20g) vs at (%d,%d)\n", cvGetReal2D(&stub1, pt[0], pt[1]), cvGetReal2D(&_test_stub1, pt[0], pt[1]), @@ -259,7 +259,7 @@ protected: if( !CV_ARE_TYPES_EQ(&stub, &_test_stub) || !CV_ARE_SIZES_EQ(&stub, &_test_stub) || //cvNorm(&stub, &_test_stub, CV_L2) != 0 ) - cvtest::cmpEps( Mat(&stub1), Mat(&_test_stub1), &max_diff, 0, &pt, true) < 0 ) + cvtest::cmpEps( cv::cvarrToMat(&stub1), cv::cvarrToMat(&_test_stub1), &max_diff, 0, &pt, true) < 0 ) { ts->printf( cvtest::TS::LOG, "C++ method: the read nd matrix is not correct: (%.20g vs %.20g) vs at (%d,%d)\n", cvGetReal2D(&stub1, pt[0], pt[1]), cvGetReal2D(&_test_stub1, pt[1], pt[0]), @@ -271,11 +271,11 @@ protected: cvRelease((void**)&m_nd); Ptr m_s = (CvSparseMat*)fs["test_sparse_mat"].readObj(); - Ptr _test_sparse_ = (CvSparseMat*)test_sparse_mat; + Ptr _test_sparse_ = cvCreateSparseMat(test_sparse_mat); Ptr _test_sparse = (CvSparseMat*)cvClone(_test_sparse_); SparseMat m_s2; fs["test_sparse_mat"] >> m_s2; - Ptr _m_s2 = (CvSparseMat*)m_s2; + Ptr _m_s2 = cvCreateSparseMat(m_s2); if( !m_s || !CV_IS_SPARSE_MAT(m_s) || !cvTsCheckSparse(m_s, _test_sparse,0) || diff --git a/modules/core/test/test_mat.cpp b/modules/core/test/test_mat.cpp index 3693c2dcb1..830c329f6f 100644 --- a/modules/core/test/test_mat.cpp +++ b/modules/core/test/test_mat.cpp @@ -734,7 +734,7 @@ void Core_ArrayOpTest::run( int /* start_from */) } } - Ptr M2 = (CvSparseMat*)M; + Ptr M2 = cvCreateSparseMat(M); MatND Md; M.copyTo(Md); SparseMat M3; SparseMat(Md).convertTo(M3, Md.type(), 2); diff --git a/modules/core/test/test_math.cpp b/modules/core/test/test_math.cpp index 1c5c50c290..b9beeb7d30 100644 --- a/modules/core/test/test_math.cpp +++ b/modules/core/test/test_math.cpp @@ -2292,9 +2292,9 @@ void Core_SolvePolyTest::run( int ) cvFlip(&amat, &amat, 0); int nr2; if( cubic_case == 0 ) - nr2 = cv::solveCubic(cv::Mat(&amat),umat2); + nr2 = cv::solveCubic(cv::cvarrToMat(&amat),umat2); else - nr2 = cv::solveCubic(cv::Mat_(cv::Mat(&amat)), umat2); + nr2 = cv::solveCubic(cv::Mat_(cv::cvarrToMat(&amat)), umat2); cvFlip(&amat, &amat, 0); if(nr2 > 0) std::sort(ar2.begin(), ar2.begin()+nr2, pred_double()); diff --git a/modules/gpu/perf/perf_video.cpp b/modules/gpu/perf/perf_video.cpp index 046bc27f5d..07014849ad 100644 --- a/modules/gpu/perf/perf_video.cpp +++ b/modules/gpu/perf/perf_video.cpp @@ -596,8 +596,8 @@ PERF_TEST_P(Video, Video_FGDStatModel, stopTimer(); } - const cv::Mat background = model->background; - const cv::Mat foreground = model->foreground; + const cv::Mat background = cv::cvarrToMat(model->background); + const cv::Mat foreground = cv::cvarrToMat(model->foreground); CPU_SANITY_CHECK(background); CPU_SANITY_CHECK(foreground); diff --git a/modules/highgui/src/cap.cpp b/modules/highgui/src/cap.cpp index 936d213ef1..d1325a3b24 100644 --- a/modules/highgui/src/cap.cpp +++ b/modules/highgui/src/cap.cpp @@ -495,10 +495,10 @@ bool VideoCapture::retrieve(Mat& image, int channel) return false; } if(_img->origin == IPL_ORIGIN_TL) - image = Mat(_img); + image = cv::cvarrToMat(_img); else { - Mat temp(_img); + Mat temp = cv::cvarrToMat(_img); flip(temp, image, 0); } return true; diff --git a/modules/highgui/src/window_QT.cpp b/modules/highgui/src/window_QT.cpp index 7717bde540..eda75bb3cd 100644 --- a/modules/highgui/src/window_QT.cpp +++ b/modules/highgui/src/window_QT.cpp @@ -948,7 +948,7 @@ void GuiReceiver::showImage(QString name, void* arr) mat = cvGetMat(arr, &stub); - cv::Mat im(mat); + cv::Mat im = cv::cvarrToMat(mat); cv::imshow(name.toUtf8().data(), im); } else diff --git a/modules/highgui/test/test_video_io.cpp b/modules/highgui/test/test_video_io.cpp index b91acf74ab..bdc032f0d2 100644 --- a/modules/highgui/test/test_video_io.cpp +++ b/modules/highgui/test/test_video_io.cpp @@ -247,7 +247,7 @@ void CV_HighGuiTest::VideoTest(const string& dir, const cvtest::VideoFormat& fmt if (!img) break; - frames.push_back(Mat(img).clone()); + frames.push_back(cv::cvarrToMat(img, true)); if (writer == 0) { @@ -285,7 +285,7 @@ void CV_HighGuiTest::VideoTest(const string& dir, const cvtest::VideoFormat& fmt break; Mat img = frames[i]; - Mat img1(ipl1); + Mat img1 = cv::cvarrToMat(ipl1); double psnr = PSNR(img1, img); if (psnr < thresDbell) diff --git a/modules/imgproc/src/histogram.cpp b/modules/imgproc/src/histogram.cpp index a31f62499e..f768f5cdd5 100644 --- a/modules/imgproc/src/histogram.cpp +++ b/modules/imgproc/src/histogram.cpp @@ -2456,7 +2456,8 @@ cvCompareHist( const CvHistogram* hist1, if( !CV_IS_SPARSE_MAT(hist1->bins) ) { - cv::Mat H1((const CvMatND*)hist1->bins), H2((const CvMatND*)hist2->bins); + cv::Mat H1 = cv::cvarrToMat(hist1->bins); + cv::Mat H2 = cv::cvarrToMat(hist2->bins); return cv::compareHist(H1, H2, method); } @@ -2758,7 +2759,7 @@ cvCalcArrHist( CvArr** img, CvHistogram* hist, int accumulate, const CvArr* mask if( !CV_IS_SPARSE_HIST(hist) ) { - cv::Mat H((const CvMatND*)hist->bins); + cv::Mat H = cv::cvarrToMat(hist->bins); cv::calcHist( &images[0], (int)images.size(), 0, _mask, H, cvGetDims(hist->bins), H.size, ranges, uniform, accumulate != 0 ); } @@ -2768,7 +2769,8 @@ cvCalcArrHist( CvArr** img, CvHistogram* hist, int accumulate, const CvArr* mask if( !accumulate ) cvZero( hist->bins ); - cv::SparseMat sH(sparsemat); + cv::SparseMat sH; + sparsemat->copyToSparseMat(sH); cv::calcHist( &images[0], (int)images.size(), 0, _mask, sH, sH.dims(), sH.dims() > 0 ? sH.hdr->size : 0, ranges, uniform, accumulate != 0, true ); @@ -2820,13 +2822,14 @@ cvCalcArrBackProject( CvArr** img, CvArr* dst, const CvHistogram* hist ) if( !CV_IS_SPARSE_HIST(hist) ) { - cv::Mat H((const CvMatND*)hist->bins); + cv::Mat H = cv::cvarrToMat(hist->bins); cv::calcBackProject( &images[0], (int)images.size(), 0, H, _dst, ranges, 1, uniform ); } else { - cv::SparseMat sH((const CvSparseMat*)hist->bins); + cv::SparseMat sH; + ((const CvSparseMat*)hist->bins)->copyToSparseMat(sH); cv::calcBackProject( &images[0], (int)images.size(), 0, sH, _dst, ranges, 1, uniform ); } diff --git a/modules/imgproc/test/test_histograms.cpp b/modules/imgproc/test/test_histograms.cpp index 3ac1e94be0..ccdaa74f27 100644 --- a/modules/imgproc/test/test_histograms.cpp +++ b/modules/imgproc/test/test_histograms.cpp @@ -630,7 +630,8 @@ void CV_MinMaxHistTest::run_func(void) { if( hist_type != CV_HIST_ARRAY && test_cpp ) { - cv::SparseMat h((CvSparseMat*)hist[0]->bins); + cv::SparseMat h; + ((CvSparseMat*)hist[0]->bins)->copyToSparseMat(h); double _min_val = 0, _max_val = 0; cv::minMaxLoc(h, &_min_val, &_max_val, min_idx, max_idx ); min_val = (float)_min_val; @@ -727,10 +728,11 @@ void CV_NormHistTest::run_func(void) { if( hist_type != CV_HIST_ARRAY && test_cpp ) { - cv::SparseMat h((CvSparseMat*)hist[0]->bins); + cv::SparseMat h; + ((CvSparseMat*)hist[0]->bins)->copyToSparseMat(h); cv::normalize(h, h, factor, CV_L1); cvReleaseSparseMat((CvSparseMat**)&hist[0]->bins); - hist[0]->bins = (CvSparseMat*)h; + hist[0]->bins = cvCreateSparseMat(h); } else cvNormalizeHist( hist[0], factor ); @@ -978,8 +980,9 @@ void CV_CompareHistTest::run_func(void) int k; if( hist_type != CV_HIST_ARRAY && test_cpp ) { - cv::SparseMat h0((CvSparseMat*)hist[0]->bins); - cv::SparseMat h1((CvSparseMat*)hist[1]->bins); + cv::SparseMat h0, h1; + ((CvSparseMat*)hist[0]->bins)->copyToSparseMat(h0); + ((CvSparseMat*)hist[1]->bins)->copyToSparseMat(h1); for( k = 0; k < MAX_METHOD; k++ ) result[k] = cv::compareHist(h0, h1, k); } diff --git a/modules/legacy/src/calonder.cpp b/modules/legacy/src/calonder.cpp index f062f74add..c5a8a6ec2b 100644 --- a/modules/legacy/src/calonder.cpp +++ b/modules/legacy/src/calonder.cpp @@ -334,7 +334,7 @@ void RandomizedTree::train(std::vector const& base_set, Size patchSize(PATCH_SIZE, PATCH_SIZE); for (keypt_it = base_set.begin(); keypt_it != base_set.end(); ++keypt_it, ++class_id) { for (int i = 0; i < views; ++i) { - make_patch( Mat(keypt_it->image), Point(keypt_it->x, keypt_it->y ), patch, patchSize, rng ); + make_patch( cv::cvarrToMat(keypt_it->image), Point(keypt_it->x, keypt_it->y ), patch, patchSize, rng ); IplImage iplPatch = patch; addExample(class_id, getData(&iplPatch)); } diff --git a/modules/legacy/src/em.cpp b/modules/legacy/src/em.cpp index 200f743138..c11c23598d 100644 --- a/modules/legacy/src/em.cpp +++ b/modules/legacy/src/em.cpp @@ -139,15 +139,15 @@ void init_params(const CvEMParams& src, Mat& prbs, Mat& weights, Mat& means, std::vector& covsHdrs) { - prbs = src.probs; - weights = src.weights; - means = src.means; + prbs = cv::cvarrToMat(src.probs); + weights = cv::cvarrToMat(src.weights); + means = cv::cvarrToMat(src.means); if(src.covs) { covsHdrs.resize(src.nclusters); for(size_t i = 0; i < covsHdrs.size(); i++) - covsHdrs[i] = src.covs[i]; + covsHdrs[i] = cv::cvarrToMat(src.covs[i]); } } diff --git a/modules/legacy/src/levmarprojbandle.cpp b/modules/legacy/src/levmarprojbandle.cpp index 162ea528c4..84c2aee24d 100644 --- a/modules/legacy/src/levmarprojbandle.cpp +++ b/modules/legacy/src/levmarprojbandle.cpp @@ -745,6 +745,7 @@ void icvReconstructPoints4DStatus(CvMat** projPoints, CvMat **projMatrs, CvMat** double* matrW_dat = 0; CV_FUNCNAME( "icvReconstructPoints4DStatus" ); + __BEGIN__; /* ----- Test input params for errors ----- */ @@ -770,6 +771,7 @@ void icvReconstructPoints4DStatus(CvMat** projPoints, CvMat **projMatrs, CvMat** CV_ERROR( CV_StsOutOfRange, "Points must have 4 cordinates" ); } + /* !!! Not tested all input parameters */ /* ----- End test ----- */ @@ -778,75 +780,75 @@ void icvReconstructPoints4DStatus(CvMat** projPoints, CvMat **projMatrs, CvMat** /* Allocate maximum data */ + { + double matrV_dat[4*4]; + CvMat matrV = cvMat(4,4,CV_64F,matrV_dat); - CvMat matrV; - double matrV_dat[4*4]; - matrV = cvMat(4,4,CV_64F,matrV_dat); - - CV_CALL(matrA_dat = (double*)cvAlloc(3*numImages * 4 * sizeof(double))); - CV_CALL(matrW_dat = (double*)cvAlloc(3*numImages * 4 * sizeof(double))); + CV_CALL(matrA_dat = (double*)cvAlloc(3*numImages * 4 * sizeof(double))); + CV_CALL(matrW_dat = (double*)cvAlloc(3*numImages * 4 * sizeof(double))); - /* reconstruct each point */ - for( currPoint = 0; currPoint < numPoints; currPoint++ ) - { - /* Reconstruct current point */ - /* Define number of visible projections */ - int numVisProj = 0; - for( currImage = 0; currImage < numImages; currImage++ ) + /* reconstruct each point */ + for( currPoint = 0; currPoint < numPoints; currPoint++ ) { - if( cvmGet(presPoints[currImage],0,currPoint) > 0 ) + /* Reconstruct current point */ + /* Define number of visible projections */ + int numVisProj = 0; + for( currImage = 0; currImage < numImages; currImage++ ) { - numVisProj++; + if( cvmGet(presPoints[currImage],0,currPoint) > 0 ) + { + numVisProj++; + } } - } - if( numVisProj < 2 ) - { - /* This point can't be reconstructed */ - continue; - } + if( numVisProj < 2 ) + { + /* This point can't be reconstructed */ + continue; + } - /* Allocate memory and create matrices */ - CvMat matrA; - matrA = cvMat(3*numVisProj,4,CV_64F,matrA_dat); + /* Allocate memory and create matrices */ + CvMat matrA; + matrA = cvMat(3*numVisProj,4,CV_64F,matrA_dat); - CvMat matrW; - matrW = cvMat(3*numVisProj,4,CV_64F,matrW_dat); + CvMat matrW; + matrW = cvMat(3*numVisProj,4,CV_64F,matrW_dat); - int currVisProj = 0; - for( currImage = 0; currImage < numImages; currImage++ )/* For each view */ - { - if( cvmGet(presPoints[currImage],0,currPoint) > 0 ) + int currVisProj = 0; + for( currImage = 0; currImage < numImages; currImage++ )/* For each view */ { - double x,y; - x = cvmGet(projPoints[currImage],0,currPoint); - y = cvmGet(projPoints[currImage],1,currPoint); - for( int k = 0; k < 4; k++ ) + if( cvmGet(presPoints[currImage],0,currPoint) > 0 ) { - matrA_dat[currVisProj*12 + k] = - x * cvmGet(projMatrs[currImage],2,k) - cvmGet(projMatrs[currImage],0,k); + double x,y; + x = cvmGet(projPoints[currImage],0,currPoint); + y = cvmGet(projPoints[currImage],1,currPoint); + for( int k = 0; k < 4; k++ ) + { + matrA_dat[currVisProj*12 + k] = + x * cvmGet(projMatrs[currImage],2,k) - cvmGet(projMatrs[currImage],0,k); - matrA_dat[currVisProj*12+4 + k] = - y * cvmGet(projMatrs[currImage],2,k) - cvmGet(projMatrs[currImage],1,k); + matrA_dat[currVisProj*12+4 + k] = + y * cvmGet(projMatrs[currImage],2,k) - cvmGet(projMatrs[currImage],1,k); - matrA_dat[currVisProj*12+8 + k] = - x * cvmGet(projMatrs[currImage],1,k) - y * cvmGet(projMatrs[currImage],0,k); + matrA_dat[currVisProj*12+8 + k] = + x * cvmGet(projMatrs[currImage],1,k) - y * cvmGet(projMatrs[currImage],0,k); + } + currVisProj++; } - currVisProj++; } - } - /* Solve system for current point */ - { - cvSVD(&matrA,&matrW,0,&matrV,CV_SVD_V_T); + /* Solve system for current point */ + { + cvSVD(&matrA,&matrW,0,&matrV,CV_SVD_V_T); - /* Copy computed point */ - cvmSet(points4D,0,currPoint,cvmGet(&matrV,3,0));//X - cvmSet(points4D,1,currPoint,cvmGet(&matrV,3,1));//Y - cvmSet(points4D,2,currPoint,cvmGet(&matrV,3,2));//Z - cvmSet(points4D,3,currPoint,cvmGet(&matrV,3,3));//W - } + /* Copy computed point */ + cvmSet(points4D,0,currPoint,cvmGet(&matrV,3,0));//X + cvmSet(points4D,1,currPoint,cvmGet(&matrV,3,1));//Y + cvmSet(points4D,2,currPoint,cvmGet(&matrV,3,2));//Z + cvmSet(points4D,3,currPoint,cvmGet(&matrV,3,3));//W + } + } } {/* Compute projection error */ @@ -913,7 +915,7 @@ static void icvProjPointsStatusFunc( int numImages, CvMat *points4D, CvMat **pro { CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" ); } - + { int numPoints; numPoints = points4D->cols; if( numPoints < 1 ) @@ -994,7 +996,7 @@ static void icvProjPointsStatusFunc( int numImages, CvMat *points4D, CvMat **pro } } } - + } __END__; } diff --git a/modules/legacy/src/oneway.cpp b/modules/legacy/src/oneway.cpp index 1c8d4bc83c..acb5e3cda9 100644 --- a/modules/legacy/src/oneway.cpp +++ b/modules/legacy/src/oneway.cpp @@ -1740,7 +1740,7 @@ namespace cv{ CV_Error(CV_StsNotImplemented, "OpenCV was built without SURF support"); surf_extractor->set("hessianThreshold", 1.0); //printf("Extracting SURF features..."); - surf_extractor->detect(Mat(img), features); + surf_extractor->detect(cv::cvarrToMat(img), features); //printf("done\n"); for (int j = 0; j < (int)features.size(); j++) diff --git a/modules/legacy/src/trifocal.cpp b/modules/legacy/src/trifocal.cpp index 87aadf696d..a8ad68628e 100644 --- a/modules/legacy/src/trifocal.cpp +++ b/modules/legacy/src/trifocal.cpp @@ -223,7 +223,7 @@ int icvComputeProjectMatrices6Points( CvMat* points1,CvMat* points2,CvMat* point CV_ERROR( CV_StsUnmatchedSizes, "Number of coordinates of points4D must be 4" ); } #endif - + { /* Find transform matrix for each camera */ int i; CvMat* points[3]; @@ -400,7 +400,7 @@ int icvComputeProjectMatrices6Points( CvMat* points1,CvMat* points2,CvMat* point #endif }/* for all sollutions */ - + } __END__; return numSol; } @@ -1362,7 +1362,7 @@ void icvFindBaseTransform(CvMat* points,CvMat* resultT) /* Function gets four points and compute transformation to e1=(100) e2=(010) e3=(001) e4=(111) */ /* !!! test each three points not collinear. Need to test */ - + { /* Create matrices */ CvMat matrA; CvMat vectB; @@ -1410,7 +1410,7 @@ void icvFindBaseTransform(CvMat* points,CvMat* resultT) cvInvert(&matrA,&tmpRes); cvConvert(&tmpRes,resultT); - + } __END__; return; @@ -1459,7 +1459,7 @@ void GetGeneratorReduceFundSolution(CvMat* points1,CvMat* points2,CvMat* fundRed } /* Using 3 corr. points compute reduce */ - + { /* Create matrix */ CvMat matrA; double matrA_dat[3*5]; @@ -1507,7 +1507,7 @@ void GetGeneratorReduceFundSolution(CvMat* points1,CvMat* points2,CvMat* fundRed cvmSet(fundReduceCoef1,0,i,cvmGet(&matrV,3,i)); cvmSet(fundReduceCoef2,0,i,cvmGet(&matrV,4,i)); } - + } __END__; return; @@ -1551,7 +1551,7 @@ int GetGoodReduceFundamMatrFromTwo(CvMat* fundReduceCoef1,CvMat* fundReduceCoef2 { CV_ERROR( CV_StsUnmatchedSizes, "Size of resFundReduceCoef must be 1x5" ); } - + { double p1,q1,r1,s1,t1; double p2,q2,r2,s2,t2; p1 = cvmGet(fundReduceCoef1,0,0); @@ -1599,7 +1599,7 @@ int GetGoodReduceFundamMatrFromTwo(CvMat* fundReduceCoef1,CvMat* fundReduceCoef2 numRoots++; } } - + } __END__; return numRoots; } @@ -1636,7 +1636,7 @@ void GetProjMatrFromReducedFundamental(CvMat* fundReduceCoefs,CvMat* projMatrCoe /* Computes project matrix from given reduced matrix */ /* we have p,q,r,s,t and need get a,b,c,d */ /* Fill matrix to compute ratio a:b:c as A:B:C */ - + { CvMat matrA; double matrA_dat[3*3]; matrA = cvMat(3,3,CV_64F,matrA_dat); @@ -1752,7 +1752,7 @@ void GetProjMatrFromReducedFundamental(CvMat* fundReduceCoefs,CvMat* projMatrCoe cvmSet(projMatrCoefs,0,3,d); } - + } __END__; return; } @@ -2106,7 +2106,7 @@ void icvReconstructPointsFor3View( CvMat* projMatr1,CvMat* projMatr2,CvMat* proj { CV_ERROR( CV_StsUnmatchedSizes, "Size of projection matrices must be 3x4" ); } - + { CvMat matrA; double matrA_dat[36]; matrA = cvMat(9,4,CV_64F,matrA_dat); @@ -2203,7 +2203,7 @@ void icvReconstructPointsFor3View( CvMat* projMatr1,CvMat* projMatr2,CvMat* proj } } }*/ - + } __END__; return; } diff --git a/modules/ml/src/boost.cpp b/modules/ml/src/boost.cpp index 6af9c134b4..53c194f3cf 100644 --- a/modules/ml/src/boost.cpp +++ b/modules/ml/src/boost.cpp @@ -1655,10 +1655,10 @@ CvBoost::predict( const CvMat* _sample, const CvMat* _missing, const int* cmap = data->cat_map->data.i; const int* cofs = data->cat_ofs->data.i; - cv::Mat sample = _sample; + cv::Mat sample = cv::cvarrToMat(_sample); cv::Mat missing; if(!_missing) - missing = _missing; + missing = cv::cvarrToMat(_missing); // if need, preprocess the input vector if( !raw_mode ) diff --git a/modules/ml/src/rtrees.cpp b/modules/ml/src/rtrees.cpp index 8e287864a1..7947b062f2 100644 --- a/modules/ml/src/rtrees.cpp +++ b/modules/ml/src/rtrees.cpp @@ -861,7 +861,7 @@ float CvRTrees::predict_prob( const Mat& _sample, const Mat& _missing) const Mat CvRTrees::getVarImportance() { - return Mat(get_var_importance()); + return cvarrToMat(get_var_importance()); } // End of file. diff --git a/modules/ml/src/tree.cpp b/modules/ml/src/tree.cpp index b1aa123b99..e8072958fd 100644 --- a/modules/ml/src/tree.cpp +++ b/modules/ml/src/tree.cpp @@ -4142,7 +4142,7 @@ void CvDTree::read( CvFileStorage* fs, CvFileNode* node, CvDTreeTrainData* _data Mat CvDTree::getVarImportance() { - return Mat(get_var_importance()); + return cvarrToMat(get_var_importance()); } /* End of file. */ diff --git a/modules/ml/test/test_emknearestkmeans.cpp b/modules/ml/test/test_emknearestkmeans.cpp index b75e477f3a..6841f9d72e 100644 --- a/modules/ml/test/test_emknearestkmeans.cpp +++ b/modules/ml/test/test_emknearestkmeans.cpp @@ -597,7 +597,7 @@ protected: ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); } - Mat values = data.get_values(); + Mat values = cv::cvarrToMat(data.get_values()); CV_Assert(values.cols == 58); int responseIndex = 57; diff --git a/modules/objdetect/src/datamatrix.cpp b/modules/objdetect/src/datamatrix.cpp index d1dfcdab21..94aed159b7 100644 --- a/modules/objdetect/src/datamatrix.cpp +++ b/modules/objdetect/src/datamatrix.cpp @@ -528,7 +528,7 @@ void findDataMatrix(InputArray _image, { _dmtx.create(rc_i.original->rows, rc_i.original->cols, rc_i.original->type, i); Mat dst = _dmtx.getMat(i); - Mat(rc_i.original).copyTo(dst); + cv::cvarrToMat(rc_i.original).copyTo(dst); } cvReleaseMat(&rc_i.original); } diff --git a/modules/objdetect/src/haar.cpp b/modules/objdetect/src/haar.cpp index 731e98102c..9bacab0314 100644 --- a/modules/objdetect/src/haar.cpp +++ b/modules/objdetect/src/haar.cpp @@ -1611,17 +1611,17 @@ cvHaarDetectObjectsForROC( const CvArr* _img, if( use_ipp ) { cv::Mat fsum(sum1.rows, sum1.cols, CV_32F, sum1.data.ptr, sum1.step); - cv::Mat(&sum1).convertTo(fsum, CV_32F, 1, -(1<<24)); + cv::cvarrToMat(&sum1).convertTo(fsum, CV_32F, 1, -(1<<24)); } else #endif cvSetImagesForHaarClassifierCascade( cascade, &sum1, &sqsum1, _tilted, 1. ); - cv::Mat _norm1(&norm1), _mask1(&mask1); + cv::Mat _norm1 = cv::cvarrToMat(&norm1), _mask1 = cv::cvarrToMat(&mask1); cv::parallel_for_(cv::Range(0, stripCount), cv::HaarDetectObjects_ScaleImage_Invoker(cascade, (((sz1.height + stripCount - 1)/stripCount + ystep-1)/ystep)*ystep, - factor, cv::Mat(&sum1), cv::Mat(&sqsum1), &_norm1, &_mask1, + factor, cv::cvarrToMat(&sum1), cv::cvarrToMat(&sqsum1), &_norm1, &_mask1, cv::Rect(equRect), allCandidates, rejectLevels, levelWeights, outputRejectLevels, &mtx)); } } diff --git a/modules/python/src2/cv2.cv.hpp b/modules/python/src2/cv2.cv.hpp index f7a6f73777..76b7d3c084 100644 --- a/modules/python/src2/cv2.cv.hpp +++ b/modules/python/src2/cv2.cv.hpp @@ -253,7 +253,7 @@ static PyObject *iplimage_tostring(PyObject *self, PyObject *args) return NULL; if (i == NULL) return NULL; - cv::Mat img(i); + cv::Mat img = cvarrToMat(i); size_t esz = img.elemSize(); int nrows = img.rows, ncols = img.cols; diff --git a/modules/ts/src/ts_func.cpp b/modules/ts/src/ts_func.cpp index 62e16fee4d..7208484293 100644 --- a/modules/ts/src/ts_func.cpp +++ b/modules/ts/src/ts_func.cpp @@ -71,7 +71,7 @@ int randomType(RNG& rng, int typeMask, int minChannels, int maxChannels) { int channels = rng.uniform(minChannels, maxChannels+1); int depth = 0; - CV_Assert((typeMask & DEPTH_MASK_ALL) != 0); + CV_Assert((typeMask & _OutputArray::DEPTH_MASK_ALL) != 0); for(;;) { depth = rng.uniform(CV_8U, CV_64F+1); diff --git a/samples/c/facedetect.cpp b/samples/c/facedetect.cpp index a7d7f4adba..8976a9cdcd 100644 --- a/samples/c/facedetect.cpp +++ b/samples/c/facedetect.cpp @@ -1,6 +1,7 @@ #include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/core/utility.hpp" #include #include @@ -124,7 +125,7 @@ int main( int argc, const char** argv ) for(;;) { IplImage* iplImg = cvQueryFrame( capture ); - frame = iplImg; + frame = cv::cvarrToMat(iplImg); if( frame.empty() ) break; if( iplImg->origin == IPL_ORIGIN_TL ) diff --git a/samples/c/smiledetect.cpp b/samples/c/smiledetect.cpp index c54c724398..214ae94127 100644 --- a/samples/c/smiledetect.cpp +++ b/samples/c/smiledetect.cpp @@ -1,6 +1,7 @@ #include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/core/utility.hpp" #include #include @@ -120,7 +121,7 @@ int main( int argc, const char** argv ) for(;;) { IplImage* iplImg = cvQueryFrame( capture ); - frame = iplImg; + frame = cv::cvarrToMat(iplImg); if( frame.empty() ) break; if( iplImg->origin == IPL_ORIGIN_TL ) diff --git a/samples/c/tree_engine.cpp b/samples/c/tree_engine.cpp index 74993ae490..2c3046fd73 100644 --- a/samples/c/tree_engine.cpp +++ b/samples/c/tree_engine.cpp @@ -1,5 +1,6 @@ #include "opencv2/ml/ml.hpp" #include "opencv2/core/core_c.h" +#include "opencv2/core/utility.hpp" #include #include @@ -21,7 +22,7 @@ static void help() static int count_classes(CvMLData& data) { - cv::Mat r(data.get_responses()); + cv::Mat r = cv::cvarrToMat(data.get_responses()); std::map rmap; int i, n = (int)r.total(); for( i = 0; i < n; i++ ) @@ -42,7 +43,7 @@ static void print_result(float train_err, float test_err, const CvMat* _var_imp) if (_var_imp) { - cv::Mat var_imp(_var_imp), sorted_idx; + cv::Mat var_imp = cv::cvarrToMat(_var_imp), sorted_idx; cv::sortIdx(var_imp, sorted_idx, CV_SORT_EVERY_ROW + CV_SORT_DESCENDING); printf( "variable importance:\n" ); diff --git a/samples/cpp/Qt_sample/main.cpp b/samples/cpp/Qt_sample/main.cpp index f987de471a..b43473310e 100644 --- a/samples/cpp/Qt_sample/main.cpp +++ b/samples/cpp/Qt_sample/main.cpp @@ -118,7 +118,7 @@ static void foundCorners(vector *srcImagePoints,IplImage* source, cvNormalize(grayImage, grayImage, 0, 255, CV_MINMAX); cvThreshold( grayImage, grayImage, 26, 255, CV_THRESH_BINARY_INV);//25 - Mat MgrayImage = grayImage; + Mat MgrayImage = cv::cvarrToMat(grayImage); //For debug //MgrayImage = MgrayImage.clone();//deep copy vector > contours; @@ -184,7 +184,7 @@ static void foundCorners(vector *srcImagePoints,IplImage* source, } srcImagePoints->at(3) = srcImagePoints_temp.at(index); - Mat Msource = source; + Mat Msource = cv::cvarrToMat(source); stringstream ss; for(size_t i = 0 ; i #include #include +#include " using namespace cv; // The new C++ interface API is inside this namespace. Import it. using namespace std; @@ -33,7 +34,7 @@ int main( int argc, char** argv ) cerr << "Can not load image " << imagename << endl; return -1; } - Mat I(IplI); // Convert to the new style container. Only header created. Image not copied. + Mat I = cv::cvarrToMat(IplI); // Convert to the new style container. Only header created. Image not copied. #else Mat I = imread(imagename); // the newer cvLoadImage alternative, MATLAB-style function if( I.empty() ) // same as if( !I.data ) diff --git a/samples/cpp/tutorial_code/objectDetection/objectDetection.cpp b/samples/cpp/tutorial_code/objectDetection/objectDetection.cpp index 0eb1752ece..0f5cb6a445 100644 --- a/samples/cpp/tutorial_code/objectDetection/objectDetection.cpp +++ b/samples/cpp/tutorial_code/objectDetection/objectDetection.cpp @@ -6,6 +6,7 @@ #include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/core/utility.hpp" #include #include @@ -43,7 +44,7 @@ int main( void ) { for(;;) { - frame = cvQueryFrame( capture ); + frame = cv::cvarrToMat(cvQueryFrame( capture )); //-- 3. Apply the classifier to the frame if( !frame.empty() ) diff --git a/samples/cpp/tutorial_code/objectDetection/objectDetection2.cpp b/samples/cpp/tutorial_code/objectDetection/objectDetection2.cpp index 086bbaf3bf..8e9b9d3305 100644 --- a/samples/cpp/tutorial_code/objectDetection/objectDetection2.cpp +++ b/samples/cpp/tutorial_code/objectDetection/objectDetection2.cpp @@ -6,6 +6,7 @@ #include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/core/utility.hpp" #include #include @@ -43,7 +44,7 @@ int main( void ) { for(;;) { - frame = cvQueryFrame( capture ); + frame = cv::cvarrToMat(cvQueryFrame( capture )); //-- 3. Apply the classifier to the frame if( !frame.empty() )