pytorch3d.transforms

pytorch3d.transforms.acos_linear_extrapolation(x: Tensor, bounds: Tuple[float, float] = (-0.9999, 0.9999)) Tensor[source]

Implements arccos(x) which is linearly extrapolated outside x’s original domain of (-1, 1). This allows for stable backpropagation in case x is not guaranteed to be strictly within (-1, 1).

More specifically:

bounds=(lower_bound, upper_bound)
if lower_bound <= x <= upper_bound:
    acos_linear_extrapolation(x) = acos(x)
elif x <= lower_bound: # 1st order Taylor approximation
    acos_linear_extrapolation(x)
        = acos(lower_bound) + dacos/dx(lower_bound) * (x - lower_bound)
else:  # x >= upper_bound
    acos_linear_extrapolation(x)
        = acos(upper_bound) + dacos/dx(upper_bound) * (x - upper_bound)
Parameters:
  • x – Input Tensor.

  • bounds – A float 2-tuple defining the region for the linear extrapolation of acos. The first/second element of bound describes the lower/upper bound that defines the lower/upper extrapolation region, i.e. the region where x <= bound[0]/bound[1] <= x. Note that all elements of bound have to be within (-1, 1).

Returns:

acos_linear_extrapolationTensor containing the extrapolated arccos(x).

pytorch3d.transforms.axis_angle_to_matrix(axis_angle: Tensor) Tensor[source]

Convert rotations given as axis/angle to rotation matrices.

Parameters:

axis_angle – Rotations given as a vector in axis angle form, as a tensor of shape (…, 3), where the magnitude is the angle turned anticlockwise in radians around the vector’s direction.

Returns:

Rotation matrices as tensor of shape (…, 3, 3).

pytorch3d.transforms.axis_angle_to_quaternion(axis_angle: Tensor) Tensor[source]

Convert rotations given as axis/angle to quaternions.

Parameters:

axis_angle – Rotations given as a vector in axis angle form, as a tensor of shape (…, 3), where the magnitude is the angle turned anticlockwise in radians around the vector’s direction.

Returns:

quaternions with real part first, as tensor of shape (…, 4).

pytorch3d.transforms.euler_angles_to_matrix(euler_angles: Tensor, convention: str) Tensor[source]

Convert rotations given as Euler angles in radians to rotation matrices.

Parameters:
  • euler_angles – Euler angles in radians as tensor of shape (…, 3).

  • convention – Convention string of three uppercase letters from {“X”, “Y”, and “Z”}.

Returns:

Rotation matrices as tensor of shape (…, 3, 3).

pytorch3d.transforms.matrix_to_axis_angle(matrix: Tensor) Tensor[source]

Convert rotations given as rotation matrices to axis/angle.

Parameters:

matrix – Rotation matrices as tensor of shape (…, 3, 3).

Returns:

Rotations given as a vector in axis angle form, as a tensor

of shape (…, 3), where the magnitude is the angle turned anticlockwise in radians around the vector’s direction.

pytorch3d.transforms.matrix_to_euler_angles(matrix: Tensor, convention: str) Tensor[source]

Convert rotations given as rotation matrices to Euler angles in radians.

Parameters:
  • matrix – Rotation matrices as tensor of shape (…, 3, 3).

  • convention – Convention string of three uppercase letters.

Returns:

Euler angles in radians as tensor of shape (…, 3).

pytorch3d.transforms.matrix_to_quaternion(matrix: Tensor) Tensor[source]

Convert rotations given as rotation matrices to quaternions.

Parameters:

matrix – Rotation matrices as tensor of shape (…, 3, 3).

Returns:

quaternions with real part first, as tensor of shape (…, 4).

pytorch3d.transforms.matrix_to_rotation_6d(matrix: Tensor) Tensor[source]

Converts rotation matrices to 6D rotation representation by Zhou et al. [1] by dropping the last row. Note that 6D representation is not unique. :param matrix: batch of rotation matrices of size (*, 3, 3)

Returns:

6D rotation representation, of size (*, 6)

[1] Zhou, Y., Barnes, C., Lu, J., Yang, J., & Li, H. On the Continuity of Rotation Representations in Neural Networks. IEEE Conference on Computer Vision and Pattern Recognition, 2019. Retrieved from http://arxiv.org/abs/1812.07035

