I have a list of lists of images that I would like to stack and create mean images for each list of images.
Images are .jpg files 2592x1944 pixels large. Each list contains about 300 images. This means I can't import them all at once due to limited computer memory.
I have tried several methods of importing and stacking the images. Each method was timed in a clean mathematica session (I have quit the kernel between executions).
Image file names are stored in imghs:
Length@imghs (* this is constant *)
24
Length /@ imghs (* this will increase with time *)
{307, 310, 312, 311, 312, 311, 312, 311, 310, 311, 308, 308, 312, 309, 311, 310, 308, 313, 316, 314, 317, 317, 311, 316}
Here are my methods and timings:
AbsoluteTiming[
means = ParallelMap[
ImageMultiply[
Fold[ImageAdd[Image[#1, "Real"], Image[Import[#2], "Real"]] &,
Import[#[[1]]], #[[2 ;;]]], 1/Length[#]] &,
imghs[[1 ;; -1 ;; 6, 1 ;; 100]]];]
{61.559226, Null}
DistributeDefinitions[i];
AbsoluteTiming[
means2 = ParallelMap[(i = Image[Import[#[[1]]], "Real"];
Do[i = ImageAdd[i, Image[Import[img]]], {img, #[[2 ;;]]}];
i = ImageMultiply[i, 1/Length[#]]) &,
imghs[[1 ;; -1 ;; 6, 1 ;; 100]]];]
{42.876076, Null}
DistributeDefinitions[i];
AbsoluteTiming[
means3 = ParallelMap[(i = Import[#[[1]], "Data"];
Do[i += Import[img, "Data"], {img, #[[2 ;;]]}];
i *= 1/Length[#]; Image[i]) &, imghs[[1 ;; -1 ;; 6, 1 ;; 100]]];]
{114.549350, Null}
SetSharedVariable[j];
AbsoluteTiming[
means4 = Map[(j = Import[#[[1]], "Data"];
ParallelDo[j += Import[img, "Data"], {img, #[[2 ;;]]}];
j *= 1/Length[#]; Image[j]) &, imghs[[1 ;; -1 ;; 6, 1 ;; 100]]];]
{303.752849, Null}
I had expected the Fold method to be the fastest, but it turns out this was not the case. I experimented with different combinations of parallelization and import formats and the second method is the fastest that I can achieve. Are there other options to speed up the stacking? I am aware of this question but that involves a single multi-frame .tiff image so I can't use those methods.
Foldmethod you have an extra image constructor call in every step. Try moving it around theImportin the second argument. A much greater speed-up should come by usingImage`ImportExportDump`ImageReadJPEGin place ofImport. – Batracos May 17 '18 at 08:28