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;