OpenCV 矩陣元素的資料型別
轉: https://www.jianshu.com/p/204f292937bb
在以下兩個場景中使用 OpenCV 時,我們必須事先知道矩陣元素的資料型別:
- 使用
at
方法訪問資料元素的時候要指明資料型別 - 做數值運算的時候,比如究竟是整數除法還是浮點數除法。
但面對一大堆程式碼,我們有時並不清楚當前的矩陣元素究竟是什麼型別,這篇文章就是以 cv::Mat
類為例來解決這個問題。
cv::Mat 類的物件有一個成員函式 type()
用來返回矩陣元素的資料型別,返回值是 int
型別,不同的返回值代表不同的型別。OpenCV Reference Manual 中對 type()
Mat::type
C++: int Mat::type() const
The method returns a matrix element type. This is an identifier compatible with the CvMat type system, like CV_16SC3 or 16-bit signed 3-channel array, and so on.
實際的程式碼如下所示:
cv::Mat haha = cv::Mat::zeros(3,3,CV_64F); int hahaType = haha.type(); std::cout<<"hahaType = "<<hahaType<<std::endl;
至此,知道了 type()
函式,下一步更關鍵的就是返回值和具體型別之間的對應關係了。文章《[LIST OF MAT TYPE IN OPENCV][LIST OF MAT TYPE IN OPENCV]》對此整理得非常清楚,具體如下表所示:
C1 | C2 | C3 | C4 | |
---|---|---|---|---|
CV_8U | 0 | 8 | 16 | 24 |
CV_8S | 1 | 9 | 17 | 25 |
CV_16U | 2 | 10 | 18 | 26 |
CV_16S | 3 | 11 | 19 | 27 |
CV_32S | 4 | 12 | 20 | 28 |
CV_32F | 5 | 13 | 21 | 29 |
CV_64F | 6 | 14 | 22 | 30 |
表頭的 C1, C2, C3, C4 指的是通道(Channel)數,比如灰度影象只有 1 個通道,是 C1;JPEG格式 的 RGB 彩色影象就是 3 個通道,是 C3;PNG 格式的彩色影象除了 RGB 3個通道外,還有一個透明度通道,所以是 C4。大家還會發現 7 怎麼沒有被定義型別,這個可以看 OpenCV 原始碼,有如下所示的一行,說明 7 是用來給使用者自定義的:
#define CV_USRTYPE1 7
如果僅僅是為了在數值計算前明確資料型別,那麼看到這裡就可以了;如果是要使用 at
方法訪問資料元素,那麼還需要下面一步。因為以單通道為例,at
方法接受的是 uchar
這樣的資料型別,而非 CV_8U
。在已知通道數和每個通道資料型別的情況下,指定給 at
方法的資料型別如下表所示:
C1 | C2 | C3 | C4 | C6 | |
---|---|---|---|---|---|
uchar | uchar |
cv::Vec2b |
cv::Vec3b |
cv::Vec4b |
|
short | short |
cv::Vec2s |
cv::Vec3s |
cv::Vec4s |
|
int | int |
cv::Vec2i |
cv::Vec3i |
cv::Vec4i |
|
float | float |
cv::Vec2f |
cv::Vec3f |
cv::Vec4f |
cv::Vec6f |
double | double |
cv::Vec2d |
cv::Vec3d |
cv::Vec4d |
cv::Vec6d |
至此,我們就可以像《OpenCV for Matlab Users (2)》中演示的一樣採用如下方式訪問影象(矩陣)了
cv::Vec3b vec3b = img.at<cv::Vec3b>(0,0);
uchar vec3b0 = img.at<cv::Vec3b>(0,0)[0];
uchar vec3b1 = img.at<cv::Vec3b>(0,0)[1];
uchar vec3b2 = img.at<cv::Vec3b>(0,0)[2];
std::cout<<"vec3b = "<<vec3b<<std::endl;
std::cout<<"vec3b0 = "<<(int)vec3b0<<std::endl;
std::cout<<"vec3b1 = "<<(int)vec3b1<<std::endl;
std::cout<<"vec3b2 = "<<(int)vec3b2<<std::endl;
初寫於 2015-04-30.
首發於 Yimian Dai's Homepage,轉載請註明出處。
參考資料
- [LIST OF MAT TYPE IN OPENCV][LIST OF MAT TYPE IN OPENCV]
附錄
資料型別及其取值範圍
數值 | 具體型別 | 取值範圍 |
---|---|---|
CV_8U | 8 位無符號整數 | (0…..255) |
CV_8S | 8 位符號整數 | (-128…..127) |
CV_16U | 16 位無符號整數 | (0……65535) |
CV_16S | 16 位符號整數 | (-32768…..32767) |
CV_32S | 32 位符號整數 | (-2147483648……2147483647) |
CV_32F | 32 位浮點數 | (-FLT_MAX ………FLT_MAX,INF,NAN) |
CV_64F | 64 位浮點數 | (-DBL_MAX ……….DBL_MAX,INF,NAN) |
Vec 類的定義
template<typename _Tp, int n> class Vec : public Matx<_Tp, n, 1> {...};
typedef Vec<uchar, 2> Vec2b;
typedef Vec<uchar, 3> Vec3b;
typedef Vec<uchar, 4> Vec4b;
typedef Vec<short, 2> Vec2s;
typedef Vec<short, 3> Vec3s;
typedef Vec<short, 4> Vec4s;
typedef Vec<int, 2> Vec2i;
typedef Vec<int, 3> Vec3i;
typedef Vec<int, 4> Vec4i;
typedef Vec<float, 2> Vec2f;
typedef Vec<float, 3> Vec3f;
typedef Vec<float, 4> Vec4f;
typedef Vec<float, 6> Vec6f;
typedef Vec<double, 2> Vec2d;
typedef Vec<double, 3> Vec3d;
typedef Vec<double, 4> Vec4d;
typedef Vec<double, 6> Vec6d;
[LIST OF MAT TYPE IN OPENCV]: http://ninghang.blogspot.jp/2012/11/list-of-mat-type-in-opencv.html
作者:YimianDai
連結:https://www.jianshu.com/p/204f292937bb
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。