# How to calculate the mean of images?

In practice, subtracting the mean image from a dataset significantly improves classification accuracies. I thought there would be a ImageMean[] function but can't find one, so what is an efficient way to implement this for a list of given images of the same dimensions?

I typically calculate the mean image pixel values in C like this:

  const int channels = sum_blob.channels();
const int dim = sum_blob.height() * sum_blob.width();
std::vector<float> mean_values(channels, 0.0);

for (int c = 0; c < channels; ++c) {
for (int i = 0; i < dim; ++i) {
mean_values[c] += sum_blob.data(dim * c + i);
}
LOG(INFO) << "mean_value channel [" << c << "]:" << mean_values[c] / dim;
}


I need this to work for more than just a few images. Given a set of a few thousand images on filesystem, is there anyway of doing this without loading all the images into memory at the same time (which kills the front end).

This is what I have so far:

ImageMean[imgs_List] := Image@Mean[ImageData[#, "Real"] & /@ imgs]
imgs = Table[RandomImage[1, {256, 256}, ColorSpace -> "RGB"], {i, 10^5}];
AbsoluteTiming[ImageMean @ imgs]


This isn't giving me the save results as my c-code and it's slower than I think it can be (I'm not sure if it's correct in all colorspaces either). Plus it won't work for a large set of images that don't fit into memory all at once, it would be great if there is a way to enlist out-of-core methods (ImageFileApply, ImageFileFilter, ImageFileScan, ...).

• Why wouldn't ImageMultiply[Fold[ImageAdd[#2, #1] &, 0, imgs], 1/Length[imgs]] be suitable? – J. M. is away Aug 20 '15 at 19:31
• You may post your doubt about "(I'm not sure if it's correct in all colorspaces either)" in stackexchange DSP – Dr. belisarius Aug 20 '15 at 21:00

ImageAdd does some scaling/truncating, so cant be used directly for this purpose.

Try this, note for testing I'm averaging three copies of the same image and expect to recover the same image.

i0 = ExampleData[{"TestImage", "Boat"}];
imgs = {i0, i0, i0};
Image[Fold[ImageData[#2] + #1 &, 0 ImageData[i0] , imgs]/Length[imgs]]


here is the resuly of using ImageAdd/ImageMultiply

Performing the multiply first seems to fix this:

Fold[ImageAdd[ImageMultiply[#2, 1/Length[imgs]], #1] &, 0, imgs]


(watch for precision issues with large numbers of images though )

• Do you know which one is more generally used when normalizing a set of images for classifcation pipelines? – M.R. Aug 20 '15 at 19:53