Calculates landmarks by barycentric interpolation. Parameters ---------- vertices: torch.tensor BxVx3, dtype = torch.float32 The tensor of input vertices faces: torch.tensor Fx3, dtype = torch.long The faces of the mesh lmk_faces_idx: torch.tensor L, dtype = torc
(vertices: Tensor, faces: Tensor, lmk_faces_idx: Tensor,
lmk_bary_coords: Tensor)
| 101 | |
| 102 | |
| 103 | def vertices2landmarks(vertices: Tensor, faces: Tensor, lmk_faces_idx: Tensor, |
| 104 | lmk_bary_coords: Tensor) -> Tensor: |
| 105 | """Calculates landmarks by barycentric interpolation. |
| 106 | |
| 107 | Parameters |
| 108 | ---------- |
| 109 | vertices: torch.tensor BxVx3, dtype = torch.float32 |
| 110 | The tensor of input vertices |
| 111 | faces: torch.tensor Fx3, dtype = torch.long |
| 112 | The faces of the mesh |
| 113 | lmk_faces_idx: torch.tensor L, dtype = torch.long |
| 114 | The tensor with the indices of the faces used to calculate the |
| 115 | landmarks. |
| 116 | lmk_bary_coords: torch.tensor Lx3, dtype = torch.float32 |
| 117 | The tensor of barycentric coordinates that are used to interpolate |
| 118 | the landmarks |
| 119 | |
| 120 | Returns |
| 121 | ------- |
| 122 | landmarks: torch.tensor BxLx3, dtype = torch.float32 |
| 123 | The coordinates of the landmarks for each mesh in the batch |
| 124 | """ |
| 125 | # Extract the indices of the vertices for each face |
| 126 | # BxLx3 |
| 127 | batch_size, num_verts = vertices.shape[:2] |
| 128 | device = vertices.device |
| 129 | |
| 130 | lmk_faces = torch.index_select(faces, 0, lmk_faces_idx.view(-1)).view( |
| 131 | batch_size, -1, 3) |
| 132 | |
| 133 | lmk_faces += torch.arange(batch_size, dtype=torch.long, |
| 134 | device=device).view(-1, 1, 1) * num_verts |
| 135 | |
| 136 | lmk_vertices = vertices.view(-1, 3)[lmk_faces].view(batch_size, -1, 3, 3) |
| 137 | |
| 138 | landmarks = torch.einsum('blfi,blf->bli', [lmk_vertices, lmk_bary_coords]) |
| 139 | return landmarks |
| 140 | |
| 141 | |
| 142 | def lbs( |