OpenCV中IplImage, CvMat, Mat 基本使用和元素遍历
来源:互联网 发布:阿里云可以挣钱吗 编辑:程序博客网 时间:2024/05/18 02:44
opencv中常见的与图像操作有关的数据容器有Mat,cvMat和IplImage,这三种类型都可以代表和显示图像。在OpenCV的文档中说明Mat类型通过C++面向对象的方法实现的,可以进行Matlab风格的矩阵操作,IplImage类型和CvMat类型用C语言实现的,两者之间存在着类似于面向对象中的继承关系。
一、IplImage
1.1 先上OpenCV中的图像信息头,该结构体的定义如下:
typedef struct _IplImage{ int nSize; /* sizeof(IplImage) */ int ID; /* version (=0)*/ int nChannels; /* Most of OpenCV functions support 1,2,3 or 4 channels */ int alphaChannel; /* Ignored by OpenCV */ int depth; /* Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported. */ char colorModel[4]; /* Ignored by OpenCV */ char channelSeq[4]; /* ditto */ int dataOrder; /* 0 - interleaved color channels, 1 - separate color channels. cvCreateImage can only create interleaved images */ int origin; /* 0 - top-left origin, 1 - bottom-left origin (Windows bitmaps style). */ int align; /* Alignment of image rows (4 or 8). OpenCV ignores it and uses widthStep instead. */ int width; /* Image width in pixels. */ int height; /* Image height in pixels. */ struct _IplROI *roi; /* Image ROI. If NULL, the whole image is selected. */ struct _IplImage *maskROI; /* Must be NULL. */ void *imageId; /* " " */ struct _IplTileInfo *tileInfo; /* " " */ int imageSize; /* Image data size in bytes (==image->height*image->widthStep in case of interleaved data)*/ char *imageData; /* Pointer to aligned image data. */ int widthStep; /* Size of aligned image row in bytes. */ int BorderMode[4]; /* Ignored by OpenCV. */ int BorderConst[4]; /* Ditto. */ char *imageDataOrigin; /* Pointer to very origin of image data (not necessarily aligned) - needed for correct deallocation */}IplImage;(1)dataOrder这个可以取两个不同的值(0/1),其中交叉存取颜色通道:指颜色数据排列会是BGRBGR....
分开颜色通道:几个颜色通道就分几个颜色平面存储。
(2)roi代表感兴趣区域,是IplROI结构体,包含了xOffset,yOffset,height,width,coi成员变量,分别代表感情兴趣区域的x坐标,y坐标,高,宽。
1.2 访问IplImage中的数据元素
在访问时,分为间接访问和直接访问,同时当存储的数据元素为浮点型时,将(uchar*)改变为(float*)
/*间接存取*/ IplImage* img=cvLoadImage("lena.jpg", 1); CvScalar s; /*sizeof(s) == img->nChannels*/ s=cvGet2D(img,i,j); /*get the (i,j) pixel value*/ cvSet2D(img,i,j,s); /*set the (i,j) pixel value*/ /*宏操作*/ IplImage* img; //malloc memory by cvLoadImage or cvCreateImage for(int row = 0; row < img->height; row++) { for (int col = 0; col < img->width; col++) { b = CV_IMAGE_ELEM(img, UCHAR, row, col * img->nChannels + 0); g = CV_IMAGE_ELEM(img, UCHAR, row, col * img->nChannels + 1); r = CV_IMAGE_ELEM(img, UCHAR, row, col * img->nChannels + 2); } } /*直接存取*/ IplImage* img; //malloc memory by cvLoadImage or cvCreateImage uchar b, g, r; // 3 channels for(int row = 0; row < img->height; row++) { for (int col = 0; col < img->width; col++) { b = ((uchar *)(img->imageData + row * img->widthStep))[col * img->nChannels + 0]; g = ((uchar *)(img->imageData + row * img->widthStep))[col * img->nChannels + 1]; r = ((uchar *)(img->imageData + row * img->widthStep))[col * img->nChannels + 2]; } }
二、CvMat
2.1 先上OpenCV中的图像信息头,该结构体的定义如下:
typedef struct CvMat{ int type; int step; /* for internal use only */ int* refcount; int hdr_refcount; union { uchar* ptr; short* s; int* i; float* fl; double* db; } data;#ifdef __cplusplus union { int rows; int height; }; union { int cols; int width; };#else int rows; int cols;#endif}CvMat;2.2 访问CvMat中的数据元素
/*间接访问*/ /*访问CV_32F1和CV_64FC1*/ cvmSet( CvMat* mat, int row, int col, double value); cvmGet( const CvMat* mat, int row, int col ); /*访问多通道或者其他数据类型: scalar的大小为图像的通道值*/ CvScalar cvGet2D(const CvArr * arr, int idx0, int idx1); //CvArr只作为函数的形参void cvSet2D(CvArr* arr, int idx0, int idx1, CvScalar value); /*直接访问: 取决于数组的数据类型*/ /*CV_32FC1*/ CvMat * cvmat = cvCreateMat(4, 4, CV_32FC1); cvmat->data.fl[row * cvmat->cols + col] = (float)3.0; /*CV_64FC1*/ CvMat * cvmat = cvCreateMat(4, 4, CV_64FC1); cvmat->data.db[row * cvmat->cols + col] = 3.0; /*一般对于单通道*/ CvMat * cvmat = cvCreateMat(4, 4, CV_64FC1); CV_MAT_ELEM(*cvmat, double, row, col) = 3.0; /*double是根据数组的数据类型传入,这个宏不能处理多通道*/ /*一般对于多通道*/ if (CV_MAT_DEPTH(cvmat->type) == CV_32F) CV_MAT_ELEM_CN(*cvmat, float, row, col * CV_MAT_CN(cvmat->type) + ch) = (float)3.0; // ch为通道值 if (CV_MAT_DEPTH(cvmat->type) == CV_64F) CV_MAT_ELEM_CN(*cvmat, double, row, col * CV_MAT_CN(cvmat->type) + ch) = 3.0; // ch为通道值 /*多通道数组*/ /*3通道*/ for (int row = 0; row < cvmat->rows; row++) { p = cvmat ->data.fl + row * (cvmat->step / 4); for (int col = 0; col < cvmat->cols; col++) { *p = (float) row + col; *(p+1) = (float)row + col + 1; *(p+2) = (float)row + col + 2; p += 3; } } /*2通道*/ CvMat * vector = cvCreateMat(1,3, CV_32SC2);CV_MAT_ELEM(*vector, CvPoint, 0, 0) = cvPoint(100,100); /*4通道*/ CvMat * vector = cvCreateMat(1,3, CV_64FC4);CV_MAT_ELEM(*vector, CvScalar, 0, 0) = CvScalar(0, 0, 0, 0);
三、Mat
Mat是opencv2.0推出的处理图像的新的数据结构,现在越来越有趋势取代之前的cvMat和lplImage,相比之下Mat最大的好处就是能够更加方便的进行内存管理,不再需要程序员手动管理内存的释放。opencv2.3中提到Mat是一个多维的密集数据数组,可以用来处理向量和矩阵、图像、直方图等等常见的多维数据。
3.1 先上OpenCV中的图像信息头,该类的定义如下:
class CV_EXPORTS Mat{public: //! default constructor Mat(); //! constructs 2D matrix of the specified size and type // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.) Mat(int rows, int cols, int type); Mat(Size size, int type); //! constucts 2D matrix and fills it with the specified value _s. Mat(int rows, int cols, int type, const Scalar& s); Mat(Size size, int type, const Scalar& s); //! constructs n-dimensional matrix Mat(int ndims, const int* sizes, int type); Mat(int ndims, const int* sizes, int type, const Scalar& s); //! copy constructor Mat(const Mat& m); //! constructor for matrix headers pointing to user-allocated data Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP); Mat(Size size, int type, void* data, size_t step=AUTO_STEP); Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0); //! creates a matrix header for a part of the bigger matrix Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all()); Mat(const Mat& m, const Rect& roi); Mat(const Mat& m, const Range* ranges); //! converts old-style CvMat to the new matrix; the data is not copied by default Mat(const CvMat* m, bool copyData=false); //! converts old-style CvMatND to the new matrix; the data is not copied by default Mat(const CvMatND* m, bool copyData=false); //! converts old-style IplImage to the new matrix; the data is not copied by default Mat(const IplImage* img, bool copyData=false); //! builds matrix from std::vector with or without copying the data template<typename _Tp> explicit Mat(const vector<_Tp>& vec, bool copyData=false); //! builds matrix from cv::Vec; the data is copied by default template<typename _Tp, int n> explicit Mat(const Vec<_Tp, n>& vec, bool copyData=true); //! builds matrix from cv::Matx; the data is copied by default template<typename _Tp, int m, int n> explicit Mat(const Matx<_Tp, m, n>& mtx, bool copyData=true); //! builds matrix from a 2D point template<typename _Tp> explicit Mat(const Point_<_Tp>& pt, bool copyData=true); //! builds matrix from a 3D point template<typename _Tp> explicit Mat(const Point3_<_Tp>& pt, bool copyData=true); //! builds matrix from comma initializer template<typename _Tp> explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer); //! download data from GpuMat explicit Mat(const gpu::GpuMat& m); //! destructor - calls release() ~Mat(); //! assignment operators Mat& operator = (const Mat& m); Mat& operator = (const MatExpr& expr); //! returns a new matrix header for the specified row Mat row(int y) const; //! returns a new matrix header for the specified column Mat col(int x) const; //! ... for the specified row span Mat rowRange(int startrow, int endrow) const; Mat rowRange(const Range& r) const; //! ... for the specified column span Mat colRange(int startcol, int endcol) const; Mat colRange(const Range& r) const; //! ... for the specified diagonal // (d=0 - the main diagonal, // >0 - a diagonal from the lower half, // <0 - a diagonal from the upper half) Mat diag(int d=0) const; //! constructs a square diagonal matrix which main diagonal is vector "d" static Mat diag(const Mat& d); //! returns deep copy of the matrix, i.e. the data is copied Mat clone() const; //! copies the matrix content to "m". // It calls m.create(this->size(), this->type()). void copyTo( OutputArray m ) const; //! copies those matrix elements to "m" that are marked with non-zero mask elements. void copyTo( OutputArray m, InputArray mask ) const; //! converts matrix to another datatype with optional scalng. See cvConvertScale. void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const; void assignTo( Mat& m, int type=-1 ) const; //! sets every matrix element to s Mat& operator = (const Scalar& s); //! sets some of the matrix elements to s, according to the mask Mat& setTo(InputArray value, InputArray mask=noArray()); //! creates alternative matrix header for the same data, with different // number of channels and/or different number of rows. see cvReshape. Mat reshape(int cn, int rows=0) const; Mat reshape(int cn, int newndims, const int* newsz) const; //! matrix transposition by means of matrix expressions MatExpr t() const; //! matrix inversion by means of matrix expressions MatExpr inv(int method=DECOMP_LU) const; //! per-element matrix multiplication by means of matrix expressions MatExpr mul(InputArray m, double scale=1) const; //! computes cross-product of 2 3D vectors Mat cross(InputArray m) const; //! computes dot-product double dot(InputArray m) const; //! Matlab-style matrix initialization static MatExpr zeros(int rows, int cols, int type); static MatExpr zeros(Size size, int type); static MatExpr zeros(int ndims, const int* sz, int type); static MatExpr ones(int rows, int cols, int type); static MatExpr ones(Size size, int type); static MatExpr ones(int ndims, const int* sz, int type); static MatExpr eye(int rows, int cols, int type); static MatExpr eye(Size size, int type); //! allocates new matrix data unless the matrix already has specified size and type. // previous data is unreferenced if needed. void create(int rows, int cols, int type); void create(Size size, int type); void create(int ndims, const int* sizes, int type); //! increases the reference counter; use with care to avoid memleaks void addref(); //! decreases reference counter; // deallocates the data when reference counter reaches 0. void release(); //! deallocates the matrix data void deallocate(); //! internal use function; properly re-allocates _size, _step arrays void copySize(const Mat& m); //! reserves enough space to fit sz hyper-planes void reserve(size_t sz); //! resizes matrix to the specified number of hyper-planes void resize(size_t sz); //! resizes matrix to the specified number of hyper-planes; initializes the newly added elements void resize(size_t sz, const Scalar& s); //! internal function void push_back_(const void* elem); //! adds element to the end of 1d matrix (or possibly multiple elements when _Tp=Mat) template<typename _Tp> void push_back(const _Tp& elem); template<typename _Tp> void push_back(const Mat_<_Tp>& elem); void push_back(const Mat& m); //! removes several hyper-planes from bottom of the matrix void pop_back(size_t nelems=1); //! locates matrix header within a parent matrix. See below void locateROI( Size& wholeSize, Point& ofs ) const; //! moves/resizes the current matrix ROI inside the parent matrix. Mat& adjustROI( int dtop, int dbottom, int dleft, int dright ); //! extracts a rectangular sub-matrix // (this is a generalized form of row, rowRange etc.) Mat operator()( Range rowRange, Range colRange ) const; Mat operator()( const Rect& roi ) const; Mat operator()( const Range* ranges ) const; //! converts header to CvMat; no data is copied operator CvMat() const; //! converts header to CvMatND; no data is copied operator CvMatND() const; //! converts header to IplImage; no data is copied operator IplImage() const; template<typename _Tp> operator vector<_Tp>() const; template<typename _Tp, int n> operator Vec<_Tp, n>() const; template<typename _Tp, int m, int n> operator Matx<_Tp, m, n>() const; //! returns true iff the matrix data is continuous // (i.e. when there are no gaps between successive rows). // similar to CV_IS_MAT_CONT(cvmat->type) bool isContinuous() const; //! returns true if the matrix is a submatrix of another matrix bool isSubmatrix() const; //! returns element size in bytes, // similar to CV_ELEM_SIZE(cvmat->type) size_t elemSize() const; //! returns the size of element channel in bytes. size_t elemSize1() const; //! returns element type, similar to CV_MAT_TYPE(cvmat->type) int type() const; //! returns element type, similar to CV_MAT_DEPTH(cvmat->type) int depth() const; //! returns element type, similar to CV_MAT_CN(cvmat->type) int channels() const; //! returns step/elemSize1() size_t step1(int i=0) const; //! returns true if matrix data is NULL bool empty() const; //! returns the total number of matrix elements size_t total() const; //! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const; //! returns pointer to i0-th submatrix along the dimension #0 uchar* ptr(int i0=0); const uchar* ptr(int i0=0) const; //! returns pointer to (i0,i1) submatrix along the dimensions #0 and #1 uchar* ptr(int i0, int i1); const uchar* ptr(int i0, int i1) const; //! returns pointer to (i0,i1,i3) submatrix along the dimensions #0, #1, #2 uchar* ptr(int i0, int i1, int i2); const uchar* ptr(int i0, int i1, int i2) const; //! returns pointer to the matrix element uchar* ptr(const int* idx); //! returns read-only pointer to the matrix element const uchar* ptr(const int* idx) const; template<int n> uchar* ptr(const Vec<int, n>& idx); template<int n> const uchar* ptr(const Vec<int, n>& idx) const; //! template version of the above method template<typename _Tp> _Tp* ptr(int i0=0); template<typename _Tp> const _Tp* ptr(int i0=0) const; template<typename _Tp> _Tp* ptr(int i0, int i1); template<typename _Tp> const _Tp* ptr(int i0, int i1) const; template<typename _Tp> _Tp* ptr(int i0, int i1, int i2); template<typename _Tp> const _Tp* ptr(int i0, int i1, int i2) const; template<typename _Tp> _Tp* ptr(const int* idx); template<typename _Tp> const _Tp* ptr(const int* idx) const; template<typename _Tp, int n> _Tp* ptr(const Vec<int, n>& idx); template<typename _Tp, int n> const _Tp* ptr(const Vec<int, n>& idx) const; //! the same as above, with the pointer dereferencing template<typename _Tp> _Tp& at(int i0=0); template<typename _Tp> const _Tp& at(int i0=0) const; template<typename _Tp> _Tp& at(int i0, int i1); template<typename _Tp> const _Tp& at(int i0, int i1) const; template<typename _Tp> _Tp& at(int i0, int i1, int i2); template<typename _Tp> const _Tp& at(int i0, int i1, int i2) const; template<typename _Tp> _Tp& at(const int* idx); template<typename _Tp> const _Tp& at(const int* idx) const; template<typename _Tp, int n> _Tp& at(const Vec<int, n>& idx); template<typename _Tp, int n> const _Tp& at(const Vec<int, n>& idx) const; //! special versions for 2D arrays (especially convenient for referencing image pixels) template<typename _Tp> _Tp& at(Point pt); template<typename _Tp> const _Tp& at(Point pt) const; //! template methods for iteration over matrix elements. // the iterators take care of skipping gaps in the end of rows (if any) template<typename _Tp> MatIterator_<_Tp> begin(); template<typename _Tp> MatIterator_<_Tp> end(); template<typename _Tp> MatConstIterator_<_Tp> begin() const; template<typename _Tp> MatConstIterator_<_Tp> end() const; enum { MAGIC_VAL=0x42FF0000, AUTO_STEP=0, CONTINUOUS_FLAG=CV_MAT_CONT_FLAG, SUBMATRIX_FLAG=CV_SUBMAT_FLAG }; /*! includes several bit-fields: - the magic signature - continuity flag - depth - number of channels */ int flags; //! the matrix dimensionality, >= 2 int dims; //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions int rows, cols; //! pointer to the data uchar* data; //! pointer to the reference counter; // when matrix points to user-allocated data, the pointer is NULL int* refcount; //! helper fields used in locateROI and adjustROI uchar* datastart; uchar* dataend; uchar* datalimit; //! custom allocator MatAllocator* allocator; struct CV_EXPORTS MSize { MSize(int* _p); Size operator()() const; const int& operator[](int i) const; int& operator[](int i); operator const int*() const; bool operator == (const MSize& sz) const; bool operator != (const MSize& sz) const; int* p; }; struct CV_EXPORTS MStep { MStep(); MStep(size_t s); const size_t& operator[](int i) const; size_t& operator[](int i); operator size_t() const; MStep& operator = (size_t s); size_t* p; size_t buf[2]; protected: MStep& operator = (const MStep&); }; MSize size; MStep step;protected: void initEmpty();};3.2 访问Mat中的数据元素
/*对某行进行访问*/ Mat M; M.row(3) = M.row(3) + M.row(5) * 3; /*第5行扩大三倍加到第3行*/ /*对某列进行复制操作*/ Mat M1 = M.col(1); M.col(7).copyTo(M1); /*第7列复制给第1列*/ /*对某个元素的访问*/ Mat M; M.at<double>(i,j); /*double*/ M.at(uchar)(i,j); /*CV_8UC1*/ Vec3i bgr1 = M.at(Vec3b)(i,j) /*CV_8UC3*/ Vec3s bgr2 = M.at(Vec3s)(i,j) /*CV_8SC3*/ Vec3w bgr3 = M.at(Vec3w)(i,j) /*CV_16UC3*/ /*遍历整个二维数组*/ double sum = 0.0f; for(int row = 0; row < M.rows; row++) { const double * Mi = M.ptr<double>(row); for (int col = 0; col < M.cols; col++) sum += std::max(Mi[j], 0.); } /*STL iterator*/ double sum=0; MatConstIterator<double> it = M.begin<double>(), it_end = M.end<double>(); for(; it != it_end; ++it) sum += std::max(*it, 0.);
0 0
- OpenCV中IplImage, CvMat, Mat 基本使用和元素遍历
- OpenCV中IplImage, CvMat, Mat 基本使用和元素遍历
- OpenCV中IplImage, CvMat, Mat 基本使用和元素遍历
- Opencv读取mat和cvMat元素&&Mat与IplImage和CvMat类型之间的相互转换
- opencv中IplImage, CvMat, Mat 数据结构的使用简介
- OpenCv中cv::Mat和IplImage,CvMat之间的转换
- OpenCv中cv::Mat和IplImage,CvMat之间的转换
- OpenCV中IplImage, CvMat, Mat 的关系和相互转换
- OpenCV中IplImage, CvMat, Mat 创建和相互转换
- opencv中Mat、CvMat和IplImage的相互转化
- OpenCv中cv::Mat和IplImage,CvMat之间的转换
- OpenCV中Mat、cvMat和IplImage类型转换
- OpenCV中IplImage/CvMat/Mat转化关系
- OpenCV中Mat,IplImage,CVMat类型转换
- opencv数据容器Mat,cvMat和IplImage
- opencv数据容器Mat,cvMat和IplImage
- Mat,cvMat和IplImage
- OpenCV中的Mat, cvMat, IplImage
- The import XXX cannot be resolved
- 微信自用的移动端IM网络层跨平台组件库Mars已正式开源
- 批处理恶搞大全
- Iocomp之数码管控件汇总
- JavaWeb入门(二) 面向对象篇
- OpenCV中IplImage, CvMat, Mat 基本使用和元素遍历
- 图解sqlserver命令行工具sqlcmd的使用
- 使用runOnUiThread更新主线程UI
- DZone——JXTA
- oracle 用户管理
- Qt网络编程之获取网络信息
- JavaScript 设置页面是否被缩放
- Linux_查看CPU信息、机器型号等硬件信息
- Ceph rbd写入数据