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>
This commit is contained in:
66
tools/debug_vh.py
Normal file
66
tools/debug_vh.py
Normal file
@@ -0,0 +1,66 @@
|
||||
"""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()
|
||||
Reference in New Issue
Block a user