0

I need to calculate the remapped coordinates of two known points within a volume after application of scipy.ndimage.interpolation.affine_transform with a rotation matrix I've generated.

In addition to being rotated during affine_transform, the output array is also padded compared to the input array to take into account the fact that the rotated volume may fall outside the bounds of the original array's shape.

I have the coordinates of the two known points in the volume before transformation (xb1,yb1,zb1) and (xb2,yb2,zb2). I want to know what the new position of those coordinates are after affine transformation and expansion of the array (xa1,ya1,za1) & (za2, ya2, za2). In affine_transform, the rotation is performed at the mid point between (xb1,yb1,zb1) and (xb2,yb2,zb2) at the center of the volume.

Edit: What I've tried so far: I made a zeros array of the same shape as the volume I'm tranforming. The two elements in the zeros array corresponding to the two starting points are set to two 32bit integers, 1000 for one, 5000 for the other. I then transform the marked zeros array with the same transformation matrix as the volume, and then after affine_transform with a spline order of 0 (to maintain the starting element values in the transformed array), I just use np.any to return the index of the 1000 and 5000 elements in the transformed array. This works OK, but there are instances where during the process of affine_transform, one point can go "missing" - probably through interpolation with a spline order of 0 (no spline). So this doesn't work in all cases.

kabammi
  • 326
  • 3
  • 14
  • Use the rotation matrix to transform the points. – MB-F Oct 31 '17 at 07:44
  • thanks kazemakase, that's useful, but the rotation pivot is the centre point between the initial start & end points (which isn't the center of the array the volume is in). affine_transform also remaps the pivot point to the array center. Maybe I can apply the transform to the start & end points like https://stackoverflow.com/questions/12148351/efficiently-rotate-a-set-of-points-with-a-rotation-matrix-in-numpy & then calculate the translation required to move the pivot point to the center of the array & apply the same translation to both start and end points. This might work. – kabammi Oct 31 '17 at 22:42

1 Answers1

0

I have got it working in a rather roundabout way, leading from kazemakase's first suggestion.

I first calculate the rotation matrix for the intial points, p1 and p2. This is te same matrix used for transformation of the volume in the array (shifting the points vector pV = p2-p1 to [0,1,0]. I did this using code modified from: Imprecision with rotation matrix to align a vector to an axis

Using the rotation matrix, I then calculate the rotated point positions with:

p1Dest = np.dot(p1, rotation_matrix.T)
p2Dest = np.dot(p2, rotation_matrix.T)

I then determine the center coordinate between p1Dest and p2Dest (I use a bresenham line calcuation, and aquire the median value -- http://code.activestate.com/recipes/578112-bresenhams-line-algorithm-in-n-dimensions/). I'll call it pDCenter.

Then to move pdCenter to the center of the array, I first determine the center of the array of the transformed volume (I'll call it cArrayT). I used a hacky method.

def centreOfArray(array):
    centerList = []
    for d in array.shape:
        centerOfAxis = np.int(d/2.)
        centerList.append(centerOfAxis)
    return np.asarray(centerList)

With both centers, I then calculate pTransl = pDCenter-cArrayT. Then subtract pTransl from p1Dest and p2Dest, and I have my final coordinates.

I'm sure there's probably a significantly easier method, but this seems to work for me.

kabammi
  • 326
  • 3
  • 14