pytorch3d.transforms.quaternion_apply(quaternion: Tensor, point: Tensor) Tensor[source]

Apply the rotation given by a quaternion to a 3D point. Usual torch rules for broadcasting apply.

Parameters:
  • quaternion – Tensor of quaternions, real part first, of shape (…, 4).

  • point – Tensor of 3D points of shape (…, 3).

Returns:

Tensor of rotated points of shape (…, 3).

pytorch3d.transforms.quaternion_invert(quaternion: Tensor) Tensor[source]

Given a quaternion representing rotation, get the quaternion representing its inverse.

Parameters:

quaternion – Quaternions as tensor of shape (…, 4), with real part first, which must be versors (unit quaternions).

Returns:

The inverse, a tensor of quaternions of shape (…, 4).

pytorch3d.transforms.quaternion_multiply(a: Tensor, b: Tensor) Tensor[source]

Multiply two quaternions representing rotations, returning the quaternion representing their composition, i.e. the versor with nonnegative real part. Usual torch rules for broadcasting apply.

Parameters:
  • a – Quaternions as tensor of shape (…, 4), real part first.

  • b – Quaternions as tensor of shape (…, 4), real part first.

Returns:

The product of a and b, a tensor of quaternions of shape (…, 4).

pytorch3d.transforms.quaternion_raw_multiply(a: Tensor, b: Tensor) Tensor[source]

Multiply two quaternions. Usual torch rules for broadcasting apply.

Parameters:
  • a – Quaternions as tensor of shape (…, 4), real part first.

  • b – Quaternions as tensor of shape (…, 4), real part first.

Returns:

The product of a and b, a tensor of quaternions shape (…, 4).

pytorch3d.transforms.quaternion_to_axis_angle(quaternions: Tensor) Tensor[source]

Convert rotations given as quaternions to axis/angle.

Parameters:

quaternions – quaternions with real part first, as tensor of shape (…, 4).

Returns:

Rotations given as a vector in axis angle form, as a tensor

of shape (…, 3), where the magnitude is the angle turned anticlockwise in radians around the vector’s direction.

pytorch3d.transforms.quaternion_to_matrix(quaternions: Tensor) Tensor[source]

Convert rotations given as quaternions to rotation matrices.

Parameters:

quaternions – quaternions with real part first, as tensor of shape (…, 4).

Returns:

Rotation matrices as tensor of shape (…, 3, 3).

pytorch3d.transforms.random_quaternions(n: int, dtype: dtype | None = None, device: str | device | None = None) Tensor[source]

Generate random quaternions representing rotations, i.e. versors with nonnegative real part.

Parameters:
  • n – Number of quaternions in a batch to return.

  • dtype – Type to return.

  • device – Desired device of returned tensor. Default: uses the current device for the default tensor type.

Returns:

Quaternions as tensor of shape (N, 4).

pytorch3d.transforms.random_rotation(dtype: dtype | None = None, device: str | device | None = None) Tensor[source]

Generate a single random 3x3 rotation matrix.

Parameters:
  • dtype – Type to return

  • device – Device of returned tensor. Default: if None, uses the current device for the default tensor type

Returns:

Rotation matrix as tensor of shape (3, 3).

pytorch3d.transforms.random_rotations(n: int, dtype: dtype | None = None, device: str | device | None = None) Tensor[source]

Generate random rotations as 3x3 rotation matrices.

Parameters:
  • n – Number of rotation matrices in a batch to return.

  • dtype – Type to return.

  • device – Device of returned tensor. Default: if None, uses the current device for the default tensor type.

Returns:

Rotation matrices as tensor of shape (n, 3, 3).

pytorch3d.transforms.rotation_6d_to_matrix(d6: Tensor) Tensor[source]

Converts 6D rotation representation by Zhou et al. [1] to rotation matrix using Gram–Schmidt orthogonalization per Section B of [1]. :param d6: 6D rotation representation, of size (*, 6)

Returns:

batch of rotation matrices of size (*, 3, 3)

[1] Zhou, Y., Barnes, C., Lu, J., Yang, J., & Li, H. On the Continuity of Rotation Representations in Neural Networks. IEEE Conference on Computer Vision and Pattern Recognition, 2019. Retrieved from http://arxiv.org/abs/1812.07035

