我注意到scipy.ndimage.zoom的结果取决于原始图像的大小。在下面的代码示例中,将生成一个棋盘图像,然后使用ndimage.zoom进行缩放。如果一个棋盘格拼贴仅为2x2像素,则缩放系数似乎太大,并且裁剪出了生成的图像。相反,如果图块的尺寸为10x10,则结果看起来不错。
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图块:
10x10片:
据我所知,我一直在使用scipy.misc.imresize,它不显示此行为,但我想避免对PIL的其他依赖。
我是在做错什么还是缩放错误?
最佳答案
自您发布问题以来已经有一段时间了...万一您仍然有兴趣,我也遇到了类似的问题,并使用了以下方法:
import skimage
data_new = skimage.transform.resize(data_old, [new_shape_x, new_shape_z], order = 0)
确保设置order = 0,因为默认值为order = 1,这将导致在值之间进行一阶样条插值(这将导致图块在其边界处模糊)。
无论如何,我不知道这是否是一个好方法,尽管它对我有用。如果是bug,我就无法回答,因为我对编程真的不了解。此外,我还尝试使用scipy.ndimage.interpolation.zoom函数,但是像您的情况一样,图块的边界不在应有的位置。因此,我使用了skimage。
如果您对上下文感兴趣:我研究了断裂力学,需要创建平滑变化的随机强度分布。因此,我创建了一个由窦和余弦函数组成的曲面,该曲面在x和z方向上具有一定数量的周期。然后,我获取该曲面的绝对值,然后将其乘以不规则的棋盘状曲面。在棋盘状表面上每个方向上的瓦片数必须与相应的强度变化表面中的周期数/2相匹配。最终表面的计算如下(逐段加法和乘法):
strength_surface[i,j] = strength_mean[i,j] + random_grid[i,j] * strength_variation[i,j]
其中random_grid必须调整大小以匹配其他曲面的形状。
关于python - scipy.ndimage.zoom结果取决于图像大小,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33721988/