Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I got a piece of artwork in dimension of 20x20 pixels. I attempted to divide it into a 5x5 array of elements each of a smaller size of 4x4 pixels, and would like to find the mean color of the elements. I got the job done in a double for-loop. Is there a better way to do it? I need a faster way to treat much larger pieces.

enter image description here

avg = ConstantArray[0, {5, 5}];
image = Import[""] ;
idata = ImageData[image];
ddata = Partition[idata , {4, 4}, 4] ;
For[i = 1, i <= 5, i++,
 For[j = 1, j <= 5, j++,
  avg[[i, j]] = Mean@Flatten[ddata[[i, j]], 1 ];

This is what I got:

Mathematica graphics

share|improve this question
up vote 15 down vote accepted

Here is a way to achieve this:

img = Import["file.jpg"];
data = ImageData[img];


Image @ Developer`PartitionMap[Mean[Flatten[#, 1]] &, data, {4, 4}, 4]

Mathematica graphics

share|improve this answer
Nice, I did not know about PartitionMap. That's super useful. – mfvonh Aug 24 '14 at 4:17
@mfvonh, I know. It's a gem I use often :) – RunnyKine Aug 24 '14 at 4:19

What you describe is nearly a linear downsampling of the image as achieved with ImageResize:

img = Import[""]

ImageResize[img, Scaled[1/4], Resampling -> "Linear"]

enter image description here

The values are not exact, presumably due to a different alignment of the resampling grid but I have not found a way to adjust that in this function.

share|improve this answer
I'm not sure, but my guess would be that the edge values surrounding a grid cell have some weight in the resampled mean value. There is, I believe, a theoretical reason for preferring this approach (at least for photographs) -- maybe one of our image experts will comment. Another strong reason is that ImageResize is quite a bit faster than the other current answers. (+1 of course.) – Michael E2 Aug 24 '14 at 16:42
@MichaelE2 Would you say that (42825) explains this issue, at least pragmatically? – Mr.Wizard Aug 24 '14 at 19:01
It seems to explain upsampling. Downsampling seems different. – Michael E2 Aug 24 '14 at 19:35
image = Import[""]
ImagePartition[image, {4, 4}] /. i_Image :> MeanFilter[i, 4] // ImageAssemble

enter image description here


For comparison:

image = Import[""];
rk = Image@Developer`PartitionMap[Mean[Flatten[#, 1]] &, %, {4, 4}, 4]
mf = ImagePartition[image, {4, 4}] /. i_Image :> MeanFilter[i, 4] // ImageAssemble
mw = ImageResize[image, Scaled[1/4], Resampling -> "Linear"]
{rk, mf, mw} = Show[#, ImageSize -> 200] & /@ ImageResize[#, 200] & /@ {rk, mf, mw}
ColorNegate /@ ImageSubtract @@@ Subsets[%, {2}]
ImageAdjust /@ %;
Transpose[{%%, %}] // GraphicsGrid

Rows are: rk-mf, rk-mw, mf-mw

enter image description here

share|improve this answer
The values produced by this method are also not exact as MeanFilter does not take a complete average of the image. Also, the "pixels" are really 4x4 sections. – Mr.Wizard Aug 24 '14 at 6:37
Thanks for the feedback, I wouldn't have picked up on that. – mfvonh Aug 24 '14 at 16:33
Clearly your result is closer to the OP's original, apart from the 4x4 "pixel" thing. – Mr.Wizard Aug 24 '14 at 19:05
Closer-ish -- there appear to be problems on the boundaries as you alluded to. And it's slow :) – mfvonh Aug 24 '14 at 19:30

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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