OpenCV - 访问Mat矩阵中的元素
2012.06.07 补记:半年前我对 OpenCV 还不了解,OpenCV 提供多种方法访问 Mat 中的元素,十分方便。这篇文章中提及的几种方法需要重新修改。
Mat矩阵中数据指针 Mat.data
是uchar类型指针,CV_8U
系列可以通过计算指针位置快速地定位矩阵中的任意元素。
二维单通道元素可以用 Mat::at(i, j)
访问,i
是行序号,j
是列序号。
但对于多通道的非 unsigned char 类型矩阵来说,以上方法都不好
注:后来知道可以通过类型转换,用指针访问 data 数据,见后文
可以用 Mat::ptr()
来获得指向某行元素的指针,在通过行数与通道数计算相应点的指针。
参照 OpenCV 的 Mat::at()
函数,写了一个访问二维Mat矩阵的两个简单的小函数,没有边界检查。
#include <opencv2/core/core.hpp>
template<typename ItemType>
ItemType* getMatPointPtr(cv::Mat & src, int i , int j , int c = 0)
{
ItemType* curRow = src.ptr<itemType>(i);
return curRow + j * src.channels() + c;
}
template<typename ItemType>
ItemType getMatPoint(cv::Mat & src, int i , int j , int c = 0)
{
ItemType* curRow = src.ptr<itemType>(i);
return *(curRow + j * src.channels() + c);
}
OpenCV 中的 Mat::at()
代码有严格的边界检测,Mat::ptr()
也有边界检测,但代码中没有检测 j
是否越界。
以下是 2012 年 1 月 12日补写:
可以通过转换指针类型,访问非uchar类型的Mat元素。
例如图像是CV_64FC1
格式,可以将Mat.data
指针直接转换成double*类型:
// imgMat is a image.
double* pimg = (double*)(imgMat.data)
也可以用C++中的显式转换符static_cast,不过要通过void*类型过渡:
void* pvoid = static_cast<void*>(imgMat.data);
double* pimg = static_cast<double*>(pvoid);
这种方式在 Debug 模式下速度提升非常显著,但没有任何的边界检查和异常处理,使用时必须十分小心。
使用 Mat::ptr
的速度和直接使用这种方法差不多,多一层保护总比没有保护强。