pytorch3d.transforms.standardize_quaternion(quaternions: Tensor) Tensor[source]

Convert a unit quaternion to a standard form: one in which the real part is non negative.

Parameters:

quaternions – Quaternions with real part first, as tensor of shape (…, 4).

Returns:

Standardized quaternions as tensor of shape (…, 4).

pytorch3d.transforms.se3_exp_map(log_transform: Tensor, eps: float = 0.0001) Tensor[source]

Convert a batch of logarithmic representations of SE(3) matrices log_transform to a batch of 4x4 SE(3) matrices using the exponential map. See e.g. [1], Sec 9.4.2. for more detailed description.

A SE(3) matrix has the following form:

` [ R 0 ] [ T 1 ] , `

where R is a 3x3 rotation matrix and T is a 3-D translation vector. SE(3) matrices are commonly used to represent rigid motions or camera extrinsics.

In the SE(3) logarithmic representation SE(3) matrices are represented as 6-dimensional vectors [log_translation | log_rotation], i.e. a concatenation of two 3D vectors log_translation and log_rotation.

The conversion from the 6D representation to a 4x4 SE(3) matrix transform is done as follows:

``` transform = exp( [ hat(log_rotation) 0 ]

[ log_translation 1 ] ) ,

```

where exp is the matrix exponential and hat is the Hat operator [2].

Note that for any log_transform with 0 <= ||log_rotation|| < 2pi (i.e. the rotation angle is between 0 and 2pi), the following identity holds: ` se3_log_map(se3_exponential_map(log_transform)) == log_transform `

The conversion has a singularity around ||log(transform)|| = 0 which is handled by clamping controlled with the eps argument.

Parameters:
  • log_transform – Batch of vectors of shape (minibatch, 6).

  • eps – A threshold for clipping the squared norm of the rotation logarithm to avoid unstable gradients in the singular case.

Returns:

Batch of transformation matrices of shape (minibatch, 4, 4).

Raises:

ValueError if log_transform is of incorrect shape.

[1] https://jinyongjeong.github.io/Download/SE3/jlblanco2010geometry3d_techrep.pdf [2] https://en.wikipedia.org/wiki/Hat_operator

pytorch3d.transforms.se3_log_map(transform: Tensor, eps: float = 0.0001, cos_bound: float = 0.0001) Tensor[source]

Convert a batch of 4x4 transformation matrices transform to a batch of 6-dimensional SE(3) logarithms of the SE(3) matrices. See e.g. [1], Sec 9.4.2. for more detailed description.

A SE(3) matrix has the following form:

` [ R 0 ] [ T 1 ] , `

where R is an orthonormal 3x3 rotation matrix and T is a 3-D translation vector. SE(3) matrices are commonly used to represent rigid motions or camera extrinsics.

In the SE(3) logarithmic representation SE(3) matrices are represented as 6-dimensional vectors [log_translation | log_rotation], i.e. a concatenation of two 3D vectors log_translation and log_rotation.

The conversion from the 4x4 SE(3) matrix transform to the 6D representation log_transform = [log_translation | log_rotation] is done as follows:

` log_transform = log(transform) log_translation = log_transform[3, :3] log_rotation = inv_hat(log_transform[:3, :3]) `

where log is the matrix logarithm and inv_hat is the inverse of the Hat operator [2].

Note that for any valid 4x4 transform matrix, the following identity holds: ` se3_exp_map(se3_log_map(transform)) == transform `

The conversion has a singularity around (transform=I) which is handled by clamping controlled with the eps and cos_bound arguments.

Parameters:
  • transform – batch of SE(3) matrices of shape (minibatch, 4, 4).

  • eps – A threshold for clipping the squared norm of the rotation logarithm to avoid division by zero in the singular case.

  • cos_bound – Clamps the cosine of the rotation angle to [-1 + cos_bound, 3 - cos_bound] to avoid non-finite outputs. The non-finite outputs can be caused by passing small rotation angles to the acos function in so3_rotation_angle of so3_log_map.

Returns:

Batch of logarithms of input SE(3) matrices of shape (minibatch, 6).

Raises:
  • ValueError if transform is of incorrect shape.

  • ValueError if R has an unexpected trace.

