行有序数据到列有序数据的最快转换
Fastest Conversion of Row-Ordered data to Column-Ordered data
我有一个来自openCV的IplImage,它以行顺序格式存储数据;
图像数据被存储在一维阵列char*数据中;位置x,y的元素由给出
elem(x,y) = data[y*width + x] // see note at end
我想尽快将此图像转换为以列顺序格式存储数据的第二种图像格式;那就是
elem(x,y) = data[x*height + y]
显然,实现这种转换的一种方法是简单地通过double-for循环逐个元素。
有更快的路吗?
注意,对于openCV affecionados,elem(x,y)的实际位置由data + y*widthstep + x*sizeof(element)
给出,但这给出了一般的想法,对于char数据sizeof(element)=1,我们可以使widthstep=width,因此公式是精确的
它被称为"矩阵换位"最佳方法试图最大限度地减少缓存未命中的数量,交换小瓦片具有一个或几个高速缓存槽的大小。对于多级缓存,这将变得困难。从这里开始阅读
这是一个更先进的
顺便说一句,url处理的是"就地"换位。创建转置副本会有所不同(它使用的缓存插槽是原来的两倍,duh!)
假设您需要一个移动了所有元素的新数组,那么在算法速度方面,您能管理的最快值是元素数量的O(N)(即宽度*高度)。
对于实际花费的时间,可以生成多个线程,每个线程复制一些元素。当然,只有当你真的有很多的时候,这才是值得的。
如果线程已经创建,并且它们接受队列中的任务,或者其他什么,那么如果要处理大量这样的图像,这将是最有效的。
当然,在你的单个"循环"中,你可以避免多次进行相同的乘法运算,指针运算可能比随机存取快一点。
您已经回答了自己的问题,但没有代码。我想你需要之类的东西
typedef struct
{
unsigned char r;
unsigned char g;
unsigned char b;
}somePixelFormat;
#define HEIGHT 2
#define WIDTH 4
// let's say this is original image width=4 height=2 expresed as one dimentional
// array of structs that adhere to your pixel format
somePixelFormat src[ WIDTH * HEIGHT ] =
{
{0,0,0}, {1,1,1}, {2,2,2}, {3,3,3},
{4,4,4}, {5,5,5}, {6,6,6}, {7,7,7}
};
somePixelFormat dst[ WIDTH * HEIGHT ];
void printImage( void *img, int width, int height, int pixelByteCount )
{
for ( int row = 0; row < height; row++ )
{
for ( int col = 0; col < width; col++ )
{
printf( "(%02d,%02d,%02d) ", ((somePixelFormat*)img + width * row + col)->r,
((somePixelFormat*)img + width * row + col)->g,
((somePixelFormat*)img + width * row + col)->b );
}
printf ( "n" );
}
printf("nn");
}
void flip( void *dstImg, void *srcImg, int srcWidth, int srcHeight, int pixelByteCount )
{
for ( int row = 0; row < srcHeight; row++ )
{
for ( int col = 0; col < srcWidth; col++ )
{
*((somePixelFormat*)dstImg + srcHeight * col + row) = *((somePixelFormat*)srcImg + srcWidth * row + col);
}
}
}
int main()
{
printImage( src, 4, 2, sizeof(somePixelFormat) );
flip( dst, src, 4, 2, sizeof(somePixelFormat) );
printImage( dst, 2, 4, sizeof(somePixelFormat) );
getchar();
return 0;
}
下面是输出示例:
(00,00,00) (01,01,01) (02,02,02) (03,03,03)
(04,04,04) (05,05,05) (06,06,06) (07,07,07)
(00,00,00) (04,04,04)
(01,01,01) (05,05,05)
(02,02,02) (06,06,06)
(03,03,03) (07,07,07)
相关文章:
- 防止主数据类型C++的隐式转换
- 用于访问容器<T>数据成员的正确 API
- 嵌套在类中时无法设置成员数据
- 使用流处理接收到的数据
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在cuda线程之间共享大量常量数据
- C++将文本文件中的数据读取到结构数组中
- 如何在C++中序列化结构数据
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 在c代码之间共享数据的最佳方式
- 链表,反向函数,数据结构
- 数据成员SFINAE的C++17测试:gcc vs clang
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 如何对点云数据进行排序
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- 提取和排序数组中的数据
- C 气泡排序:排序数组丢失最大的数据片段,并替换为内存地址