Miringkan gradien diagonal menjadi vertikal

Saya memiliki gradien yang tidak terlalu linier pada sudut tertentu terhadap horizontal sebagai gambar. Berikut beberapa data mainan:

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)

gradien diagonal

Saya pada dasarnya ingin memperbaiki kemiringan gradien sehingga horizontal, yaitu gradien meningkat ke kanan dan semua irisan vertikal konstan.

Hal ini tentunya akan menghasilkan jajar genjang dengan sumbu x yang lebih besar dari gambar masukan. Mengembalikan array Numpy yang bertopeng akan ideal. Inilah kartun (yang buruk) untuk diilustrasikan dengan cepat.

masukkan deskripsi gambar di sini

Adakah yang tahu bagaimana cara mencapai ini? Terima kasih!


person Joe Flip    schedule 29.09.2016    source sumber
comment
kemungkinan duplikat stackoverflow.com/questions/33085142/skewing- sebuah-array-dalam-python ?   -  person dnalow    schedule 29.09.2016
comment
@dnalow Sudah dekat tetapi solusi itu tidak melakukan interpolasi. Seperti yang saya masukkan dalam deskripsi, ini bukan gradien linier jadi ada lebih dari sekedar kemiringan yang perlu dilakukan. Saya kira setiap baris perlu diinterpolasi ke nilai baris terbawah sebelum diterjemahkan ke dalam x.   -  person Joe Flip    schedule 29.09.2016


Jawaban (1)


Anda dapat melakukan interpolasi untuk menentukan kemiringan dan melakukan interpolasi lagi untuk memperbaikinya.

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)

Ini berfungsi pada gambar contoh, tetapi Anda harus melakukan beberapa pemeriksaan tambahan agar berfungsi pada gradien lain. Ini tidak berfungsi pada gradien yang nonlinier dalam arah x. Demo:

demo

Skrip lengkap:

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