Files
railway-client/docs/진행현황_2026-05-22.md
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

10 KiB
Raw Blame History

철도 디지털 트윈 — AI 라벨링 파이프라인 진행 현황

기준일: 2026-05-22
프로젝트: d:\MYCLAUDE_PROJECT\x-anylabeling01
목표: 드론 부감 이미지에서 철도 지장물 자동 탐지 → YOLOv26 학습 데이터 구축 → 디지털 트윈


1. 탐지 대상 (지장물 카테고리)

카테고리 한글 상태
raamen (ラーメン) 라멘형 전철주 완료
pole 전철주 일반 완료
rail 레일 완료
sleeper 침목 완료
control_box 컨트롤박스 (소형 금속 박스) 🔄 진행 중

2. 완료된 작업

2-1. 라멘형 전철주 검출 (tools/detect_raamen.py)

  • 방식: SAM3.1 텍스트 grounding + VP(소실점) 기반 H/V 분류
  • 입력: 드론 고해상도 이미지 (.JPG), 선택적으로 --json (detect_all_objects.py 결과 재사용)
  • 출력: AnyLabeling JSON (폴리곤 + H/V 라벨)
  • 핵심 알고리즘:
    • 이미지를 타일 분할 → SAM3.1 병렬 호출
    • VP(소실점) 다중 시드 + 반복 정제로 수직(V) / 수평(H) 분류
    • H-max-diff 필터로 수평 빔과 수직 기둥 구분
    • Cross-NMS로 중복 제거
  • 최근 커밋: 923c396 (VP 다중 시드 + 반복 정제로 V/H 분류 정확도 향상)

2-2. 전체 객체 검출 UI (tools/web_ui.py)

  • FastAPI + uvicorn 기반 웹 UI
  • 이미지 선택 → 타일/카테고리 설정 → detect_all_objects.py 실행 → 결과 프리뷰
  • 개선 사항 (이번 세션):
    • 마우스 휠 줌 + 드래그 팬 추가
    • --save-labels--save-json 수정 (txt 금지, JSON만)
    • --debug 플래그 제거 (존재하지 않는 옵션)
    • 프리뷰 해상도 1200 → 2000px

2-3. 전체 객체 검출 (tools/detect_all_objects.py)

  • SAM3.1 텍스트 grounding, 카테고리별 타일 검출
  • configs/railway_zone.json 카테고리 설정 사용
  • 출력 경로 개선: output/detect/{이미지명}/tiles{N}_{카테고리}_{번호}.jpg
  • --save-json 옵션으로 AnyLabeling JSON 저장

2-4. SAM3 Everything 탐색 (tools/sam3_everything_explore.py)

  • 38개 항목 광역 프롬프트로 이미지 전체 탐색
  • 타일 병렬 처리 + NMS
  • JSON 라벨 통계 출력 (text_prompt 후보 발굴용)
  • --prompt-extra 옵션으로 추가 어휘 주입 가능
  • 테스트 결과 (DJI_20260306113838_0004.JPG, 8×6 타일):
    • 총 7,111개 세그먼트 검출
    • control_box 관련 라벨 1,740개 매칭
    • 문제: 정밀도 ~1-2%, false positive 폭증 → SAM3 텍스트 grounding 한계 확인

3. 핵심 결정 사항

3-1. YOLOv26 단독 전환 (2026-05-19)

배경: SAM3.1 텍스트 grounding으로 control_box 탐지 시도 → 완전 실패

시도 결과
고립 프롬프트 ("railway control box, electrical cabinet...") 0 → 0 검출
conf 0.20 → 0.10 낮춤 0 → 0 검출
16×12 세밀한 타일 그리드 0 → 0 검출
인접 4개 타일 수동 실험 0 → 0 검출
38개 광역 프롬프트 1,740개 매칭, 정밀도 ~1-2%

결론: SAM3.1은 부감 드론 시점 소형 객체 텍스트 grounding에 부적합

전환: YOLOv26 학습 데이터셋 구축 → fine-tune → 추론 경로

