opencv之mat访问元素的方法
方式1: at
(i, j)访问
这种方式在Debug模式下的访问速度是最慢的,但是在Release模式下的访问速度也是相当快的,和其他方式相近。
- 单通道遍历
int ROWS = 100; // height
int COLS = 200; // width
Mat img1(ROWS , COLS , CV_32FC1);
for (int i=0; i<ROWS ; i++)
{
for (int j=0; j<COLS ; j++)
{
img1.at<float>(i,j) = 3.2f;
}
}
- 多通道遍历
int ROWS = 100; // height
int COLS = 200; // width
Mat img1(ROWS , COLS , CV_8UC3);
for (int i=0; i<ROWS ; i++)
{
for (int j=0; j<COLS ; j++)
{
img1.at<vec3b>(i,j)[0]= 3.2f; // B 通道
img1.at<vec3b>(i,j)[1]= 3.2f; // G 通道
img1.at<vec3b>(i,j)[2]= 3.2f; // R 通道
}
}
注:这种方式会判断溢出, 不会出现指针越位问题。
方式2: ptr
(i) [j] 方式
int ROWS = 100; // height
int COLS = 200; // width
Mat img5(ROWS , COLS , CV_32FC1);
for (int i=0; i<ROWS ; i++)
{
const float* pData1=img5.ptr<float>(i);
for (int j=0; j<COLS ; j++)
{
pData1[j] = 3.2f;
}
}
另外,通过判断数据内存区域为连续,可以将矩阵当做一个长向量进行访问(下面改用首地址用data获取,但是data默认是 uchar* 类型,需要进行强制转换):
if (M.isContinuous()) // 一般手动分配或者深复制的矩阵,都是连续的。
{
//const double*Mi = M.ptr<double>(0); 32us
const double*Mi = (double *)M.data; 32us
for (int j = 0; j < M.cols*M.rows; j++)
sum += Mi[j];
}
参考
opencv Mat数据的三种标准访问方式 - Zack888 - 博客园
OpenCv2 学习笔记(6) Mat元素访问和效率比较 - wanggao_1990的专栏 - CSDN博客