feat: Otsu adaptive threshold, Method A 포팅, BV ellipse cap, UI 정리
Algorithm: - Otsu 1D adaptive threshold 포팅 (span_utils.py otsu_1d, 기본 ON) - Method A 벽 검출 포팅 (PiezoEchoAnalyzerA.kt: plateau score + prominence) - Method A cross-validation (채널간 중앙값/gradient 보정) - BV cap 높이: parabolic → ellipse 피팅 (8점 축정렬 타원) - Bottom cap: sphere, Top cap: cone (Python bv_estimation.py 동기화) - 설정에 Method A/B 토글 (왼쪽=A, 오른쪽=B) Logging: - BLE 로그 + CSV에 otsu threshold 값 기록 - 측정 로그에 method label (A/B) 표시 UI: - 설정 패널: floating overlay로 변경 + MaxVolume 슬라이더 추가 - Onboarding: 1페이지로 단순화 (Pager/indicator 제거) - Registration: 한 페이지에 전체 입력 + Skip 버튼 - Placement: 로딩 인디케이터/스캔 텍스트 삭제 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -54,7 +54,9 @@ object AdcCsvLogger {
|
||||
val timestamp = timeFmt.format(Date())
|
||||
val volStr = volumeMl?.let { "%.1f".format(it) } ?: ""
|
||||
val lrStr = "%.2f".format(lrRatio)
|
||||
val thrStr = "%.0f".format(com.example.medilightv2android.managers.GreenZoneConstants.lowEchoAmp)
|
||||
val analyzer = com.example.medilightv2android.managers.PiezoEchoAnalyzer.shared
|
||||
val thrStr = if (analyzer.useAdaptiveThreshold && analyzer.lastOtsuThreshold > 0)
|
||||
"%.0f".format(analyzer.lastOtsuThreshold) else "%.0f".format(com.example.medilightv2android.managers.GreenZoneConstants.lowEchoAmp)
|
||||
val dpsStr = "%.3f".format(com.example.medilightv2android.managers.PiezoHW.distancePerSample)
|
||||
val sgStr = if (com.example.medilightv2android.managers.PiezoEchoAnalyzer.shared.useSgFilter) "ON" else "OFF"
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ class BleDebugLogger private constructor(private val context: Context) {
|
||||
info("ENDIAN_DETECT ${if (isBigEndian) "BIG" else "LITTLE"} (LE=$firstSampleLE, BE=$firstSampleBE)")
|
||||
}
|
||||
|
||||
fun measurementResult(volumeMl: Double?, lrRatio: Double, validChannels: Int, urineLines: List<Int>) {
|
||||
fun measurementResult(volumeMl: Double?, lrRatio: Double, validChannels: Int, urineLines: List<Int>, otsuThreshold: Double = 0.0) {
|
||||
val scanId = AdcCsvLogger.lastScanId
|
||||
val msg = buildString {
|
||||
append("MEASUREMENT scan=$scanId")
|
||||
@@ -163,6 +163,7 @@ class BleDebugLogger private constructor(private val context: Context) {
|
||||
append(" lr=${"%.2f".format(lrRatio)}")
|
||||
append(" valid=$validChannels/6")
|
||||
append(" urine=[${urineLines.joinToString(",")}]")
|
||||
if (otsuThreshold > 0) append(" otsu=${"%.0f".format(otsuThreshold)}")
|
||||
}
|
||||
add(Entry(System.currentTimeMillis(), Level.INFO, msg))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user