준비 완료:

  • yolo26n.pt, yolo26n-seg.pt 사전학습 모델 (프로젝트 루트)
  • ultralytics 26.x 설치 완료
  • X-AnyLabeling-Server YOLO endpoint 연동 완료

3-2. SAM3 활용 방식 변경

  • 폐기: SAM3 텍스트 grounding → 단독 검출기
  • 유지: SAM3 everything 모드 → 후보 bbox 생성기 (인간 라벨링 보조)
  • 신규: YOLOv26 fine-tune → production 검출기

4. 현재 진행 중: control_box 라벨링 파이프라인

4-1. 전략 (부트스트랩)

SAM3 everything → 1,740개 후보 bbox
        ↓
  labeling_server.py (인간 투표)
        ↓
  MIN_VOTES=3, TRUE_RATIO=0.6 필터
        ↓
  YOLO 학습용 txt 라벨
        ↓
  YOLOv26 fine-tune (yolo26n.pt)
        ↓
  production 검출기

4-2. 라벨링 서버 (tools/labeling_server.py) — v2

실행 명령:

python tools/labeling_server.py \
  --json "data/역사이미지/slope/DJI_20260306113838_0004_everything.json" \
  --reset

브라우저: http://서버IP:7001

UI 방식 (v2 — 전체 이미지 오버레이):

  • 전체 드론 이미지 표시 (최대 3000px)
  • SAM3 후보 1,740개를 색상 bbox로 오버레이
    • 🟡 노랑: 미투표
    • 🟢 초록: 컨트롤박스 YES
    • 🔴 빨강: 아님 NO
    • 회색: 타인 투표 완료
  • 마우스 휠 줌 / 드래그 이동 / F키 맞춤
  • bbox 클릭 → YES/NO 즉시 저장 (SQLite)
  • 호버 → 라벨명 + 점수 툴팁

집계 기준:

  • MIN_VOTES = 3 (3인 이상 투표)
  • TRUE_RATIO = 0.6 (60% 이상 YES)

