Opencv Mat元素操作

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 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;



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值