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
, ...).
ImageMultiply[Fold[ImageAdd[#2, #1] &, 0, imgs], 1/Length[imgs]]
be suitable? $\endgroup$