2016-09-29 1 views
3

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

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) 

diagonal gradient

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

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

enter image description here

Любая идея, как этого добиться? Благодаря!

+0

возможно дубликат http://stackoverflow.com/questions/33085142/skewing-an-array-in-python? – dnalow

+0

@dnalow Это близко, но это решение не интерполирует. Как я сказал в описании, это не совсем линейный градиент, поэтому нужно сделать нечто большее, чем просто перекос, который нужно сделать. Я думаю, каждая строка должна быть интерполирована на значения нижней строки, прежде чем они будут переведены в x. –

ответ

1

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

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, хотя. Демонстрация:

demo

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

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() 
+0

Да! Это именно то, что я ищу. Спасибо! –