【发布时间】:2016-05-28 03:56:00
【问题描述】:
我在 Matlab 中有一个 3D 矩阵 A。我想使用 3x3x3 移动窗口在这个矩阵中找到局部极值(最小值和最大值)。也就是说,我想要所有满足的索引i,j,k
tmp = A(i-1:i+1,j-1:j+1,k-1:k+1)
A(i,j,k) == min(tmp(:)) || A(i,j,k) == max(tmp(:))
我有一个使用嵌套 for 循环(见下文)的脚本来使用上述条件查找极值。我只是想知道是否有办法对操作进行矢量化。
我还应该提到边界是周期性的;例如,在点{i,j,k} = {1,1,1},评估应该是
tmp = A([end,1,2],[end,1,2],[end,1,2])
A(1,1,1) == min(tmp(:)) || A(1,1,1) == max(tmp(:))
上述脚本如下:
s = size(A);
% Make outer boundaries equal
A1 = [A(end,:,:); A; A(1,:,:)];
A1 = [A1(:,end,:), A1, A1(:,1,:)];
A2 = NaN(s + [2 2 2]);
A2(:,:,1) = A1(:,:,end);
A2(:,:,2:end-1) = A1;
A2(:,:,end) = A1(:,:,1);
% Create arrays to record extrema
minvals = false(s); maxvals = minvals;
for i = 2:s(1)+1
for j = 2:s(2)+1
for k = 2:s(3)+1
tmp = A2(i-1:i+1,j-1:j+1,k-1:k+1);
a = A2(i,j,k);
if a == min(tmp(:))
minvals(i-1,j-1,k-1) = true;
end
if a == max(tmp(:))
maxvals(i-1,j-1,k-1) = true;
end
end
end
end
[MINidc.i, MINidc.j, MINidc.k] = ind2sub(s,find(minvals));
[MAXidc.i, MAXidc.j, MAXidc.k] = ind2sub(s,find(maxvals));
【问题讨论】:
-
你的矩阵有多大?向量化这个(我现在不确定如何)需要为每个 max 调用创建一个单独的行。这会将您的数据放大 27 倍。这是可行的还是会超出内存?
-
@Daniel 在我的特殊情况下,这不是问题。事实上,for 循环的实现运行得足够快。我问更多是出于好奇。所以让我们假设内存增加 27 倍不是问题。
-
@Divakar:我看不出与那个问题有关联。
标签: matlab max vectorization minimum