我正在使用C ++开发CT重建算法。我正在使用C ++,因为我需要使用用C ++编写的库来让我读/写特定的文件格式。
该重建算法涉及处理3D和2D图像。我在C和MATLAB中使用数组编写了类似的算法。但是,我读过,在C ++中,数组是“邪恶的”(参见http://www.parashift.com/c++-faq-lite/containers.html)。我使用数组操作图像的方式(在C中)如下(这将创建一个将用作3D图像的3D数组):
int i,j;
int *** image; /* another way to make a 5x12x27 array */
image = (int ***) malloc(depth * sizeof(int **));
for (i = 0; i < depth; ++i) {
image[i] = (int **) malloc(height * sizeof(int *));
for (j = 0; j < height; ++j) {
image[i][j] = (int *) malloc(width * sizeof(int));
}
}
或者我使用1维数组并进行索引算法来模拟3D数据。最后,我释放了必要的记忆。 我已经读过在C ++中有相同的方法。我已经看到我可以创建自己的矩阵类,它使用向量矢量(来自STL)或者我可以使用boost-matrix库。问题是,这使我的代码看起来很臃肿。
我的问题是:
1)是否有理由不为此目的使用数组?我为什么要使用更复杂的数据结构?
2)我认为我不会使用容器的优点(如我发布的C ++ FAQ lite链接中所示)。有什么我没看到的吗?
3)C ++ FAQ lite提到数组会降低我的工作效率。我真的不明白这是如何适用于我的情况。你们觉得怎么样?
答案 0 :(得分:1)
答案 1 :(得分:1)
在同等熟悉两种类型的代码时,在更高级别工作总能节省您的时间。它通常更简单,您可能不需要打扰删除等任务。
也就是说,如果您已经拥有C代码,并且基本上将malloc
转换为new
(或保持原样),那么留下它是完全合理的。没有理由重复工作没有优势。如果您要扩展它并添加更多功能,您可能需要考虑重写。图像处理通常是一个密集的过程,出于性能原因,我会一直看到像你这样的直接代码。
数组有目的,向量有目的,等等。你似乎理解权衡,所以我不会进入那个。了解你正在做的事情的背景是必要的;任何人说数组总是坏的或者矢量总是太多开销(等等)可能不知道他们在谈论什么。
答案 2 :(得分:1)
如果3D画布具有固定大小,则使用容器不会获得太多奖励。我会像你一样避免在小块中分配矩阵,而只是做
#define DIM_X 5
#define DIM_Y 12
#define DIM_Z 27
#define SIZE (DIM_X * DIM_Y * DIM_Z)
#define OFFS(x, y, z) (x + y * DIM_X + z * (DIM_Y * DIM_X))
然后
class 3DImage {
private unsigned int pixel_data[SIZE];
int & operator()(int x, int y, int z) { return pixel_data[OFFS(x,y,z)]; }
}
之后你就可以做到。
3DImage img;
img(1,1,1) = 10;
img(2,2,2) = img(1,1,1) + 2;
没有任何内存分配或算法开销。但正如其他人所指出的那样,数据结构的选择还取决于您计划在图像上运行的算法类型。但是,您始终可以调整第三方算法,例如如果需要,可以使用适当的外观类进行矩阵求逆;这个平面表示比你编写的嵌套指针数组快得多。
如果维度编译时间不固定,您显然仍然可以使用完全相同的方法,只需要动态分配pixel_data并将维度存储在3DImage对象本身中。这是那个版本:
class 3DImage {
private unsigned int *pixel_data;
unsigned int dim_x, dim_y, dim_z;
3DImage(int xd, int yd, int zd) { dim_x = xd; dim_y = yd; dim_z = zd;
pixel_data = new int[dim_x * dim_y * dim_z];
}
virtual ~3DImage() { delete pixel_data; }
int & operator(int x, int y, int z) {
return pixel_data[x + y * dim_x + z * dim_y * dim_x];
}
}
答案 3 :(得分:1)
我的问题是: 1)是否有理由不为此目的使用数组?我为什么要使用更复杂的数据结构?
我个人更喜欢使用基本数组。基本上我指的是一维线性阵列。假设您有一个512 X 512图像,并且您有5个切片,那么图像阵列如下所示:
int sizeX = 512;
int sizeY = 512;
int sizeZ = 5;
float* img = new float[sizeX * sizeY * sizeZ]
要访问位置(x,y,z)
的像素/体素,您需要执行以下操作:
float val = img[z*sizeX*sizeY + y*sizeX + sizeX];
2)我不认为我会利用容器的优势(如我发布的C ++ FAQ lite链接所示)。我有没有看到的东西?
使用容器更像是编程事物(更容易,更安全,异常捕获......)。如果你是算法人员,那么它可能根本就不是你的问题。但是,在C ++中使用<vector>
的一个示例,您始终可以这样做:
int sizeX = 512;
int sizeY = 512;
int sizeZ = 5;
std::vector<float> img(sizeX * sizeY * sizeZ);
float* p = &img[0];
3)C ++ FAQ lite提到数组会降低我的工作效率。我真的不明白这是如何适用于我的情况的。你们有什么想法?
我不明白为什么数组会降低你的工作效率。当然,c ++人更喜欢使用向量到原始数组。但同样,这只是一个编程问题。
希望这有帮助。
<强>补充:强>
进行2D / 3D CT重建的最简单方法是使用MATLAB / python + C / C ++;但同样,这需要你有足够的经验何时使用哪个。 MATLAB内置了FFT / IFFT,因此您不必为此编写C / C ++代码。我记得我之前使用过KissFFT,这没问题。