How to efficiently calculate mean and standard deviation of two large images at multiple misalignments?

2 views (last 30 days)
I would like to calculate the difference between two large images (ca. 10k px x 20k px; >1GB). The difference between the two images needs to be calculated at multiple misalignments between the two images (e.g. the two images can be misaligned at most by 50 px in each direction). I am actually interested then in the image of the average difference and the standard deviation of the difference (of all possible misalignments).
What is the most efficient way to do this?
Currently, I use two for loops to cover all possible misalignments, calculate the difference between the two (moved) images and add the result to a sum to get at the end the mean difference image as in:
SD = zeros(res_size); % Resulting image is cropped.
for xi = -N:1:N % Possible misalignment between images in X-direction.
for yi = -N:1:N % Possible misalignment between images in Y-direction.
% Add to sum of differences
SD = SD + (...
I1( idx(1,1) : idx(1,2) , idx(2,1) : idx(2,2) ) - ...
I2( idx(1,1) + xi : idx(1,2) + xi, idx(2,1) + yi : idx(2,2) + yi ) ...
);
end
end
I_dif_mean = SD / (N*2+1)^2;
Then I repeat the same process but subtract the mean image from the difference between the two (moved) images, square it and add it to another sum to get the STD at the end.
SDD = SDD + (...
(...
I1( idx(1,1) : idx(1,2) , idx(2,1) : idx(2,2) ) - ...
I2( idx(1,1) + xi : idx(1,2) + xi, idx(2,1) + yi : idx(2,2) + yi ) ...
) - I_dif_mean( idx(1,1) : idx(1,2), idx(2,1) : idx(2,2) ) ...
).^2;
Is there a way to speed this? Currently it takes roughly 8 hours to calculate the results.
  2 Comments
uhu
uhu on 26 Nov 2021
Excuse me, I do not understand what you mean by "asking my questions multiple times". This is the only post I have made so far, and I wanted to know what is the most efficient way to solve the problem (if there exist any) or if someone at least sees an option to speed up the algorithm I have tried out (even though it might not be the most efficient one).

Sign in to comment.

Answers (1)

Image Analyst
Image Analyst on 26 Nov 2021
8 hours? Wow. Why not use the built-in mean(), mean2(), std(), or std2() functions?
  5 Comments
Image Analyst
Image Analyst on 26 Nov 2021
I understand now. I think you'd have to do 9 subtractions, each where the image is shifted and cropped/padded so they have the same shape. Then you could get the mean and std something like
% Concatenate all 9 images together.
s = cat(3, sub1, sub2, sub3, sub4, sub5, sub6, sub7, sub8, sub9];
% Compute mean for each pixel amongst the 9 values
m = mean(s, [], 3);
% Compute st dev for each pixel amongst the 9 values
sd = std(s, [], 3);
You can probably use imtranslate to shift the "moving" image. Of course there will be edge effects near the edges of the image where there is no overlap.
uhu
uhu on 26 Nov 2021
Edited: uhu on 26 Nov 2021
This is unfrotunately not possible because in reality I have up to 50 pixels of misalignment in each direction. This results in 10201 of images, where each takes more than 1GB, thus I would need more than 10TB of RAM.
That is why I have used the approach of cumulative sums, where I need to store in RAM only one such large image. The only problem is it takes long, and I was wondering if I could somehow speed up the algorithm.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!