在C ++中优化3D成像过程

我正在处理3D立体图像,可能(256x256x256)。 我有3个这样的卷,我想阅读和操作。 目前,每卷都被存储为一个我使用ifstream读取的数字文本文件。 我将它保存为矩阵(这是我通过动态分配3D数组写入的类)。 然后我对这三个矩阵进行运算,加法运算,乘法运算甚至傅立叶变换。 到目前为止,一切运行良好,但是,它需要很多时间,特别是傅里叶变换,因为它有6个嵌套循环。

我想知道我如何加快这一点。 此外,我是否已将图像存储在文本文件中这一事实会产生变化。 我应该将它们保存为二进制还是其他一些更简单/更快的格式来读取? fstream是我能读的最快的方式吗? 我每次使用相同的3个矩阵而不改变它们。 这有什么区别吗? 另外,是指向指针的指针最好的方式来存储一个3d音量? 如果不是,我还能做什么?


另外,是指向指针的指针最好的方式来存储一个3d音量?

不要那样通常很不起作用。

如果不是,我还能做什么?

如果将其存储在连续的块中,并且将计算出的偏移量用到块中,则可能会获得更好的性能。

我通常会使用这样的结构:

class DataBlock {

  unsigned int nx;
  unsigned int ny;
  unsigned int nz;
  std::vector<double> data;

  DataBlock(in_nx,in_ny,in_nz) : 
   nx(in_nx), ny(in_ny), nz(in_nz) , data(in_nx*in_ny*in_nz, 0)
  {}

  //You may want to make this check bounds in debug builds
  double& at(unsigned int x, unsigned int y, unsigned int z) { 
    return data[ x + y*nx + z*nx*ny ];
  };

  const double& at(unsigned int x, unsigned int y, unsigned int z) const { 
    return data[ x + y*nx + z*nx*ny ];
  };

  private:
    //Dont want this class copied, so remove the copy constructor and assignment.
    DataBlock(const DataBlock&);
    DataBlock&operator=(const DataBlock&);
};

将明显的(256 ^ 3元素)3D图像文件存储为纯文本是浪费资源。 不失一般性,如果你的图像有一个纯文本文件,并且你的文件的每一行都包含一个值,你将不得不阅读几个字符,直到找到行的末尾(对于一个3位数的数字,这些将是4个字节;数字3个字节,换行1个字节)。 之后,您将不得不将这些单个数字转换为数字。 使用二进制时,您直接读取固定数量的字节,您将获得您的号码。 您可以并应该将其作为二进制图像进行编写和读取。

这样做有几种格式,我推荐的格式是VTK的元图像文件格式。 在这种格式下,您有一个明文头文件和一个包含实际图像数据的二进制文件。 使用头文件中的信息,您将知道图像的大小以及您将使用的数据类型。 在您的程序中,您可以直接读取二进制数据并将其保存到3D数组中。

如果您真的想加快速度,请使用CUDA或OpenCL,这对于您的应用程序来说非常快。

有几个c ++库可以帮助您编写,保存和处理图像数据,包括前面提到的VTK和ITK。


2563比较大。 解析2563个文本字符串将需要相当长的时间。 使用二进制将使读/写过程更快 ,因为它并不需要大量从字符串转换为/,并使用更少的空间 。 例如,要从文本文件中将数字123读取为char ,程序将需要将其作为字符串读取,并使用大量乘以10来将其从十进制转换为二进制。但是,如果您直接将它作为二进制值0b1111011写入需要将该字节再次读回到内存中,根本不需要转换。

使用十六进制数字也可以提高阅读速度,因为每个十六进制数字可以直接映射到二进制值,但是如果您需要更高的速度,二进制文件就是要走的路。 只需一个fread命令就足以在不到1秒的时间内将整个2563字节= 16MB的文件加载到内存中。 当你做,只是fwrite回文件。 为了加速您可以使用SIMD(SSE / AVX),CUDA或其他并行处理技术。 您可以通过多线程或仅保存非零值来进一步提高速度,因为在许多情况下,大多数值通常为0。

另一个原因可能是因为你的数组很大,每个维数都是2的幂。这已经在SO的许多问题中讨论过了:

  • 为什么2048x2048与2047x2047阵列乘法相比,会有巨大的性能下降?
  • 为什么我的程序在循环8192个元素时很慢?
  • 为什么转置一个512x512的矩阵要比转置513x513的矩阵慢得多?
  • 您可以考虑将最后一个维度更改为257,然后重试。

    链接地址: http://www.djcxy.com/p/15089.html

    上一篇: Optimizing for 3D imaging processes in C++

    下一篇: Can't get over 50% max. theoretical performance on matrix multiply