[1] https://jinyongjeong.github.io/Download/SE3/jlblanco2010geometry3d_techrep.pdf [2] https://en.wikipedia.org/wiki/Hat_operator

pytorch3d.transforms.so3_exp_map(log_rot: Tensor, eps: float = 0.0001) Tensor[source]

Convert a batch of logarithmic representations of rotation matrices log_rot to a batch of 3x3 rotation matrices using Rodrigues formula [1].

In the logarithmic representation, each rotation matrix is represented as a 3-dimensional vector (log_rot) who’s l2-norm and direction correspond to the magnitude of the rotation angle and the axis of rotation respectively.

The conversion has a singularity around log(R) = 0 which is handled by clamping controlled with the eps argument.

Parameters:
  • log_rot – Batch of vectors of shape (minibatch, 3).

  • eps – A float constant handling the conversion singularity.

Returns:

Batch of rotation matrices of shape (minibatch, 3, 3).

Raises:

ValueError if log_rot is of incorrect shape.

[1] https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula

pytorch3d.transforms.so3_exponential_map(log_rot: Tensor, eps: float = 0.0001) Tensor[source]
pytorch3d.transforms.so3_log_map(R: Tensor, eps: float = 0.0001, cos_bound: float = 0.0001) Tensor[source]

Convert a batch of 3x3 rotation matrices R to a batch of 3-dimensional matrix logarithms of rotation matrices The conversion has a singularity around (R=I).

Parameters:
  • R – batch of rotation matrices of shape (minibatch, 3, 3).

  • eps – (unused, for backward compatibility)

  • cos_bound – (unused, for backward compatibility)

Returns:

Batch of logarithms of input rotation matrices of shape (minibatch, 3).

pytorch3d.transforms.so3_relative_angle(R1: Tensor, R2: Tensor, cos_angle: bool = False, cos_bound: float = 0.0001, eps: float = 0.0001) Tensor[source]

Calculates the relative angle (in radians) between pairs of rotation matrices R1 and R2 with angle = acos(0.5 * (Trace(R1 R2^T)-1))

Note

This corresponds to a geodesic distance on the 3D manifold of rotation matrices.

Parameters:
  • R1 – Batch of rotation matrices of shape (minibatch, 3, 3).

  • R2 – Batch of rotation matrices of shape (minibatch, 3, 3).

  • cos_angle – If==True return cosine of the relative angle rather than the angle itself. This can avoid the unstable calculation of acos.

  • cos_bound – Clamps the cosine of the relative rotation angle to [-1 + cos_bound, 1 - cos_bound] to avoid non-finite outputs/gradients of the acos call. Note that the non-finite outputs/gradients are returned when the angle is requested (i.e. cos_angle==False) and the rotation angle is close to 0 or π.

  • eps – Tolerance for the valid trace check of the relative rotation matrix in so3_rotation_angle.

Returns:

Corresponding rotation angles of shape (minibatch,). If cos_angle==True, returns the cosine of the angles.

Raises:
  • ValueError if R1 or R2 is of incorrect shape.

  • ValueError if R1 or R2 has an unexpected trace.

pytorch3d.transforms.so3_rotation_angle(R: Tensor, eps: float = 0.0001, cos_angle: bool = False, cos_bound: float = 0.0001) Tensor[source]

Calculates angles (in radians) of a batch of rotation matrices R with angle = acos(0.5 * (Trace(R)-1)). The trace of the input matrices is checked to be in the valid range [-1-eps,3+eps]. The eps argument is a small constant that allows for small errors caused by limited machine precision.

Parameters:
  • R – Batch of rotation matrices of shape (minibatch, 3, 3).

  • eps – Tolerance for the valid trace check.

  • cos_angle – If==True return cosine of the rotation angles rather than the angle itself. This can avoid the unstable calculation of acos.

  • cos_bound – Clamps the cosine of the rotation angle to [-1 + cos_bound, 1 - cos_bound] to avoid non-finite outputs/gradients of the acos call. Note that the non-finite outputs/gradients are returned when the angle is requested (i.e. cos_angle==False) and the rotation angle is close to 0 or π.

Returns:

Corresponding rotation angles of shape (minibatch,). If cos_angle==True, returns the cosine of the angles.

Raises:
  • ValueError if R is of incorrect shape.

  • ValueError if R has an unexpected trace.

