参考博客:
OpenCv中cv::Mat和IplImage,CvMat之间的转换
Mat类型较CvMat和IplImage有更强的矩阵运算能力,支持常见的矩阵运算(参照Matlab中的各种矩阵运算),所以将IplImage类型和CvMat类型转换为Mat类型更易于数据处理。
关于 Mat ,首先要知道的是你不必再手动地(1)为其开辟空间(2)在不需要时立即将空间释放。但手动地做还是可以的:大多数OpenCV函数仍会手动地为输出数据开辟空间。当传递一个已经存在的 Mat 对象时,开辟好的矩阵空间会被重用。也就是说,我们每次都使用大小正好的内存来完成任务。
基本上讲 Mat 是一个类,由两个数据部分组成:矩阵头(包含矩阵尺寸,存储方法,存储地址等信息)和一个指向存储所有像素值的矩阵(根据所选存储方法的不同矩阵可以是不同的维数)的指针。矩阵头的尺寸是常数值,但矩阵本身的尺寸会依图像的不同而不同,通常比矩阵头的尺寸大数个数量级。因此,当在程序中传递图像并创建拷贝时,大的开销是由矩阵造成的,而不是信息头。
为了解决图像传输拖程序速度,OpenCV使用引用计数机制。其思路是让每个 Mat 对象有自己的信息头,但共享同一个矩阵。这通过让矩阵指针指向同一地址而实现。而拷贝构造函数则 只拷贝信息头和矩阵指针 ,而不拷贝矩阵。
Mat对象操作:
1、创建Mat类对象
Mat A, C; // 只创建信息头部分 A = imread(argv[1], CV_LOAD_IMAGE_COLOR); // 这里为矩阵开辟内存 Mat B(A); // 使用拷贝构造函数 C = A; // 赋值运算符
2、创建ROI的信息头
Mat D (A, Rect(10, 10, 100, 100) ); // using a rectangle Mat E = A(Range:all(), Range(1,3)); // using row and column boundaries
3、矩阵的拷贝
Mat F = A.clone(); Mat G; A.copyTo(G);
总结:
- OpenCV函数中输出图像的内存分配是自动完成的(如果不特别指定的话)。
- 使用OpenCV的C++接口时不需要考虑内存释放问题。
- 赋值运算符和拷贝构造函数( ctor )只拷贝信息头。
- 使用函数 clone() 或者 copyTo() 来拷贝一副图像的矩阵。
像素值的存储
颜色空间:
指对一个给定的颜色,如何组合颜色元素以对其编码。最简单的颜色空间要属灰度级空间,只处理黑色和白色,对它们进行组合可以产生不同程度的灰色。
对于 彩色 方式则有更多种类的颜色空间,但不论哪种方式都是把颜色分成三个或者四个基元素,通过组合基元素可以产生所有的颜色。RGB颜色空间是最常用的一种颜色空间,这归功于它也是人眼内部构成颜色的方式。它的基色是红色、绿色和蓝色,有时为了表示透明颜色也会加入第四个元素 alpha (A)。
- RGB是最常见的,这是因为人眼采用相似的工作机制,它也被显示设备所采用。
- HSV和HLS把颜色分解成色调、饱和度和亮度/明度。这是描述颜色更自然的方式,比如可以通过抛弃最后一个元素,使算法对输入图像的光照条件不敏感。
- YCrCb在JPEG图像格式中广泛使用。
- CIE L*a*b*是一种在感知上均匀的颜色空间,它适合用来度量两个颜色之间的 距离 。
存储类型:
每个组成元素都有其自己的定义域,取决于其数据类型。如何存储一个元素决定了我们在其定义域上能够控制的精度。最小的数据类型是char ,占一个字节或者8位,可以是有符号型(0到255之间)或无符号型(-127到+127之间)。尽管使用三个 char 型元素已经可以表示1600万种可能的颜色(使用RGB颜色空间),但若使用float(4字节,32位)或double(8字节,64位)则能给出更加精细的颜色分辨能力。但同时也要切记增加元素的尺寸也会增加了图像所占的内存空间。
int flags;
int dims; 矩阵的维度(>=2)
int rows, cols; 矩阵行列值( 对二维矩阵而言,超过二维赋值为(-1,-1) )
uchar *data; 数据指针
int* refcount; 引用计数,当矩阵指针指向用户分配的数据,指针为NULL(?)
uchar* datastart; 设定ROI区域空间的三个指针
uchar* dataend;
uchar* datalimit;
MatAllocator* allocator; custom allocator(?)
MSize size;
MStep step; 每行数据字节数
1 class CV_EXPORTS Mat 2 { 3 public: 4 //! default constructor 5 Mat(); 6 //! constructs 2D matrix of the specified size and type 7 // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.) 8 Mat(int rows, int cols, int type); 9 Mat(Size size, int type); 10 //! constucts 2D matrix and fills it with the specified value _s. 11 Mat(int rows, int cols, int type, const Scalar& s); 12 Mat(Size size, int type, const Scalar& s); 13 14 //! constructs n-dimensional matrix 15 Mat(int ndims, const int* sizes, int type); 16 Mat(int ndims, const int* sizes, int type, const Scalar& s); 17 18 //! copy constructor 19 Mat(const Mat& m); 20 //! constructor for matrix headers pointing to user-allocated data 21 Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP); 22 Mat(Size size, int type, void* data, size_t step=AUTO_STEP); 23 Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0); 24 25 //! creates a matrix header for a part of the bigger matrix 26 Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all()); 27 Mat(const Mat& m, const Rect& roi); 28 Mat(const Mat& m, const Range* ranges); 29 //! converts old-style CvMat to the new matrix; the data is not copied by default 30 Mat(const CvMat* m, bool copyData=false); 31 //! converts old-style CvMatND to the new matrix; the data is not copied by default 32 Mat(const CvMatND* m, bool copyData=false); 33 //! converts old-style IplImage to the new matrix; the data is not copied by default 34 Mat(const IplImage* img, bool copyData=false); 35 //! builds matrix from std::vector with or without copying the data 36 template<typename _Tp> explicit Mat(const vector<_Tp>& vec, bool copyData=false); 37 //! builds matrix from cv::Vec; the data is copied by default 38 template<typename _Tp, int n> explicit Mat(const Vec<_Tp, n>& vec, bool copyData=true); 39 //! builds matrix from cv::Matx; the data is copied by default 40 template<typename _Tp, int m, int n> explicit Mat(const Matx<_Tp, m, n>& mtx, bool copyData=true); 41 //! builds matrix from a 2D point 42 template<typename _Tp> explicit Mat(const Point_<_Tp>& pt, bool copyData=true); 43 //! builds matrix from a 3D point 44 template<typename _Tp> explicit Mat(const Point3_<_Tp>& pt, bool copyData=true); 45 //! builds matrix from comma initializer 46 template<typename _Tp> explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer); 47 48 //! download data from GpuMat 49 explicit Mat(const gpu::GpuMat& m); 50 51 //! destructor - calls release() 52 ~Mat(); 53 //! assignment operators 54 Mat& operator = (const Mat& m); 55 Mat& operator = (const MatExpr& expr); 56 57 //! returns a new matrix header for the specified row 58 Mat row(int y) const; 59 //! returns a new matrix header for the specified column 60 Mat col(int x) const; 61 //! ... for the specified row span 62 Mat rowRange(int startrow, int endrow) const; 63 Mat rowRange(const Range& r) const; 64 //! ... for the specified column span 65 Mat colRange(int startcol, int endcol) const; 66 Mat colRange(const Range& r) const; 67 //! ... for the specified diagonal 68 // (d=0 - the main diagonal, 69 // >0 - a diagonal from the lower half, 70 // <0 - a diagonal from the upper half) 71 Mat diag(int d=0) const; 72 //! constructs a square diagonal matrix which main diagonal is vector "d" 73 static Mat diag(const Mat& d); 74 75 //! returns deep copy of the matrix, i.e. the data is copied 76 Mat clone() const; 77 //! copies the matrix content to "m". 78 // It calls m.create(this->size(), this->type()). 79 void copyTo( OutputArray m ) const; 80 //! copies those matrix elements to "m" that are marked with non-zero mask elements. 81 void copyTo( OutputArray m, InputArray mask ) const; 82 //! converts matrix to another datatype with optional scalng. See cvConvertScale. 83 void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const; 84 85 void assignTo( Mat& m, int type=-1 ) const; 86 87 //! sets every matrix element to s 88 Mat& operator = (const Scalar& s); 89 //! sets some of the matrix elements to s, according to the mask 90 Mat& setTo(InputArray value, InputArray mask=noArray()); 91 //! creates alternative matrix header for the same data, with different 92 // number of channels and/or different number of rows. see cvReshape. 93 Mat reshape(int cn, int rows=0) const; 94 Mat reshape(int cn, int newndims, const int* newsz) const; 95 96 //! matrix transposition by means of matrix expressions 97 MatExpr t() const; 98 //! matrix inversion by means of matrix expressions 99 MatExpr inv(int method=DECOMP_LU) const; 100 //! per-element matrix multiplication by means of matrix expressions 101 MatExpr mul(InputArray m, double scale=1) const; 102 103 //! computes cross-product of 2 3D vectors 104 Mat cross(InputArray m) const; 105 //! computes dot-product 106 double dot(InputArray m) const; 107 108 //! Matlab-style matrix initialization 109 static MatExpr zeros(int rows, int cols, int type); 110 static MatExpr zeros(Size size, int type); 111 static MatExpr zeros(int ndims, const int* sz, int type); 112 static MatExpr ones(int rows, int cols, int type); 113 static MatExpr ones(Size size, int type); 114 static MatExpr ones(int ndims, const int* sz, int type); 115 static MatExpr eye(int rows, int cols, int type); 116 static MatExpr eye(Size size, int type); 117 118 //! allocates new matrix data unless the matrix already has specified size and type. 119 // previous data is unreferenced if needed. 120 void create(int rows, int cols, int type); 121 void create(Size size, int type); 122 void create(int ndims, const int* sizes, int type); 123 124 //! increases the reference counter; use with care to avoid memleaks 125 void addref(); 126 //! decreases reference counter; 127 // deallocates the data when reference counter reaches 0. 128 void release(); 129 130 //! deallocates the matrix data 131 void deallocate(); 132 //! internal use function; properly re-allocates _size, _step arrays 133 void copySize(const Mat& m); 134 135 //! reserves enough space to fit sz hyper-planes 136 void reserve(size_t sz); 137 //! resizes matrix to the specified number of hyper-planes 138 void resize(size_t sz); 139 //! resizes matrix to the specified number of hyper-planes; initializes the newly added elements 140 void resize(size_t sz, const Scalar& s); 141 //! internal function 142 void push_back_(const void* elem); 143 //! adds element to the end of 1d matrix (or possibly multiple elements when _Tp=Mat) 144 template<typename _Tp> void push_back(const _Tp& elem); 145 template<typename _Tp> void push_back(const Mat_<_Tp>& elem); 146 void push_back(const Mat& m); 147 //! removes several hyper-planes from bottom of the matrix 148 void pop_back(size_t nelems=1); 149 150 //! locates matrix header within a parent matrix. See below 151 void locateROI( Size& wholeSize, Point& ofs ) const; 152 //! moves/resizes the current matrix ROI inside the parent matrix. 153 Mat& adjustROI( int dtop, int dbottom, int dleft, int dright ); 154 //! extracts a rectangular sub-matrix 155 // (this is a generalized form of row, rowRange etc.) 156 Mat operator()( Range rowRange, Range colRange ) const; 157 Mat operator()( const Rect& roi ) const; 158 Mat operator()( const Range* ranges ) const; 159 160 //! converts header to CvMat; no data is copied 161 operator CvMat() const; 162 //! converts header to CvMatND; no data is copied 163 operator CvMatND() const; 164 //! converts header to IplImage; no data is copied 165 operator IplImage() const; 166 167 template<typename _Tp> operator vector<_Tp>() const; 168 template<typename _Tp, int n> operator Vec<_Tp, n>() const; 169 template<typename _Tp, int m, int n> operator Matx<_Tp, m, n>() const; 170 171 //! returns true iff the matrix data is continuous 172 // (i.e. when there are no gaps between successive rows). 173 // similar to CV_IS_MAT_CONT(cvmat->type) 174 bool isContinuous() const; 175 176 //! returns true if the matrix is a submatrix of another matrix 177 bool isSubmatrix() const; 178 179 //! returns element size in bytes, 180 // similar to CV_ELEM_SIZE(cvmat->type) 181 size_t elemSize() const; 182 //! returns the size of element channel in bytes. 183 size_t elemSize1() const; 184 //! returns element type, similar to CV_MAT_TYPE(cvmat->type) 185 int type() const; 186 //! returns element type, similar to CV_MAT_DEPTH(cvmat->type) 187 int depth() const; 188 //! returns element type, similar to CV_MAT_CN(cvmat->type) 189 int channels() const; 190 //! returns step/elemSize1() 191 size_t step1(int i=0) const; 192 //! returns true if matrix data is NULL 193 bool empty() const; 194 //! returns the total number of matrix elements 195 size_t total() const; 196 197 //! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise 198 int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const; 199 200 //! returns pointer to i0-th submatrix along the dimension #0 201 uchar* ptr(int i0=0); 202 const uchar* ptr(int i0=0) const; 203 204 //! returns pointer to (i0,i1) submatrix along the dimensions #0 and #1 205 uchar* ptr(int i0, int i1); 206 const uchar* ptr(int i0, int i1) const; 207 208 //! returns pointer to (i0,i1,i3) submatrix along the dimensions #0, #1, #2 209 uchar* ptr(int i0, int i1, int i2); 210 const uchar* ptr(int i0, int i1, int i2) const; 211 212 //! returns pointer to the matrix element 213 uchar* ptr(const int* idx); 214 //! returns read-only pointer to the matrix element 215 const uchar* ptr(const int* idx) const; 216 217 template<int n> uchar* ptr(const Vec<int, n>& idx); 218 template<int n> const uchar* ptr(const Vec<int, n>& idx) const; 219 220 //! template version of the above method 221 template<typename _Tp> _Tp* ptr(int i0=0); 222 template<typename _Tp> const _Tp* ptr(int i0=0) const; 223 224 template<typename _Tp> _Tp* ptr(int i0, int i1); 225 template<typename _Tp> const _Tp* ptr(int i0, int i1) const; 226 227 template<typename _Tp> _Tp* ptr(int i0, int i1, int i2); 228 template<typename _Tp> const _Tp* ptr(int i0, int i1, int i2) const; 229 230 template<typename _Tp> _Tp* ptr(const int* idx); 231 template<typename _Tp> const _Tp* ptr(const int* idx) const; 232 233 template<typename _Tp, int n> _Tp* ptr(const Vec<int, n>& idx); 234 template<typename _Tp, int n> const _Tp* ptr(const Vec<int, n>& idx) const; 235 236 //! the same as above, with the pointer dereferencing 237 template<typename _Tp> _Tp& at(int i0=0); 238 template<typename _Tp> const _Tp& at(int i0=0) const; 239 240 template<typename _Tp> _Tp& at(int i0, int i1); 241 template<typename _Tp> const _Tp& at(int i0, int i1) const; 242 243 template<typename _Tp> _Tp& at(int i0, int i1, int i2); 244 template<typename _Tp> const _Tp& at(int i0, int i1, int i2) const; 245 246 template<typename _Tp> _Tp& at(const int* idx); 247 template<typename _Tp> const _Tp& at(const int* idx) const; 248 249 template<typename _Tp, int n> _Tp& at(const Vec<int, n>& idx); 250 template<typename _Tp, int n> const _Tp& at(const Vec<int, n>& idx) const; 251 252 //! special versions for 2D arrays (especially convenient for referencing image pixels) 253 template<typename _Tp> _Tp& at(Point pt); 254 template<typename _Tp> const _Tp& at(Point pt) const; 255 256 //! template methods for iteration over matrix elements. 257 // the iterators take care of skipping gaps in the end of rows (if any) 258 template<typename _Tp> MatIterator_<_Tp> begin(); 259 template<typename _Tp> MatIterator_<_Tp> end(); 260 template<typename _Tp> MatConstIterator_<_Tp> begin() const; 261 template<typename _Tp> MatConstIterator_<_Tp> end() const; 262 263 enum { MAGIC_VAL=0x42FF0000, AUTO_STEP=0, CONTINUOUS_FLAG=CV_MAT_CONT_FLAG, SUBMATRIX_FLAG=CV_SUBMAT_FLAG }; 264 265 /*! includes several bit-fields: 266 - the magic signature 267 - continuity flag 268 - depth 269 - number of channels 270 */ 271 int flags; 272 //! the matrix dimensionality, >= 2 273 int dims; 274 //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions 275 int rows, cols; 276 //! pointer to the data 277 uchar* data; 278 279 //! pointer to the reference counter; 280 // when matrix points to user-allocated data, the pointer is NULL 281 int* refcount; 282 283 //! helper fields used in locateROI and adjustROI 284 uchar* datastart; 285 uchar* dataend; 286 uchar* datalimit; 287 288 //! custom allocator 289 MatAllocator* allocator; 290 291 struct CV_EXPORTS MSize 292 { 293 MSize(int* _p); 294 Size operator()() const; 295 const int& operator[](int i) const; 296 int& operator[](int i); 297 operator const int*() const; 298 bool operator == (const MSize& sz) const; 299 bool operator != (const MSize& sz) const; 300 301 int* p; 302 }; 303 304 struct CV_EXPORTS MStep 305 { 306 MStep(); 307 MStep(size_t s); 308 const size_t& operator[](int i) const; 309 size_t& operator[](int i); 310 operator size_t() const; 311 MStep& operator = (size_t s); 312 313 size_t* p; 314 size_t buf[2]; 315 protected: 316 MStep& operator = (const MStep&); 317 }; 318 319 MSize size; 320 MStep step; 321 322 protected: 323 void initEmpty(); 324 };