Mat数据类型与访问

Mat数据类型与访问

1.opencv数据类型与常用类型对应关系

  想要准确的访问Mat中元素值,了解opencv中数据类型很重要,他决定了Mat中每个元素所占内存的大小。
  opencv中各种类型定义:

#define CV_8U   0                   //对应uchar
#define CV_8S   1                   //对应char
#define CV_16U  2                   //对应ushort
#define CV_16S  3                   //对应short
#define CV_32S  4                   //对应int
#define CV_32F  5                   //对应float
#define CV_64F  6                   //对应double
#define CV_USRTYPE1 7
...
#define CV_8UC1 CV_MAKETYPE(CV_8U,1)            //0
#define CV_8UC2 CV_MAKETYPE(CV_8U,2)            //8
#define CV_8UC3 CV_MAKETYPE(CV_8U,3)            //16
#define CV_8UC4 CV_MAKETYPE(CV_8U,4)            //32
#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n))

#define CV_8SC1 CV_MAKETYPE(CV_8S,1)            //1
#define CV_8SC2 CV_MAKETYPE(CV_8S,2)            //9
#define CV_8SC3 CV_MAKETYPE(CV_8S,3)            //17
#define CV_8SC4 CV_MAKETYPE(CV_8S,4)            //33
#define CV_8SC(n) CV_MAKETYPE(CV_8S,(n))
...
#define CV_64FC1 CV_MAKETYPE(CV_64F,1)        //6
#define CV_64FC2 CV_MAKETYPE(CV_64F,2)        //14
#define CV_64FC3 CV_MAKETYPE(CV_64F,3)        //22
#define CV_64FC4 CV_MAKETYPE(CV_64F,4)        //38
#define CV_64FC(n) CV_MAKETYPE(CV_64F,(n))

注:CV_MAKETYPE(depth,cn)=(cn-1)*8+depth        //定义类型,类型不冲突

补充:opencv中数据类型的变化

  注意opencv中各个函数所适用的Mat矩阵数据类型。当Mat矩阵数据类型不合适时,函数调用后可能引起数据类型的变化,如果发生改变,从而会对Mat矩阵数据的访问造成影响。
  
例:(VS中 C++代码)

camMatrix = cv::Mat::zeros(3, 3, CV_32FC1);             //float
cv::calibrateCamera(ptWs, m_pts, image.size(), camMatrix, distCoeffs, rotations, tranlation, CV_CALIB_FIX_K3);

  如上述代码,新建的内参矩阵camMatrix均为float类型(32位),在调用calibrateCamera标定程序进行标定后,内参矩阵camMatrix数据类型由初始的32位float类型变为了64为的double类型,从而导致后面数据访问出现错误。故这里需要将camMatrix初始化为CV_64FC1。
  在不确定类型时,可以通过查看源码或者调试查看类型变换得到变量类型。 如实际查看opencv源码可以看出calibrateCamera源码中,世界坐标(ptWs)与图像点坐标(m_pts)为float类型(32位),而源码中内参矩阵(camMatrix)、畸变矩阵(distCoeffs)、旋转向量矩阵(rotations - (1通道)X3(行)Xn(列))、平移向量矩阵都转化为了CV_64F类型。

2.Mat数据访问

2.1 at(i,j)

 int ROWS = 100; 
 int COLS = 200; 
 Mat img(ROWS , COLS , CV_32FC1);  
   
 for (int i=0; i<ROWS ; i++)  
 {  
     for (int j=0; j<COLS ; j++)  
     {  
         img.at<float>(i,j) = 3.2f;  
     }  
 }  

2.2 ptr(i)[j]

 int ROWS = 100; 
 int COLS = 200; 
 Mat img(ROWS , COLS , CV_32FC1);  
   
 for (int i=0; i<ROWS ; i++)  
 {  
     float* ptr = img.ptr<float>(i);
     for (int j=0; j<COLS ; j++)  
     {  
         ptr[j] = 3.2f;  
     }  
 }  

补: 访问8位图像时,type = uchar;
  24位图像时,type = vec3b;

原文地址:https://www.cnblogs.com/silentteen/p/7985995.html