Результат scipy.ndimage.zoom зависит от размера изображения
Я заметил, что результат scipy.ndimage.zoom зависит от размера исходного изображения. В следующем примере кода создается изображение шахматной доски, а затем масштабируется с помощью ndimage.zoom. Если размер одной плитки шахматной доски составляет всего 2x2 пикселя, коэффициент масштабирования кажется слишком большим, и результирующее изображение обрезается. Напротив, если плитка имеет размеры 10х10, результат выглядит хорошо.
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)
Вплоть до того, что я использовал scipy.misc.imresize, который не показывает такое поведение, но я хочу избежать дополнительной зависимости от PIL.
Я делаю что-то не так или это ошибка увеличения?
1 ответ
Прошло уже много времени с тех пор, как вы опубликовали свой вопрос... на тот случай, если вы все еще заинтересованы, у меня возникла похожая проблема, и я использовал следующее:
import skimage
data_new = skimage.transform.resize(data_old, [new_shape_x, new_shape_z], order = 0)
Убедитесь, что вы установили order = 0, потому что по умолчанию это order = 1, что приведет к сплайн-интерполяции первого порядка между значениями (это заставит плитки размываться на их границах).
Во всяком случае, я не знаю, если это хороший способ сделать это, но у меня это сработало. Я не могу ответить, если это ошибка, потому что я действительно недостаточно знаю о программировании, чтобы ответить на этот вопрос. Кроме того, я также пытался использовать функцию scipy.ndimage.interpolation.zoom, но тогда границы плиток были не там, где они должны быть, как в вашем случае. Поэтому я использовал лыжный маг.
Если вам интересен контекст: я работал над механикой разрушения и мне нужно было создать случайные распределения прочности, которые плавно меняются. Таким образом, я создал поверхность с комбинацией синусной и косинусовой функций, которая имела определенное количество периодов в направлении x и z. Затем я взял абсолютную величину этой поверхности и умножил ее на неправильную шахматную поверхность. Количество плиток в каждом направлении на шахматной поверхности должно соответствовать количеству периодов /2 в соответствующей поверхности изменения прочности. Конечная поверхность была рассчитана следующим образом (кусочно сложение и умножение):
strength_surface[i,j] = strength_mean[i,j] + random_grid[i,j] * strength_variation[i,j]
где random_grid должен был быть изменен, чтобы соответствовать форме других поверхностей.