你可以这样做:
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 中,这始终是一种很好的做法,并且它几乎总是会为您提供比动态调整更大的性能提升。