import os import json import numpy as np import torch def compute_geometric_pathology(model, cameras=None) -> dict: """ 提取几何病理学指纹。 底层计算已通过 IoC 模式下放给各个 Wrapper 的 compute_physical_metrics 接口。 此处仅负责集中管控诊断阈值 (Pathology Flags)。 """ print(f"🔬 [UFD-EvalKit] 正在请求变体自述几何资产...") try: metrics = model.compute_physical_metrics(cameras=cameras) except NotImplementedError: print(" ⚠️ [UFD-EvalKit] Wrapper 未实现 compute_physical_metrics,返回空字典。") metrics = {} except Exception as e: return {"error": f"提取物理指标失败: {str(e)}"} # 集中研判诊断标签 (Pathology Flags),保持全榜单阈值标准绝对统一 flags = [] if metrics.get("gamma_median", 0) > 18.0: flags.append("SEVERE_ANISOTROPY_DISTORTION") if metrics.get("alpha_mean", 1.0) < 0.05: flags.append("OPACITY_MINIMIZATION_COLLAPSE") if metrics.get("scale_mean", 0) > 5.0: flags.append("GLOBAL_SCALE_INFLATION") metrics["pathology_flags"] = flags return metrics def depth_to_normal(depth): """从深度图反推屏幕空间法向 (Method-agnostic)""" if len(depth.shape) == 2: depth = depth.unsqueeze(0).unsqueeze(0) elif len(depth.shape) == 3: depth = depth.unsqueeze(0) # 使用简单差分计算深度梯度 dx = depth[:, :, :, 1:] - depth[:, :, :, :-1] dy = depth[:, :, 1:, :] - depth[:, :, :-1, :] # 填充边界对齐尺寸 dx = torch.nn.functional.pad(dx, (0, 1, 0, 0)) dy = torch.nn.functional.pad(dy, (0, 0, 0, 1)) # 构造近似法向量并归一化 normal = torch.cat([-dx, -dy, torch.ones_like(depth)], dim=1) normal = torch.nn.functional.normalize(normal, dim=1) # 映射到 [0, 1] 用于可视化存储 return (normal + 1.0) / 2.0