SplatAtlas / scripts /phase2_counterfactual /aggregate_part3b.py
KCBtheone's picture
Upload SplatAtlas benchmark pipeline code
23e73f9 verified
Raw
History Blame Contribute Delete
3.33 kB
import os, json, numpy as np
from datetime import datetime, timezone
OUTPUT_ROOT = "/root/autodl-tmp/SplatAtlas/outputs/error_responsibility"
PROF_DIR = os.path.join(OUTPUT_ROOT, "_profiles")
METHODS = ['vanilla_3dgs', 'analyticsplatting', 'erankgs', 'ges', 'lightgaussian', 'minisplatting', 'opti3dgs', 'pgsr', 'steepgs']
SCENES = ['bicycle','bonsai','counter','flowers','garden','kitchen','room','stump','treehill',
'auditorium','ballroom','barn','caterpillar','courtroom','lighthouse','museum','palace','playground','temple','train','truck',
'DrJohnson','Playroom',
'Chair','Drums','Ficus','Hotdog','Lego','Materials','Mic','Ship']
METRICS = ["psnr_full", "sh_net_effect", "sh_corruption_rate", "opacity_net_effect", "coverage", "coverage_error_fraction", "residual_error"]
# 1. 抓取所有 9 个方法在 31 个场景上的中位数 (Cross-Scene Median)
method_medians = {m: {} for m in METHODS}
for m in METHODS:
for metric in METRICS:
vals = []
for s in SCENES:
p = os.path.join(OUTPUT_ROOT, f"{m}_{s}", "counterfactual_summary.json")
if os.path.exists(p):
with open(p) as f:
d = json.load(f)
if d.get(metric) is not None:
vals.append(d[metric])
method_medians[m][metric] = float(np.median(vals)) if vals else 0.0
# 2. 计算相对 IQR 统计量 (跨 9 种方法)
def calc_iqr_stats(vals_list):
if not vals_list: return None, None, None
med = float(np.median(vals_list))
abs_iqr = float(np.percentile(vals_list, 75) - np.percentile(vals_list, 25))
rel_iqr = (abs_iqr / abs(med) * 100) if med != 0 else None
return med, abs_iqr, rel_iqr
cross_method_analysis = {"n_methods": len(METHODS), "methods_included": METHODS, "metrics": {}}
# 提取 PSNR 基础倍率
psnr_vals = [method_medians[m]["psnr_full"] for m in METHODS]
_, _, psnr_rel_iqr = calc_iqr_stats(psnr_vals)
for metric in METRICS:
vals = [method_medians[m][metric] for m in METHODS]
med, abs_iqr, rel_iqr = calc_iqr_stats(vals)
ratio_rel = (rel_iqr / psnr_rel_iqr) if (rel_iqr is not None and psnr_rel_iqr) else None
cross_method_analysis["metrics"][metric] = {
"median_of_9_methods": med,
"relative_iqr_pct": rel_iqr,
"ratio_vs_psnr_relative": ratio_rel
}
# 3. 输出报告
md_lines = [
"# Phase 2 Part 3b — Final Heterogeneous Array Findings",
f"\n**Scope**: {len(METHODS)} methods (Vanilla + 8 heterogeneous), {len(SCENES)} scenes.",
"\n## Ultimate Discriminative Power (Relative IQR)",
f"> **Baseline**: PSNR Relative IQR across 9 methods = **{psnr_rel_iqr:.2f}%**",
"\n| Metric | Relative IQR (%) | Ratio vs PSNR (Discriminative Multiplier) |",
"|---|---|---|"
]
for metric in METRICS:
if metric == "psnr_full": continue
d = cross_method_analysis["metrics"][metric]
rel_str = f"{d['relative_iqr_pct']:.2f}%" if d['relative_iqr_pct'] is not None else "N/A"
ratio_str = f"**{d['ratio_vs_psnr_relative']:.1f}x**" if d['ratio_vs_psnr_relative'] is not None else "N/A"
md_lines.append(f"| {metric} | {rel_str} | {ratio_str} |")
md_content = "\n".join(md_lines)
with open(os.path.join(PROF_DIR, "part3b_findings.md"), "w") as f:
f.write(md_content)
print(md_content)