# Irregular image binning

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"]]


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

• to literally simulate hardware binning you want to Partiton the image and take the mean of each subset. – george2079 Sep 21 '16 at 1:26
• ImagePartition / NeatExamples? – Kuba Sep 21 '16 at 10:04
• It is related to my question here: mathematica.stackexchange.com/questions/101678/… – 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}]]


ImageDimensions[%]
(* {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]


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

• Doesn't fit my application, but interesting. I wasn't aware of ColorQuantize. – dionys Sep 21 '16 at 7:42
• 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 ) – george2079 Sep 21 '16 at 15:56
• This is also what dithering is about... locally increasing the number of bins... – bill s Sep 21 '16 at 16:03
ImageAssemble@
Map[ColorQuantize[#, 1] &, ImagePartition[img, {10, 10}], {2}]


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


3

then bin it..

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


95

• For some reason, the bins are always square ... I get the same for {1,10} and {10,10}. – dionys Sep 21 '16 at 15:57
• 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. – george2079 Sep 21 '16 at 16:14
• 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. – dionys Sep 21 '16 at 16:29