MATLAB:矢量化3D数组的填充

时间:2013-10-26 20:29:48

标签: arrays matlab matrix

我想将一定数量的灰度图像( - > 2D-阵列)作为3D阵列中的图层进行安全保护。 因为对于实时应用程序应该非常快,我想对以下代码进行矢量化,其中m是移位数:

for i=1:m
  array(:,:,i)=imabsdiff(circshift(img1,[0 i-1]), img2);
end

nispio向我展示了一个非常高级的版本,你可以在这里看到:

I = speye(size(img1,2)); E = -1*I;
ii = toeplitz(1:m,[1,size(img1,2):-1:2]);
D = vertcat(repmat(I,1,m),E(:,ii));

data_c = shape(abs([double(img1),double(img2)]*D),size(data_r,1),size(data_r,2),m);

目前两个操作的结果不一样,可能会将图像移动到错误的方向。我的知识非常有限,所以我完全不懂代码。

2 个答案:

答案 0 :(得分:2)

你可以这样做:

M = 16; N = 20; img1 = randi(255,M,N);       % Create a random M x N image
ii = toeplitz(1:N,circshift(fliplr(1:N)',1)); % Create an indexing variable

% Create layers that are shifted copies of the image
array = reshape(img1(:,ii),M,N,N);

只要您的图片尺寸不变,您只需要创建一次ii变量即可。之后,您可以在每次图像更改时调用最后一行。我不确定这会给你一个超过for循环的速度优势,但它会像你要求的那样进行矢量化。 :)

更新

根据有关此问题的新信息,此解决方案应该为您提供速度增加的顺序:

clear all;

% Set image sizes
M = 360; N = 500;

% Number of column shifts to test
ncols = 200;

% Create comparison matrix (see NOTE)
I = speye(N); E = -1*I;
ii = toeplitz([1:N],[1,N:-1:(N-ncols+2)]);
D = vertcat(repmat(I,1,ncols),E(:,ii));

% Generate some test images
img1 = randi(255,M,N);
img2 = randi(255,M,N);

% Compare images (vectorized)
data_c = reshape(abs([img2,img1]*D),M,N,ncols);

% Compare images (for loop)
array = zeros(M,N,ncols); % <-- Pre-allocate this array!
for i=1:ncols
  array(:,:,i)=imabsdiff(circshift(img1,[0 i-1]),img2);
end

这使用矩阵乘法进行比较,而不是生成一大堆移位的图像副本。

注意:如果您的图片尺寸没有变化,则只应生成一次矩阵D。请注意,D矩阵完全独立于图像,因此每次重新生成它都是浪费。但是,如果图片大小确实发生了变化,则需要更新D

修改:我已将代码更新为更接近您正在寻找的内容。然后我抛出“原始”for循环实现,以显示它们给出相同的结果。有关矢量化版本的一件值得注意的事情是,它有可能成为非常记忆的内容。如果ncols = ND矩阵有N^3个元素。即使D稀疏,当你将D乘以非稀疏图像时,事情会快速分崩离析。

另外,请注意我在array循环之前预先分配for。在Matlab中,这是始终的良好实践,在实际应用中,它几乎总能为您提供超出动态大小调整的大量性能。

答案 1 :(得分:0)

如果问题被正确理解,我认为您需要for循环

for v=1:1:20
  array(:,:,v)=circshift(image,[0 v]);
end