Opencv CvMat matrix Learning

Source: Internet
Author: User

Follow: http://manxh.com/

1. Initialization matrix:

Method 1: point-by-point assignment:

Cvmat * MAT = cvcreatemat (2, 2, cv_64fc1 );
Cvzero (MAT );
Cvmset (MAT, 0, 0, 1 );
Cvmset (MAT, 0, 1, 2 );
Cvmset (MAT, 1, 0, 3 );
Cvmset (MAT, 2, 2, 4 );
Cvreleasemat (& mat );

Method 2: connect existing arrays:

Double A [] = {1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12 };
Cvmat MAT = cvmat (3, 4, cv_64fc1, a); // 64fc1 for double
// Cvreleasemat is not required because the data memory allocation is performed by arrays defined by double.

2. Conversion from iplimage to cvmat

Method 1: cvgetmat:
Cvmat mathdr, * MAT = cvgetmat (IMG, & mathdr );

Method 2: cvconvert:
Cvmat * MAT = cvcreatemat (IMG-> height, IMG-> width, cv_64fc3 );
Cvconvert (IMG, mat );
// # Define cvConvert (src, dst) cvConvertScale (src), (dst), 1, 0)

3. Conversion of cvArr (IplImage or cvMat) to cvMat
Method 1: cvGetMat:
Int coi = 0;
CvMat * mat = (CvMat *) arr;
If (! CV_IS_MAT (mat ))
{
Mat = cvGetMat (mat, & matstub, & coi );
If (coi! = 0) reutn; // CV_ERROR_FROM_CODE (CV_BadCOI );
}
Written as a function:
// This is just an example of function
// To support both IplImage and cvMat as an input
CVAPI (void) cvIamArr (const CvArr * arr)
{
CV_FUNCNAME ("cvIamArr ");
_ BEGIN __;
CV_ASSERT (mat = NULL );
CvMat matstub, * mat = (CvMat *) arr;
Int coi = 0;
If (! CV_IS_MAT (mat ))
{
CV_CALL (mat = cvGetMat (mat, & matstub, & coi ));
If (COI! = 0) cv_error_from_code (cv_badcoi );
}
// Process as cvmat
_ End __;
}

4. Direct image operations
Method 1: directly operate int Col, row, Z in an array;
Uchar B, G, R;
For (y = 0; row height; y ++)
{
For (COL = 0; Col width; Col ++)
{
B = IMG-> imagedata [img-> widthstep * row + Col * 3]
G = IMG-> imagedata [img-> widthstep * row + Col * 3 + 1];
R = IMG-> imagedata [img-> widthstep * row + Col * 3 + 2];
}
}
Method 2: Macro operation:
Int row, Col;
Uchar B, G, R;
For (ROW = 0; row height; row ++)
{
For (COL = 0; Col width; Col ++)
{
B = cv_image_elem (IMG, uchar, row, Col * 3 );
G = cv_image_elem (IMG, uchar, row, Col * 3 + 1 );
R = cv_image_elem (IMG, uchar, row, Col * 3 + 2 );
}
}
Note: cv_image_elem (IMG, uchar, row, Col * IMG-> nchannels + CH)

5. Direct cvmat operations
The direct operation of arrays is depressing because it depends on the Data Type of arrays.

For cv_32fc1 (1 channel float ):
Cvmat * m = cvcreatemat (4, 4, cv_32fc1 );
M-> data. Fl [row * m-> Cols + Col] = (float) 3.0;

For cv_64fc1 (1 channel double ):
Cvmat * m = cvcreatemat (4, 4, cv_64fc1 );
M-> data. DB [row * m-> Cols + Col] = 3.0;

Generally, for arrays of Channel 1:
Cvmat * m = cvcreatemat (4, 4, cv_64fc1 );
Cv_mat_elem (* m, double, row, col) = 3.0;
Note that the double type must be input based on the data type of the array. This macro cannot do anything about multi-channel.

For multi-channel:
Let's take a look at the definition of this macro: # define cv_mat_elem_cn (MAT, elemtype, row, col )/
(* (Elemtype *) (MAT). Data. PTR + (size_t) (MAT). Step * (ROW) + sizeof (elemtype) * (COL )))
If (cv_mat_depth (m-> type) = cv_32f)
Cv_mat_elem_cn (* m, float, row, Col * cv_mat_cn (m-> type) + CH) = 3.0;
If (cv_mat_depth (m-> type) = cv_64f)
Cv_mat_elem_cn (* m, double, row, Col * cv_mat_cn (m-> type) + CH) = 3.0;
The optimization method is as follows:
# Define cv_8u 0
# Define cv_8s 1
# Define cv_16u 2
# Define cv_16s 3
# Define cv_32s 4
# Define cv_32f 5
# Define cv_64f 6
# Define cv_usrtype1 7

