From 287f5c256b2f756a6107f80cb0ee321d526ec037 Mon Sep 17 00:00:00 2001 From: minsung Date: Tue, 28 Apr 2026 08:58:54 +0900 Subject: [PATCH] Scope reduction: remove rail/3D, focus on portal-frame pole 2D detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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) --- .claude/agents/data-pipeline-builder.md | 18 ++++---- .claude/agents/module-evaluator.md | 8 ++-- .claude/agents/pole-detector-builder.md | 8 ++-- .claude/agents/rail-detector-builder.md | 2 +- .claude/agents/triangulation-builder.md | 2 +- CLAUDE.md | 54 +++++++++++------------ PLAN.md | 58 ++++++++++++------------- PROGRESS.md | 27 +++++------- 8 files changed, 87 insertions(+), 90 deletions(-) diff --git a/.claude/agents/data-pipeline-builder.md b/.claude/agents/data-pipeline-builder.md index b06a985..603f9cb 100644 --- a/.claude/agents/data-pipeline-builder.md +++ b/.claude/agents/data-pipeline-builder.md @@ -1,12 +1,12 @@ --- name: data-pipeline-builder -description: RailPose3D 데이터 파이프라인 Generator. 라벨 포맷 정의(COCO-keypoints), 30장 라벨링 가이드, dataloader, augmentation 정책, RailSem19/UAV-RSOD 다운로드 스크립트, SfM-consistent self-training 루프(`sfm_self_training.py`) 구현. Sprint S0 일부, S6 에서 호출. +description: PoleDetect2D 데이터 파이프라인 Generator. 라벨 포맷 정의(COCO-keypoints 4-point), 30장 라벨링 가이드, dataloader, augmentation 정책, SfM-consistent self-training 루프(`sfm_self_training.py`) 구현. Sprint S0 일부, S3 에서 호출. model: inherit tools: Read, Write, Edit, Glob, Grep, Bash color: green --- -너는 RailPose3D 데이터 파이프라인 Generator 다. +너는 PoleDetect2D 데이터 파이프라인 Generator 다. ## 시작 시 필수 절차 @@ -14,24 +14,26 @@ color: green ## 책임 -- **라벨 스키마**: `data/labels/poles_4kpt.json` — COCO-keypoints, 4점 `{base, top, L_arm, R_arm}`. Schema 문서 `docs/labeling-guide.md` 작성. -- **데이터셋 가져오기**: RailSem19, UAV-RSOD 다운로드 스크립트 (`scripts/download_datasets.sh`). +- **라벨 스키마**: `data/labels/poles_4kpt.json` — COCO-keypoints, 4점 `{foot_L, foot_R, head_L, head_R}`. Schema 문서 `docs/labeling-guide.md` 작성. + - foot_L/R: 왼쪽/오른쪽 기둥 하단 (지면 접점) + - head_L/R: 왼쪽/오른쪽 기둥 상단 (가로 보 연결점) - **Augmentation**: `src/detection/augment_copy_paste.py` — SAM2 mask 로 pole crop, 다양한 배경에 paste, keypoint 좌표 동시 변환. - **Self-training 루프**: `src/self_training/sfm_self_training.py` ``` for round in range(N): detections = model.infer(all_views) - points_3d = triangulate(detections, sfm_poses) - pseudo_labels = reproject(points_3d, sfm_poses) # incl. views where model failed - filtered = filter_by_reprojection_error(pseudo_labels, threshold=5px) + # SfM 카메라 포즈로 cross-view pseudo-label 생성 (3D 중간 단계, 출력 아님) + points_3d_tmp = triangulate(detections, sfm_poses) + pseudo_labels_2d = reproject(points_3d_tmp, sfm_poses) + filtered = filter_by_reprojection_error(pseudo_labels_2d, threshold=5px) train_model(real_labels ∪ filtered) ``` + SfM 카메라 포즈는 pseudo-label 생성 도구로만 사용. 3D 좌표 자체는 출력하지 않는다. ## 산출물 - `data/labels/poles_4kpt.json` (스키마 + 빈 템플릿) - `docs/labeling-guide.md` -- `scripts/download_datasets.sh` - `src/detection/augment_copy_paste.py` - `src/self_training/sfm_self_training.py` diff --git a/.claude/agents/module-evaluator.md b/.claude/agents/module-evaluator.md index 059a051..6062d32 100644 --- a/.claude/agents/module-evaluator.md +++ b/.claude/agents/module-evaluator.md @@ -1,12 +1,12 @@ --- name: module-evaluator -description: RailPose3D의 Evaluator 에이전트. Generator 가 만든 모듈에 대해 contract 의 번호 매긴 성공 조건을 하나씩 검증한다. PCK@5px (Module A), mIoU + Hausdorff (Module B), reprojection error + GeoJSON CRS (Module C). Pass/fail 결과를 contract 파일과 PROGRESS.md 에 기록. 모든 sprint 종료 시 호출. +description: PoleDetect2D의 Evaluator 에이전트. Generator 가 만든 모듈에 대해 contract 의 번호 매긴 성공 조건을 하나씩 검증한다. PCK@5px (Module A). Pass/fail 결과를 contract 파일과 PROGRESS.md 에 기록. 모든 sprint 종료 시 호출. model: inherit tools: Read, Write, Edit, Glob, Grep, Bash color: orange --- -너는 RailPose3D **Evaluator** 다. 코드를 만들거나 고치지 않는다. Builder 가 만든 결과물을 측정·판정한다. +너는 PoleDetect2D **Evaluator** 다. 코드를 만들거나 고치지 않는다. Builder 가 만든 결과물을 측정·판정한다. ## 시작 시 필수 절차 @@ -25,8 +25,8 @@ Contract 의 각 success criterion 마다: ## 모듈별 표준 지표 - **Module A (pole)**: `data/eval/pole_pck.json` 의 PCK@5px on 30 holdout, contract 임계값 비교. -- **Module B (rail)**: `data/eval/rail_iou.json` 의 mIoU, polyline Hausdorff distance. -- **Module C (3D)**: synthetic test 의 reprojection error median, GeoJSON CRS validation (EPSG:5186), GCP 비교 거리. + - 4 keypoint 모두 측정: foot_L, foot_R, head_L, head_R + - foot keypoint 는 base 검출 품질의 핵심 지표 ## Evaluator tuning diff --git a/.claude/agents/pole-detector-builder.md b/.claude/agents/pole-detector-builder.md index 2fb16fd..5b78db4 100644 --- a/.claude/agents/pole-detector-builder.md +++ b/.claude/agents/pole-detector-builder.md @@ -1,6 +1,6 @@ --- name: pole-detector-builder -description: RailPose3D Module A (전철주 4-keypoint pose detection)의 Generator 에이전트. RTMPose-m/ViTPose 학습·추론·copy-paste augmentation·Grounding-DINO+SAM2 zero-shot 부트스트랩을 구현. Module A 관련 sprint(S1 부분, S2, S6의 A 부분, S8) 에서 호출. +description: PoleDetect2D Module A (라멘구조 전철주 4-keypoint pose detection)의 Generator 에이전트. RTMPose-m/ViTPose 학습·추론·copy-paste augmentation·Grounding-DINO+SAM2 zero-shot 부트스트랩을 구현. Module A 관련 sprint(S1, S2, S3의 A 부분, S4) 에서 호출. model: inherit tools: Read, Write, Edit, Glob, Grep, Bash color: green @@ -18,8 +18,10 @@ color: green ## 기술 스택 (CLAUDE.md 와 일치 필수) - **모델**: RTMPose-m (primary) → ViTPose-Base (fallback). YOLO11-pose 도 옵션. -- **Keypoint schema**: COCO-keypoints 포맷, 4점 `{base, top, left_crossarm_tip, right_crossarm_tip}` per pole. -- **Bootstrap**: Grounding-DINO 1.5 (`"utility pole"`, `"전봇대"`) → SAM 2.1 box prompt → 마스크 PCA → base 후보. +- **Keypoint schema**: COCO-keypoints 포맷, 4점 `{foot_L, foot_R, head_L, head_R}` per 라멘구조 전철주. + - foot_L/R: 왼쪽/오른쪽 기둥 하단 (지면 접점) + - head_L/R: 왼쪽/오른쪽 기둥 상단 (가로 보 연결점) +- **Bootstrap**: Grounding-DINO 1.5 (`"portal frame pole"`, `"전철주"`, `"문형 가구"`) → SAM 2.1 box prompt → 마스크에서 좌우 기둥 PCA → foot/head 후보. - **Augmentation**: Albumentations + copy-paste (SAM2 mask 기반, keypoint 보존 변환). - **Self-training**: SfM 카메라 포즈 reprojection 으로 pseudo-label 생성, reprojection error > 5px outlier 제거. diff --git a/.claude/agents/rail-detector-builder.md b/.claude/agents/rail-detector-builder.md index 3590fac..b03f562 100644 --- a/.claude/agents/rail-detector-builder.md +++ b/.claude/agents/rail-detector-builder.md @@ -1,6 +1,6 @@ --- name: rail-detector-builder -description: RailPose3D Module B (레일 segmentation + polyline)의 Generator 에이전트. SegFormer-B2 3-stage transfer (RailSem19 → UAV-RSOD → 30장), skeletonize, RDP 단순화, DeepLSD sub-pixel refinement 구현. Module B 관련 sprint (S1 부분, S3, S6의 B 부분) 에서 호출. +description: "[INACTIVE — 2026-04-28 범위 축소로 비활성화] 레일 segmentation 모듈. 재활성화 시 PLAN.md 범위 검토 필요." model: inherit tools: Read, Write, Edit, Glob, Grep, Bash color: green diff --git a/.claude/agents/triangulation-builder.md b/.claude/agents/triangulation-builder.md index d33a7fc..a2ec20d 100644 --- a/.claude/agents/triangulation-builder.md +++ b/.claude/agents/triangulation-builder.md @@ -1,6 +1,6 @@ --- name: triangulation-builder -description: RailPose3D Module C (2D→3D triangulation)의 Generator 에이전트. SfM 카메라 포즈 로드, DBSCAN-in-world-XY pole association, pycolmap triangulate, pyceres bundle adjustment, PDAL CSF ground 추출, Open3D raycasting, scipy splprep B-spline rail fitting 구현. Sprint S4·S5·S7 에서 호출. +description: "[INACTIVE — 2026-04-28 범위 축소로 비활성화] 2D→3D 삼각측량 모듈. 재활성화 시 PLAN.md 범위 검토 필요." model: inherit tools: Read, Write, Edit, Glob, Grep, Bash color: green diff --git a/CLAUDE.md b/CLAUDE.md index ed77ce2..20ce595 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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 # plan-architect → contract 생성 → builder agent 작업 # generator - → /eval # 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-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 diff --git a/PLAN.md b/PLAN.md index 832d280..6b506d2 100644 --- a/PLAN.md +++ b/PLAN.md @@ -1,56 +1,52 @@ -# RailPose3D — PLAN +# PoleDetect2D — PLAN > 이 문서는 **불변 기준선(baseline)** 이다. 일상 진행 상태는 [PROGRESS.md](PROGRESS.md) 에 기록한다. -> 자세한 배경·근거는 [docs/plan.md](docs/plan.md) (사용자 승인 plan), [docs/research.md](docs/research.md) 참조. +> 자세한 배경·근거는 [docs/plan.md](docs/plan.md), [docs/research.md](docs/research.md) 참조. ## Goal -드론 영상(nadir + oblique) 으로부터 **전철주(catenary pole)** 와 **레일(rail)** 등 가늘고 긴 구조물을 검출하고, 기존 SfM 카메라 포즈를 활용해 **3D 좌표(EPSG:5186)** 로 추출한다. +드론 영상(nadir + oblique) 으로부터 **라멘구조 전철주(portal-frame catenary pole)** 를 **2D 이미지상에서 정확히 검출**한다. +출력은 keypoint 좌표 (픽셀) + 신뢰도이며, 3D 좌표 추출은 이 프로젝트 범위 밖이다. ## 핵심 설계 결정 (불변) -1. **메시는 버린다.** SfM dense mesh 의 fragmented 출력에 의존하지 않는다. 카메라 포즈 + ground 분류 dense cloud 만 사용. -2. **2D 정확 검출 → 3D 삼각측량.** 가는 물체는 detection-then-triangulate 가 mesh 기반보다 정확. -3. **Pose/keypoint 모델 (bbox 아님).** 4-keypoint `{base, top, L_arm, R_arm}` 로 base/완금 구조적 구분. -4. **Segmentation + skeletonize (lane detector 아님).** 레일은 nadir/oblique view-invariant. -5. **Self-training over SfM.** 30장 라벨을 카메라 포즈로 5–20× 증식. +1. **Pose/keypoint 모델 (bbox 아님).** 라멘구조 4-keypoint `{foot_L, foot_R, head_L, head_R}` 로 기둥 발목/머리를 구조적으로 구분한다. +2. **라멘구조 전용 스키마.** 두 수직 기둥과 연결 보(beam)를 가진 H-frame / 문형 가구 구조. +3. **Self-training over SfM.** 30장 라벨을 SfM 카메라 포즈 reprojection 으로 5–20× 증식하여 2D pseudo-label 생성. +4. **Zero-shot bootstrap 우선.** Grounding-DINO + SAM2 로 라벨 없이 시작. -## 3-모듈 분해 +## 단일 모듈 구성 -- **Module A — Pole Keypoint Detection** (RTMPose-m, 4-keypoint) -- **Module B — Rail Segmentation** (SegFormer-B2, 3-stage transfer + skeletonize) -- **Module C — 2D→3D Triangulation** (DBSCAN association + pycolmap + pyceres / PDAL CSF + Open3D + scipy splprep) +- **Module A — Pole Keypoint Detection** + - 대상: 라멘구조 전철주 (portal-frame, 문형 가구) + - 모델: RTMPose-m (primary) / ViTPose-Base (fallback) + - Keypoint: `{foot_L, foot_R, head_L, head_R}` — COCO-keypoints 포맷 ## Sprint 분할 (마일스톤) -| Sprint | 모듈 | 목표 | 성공 조건 (contract) | -|---|---|---|---| -| **S0** Bootstrap | Infra | 디렉터리·환경·CI 골격 | `pipeline/run_full.py --version` 동작, lint/format pass | -| **S1** MVP-Zero | A+B | Grounding-DINO + SAM2 zero-label baseline | 30장 검증, pole base 픽셀 오차·rail mIoU 정량화 | -| **S2** Pole-A1 | A | RTMPose-m fine-tune (30장 → 300장 copy-paste aug) | PCK@5px ≥ MVP baseline + 20% | -| **S3** Rail-B1 | B | SegFormer 3-stage transfer | rail mIoU ≥ 0.70 on 30 holdout | -| **S4** Triangulate | C | DBSCAN + pycolmap + pyceres pole pipeline | 3D pole point reprojection error < 5 px median | -| **S5** Rail-3D | C | Open3D raycasting + B-spline rail pipeline | 3D rail Hausdorff vs GCP < 10 cm | -| **S6** Self-train | A,B | SfM-consistent self-training loop | 라운드 N+1 PCK > 라운드 N | -| **S7** E2E | All | 100m trial section end-to-end | GeoJSON + DXF export, QGIS 시각화 일치 | -| **S8** Korean catenary 분기 | A | 단주 vs 문형 가구 분류 + 4kpt 변형 | 두 타입에서 PCK@5px ≥ 0.85 | +| Sprint | 목표 | 성공 조건 (contract) | +|---|---|---| +| **S0** Bootstrap | 디렉터리·환경·CI 골격 | `pipeline/run_detect.py --version` 동작, lint/format pass | +| **S1** MVP-Zero | Grounding-DINO+SAM2 zero-label baseline | 30장 pole keypoint 픽셀 오차 baseline 정량화 | +| **S2** Pole-Train | RTMPose-m fine-tune (30장→300장 copy-paste aug) | PCK@5px ≥ S1 baseline + 20% | +| **S3** Self-train | SfM-consistent self-training loop (2D pseudo-label) | 라운드 N+1 PCK > 라운드 N, 3라운드 연속 | +| **S4** Korean-variants | 라멘구조 vs 단주 분류 분기, 다형 keypoint | 두 타입 PCK@5px ≥ 0.85 | -각 sprint 는 시작 시 `/contract ` 로 contract 파일을 생성하고, 완료 시 `/eval ` 로 검증한다. +각 sprint 는 시작 시 `/contract ` 로 contract 파일을 생성하고, 완료 시 `/eval A` 로 검증한다. ## 검증 기준 (정량 지표) -- **Module A**: PCK@5px (base keypoint), 30장 holdout -- **Module B**: mIoU (rail mask), Hausdorff (polyline) -- **Module C**: reprojection error (pole), Hausdorff vs GCP (rail), GeoJSON CRS=EPSG:5186 통과 +- **Module A**: PCK@5px (4 keypoint 전체, 특히 foot_L / foot_R), 30장 holdout +- 기준 파일: `data/eval/pole_pck.json` ## 위험 관리 | 위험 | 대응 | |---|---| -| 전철주 base 가림 | self-training 으로 다중뷰 일관성 검증 | -| Windows pycolmap/pyceres 빌드 | conda-forge wheel 우선, 실패 시 WSL2 fallback | -| 좌표계 mismatch | GCP 3점 이상으로 7-param Helmert | -| 한국 catenary 다양성 (단주/문형) | S8에서 분기 처리 | +| 기둥 하단(foot)이 ballast·식생에 가려짐 | SfM pseudo-label 로 다른 뷰의 가시 foot 활용 | +| 라멘구조 외 단주 혼입 | S4 에서 pole_type 분기 처리 | +| 한국 catenary 다양성 (간격·폭 다양) | copy-paste aug 시 scale 범위 확장 | +| Windows MMPose 빌드 | conda-forge wheel, ONNX export fallback | ## 참고 산출물 diff --git a/PROGRESS.md b/PROGRESS.md index f0f66b1..87c5a64 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -1,8 +1,8 @@ -# RailPose3D — PROGRESS +# PoleDetect2D — PROGRESS > 이 문서는 **현재 상태**를 추적한다. 모든 에이전트는 작업 시작 시 [PLAN.md](PLAN.md) 와 이 파일을 읽고, 종료 시 이 파일을 갱신한다. -마지막 업데이트: 2026-04-27 (초기 셋업) +마지막 업데이트: 2026-04-28 (범위 축소: 레일 제거, 3D 제거, 라멘구조 전철주 2D 검출로 집중) ## Current Sprint @@ -14,13 +14,9 @@ |---|---|---|---|---|---| | S0 Bootstrap | 🔲 todo | — | — | — | — | | S1 MVP-Zero | 🔲 todo | — | — | — | — | -| S2 Pole-A1 | 🔲 todo | — | — | — | — | -| S3 Rail-B1 | 🔲 todo | — | — | — | — | -| S4 Triangulate | 🔲 todo | — | — | — | — | -| S5 Rail-3D | 🔲 todo | — | — | — | — | -| S6 Self-train | 🔲 todo | — | — | — | — | -| S7 E2E | 🔲 todo | — | — | — | — | -| S8 Korean variants | 🔲 todo | — | — | — | — | +| S2 Pole-Train | 🔲 todo | — | — | — | — | +| S3 Self-train | 🔲 todo | — | — | — | — | +| S4 Korean-variants | 🔲 todo | — | — | — | — | 상태 표기: 🔲 todo / 🔄 in-progress / ✅ done / ⛔ blocked @@ -29,24 +25,25 @@ **Sprint S0 Bootstrap** 시작. 작업 항목: 1. 프로젝트 디렉터리 골격 생성 (`src/`, `configs/`, `data/`, `pipeline/`) -2. `pyproject.toml` + 의존성 (uv 또는 conda env) +2. `pyproject.toml` + 의존성 (mmpose, albumentations, ruff, pytest) 3. pre-commit / ruff / pytest 셋업 -4. `pipeline/run_full.py` placeholder -5. README 갱신 (RailPose3D 명명 반영) +4. `pipeline/run_detect.py` placeholder (pole detection only) +5. README 갱신 (PoleDetect2D 범위 반영) → 시작하려면 `/sprint S0` 또는 `plan-architect` 에이전트 호출. ## Blockers / Open Questions -- [ ] 사용자에게서 실제 드론 영상 + Metashape export 확보 시점 미확정 -- [ ] GCP (Ground Control Points) 좌표 데이터 가용성 확인 필요 -- [ ] pycolmap/pyceres 윈도우 빌드 가능 여부 — conda-forge에 최신 wheel 있는지 확인 필요 +- [ ] 라멘구조 전철주 실제 드론 영상 확보 시점 미확정 +- [ ] 30장 라벨 재작업 필요 — 기존 base 단일 라벨에서 `{foot_L, foot_R, head_L, head_R}` 4-keypoint 로 재라벨링 +- [ ] Windows MMPose 빌드 가능 여부 — conda-forge 확인 필요 ## Activity Log | 일시 | 에이전트/사용자 | 액션 | 결과 | |---|---|---|---| | 2026-04-27 | user | 프로젝트 RailPose3D 명명, harness 구조 셋업 지시 | CLAUDE.md, PLAN.md, PROGRESS.md, .claude/* 생성 | +| 2026-04-28 | user | 범위 축소 지시: 레일 제거, 3D 제거, 라멘구조 전철주 2D 검출만 | PLAN.md, PROGRESS.md, CLAUDE.md, agents 갱신 | ---