MCPcopy Create free account
hub / github.com/InternRobotics/G2VLM / align_points_scale_z_shift

Function align_points_scale_z_shift

modeling/pi3/utils/alignment.py:251–302  ·  view source on GitHub ↗

Align `points_src` to `points_tgt` with respect to a shared xyz scale and z shift. It is similar to `align_affine` but scale and shift are applied to different dimensions. ### Parameters: - `points_src: torch.Tensor` of shape (..., N, 3) - `points_tgt: torch.Tensor` of shape (

(points_src: torch.Tensor, points_tgt: torch.Tensor, weight: Optional[torch.Tensor], trunc: Optional[Union[float, torch.Tensor]] = None)

Source from the content-addressed store, hash-verified

249
250
251def align_points_scale_z_shift(points_src: torch.Tensor, points_tgt: torch.Tensor, weight: Optional[torch.Tensor], trunc: Optional[Union[float, torch.Tensor]] = None):
252 """
253 Align `points_src` to `points_tgt` with respect to a shared xyz scale and z shift.
254 It is similar to `align_affine` but scale and shift are applied to different dimensions.
255
256 ### Parameters:
257 - `points_src: torch.Tensor` of shape (..., N, 3)
258 - `points_tgt: torch.Tensor` of shape (..., N, 3)
259 - `weights: torch.Tensor` of shape (..., N)
260
261 ### Returns:
262 - `scale: torch.Tensor` of shape (...).
263 - `shift: torch.Tensor` of shape (..., 3). x and y shifts are zeros.
264 """
265 dtype, device = points_src.dtype, points_src.device
266
267 # Flatten batch dimensions for simplicity
268 batch_shape, n = points_src.shape[:-2], points_src.shape[-2]
269 batch_size = math.prod(batch_shape)
270 points_src, points_tgt, weight = points_src.reshape(batch_size, n, 3), points_tgt.reshape(batch_size, n, 3), weight.reshape(batch_size, n)
271
272 # Take anchors
273 anchor_where_batch, anchor_where_n = torch.where(weight > 0)
274 with torch.no_grad():
275 zeros = torch.zeros(anchor_where_batch.shape[0], device=device, dtype=dtype)
276 points_src_anchor = torch.stack([zeros, zeros, points_src[anchor_where_batch, anchor_where_n, 2]], dim=-1) # (anchors, 3)
277 points_tgt_anchor = torch.stack([zeros, zeros, points_tgt[anchor_where_batch, anchor_where_n, 2]], dim=-1) # (anchors, 3)
278
279 points_src_anchored = points_src[anchor_where_batch, :, :] - points_src_anchor[..., None, :] # (anchors, n, 3)
280 points_tgt_anchored = points_tgt[anchor_where_batch, :, :] - points_tgt_anchor[..., None, :] # (anchors, n, 3)
281 weight_anchored = weight[anchor_where_batch, :, None].expand(-1, -1, 3) # (anchors, n, 3)
282
283 # Solve optimal scale and shift for each anchor
284 MAX_ELEMENTS = 2 ** 20
285 scale, loss, index = split_batch_fwd(align, MAX_ELEMENTS // n, points_src_anchored.flatten(-2), points_tgt_anchored.flatten(-2), weight_anchored.flatten(-2), trunc) # (anchors,)
286
287 loss, index_anchor = scatter_min(size=batch_size, dim=0, index=anchor_where_batch, src=loss) # (batch_size,)
288
289 # Reproduce by indexing for shorter compute graph
290 index_2 = index[index_anchor] # (batch_size,) [0, 3n)
291 index_1 = anchor_where_n[index_anchor] * 3 + index_2 % 3 # (batch_size,) [0, 3n)
292
293 zeros = torch.zeros((batch_size, n), device=device, dtype=dtype)
294 points_tgt_00z, points_src_00z = torch.stack([zeros, zeros, points_tgt[..., 2]], dim=-1), torch.stack([zeros, zeros, points_src[..., 2]], dim=-1)
295 tgt_1, src_1 = torch.gather(points_tgt_00z.flatten(-2), dim=1, index=index_1[..., None]).squeeze(-1), torch.gather(points_src_00z.flatten(-2), dim=1, index=index_1[..., None]).squeeze(-1)
296 tgt_2, src_2 = torch.gather(points_tgt.flatten(-2), dim=1, index=index_2[..., None]).squeeze(-1), torch.gather(points_src.flatten(-2), dim=1, index=index_2[..., None]).squeeze(-1)
297
298 scale = (tgt_2 - tgt_1) / torch.where(src_2 != src_1, src_2 - src_1, 1.0)
299 shift = torch.gather(points_tgt_00z, dim=1, index=(index_1 // 3)[..., None, None].expand(-1, -1, 3)).squeeze(-2) - scale[..., None] * torch.gather(points_src_00z, dim=1, index=(index_1 // 3)[..., None, None].expand(-1, -1, 3)).squeeze(-2)
300 scale, shift = scale.reshape(batch_shape), shift.reshape(*batch_shape, 3)
301
302 return scale, shift
303
304
305def align_points_scale_xyz_shift(points_src: torch.Tensor, points_tgt: torch.Tensor, weight: Optional[torch.Tensor], trunc: Optional[Union[float, torch.Tensor]] = None, max_iters: int = 30, eps: float = 1e-6):

Callers

nothing calls this directly

Calls 2

split_batch_fwdFunction · 0.70
scatter_minFunction · 0.70

Tested by

no test coverage detected