Как сократить время выполнения моего кода сопоставления изображений в MATLAB?

Я пытаюсь стабилизировать видеофайл в MATLAB, используя простой алгоритм сопоставления изображений. По сути, я беру окно первого кадра видео и вычитаю его с n-м кадром. Я хочу получить массив векторов смещения x и y от положения n-го кадра до первого кадра. Видео в формате градаций серого 1501x971 с 391 кадром.

Ниже мой код. Я позволил коду работать более 15 минут и все еще работает. Я искал ответы и реализовал int8 и матричные решения с предварительным распределением, которые, как я видел, предлагали люди, но это все еще слишком долго. Любая помощь будет оценена по достоинству.

% Define image region (window)
xmin = 35;
xmax = 1465;
ymin = 35;
ymax = 940;

% Matching algorithm
error = uint16(10^8); % set error to a larger number than expecting in the loop
deltax = 0;
deltay = 0;
deltaxArray = zeros(1,N,'int8');    % prealloacting arrays
deltayArray = zeros(1,N,'int8');    % using int8 to optimize code
deltaxArray(1) = 0;
deltayArray(1) = 0;

for n = 2:N % N = number of frames
    for deltay = -34:31         % Iterating over all possible displacements
        for deltax = -34:36
            current_error = uint16(sum(abs(f(1, ymin+deltay:ymax+deltay , xmin+deltax:xmax+deltax ) - f(n, ymin:ymax, xmin:xmax)),'all'));        % f is the video array
            if current_error < error        % searching for the smallest error in the nth frame
                error = current_error;      % set error if current error is smaller
                deltaxArray(n) = deltax;    % save x displacement coordinate
                deltayArray(n) = deltay;    % save y displacement coordinate
            end
        end
    end
    error = uint16(10^8);   % reset error for next iteration
end

person Dan L    schedule 06.04.2020    source источник
comment
Я не специалист по обработке видео в Matlab. Но у вас есть три уровня for-циклов, а внутри выглядит как минимум еще два уровня с : и sum, вы по идее работаете с O(n^5) алгоритмом. Обычно это означает, что это очень-очень медленно... Посмотрите, сможете ли вы уменьшить уровень итераций.   -  person Forever    schedule 07.04.2020


Ответы (1)


Используйте профайлер.

profile on;
your_script_name;
profile viewer;

это говорит вам, какие строки вашего кода занимают большую часть времени выполнения.

вывод выглядит следующим образом: https://www.mathworks.com/help/matlab/matlab_prog/profiling-for-improving-performance.html

но, прочитав свой код, вы должны подумать о векторизации своего кода, работая на уровне матрицы/вектора, а не на уровне элемента, используя циклы for. смотрите уроки в этом посте

Более быстрый способ зацикливать пиксель за пикселем для вычисления энтропии в изображении

person FangQ    schedule 06.04.2020
comment
К сожалению, я не думаю, что смогу векторизовать свои циклы for, потому что я использую переменные цикла для заполнения массивов внутри цикла. Возможно, есть способ использовать другие алгоритмы оптимизации, но мне трудно сократить время выполнения этого кода. - person Dan L; 07.04.2020