How to efficiently calculate mean and standard deviation of two large images at multiple misalignments?
2 views (last 30 days)
Show older comments
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
Answers (1)
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
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.
See Also
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!