- 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>
67 lines
2.2 KiB
Python
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()
|