【问题标题】:Vectorize cut off view of an image stack in Matlab在 Matlab 中矢量化图像堆栈的截断视图
【发布时间】:2014-09-03 18:14:47
【问题描述】:

我正在处理成堆的显微镜图像。我所说的堆栈是指在另一个之上获取的几个图像,如这个非常自制的图表所示:(对不起质量)其中:

H = 图像高度(以像素为单位)

W = 图像宽度(以像素为单位)

Z = 堆栈中的切片数(即图像数)。

我想要做的是,对于堆栈中的每个“高度”位置,测量一个正交的“WZ 视图”,即沿矩形的截断视图,例如图像上的红色视图。现在我有以下运行良好的代码:

DummyProjMatrixYZ = zeros(SliceNumber,ImageWidth,ImageHeight,3,'uint16');

for h = ImageHeight:-1:1
    for z = 1:SliceNumber

        DummyProjMatrixWZ(z,:,h,:) = MovieCell{z}(h,:,:); % MovieCell is a cell array containing the individual frames (i.e. slices in the stack) of dimensions (Height,Width,3).
    end    
end

代码工作正常,但我必须为每个“高度单位”循环遍历整个切片,这根本不是最优的。

我的问题是:如何对之前的代码进行矢量化以提高速度,因为我最终将使用相当大的数据集。我想我脑子有问题,不知道如何有效地做到这一点。

【问题讨论】:

  • 1) MovieCell 的大小是多少? , 2) 为什么它在一个单元格数组中而不是一个 4D 矩阵中?
  • @natan 1) MovieCell 的大小为 (1,z),其中 z 是切片数,即通常从 20 到 200。 2)它在一个单元格数组中,因为它对于我之前必须处理其中的图像的操作要简单得多。但我同意将图像存储在 4D 矩阵中更有意义。
  • 如果它的 z 值只有 20-200,为什么不继续循环呢?你会节省多少时间?
  • 对于小型数据集来说它非常快,但我也想在包含 20-50 个时间点的图像序列中计算 HZ 视图(即不仅仅是我的示例中的 1 个)对于包含 20 个图像的堆栈1024x1024,需要 1 秒,对于 220 个图像堆栈,需要 9 秒。因此,我可以预期,为 20 多个时间点进行两次计算(对于 HZ 视图)将需要相当长的时间。

标签: image matlab vectorization cell-array


【解决方案1】:

在我看来,这基本上就像一个indexing problem。看看这是否适合你 -

%// Get all of the data into SliceNumber*ImageWidth x ImageWidth x 3 numeric 
%// array. No more messing around with cell arrays is needed after this point.
A = vertcat(MovieCell{:});

%// Cocatenate data along dim3 to create a 2D array
A1 = reshape(permute(A,[1 3 2]),size(A,1)*size(A,3),[]);

%// Cut A1 after every ImageHeight rows to form a 3D array
A2 = permute(reshape(A1,ImageHeight,size(A1,1)/ImageHeight,[]),[1 3 2]);

%// Cut A2's dim3 into SliceNumber x 3 to create a 4D array
A3 = reshape(A2,ImageHeight,ImageWidth,SliceNumber,3);

%// Change the dimensions to match with original DummyProjMatrixWZ's
DummyProjMatrixWZ = permute(A3,[3 2 1 4]);

短版 -

%// Get all of the data into SliceNumber*ImageWidth x ImageWidth x Ch numeric 
%// array. No more messing around with cell arrays is needed after this point.
A = vertcat(MovieCell{:});

%// Cut A at every H rows and resize to H x W x Slice*Ch to form a 3D array
A2 = permute(reshape(permute(A,[1 3 2]),ImageHeight,[],ImageWidth),[1 3 2]);

%// Cut A2's dim3 into Slice x Ch to create a 4D array and rearrange dims
DPrjMatWZ = permute(reshape(A2,ImageHeight,ImageWidth,SliceNumber,[]),[3 2 1 4]);

这里,Ch 表示使用的通道数,在问题情况下为3DPrjMatWZ 为最终输出。

【讨论】:

  • 是的,它运行良好,我的 220 个图像堆栈的计算时间减少了一半,因此大型数据集的好处将非常重要,谢谢,太棒了!
  • @Benoit_11 非常酷!很高兴看到真正的好处! :) 您可以尝试将最后两行合并为一行,看看是否有进一步改进。
  • 没错。我必须承认,我希望你能看看我的问题并提出一些矢量化魔法谢谢!
  • @Benoit_11 查看刚刚添加的更短版本!由于使用的变量更少,内存可能会更好。
  • 不错!感谢您的努力,我对此表示赞赏:)
猜你喜欢
  • 1970-01-01
  • 2013-05-31
  • 2010-10-05
  • 1970-01-01
  • 1970-01-01
  • 2019-11-26
  • 2015-06-07
  • 2016-07-03
  • 2013-07-02
相关资源
最近更新 更多