C++:解除分配 3D 矢量
C++: Deallocating 3d vector
对于 3D 医学图像的 slic 超像素创建,我创建了一个 3d 矢量(std::vector of std::vector of std::vector hold DataStr 对象)。图像尺寸 (~150 x 150 x 150)。DataStr 是一种结构,用于在同一 3D 矢量中存储体素信息,例如指向其邻居的指针矢量。事实证明,使用它比使用邻域迭代器或 KdTree 最近邻搜索循环浏览图像要快得多,因为此信息必须可用于 slic 算法的每次迭代。此外,相比之下,使用它非常方便。但是,当 3d 矢量超出范围时,3d 矢量的释放需要 ~4 分钟。谁能告诉我为什么会这样,我该如何避免这种情况?谢谢!
编辑:
第一次在这里提问,感谢您的耐心等待:-)!
struct DataStr{
std::vector<DataStr*> neighbors;
float cmpVal;
int association;
cv::Mat index;
float intensity;
DataStr() :association{ -1 }, cmpVal{ std::numeric_limits<float>::max() }{}
};
以上是 .hpp 文件中的结构。以下定义和初始化
std::vector<std::vector<std::vector<DataStr>>> dat;
for (int i{ 0 }; i < imgDim[0]; ++i)
{
dat.resize(imgDim[0]);
for (int j{ 0 }; j < imgDim[1]; ++j)
{
dat[i].resize(imgDim[1]);
for (int k{ 0 }; k < imgDim[2]; ++k)
{
dat[i][j].resize(imgDim[2], DataStr{});
}
}
}
imgDim是图像尺寸的3D数组。
for (it_nImg.GoToBegin(), it_nMask.GoToBegin(), it_nCent.GoToBegin(); !it_nImg.IsAtEnd(); ++it_nImg, ++it_nMask, ++it_nCent)
{
auto idx = it_nMask.GetIndex();
DataStr* str = &dat[idx[0]][idx[1]][idx[2]];
(*str).intensity = it_nImg.GetCenterPixel();
(*str).index = (cv::Mat_<float>(1, 3) << idx[0], idx[1], idx[2]);
for (int i = 0; i < it_nMask.Size(); ++i)
{
auto tmpIdx = it_nMask.GetIndex(i);
(*str).neighbors.push_back(&dat[tmpIdx[0]][tmpIdx[1]][tmpIdx[2]]);
}
}
it_n* 是 itk 库中的图像邻域迭代器,用于填充图像中每个体素的 DataStr 中的邻域向量。 it_nMask.Size() 是所选邻域的大小。 it_n*。GetIndex() 提供了 3d 体素索引的 3 元素数组。多谢。
编辑编辑:
如果我存储相邻体素的索引而不是指向它们的指针,则释放只需要 0.5 秒。这是因为指向 DataStr 的指针长度为 8 字节,而 int 在我的机器上只有 4 个字节吗?
您提到性能问题出在析构函数中。 向量向量 向量 向量会导致150 + 150 * 150
分配和解除分配。 如果您在分配中没有看到它,我怀疑这是因为它在使用量中摊销了。
在你的情况下可以接受吗
std::vector<DataStr> dat;
int dat_size = imgDim[0] * imgDim[1] * imgDim[2];
dat.reserve(dat_size);
// No need to loop and initialize, the default constructor
// will do that for you.
然后在你的大循环中,替换这一行
DataStr* str = &dat[idx[0]][idx[1]][idx[2]];
有了这个
DataStr& str = dat[dat_index(idx[0], idx[1], idx[2])];
(然后有一些细节,因为我使用了引用而不是指针)。 在这里,我定义了一个辅助函数,
inline int dat_index(int x, int y, int z) {
return imgDim[0] * imgDim[1] * x + imgDim[0] * y + z;
}
这可能会略有不同,具体取决于您对指数的看法。
- 3D 矢量在球体上迭代
- 尝试访问 3D 矢量中的元素时出现 Seg 错误
- 计算每个维度的两个 3D 矢量之间的角度
- 如何使用偏航、俯仰和滚动旋转 3D 矢量?
- C++ 和 Lua 函数之间的交互与 3D 矢量参数
- 如何根据物体位置和速度,玩家位置和向前矢量计算左耳和右耳的音量?(3D声音)
- 用于 3D 矢量的高效除法运算符
- 将 3D 矢量浮点打包到无符号 int 中并将其解压缩
- 3D 矢量 - 变换和减号
- 我如何将一组整数集变成C 中的3D矢量
- 如何获取 3D 标准::矢量的大小
- C :将矢量重新为3D数组
- 3D 矢量 - "No instance of overload function?"
- 使矢量 3D 源自矢量 ND,需要保留场 x y z
- 在转换3D矢量时,为什么GLM给出错误的结果
- 如何获取3D矢量的剩余轴知道其他两个
- 查找 3D 点的两个交集的最佳方法::矢量
- 提升program_options:在 3D 矢量中读取作为命令行参数
- 特征:从 3D 矢量 c++ 中减去标量
- 1D 矢量 - 3D 索引