Common Data containers related to image operations in opencv include mat, cvmat, and iplimage. These three types can represent and display images. However, mat types focus on computing, the mathematics is high, and the calculation of Mat type is also optimized by opencv. The cvmat and iplimage types focus more on "Images". opencv optimizes image operations (such as scaling, single-channel extraction, and image threshold operations. Before opencv2.0, opencv was fully implemented in C. However, the relationship between the iplimage type and the cvmat type is similar to the inheritance relationship in the object-oriented model. In fact, there is a more abstract base class-cvarr on the cvmat, which is common in source code.
1. iplimage
The image information header in opencv, which is defined as follows:
typedef struct _IplImage { int nSize; int ID; int nChannels; int alphaChannel; int depth; char colorModel[4]; char channelSeq[4]; int dataOrder; int origin; int align; int width; int height; struct _IplROI *roi; struct _IplImage *maskROI; void *imageId; struct _IplTileInfo *tileInfo; int imageSize; char *imageData; int widthStep; int BorderMode[4]; int BorderConst[4]; char *imageDataOrigin; } IplImage;
Two values in dataorder: the cross-access color channel is the color data arrangement, which will be the staggered arrangement of bgrbgr. Separated color channels are stored in several color channels in several color planes. ROI is the structure of iplroi, which contains xoffset, yoffset, height, width, and COI member variables. xoffset, yoffset is the X, Y coordinates, and COI represents the channel.
Of interest (Channel of interest), valid only when not 0. Access the data elements in the image and store them indirectly and directly. When the image elements are float, change (uchar *) to (float *):
ViewCode
IplImage* img=cvLoadImage("lena.jpg", 1);CvScalar s; s=cvGet2D(img,i,j); cvSet2D(img,i,j,s); IplImage* img; //malloc memory by cvLoadImage or cvCreateImagefor(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 cvCreateImageuchar b, g, r; // 3 channelsfor(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];}}
When iplimage * is used for initialization, It is a pointer to the structure iplimage:
IplImage * cvLoadImage(constchar * filename, int//load images from specified image IplImage * cvCreateImage(CvSize size, int depth, int channels); //allocate memory
2. cvmat
First, we need to know that, first, there is no vector structure in opencv. A vector is required at any time, and only one column matrix is required (if a transpose or bounded vector is required, a row matrix is required ). Second, the concept of opencv matrix is more abstract than what we learned in linear algebra, especially matrix elements. It is not just a simple numerical type, but a multi-channel value. Cvmat structure:
typedef struct CvMat { int type; int step; int* refcount; union {uchar* ptr;short* s;int* i;float* fl;double* db;} data; union {int rows;int height;};union {int cols; int width;};} CvMat;
Create cvmat data:
View
Code
CvMat * cvCreateMat(int rows, int cols, int type); CV_INLine CvMat cvMat((int rows, int cols, int type, void* data CV_DEFAULT); CvMat * cvInitMatHeader(CvMat * mat, int rows, int cols, int type, void * data CV_DEFAULT(NULL), int step CV_DEFAULT(CV_AUTOSTEP));
Access Matrix data:
Cvmset (cvmat * mat, int row, int Col, double value); cvmget (const cvmat * mat, int row, int col); cvscalar cvget2d (const cvarr * arr, int idx0, int idx1); // cvarr is used only as the function parameter void cvset2d (cvarr * arr, int idx0, int idx1, cvscalar value );
CvMat * cvmat = cvCreateMat(4, 4, CV_32FC1);cvmat->data.fl[row * cvmat->cols + col] = (float)3.0;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;
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 is the channel value 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 is the channel Value
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; }}CvMat * vector = cvCreateMat(1,3, CV_32SC2);CV_MAT_ELEM(*vector, CvPoint, 0, 0) = cvPoint(100,100);CvMat * vector = cvCreateMat(1,3, CV_64FC4);CV_MAT_ELEM(*vector, CvScalar, 0, 0) = CvScalar(0, 0, 0, 0);
Cvmat * m1 = cvcreatemat (4,4, cv_32fc1 );
Cvmat * m2;
M2 = cvclonemat (M1 );
3. Mat
MAT is a new data structure for image processing launched by opencv2.0. Now it is becoming more and more popular to replace the previous cvmat and lplimage. The biggest advantage of mat is that it can facilitate memory management, programmers no longer need to manually manage the release of memory. As mentioned in opencv2.3, mat is a multi-dimensional dense data array that can be used to process common multi-dimensional data such as vectors and matrices, images, and histograms.
Class cv_exports mat {public: int flags; (Note: currently, we do not know what flags is used for.) int dims; int rows, cols; uchar * data; int * refcount ;...};
From the above structure, we can see that mat is also a matrix header. By default, no memory is allocated, but it only points to a piece of memory (pay attention to read/write protection ). Use the create function or mat constructor for initialization. The following code is compiled from opencv2.3.1 manual:
Mat(nrows, ncols, type, fillValue]); M.create(nrows, ncols, type);
Example: mat M (100, cv_32fc2, scalar (); M. Create (, 60, cv_8uc (15 ));
int sz[] = {100, 100, 100}; Mat bigCube(3, sz, CV_8U, Scalar:all(0));
double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}};Mat M = Mat(3, 3, CV_64F, m).inv();
Mat img(Size(320,240),CV_8UC3); Mat img(height, width, CV_8UC3, pixels, step);
IplImage* img = cvLoadImage("greatwave.jpg", 1);Mat mtx(img,0); // convert IplImage* -> Mat;
Data elements accessing mat:
Mat M;M.row(3) = M.row(3) + M.row(5) * 3; Mat M1 = M.col(1);M.col(7).copyTo(M1); Mat M;M.at<double>(i,j); M.at(uchar)(i,j); Vec3i bgr1 = M.at(Vec3b)(i,j) Vec3s bgr2 = M.at(Vec3s)(i,j) Vec3w bgr3 = M.at(Vec3w)(i,j) double sum = 0.0f;for(int row = 0; row < M.rows; row++){ constdouble * Mi = M.ptr<double>(row); for (int col = 0; col < M.cols; col++) sum += std::max(Mi[j], 0.);}double sum=0;MatConstIterator<double> it = M.begin<double>(), it_end = M.end<double>();for(; it != it_end; ++it) sum += std::max(*it, 0.);
Mat can perform matrix operations in the MATLAB style. For example, initializers, zeros (), ones (), and eye () can be used during initialization (). in addition to the preceding content, mat has three important methods: View
Code
Mat MAT = imread (const string * filename); // read the image imshow (conststring framename, inputarray mat); // display the image imwrite (conststring & filename, inputarray IMG ); // store images
4. Mutual conversion between cvmat, mat, and iplimage
IpIImage -> CvMatCvMat matheader;CvMat * mat = cvGetMat(img, &matheader);CvMat * mat = cvCreateMat(img->height, img->width, CV_64FC3);cvConvert(img, mat)
Iplimage-> matmat: MAT (const iplimage * IMG, bool copydata = false); example: iplimage * iplimg = cvloadimage ("greatwave.jpg", 1); MAT (iplimg );
Mat -> IplImageMat MIplImage iplimage = M;
CvMat -> MatMat::Mat(const CvMat* m, bool copyData=false);
Mat-> cvmat example (assuming that mat-type imgmat image data exists): cvmat = imgmat;/* mat-> cvmat, similar to converting to iplimage, only create matrix headers without copying data