class pytorch3d.transforms.Rotate(R: Tensor, dtype: dtype = torch.float32, device: str | device | None = None, orthogonal_tol: float = 1e-05)[source]

Bases: Transform3d

__init__(R: Tensor, dtype: dtype = torch.float32, device: str | device | None = None, orthogonal_tol: float = 1e-05) None[source]

Create a new Transform3d representing 3D rotation using a rotation matrix as the input.

Parameters:
  • R – a tensor of shape (3, 3) or (N, 3, 3)

  • orthogonal_tol – tolerance for the test of the orthogonality of R

class pytorch3d.transforms.RotateAxisAngle(angle, axis: str = 'X', degrees: bool = True, dtype: dtype = torch.float32, device: str | device | None = None)[source]

Bases: Rotate

__init__(angle, axis: str = 'X', degrees: bool = True, dtype: dtype = torch.float32, device: str | device | None = None) None[source]

Create a new Transform3d representing 3D rotation about an axis by an angle.

Assuming a right-hand coordinate system, positive rotation angles result in a counter clockwise rotation.

Parameters:
  • angle

    • A torch tensor of shape (N,)

    • A python scalar

    • A torch scalar

  • axis – string: one of [“X”, “Y”, “Z”] indicating the axis about which to rotate. NOTE: All batch elements are rotated about the same axis.

class pytorch3d.transforms.Scale(x, y=None, z=None, dtype: dtype = torch.float32, device: str | device | None = None)[source]

Bases: Transform3d

__init__(x, y=None, z=None, dtype: dtype = torch.float32, device: str | device | None = None) None[source]

A Transform3d representing a scaling operation, with different scale factors along each coordinate axis.

Option I: Scale(s, dtype=torch.float32, device=’cpu’)
s can be one of
  • Python scalar or torch scalar: Single uniform scale

  • 1D torch tensor of shape (N,): A batch of uniform scale

  • 2D torch tensor of shape (N, 3): Scale differently along each axis

Option II: Scale(x, y, z, dtype=torch.float32, device=’cpu’)
Each of x, y, and z can be one of
  • python scalar

  • torch scalar

  • 1D torch tensor

class pytorch3d.transforms.Transform3d(dtype: dtype = torch.float32, device: str | device = 'cpu', matrix: Tensor | None = None)[source]

Bases: object

A Transform3d object encapsulates a batch of N 3D transformations, and knows how to transform points and normal vectors. Suppose that t is a Transform3d; then we can do the following:

N = len(t)
points = torch.randn(N, P, 3)
normals = torch.randn(N, P, 3)
points_transformed = t.transform_points(points)    # => (N, P, 3)
normals_transformed = t.transform_normals(normals)  # => (N, P, 3)

BROADCASTING Transform3d objects supports broadcasting. Suppose that t1 and tN are Transform3d objects with len(t1) == 1 and len(tN) == N respectively. Then we can broadcast transforms like this:

t1.transform_points(torch.randn(P, 3))     # => (P, 3)
t1.transform_points(torch.randn(1, P, 3))  # => (1, P, 3)
t1.transform_points(torch.randn(M, P, 3))  # => (M, P, 3)
tN.transform_points(torch.randn(P, 3))     # => (N, P, 3)
tN.transform_points(torch.randn(1, P, 3))  # => (N, P, 3)

COMBINING TRANSFORMS Transform3d objects can be combined in two ways: composing and stacking. Composing is function composition. Given Transform3d objects t1, t2, t3, the following all compute the same thing:

y1 = t3.transform_points(t2.transform_points(t1.transform_points(x)))
y2 = t1.compose(t2).compose(t3).transform_points(x)
y3 = t1.compose(t2, t3).transform_points(x)

Composing transforms should broadcast.

if len(t1) == 1 and len(t2) == N, then len(t1.compose(t2)) == N.

We can also stack a sequence of Transform3d objects, which represents composition along the batch dimension; then the following should compute the same thing.

N, M = len(tN), len(tM)
xN = torch.randn(N, P, 3)
xM = torch.randn(M, P, 3)
y1 = torch.cat([tN.transform_points(xN), tM.transform_points(xM)], dim=0)
y2 = tN.stack(tM).transform_points(torch.cat([xN, xM], dim=0))

