7
$\begingroup$

Imagine I have a stack of image frames, $(f_1, ..., f_N) \in F$, where each $f_i$ has the same set of $(x,y)$ dimensions. Using these frames, I'd like to create an image where each pixel in the image consists of the standard deviation of the values at the corresponding pixel position in each of the $f_i$.

Unfortunately, the following procedure is painfully slow (when applied to a $256 \times 256$ pixel image):

SDImage = ImageData@FrameStack[[1]];
  For[a = 1, a <= ImageDimensions[FrameStack[[1]]][[1]], a++,
    For[b = 1, b <= ImageDimensions[FrameStack[[1]]][[2]], b++,
     SDImage[[a, b]] = StandardDeviation[Table[ImageData[FrameStack[[k]]][[a, b]], {k, 1, Length[FrameStack]}]];
     Print[SDImage[[a, b]]];
    ];
  ];

SDImage = Image[SDImage]  

Is there a faster method of doing this, or perhaps a built in tool (like in ImageJ)?

$\endgroup$
3
  • 2
    $\begingroup$ By the way: The code you posted in your question might be painful slow because the procedural nature of the code. Trying to avoid For loops and using Mathematica build in functions is always a good way in making the code more efficient. $\endgroup$
    – g3kk0
    Jul 27, 2013 at 8:15
  • $\begingroup$ Related: Averagind 2D datasets. Or different approach for work with multiple images. Offtop: try to avoid you variable names starting with capital letters. $\endgroup$
    – Kuba
    Jul 27, 2013 at 8:16
  • $\begingroup$ "why loops in Mathematica are slow" $\endgroup$
    – cormullion
    Jul 27, 2013 at 11:02

3 Answers 3

8
$\begingroup$

Assuming you have loaded a stack of images and stored in a variable called imageStack you can do the following to compute the standard deviation image over the entire stack:

imageStack = Import["ExampleData/CTengine.tiff"];
xyStd = Image@Thread[StandardDeviation[ImageData /@ imageStack], {1}];

This gives you the standard deviation image in z direction of the stack. For the upper example xyStd gives the following image:

Standard deviation image of engine example.

Edit

As Kuba pointed out, a better solution would be:

StandardDeviation[ImageData /@ imageStack]
$\endgroup$
3
  • 2
    $\begingroup$ StandardDeviation[ImageData /@ imageStack] is enough. $\endgroup$
    – Kuba
    Jul 27, 2013 at 8:02
  • $\begingroup$ @Kuba: right, thanks ;) $\endgroup$
    – g3kk0
    Jul 27, 2013 at 8:11
  • $\begingroup$ No problem :) I've made that mistake here $\endgroup$
    – Kuba
    Jul 27, 2013 at 8:15
6
$\begingroup$

This is about 100 times faster than g3kk0's answer on my machine---the results are identical:

imageStack = Image[ColorCombine@Import["ExampleData/CTengine.tiff", "ImageList"], "Real"];
ImageApply[StandardDeviation, imageStack]
$\endgroup$
2
  • $\begingroup$ I can confirm the speedup. Thank you! $\endgroup$ Jul 31, 2013 at 5:23
  • $\begingroup$ Nice usage of ColorCombine and ImageApply. I can confirm a speedup of about 25 fold compared to my version. $\endgroup$
    – g3kk0
    Jul 31, 2013 at 9:51
2
$\begingroup$

I wondered whether the built-in StandardDeviationFilter would work here (on Alexander's imageStack).

 StandardDeviationFilter[
 Image3D[
  imageStack, 
  ColorFunction -> "LowRange"],
 {Length[imageStack], 1, 1}]

filtered engine

It kind of works - but it's probably not the solution you're looking for.

$\endgroup$
8
  • $\begingroup$ That's a good suggestion - but I previously tried this, and in my particular case, the results are radically different. $\endgroup$ Jul 27, 2013 at 12:30
  • $\begingroup$ @SparsePine Oh. $\endgroup$
    – cormullion
    Jul 27, 2013 at 12:32
  • $\begingroup$ Perhaps this is better StandardDeviationFilter[Image3D[imageStack], {Ceiling@Length[imageStack]/2, 0, 0}] -- the last arguments are radii. But it's several times slower than Alexander Schmitz's. $\endgroup$
    – Michael E2
    Jul 27, 2013 at 12:42
  • $\begingroup$ @cormullion Sorry, I think I came off as a bit rude there. That really wasn't my intention. I just meant to say that I tried the filter, and it just didn't work very well in my particular case. Thank you for your answer! $\endgroup$ Jul 27, 2013 at 12:53
  • $\begingroup$ @SparsePine No, I didn't think that... I was just surprised that you'd tried it. It's always worth mentioning what you've tried (and providing a small sample of your data). Image3d isn't very quick or dependable on my machine anyway... $\endgroup$
    – cormullion
    Jul 27, 2013 at 13:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.