geometry¶
feat.utils.geometry
¶
Pure-PyTorch geometric helpers used by the detector pipeline.
These replace the small handful of kornia calls py-feat used to make so we
don't need to take on the kornia dependency. All ops are batched, dtype/device
preserving, and work inside torch.inference_mode.
Replaces:
- kornia.geometry.conversions.axis_angle_to_rotation_matrix
- kornia.geometry.conversions.rotation_matrix_to_axis_angle
- kornia.geometry.conversions.rotation_matrix_to_quaternion
- kornia.geometry.conversions.euler_from_quaternion
- kornia.geometry.transform.warp_affine
Numerical parity with kornia is tested in
feat/tests/test_geometry.py and held to ~1e-5 absolute tolerance.
axis_angle_to_rotation_matrix(axis_angle)
¶
Convert axis-angle (rotation vector) to rotation matrix via Rodrigues.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
axis_angle
|
Tensor
|
|
required |
Returns:
| Type | Description |
|---|---|
Tensor
|
|
Source code in feat/utils/geometry.py
euler_from_quaternion(w, x, y, z)
¶
Convert (w, x, y, z) quaternion to (roll, pitch, yaw) Euler angles.
Matches kornia.geometry.conversions.euler_from_quaternion (XYZ
intrinsic, returned as a 3-tuple of tensors).
Source code in feat/utils/geometry.py
rotation_matrix_to_axis_angle(R)
¶
Convert rotation matrix to axis-angle (rotation vector).
Three numerical regimes need separate handling:
- theta near 0: skew-symmetric part is ~0; the full Rodrigues
formula is unstable. Use
axis * 0.5(the leading-order term). - theta in the bulk: standard recipe
axis = skew / (2 sin(theta)). - theta near pi:
sin(theta) ~ 0again, butaxisfrom the skew has vanishingly small magnitude in any direction not orthogonal to the axis. Fall back to extracting the axis from the diagonal of(R + I) / 2, which has rank 1 and whose dominant column gives the axis. Standard fallback (Hartley & Zisserman, Eigen'sAngleAxis::fromRotationMatrix).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
R
|
Tensor
|
|
required |
Returns:
| Type | Description |
|---|---|
Tensor
|
|
Source code in feat/utils/geometry.py
rotation_matrix_to_quaternion(R)
¶
Convert rotation matrix to unit quaternion (w, x, y, z).
Uses Shepperd's method for numerical stability across the rotation sphere.
Returns a [..., 4] tensor with the scalar component first, matching
kornia's output ordering.
Source code in feat/utils/geometry.py
warp_affine(src, M, dsize, mode='bilinear', padding_mode='zeros', align_corners=False, fill_value=None)
¶
Apply a 2D affine transform to a batch of images.
Drop-in replacement for kornia.geometry.transform.warp_affine.
Convention matches kornia: M is a [B, 2, 3] matrix mapping
source pixel coordinates to destination pixel coordinates (the
forward, visible transform). Internally this is inverted to feed
F.affine_grid, which wants the destination-to-source mapping.
The pixel-coordinate normalization always uses kornia's convention
(2 / (dim - 1) scale; the same form for both align_corners
settings) โ kornia's normal_transform_pixel does not branch on
align_corners, so neither do we. align_corners is still
passed to F.affine_grid and F.grid_sample to match kornia
end-to-end.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
src
|
Tensor
|
|
required |
M
|
Tensor
|
|
required |
dsize
|
tuple[int, int]
|
|
required |
mode
|
str
|
|
'bilinear'
|
padding_mode
|
str
|
passed through to |
'zeros'
|
align_corners
|
bool
|
passed through to |
False
|
fill_value
|
tuple
|
optional |
None
|
Returns:
| Type | Description |
|---|---|
Tensor
|
|
Source code in feat/utils/geometry.py
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | |