Scope reduction: remove rail/3D, focus on portal-frame pole 2D detection

- Remove Module B (rail segmentation) and Module C (2D→3D triangulation)
- Rename project: RailPose3D → PoleDetect2D
- Update keypoint schema: {base,top,L_arm,R_arm} → {foot_L,foot_R,head_L,head_R}
- Sprint table reduced from 9 to 5: S0–S4 (pole-only)
- Mark rail-detector-builder and triangulation-builder as INACTIVE
- SfM poses kept for self-training pseudo-label generation only (no 3D output)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
minsung
2026-04-28 08:58:54 +09:00
parent 417f880a87
commit 287f5c256b
8 changed files with 87 additions and 90 deletions

View File

@@ -1,6 +1,7 @@
# CLAUDE.md — RailPose3D
# CLAUDE.md — PoleDetect2D
> **프로젝트 명**: **RailPose3D** — 드론 영상에서 전철주·레일 등 **긴 물체를 검출**하고 SfM 카메라 포즈로 **3D 좌표화**하는 R&D 프로젝트.
> **프로젝트 명**: **PoleDetect2D** — 드론 영상에서 **라멘구조 전철주(portal-frame catenary pole)** 를 2D로 검출하는 R&D 프로젝트.
> (구 프로젝트명: RailPose3D. 2026-04-28 범위 축소: 레일 제거, 3D 제거, 라멘구조 전철주 2D 검출에 집중.)
## 0. 모든 에이전트 첫 행동 (필수)
@@ -8,44 +9,46 @@
1. [PLAN.md](PLAN.md) 를 읽는다 — 불변 기준선·sprint 분할·검증 지표.
2. [PROGRESS.md](PROGRESS.md) 를 읽는다 — 현재 sprint, 다음 액션, blocker.
3. 자신의 역할이 어느 sprint·module 에 속하는지 PROGRESS.md 의 *Current Sprint* 섹션과 대조해 명시한 뒤 작업을 시작한다.
3. 자신의 역할이 어느 sprint 에 속하는지 PROGRESS.md 의 *Current Sprint* 섹션과 대조해 명시한 뒤 작업을 시작한다.
작업이 끝나면 **반드시** PROGRESS.md 의 Sprint 상태판 + Activity Log 를 갱신한다.
## 1. Goal (요약)
- **입력**: 드론 nadir + oblique 영상, 그리고 SfM(COLMAP/Metashape)이 산출한 카메라 포즈와 sparse/dense cloud (사용자 보유).
- **출력**: 전철주 base 의 3D point + 레일의 3D polyline (EPSG:5186 GeoJSON / DXF).
- **입력**: 드론 nadir + oblique 영상.
- **출력**: 라멘구조 전철주의 4-keypoint 픽셀 좌표 `{foot_L, foot_R, head_L, head_R}` + 신뢰도.
- **제약**: 라벨 30장만 보유 (zero-shot/transfer/self-training 우선), Windows 환경, 한국 catenary 도메인.
- **범위 밖**: 레일 검출, 3D 좌표 추출, GeoJSON/DXF export.
## 2. Architecture (3-모듈, 불변)
## 2. Architecture (단일 모듈)
| Module | 책임 | 채택 |
|---|---|---|
| **A** Pole keypoint | 전철주 4-keypoint `{base, top, L_arm, R_arm}` | RTMPose-m / ViTPose |
| **B** Rail seg | 레일 binary mask → skeleton → polyline | SegFormer-B2 (3-stage transfer) |
| **C** 2D→3D | 다중뷰 삼각측량으로 3D 좌표 산출 | DBSCAN + pycolmap + pyceres / PDAL CSF + Open3D + scipy |
| **A** Pole keypoint | 라멘구조 4-keypoint `{foot_L, foot_R, head_L, head_R}` | RTMPose-m / ViTPose |
- **foot_L / foot_R**: 왼쪽/오른쪽 기둥 하단 (지면 접점)
- **head_L / head_R**: 왼쪽/오른쪽 기둥 상단 (가로 보 연결점)
자세한 근거는 [docs/plan.md](docs/plan.md) 참조.
### 절대 하지 않는 것
- bbox 기반 detector 로 base 추정 (oblique view 에서 완금이 base 로 오인됨 — 기하 문제)
- SfM dense mesh 에서 직접 객체 추출 (가는 물체에서 fragment)
- bbox 기반 detector 로 foot 추정 (oblique view 에서 가로 보가 foot 으로 오인됨 — 기하 문제)
- 30장으로 큰 모델 from-scratch 학습
- Lane detector(CLRNet 등) 를 nadir 드론에 그대로 적용
- BlenderProc 합성 데이터에만 의존
- 레일 검출 코드 추가 (범위 밖)
- 3D 삼각측량 코드 추가 (범위 밖)
## 3. Harness 설계 원칙 (Anthropic engineering blog 기반)
이 프로젝트는 **Planner / Generator / Evaluator** 3-역할 분리 하네스로 운영한다.
- **Planner = `plan-architect` 에이전트** — sprint 단위로 분해, contract(번호 매긴 성공 조건) 작성.
- **Generator = 모듈별 builder 에이전트** — `pole-detector-builder`, `rail-detector-builder`, `triangulation-builder`, `data-pipeline-builder`.
- **Evaluator = `module-evaluator` 에이전트** — PCK / mIoU / reprojection error 등 정량 지표로 contract pass/fail 판정.
- **Generator = `pole-detector-builder`, `data-pipeline-builder`** — 검출 모델, 데이터 파이프라인, self-training 구현.
- **Evaluator = `module-evaluator` 에이전트** — PCK@5px 로 contract pass/fail 판정.
원칙:
- **Decomposition** — 한 sprint 에 한 모듈·한 feature 만.
- **Decomposition** — 한 sprint 에 한 feature 만.
- **File-based handoff** — 대화 턴이 아니라 PLAN.md / PROGRESS.md / `docs/contracts/*.md` 로 인계.
- **Context reset over compaction** — 컨텍스트 압박 시 `/handoff` 로 상태 스냅샷 후 새 세션 시작.
- **Evaluator tuning loop** — evaluator 의 판단이 사용자와 어긋나면 evaluator 프롬프트를 갱신.
@@ -57,7 +60,7 @@
[user] → /start # PLAN+PROGRESS 자동 로드·요약
→ /sprint <id> # plan-architect → contract 생성
→ builder agent 작업 # generator
→ /eval <module> # module-evaluator → pass/fail
→ /eval A # module-evaluator → PCK pass/fail
→ /progress # PROGRESS.md 갱신
↳ context 부족 시 /handoff 후 새 세션
```
@@ -75,30 +78,27 @@ detectelectronpole/
│ ├── research.md
│ ├── contracts/ ← sprint contract 파일 (S<n>-contract.md)
│ └── handoffs/ ← context 핸드오프 스냅샷
├── data/ ← 드론 원본·SfM·라벨 (gitignored)
├── configs/ ← MMPose, SegFormer 등 설정
├── data/ ← 드론 원본·라벨 (gitignored)
├── configs/ ← MMPose 설정
├── src/
│ ├── detection/ ← 모듈 A, B
── triangulation/ ← 모듈 C
│ ├── self_training/
│ └── export/ ← GeoJSON/DXF
│ ├── detection/ ← Module A (pole keypoint)
── self_training/ ← SfM-consistent pseudo-label loop
├── pipeline/
│ └── run_full.py end-to-end orchestrator
│ └── run_detect.py ← detection orchestrator
├── tests/
└── .claude/
├── agents/ ← 서브에이전트
├── skills/ ← /start, /sprint, /eval, /progress, /handoff, /contract
├── commands/ ← (legacy mirror, skills 와 동일 내용)
└── settings.json ← hooks
```
## 6. 코딩·환경 규약
- Python 3.11+, `uv` 또는 conda 환경.
- 라이브러리: `pycolmap`, `pyceres`, `open3d`, `pdal`, `mmpose`, `transformers`(SegFormer), `albumentations`, `scipy`, `geomdl`, `ezdxf`.
- 라이브러리: `mmpose`, `albumentations`, `opencv-python`, `numpy`, `scipy`.
- 타입 힌트 필수, `ruff` + `pytest`.
- 모든 detection 출력은 **COCO-keypoints** (pole) / **GeoJSON-like polyline** (rail) 통합 포맷으로 직렬화.
- 좌표계: 기본 EPSG:5186 (Korea Central Belt 2010), 로컬 frame 인 경우 GCP 3점으로 변환.
- 모든 detection 출력은 **COCO-keypoints** 포맷 (pole).
- SfM 카메라 포즈는 self-training pseudo-label 생성 용도로만 사용 (3D 출력 없음).
## 7. Memory & Imports