I noticed that the result of scipy.ndimage.zoom depends on the size of the original image. In the following code sample a checkerboard image is generated and then zoomed with ndimage.zoom. If one checkerboard tile is just 2x2 pixels, the zoom factor seems to be too large and the resulting image gets cropped. In contrast, if the tile has dimensions 10x10, the result looks good.
from __future__ import division
import numpy as np
from scipy import ndimage, misc
import wx
y,x = 2,2 # change tile size here
imgdata = np.zeros((y,x),dtype='uint8')
imgdata[y/2:,x/2:] = 255
imgdata[:y/2,:x/2] = 255
imgdata = np.tile(imgdata,(4,4))
imgdata = np.array((imgdata,imgdata,imgdata))
d,y,x = imgdata.shape
zoom = 200.0/y
w, h = int(x*zoom), int(y*zoom)
app = wx.App(None)
zoomed = np.ascontiguousarray(ndimage.interpolation.zoom(imgdata,[1,zoom, zoom],order=0).transpose((1,2,0)), dtype='uint8')
image = wx.ImageFromBuffer(w, h, zoomed)
image.SaveFile('zoomed.png',wx.BITMAP_TYPE_PNG)
02x02 tile:
10x10 tile:
Up to know I have been using scipy.misc.imresize which does not show this behaviour but I want to avoid the additional dependency on PIL.
Am I doing something wrong or is this a bug in zoom?
i'ts been a while since you posted your question... in case you're still interested, I had a similar problem and used the following:
import skimage
data_new = skimage.transform.resize(data_old, [new_shape_x, new_shape_z], order = 0)
Make sure you set order = 0, because the default is order = 1, which will result in a first order spline interpolation between the values (this causes the tiles to blur at their boundaries).
Anyway, I don't know if that's a good way to do it, it worked for me though. I can't answer if it's a bug, because I really don't know enough about programming to answer that. Furthermore I also tried to use the the scipy.ndimage.interpolation.zoom function, but then the boundaries of the tiles weren't where they should be, like in your case. Therefore I used skimage.
In case you're interested in the context: I worked on fracture-mechanics and needed to create random strength-distributions that are varying smoothly. So I created a surface with a combination of sinus and cosinus funcitons, that had a certain number of periods in x and z direction. Then I took the absolute value of that surface and multiplied it with an irregular chessboard-like surface. The numbers of tiles in each direction on the chessboard-like surface had to match the number of periods/2 in the corresponding strength-variation surface. The final surface was calculated as follows (piecewise addition and multiplication):
strength_surface[i,j] = strength_mean[i,j] + random_grid[i,j] * strength_variation[i,j]
where random_grid had to be resized to match the shape of the other surfaces.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With