Как избежать циклов в этом коде Matlab? - PullRequest
0 голосов
/ 07 мая 2018

Я пытаюсь выполнить гауссово сглаживание 2D-объекта в Matlab. Вот сокращенная версия моего кода

[m,n] = size(object);
area = m*n;
x = [1:m]; y = [1:n]; [x,y] = meshgrid(x,y);
z = zeros(size(x));
for i = 1:m,
    for j = 1:n,
        z = z + object(i,j)*exp(-((x-i).*(x-i) + (y-j).*(y-j)));
    end
end
z = z/area;

Этот код работает довольно хорошо, но очень медленно для больших входных матриц. Мне интересно, есть ли способ сделать это быстрее, избегая петель for? Я пытался придумать способы ускорить это, но не могу найти ничего полезного.

1 Ответ

0 голосов
/ 08 мая 2018

Здесь у вас есть векторизованная форма без петель. Но он использует гораздо больше памяти и в зависимости от машины может работать медленнее, чем цикл. Однако большая часть вычислительного времени используется для вычисления переменной «ядро», которая не зависит от образа. Поэтому, если вам нужно обработать много изображений одинакового размера, вы должны вычислить его только один раз, и тогда вы сможете значительно сэкономить время. Я повторяю здесь ваш код в первую очередь, потому что я исправил некоторые смешивания х, у, м, п

[m,n] = size(object);
area = m*n;
x = [1:n]; y = [1:m]; [y,x] = meshgrid(x,y);
z = zeros(size(x));
for i = 1:m,
    for j = 1:n,
        z = z + object(i,j)*exp(-((x-i).*(x-i) + (y-j).*(y-j)));
    end
end
z = z/area;

Вот первая векторизованная форма

xi=bsxfun(@minus,repmat(x(:),1,area),x(:)');
yj=bsxfun(@minus,repmat(y(:),1,area),y(:)');
kernel=exp(-(xi.^2 + yj.^2));
w=kernel*object(:);
w=reshape(w,[m,n])/area;

И альтернативная форма, не использующая bsxfun

xx=repmat(x(:),1,area);
yy=repmat(y(:),1,area);
xx=xx-xx';
yy=yy-yy';
kernel=exp(-(xx.^2 + yy.^2));
w=kernel*object(:);
w=reshape(w,[m,n])/area;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...