Is there a good way to "bin" image data, which is analogous to hardware binning of a detector array? I'd like it to treat image data such that multiple values are averaged to form one mega-sample, giving the impression of a coarser detector array.

Here's an try with ImageResize and ArrayResample:

Module[{data, fn},
 data = ImageData@ColorConvert[ExampleData[{"TestImage", "Lena"}], "Grayscale"];
 fn = ImageResize[#, Scaled[5], Resampling -> "Nearest"] &;
 fn@Image@ArrayResample[data, Scaled[0.2], Resampling -> "Nearest"]]

enter image description here

I would like to set the bins with more flexibility, for instance, binning in a single dimension.

  • $\begingroup$ to literally simulate hardware binning you want to Partiton the image and take the mean of each subset. $\endgroup$ – george2079 Sep 21 '16 at 1:26
  • $\begingroup$ ImagePartition / NeatExamples? $\endgroup$ – Kuba Sep 21 '16 at 10:04
  • $\begingroup$ It is related to my question here: mathematica.stackexchange.com/questions/101678/… $\endgroup$ – Oleksandr R. Sep 21 '16 at 10:06
binPixels[img_, binSize_] /;Length[binSize]==2 :=
   Module[{pieces, avg},
          pieces = ImagePartition[img, {{1, binSize[[1]]}, {1, binSize[[2]]}}];
          avg = Mean@Flatten@ImageData[#] &;
          ImageAssemble@Table[Image@Array[(avg@pieces[[i, j]]) &, Reverse@binSize],
                              {i, First@Dimensions[pieces]}, {j, Last@Dimensions[pieces]}]]

With[{img = ColorConvert[ExampleData[{"TestImage", "Lena"}], "Grayscale"]},
      binPixels[img, {5, 10}]]

enter image description here

(* {515, 520} *)

ColorQuantize reduces the number of "colors" (in this case, of grey scale values), effectively binning pixels of the image.

ColorQuantize[ColorConvert[ExampleData[{"TestImage", "Lena"}], "Grayscale"], 3]

enter image description here

Use the Dithering->False option if you want the resulting image to not use dithering.

  • $\begingroup$ Doesn't fit my application, but interesting. I wasn't aware of ColorQuantize. $\endgroup$ – dionys Sep 21 '16 at 7:42
  • $\begingroup$ binning actually can increase the number of colors. Simple example if you take a 1-bit image and do 4 pixel binning you end up with 4 "colors" (that's exactly why its done in hardware you trade better dynamic range for lower resolution ) $\endgroup$ – george2079 Sep 21 '16 at 15:56
  • $\begingroup$ This is also what dithering is about... locally increasing the number of bins... $\endgroup$ – bill s Sep 21 '16 at 16:03
 Map[ColorQuantize[#, 1] &, ImagePartition[img, {10, 10}], {2}]

enter image description here

to illustrate the increased colors, suppose we start with bill's quantized image:

qimg = ColorQuantize[
   ColorConvert[ExampleData[{"TestImage", "Lena"}], "Grayscale"], 3];
Union@Flatten@ImageData[qimg] // Length


then bin it..

binned = ImageAssemble@
   Map[ColorQuantize[#, 1] &, ImagePartition[qimg, {4, 4}], {2}];
Union@Flatten@ImageData[binned] // Length


  • $\begingroup$ For some reason, the bins are always square ... I get the same for {1,10} and {10,10}. $\endgroup$ – dionys Sep 21 '16 at 15:57
  • $\begingroup$ with this approach each rectangular bin is replaced with a uniform bin of the same shape so the overall aspect ratio doesn't change. Try {10, 40} and I think you should see. $\endgroup$ – george2079 Sep 21 '16 at 16:14
  • $\begingroup$ I see what you mean. Looks like the partition spec is interpreted as {min,max} instead of {dx,dy}, as I had assumed, thinking in terms of pixel binning. $\endgroup$ – dionys Sep 21 '16 at 16:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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