| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import torch.nn as nn |
|
|
| from ..model.utils.attention import Mlp |
| from ..model.utils.block import Block |
| from ..model.utils.transform import extri_intri_to_pose_encoding |
| from ..utils.geometry import affine_inverse |
|
|
|
|
| class CameraEnc(nn.Module): |
| """ |
| CameraHead predicts camera parameters from token representations using iterative refinement. |
| |
| It applies a series of transformer blocks (the "trunk") to dedicated camera tokens. |
| """ |
|
|
| def __init__( |
| self, |
| dim_out: int = 1024, |
| dim_in: int = 9, |
| trunk_depth: int = 4, |
| target_dim: int = 9, |
| num_heads: int = 16, |
| mlp_ratio: int = 4, |
| init_values: float = 0.01, |
| **kwargs, |
| ): |
| super().__init__() |
| self.target_dim = target_dim |
| self.trunk_depth = trunk_depth |
| self.trunk = nn.Sequential( |
| *[ |
| Block( |
| dim=dim_out, |
| num_heads=num_heads, |
| mlp_ratio=mlp_ratio, |
| init_values=init_values, |
| ) |
| for _ in range(trunk_depth) |
| ] |
| ) |
| self.token_norm = nn.LayerNorm(dim_out) |
| self.trunk_norm = nn.LayerNorm(dim_out) |
| self.pose_branch = Mlp( |
| in_features=dim_in, |
| hidden_features=dim_out // 2, |
| out_features=dim_out, |
| drop=0, |
| ) |
|
|
| def forward( |
| self, |
| ext, |
| ixt, |
| image_size, |
| ) -> tuple: |
| c2ws = affine_inverse(ext) |
| pose_encoding = extri_intri_to_pose_encoding( |
| c2ws, |
| ixt, |
| image_size, |
| ) |
| pose_encoding = pose_encoding.to(dtype=self.pose_branch.fc1.weight.dtype) |
| pose_tokens = self.pose_branch(pose_encoding) |
| pose_tokens = self.token_norm(pose_tokens) |
| pose_tokens = self.trunk(pose_tokens) |
| pose_tokens = self.trunk_norm(pose_tokens) |
| return pose_tokens |
|
|