Этот вопрос связан с этими двумя:
Введение в векторизацию в MATLAB - есть ли хорошие уроки?
Фильтр, который использует элементы из двух массивов одновременно
Основываясь на прочитанных мною уроках, я пытался векторизовать какую-то процедуру, которая занимает действительно много времени.
Я переписал это:
function B = bfltGray(A,w,sigma_r)
dim = size(A);
B = zeros(dim);
for i = 1:dim(1)
for j = 1:dim(2)
% Extract local region.
iMin = max(i-w,1);
iMax = min(i+w,dim(1));
jMin = max(j-w,1);
jMax = min(j+w,dim(2));
I = A(iMin:iMax,jMin:jMax);
% Compute Gaussian intensity weights.
F = exp(-0.5*(abs(I-A(i,j))/sigma_r).^2);
B(i,j) = sum(F(:).*I(:))/sum(F(:));
end
end
в это:
function B = rngVect(A, w, sigma)
W = 2*w+1;
I = padarray(A, [w,w],'symmetric');
I = im2col(I, [W,W]);
H = exp(-0.5*(abs(I-repmat(A(:)', size(I,1),1))/sigma).^2);
B = reshape(sum(H.*I,1)./sum(H,1), size(A, 1), []);
Где
A
- матрица 512x512
w
равно половине размера окна, обычно равно 5
sigma
- параметр в диапазоне [0 1] (обычно один из: 0,1, 0,2 или 0,3)
Таким образом, матрица I
будет иметь 512x512x121 = 31719424elements
Но эта версия кажется такой же медленной, как и первая, но, кроме того, она использует много памяти и иногда вызывает проблемы с памятью.
Полагаю, я сделал что-то не так.Вероятно, какая-то логическая ошибка в отношении векторизации.Ну, на самом деле, я не удивлен - этот метод создает действительно большие матрицы и, вероятно, вычисления пропорционально длиннее.
Я также пытался написать его, используя nlfilter (аналогично второму решению, данномуДжонас ), но это кажется трудным, поскольку я использую Matlab 6.5 (R13) (нет доступных сложных функциональных дескрипторов).
Итак, еще раз, я прошу не о готовом решении, а о некоторых идеях, которые помогут мне решить это в разумные сроки.Может быть, вы укажете мне, что я сделал не так.
Редактировать:
Как предположил Михаил, результаты профилирования следующие:
65% времени было потрачено в строке H= exp(...)
25%время использовалось im2col