Int elem_size = cv_elem_size (mat-> type );
For (COL = start_col; Col <end_col; Col ++ ){
For (ROW = 0; row <mat-> rows; row ++ ){
For (ELEM = 0; ELEM <elem_size; ELEM ++ ){
(Mat-> data. ptr + (size_t) mat-> step * row) + (elem_size * col) [elem] =
(Submat-> data. ptr + (size_t) submat-> step * row) + (elem_size * (col-start_col) [elem];
}
}
}

The following operations are recommended for multi-channel Arrays:
For (row = 0; row <mat-> rows; row ++)
{
P = mat-> data. fl + row * (mat-> step/4 );

For (col = 0; col <mat-> cols; col ++)
{
* P = (float) row + col;
* (P + 1) = (float) row + col + 1;
* (P + 2) = (float) row + col + 2;
P + = 3;
}
}
For two or four channels:
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 );

6. indirect access to cvmat
Cvmget/set is the easiest way to access the cv_32fc1 and cv_64fc1 arrays. Its access speed is almost the same as direct access speed.
Cvmset (MAT, row, Col, value );
Cvmget (MAT, row, col );
Example: print an array
Inline void cvdoublematprint (const cvmat * mat)
{
Int I, J;
For (I = 0; I <mat-> rows; I ++)
{
For (j = 0; j <mat-> Cols; j ++)
{
Printf ("% F", cvmget (MAT, I, j ));
}
Printf ("/N ");
}
}

Cvget/set2d is a good choice for other data types, such as those with multiple channels.
Cvscalar scalar = cvget2d (MAT, row, col );
Cvset2d (MAT, row, Col, cvscalar (R, G, B ));

Note: The data cannot be int, because cvget2d obtains the double type in essence.
For example, print a multi-channel matrix:
Inline void cv3doublematprint (const cvmat * mat)
{
Int I, J;
For (I = 0; I <mat-> rows; I ++)
{
For (j = 0; j <mat-> Cols; j ++)
{
Cvscalar scal = cvget2d (MAT, I, j );
Printf ("(% F, % F, % F)", Scal. Val [0], Scal. Val [1], Scal. Val [2]);
}
Printf ("/N ");
}
}

7. Modify the matrix shape-cvreshape operation
Experiments show that the sequence of matrix operations is: first meet the channel, then meet the column, and finally meet the row.
Note: This is different from MATLAB. MATLAB is the sequence of rows, columns, and channels.
Here is an example:
For one channel:
// 1 channel
Cvmat * mat, mathdr;
Double data [] = {11, 12, 13, 14,
21, 22, 23, 24,
31, 32, 33, 34 };
Cvmat * orig = & cvmat (3, 4, cv_64fc1, data );
// 11 12 13 14
// 21 22 23 24
// 31 32 33 34
MAT = cvreshape (orig, & mathdr, 1, 1); // new_ch, new_rows
Cvdoublematprint (MAT); // above
// 11 12 13 14 21 22 23 24 31 32 33 34
MAT = cvreshape (MAT, & mathdr, 1, 3); // new_ch, new_rows
Cvdoublematprint (MAT); // above
// 11 12 13 14
// 21 22 23 24
// 31 32 33 34
MAT = cvreshape (orig, & mathdr, 1, 12); // new_ch, new_rows
Cvdoublematprint (MAT); // above
// 11
// 12
// 13
// 14
// 21
// 22
// 23
// 24
// 31
// 32
// 33
// 34
MAT = cvreshape (MAT, & mathdr, 1, 3); // new_ch, new_rows
Cvdoublematprint (MAT); // above
// 11 12 13 14
// 21 22 23 24
// 31 32 33 34
MAT = cvreshape (orig, & mathdr, 1, 2); // new_ch, new_rows
Cvdoublematprint (MAT); // above
// 11 12 13 14 21 22
// 23 24 31 32 33 34
MAT = cvreshape (MAT, & mathdr, 1, 3); // new_ch, new_rows
Cvdoublematprint (MAT); // above
// 11 12 13 14
// 21 22 23 24
// 31 32 33 34
MAT = cvreshape (orig, & mathdr, 1, 6); // new_ch, new_rows
Cvdoublematprint (MAT); // above
// 11 12
// 13 14
// 21 22
// 23 24
// 31 32
// 33 34
MAT = cvreshape (MAT, & mathdr, 1, 3); // new_ch, new_rows
Cvdoublematprint (MAT); // above
// 11 12 13 14
// 21 22 23 24
// 31 32 33 34
// Use cvtranspose and cvreshape (MAT, & mathdr, 1, 2) to get
// 11 23
// 12 24
// 13 31
// 14 32
// 21 33
// 22 34
// Use cvtranspose again when to recover

