From a89936c862cbc57652b8183e1c06254ddc964203 Mon Sep 17 00:00:00 2001 From: jjangddu Date: Thu, 13 Aug 2026 14:42:35 +0900 Subject: [PATCH] =?UTF-8?q?docs(algo):=20ALGO=5FBRANCH=5FCOMPARISON=20?= =?UTF-8?q?=C2=A73-4=20METHOD=5FD=20vs=20METHOD=5FD=5FPHANTOM=20=EC=8B=AC?= =?UTF-8?q?=EC=B8=B5=20=EB=B9=84=EA=B5=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존 §3 BV Estimation 은 브랜치 비교 관점만 · 두 method 자체를 나란히 놓고 상세 대조하는 섹션 없어서 §3-4 로 추가 (사용자 요청). 포함 (7 sub-section): 3-4-1. 부피 공식 (Frustum+Cap vs 4/3πr³) 3-4-2. 파이프라인 stage 비교 표 (11 stage · METHOD_D 만 있는 것 명시) 3-4-3. 결과 특성 표 (정확도 · 계산 비용 · 재현성 · phantom vs 인체) 3-4-4. 예시 계산 (phantom 300mL · 지름 83mm · 두 method 각각 산수) 3-4-5. 언제 어느 method 써야 하나 (권장 매트릭스) 3-4-6. 코드 진입점 요약 (dispatcher) 3-4-7. 향후 개선 여지 (하이브리드 · ellipsoid 확장 등) 핵심 근거: · phantom 300mL 실측 → METHOD_D_PHANTOM 296mL (-1.3%) vs METHOD_D 250mL (-17%) · 원인: 큰 대칭 방광은 구 가정이 정확 · Frustum+cap 은 adaptive 로도 저추정 --- docs/ALGO_BRANCH_COMPARISON.md | 111 +++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/docs/ALGO_BRANCH_COMPARISON.md b/docs/ALGO_BRANCH_COMPARISON.md index f6ed613..4c45e28 100644 --- a/docs/ALGO_BRANCH_COMPARISON.md +++ b/docs/ALGO_BRANCH_COMPARISON.md @@ -154,6 +154,117 @@ VesiScan-Basic Android 앱은 두 개의 활성 브랜치로 관리됨. | Streaming BV | — | `piezo/StreamingBladderEstimator.kt` (신규) | | BV 분기점 | `ui/views/monitoring/PiezoMonitoringView.kt:487-491` (`METHOD_D_PHANTOM → estimateBvPhantomSphere`) | `piezo/ui/PiezoMonitoringView.kt:406-418` (`useStreamingBv → streamingBv.update(signals)`) | +### 3-4. 심층 비교 · METHOD_D vs METHOD_D_PHANTOM + +두 method 는 **같은 detection walls 를 입력**받지만 · 부피 계산 철학이 근본 다름. + +#### 3-4-1. 부피 공식 + +**METHOD_D** — 다각형 근사 + 타원 cap +``` +BV = V_frustum + V_topCap + V_bottomCap + ┌───────┬─────────┬──────────┐ + │ 6채널 │ Halir │ Sphere │ + │ frustum│ ellipse │ (fixed) │ + │ 적분 │ fit │ │ + └───────┴─────────┴──────────┘ +``` +방광을 6채널 벽 사이 다각형(frustum) + 상하 cap 으로 근사. `adaptive_large_bladder_relax` 로 큰 방광 처리 시 constraint 완화. Python `runners.estimate_bv` 1:1. + +**METHOD_D_PHANTOM** — 순수 구 +``` +BV = (4/3) · π · r³ + r = mean(D_center 4채널) / 2 + D_ch = (post_ch - ant_ch) × dps +``` +방광을 완전 대칭 구로 가정 · center CH0~CH3 지름 평균으로 반지름 산출. Cap · lr_ratio · Halir 다 우회. + +#### 3-4-2. 파이프라인 stage 비교 + +| Stage | METHOD_D | METHOD_D_PHANTOM | +|---|---|---| +| 1. walls 입력 | `List` (subsample refined) | `List` (동일) | +| 2. lumen inset | `applyLumenInsetOne(0.15)` — 벽 15% 안쪽 이동 | ❌ 없음 (raw walls) | +| 3. center wall repair | gap 보간 · gap≥2 top drop | ❌ 없음 | +| 4. lr_ratio | `lrRatioOverride ?: computeLrRatio()` | ❌ 없음 (구 = 1:1) | +| 5. Frustum 계산 | 6채널 x-z 타원 · SI-sorted · frustum 적분 | ❌ 없음 | +| 6. Top cap | Halir-Flusser 타원 fit + `ellipse_cap_height` | ❌ 없음 | +| 7. Bottom cap | Sphere (`bottomKind = "sphere"`) | ❌ 없음 (전체가 구) | +| 8. adaptive relax | low_wide_endpoint 검사 → 재계산 | ❌ 없음 | +| 9. b_si_floor | 하한 `b_si ≥ 0.85 × edge_min` | ❌ 없음 | +| 10. Post outlier | `post_outlier_filter=false` (default) | ❌ 없음 | +| 11. 최종 | Σ frustum + top cap + bottom cap | `4/3 π (D̄/2)³` | + +#### 3-4-3. 결과 특성 + +| 특성 | METHOD_D | METHOD_D_PHANTOM | +|---|---|---| +| **정확도 (실제 방광)** | 높음 (Python parity · Δ~0mL 검증) | 낮음 (구 가정) | +| **정확도 (phantom 300mL)** | 250mL (adaptive 로도 -17%) | **296mL** (-1.3%) ✓ | +| **CH3 flick 민감도** | 낮음 (frustum 은 채널 몇 개 빠져도 ok) | 높음 (평균에 직접 반영) | +| **비대칭 방광** | 잘 대응 (frustum + LR ratio) | 왜곡 심함 (구 가정) | +| **작은 방광 (<100mL)** | 정확 | 정확 (구 가정 잘 맞음) | +| **큰 방광 (>400mL)** | 정확 | 저추정 (구 부피 성장률 < 실제) | +| **계산 비용** | 높음 (타원 fit · SVD · relax 재계산) | 매우 낮음 (곱셈 몇 번) | +| **결과 재현성** | 파이썬 소수점까지 일치 | trivial · dps · walls 만 의존 | + +#### 3-4-4. 예시 계산 (phantom 300mL · 지름 83mm) + +Method D walls 예시: +``` +CH0: ant=15, post=57 → span 42 +CH1: ant=13, post=59 → span 46 +CH2: ant=14, post=57 → span 43 +CH3: ant=16, post=55 → span 39 +CH4/5: ant=18, post=44 (LR wings) +``` + +**METHOD_D_PHANTOM 계산**: +``` +D̄ = mean(42, 46, 43, 39) × 1.968 = 42.5 × 1.968 = 83.64 mm +r = 41.82 mm +V = 4/3 · π · 41.82³ = 306,326 mm³ ≈ 306 mL ✓ +``` + +**METHOD_D 계산** (근사): +``` +V_frustum = Σ frustum(z_i, z_{i+1}, S_i, S_{i+1}) (4채널 → 3 slice) + ≈ 165 mL (본체) +V_top (Halir + adaptive) ≈ 55 mL (배꼽쪽 cap · b_si_floor 로 확장) +V_bottom (sphere) ≈ 30 mL (치골쪽 cap) +V_total ≈ 250 mL (-17% 저추정 · adaptive 로도 큰 phantom 처리 어려움) +``` + +#### 3-4-5. 언제 어느 것 써야 하나 + +| 시나리오 | 권장 method | 근거 | +|---|---|---| +| Phantom 시연 (구·타원 방광 모형) | **METHOD_D_PHANTOM** | 구 가정 정확 · 300mL 재현 | +| 인체 실측 (임상) | **METHOD_D** | 비대칭 방광 · Halir + adaptive 필수 | +| Alignment 위치 판정 | detection method 만 사용 (BV 무관) | walls 만 필요 | +| BV parity 테스트 (Python 대조) | **METHOD_D** | bit-perfect 일치 | +| CH3 검출 불안정 자세 | **METHOD_D** | frustum 이 채널 결손 관용 | +| 빠른 UI 반응 (계산 지연 최소) | METHOD_D_PHANTOM | O(1) 계산 | + +#### 3-4-6. 코드 진입점 요약 (demo-final) + +```kotlin +// PiezoMonitoringView.kt:487-491 +val bvResult = if (bvMethod == BvMethod.METHOD_D_PHANTOM) { + estimateBvPhantomSphere(walls) // PiezoBVEstimator.kt:600 · ~30 L +} else { + estimateBv(walls) // PiezoBVEstimator.kt:595 · ~600 L +} +``` +- `estimateBvPhantomSphere` — 30 lines · 순수 계산 · state 없음 +- `estimateBv` — 600 lines + EllipseFitSpecific.kt (150 L) + adaptive wrapper + +#### 3-4-7. 향후 개선 여지 (선택) + +- **하이브리드 method**: walls 대칭성 분산 계산 → 낮으면 PHANTOM · 높으면 METHOD_D 자동 선택 +- **METHOD_D_PHANTOM 확장**: 반지름 산출 시 CH1/CH2 만 사용 (CH0/CH3 는 flick 심함) 옵션 +- **METHOD_D_PHANTOM_ELLIPSOID**: 구 대신 반지름 2개 (SI + AP) 로 회전 타원체 · 근사 개선 + --- ## 4. 브랜치 전용 파일/기능 요약