[英]Fast image (or matrix) transpose implementation in C++
這篇文章討論了如何使用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_
,我們假設圖像像素逐行保留。 關於進一步改進上述代碼有什么想法嗎?
在不接觸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;
}
這樣每次迭代可以節省一個以上的操作( for
循環中for
i++
)。 此外src
進行比較錯誤的end
之前。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.