Relationship and mutual conversion between IplImage, CvMat, and Mat)

Source: Internet
Author: User
Tags scalar

(I see a very good article about the relationship between opencv internal classes .)

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:

View Code
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 and yOffset are x and y coordinates, coi indicates the channel of interest (channel of interest), which is valid only when the value is 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 *):

View Code

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 cvCreateImage
For (int row = 0; row height; row ++)
{
For (int col = 0; col 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 height; row ++)
{
For (int col = 0; col 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:

View Code
IplImage * cvLoadImage (const char * filename, int iscolor CV_DEFAULT (CV_LOAD_IMAGE_COLOR); // 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:

View Code
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:

View Code


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 indicates 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 (100,100, CV_32SC2); CV_MAT_ELEM (* vector, CvPoint, 0, 0) = cvPoint );

CvMat * vector = cvCreateMat (1, 3, CV_64FC4); CV_MAT_ELEM (* vector, CvScalar, 0, 0) = CvScalar (0, 0, 0, 0 );

Copy matrix operation:

View Code

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.

View Code
Class CV_EXPORTS Mat
{

Public:




Int flags; (Note: currently, I do not know what flags are used)
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:

View Code
Mat (nrows, ncols, type, fillValue]);
M. create (nrows, ncols, type );

Example:
Mat M (7, 7, CV_32FC2, Scalar (1, 3 ));
M. create (100, 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 CTX (img, 0); // convert IplImage *-> Mat;

Data elements accessing Mat:

View Code

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 ++)

Const double * 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 (const string frameName, InputArray mat); // display the image
Imwrite (const string & filename, InputArray img); // save the image

 

4. Mutual conversion between CvMat, Mat, and IplImage

View Code
IpIImage-> CvMat

CvMat matheader;
CvMat * mat = cvGetMat (img, & matheader );

CvMat * mat = cvCreateMat (img-> height, img-> width, CV_64FC3 );
CvConvert (img, mat)


IplImage-> Mat
Mat: Mat (const IplImage * img, bool copyData = false );
Example:
IplImage * iplImg = cvLoadImage ("greatwave.jpg", 1 );
Mat CTX (iplImg );

 

Mat-> IplImage
Mat M
IplImage iplimage = M;

CvMat-> Mat
Mat: Mat (const CvMat * m, bool copyData = false );

Mat-> CvMat
Example (assuming Mat-type imgMat image data exists ):
CvMat cvMat = imgMat;/* Mat-> CvMat, similar to converting to IplImage, only create matrix headers without copying data
------------------------------------------------------------------- I. MatType: Matrix type, Matrix.

In openCV, Mat is a multi-dimensional dense data array. It can be used to process common multidimensional data such as vectors and matrices, images, and histograms.

Mat has three important methods:

1. Mat mat = imread (const String * filename); read the image

2. imshow (const string frameName, InputArray mat); displays the image

3. imwrite (const string & filename, InputArray img); save the image

Compared with the CvMat and IplImage types, the Mat type has stronger matrix computing capabilities and supports common matrix operations. In computing-intensive applications, converting the CvMat and IplImage types to the Mat type greatly reduces the computing time.

A. Mat-> IplImage

Create an image header without copying data.

Example: // assume that the Mat-type imgMat image data exists.

IplImage pImg = IplImage (imgMat );

B. Mat-> CvMat

Similar to IplImage conversion, only matrix headers are created without copying data.

Example: // assume that the Mat-type imgMat image data exists.

CvMat cvMat = imgMat;

 

II,CvMat type and IplImage type: "Image" type

In openCV, both the Mat type and CvMat and IplImage type can represent and display images. However, the Mat type focuses on computing and has a high mathematics, openCV also optimizes the calculation of the Mat type. The CvMat and IplImage types focus more on "images". openCV optimizes image operations (such as scaling, single-channel extraction, and image threshold operations.

Supplement:IplImage is derived from CvMat, while CvMat is derived from CvArr-> CvMat-> IplImage

CvArr is used as a function parameter. CvMat is used internally, regardless of whether CvMat or IplImage is passed in.

1. CvMat

A. CvMat-> IplImage

IplImage * img = cvCreateImage (cvGetSize (mat), 8, 1 );
CvGetImage (matI, img );

CvSaveImage ("rice1.bmp", img );

B. CvMat-> Mat

Similar to IplImage conversion, you can choose whether to copy data.

Mat: Mat (const CvMat * m, bool copyData = false );

In openCV, there is no vector data structure. We can use matrix data to represent vectors at any time.

However, the CvMat type is more abstract than the vector concept we learned in the linear algebra course. For example, the element data type of CvMat is not limited to the basic data type. For example, create a two-dimensional data matrix below:

CvMat * cvCreatMat (int rows, int cols, int type );

The type here can be any predefined data type, such as RGB or other multi-channel data. In this way, we can represent a variety of images on a CvMat matrix.

 

2. IplImage

In terms of type relationship, we can say that the IplImage type inherits from the CvMat type, and other variables include parsing it into image data.

The IplImage type has many more parameters than CvMat, such as depth and nChannels. In normal matrix types, the depth and number of channels are usually expressed at the same time, for example, 32-bit representation of RGB + Alpha. however, in image processing, we often separate the depth from the number of channels, which is an optimization solution for image representation by OpenCV.

Another optimization of IplImage for images is the variable origin-origin. In computer vision processing, the most important thing is that the definition of the origin is unclear. Image sources, encoding formats, and even the operating system will affect the selection of the original location. To make up for this, openCV allows users to define their own origin settings. The value 0 indicates that the origin is in the upper left corner of the image, and 1 indicates the lower left corner.

The dataOrder parameter defines the data format. There are two values: IPL_DATA_ORDER_PIXEL and IPL_DATA_ORDER_PLANE. The former is the cross-arrangement of data of different channels for pixels, and the latter indicates that all channels are arranged in parallel in order.

All additional variables of the IplImage type are optimized for the representation and computing capability of "images.

A. IplImage-> Mat

IplImage * pImg = cvLoadImage ("lena.jpg ");
Mat img (pImg, 0); // 0 is a non-invasive image, that is, the data of pImg and img share the same location of the memory, and each header has
B. IplImage-> CvMat

Method 1: CvMat mathdr, * mat = cvGetMat (img, & mathdr );

Method 2: CvMat * mat = cvCreateMat (img-> height, img-> width, CV_64FC3 );
CvConvert (img, mat );

C. IplImage *-> BYTE *

BYTE * data = img-> imageData;

 

There is a small difference between CvMat and IplImage:

1. When creating a matrix, the first parameter is the number of rows, and the second parameter is the number of columns.

CvMat * cvCreateMat (int rows, int cols, int type );

2. When an image is created, the first parameter of CvSize is width, that is, the number of columns, and the second parameter is height, that is, the number of rows. This is the opposite of the CvMat matrix.

IplImage * cvCreateImage (CvSize size, int depth, int channels );

CvSize cvSize (int width, int height );

 

Each buffer row in IplImage is 4-byte aligned. CvMat does not have this limit.

 

Supplement:

A. BYTE *-> IplImage *

Img = cvCreateImageHeader (cvSize (width, height), depth, channels );

CvSetData (img, data, step );

// Create an IplImage Image header with cvCreateImageHeader () to specify the size, depth, and number of channels of the image;

// Then, cvSetData () sets the IplImage Image Header data based on the BYTE * image data pointer,

// Step specifies the number of bytes occupied by each line of the IplImage Image. For an IPL_DEPTH_8U image of Channel 1, step can be equal to width.

Relationship and mutual conversion between IplImage, CvMat, and Mat)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.