diff --git a/AGENTS.md b/AGENTS.md index 273db6d..c1d9e86 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -115,12 +115,18 @@ When changing the primary compare page: For the current 20nm visual baseline, prefer: - [`navsea_strict_audit.py`](/root/sourceserver/pbf/navsea_strict_audit.py) +- [`strict_audit_hotspots_20nm.json`](/root/sourceserver/pbf/strict_audit_hotspots_20nm.json) This script combines: - browser-rendered screenshot diff from the fixed compare page - backend render audit summary from the current 20nm audit JSON +And now focuses on: + +- small AOI hotspot crops that are chosen to calibrate backend audit blind spots +- not just one coarse full-screen diff number + Use it when you need one report that explains both: - what the user really sees diff --git a/STEP_RECORD.md b/STEP_RECORD.md index 489cd4e..48963d5 100644 --- a/STEP_RECORD.md +++ b/STEP_RECORD.md @@ -334,12 +334,23 @@ Remote: `ssh://git@nas:2222/tei/pbf.git` 本轮已新增统一审计脚本: - [`navsea_strict_audit.py`](/root/sourceserver/pbf/navsea_strict_audit.py) +- [`strict_audit_hotspots_20nm.json`](/root/sourceserver/pbf/strict_audit_hotspots_20nm.json) 它会把两部分合并到同一份报告里: - 浏览器真实出图截图差异 - 当前 20nm backend render audit 摘要 +但当前实际工作方式已经进一步收紧为: + +- 后台 render audit 是主审计 +- 小范围 AOI 图像审计是校准审计 +- 不再只看整屏大 diff +- 只盯后台最容易误判的热点区域: + - 航标 / 灯塔 / 红绿标识 + - 鱼礁 / 碍航点 + - 远处 symbol / 小灯 + 当前产物: - [strict_audit_summary.md](/root/sourceserver/pbf/report/strict_audit/strict_audit_summary.md) @@ -348,25 +359,36 @@ Remote: `ssh://git@nas:2222/tei/pbf.git` - [compare_left.png](/root/sourceserver/pbf/report/strict_audit/compare_left.png) - [compare_right.png](/root/sourceserver/pbf/report/strict_audit/compare_right.png) - [compare_diff.png](/root/sourceserver/pbf/report/strict_audit/compare_diff.png) +- [report/strict_audit/hotspots](/root/sourceserver/pbf/report/strict_audit/hotspots) 当前 `r7` strict audit 结论: - compare version: - `20nm-r7-20260331-2044` - visual changed ratio: - - `0.887847` + - `0.899848` - changed pixels: - - `411961 / 464000` + - `230361 / 256000` - backend render audit 总体仍是: - `extra_in_engineering = 258317` - `missing_in_engineering = 258317` +当前热点 AOI 排名: + +1. `southwest_lighthouse_cluster` + - changed ratio: `0.972315` +2. `takashima_main_harbor_marks` + - changed ratio: `0.783759` +3. `takashima_inner_nearshore_hazards` + - changed ratio: `0.744246` +4. `east_breakwater_marks` + - changed ratio: `0.617833` + 这份统一审计的意义是: -- 以后不再把“视觉变好了”与“后台数字没变”当成互相冲突 -- 可以一眼看出: - - 浏览器真实出图变没变 - - 后台 render audit 有没有跟上 +- 以后不再只靠整屏图像差异判断问题 +- 可以用少量热点小框去校准后台 render audit 的盲区 +- 当用户肉眼说“这里还不对”时,可以直接把那个区域加入热点审计并复跑 线上已同步: @@ -701,21 +723,26 @@ Style 语义专项里仍最重要的是: 下次继续时,建议按这个顺序推进: -- 先以固定页面 - - `http://192.168.200.184/newpec/domain/navsea-compare-legacy-domain-compatible.html` +- 固定只用: + - `http://192.168.200.184/newpec/navsea-compare-karatsu-20nm.html` 作为唯一视觉基线 -- 以 [`src/Domain/style.domain-legacy-compatible-karatsu-10nm.deployed-2026-03-31.json`](/root/sourceserver/pbf/src/Domain/style.domain-legacy-compatible-karatsu-10nm.deployed-2026-03-31.json) - 作为“最接近旧版”的右侧样式母版 -- 在 Domain compatible 线上逐层确认: - - 哪些 layer 仍依赖 legacy 日文字段 - - 哪些可以直接切到标准字段而不改变视觉 - - 哪些需要加兼容映射才能保持视觉不变 +- 固定只用: + - `/home/wwwroot/pbf-delivery-karatsu-20nm` + 作为当前 delivery PBF +- 先围绕 strict audit 热点逐组修: + - `southwest_lighthouse_cluster` + - `takashima_main_harbor_marks` + - `takashima_inner_nearshore_hazards` + - `east_breakwater_marks` +- 每修一轮就重跑: + - [`navsea_strict_audit.py`](/root/sourceserver/pbf/navsea_strict_audit.py) +- 目的不是追求整屏 diff 立刻变小,而是让后台 render audit 对热点问题的判断逐步和肉眼一致 -当前真正的下一步不再是继续调 `20nm compare` 页面,而是: +当前真正的下一步是: -- 把 deployed baseline style 中对 legacy 字段的依赖系统列出来 -- 以固定 compare 页面做逐步替换验证 -- 每次替换后只在这一个页面上检查视觉回归 +- 把用户指出的新问题优先落进热点 AOI +- 用热点截图和点击拾取结果对照右侧实际图层与属性 +- 再决定是继续修 [`style.navsea-delivery-karatsu-10nm.json`](/root/sourceserver/pbf/src/pbf/style.navsea-delivery-karatsu-10nm.json),还是回到 builder 补更细的 delivery 语义字段 ## Important Notes @@ -729,4 +756,4 @@ Style 语义专项里仍最重要的是: 下次开机如果要快速接上,可以先看这份文件,再按下面这句继续: -`继续处理 STEP_RECORD.md 里记录的固定 compare 基线,围绕 navsea-compare-legacy-domain-compatible.html 这一个页面,在 pbf-domain-karatsu-10nm 线上逐步去掉日文字段依赖,同时保持视觉尽量不变。` +`继续处理 STEP_RECORD.md 里记录的 20nm 固定 compare 基线,围绕 navsea-compare-karatsu-20nm.html 这一个页面和 pbf-delivery-karatsu-20nm 这套 PBF,按 strict audit 的热点 AOI 逐组修视觉问题,并用小范围图像审计去校准后台 render audit。` diff --git a/navsea_strict_audit.py b/navsea_strict_audit.py index 8c63abf..448ea15 100644 --- a/navsea_strict_audit.py +++ b/navsea_strict_audit.py @@ -5,7 +5,6 @@ import argparse import json import re import subprocess -import tempfile from dataclasses import dataclass from pathlib import Path from typing import Any @@ -19,6 +18,7 @@ DEFAULT_BACKEND_AUDIT_JSON = Path( "/root/sourceserver/pbf/NavSea_Original_vs_Delivery_Render_Audit_Karatsu_20nm_2026-03-31.r7.json" ) DEFAULT_OUTPUT_DIR = Path("/root/sourceserver/pbf/report/strict_audit") +DEFAULT_HOTSPOTS_PATH = Path("/root/sourceserver/pbf/strict_audit_hotspots_20nm.json") @dataclass @@ -32,6 +32,15 @@ class CropBox: return (self.left, self.top, self.right, self.bottom) +@dataclass(frozen=True) +class HotspotSpec: + id: str + label: str + notes: str + pane_box_norm: tuple[float, float, float, float] + backend_focus: tuple[str, ...] + + def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser( description="Run strict audit by combining browser-rendered visual diff with backend render audit summary." @@ -39,11 +48,12 @@ def parse_args() -> argparse.Namespace: parser.add_argument("--compare-url", default=DEFAULT_COMPARE_URL) parser.add_argument("--backend-audit-json", type=Path, default=DEFAULT_BACKEND_AUDIT_JSON) parser.add_argument("--output-dir", type=Path, default=DEFAULT_OUTPUT_DIR) - parser.add_argument("--width", type=int, default=1600) - parser.add_argument("--height", type=int, default=900) + parser.add_argument("--width", type=int, default=1280) + parser.add_argument("--height", type=int, default=720) parser.add_argument("--toolbar-height", type=int, default=150) parser.add_argument("--bottom-trim", type=int, default=170) - parser.add_argument("--timeout-sec", type=int, default=90) + parser.add_argument("--timeout-sec", type=int, default=120) + parser.add_argument("--hotspots-json", type=Path, default=DEFAULT_HOTSPOTS_PATH) return parser.parse_args() @@ -65,7 +75,7 @@ def run_browser_screenshot(compare_url: str, output_png: Path, width: int, heigh "--disable-gpu", "--enable-unsafe-swiftshader", "--no-sandbox", - "--virtual-time-budget=20000", + "--virtual-time-budget=15000", f"--window-size={width},{height}", f"--screenshot={output_png}", compare_url, @@ -82,6 +92,30 @@ def build_crop_boxes(image_width: int, image_height: int, toolbar_height: int, b return left_box, right_box +def load_hotspots(hotspots_json: Path) -> list[HotspotSpec]: + raw = json.loads(hotspots_json.read_text()) + hotspots: list[HotspotSpec] = [] + for item in raw: + hotspots.append( + HotspotSpec( + id=item["id"], + label=item["label"], + notes=item.get("notes", ""), + pane_box_norm=tuple(item["pane_box_norm"]), + backend_focus=tuple(item.get("backend_focus", [])), + ) + ) + return hotspots + + +def normalized_box_to_pixels(box_norm: tuple[float, float, float, float], pane_width: int, pane_height: int) -> CropBox: + left = max(0, min(pane_width, round(box_norm[0] * pane_width))) + top = max(0, min(pane_height, round(box_norm[1] * pane_height))) + right = max(left + 1, min(pane_width, round(box_norm[2] * pane_width))) + bottom = max(top + 1, min(pane_height, round(box_norm[3] * pane_height))) + return CropBox(left, top, right, bottom) + + def compute_visual_metrics(left_img: Image.Image, right_img: Image.Image) -> dict[str, Any]: if left_img.size != right_img.size: raise ValueError(f"image sizes differ: {left_img.size} vs {right_img.size}") @@ -116,7 +150,16 @@ def compute_visual_metrics(left_img: Image.Image, right_img: Image.Image) -> dic } -def save_visual_outputs(full_png: Path, left_png: Path, right_png: Path, diff_png: Path, toolbar_height: int, bottom_trim: int) -> dict[str, Any]: +def save_visual_outputs( + full_png: Path, + left_png: Path, + right_png: Path, + diff_png: Path, + toolbar_height: int, + bottom_trim: int, + hotspots: list[HotspotSpec], + output_dir: Path, +) -> dict[str, Any]: image = Image.open(full_png).convert("RGBA") left_box, right_box = build_crop_boxes(image.width, image.height, toolbar_height, bottom_trim) left = image.crop(left_box.as_tuple()) @@ -131,9 +174,49 @@ def save_visual_outputs(full_png: Path, left_png: Path, right_png: Path, diff_pn metrics["full_crop_left"] = list(left_box.as_tuple()) metrics["full_crop_right"] = list(right_box.as_tuple()) + metrics["hotspots"] = save_hotspot_outputs(left, right, hotspots, output_dir) return metrics +def save_hotspot_outputs( + left_img: Image.Image, + right_img: Image.Image, + hotspots: list[HotspotSpec], + output_dir: Path, +) -> list[dict[str, Any]]: + hotspot_dir = output_dir / "hotspots" + hotspot_dir.mkdir(parents=True, exist_ok=True) + + results: list[dict[str, Any]] = [] + for hotspot in hotspots: + box = normalized_box_to_pixels(hotspot.pane_box_norm, left_img.width, left_img.height) + left_crop = left_img.crop(box.as_tuple()) + right_crop = right_img.crop(box.as_tuple()) + metrics = compute_visual_metrics(left_crop, right_crop) + diff_img = metrics.pop("diff_image") + diff_boost = diff_img.convert("RGB").point(lambda value: min(255, value * 4)) + + left_path = hotspot_dir / f"{hotspot.id}_left.png" + right_path = hotspot_dir / f"{hotspot.id}_right.png" + diff_path = hotspot_dir / f"{hotspot.id}_diff.png" + left_crop.save(left_path) + right_crop.save(right_path) + diff_boost.save(diff_path) + + metrics["id"] = hotspot.id + metrics["label"] = hotspot.label + metrics["notes"] = hotspot.notes + metrics["backend_focus"] = list(hotspot.backend_focus) + metrics["pane_box_norm"] = list(hotspot.pane_box_norm) + metrics["pane_box_pixels"] = list(box.as_tuple()) + metrics["left_image"] = str(left_path) + metrics["right_image"] = str(right_path) + metrics["diff_image"] = str(diff_path) + results.append(metrics) + + return sorted(results, key=lambda item: item["changed_ratio"], reverse=True) + + def load_backend_summary(report_json_path: Path) -> dict[str, Any]: data = json.loads(report_json_path.read_text()) @@ -200,6 +283,32 @@ def write_reports( f"- `{output_dir / 'compare_right.png'}`", f"- `{output_dir / 'compare_diff.png'}`", "", + "## Hotspot AOI Audit", + "", + ] + + for hotspot in visual_metrics.get("hotspots", []): + lines.extend( + [ + f"### {hotspot['label']}", + "", + f"- id: `{hotspot['id']}`", + f"- notes: `{hotspot['notes']}`", + f"- backend focus: `{hotspot['backend_focus']}`", + f"- changed pixels: `{hotspot['changed_pixels']}` / `{hotspot['total_pixels']}`", + f"- changed ratio: `{hotspot['changed_ratio']}`", + f"- mean abs rgb: `{hotspot['mean_abs_rgb']}`", + f"- pane box norm: `{hotspot['pane_box_norm']}`", + f"- pane box pixels: `{hotspot['pane_box_pixels']}`", + f"- left image: `{hotspot['left_image']}`", + f"- right image: `{hotspot['right_image']}`", + f"- diff image: `{hotspot['diff_image']}`", + "", + ] + ) + + lines.extend( + [ "## Backend Render Audit", "", f"- original feature instances: `{backend_summary['original_feature_instances']}`", @@ -208,7 +317,8 @@ def write_reports( "", "Status counts:", "", - ] + ] + ) for key, value in backend_summary["status_counts"].items(): lines.append(f"- `{key}`: `{value}`") @@ -238,6 +348,7 @@ def main() -> None: args.output_dir.mkdir(parents=True, exist_ok=True) compare_version = fetch_compare_version(args.compare_url) + hotspots = load_hotspots(args.hotspots_json) full_png = args.output_dir / "compare_full.png" left_png = args.output_dir / "compare_left.png" right_png = args.output_dir / "compare_right.png" @@ -251,6 +362,8 @@ def main() -> None: diff_png=diff_png, toolbar_height=args.toolbar_height, bottom_trim=args.bottom_trim, + hotspots=hotspots, + output_dir=args.output_dir, ) backend_summary = load_backend_summary(args.backend_audit_json) report_md, report_json = write_reports( @@ -270,6 +383,13 @@ def main() -> None: "report_json": str(report_json), "changed_ratio": visual_metrics["changed_ratio"], "changed_pixels": visual_metrics["changed_pixels"], + "hotspots": [ + { + "id": item["id"], + "changed_ratio": item["changed_ratio"], + } + for item in visual_metrics.get("hotspots", []) + ], }, ensure_ascii=False, indent=2, diff --git a/report/strict_audit/compare_diff.png b/report/strict_audit/compare_diff.png index 1ae6a86..d28a3ea 100644 Binary files a/report/strict_audit/compare_diff.png and b/report/strict_audit/compare_diff.png differ diff --git a/report/strict_audit/compare_full.png b/report/strict_audit/compare_full.png index a78b744..f401c31 100644 Binary files a/report/strict_audit/compare_full.png and b/report/strict_audit/compare_full.png differ diff --git a/report/strict_audit/compare_left.png b/report/strict_audit/compare_left.png index 7a87a68..769b817 100644 Binary files a/report/strict_audit/compare_left.png and b/report/strict_audit/compare_left.png differ diff --git a/report/strict_audit/compare_right.png b/report/strict_audit/compare_right.png index 8ea0c81..1daf98e 100644 Binary files a/report/strict_audit/compare_right.png and b/report/strict_audit/compare_right.png differ diff --git a/report/strict_audit/hotspots/east_breakwater_marks_diff.png b/report/strict_audit/hotspots/east_breakwater_marks_diff.png new file mode 100644 index 0000000..57df538 Binary files /dev/null and b/report/strict_audit/hotspots/east_breakwater_marks_diff.png differ diff --git a/report/strict_audit/hotspots/east_breakwater_marks_left.png b/report/strict_audit/hotspots/east_breakwater_marks_left.png new file mode 100644 index 0000000..c60b5bb Binary files /dev/null and b/report/strict_audit/hotspots/east_breakwater_marks_left.png differ diff --git a/report/strict_audit/hotspots/east_breakwater_marks_right.png b/report/strict_audit/hotspots/east_breakwater_marks_right.png new file mode 100644 index 0000000..7a08ac2 Binary files /dev/null and b/report/strict_audit/hotspots/east_breakwater_marks_right.png differ diff --git a/report/strict_audit/hotspots/southwest_lighthouse_cluster_diff.png b/report/strict_audit/hotspots/southwest_lighthouse_cluster_diff.png new file mode 100644 index 0000000..5203e79 Binary files /dev/null and b/report/strict_audit/hotspots/southwest_lighthouse_cluster_diff.png differ diff --git a/report/strict_audit/hotspots/southwest_lighthouse_cluster_left.png b/report/strict_audit/hotspots/southwest_lighthouse_cluster_left.png new file mode 100644 index 0000000..a425f08 Binary files /dev/null and b/report/strict_audit/hotspots/southwest_lighthouse_cluster_left.png differ diff --git a/report/strict_audit/hotspots/southwest_lighthouse_cluster_right.png b/report/strict_audit/hotspots/southwest_lighthouse_cluster_right.png new file mode 100644 index 0000000..a47fcf2 Binary files /dev/null and b/report/strict_audit/hotspots/southwest_lighthouse_cluster_right.png differ diff --git a/report/strict_audit/hotspots/takashima_inner_nearshore_hazards_diff.png b/report/strict_audit/hotspots/takashima_inner_nearshore_hazards_diff.png new file mode 100644 index 0000000..beb7570 Binary files /dev/null and b/report/strict_audit/hotspots/takashima_inner_nearshore_hazards_diff.png differ diff --git a/report/strict_audit/hotspots/takashima_inner_nearshore_hazards_left.png b/report/strict_audit/hotspots/takashima_inner_nearshore_hazards_left.png new file mode 100644 index 0000000..af49485 Binary files /dev/null and b/report/strict_audit/hotspots/takashima_inner_nearshore_hazards_left.png differ diff --git a/report/strict_audit/hotspots/takashima_inner_nearshore_hazards_right.png b/report/strict_audit/hotspots/takashima_inner_nearshore_hazards_right.png new file mode 100644 index 0000000..361d398 Binary files /dev/null and b/report/strict_audit/hotspots/takashima_inner_nearshore_hazards_right.png differ diff --git a/report/strict_audit/hotspots/takashima_main_harbor_marks_diff.png b/report/strict_audit/hotspots/takashima_main_harbor_marks_diff.png new file mode 100644 index 0000000..3588bba Binary files /dev/null and b/report/strict_audit/hotspots/takashima_main_harbor_marks_diff.png differ diff --git a/report/strict_audit/hotspots/takashima_main_harbor_marks_left.png b/report/strict_audit/hotspots/takashima_main_harbor_marks_left.png new file mode 100644 index 0000000..2e4c956 Binary files /dev/null and b/report/strict_audit/hotspots/takashima_main_harbor_marks_left.png differ diff --git a/report/strict_audit/hotspots/takashima_main_harbor_marks_right.png b/report/strict_audit/hotspots/takashima_main_harbor_marks_right.png new file mode 100644 index 0000000..9307acb Binary files /dev/null and b/report/strict_audit/hotspots/takashima_main_harbor_marks_right.png differ diff --git a/report/strict_audit/strict_audit_summary.json b/report/strict_audit/strict_audit_summary.json index 4ac5b69..346d996 100644 --- a/report/strict_audit/strict_audit_summary.json +++ b/report/strict_audit/strict_audit_summary.json @@ -3,38 +3,222 @@ "compare_version": "20nm-r7-20260331-2044", "backend_audit_json": "/root/sourceserver/pbf/NavSea_Original_vs_Delivery_Render_Audit_Karatsu_20nm_2026-03-31.r7.json", "visual_metrics": { - "image_width": 800, - "image_height": 580, - "total_pixels": 464000, - "changed_pixels": 411961, - "changed_ratio": 0.887847, + "image_width": 640, + "image_height": 400, + "total_pixels": 256000, + "changed_pixels": 230361, + "changed_ratio": 0.899848, "mean_abs_rgb": [ - 30.3034, - 31.6079, - 61.2516 + 27.394, + 28.0012, + 51.399 ], "rms_rgb": [ - 45.7879, - 45.5806, - 75.4396 + 42.1614, + 40.8117, + 66.9404 ], "diff_bbox": [ 0, 0, - 800, - 580 + 640, + 400 ], "full_crop_left": [ 0, 150, - 800, - 730 + 640, + 550 ], "full_crop_right": [ - 800, + 640, 150, - 1600, - 730 + 1280, + 550 + ], + "hotspots": [ + { + "image_width": 90, + "image_height": 120, + "total_pixels": 10800, + "changed_pixels": 10501, + "changed_ratio": 0.972315, + "mean_abs_rgb": [ + 35.1766, + 36.7016, + 83.6827 + ], + "rms_rgb": [ + 43.2452, + 44.0282, + 90.1318 + ], + "diff_bbox": [ + 0, + 0, + 90, + 120 + ], + "id": "southwest_lighthouse_cluster", + "label": "西南灯塔区", + "notes": "左下角远处灯塔与标记点,用来校验远处 symbol 表现。", + "backend_focus": [ + "p航路標識群", + "p陸上構造物" + ], + "pane_box_norm": [ + 0.0, + 0.7, + 0.14, + 1.0 + ], + "pane_box_pixels": [ + 0, + 280, + 90, + 400 + ], + "left_image": "/root/sourceserver/pbf/report/strict_audit/hotspots/southwest_lighthouse_cluster_left.png", + "right_image": "/root/sourceserver/pbf/report/strict_audit/hotspots/southwest_lighthouse_cluster_right.png", + "diff_image": "/root/sourceserver/pbf/report/strict_audit/hotspots/southwest_lighthouse_cluster_diff.png" + }, + { + "image_width": 147, + "image_height": 80, + "total_pixels": 11760, + "changed_pixels": 9217, + "changed_ratio": 0.783759, + "mean_abs_rgb": [ + 25.8832, + 26.3819, + 35.8165 + ], + "rms_rgb": [ + 40.7513, + 43.6982, + 55.4931 + ], + "diff_bbox": [ + 0, + 0, + 147, + 80 + ], + "id": "takashima_main_harbor_marks", + "label": "高岛主港航标区", + "notes": "主港口灯塔、红绿标识、近岸障碍标记。", + "backend_focus": [ + "p航路標識群", + "safety_icon_missing", + "text_missing_in_engineering" + ], + "pane_box_norm": [ + 0.34, + 0.05, + 0.57, + 0.25 + ], + "pane_box_pixels": [ + 218, + 20, + 365, + 100 + ], + "left_image": "/root/sourceserver/pbf/report/strict_audit/hotspots/takashima_main_harbor_marks_left.png", + "right_image": "/root/sourceserver/pbf/report/strict_audit/hotspots/takashima_main_harbor_marks_right.png", + "diff_image": "/root/sourceserver/pbf/report/strict_audit/hotspots/takashima_main_harbor_marks_diff.png" + }, + { + "image_width": 115, + "image_height": 68, + "total_pixels": 7820, + "changed_pixels": 5820, + "changed_ratio": 0.744246, + "mean_abs_rgb": [ + 26.0925, + 28.3926, + 32.3252 + ], + "rms_rgb": [ + 40.8552, + 45.3891, + 51.1523 + ], + "diff_bbox": [ + 0, + 0, + 115, + 68 + ], + "id": "takashima_inner_nearshore_hazards", + "label": "高岛近岸碍航与鱼礁区", + "notes": "近岸鱼礁、碍航点、灯塔与小灯混合区。", + "backend_focus": [ + "p投錨注意障害物", + "p航行危険障害物", + "p航路標識群" + ], + "pane_box_norm": [ + 0.44, + 0.14, + 0.62, + 0.31 + ], + "pane_box_pixels": [ + 282, + 56, + 397, + 124 + ], + "left_image": "/root/sourceserver/pbf/report/strict_audit/hotspots/takashima_inner_nearshore_hazards_left.png", + "right_image": "/root/sourceserver/pbf/report/strict_audit/hotspots/takashima_inner_nearshore_hazards_right.png", + "diff_image": "/root/sourceserver/pbf/report/strict_audit/hotspots/takashima_inner_nearshore_hazards_diff.png" + }, + { + "image_width": 109, + "image_height": 64, + "total_pixels": 6976, + "changed_pixels": 4310, + "changed_ratio": 0.617833, + "mean_abs_rgb": [ + 14.5257, + 14.9903, + 20.7008 + ], + "rms_rgb": [ + 30.1275, + 32.1947, + 39.6306 + ], + "diff_bbox": [ + 0, + 4, + 109, + 64 + ], + "id": "east_breakwater_marks", + "label": "东侧防波堤灯台区", + "notes": "右上沿岸的防波堤灯台与港口标记。", + "backend_focus": [ + "p航路標識群", + "safety_icon_missing" + ], + "pane_box_norm": [ + 0.83, + 0.0, + 1.0, + 0.16 + ], + "pane_box_pixels": [ + 531, + 0, + 640, + 64 + ], + "left_image": "/root/sourceserver/pbf/report/strict_audit/hotspots/east_breakwater_marks_left.png", + "right_image": "/root/sourceserver/pbf/report/strict_audit/hotspots/east_breakwater_marks_right.png", + "diff_image": "/root/sourceserver/pbf/report/strict_audit/hotspots/east_breakwater_marks_diff.png" + } ] }, "backend_summary": { diff --git a/report/strict_audit/strict_audit_summary.md b/report/strict_audit/strict_audit_summary.md index 5127af2..b9e51d4 100644 --- a/report/strict_audit/strict_audit_summary.md +++ b/report/strict_audit/strict_audit_summary.md @@ -8,12 +8,12 @@ ## Visual Audit -- changed pixels: `411961` / `464000` -- changed ratio: `0.887847` -- mean abs rgb: `[30.3034, 31.6079, 61.2516]` -- rms rgb: `[45.7879, 45.5806, 75.4396]` -- left crop: `[0, 150, 800, 730]` -- right crop: `[800, 150, 1600, 730]` +- changed pixels: `230361` / `256000` +- changed ratio: `0.899848` +- mean abs rgb: `[27.394, 28.0012, 51.399]` +- rms rgb: `[42.1614, 40.8117, 66.9404]` +- left crop: `[0, 150, 640, 550]` +- right crop: `[640, 150, 1280, 550]` Artifacts: @@ -22,6 +22,64 @@ Artifacts: - `/root/sourceserver/pbf/report/strict_audit/compare_right.png` - `/root/sourceserver/pbf/report/strict_audit/compare_diff.png` +## Hotspot AOI Audit + +### 西南灯塔区 + +- id: `southwest_lighthouse_cluster` +- notes: `左下角远处灯塔与标记点,用来校验远处 symbol 表现。` +- backend focus: `['p航路標識群', 'p陸上構造物']` +- changed pixels: `10501` / `10800` +- changed ratio: `0.972315` +- mean abs rgb: `[35.1766, 36.7016, 83.6827]` +- pane box norm: `[0.0, 0.7, 0.14, 1.0]` +- pane box pixels: `[0, 280, 90, 400]` +- left image: `/root/sourceserver/pbf/report/strict_audit/hotspots/southwest_lighthouse_cluster_left.png` +- right image: `/root/sourceserver/pbf/report/strict_audit/hotspots/southwest_lighthouse_cluster_right.png` +- diff image: `/root/sourceserver/pbf/report/strict_audit/hotspots/southwest_lighthouse_cluster_diff.png` + +### 高岛主港航标区 + +- id: `takashima_main_harbor_marks` +- notes: `主港口灯塔、红绿标识、近岸障碍标记。` +- backend focus: `['p航路標識群', 'safety_icon_missing', 'text_missing_in_engineering']` +- changed pixels: `9217` / `11760` +- changed ratio: `0.783759` +- mean abs rgb: `[25.8832, 26.3819, 35.8165]` +- pane box norm: `[0.34, 0.05, 0.57, 0.25]` +- pane box pixels: `[218, 20, 365, 100]` +- left image: `/root/sourceserver/pbf/report/strict_audit/hotspots/takashima_main_harbor_marks_left.png` +- right image: `/root/sourceserver/pbf/report/strict_audit/hotspots/takashima_main_harbor_marks_right.png` +- diff image: `/root/sourceserver/pbf/report/strict_audit/hotspots/takashima_main_harbor_marks_diff.png` + +### 高岛近岸碍航与鱼礁区 + +- id: `takashima_inner_nearshore_hazards` +- notes: `近岸鱼礁、碍航点、灯塔与小灯混合区。` +- backend focus: `['p投錨注意障害物', 'p航行危険障害物', 'p航路標識群']` +- changed pixels: `5820` / `7820` +- changed ratio: `0.744246` +- mean abs rgb: `[26.0925, 28.3926, 32.3252]` +- pane box norm: `[0.44, 0.14, 0.62, 0.31]` +- pane box pixels: `[282, 56, 397, 124]` +- left image: `/root/sourceserver/pbf/report/strict_audit/hotspots/takashima_inner_nearshore_hazards_left.png` +- right image: `/root/sourceserver/pbf/report/strict_audit/hotspots/takashima_inner_nearshore_hazards_right.png` +- diff image: `/root/sourceserver/pbf/report/strict_audit/hotspots/takashima_inner_nearshore_hazards_diff.png` + +### 东侧防波堤灯台区 + +- id: `east_breakwater_marks` +- notes: `右上沿岸的防波堤灯台与港口标记。` +- backend focus: `['p航路標識群', 'safety_icon_missing']` +- changed pixels: `4310` / `6976` +- changed ratio: `0.617833` +- mean abs rgb: `[14.5257, 14.9903, 20.7008]` +- pane box norm: `[0.83, 0.0, 1.0, 0.16]` +- pane box pixels: `[531, 0, 640, 64]` +- left image: `/root/sourceserver/pbf/report/strict_audit/hotspots/east_breakwater_marks_left.png` +- right image: `/root/sourceserver/pbf/report/strict_audit/hotspots/east_breakwater_marks_right.png` +- diff image: `/root/sourceserver/pbf/report/strict_audit/hotspots/east_breakwater_marks_diff.png` + ## Backend Render Audit - original feature instances: `258317` diff --git a/strict_audit_hotspots_20nm.json b/strict_audit_hotspots_20nm.json new file mode 100644 index 0000000..18a6d2c --- /dev/null +++ b/strict_audit_hotspots_20nm.json @@ -0,0 +1,44 @@ +[ + { + "id": "takashima_main_harbor_marks", + "label": "高岛主港航标区", + "notes": "主港口灯塔、红绿标识、近岸障碍标记。", + "pane_box_norm": [0.34, 0.05, 0.57, 0.25], + "backend_focus": [ + "p航路標識群", + "safety_icon_missing", + "text_missing_in_engineering" + ] + }, + { + "id": "takashima_inner_nearshore_hazards", + "label": "高岛近岸碍航与鱼礁区", + "notes": "近岸鱼礁、碍航点、灯塔与小灯混合区。", + "pane_box_norm": [0.44, 0.14, 0.62, 0.31], + "backend_focus": [ + "p投錨注意障害物", + "p航行危険障害物", + "p航路標識群" + ] + }, + { + "id": "east_breakwater_marks", + "label": "东侧防波堤灯台区", + "notes": "右上沿岸的防波堤灯台与港口标记。", + "pane_box_norm": [0.83, 0.0, 1.0, 0.16], + "backend_focus": [ + "p航路標識群", + "safety_icon_missing" + ] + }, + { + "id": "southwest_lighthouse_cluster", + "label": "西南灯塔区", + "notes": "左下角远处灯塔与标记点,用来校验远处 symbol 表现。", + "pane_box_norm": [0.0, 0.70, 0.14, 1.0], + "backend_focus": [ + "p航路標識群", + "p陸上構造物" + ] + } +]