Utility routines for working with points and affine transforms
append_diag(aff, steps[, starts]) | Add diagonal elements steps and translations starts to affine |
apply_affine(aff, pts) | Apply affine matrix aff to points pts |
dot_reduce(*args) | Apply numpy dot product function from right to left on arrays |
from_matvec(matrix[, vector]) | Combine a matrix and vector into an homogeneous affine |
to_matvec(transform) | Split a transform into its matrix and vector components. |
Add diagonal elements steps and translations starts to affine
Typical use is in expanding 4x4 affines to larger dimensions. Nipy is the main consumer because it uses NxM affines, whereas we generally only use 4x4 affines; the routine is here for convenience.
Parameters: | aff : 2D array
steps : scalar or sequence
starts : scalar or sequence
|
---|---|
Returns: | aff_plus : 2D array
|
Examples
>>> aff = np.eye(4)
>>> aff[:3,:3] = np.arange(9).reshape((3,3))
>>> append_diag(aff, [9, 10], [99,100])
array([[ 0., 1., 2., 0., 0., 0.],
[ 3., 4., 5., 0., 0., 0.],
[ 6., 7., 8., 0., 0., 0.],
[ 0., 0., 0., 9., 0., 99.],
[ 0., 0., 0., 0., 10., 100.],
[ 0., 0., 0., 0., 0., 1.]])
Apply affine matrix aff to points pts
Returns result of application of aff to the right of pts. The coordinate dimension of pts should be the last.
For the 3D case, aff will be shape (4,4) and pts will have final axis length 3 - maybe it will just be N by 3. The return value is the transformed points, in this case:
res = np.dot(aff[:3,:3], pts.T) + aff[:3,3:4]
transformed_pts = res.T
This routine is more general than 3D, in that aff can have any shape (N,N), and pts can have any shape, as long as the last dimension is for the coordinates, and is therefore length N-1.
Parameters: | aff : (N, N) array-like
pts : (..., N-1) array-like
|
---|---|
Returns: | transformed_pts : (..., N-1) array
|
Examples
>>> aff = np.array([[0,2,0,10],[3,0,0,11],[0,0,4,12],[0,0,0,1]])
>>> pts = np.array([[1,2,3],[2,3,4],[4,5,6],[6,7,8]])
>>> apply_affine(aff, pts)
array([[14, 14, 24],
[16, 17, 28],
[20, 23, 36],
[24, 29, 44]]...)
Just to show that in the simple 3D case, it is equivalent to:
>>> (np.dot(aff[:3,:3], pts.T) + aff[:3,3:4]).T
array([[14, 14, 24],
[16, 17, 28],
[20, 23, 36],
[24, 29, 44]]...)
But pts can be a more complicated shape:
>>> pts = pts.reshape((2,2,3))
>>> apply_affine(aff, pts)
array([[[14, 14, 24],
[16, 17, 28]],
[[20, 23, 36],
[24, 29, 44]]]...)
Apply numpy dot product function from right to left on arrays
For passed arrays \(A, B, C, ... Z\) returns \(A \dot B \dot C ... \dot Z\) where ”.” is the numpy array dot product.
Parameters: | **args : arrays
|
---|---|
Returns: | dot_product : array
|
Combine a matrix and vector into an homogeneous affine
Combine a rotation / scaling / shearing matrix and translation vector into a transform in homogeneous coordinates.
Parameters: | matrix : array-like
vector : None or array-like, optional
|
---|---|
Returns: | xform : array
|
See also
Examples
>>> from_matvec(np.diag([2, 3, 4]), [9, 10, 11])
array([[ 2, 0, 0, 9],
[ 0, 3, 0, 10],
[ 0, 0, 4, 11],
[ 0, 0, 0, 1]])
The vector argument is optional:
>>> from_matvec(np.diag([2, 3, 4]))
array([[2, 0, 0, 0],
[0, 3, 0, 0],
[0, 0, 4, 0],
[0, 0, 0, 1]])
Split a transform into its matrix and vector components.
The tranformation must be represented in homogeneous coordinates and is split into its rotation matrix and translation vector components.
Parameters: | transform : array-like
|
---|---|
Returns: | matrix : (N-1, M-1) array
vector : (M-1,) array
|
See also
Examples
>>> aff = np.diag([2, 3, 4, 1])
>>> aff[:3,3] = [9, 10, 11]
>>> to_matvec(aff)
(array([[2, 0, 0],
[0, 3, 0],
[0, 0, 4]]), array([ 9, 10, 11]))