Наклоните диагональный градиент, чтобы он был вертикальным

У меня есть не совсем линейный градиент под некоторым углом к ​​горизонтали как изображение. Вот некоторые данные игрушек:

g = np.ones((5,20))
for x in range(g.shape[0]):
    for y in range(g.shape[1]):
        g[x,y] += (x+y)*0.1+(y*0.01)

диагональный градиент

Я хочу существенно исправить перекос в градиенте, чтобы он был горизонтальным, т.е. градиент увеличивался вправо, а все вертикальные срезы были постоянными.

Это, конечно, создаст параллелограмм с большей осью x, чем входное изображение. Возврат замаскированного массива Numpy был бы идеальным. Вот (ужасный) мультфильм, чтобы быстро проиллюстрировать.

введите здесь описание изображения

Есть идеи, как этого добиться? Спасибо!


person Joe Flip    schedule 29.09.2016    source источник
comment
возможный дубликат stackoverflow.com/questions/33085142/skewing- массив-в-питоне ?   -  person dnalow    schedule 29.09.2016
comment
@dnalow Это близко, но это решение не интерполируется. Как я указал в описании, это не совсем линейный градиент, поэтому нужно сделать больше, чем просто перекос. Я предполагаю, что каждая строка должна быть интерполирована до значений нижней строки, прежде чем они будут переведены в x.   -  person Joe Flip    schedule 29.09.2016


Ответы (1)


Вы можете интерполировать, чтобы определить асимметрию, и снова интерполировать, чтобы исправить ее.

import numpy as np
from scipy.ndimage.interpolation import map_coordinates

m, n = g.shape
j_shift = np.interp(g[:,0], g[0,:], np.arange(n))
pad = int(np.max(j_shift))
i, j = np.indices((m, n + pad))
z = map_coordinates(g, [i, j - j_shift[:,None]], cval=np.nan)

Это работает на примере изображения, но вам нужно выполнить некоторые дополнительные проверки, чтобы заставить его работать с другими градиентами. Однако он не работает с градиентами, которые нелинейны в направлении x. Демо:

демонстрация

Полный сценарий:

import numpy as np
from scipy.ndimage.interpolation import map_coordinates

def fix(g):
    x = 1 if g[0,0] < g[0,-1] else -1
    y = 1 if g[0,0] < g[-1,0] else -1
    g = g[::y,::x]

    m, n = g.shape
    j_shift = np.interp(g[:,0], g[0,:], np.arange(n))
    pad = int(np.max(j_shift))
    i, j = np.indices((m, n + pad))
    z = map_coordinates(g, [i, j - j_shift[:,None]], cval=np.nan)

    return z[::y,::x]

import matplotlib.pyplot as plt

i, j = np.indices((50,100))
g = 0.01*i**2 + j

plt.figure(figsize=(6,5))
plt.subplot(211)
plt.imshow(g[::-1], interpolation='none')
plt.title('original')
plt.subplot(212)
plt.imshow(fix(g[::-1]), interpolation='none')
plt.title('fixed')
plt.tight_layout()
person user6758673    schedule 01.10.2016