BUILDING TRANSFORMS We provide convenience methods for easily building Transform3d objects as compositions of basic transforms.

# Scale by 0.5, then translate by (1, 2, 3)
t1 = Transform3d().scale(0.5).translate(1, 2, 3)

# Scale each axis by a different amount, then translate, then scale
t2 = Transform3d().scale(1, 3, 3).translate(2, 3, 1).scale(2.0)

t3 = t1.compose(t2)
tN = t1.stack(t3, t3)

BACKPROP THROUGH TRANSFORMS When building transforms, we can also parameterize them by Torch tensors; in this case we can backprop through the construction and application of Transform objects, so they could be learned via gradient descent or predicted by a neural network.

s1_params = torch.randn(N, requires_grad=True)
t_params = torch.randn(N, 3, requires_grad=True)
s2_params = torch.randn(N, 3, requires_grad=True)

t = Transform3d().scale(s1_params).translate(t_params).scale(s2_params)
x = torch.randn(N, 3)
y = t.transform_points(x)
loss = compute_loss(y)
loss.backward()

with torch.no_grad():
    s1_params -= lr * s1_params.grad
    t_params -= lr * t_params.grad
    s2_params -= lr * s2_params.grad

CONVENTIONS We adopt a right-hand coordinate system, meaning that rotation about an axis with a positive angle results in a counter clockwise rotation.

This class assumes that transformations are applied on inputs which are row vectors. The internal representation of the Nx4x4 transformation matrix is of the form:

M = [
        [Rxx, Ryx, Rzx, 0],
        [Rxy, Ryy, Rzy, 0],
        [Rxz, Ryz, Rzz, 0],
        [Tx,  Ty,  Tz,  1],
    ]

To apply the transformation to points, which are row vectors, the latter are converted to homogeneous (4D) coordinates and right-multiplied by the M matrix:

points = [[0, 1, 2]]  # (1 x 3) xyz coordinates of a point
[transformed_points, 1]  [points, 1] @ M
__init__(dtype: dtype = torch.float32, device: str | device = 'cpu', matrix: Tensor | None = None) None[source]
Parameters:
  • dtype – The data type of the transformation matrix. to be used if matrix = None.

  • device – The device for storing the implemented transformation. If matrix != None, uses the device of input matrix.

  • matrix – A tensor of shape (4, 4) or of shape (minibatch, 4, 4) representing the 4x4 3D transformation matrix. If None, initializes with identity using the specified device and dtype.

__getitem__(index: int | List[int] | slice | BoolTensor | LongTensor) Transform3d[source]
Parameters:

index – Specifying the index of the transform to retrieve. Can be an int, slice, list of ints, boolean, long tensor. Supports negative indices.

Returns:

Transform3d object with selected transforms. The tensors are not cloned.

compose(*others: Transform3d) Transform3d[source]

Return a new Transform3d representing the composition of self with the given other transforms, which will be stored as an internal list.

Parameters:

*others – Any number of Transform3d objects

Returns:

A new Transform3d with the stored transforms

get_matrix() Tensor[source]

Returns a 4×4 matrix corresponding to each transform in the batch.

If the transform was composed from others, the matrix for the composite transform will be returned. For example, if self.transforms contains transforms t1, t2, and t3, and given a set of points x, the following should be true:

y1 = t1.compose(t2, t3).transform(x)
y2 = t3.transform(t2.transform(t1.transform(x)))
y1.get_matrix() == y2.get_matrix()

Where necessary, those transforms are broadcast against each other.

Returns:

A (N, 4, 4) batch of transformation matrices representing

the stored transforms. See the class documentation for the conventions.

get_se3_log(eps: float = 0.0001, cos_bound: float = 0.0001) Tensor[source]

Returns a 6D SE(3) log vector corresponding to each transform in the batch.

In the SE(3) logarithmic representation SE(3) matrices are represented as 6-dimensional vectors [log_translation | log_rotation], i.e. a concatenation of two 3D vectors log_translation and log_rotation.

The conversion from the 4x4 SE(3) matrix transform to the 6D representation log_transform = [log_translation | log_rotation] is done as follows:

log_transform = log(transform.get_matrix())
log_translation = log_transform[3, :3]
log_rotation = inv_hat(log_transform[:3, :3])

