python - Rebinning ndarray while conserving summation -
i looking function can used rebin ndarray
, satisfies:
- the result can arbitrary dimensions, either upscaling or downscaling.
- after rebinning, summation should same before.
- it should not change overall image shape. in other words, should reversible in case of upscaling.
second constraint not summation-normalization or something, rebinning algorithm should calculate fraction original array elements overlapped within resulting array elements.
third argument can tested in way:
# image ndarray shape of 20x20 func(image, func(image, [40,40]),[20,20])==image # if func works intended
so far aware of 2 functions, are
ndarray.resize
: don't understand does, not looking for.scipy.misc.imresize
: interpolates values of each element, not purpose.
but not satisfy conditions mentioned. example, attached code argue behaviour of scipy.misc.imresize
.
import numpy np scipy.special import erf import matplotlib.pyplot plt scipy.misc import imresize def gaussian(size, center, width, a): xcoord=np.arange(size[0])[:,np.newaxis]+np.zeros(size[1])[np.newaxis,:] ycoord=np.zeros(size[0])[:,np.newaxis]+np.arange(size[1])[np.newaxis,:] return a*((erf((xcoord+1-center[0])/(width[0]*np.sqrt(2)))-erf((xcoord-center[0])/(width[0]*np.sqrt(2))))* (erf((ycoord+1-center[1])/(width[1]*np.sqrt(2)))-erf((ycoord-center[1])/(width[1]*np.sqrt(2))))) size=np.asarray([20,20]) c=[[0.1,0.2],[0.4,0.6],[0.8,0.4]] c=[np.asarray(x) x in c] s=[[0.02,0.02],[0.05,0.05],[0.03,0.01]] s=[np.asarray(x) x in s] im = gaussian(size, c[0]*size, s[0]*size, 1) \ +gaussian(size, c[1]*size, s[1]*size, 3) \ +gaussian(size, c[2]*size, s[2]*size, 2) sciim=imresize(imresize(im,[40,40]),[20,20]) plt.imshow(im/np.sum(im)-sciim/np.sum(sciim)) plt.show()
so, there function, preferably built-in function package, satisfies requirements?
for other language, know frebin
in idl works mentioned. of course re-write function, or perhaps did it, wonder whether if there existing solution.
frebin
implements pixel duplication when expansion integer value (like 2x increase in toy problem). if want similar reversibility in such cases, try this:
def py_frebin(im, shape): if np.isclose(x.shape % shape , np.zeros.like(x.shape)): interp = 'nearest' else: interp = 'lanczos' im2 = scipy.misc.imresize(im, shape, interp = interp, mode = 'f') im2 *= im.sum() / im2.sum() return im2
should better frebin
in non-integer expansions (as frebin
seems doing interp = 'bilinear'
less reversible), , similar in integral expansions.
Comments
Post a Comment