0
$\begingroup$

I want to calculate the mean brightness and the standard deviation of columns in a gray scale image (8bit).

Can the following calculation code be made faster or/and shorter:

imageData = ImageData[Import["https://i.sstatic.net/i6qjE.png"], "Byte"];

dim = Dimensions@imageData;
list = Range@dim[[2]];

meanColumnBrightness = Mean@imageData[[All, #]] & /@ list;
stdDevColumnBrightness = StandardDeviation@imageData[[All, #]] & /@ list;

The result is:

Needs["ErrorBarPlots`"];

yWithErrors = 
 Transpose[{Transpose[{list, meanColumnBrightness}], 
   ErrorBar /@ stdDevColumnBrightness}]

Show[ErrorListPlot[yWithErrors], Joined -> True, PlotStyle -> {Blue}, 
 Epilog -> {PointSize[Small], 
   Point[Transpose[{list, meanColumnBrightness}]]}, PlotRange -> All, 
 Frame -> True, FrameLabel -> {{"y", ""}, {"x", ""}}, 
 BaseStyle -> {FontSize -> 20, FontFamily -> "Calibri"}, 
 ImageSize -> 600]

enter image description here

$\endgroup$
4
  • $\begingroup$ why not Transpose? $\endgroup$
    – Wjx
    Commented Jul 20, 2016 at 8:11
  • $\begingroup$ Please post your solution? $\endgroup$
    – mrz
    Commented Jul 20, 2016 at 8:12
  • $\begingroup$ actually, for mean part, simply do Mean will be okay $\endgroup$
    – Wjx
    Commented Jul 20, 2016 at 8:12
  • $\begingroup$ same image output~ great~ $\endgroup$
    – Wjx
    Commented Jul 20, 2016 at 8:25

1 Answer 1

4
$\begingroup$

A few points to make here:

  1. Always use Listable attributes of functions, that will speed things up.

  2. When unnecessary, do not use symbolic processing, use numeric processing instead.

Thus, I'll first change the data to N form, then use Listable attributes of Mean and StandardDeviation to get the result in a shorter and faster code.

imgd = N@imageData;
Mean@imgd; // AbsoluteTiming
StandardDeviation@imgd; // AbsoluteTiming

The Mean part accelerated for 10 times while the StandardDeviation part accelerated for 100 times.

Hope this can help you.


Edit 1

When calculating in rows, try using "/@" instead of simple Transpose will be a good choice:

imgd = N@imageData;
a = Mean /@ imgd; // AbsoluteTiming
b = StandardDeviation /@ imgd; // AbsoluteTiming

Actually I think this will be slower than Transpose at the first place, but as the result shows that this is a better solution, let's use this one.

I'm quite confused why this form is slower, I always consider using one function's Listable form will be better than /@. Intriguing......

So similarly, if you want to speed it up instead of making the code short, for your first problem, you can use this either......

imgd = N@Transpose@imageData;
a = Mean /@ imgd; // AbsoluteTiming
b = StandardDeviation /@ imgd; // AbsoluteTiming
$\endgroup$
3
  • $\begingroup$ This is incredible ... wau ... how would you do it when you want to calculate the mean and standard deviation in rows instead of columns? $\endgroup$
    – mrz
    Commented Jul 20, 2016 at 8:38
  • 1
    $\begingroup$ edited~ in edit 1you can find out how to calculate them in rows. $\endgroup$
    – Wjx
    Commented Jul 20, 2016 at 8:44
  • $\begingroup$ Great solution ... $\endgroup$
    – mrz
    Commented Jul 20, 2016 at 8:46

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.