2016-01-27 9 views
0

У меня есть простая матрица преобразования 2x2, ей, который кодирует некоторый хвостовик преобразование координат таким образом, что X»= Sx.Применение Быстрого преобразования координат в Python

Я создал набор uniformley распределенных координат на сетке с использованием np.meshgrid() функции и в данный момент я траверсировать каждую координату и применить преобразование координат на координатном уровне. К сожалению, это очень медленно для больших массивов. Есть ли быстрые способы сделать это? Благодаря!

import numpy as np 

image_dimension = 1024 
image_index = np.arange(0,image_dimension,1) 
xx, yy = np.meshgrid(image_index,image_index) 

# Pre-calculated Transformation Matrix. 
s = np.array([[ -2.45963439e+04, -2.54997726e-01], [ 3.55680731e-02, -2.48005486e+04]]) 

xx_f = xx.flatten() 
yy_f = yy.flatten() 

for x_t in range(0, image_dimension*image_dimension): 

    # Get the current (x,y) coordinate. 
    x_y_in = np.matrix([[xx_f[x_t]],[yy_f[x_t]]]) 

    # Perform the transformation with x. 
    optout = s * x_y_in 

    # Store the new coordinate. 
    xx_f[x_t] = np.array(optout)[0][0] 
    yy_f[x_t] = np.array(optout)[1][0] 

# Reshape Output 
xx_t = xx_f.reshape((image_dimension, image_dimension)) 
yy_t = yy_f.reshape((image_dimension, image_dimension)) 

ответ

2

Loops медленно в Python. Лучше использовать vectorization. Вкратце, идея состоит в том, чтобы позволить numpy делать циклы на C, что намного быстрее.

Вы можете выразить свою задачу в качестве матричных умножений X»= Sx, где вы поставите все точки в X и превратить их всех только один вызов к продукту точки Numpy в:

xy = np.vstack([xx.ravel(), yy.ravel()]) 
xy_t = np.dot(s, xy) 
xx_t, yy_t = xy_t.reshape((2, image_dimension, image_dimension)) 
+0

отлично смотрится! попробуем его –

+0

@kazemakase Я определил ваш ответ, и я нашел его намного быстрее, чем мой, видимо, 'vstack' намного быстрее, чем любая комбинация' array (list) 'и передавая непосредственно список. У вас есть идея, почему? –

+0

@NoelSegura Я предполагаю, что это связано с тем, что я использовал 'ravel' вместо вашего' flatten'. Если я правильно прочитал документы, 'flatten' всегда создает копию массива, а' ravel' пытается создать представление. – kazemakase

4

Вы можете использовать функцию NumPy dot получить скалярное произведение вашего matices как:

xx_tn,yy_tn = np.dot(s,[xx.flatten(),yy.flatten()]) 

xx_t = xx_tn.reshape((image_dimension, image_dimension)) 
yy_t = yy_tn.reshape((image_dimension, image_dimension)) 

который гораздо быстрее

+0

большого, спасибо за это попробуем это –