1. 程式人生 > 其它 >C++ - cv::Mat資料型別 + 提取某些行或列

C++ - cv::Mat資料型別 + 提取某些行或列

簡介

1、cv::Mat 資料型別

2、cv::Mat 提取某些行或列

cv::Mat 資料型別

在以下兩個場景中使用OpenCV時,我們必須事先知道矩陣元素的資料型別:

1、使用 at 方法訪問資料元素的時候要指明資料型別

2、做數值運算的時候,比如究竟是整數除法還是浮點數除法。

cv::Mat 類的物件有一個成員函式type()用來返回矩陣元素的資料型別,返回值是 int 型別,不同的返回值代表不同的型別,具體對應關係如下所示:

 表頭的 C1, C2, C3, C4 指的是通道(Channel)數,例如:

1、灰度影象只有 1 個通道,是 C1;

2、JPEG格式 的 RGB 彩色影象就是 3 個通道,是 C3

3、PNG 格式的彩色影象除了 RGB 3個通道外,還有一個透明度通道,所以是 C4。

如果僅僅是為了在數值計算前明確資料型別,那麼看到這裡就可以了

如果是要使用 at 方法訪問資料元素,那麼還需要下面一步

因為以單通道為例,at 方法接受的是 uchar 這樣的資料型別,而非 CV_8U。

在已知通道數和每個通道資料型別的情況下,指定給 at 方法的資料型別如下表所示:

 現在,就可以使用at來訪問影象的畫素了:

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;

上述資料型別以及取值範圍

Vec類的定義

 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 提取某些行或列

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.

由於這兩個函式返回的是指向原矩陣內部位置的指標,所以最好再利用clone()函式進行資料拷貝建立新的矩陣,程式碼如下:

 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 }
結果如下:
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]

這兩個函式很有趣,它們讓我實現不用呼叫opencv特有函式來實現相應功能,而是自己可以寫函式隨機應變地實現自己所需的任何影象方面功能