C++ - cv::Mat data type + extract some rows or columns

brief introduction

1. cv::Mat data type

2. cv::Mat extracts some rows or columns

cv::Mat data type

When using OpenCV in the following two scenarios, we must know the data type of matrix elements in advance:

1. When using the at method to access data elements, you should specify the data type

2. When doing numerical operations, such as integer division or floating-point division.

The object of cv::Mat class has a member function type() to return the data type of matrix elements. The return value is int type. Different return values represent different types. The specific correspondence is as follows:

C1, C2, C3 and C4 in the header refer to the number of channels, for example:

1. Gray image has only one channel, which is C1;

2. The RGB color image in JPEG format has three channels, C3

3. PNG color image has a transparency channel in addition to three RGB channels, so it is C4.

If it's just to clarify the data type before numerical calculation, you can see here

If you want to use the at method to access data elements, you need to take the next step

Because taking a single channel as an example, the at method accepts data types such as uchar rather than CV_8U.

When the number of channels and the data type of each channel are known, the data types assigned to the at method are as follows:

Now you can use at to access the pixels of the image:

1 cv::Vec3b vec3b = img.at<cv::Vec3b>(0,0);
2 uchar vec3b0 = img.at<cv::Vec3b>(0,0)[0];
3 uchar vec3b1 = img.at<cv::Vec3b>(0,0)[1];
4 uchar vec3b2 = img.at<cv::Vec3b>(0,0)[2];
5 std::cout<<"vec3b = "<<vec3b<<std::endl;
6 std::cout<<"vec3b0 = "<<(int)vec3b0<<std::endl;
7 std::cout<<"vec3b1 = "<<(int)vec3b1<<std::endl;
8 std::cout<<"vec3b2 = "<<(int)vec3b2<<std::endl;

The above data types and value ranges

Definition of Vec class

 1 template<typename _Tp, int n> class Vec : public Matx<_Tp, n, 1> {...};
 2 
 3 typedef Vec<uchar, 2> Vec2b;
 4 typedef Vec<uchar, 3> Vec3b;
 5 typedef Vec<uchar, 4> Vec4b;
 6 
 7 typedef Vec<short, 2> Vec2s;
 8 typedef Vec<short, 3> Vec3s;
 9 typedef Vec<short, 4> Vec4s;
10 
11 typedef Vec<int, 2> Vec2i;
12 typedef Vec<int, 3> Vec3i;
13 typedef Vec<int, 4> Vec4i;
14 
15 typedef Vec<float, 2> Vec2f;
16 typedef Vec<float, 3> Vec3f;
17 typedef Vec<float, 4> Vec4f;
18 typedef Vec<float, 6> Vec6f;
19 
20 typedef Vec<double, 2> Vec2d;
21 typedef Vec<double, 3> Vec3d;
22 
23 typedef Vec<double, 4> Vec4d;
24 typedef Vec<double, 6> Vec6d;

 

cv::Mat extracts some rows or columns

Mat::rowRange

Creates a matrix header for the specified row span.

C++:  Mat  Mat:: rowRange (int  startrow, int  endrow )  const
C++:  Mat  Mat:: rowRange (const Range&  r )  const

Parameters:    
startrow – An inclusive 0-based start index of the row span.
endrow – An exclusive 0-based ending index of the row span.
r – Range structure containing both the start and the end indices.

The method makes a new header for the specified row span of the matrix. Similarly to Mat::row() and Mat::col() , this is an O(1) operation.

Mat::colRange

Creates a matrix header for the specified column span.

C++:  Mat  Mat:: colRange (int  startcol, int  endcol )  const
C++:  Mat  Mat:: colRange (const Range&  r )  const
Parameters:    
startcol – An inclusive 0-based start index of the column span.
endcol – An exclusive 0-based ending index of the column span.
r – Range structure containing both the start and the end indices.

The method makes a new header for the specified column span of the matrix. Similarly to Mat::row() and Mat::col() , this is an O(1) operation.

Since these two functions return pointers to the internal position of the original matrix, it is better to use the clone() function to copy the data and create a new matrix. The code is as follows:

 1 #include <opencv2/core/core.hpp>  
 2 #include <opencv2/highgui/highgui.hpp>  
 3 #include <iostream>  
 4   
 5 using namespace cv;  
 6 using namespace std;  
 7   
 8 int main(){  
 9      Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);  
10      cout << "Total matrix:" << endl;  
11      cout << C << endl;  
12   
13      Mat row = C.rowRange(1,3).clone();  
14      cout << "Row range:" << endl;  
15      cout << row << endl;  
16       
17      Mat col = C.colRange(1,3).clone();  
18      cout << "Col range:" << endl;  
19      cout << col << endl;  
20 }
The results are as follows:
Total matrix
[0, -1, 0;
  -1, 5, -1;
  0, -1, 0]
Row range:
[-1, 5, -1;
  0, -1, 0]
Col range:
[-1, 0;
  5, -1;
  -1, 0]

These two functions are very interesting. Instead of calling opencv specific functions to realize the corresponding functions, I can write functions to realize any image functions I need

 

Posted by pplexr on Sat, 07 May 2022 05:39:15 +0300