For three channels
// 3 channels
Cvmat mathdr, * MAT;
Double data [] ={ 111,112,113,121,122,123,
211,212,213,221,222,223 };
Cvmat * orig = & cvmat (2, 2, cv_64fc3, data );
// (111,112,113) (121,122,123)
// (211,212,213) (221,222,223)
MAT = cvreshape (orig, & mathdr, 3, 1); // new_ch, new_rows
Cv3doublematprint (MAT); // above
// (111,112,113) (121,122,123) (211,212,213) (221,222,223)
// Concatinate in column first order
MAT = cvreshape (orig, & mathdr, 1, 1); // new_ch, new_rows
Cvdoublematprint (MAT); // above
// 111 112 113 121 122 123 211 212 213 221 222 223
// Concatinate in channel first, column second, row third
MAT = cvreshape (orig, & mathdr, 1, 3); // new_ch, new_rows
Cvdoublematprint (MAT); // above
// 111 112 113 121
// 122 123 211 212
// 213 221 222 223
// Channel first, column second, row third
MAT = cvreshape (orig, & mathdr, 1, 4); // new_ch, new_rows
Cvdoublematprint (MAT); // above
// 111 112 113
// 121 122 123
// 211 212 213
// 221 222 223
// Channel first, column second, row third
// Memorize this transform because this is useful
// Add (or do something) Color Channels
Cvmat * mat2 = cvcreatemat (mat-> cols, mat-> rows, mat-> type );
Cvtranspose (MAT, mat2 );
Cvdoublematprint (mat2); // above
// 111 121 211 221
// 112 122 212 222
// 113 123 213 223
Cvreleasemat (& mat2 );

8. Calculate the color distance
We want to calculate the distance between each pixel of img1 and img2, expressed in DIST, as defined below
Iplimage * img1 = cvcreateimage (cvsize (W, h), ipl_depth_8u, 3 );
Iplimage * img2 = cvcreateimage (cvsize (W, h), ipl_depth_8u, 3 );
Cvmat * Dist = cvcreatemat (H, W, cv_64fc1 );
The stupid idea is: cvsplit-> cvsub-> cvmul-> cvadd
The Code is as follows:
Iplimage * img1b = cvcreateimage (cvgetsize (img1), img1-> depth, 1 );
IplImage * img1G = cvCreateImage (cvGetSize (img1), img1-> depth, 1 );
IplImage * img1R = cvCreateImage (cvGetSize (img1), img1-> depth, 1 );
IplImage * img2B = cvCreateImage (cvGetSize (img1), img1-> depth, 1 );
IplImage * img2G = cvCreateImage (cvGetSize (img1), img1-> depth, 1 );
IplImage * img2R = cvCreateImage (cvGetSize (img1), img1-> depth, 1 );
IplImage * diff = cvCreateImage (cvGetSize (img1), IPL_DEPTH_64F, 1 );
CvSplit (img1, img1B, img1G, img1R );
CvSplit (img2, img2B, img2G, img2R );
CvSub (img1B, img2B, diff );
CvMul (diff, diff, dist );
CvSub (img1G, img2G, diff );
CvMul (diff, diff, diff );
CvAdd (diff, dist, dist );
CvSub (img1R, img2R, diff );
CvMul (diff, diff, diff );
CvAdd (diff, dist, dist );
Cvreleaseimage (& img1b );
Cvreleaseimage (& img1g );
Cvreleaseimage (& img1r );
Cvreleaseimage (& img2b );
Cvreleaseimage (& img2g );
Cvreleaseimage (& img2r );
Cvreleaseimage (& diff );

The clever idea is:
Int d = img1-> nchannels; // D: number of colors (dimension)
Int n = img1-> width * img1-> height; // n: number of pixels
Cvmat mat1hdr, * mat1 = cvreshape (img1, & mat1hdr, 1, n); // n x D (colors)
Cvmat mat2hdr, * mat2 = cvreshape (img2, & mat2hdr, 1, n); // n x D (colors)
Cvmat diffhdr, * diff = cvcreatemat (n, D, cv_64fc1); // n x D, temporal buff
Cvsub (mat1, mat2, diff );
Cvmul (diff, diff, diff );
Dist = cvreshape (Dist, & disthdr, 1, n); // nrow x ncol to n X 1
Cvreduce (diff, DIST, 1, cv_reduce_sum); // n x D to n X 1
Dist = cvreshape (Dist, & disthdr, 1, img1-> height); // restore N x 1 to nrow x ncol
Cvreleasemat (& diff );

Follow: http://manxh.com/

 

# Pragma comment (Lib, "cxcore. lib ")
# Include "cv. H"
# Include <stdio. h>
Int main ()
{
Cvmat * MAT = cvcreatemat (3, 3, cv_32fc1 );
Cvzero (MAT); // sets the Matrix to 0.
// Assign values to Matrix Elements
Cv_mat_elem (* mat, float, 0, 0) = 1.f;
Cv_mat_elem (* mat, float, 0, 1) = 2.f;
Cv_mat_elem (* mat, float, 0, 2) = 3.f;
Cv_mat_elem (* mat, float, 1, 0) = 4.f;
Cv_mat_elem (* mat, float, 1, 1) = 5.f;
Cv_mat_elem (* mat, float, 1, 2) = 6.f;
Cv_mat_elem (* mat, float, 2, 0) = 7.f;
CV_MAT_ELEM (* mat, float, 2, 1) = 8.f;
CV_MAT_ELEM (* mat, float, 2, 2) = 9.f;
// Obtain the value of the matrix element ()
Float * p = (float *) cvPtr2D (mat, 0, 2 );
Printf ("% f/n", * p );
Return 0;
}

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.