Как исключить петлю в расчете энергии? - PullRequest
5 голосов
/ 25 марта 2011

Я делаю алгоритм, который извлекает информацию из изображений - большая часть этой информации подобна энергии. Это в основном выполняется путем запуска образа с ядром (размер указан в качестве параметра) и получения квадратов сумм значений в этом ядре.

Это делается в трех масштабах, где три размера ядра (патча) (на данный момент): smalllestPatchSize, smalllestPatchSize * 3, smalllePPatchSize * 9 (с перекрывающимися ядрами во втором и третьем случае). Это делается для нескольких цветовых каналов, градиентных фильтров и т. Д. (Всего их 17).

Мой вопрос заключается в том, можно ли векторизовать приведенный ниже код; очевидно, что эта часть кода требует гораздо больше времени для запуска, чем любая другая. Я довольно новичок в Matlab и до сих пор пытаюсь освоить векторизацию, но этот побеждает меня:)

for dim = 1:17

for i = 1:smallestPatchSize:(size(image,1) - currentPatchSize)
    for j = 1:smallestPatchSize:(size(image,2) - currentPatchSize)

        % calculate the position in the energy matrix
        % which has different dimensions than the input pictures
        iPosition = (i - 1 + smallestPatchSize) / smallestPatchSize;
        jPosition = (j - 1 + smallestPatchSize) / smallestPatchSize;

        % calculate the energy values and save them into the energy matrix
        energy(iPosition, jPosition, dim) = sum(sum(abs(...
            filters(i:i+currentPatchSize, j:j+currentPatchSize,dim)))) ^ 2;
    end
end
end

Заранее спасибо - это мой первый вопрос @ StackOverflow:)

Ответы [ 2 ]

3 голосов
/ 25 марта 2011

Вы берете локальные суммы значений блоков.Фильтр сумм является отделимым, т.е. если вы хотите сделать сумму по m-by-n, вы можете разбить ее на получение сначала суммы m-by-1, а затем суммы 1-n-n для результата,Обратите внимание, что при полной свертке вы будете брать сумму немного чаще, но это все же быстрее, чем использовать blkproc или более позднюю blockproc.

Таким образом, даже для smallestPatchSize выможете написать свой внутренний цикл как:

tmp = conv2(...
            conv2(abs(filter),ones(currentPatchSize,1),'same'),...
      ones(1,currentPatchSize,'same').^2;
%# tmp contains the energy for a sliding window filter.
energy = tmp((currentPatchSize/2+1):(currentPatchSize+1):size(image,1)-(currentPatchSize/2+1),...
      (currentPatchSize/2+1):(currentPatchSize+1):size(image,2)-(currentPatchSize/2+1));
1 голос
/ 25 марта 2011

Если у вас есть доступ к инструментарию обработки изображений, вы можете использовать blkproc:

B = blkproc(A,[m n],fun)

В вашем случае:

[m,n] = size(filters) ./ patchSize;
fun = @(x) sum( sum(x^2) ); % or whatever

B должен в конечном итоге иметь правильный размер. Вы также можете использовать перекрывающиеся регионы, если хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...