Результат 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)

02x02 плитка: Плитка 2х2

10x10 плитка: Плитка 10х10

Вплоть до того, что я использовал 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 должен был быть изменен, чтобы соответствовать форме других поверхностей.

Другие вопросы по тегам