这个post讨论了如何用OpenCV转置图像,在这里我想更进一步:假设图像是灰度图像,使用C ++转换它(或矩阵)的最快方法是什么?我的解决方案如下:
// image data is stored in an image buffer image*buffer_
unsigned char *mem = (unsigned char *) malloc(image.bufferSize_);
int height = image.Height();
int width = image.Width();
for(int i=0; i<height; i++)
{
unsigned char *ptr =image.buffer_+i*width;
for(int j=0; j<width; j++)
*(mem+j*height+i) = *(ptr+j);
}
memcpy(image.buffer_,mem,image.bufferSize_);
free(mem);
上面代码的一些解释:我们创建一个图像对象,其中包含基本图像信息以及图像像素(在image.buffer_
中)。当图像像素存储在image.buffer_
中时,我们假设图像像素是逐行保存的。有关进一步改进上述规范的任何想法?
答案 0 :(得分:1)
如果不触及malloc / free部分,复制部分可能会像这样:
size_t len = image.bufferSize_,
len1 = len - 1;
unsigned char *src = image.buffer_,
*dest = mem,
*end = dest + len;
for(size_t i = 0; i < len; i++)
{
*dest++ = *src; // dest moves to next row
src += height; // src moves to next column
// src wraps around and moves to next row
if (src > end) src -= len1;
}
这相当于具有列式目标迭代器和行式源迭代器。
如果没有实际测试,我觉得这会更快:它在内循环中有3个操作用于偏移计算,而在你的版本中有4个操作(在两个版本中加2个解除引用操作)。
修改强>
还有一项改进和更正:
//...
unsigned char *src = image.buffer_,
*src_end = src + len,
*dest = mem,
*dest_end = dest + len;
while (dest != dest_end)
{
*dest++ = *src; // dest moves to next row
src += height; // src moves to next column
// src wraps around and moves to next row
if (src > src_end) src -= len1;
}
每次迭代再保存一次操作(i++
循环中for
)。此外,src
与错误的end
进行了比较。