where log is the matrix logarithm and inv_hat is the inverse of the Hat operator [2].

See the docstring for se3.se3_log_map and [1], Sec 9.4.2. for more detailed description.

Parameters:
  • eps – A threshold for clipping the squared norm of the rotation logarithm to avoid division by zero in the singular case.

  • cos_bound – Clamps the cosine of the rotation angle to [-1 + cos_bound, 3 - cos_bound] to avoid non-finite outputs. The non-finite outputs can be caused by passing small rotation angles to the acos function in so3_rotation_angle of so3_log_map.

Returns:

A (N, 6) tensor, rows of which represent the individual transforms stored in the object as SE(3) logarithms.

Raises:

ValueError if the stored transform is not Euclidean (e.g. R is not a rotation – matrix or the last column has non-zeros in the first three places).

[1] https://jinyongjeong.github.io/Download/SE3/jlblanco2010geometry3d_techrep.pdf [2] https://en.wikipedia.org/wiki/Hat_operator

inverse(invert_composed: bool = False) Transform3d[source]

Returns a new Transform3d object that represents an inverse of the current transformation.

Parameters:

invert_composed

  • True: First compose the list of stored transformations and then apply inverse to the result. This is potentially slower for classes of transformations with inverses that can be computed efficiently (e.g. rotations and translations).

  • False: Invert the individual stored transformations independently without composing them.

Returns:

A new Transform3d object containing the inverse of the original transformation.

stack(*others: Transform3d) Transform3d[source]

Return a new batched Transform3d representing the batch elements from self and all the given other transforms all batched together.

Parameters:

*others – Any number of Transform3d objects

Returns:

A new Transform3d.

transform_points(points, eps: float | None = None) Tensor[source]

Use this transform to transform a set of 3D points. Assumes row major ordering of the input points.

Parameters:
  • points – Tensor of shape (P, 3) or (N, P, 3)

  • eps – If eps!=None, the argument is used to clamp the last coordinate before performing the final division. The clamping corresponds to: last_coord := (last_coord.sign() + (last_coord==0)) * torch.clamp(last_coord.abs(), eps), i.e. the last coordinates that are exactly 0 will be clamped to +eps.

Returns:

points_out – points of shape (N, P, 3) or (P, 3) depending on the dimensions of the transform

transform_normals(normals) Tensor[source]

Use this transform to transform a set of normal vectors.

Parameters:

normals – Tensor of shape (P, 3) or (N, P, 3)

Returns:

normals_out – Tensor of shape (P, 3) or (N, P, 3) depending on the dimensions of the transform

translate(*args, **kwargs) Transform3d[source]
scale(*args, **kwargs) Transform3d[source]
rotate(*args, **kwargs) Transform3d[source]
rotate_axis_angle(*args, **kwargs) Transform3d[source]
clone() Transform3d[source]

Deep copy of Transforms object. All internal tensors are cloned individually.

Returns:

new Transforms object.

to(device: str | device, copy: bool = False, dtype: dtype | None = None) Transform3d[source]

Match functionality of torch.Tensor.to() If copy = True or the self Tensor is on a different device, the returned tensor is a copy of self with the desired torch.device. If copy = False and the self Tensor already has the correct torch.device, then self is returned.

Parameters:
  • device – Device (as str or torch.device) for the new tensor.

  • copy – Boolean indicator whether or not to clone self. Default False.

  • dtype – If not None, casts the internal tensor variables to a given torch.dtype.

Returns:

Transform3d object.

cpu() Transform3d[source]
cuda() Transform3d[source]
class pytorch3d.transforms.Translate(x, y=None, z=None, dtype: dtype = torch.float32, device: str | device | None = None)[source]

Bases: Transform3d

__init__(x, y=None, z=None, dtype: dtype = torch.float32, device: str | device | None = None) None[source]

Create a new Transform3d representing 3D translations.

Option I: Translate(xyz, dtype=torch.float32, device=’cpu’)

xyz should be a tensor of shape (N, 3)

Option II: Translate(x, y, z, dtype=torch.float32, device=’cpu’)

Here x, y, and z will be broadcast against each other and concatenated to form the translation. Each can be:

  • A python scalar

  • A torch scalar

  • A 1D torch tensor