0

我想保护一定数量的灰度图像(-> 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);

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

4

2 回答 2

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 = N那么D矩阵有N^3元素。即使是稀疏的,当你乘以非稀疏图像D时,事情很快就会分崩离析。D

另外,请注意我在循环array之前预先分配。for在实用的 Matlab 中,这始终是一种很好的做法,并且它几乎总是会为您提供比动态调整更大的性能提升。

于 2013-10-26T23:17:48.787 回答
0

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

for v=1:1:20
  array(:,:,v)=circshift(image,[0 v]);
end
于 2013-10-26T21:15:36.840 回答