Opencv的Mat中元素操作有好几种方式(opencv中Mat是row优先存储的)。
- 通过Mat提供的at来访问
Mat H(100, 100, CV_64F);
for(int i = 0; i < H.rows; i++)
for(int j = 0; j < H.cols; j++)
H.at<double>(i,j)=1./(i+j+1);
- Mat元素地址的解引用来访问
元素具体地址为(假设Mat M一共M.dims维,copy from Mat说明文档):
2维情况为:
在matrix维度比较大时,两个的访问速度差异是很明显的,下面为我的测试代码
int main()
{
srand(time(NULL));
float *tmp = new float[1000 * 1000];
for (int i = 0; i < 1000; ++i)
{
for (int j = 0; j < 1000; ++j)
{
tmp[i * 1000 + j] = rand() % 3;
}
}
Mat a(1000, 1000, CV_32FC1, tmp);
int count = 0;
double sum = 0.0;
clock_t ref = clock();
while (count < 10)
{
count++;
sum = 0.0;
for (int i = 0; i < 1000; ++i)
{
for (int j = 0; j < 1000; ++j)
{
sum += a.at<float>(i, j);
}
}
}
cout << "At access: " << (clock() - ref) / (CLOCKS_PER_SEC * 10.0) << endl;
cout << sum << endl;
ref = clock();
count = 0;
while (count < 10)
{
count++;
sum = 0.0;
for (int i = 0; i < 1000; ++i)
{
for (int j = 0; j < 1000; ++j)
{
sum += *(float*)(a.data + a.step[0]*i + a.step[1]*j);
}
}
}
cout << "Pointer access: " << (clock() - ref) / (CLOCKS_PER_SEC*10.0) << endl;
cout << sum << endl;
system("pause");
}
测试结果是:
注意:在用指针地址访问的时候,要先将元素指针转换为对应的类型的指针,然后再解引用即:
*(float*)(a.data + a.step[0]*i + a.step[1]*j)
如果先解引用,再转换为对应类型,则得不到想要结果:
(float)*(a.data + a.step[0]*i + a.step[1]*j) // wrong
此外,关于Mat和数组之间相互赋值可以如下操作:
数组 --> Mat
float * proj = new float[he_dimension * dimension];
// do some stuff to proj ...
Mat mat_proj(he_dimension, dimension, CV_32F);
mat_proj.data = (uchar *)proj;
Mat mat_test(nrows, ncols, CV_32F);
// do some stuff to mat_test
float *arrayfmat = new float[nrows * ncols];
arrayfmat = (float *)mat_test.data;
// do some stuff to arrayfmat
delete[] arrayfmat;