2015-11-15 522 views
2

我注意到scipy.ndimage.zoom的结果取决于原始图像的大小。在以下代码示例中,会生成棋盘图像,然后使用ndimage.zoom进行缩放。如果一个棋盘图像块仅为2×2像素,则缩放因子似乎太大,所得图像会被裁剪。相反,如果瓦片尺寸为10x10,结果看起来不错。scipy.ndimage.zoom结果取决于图像大小

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瓷砖:2x2 tile

10×10瓦:10x10 tile

就知道我一直在使用scipy.misc.imresize不显示此行为,但我想,以避免对额外的依赖PIL。

我做错了什么,或者这是一个缩放错误?

回答

1

i'ts已经有一段时间,因为你发布你的问题......如果你想继续,我有一个类似的问题,使用下列内容:

import skimage 
data_new = skimage.transform.resize(data_old, [new_shape_x, new_shape_z], order = 0) 

确保您设置顺序= 0 ,因为默认值是order = 1,这将导致值之间的一阶样条插值(这会导致图块在其边界模糊)。

无论如何,我不知道这是否是一个很好的方法来做到这一点,但它为我工作。我不能回答这是否是一个错误,因为我真的不知道编程如何回答这个问题。此外,我还尝试使用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不得不被调整大小以匹配其它表面的形状。