Files
railway-client/tools/debug_vh.py
minsung 4c15d5ff5d sam31server 전환, 라멘 파이프라인 정리, 문서 추가
- sam31server를 SAM3.1 서버로 전환 (x-anylabeling01 대체)
- detect_raamen.py: B/C 분류 기반 라멘형 전철주 검출 파이프라인 정비
- sam3_everything_explore.py: Discovery Sweep 탐색 모드 정리
- detect_all_objects.py: 타일 검출 개선
- docs/railway-client-guide.html: 서버·도구·파이프라인 전체 가이드 추가
- tools 추가: detect_control_box, group_ramen_poles, render_everything_by_label, render_label_polygons, debug_vh

Closes #1

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 10:11:52 +09:00

67 lines
2.2 KiB
Python

"""debug_vh.py — catenary_pole V/H 분류 디버그 시각화."""
import argparse
import json
import sys
import cv2
import numpy as np
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent))
from group_ramen_poles import _poly_orient
COLOR = {
'V': (255, 80, 0),
'H': (0, 80, 255),
'?': (160, 160, 160),
'?_ambiguous': (0, 255, 0),
}
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--label", required=True, help="AnyLabeling JSON")
ap.add_argument("--image", required=True, help="원본 이미지")
ap.add_argument("--output", required=True, help="출력 JPG")
args = ap.parse_args()
data = json.loads(Path(args.label).read_text(encoding="utf-8"))
iH, iW = data["imageHeight"], data["imageWidth"]
buf = np.fromfile(args.image, dtype=np.uint8)
img = cv2.imdecode(buf, cv2.IMREAD_COLOR)
H, W = img.shape[:2]
font_sc = max(1.0, min(W, H) / 4000)
thick = max(2, int(font_sc * 2))
for full_idx, s in enumerate(data["shapes"]):
if s.get("label") != "catenary_pole":
continue
pts = np.array(s["points"], dtype=np.int32)
o = _poly_orient(s["points"], iH, iW)
col = COLOR.get(o, (160, 160, 160))
ov = img.copy()
cv2.fillPoly(ov, [pts], col)
cv2.addWeighted(ov, 0.30, img, 0.70, 0, img)
cv2.polylines(img, [pts], True, col, 3)
cx, cy = int(pts[:, 0].mean()), int(pts[:, 1].mean())
label = f"{full_idx}{o}"
(tw, th), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, font_sc, thick)
tx, ty = cx - tw // 2, cy + th // 2
cv2.rectangle(img, (tx-3, ty-th-4), (tx+tw+3, ty+4), (0, 0, 0), -1)
cv2.putText(img, label, (tx, ty), cv2.FONT_HERSHEY_SIMPLEX, font_sc, (255,255,255), thick+1, cv2.LINE_AA)
cv2.putText(img, label, (tx, ty), cv2.FONT_HERSHEY_SIMPLEX, font_sc, col, thick, cv2.LINE_AA)
h, w = img.shape[:2]
scale = min(1.0, 4096 / max(h, w))
if scale < 1.0:
img = cv2.resize(img, (int(w * scale), int(h * scale)))
out = Path(args.output)
out.parent.mkdir(parents=True, exist_ok=True)
cv2.imencode(out.suffix, img)[1].tofile(str(out))
print(f"saved: {out}")
if __name__ == "__main__":
main()