3

I am having a very difficult time vectoring, I can't seem to think about math in that way yet. I have this right now:

#!/usr/bin/env python

import numpy as np
import math

grid = np.zeros((2,2))
aList = np.arange(1,5).reshape(2,2)

i,j = np.indices((2,2))

iArray =  (i - aList[:,0:1]) 
jArray = (j - aList[:,1:2])

print np.power(np.power(iArray, 2) + np.power(jArray, 2), .5)

My print out looks like this:

[[ 2.23606798  1.41421356]
 [ 4.47213595  3.60555128]]

What I am trying to do is take a 2D array of pixel values, grid, and say how far each pixel is from a list of important pixels, aList.

# # @ 
# # #
* # *

An example is if the *s (0,2) and (2,2) are important pixels and I am currently at the @ (2,0) pixel, my value for the @ pixel would be:

[(0-2)^2 + (2-0)^2]^.5 + [(2-2)^2 + (0-2)^2]^.5

All grid does is hold pixel values so I need to get the index of each pixel value to associate distance. However my Alist array holds [x,y] coordinates, So that one is easy. I think I right now I have two issues: 1. I am not getting the indeces correctly 2. I am not looping over the coordinates in aList properly

2
  • 1
    Just a note: if your example is using array indices, then the coordinates of *s are (2,0), (2,2) and @ is (0, 2). Commented Jul 3, 2013 at 17:15
  • You could try to create a distance array for each of your "important points". dist2 = lambda index_array, i, j: (index_array[0]-i)**2 + (index_array[1]-j)**2, where index_array = np.indices((N,N)). This yields a mesh where each point is the distance^2 from the important point (i, j). Create one of these for each important point, then np.sqrt(sum(dist_arrays)) to get the combined distance from all important points. Commented Jul 3, 2013 at 17:28

2 Answers 2

3

With a little help from broadcasting, I get this, with data based on your last example:

import numpy as np

grid = np.zeros((3, 3))
aList = np.array([[2, 0], [2, 2]])

important_rows, important_cols = aList.T
rows, cols  = np.indices(grid.shape)

dist = np.sqrt((important_rows - rows.ravel()[:, None])**2 +
               (important_cols - cols.ravel()[:, None])**2).sum(axis=-1)
dist = dist.reshape(grid.shape)

>>> dist
array([[ 4.82842712,  4.47213595,  4.82842712],
       [ 3.23606798,  2.82842712,  3.23606798],
       [ 2.        ,  2.        ,  2.        ]])

You can get more memory efficient by doing:

important_rows, important_cols = aList.T
rows, cols = np.meshgrid(np.arange(grid.shape[0]),
                         np.arange(grid.shape[1]),
                         sparse=True, indexing='ij')
dist2 = np.sqrt((rows[..., None] - important_rows)**2 +
                (cols[..., None] - important_cols)**2).sum(axis=-1)
Sign up to request clarification or add additional context in comments.

1 Comment

Very good answer! For an array of 3000x3000 is at least 1.73 times faster that my solution...
1

My approach:

import numpy as np

n = 3

aList = np.zeros([n,n])
distance = np.zeros([n,n])

I,J = np.indices([n,n])

aList[2,2] = 1; aList[0,2] = 1   #Importan pixels
important = np.where(aList == 1) #Where the important pixels are

for i,j in zip(I[important],J[important]):   #This part could be improved...
    distance += np.sqrt((i-I)**2+(j-J)**2)

print distance

The last 'for' could be improved, but if you have only a few important pixels, the performance will be good...


Checking with:

import matplotlib.pyplot as plt

n = 500

...

aList[249+100,349] = 1; aList[249-100,349] = 1 ;aList[249,50] = 1

...

plt.plot(I[important],J[important],'rx',markersize=20)
plt.imshow(distance.T,origin='lower',
           cmap=plt.cm.gray)
plt.show()

The result is very comfortable:

enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.