对于3D医学图像的切片超像素创建,我创建了一个3d矢量 (std :: std :: vector of std :: vector of vector of 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文件中的结构。下面定义和初始化dat
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个字节吗?
答案 0 :(得分:0)
您提到性能问题在析构函数中。制作向量向量的向量会导致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;
}
可能会略有不同,具体取决于您如何考虑指数。