Railway Client 사용 가이드
+드론 항공 이미지 기반 철도 시설물 자동 검출 파이프라인
+ +🔴 라멘형(門) 전철주 검출 파이프라인
+ 최우선 기능 + +드론 사선 촬영 이미지에서 門자형 라멘 구조 전철주를 검출한다. SAM3.1로 폴리곤을 추출한 후 소실점(Vanishing Point) 기반 기하학 분석으로 C(기둥)/B(빔)를 분류, 라멘 그룹을 판정한다.
+ +B / C 접두어 — 분류 기준
++ 소실점 방향으로 향하는 수직·사선 폴리곤.
각도 임계값(
--c-thresh, 기본 20°) 이내.
+ + 수평으로 뻗은 폴리곤.
소실점 방향에서 크게 벗어난 것. +
2단계 파이프라인
+(catenary_pole polygons)
라멘 그룹 판정
Step 1 — 전철주 폴리곤 추출
+cd D:\MYCLAUDE_PROJECT\railway-client
+
+.venv\Scripts\python.exe tools/detect_all_objects.py `
+ --input "data/역사구간/1.회덕역/DJI_20260306100900_0034.JPG" `
+ --categories configs/railway_zone.json `
+ --tiles all `
+ --cols 4 --rows 3 --overlap 0.10 --workers 2
+
+ 출력: output/detect/DJI_20260306100900_0034.json — X-AnyLabeling 호환 annotation
Step 2 — 라멘 구조 분석
+.venv\Scripts\python.exe tools/detect_raamen.py `
+ --image "data/역사구간/1.회덕역/DJI_20260306100900_0034.JPG" `
+ --label "output/detect/DJI_20260306100900_0034.json" `
+ --output "output/raamen/DJI_20260306100900_0034_raamen.png"
+
+ 출력: 이미지 위에 C/B 라벨 + 라멘 그룹 번호 오버레이
+ +detect_raamen.py 파라미터
+| 파라미터 | 기본값 | 설명 |
|---|---|---|
--image | 필수 | 원본 이미지 경로 |
--label | 필수 | JSON annotation 파일 (detect_all_objects 출력) |
--output | 자동 생성 | 결과 이미지 저장 경로 |
--class-names | catenary_pole | 분석할 클래스 이름 (쉼표 구분) |
--class-ids | 없음 | 클래스 ID로 필터링 (대안) |
--epsilon | 4.0 | 폴리곤 단순화 강도 (높을수록 단순) |
--c-thresh | 20.0° | C(기둥) 판정 각도 임계값 |
--b-max-diff | 75.0° | B(빔) 최대 각도 편차 |
--margin | 30px | 근접성 그룹핑 거리 |
4단계 내부 처리 흐름
+| Phase | 처리 내용 |
|---|---|
| Phase 1 | 폴리곤 단순화(approxPolyDP) + 소실점(Vanishing Point) 계산 |
| Phase 2 | 동적 C/B 분류 — 소실점 기반 기대 각도와 비교 |
| Phase 3 | 근접성 기반 그룹핑 — B 앵커 기준으로 아래 C 탐색 |
| Phase 4 | 라멘 구조 판정 + 가림(occlusion) 예외 처리 |
Everything 탐색 모드 (Discovery Sweep)
+ +새 지역·새 구간을 처음 분석할 때 사용. SAM3.1 텍스트 grounding 방식이므로 완전 무프롬프트는 불가 — 대신 광범위한 Discovery Prompt로 이미지에 존재하는 모든 객체를 일괄 검출하고 라벨 빈도를 집계한다.
+ +detect_all_objects.py 의 카테고리·conf 튜닝에 활용.
+ 사용법
+cd D:\MYCLAUDE_PROJECT\railway-client
+
+# 기본 (8×6 타일)
+.venv\Scripts\python.exe tools/sam3_everything_explore.py `
+ --input "data/역사구간/1.회덕역/DJI_20260306100900_0034.JPG"
+
+# 타일 수 조정 (고해상도 드론 이미지)
+.venv\Scripts\python.exe tools/sam3_everything_explore.py `
+ --input "data/역사구간/..." `
+ --cols 8 --rows 6 --conf 0.10 --workers 4
+
+# 특정 영역(ROI)만 탐색
+.venv\Scripts\python.exe tools/sam3_everything_explore.py `
+ --input "..." `
+ --zone 1000 500 3000 2500
+
+# Discovery Prompt에 추가 키워드 삽입
+.venv\Scripts\python.exe tools/sam3_everything_explore.py `
+ --input "..." `
+ --prompt-extra "signal box, relay cabinet"
+ 파라미터
+| 파라미터 | 기본값 | 설명 |
|---|---|---|
--input | 필수 | 이미지 파일 경로 |
--cols | 8 | 가로 타일 분할 수 |
--rows | 6 | 세로 타일 분할 수 |
--overlap | 0.10 | 타일 겹침 비율 |
--conf | 0.10 | 신뢰도 임계값 (탐색 모드라 낮게 설정) |
--workers | 4 | 병렬 처리 스레드 수 |
--nms | 0.40 | NMS IoU 임계값 |
--zone | 없음 | ROI 좌표 (X1 Y1 X2 Y2) — 관심 영역만 처리 |
--prompt-extra | 없음 | Discovery Prompt에 추가할 키워드 |
Discovery Prompt (내장)
+다음 키워드 묶음이 자동으로 SAM3.1에 전달된다:
+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,
+small dark object on ballast, small square metal box on ground,
+control box on ballast, gray square lid on gravel,
+flat metal cover on ground, bright square object on gravel
+ --prompt-extra로 추가 키워드를 붙일 수 있다.
출력 해석
+output/everything/
+└── DJI_20260306100900_0034_everything.jpg ← 모든 segment 오버레이
+
+콘솔 출력 (라벨 빈도 집계):
+ catenary pole : 47
+ railway rail : 31
+ overhead wire : 28
+ concrete tie : 19
+ control box on ballast: 8
+ ...
+ railway_zone.json의 프롬프트에 추가하거나 conf 조정. 빈도 0인 카테고리 → 해당 이미지에 없는 객체.
+ 탐색 후 타겟 검출로 전환
+프롬프트 튜닝
서버 설정 (sam31server)
+ +시스템 아키텍처
+┌─────────────────────────────────┐
+│ sam31server │
+│ FastAPI app/main.py :8000 │
+│ GET /health │
+│ POST /v1/predict │
+│ Model: SAM 3.1 Multiplex (CUDA)│
+└──────────────┬──────────────────┘
+ │ HTTP localhost:8000
+┌──────────────▼──────────────────┐
+│ railway-client tools │
+│ detect_all_objects.py │ ─┐
+│ detect_raamen.py ◀────────┘ │ 라멘 파이프라인
+│ sam3_everything_explore.py │
+│ sam3_autolabel.py ... │
+└─────────────────────────────────┘
+
+ 요구사항
+| 항목 | 버전 |
|---|---|
| Python | 3.12 |
| PyTorch | 2.10.0+cu126 (CUDA 필수) |
| triton-windows | 3.6.0.post25 |
| FastAPI | ≥ 0.115.0 |
| SAM 3.1 모델 | HuggingFace 자동 다운로드 (최초 1회) |
디렉토리 구조
+sam31server/
+├── sam3/ ← SAM 3.1 모델 라이브러리
+├── app/
+│ ├── main.py ← FastAPI 진입점
+│ ├── api/predict.py ← POST /v1/predict
+│ ├── api/health.py ← GET /health
+│ ├── models/segment_anything_3.py
+│ ├── core/registry.py
+│ └── tasks/inference.py
+├── configs/
+│ ├── server.yaml ← 포트·동시성
+│ ├── models.yaml ← enabled: segment_anything_3
+│ └── auto_labeling/segment_anything_3.yaml
+├── bpe_simple_vocab_16e6.txt.gz
+└── start_server.bat
+서버 시작
+ +sam31server 디렉토리에서 실행
+cd D:\MYCLAUDE_PROJECT\sam31server
+
+# 배치파일
+start_server.bat
+
+# 또는 직접
+.venv\Scripts\python.exe -m app.main
+
+# 또는 uvicorn 직접 (Windows 이벤트루프 이슈 우회)
+.venv\Scripts\python.exe -m uvicorn app.main:app --host 0.0.0.0 --port 8000
+ 정상 구동 확인
+INFO | Loading [segment_anything_3] (Segment Anything 3.1)...
+INFO | SAM3 model loaded successfully
+INFO | Uvicorn running on http://0.0.0.0:8000
+ API 엔드포인트
+ +POST /v1/predict
+{
+ "model": "segment_anything_3",
+ "image": "<base64 JPEG>",
+ "params": {
+ "text_prompt": "catenary pole, overhead line pole",
+ "conf_threshold": 0.25,
+ "show_masks": true,
+ "show_boxes": false
+ }
+}
+ 응답:
+{
+ "data": {
+ "shapes": [
+ { "label": "catenary pole", "shape_type": "polygon",
+ "points": [[x,y], ...], "score": 0.87 }
+ ]
+ }
+}
+
+ | params 키 | 설명 |
|---|---|
text_prompt | 텍스트 grounding (쉼표로 다중 객체) |
marks | rectangle / point 시각 프롬프트 |
conf_threshold | 신뢰도 임계값 |
show_masks | polygon 반환 (true 권장) |
show_boxes | bounding box 반환 |
클라이언트 도구 전체 목록
+| 스크립트 | 기능 | 출력 | 우선순위 |
|---|---|---|---|
detect_all_objects.py |
+ 타일 분할 + 다중 카테고리 검출 + NMS | +PNG + JSON | +핵심 | +
detect_raamen.py |
+ 門형 라멘 전철주 B/C 분류 + 그룹 판정 | +PNG | +핵심 | +
sam3_everything_explore.py |
+ Discovery Sweep — 전체 객체 탐색 + 빈도 집계 | +PNG + 통계 | +탐색 | +
sam3_autolabel.py | 전철주 + 레일 zone 기반 자동 라벨링 | JSON | |
sam3_batch_label.py | 폴더 배치 → X-AnyLabeling JSON | JSON | |
yoloworld_sam3_pipeline.py | YOLO-World bbox → SAM3 polygon | JSON+PNG | |
video_sam3_segment.py | 영상 프레임 추출 → 세그멘테이션 | JSON/frame | |
render_everything_by_label.py | 라벨별 색상 렌더링 | PNG | |
render_label_polygons.py | polygon 오버레이 | PNG | |
sam3_segment_everything.py | 이미지 전체 세그멘테이션 | PNG | |
railway_pipeline.py | 전체 파이프라인 통합 | 종합 |
detect_all_objects.py
+.venv\Scripts\python.exe tools/detect_all_objects.py `
+ --input "data/역사구간/..." `
+ --categories configs/railway_zone.json `
+ --tiles all `
+ --cols 4 --rows 3 --overlap 0.10 --workers 2
+
+ | 파라미터 | 기본값 | 설명 |
|---|---|---|
--input | 필수 | 이미지 또는 폴더 |
--categories | railway_zone.json | 카테고리 설정 파일 |
--tiles | all | 9-24, 1,5,9, all |
--cols / --rows | 8 / 6 | 타일 분할 수 |
--overlap | 0.10 | 타일 겹침 비율 |
--workers | 4 | 병렬 스레드 |
--conf | 카테고리별 | 전역 신뢰도 오버라이드 |
출력: output/detect/이미지명_detected.png + .json
sam3_autolabel.py
+.venv\Scripts\python.exe tools/sam3_autolabel.py `
+ --input data/역사구간/1.회덕역/ `
+ --output output/labels/
+sam3_batch_label.py
+.venv\Scripts\python.exe tools/sam3_batch_label.py `
+ --input data/역사구간/ `
+ --prompt "railway catenary pole" `
+ --output output/batch_labels/ `
+ --workers 8
+yoloworld_sam3_pipeline.py
+.venv\Scripts\python.exe tools/yoloworld_sam3_pipeline.py `
+ --input data/역사구간/ `
+ --output output/labeled/
+video_sam3_segment.py
+.venv\Scripts\python.exe tools/video_sam3_segment.py
+ 스크립트 상단에서 영상 경로·프롬프트·프레임 추출 간격 직접 수정.
+렌더링 도구
+# 라벨별 색상 렌더링
+.venv\Scripts\python.exe tools/render_everything_by_label.py `
+ --input output/labels/image.json --image data/.../image.JPG
+
+# polygon 오버레이
+.venv\Scripts\python.exe tools/render_label_polygons.py `
+ --input output/labels/ --image data/.../
+카테고리 설정 — railway_zone.json
+경로: configs/railway_zone.json
| 이름 | 한국어 | 색상 | conf | 우선순위 |
|---|---|---|---|---|
control_box | 컨트롤박스 | 노랑 | 0.15 | 2 |
vehicle | 차량 | 흰색 | 0.25 | 2 |
catenary_pole | 전철주 | 마젠타 | 0.25 | 3 |
railway | 철도 레일 | 파랑 | 0.25 | 4 |
fence | 팬스/울타리 | 초록 | 0.50 | 5 |
sleeper | 침목 | 하늘 | 0.20 | 6 |
ballast | 자갈도상 | 남색 | 0.20 | 7 |
bracket | 브라켓/암 | 청색 | 0.20 | 8 |
bridge | 교량/교각 | 주황하늘 | 0.25 | 8 |
building | 건물 | 청보라 | 0.25 | 8 |
retaining_wall | 방음벽/옹벽 | 연두 | 0.25 | 9 |
culvert | 암거/소교량 | 보라 | 0.20 | 9 |
service_road | 유지보수 도로 | 회청 | 0.30 | 10 |
farmland | 농지 | 밝은초록 | 0.25 | 11 |
vegetation | 식생 | 짙은초록 | 0.25 | 12 |
프롬프트 파일
+일부 도구는 prompts/ 폴더의 텍스트 파일을 사용:
prompts/
+├── pole.txt ← 전철주 검출용 프롬프트
+├── rail.txt ← 레일 검출용 프롬프트
+├── bracket.txt ← 브라켓 검출용
+└── sleeper.txt ← 침목 검출용
+빠른 시작 — 단일 이미지 전체 파이프라인
+ +SAM3.1 서버 시작 (터미널 A)
+cd D:\MYCLAUDE_PROJECT\sam31server
+.venv\Scripts\python.exe -m app.main
+ [선택] 탐색 모드로 객체 파악 (터미널 B)
+cd D:\MYCLAUDE_PROJECT\railway-client
+.venv\Scripts\python.exe tools/sam3_everything_explore.py `
+ --input "data/역사구간/1.회덕역/.../DJI_20260306100900_0034.JPG" `
+ --cols 4 --rows 3
+ 전철주 검출 + JSON annotation 생성
+.venv\Scripts\python.exe tools/detect_all_objects.py `
+ --input "data/역사구간/1.회덕역/.../DJI_20260306100900_0034.JPG" `
+ --categories configs/railway_zone.json `
+ --tiles all --cols 4 --rows 3 --overlap 0.10 --workers 2
+ 라멘 구조 분석
+.venv\Scripts\python.exe tools/detect_raamen.py `
+ --image "data/역사구간/1.회덕역/.../DJI_20260306100900_0034.JPG" `
+ --label "output/detect/DJI_20260306100900_0034.json" `
+ --output "output/raamen/DJI_20260306100900_0034_raamen.png"
+ 트러블슈팅
+| 오류 | 원인 | 해결 |
|---|---|---|
Connection refused :8000 | 서버 미실행 | sam31server에서 서버 시작 |
Torch not compiled with CUDA | CPU 버전 torch | pip install torch==2.10.0+cu126 --index-url .../cu126 |
No module named 'triton' | triton-windows 미설치 | pip install triton-windows==3.6.0.post25 |
No module named 'decord' | decord 미설치 | pip install decord |
| 라멘 검출 없음 | catenary_pole conf 너무 높음 | Step 1에서 --conf 0.10 로 낮춤 |
| C/B 분류 오류 | 소실점 계산 불안정 | --c-thresh 조정 (기본 20°, 높이면 C 기준 완화) |
| Windows 이벤트루프 경고 | Python 3.12 + uvicorn | python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 |
+
Railway Client Guide · SAM 3.1 + FastAPI · 2026-06
+