Averaging Overlapping Pixels in Sliding Window Operation

Hello,
I'm looking for an efficient way to average overlapping pixels which are result of sliding window operation.
To explain my self, imagine we have a 2D matrix (Image) - I. We operate a sliding window operation of window size of 5x5. Each window undergoes a transform, operation and then back.
Now, a certain pixel, I(i, j) appears in many windows (Actually 25).
I want to average all those 25 pixels (Same pixel just the result using different window).
This is for example a step in the BM3D algorithm.
Does anyone knows about efficient way to this in MATLAB?
The structure should be something like:
  1. Create the patches of the image (im2col can do that).
  2. Apply the operation in the patches.
  3. Average the same pixels from all patches it was involved in.
Thank You.

1 comentario

Matt J
Matt J el 3 de Oct. de 2014
Editada: Matt J el 3 de Oct. de 2014
Now, a certain pixel, I(i, j) appears in many windows (Actually 25).
I think you really mean a certain pixel (i,j). The notation I(i,j) would refer to a pixel value, not a pixel location.
I want to average all those 25 pixels (Same pixel just the result using different window).
Conversely, here, I think you mean 25 pixel values. If the pixel in question is the same pixel each time, there shouldn't be 25 of them. You're saying, I assume, that the same pixel location receives a different value from each of the 25 blocks that it belongs to.

Iniciar sesión para comentar.

 Respuesta aceptada

Matt J
Matt J el 3 de Oct. de 2014
Editada: Matt J el 3 de Oct. de 2014
Use accumarray(subs,val,[],@mean). I can't specify any further how to construct subs and val, because I don't know in what form your block data exists now. But basically "subs" will contain a list of the pixel positions and "val" the value associated with that pixel. You can have multiple occurrences of the same pixel location listed in subs each with a different val inherited from the different blocks.

3 comentarios

Hi,
Assume we have an Image I where [M, N] = size(I).
Moreover, the blocks of size [MM, MM] are result of blockMatrix = im2col(I, [MM, MM], 'sliding').
Does it answer your question?
Thank You.
Matt J
Matt J el 3 de Oct. de 2014
Editada: Matt J el 3 de Oct. de 2014
indices=reshape(1:M*N,[M,N]);
subs = im2col(indices, [MM, MM], 'sliding');
vals = im2col(I, [MM, MM], 'sliding');
result=accumarray(subs(:),vals(:))./accumarray(subs(:),1);
result=reshape(result,M,N);
I will check it and report back.
You seem to be the vectorization prince in this forum :-).
Thank You.

Iniciar sesión para comentar.

Más respuestas (2)

Image Analyst
Image Analyst el 3 de Oct. de 2014
There can be 25 window locations that contain pixel at location (i,j). Each of those windows has one output value and is placed into an output image at different locations corresponding to the center of the window. To average those output values, you'd use imfilter() or conv2() operating on the output image (not the input image).

4 comentarios

Royi Avital
Royi Avital el 3 de Oct. de 2014
Editada: Royi Avital el 3 de Oct. de 2014
I couldn't understand your answer.
To be clear, the sliding window operation returns the full block, not the center of it.
Now it means it returns 25 pixels, yet it pixel is also part of 25 others blocks.
Now, I need an effective method to average all those 25 pixels which are the same pixel location in the input image, yet they are different places on each patch.
Did I succeed explaining the case?
Thank You.
Image Analyst
Image Analyst el 3 de Oct. de 2014
Editada: Image Analyst el 3 de Oct. de 2014
That's a different explanation - now you're saying to average all 25 pixels in a single window centered around (i,j) and what you said before was to look at 25 different windows that contain pixel (i,j): "pixel I(i, j) appears in many windows (Actually 25)." Those are different things - different numbers of windows.
What you just described in your comment is simply the convolution!
output = conv2(double(grayImage), ones(5)/25, 'same');
No, I guess I wasn't clear.
Again, think of im2col([5, 5], 'sliding'). You get many patches of 5 x 5.
Lets say we do something on each patch. The result is the filtered patch.
Now, do you agree the same pixel in the original image is now filtered in 25 different patches?
Now, I want to aggregate all those and average them.
I have a hard time visualizing what im2col does(). What is your overall objective? To blur the image?

Iniciar sesión para comentar.

Royi Avital
Royi Avital el 27 de Mayo de 2017
Editada: Royi Avital el 27 de Mayo de 2017
Another option would be:
I = reshape(accumarray(mIdx(:), mZ(:), [(M * N), 1], @(x) mean(x)), [M, N]);
Where `mZ` is the result of Image To Column and `mIdx` is the result:
mI = im2col(reshape(1:(M * N), [M, N]), modeOfOperation);

Preguntada:

el 3 de Oct. de 2014

Editada:

el 27 de Mayo de 2017

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by