0

I am trying to stabilize a video file in MATLAB using a simple image matching algorithm. Basically, I am taking a window of the first frame of the video and subtracting it with the nth frame. I want to end up with an array of x and y displacement vectors from the position of the nth frame to the first frame. The video is in a 1501x971 grayscale format with 391 frames.

Below is my code. I have let the code run for 15+ minutes and still running. I have been searching for answers and implemented the int8 and preallocating matrix solutions that I've seen people suggesting but it still runs too long. Any help would be appreciated.

% 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
Dan L
  • 1
  • 1
  • I'm not an expert with matlab video processing. But you have three levels of for-loops, and inside it looks like at least two more level with the `:` and `sum`, you are in theory working with a `O(n^5)` algorithm. That generally means it's very very slow... See if you can reduce the level of iterations – F.S. Apr 06 '20 at 23:20

1 Answers1

0

Use a profiler.

profile on;
your_script_name;
profile viewer;

this tells you which lines of your code consumed most of the runtime.

the output looks like this https://www.mathworks.com/help/matlab/matlab_prog/profiling-for-improving-performance.html

but from reading your code, you should consider vectorizing your code by operating on matrix/vector level instead of operating on element-level using for-loops. see tutorials in this post

Faster way to looping pixel by pixel to calculate entropy in an image

FangQ
  • 1,444
  • 10
  • 18
  • Unfortunately, I don't think I'm able to vectorize my for loops because I'm using the loop variables to populate arrays inside the loop. Maybe there is a way using different optimization algorithms, but I'm having a hard time reducing my runtime for this code. – Dan L Apr 07 '20 at 00:28