How to set matrix element to mean of surrounding elements?

matlab, matrix, octave

Solution

This is probably not the most effective solution, but it should work.

N = size(M, 1);
target_ind = find(M);
offset = [-N-1, -N, -N+1, -1, 0, 1, N-1, N, N+1];

area_ind = bsxfun(@plus, offset, target_ind);
X(target_ind) = median(X(area_ind), 2);

Since all corrupted pixels are guaranteed to be surrounded by pixels, we can rather easily compute the linear indices of each corrupted pixel's neighbors. Here I've assumed that `X` is a grayscale image.

If `I` has more than one channel, then we could loop over each channel and add an offset to `target_ind` and `area_ind` each time:

for i = 1:size(X, 3)
    chan_offset = (i - 1)*size(X, 1)*size(X, 2) % Add the number of elements in previous channels to get indices in the current channel
    X(target_ind + chan_offset) = median(X(area_ind + chan_offset), 2);
end

Problem

I have a matrix `X` that represents an image that was affected by noise. I also have a boolean matrix `M` that represents which pixels were affected by noise. What I want to do is to set every 'corrupted' pixel to the mean of its eight neighboring pixels. Corrupted pixels are guaranteed to always be surrounded by uncorrupted ones, and also none of the pixels on the borders of the image are corrupted. What function can I used to write a vectorised version of this?

Original source

Related problems