YOLO 내보내기: POST /api/exportlabels/yolo_export/*.txt

DB: labels/labeling.db (SQLite, 로컬)

  • candidates 테이블: json_idx, label, score, bbox, image_path
  • votes 테이블: candidate_id, user, vote, ts (UNIQUE 제약 — 1인 1표)

4-3. 현재 데이터

항목
입력 이미지 data/역사이미지/slope/DJI_20260306113838_0004.JPG
everything JSON DJI_20260306113838_0004_everything.json
전체 세그먼트 7,111개
control_box 후보 1,740개
라벨링 진행 미시작 (서버 실행 대기)

5. 다음 할 일 (TODO)

즉시

  • labeling_server.py 배포 → 직원 20명 라벨링 시작
  • 추가 이미지 _everything.json 생성 (현재 1장 → 더 많이 필요)

SAM3 Everything 프롬프트 재설계 (⚠️ 중요)

  • 문제: 현재 DISCOVERY_PROMPT 38개 항목이 control_box를 제대로 분리 못함
  • 방향: 더 구체적인 시각적 특징 기반 프롬프트 필요
    • 기존: "small square box", "compact trackside junction box" 등 → FP 폭증
    • 새 방향 검토 필요:
      • 크기/형태 명시: "small gray square metal lid on ground", "square dark gray lid flush with ballast"
      • 재질/색상 특징: "weathered gray metal surface", "flat square cover"
      • 부감 시점 특화: "top-down view of small electrical enclosure"

학습 후

  • 50-100개 이상 확정 라벨 → yolo train 실행
    yolo train model=yolo26n.pt data=configs/control_box.yaml epochs=100 imgsz=640
    
  • 검출 성능 검증 → 미달 시 데이터 추가 수집

6. 설정 파일

configs/railway_zone.json (control_box 항목)

{
  "name": "control_box",
  "name_kr": "컨트롤박스",
  "prompt": "small square gray metal box beside rail, compact trackside junction box, small near-square electrical enclosure on the ground, small cube-shaped equipment box next to track",
  "conf": 0.15,
  "priority": 2
}

SAM3 Everything DISCOVERY_PROMPT 현재 상태 (재설계 필요)

"railroad track, railway rail,
catenary pole, overhead line pole, electric pole,
overhead wire, catenary wire, power line cable,
railway sleeper, concrete tie,
guardrail, highway barrier, road fence,
bridge, viaduct, overpass,
vegetation, tree, bush, grass,
building, structure, roof, wall,
vehicle, car, truck,
road, asphalt, pavement,
slope, embankment, retaining wall,
noise barrier, sound wall,
signal, sign board"

→ control_box 관련 항목 부재 → everything 탐색에서 누락됨


7. 기술 제약 / 주의사항

  • CLI 명령어: bash 한 종류만 사용 (PowerShell 혼용 금지)
  • 라벨 저장: --save-json 옵션만 사용 (txt 금지)
  • detect_all_objects.py: --workers 8 항상 명시
  • SAM3 서버: python.exe -m app.main (X-AnyLabeling-Server 디렉토리에서 실행, localhost:8000)
  • GDINO: 폐기됨. SAM3.1 텍스트 프롬프트 (params.text_prompt) 직접 사용
  • YOLOv26: ultralytics 26.x, 모델 파일 yolo26n.pt / yolo26n-seg.pt (프로젝트 루트)

8. 주요 파일 구조

x-anylabeling01/
├── tools/
│   ├── detect_all_objects.py      # 메인 검출 도구 (SAM3 타일 검출)
│   ├── detect_raamen.py           # 라멘형 전철주 전용 검출
│   ├── web_ui.py                  # 웹 UI (FastAPI, port:8001)
│   ├── labeling_server.py         # CAPTCHA 라벨링 서버 (port:7001) ← 신규 v2
│   ├── sam3_everything_explore.py # SAM3 전체 탐색 (프롬프트 발굴용) ← 개선 필요
│   ├── sam3_segment_everything.py # SAM3 포인트 그리드 세그멘테이션
│   └── post_merge_poles.py        # 전철주 병합 후처리
├── configs/
│   └── railway_zone.json          # 카테고리별 프롬프트/conf/priority
├── labels/
│   ├── labeling.db                # 라벨링 투표 SQLite DB
│   └── yolo_export/               # YOLO txt 내보내기 결과
├── output/
│   └── detect/{이미지명}/         # 검출 결과 이미지 (타일/카테고리별)
├── yolo26n.pt                     # YOLOv26 nano 사전학습 모델
└── yolo26n-seg.pt                 # YOLOv26 nano segmentation 모델

9. 다음 세션 시작 프롬프트

철도 디지털 트윈 프로젝트 (x-anylabeling01) 이어서 진행합니다.

[현재 상태]
- detect_raamen.py (라멘형 전철주) 검출 완료
- detect_all_objects.py (다중 카테고리 SAM3 검출) 완료
- web_ui.py 개선 완료 (줌/팬, --save-json, 폴더 구조)
- labeling_server.py v2 완료 (전체 이미지 + bbox 오버레이, 클릭 투표)

[오늘 할 일: SAM3 Everything 프롬프트 재설계]
tools/sam3_everything_explore.py의 DISCOVERY_PROMPT를 재설계해야 합니다.

현재 문제:
- 기존 38개 항목 광역 프롬프트로 DJI_20260306113838_0004.JPG 처리 시
- 7,111개 세그먼트, control_box 관련 1,740개 매칭 → 정밀도 ~1-2%
- control_box (소형 정사각형 금속 박스, 자갈도상 옆 지면에 놓인 것)가 제대로 분리 안 됨

목표:
- control_box를 효과적으로 탐지할 수 있는 SAM3 텍스트 프롬프트 발굴
- 혹은 SAM3 everything → 후보 bbox 1,740개에서 더 정밀하게 필터링하는 방법 개선
- 최종적으로는 YOLOv26 학습 데이터 50-100개 확보

[기술 제약]
- CLI는 bash만 사용 (PowerShell 혼용 금지)
- 라벨 저장은 --save-json만 (txt 금지)
- SAM3 서버: python.exe -m app.main (X-AnyLabeling-Server에서, localhost:8000)
- detect_all_objects.py 실행 시 --workers 8 항상 명시