Вы можете сделать это:
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
, но оно векторизовано, как вы просили. :)
UPDATE
В свете новой информации, разделяемой о проблеме, это решение должен дать вам порядок величины увеличение скорости:
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
.
Редактировать: Я обновил код, чтобы более точно соответствовать тому, что вы, похоже, ищете. Затем я бросаю «оригинальную» для цикла реализацию, чтобы показать, что они дают тот же результат. Одна вещь, заслуживающая внимания в отношении векторизованной версии, состоит в том, что она может быть очень интенсивной в памяти. Если ncols = N
, то матрица D
имеет N^3
элементов. Несмотря на то, что D
редки, вещи быстро разваливаются, когда вы умножаете D
нерелевантными изображениями.
Также обратите внимание, что я предварительно назначил array
перед циклом for
. Это всегда хорошая практика в Matlab, где практически, и это почти всегда даст вам большой прирост производительности по динамическому размеру.
Каковы размеры изображения? v - вектор, поэтому в этом случае изображение должно быть строками x col x 20. Также я не думаю, что вы правильно используете circshift. В документации говорится: «shiftsize - это вектор целочисленных скаляров, где n-й элемент определяет величину сдвига для n-го измерения массива A.» Поэтому, если у вас нет 20 размеров для изображения ... – user2816823
'[0 1:20]' в вашем случае не имеет смысла. Если 'image' является 2-D массивом, тогда' [0 1] 'и' [0 1: n] '(n - любое число больше 1) даст тот же результат, поскольку вы вращаете одноэлементное измерение. Если вы хотите на самом деле кругово сдвинуть изображение для создания новых изображений и поместить их в 3-D массивы (я не знаю, что эта операция означает физически), то правильное решение, используемое для циклов, является правильным. –
В конце я хочу иметь массив с 20 слоями, где каждый слой содержит одно изображение, и каждое изображение должно быть сдвинуто на другую величину. Поэтому мне нужно 20 разных изображений в одном массиве. Я уже делал это с помощью цикла, но он должен был замедляться, мне нужно его для стереовидения для обнаружения препятствий в реальном времени. – Pixel