3

Let's say I have a 5x5 matrix:

arr = np.arange(25).reshape((5,5))

array([[ 0,  1,  2,  3,  4],
   [ 5,  6,  7,  8,  9],
   [10, 11, 12, 13, 14],
   [15, 16, 17, 18, 19],
   [20, 21, 22, 23, 24]])

and I want to make a 3x3 matrix out of it by averaging over it.

enter image description here

this should be done in such a way, that the blue pixel should be made out of the included black pixels, the number weighted with the area within the blue pixel.

That means that of the vlaue of the second black pixel (value 1) 3/5(?) should be added to the first blue pixel, 2/5 to the second blue pixel

thanks

2
  • 1
    Please explain it with an example! Commented Nov 7, 2013 at 17:13
  • Ah that's better! And a very cool question once properly formulated. Commented Nov 7, 2013 at 19:22

2 Answers 2

2

It doesn't seem to me like you know what you really want. But what you describe for the top left cornber can be expanded to the whole array with scipy.signal.correlate, although it produces a 4x4 output, and you have the math wrong:

>>> import scipy.signal
>>> scipy.signal.correlate(np.arange(25).reshape(5, 5),
...                        [[1, 3/5], [3/5, 9/25]], 'valid') / 4
array([[  1.44,   2.08,   2.72,   3.36],
       [  4.64,   5.28,   5.92,   6.56],
       [  7.84,   8.48,   9.12,   9.76],
       [ 11.04,  11.68,  12.32,  12.96]])
Sign up to request clarification or add additional context in comments.

2 Comments

no that's not what I was looking for, If I want to produce a 4x4 matrix, it's no longer 3/5 of the next pixel but less... I want to take the amount of "area" of the next pixel into account, that is covered by the new bigger pixel
Well, if you can't even describe what you want precisely, then it's going to be kind of hard to help you code it. You may want to try to describe what you want that smaller matrix for.
2

It seems that you want to resample your image so that it's a different size. If so, then you could use scipy.ndimage.zoom:

import numpy as np
import scipy.ndimage

arr = np.arange(25).reshape((5,5))

resized_arr = scipy.ndimage.zoom(arr, 3. / 5)

print resized_arr.shape
print resized_arr

outputs:

(3, 3)

[[ 0  2  4]
 [10 12 14]
 [20 22 24]]

The idea is that you fit a function to the 2d surface defined by the pixels in your image -- in the case of zoom, the function is a parametric spline fit. Then once you have a function fit to your surface, you can obtain samples at whatever grid points you wish.

You can also use more complex functions to fit the original image. Check out scikits.samplerate for a nice wrapper over the "source rabbit code," a full-featured resampling library.

2 Comments

yeah looks, promising, but not exactly what I want, since this whole thing does not average at all, just takes every third value. I'm afraid that's not what I want
Hm, I see what you mean, but I think this is actually doing what you want at points that aren't on the edges of the image. If you always have to reduce a 5x5 image to a 3x3 image, then you might want to just hand-compute the averaging transform. Otherwise, if you're doing this on larger images, you should keep zoom in mind.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.