Evaluate a single scene. Args: eval_metrics: list of metric categories to evaluate. Allowed values: - "depth": depth metrics (abs_rel, rmse, delta, inlier, etc.) - "pose": camera pose metrics (racc, tacc, auc, etc., based on DA3 pairwise protocol) - "
(scene, predictions, adapter, depth_alignment="median",
eval_metrics=None, gt_mesh_path=None)
| 140 | |
| 141 | |
| 142 | def evaluate_scene(scene, predictions, adapter, depth_alignment="median", |
| 143 | eval_metrics=None, gt_mesh_path=None): |
| 144 | """Evaluate a single scene. |
| 145 | |
| 146 | Args: |
| 147 | eval_metrics: list of metric categories to evaluate. Allowed values: |
| 148 | - "depth": depth metrics (abs_rel, rmse, delta, inlier, etc.) |
| 149 | - "pose": camera pose metrics (racc, tacc, auc, etc., based on DA3 pairwise protocol) |
| 150 | - "trajectory": trajectory metrics (ATE, RPE_t, RPE_r, based on evo Sim(3) alignment) |
| 151 | - "pointcloud": point cloud metrics (F-score, Overall) |
| 152 | None means evaluate all categories. |
| 153 | gt_mesh_path: if provided, use this .ply as the GT point cloud (only for |
| 154 | the whitelisted datasets + medium/dense view scene settings); when |
| 155 | None, the pointcloud evaluation is skipped. |
| 156 | |
| 157 | Returns: |
| 158 | (result_dict, timing_dict) |
| 159 | """ |
| 160 | if eval_metrics is None: |
| 161 | eval_metrics = ALL_EVAL_METRICS |
| 162 | eval_metrics = set(eval_metrics) |
| 163 | |
| 164 | result = { |
| 165 | "scene_id": scene["scene_id"], |
| 166 | "source_dataset": scene["source_dataset"], |
| 167 | "tags": scene["tags"], |
| 168 | "num_frames": len(scene["frame_indices"]), |
| 169 | } |
| 170 | eval_timing = {} |
| 171 | |
| 172 | gt_depth = scene["depth"] |
| 173 | gt_poses = scene["extrinsic"] |
| 174 | gt_intrinsic = scene["intrinsic"] |
| 175 | valid_mask = scene["valid_mask"] |
| 176 | N = len(gt_depth) |
| 177 | |
| 178 | # ---- Depth evaluation ---- |
| 179 | t_depth = time.time() |
| 180 | need_depth = "depth" in eval_metrics |
| 181 | need_tgm = "tgm" in eval_metrics |
| 182 | if (need_depth or need_tgm) and "pred_depth" in predictions: |
| 183 | pred_depth = predictions["pred_depth"] |
| 184 | |
| 185 | # Collect valid pred / gt pixels across all frames |
| 186 | all_pred_valid = [] |
| 187 | all_gt_valid = [] |
| 188 | for i in range(N): |
| 189 | frame_mask = valid_mask[i] |
| 190 | if not frame_mask.any(): |
| 191 | continue |
| 192 | all_pred_valid.append(pred_depth[i][frame_mask]) |
| 193 | all_gt_valid.append(gt_depth[i][frame_mask]) |
| 194 | |
| 195 | if all_pred_valid: |
| 196 | cat_pred = np.concatenate(all_pred_valid) |
| 197 | cat_gt = np.concatenate(all_gt_valid) |
| 198 | global_mask = np.ones(len(cat_gt), dtype=bool) |
| 199 |
no test coverage detected