android: 修正 7x7 细节增强的混叠系数(原实现把增益乘了两遍,画面满噪点)
官方 FilterDetailEnhancement_Simple 把「增益缩放后」的 k = strength*gain*2>>8 只 传给 map(决定阈值与 divisor 下限),混叠系数用的是**原始 strength**。本移植最初 两处都用 k,等于把细节再乘一遍增益:真机 level 2 满屏噪点。改为原始 strength 后 HF 能量与关闭档基本相同(0.47-0.51 vs 0.46-0.47),边缘仍被增强。 细节校正: - 一个有用的推论:每档的边缘强度其实与档位无关(化简为 128/gain),档位只决定 哪些窗口通过对比度阈值——所以调高档位是"纳入更多弱对比区域",不是"推得更狠"。 据此把档位从 0-4 扩到 0/1/2/3/4/6/8(官方 MAG_SetDetailEnhancement 钳 0..32)。 - 官方 App 自身不调用 SetDetailEnhancement(jadx 全量搜索无此符号),SetEX 是数码 变焦 ROI 与增强无关;故无法据此对齐官方默认档,保持用户可见设置、默认关闭。 测试: - 新增 blendUsesTheRawStrengthNotTheGainScaledOne 黄金值用例(推导写在注释里), 把 bug 改回去会立刻失败(已实测验证)。 - 原 gainScalesTheEffect 改为 gainDoesNotAmplifyNoiseOnAFlatField + gainBelowOneIsANoOp, 因为修正后增益不再缩放混叠幅度。98 项测试全绿。 顺带修复(同一轮真机复现): - no_device 死锁:首次 connect 撞上相机重枚举时停在「无相机」,且紧随其后的 ATTACHED 广播被 800ms 防抖丢弃 → 永久无画面。防抖/退避改为延后重试,no_device 也安排 1.5s 重试(scheduleRetry 单槽位、最新优先)。 - 手机平放时加速度计 x/y≈0,迟滞逻辑保留旧姿态角导致 OSD 文字整体转 90°; 改为 tilt<4m/s² 判定平放、姿态归零。 - 录像帧缺 max/min 标记:probesAsMarks() 现在一并返回,录像与实时画面一致。 真机(小米 22041211AC/Android12/MIUI):15.1fps 稳定、单帧 6-9ms(开增强 11ms)、 拍照与分析页标记一致且各只有一个 min/max、设置跨冷启动持久化、 屏幕熄灭时渲染停止无空转(CPU 3.7%)。
This commit is contained in:
@@ -562,17 +562,43 @@ extremes **合并成一次 draw**(原来分两次调用,彼此看不见)
|
||||
按反编译的 `CFunctions::FilterDetailEnhancement_Simple` + `LocalMap7x7_Simple`
|
||||
移植(`core/DetailEnhance.kt`):7×7 窗口按 4×4 抽样(x/y 步长 2),
|
||||
`mean = sum >> 4`,`if (strength <= (max-min)*32)` 时
|
||||
`detail = (0x8000/divisor)*(center-mean)`,最后 `gray += (k*detail) >> 15`。
|
||||
`detail = (0x8000/divisor)*(center-mean)`,最后 `gray += (strength*detail) >> 15`。
|
||||
管线位置与官方一致:`grayMap → 细节增强 → upscale2x → 调色板`。
|
||||
强度换算经官方 SDK 核对:`MAG_SetDetailEnhancement` 把等级钳到 0..32,
|
||||
调用方传 `level << 3`——**与本实现 `level shl 3` 完全一致**。
|
||||
设置页新增"图像增强"(关闭/1–4 级),**默认关闭**(无官方参考输出可逐位比对,
|
||||
故 opt-in)。默认关闭时 `RenderPipelineTest` 的逐位基线不受影响(96 项测试全绿)。
|
||||
|
||||
实机实测:级别 2 下仍 15.1fps,单帧绘制 11.3ms(滤波器约 +5ms,帧预算 66ms 内),
|
||||
细节增强清晰可见。
|
||||
**两个 strength 不可互换(本轮抓到的实现 bug)**:官方把**增益缩放后**的
|
||||
`k = strength * gain * 2 >> 8` 传给 map(决定阈值与 divisor 下限),
|
||||
但**混叠系数用的是原始 strength**。本移植最初两处都用 `k`,等于把细节
|
||||
再乘一遍增益——真机 level 2 画面满屏噪点。修正后 HF 能量与关闭档几乎相同
|
||||
(0.47~0.51 对 0.46~0.47),边缘仍被增强。
|
||||
数值由 `blendUsesTheRawStrengthNotTheGainScaledOne` 黄金值测试锁定
|
||||
(推导写在测试注释里;把 bug 改回去该测试立刻失败,已验证)。
|
||||
|
||||
**本轮真机验证(小米 22041211AL / Android 12 / MIUI,无线 adb 192.168.88.137:44323)**:
|
||||
**档位换算经官方 SDK 核对**:`MAG_SetDetailEnhancement` 把档位钳到 **0..32**,
|
||||
`SetEX` 与之无关(那是数码变焦 ROI)。**官方 App 本身不调用
|
||||
SetDetailEnhancement**(jadx 全量搜索无此符号),所以官方实时画面用的是
|
||||
SDK 内部默认档——无法据此对齐具体档位,故本应用把它做成用户可见设置
|
||||
(0/1/2/3/4/6/8 档),默认**关闭**(关闭时 `RenderPipelineTest` 逐位基线不受影响)。
|
||||
一个有用的推论:每档的边缘强度其实与档位无关(化简为 `128/gain`),
|
||||
档位只决定哪些窗口通过对比度阈值——所以调高档位是"纳入更多弱对比区域",
|
||||
而不是"把边缘推得更狠"。
|
||||
|
||||
实机实测:级别 2 下仍 15.1fps,单帧绘制 11.3ms(滤波器约 +5ms,帧预算 66ms 内)。
|
||||
|
||||
### 8) 其他顺带修复(本轮真机复现)
|
||||
|
||||
- **`no_device` 死锁**:首次 connect 若赶上相机正在重枚举(`findDevice()` 返回
|
||||
null)就停在"无相机",而 200ms 后到达的 ATTACHED 广播又落在 800ms 防抖窗口里
|
||||
被丢弃 → 永久无画面,必须手动重启 App。现在防抖与退避都改为**延后重试而非丢弃**,
|
||||
且 `no_device` 本身也会安排一次 1.5s 重试(`scheduleRetry` 单槽位、最新请求优先)。
|
||||
- **平放时 OSD 文字整体转 90°**:手机平放在桌面时加速度计 x/y 都接近 0,
|
||||
迟滞逻辑保留了上一次的姿态角。现在 tilt < 4 m/s²(约 24°)判定为"平放",
|
||||
姿态角归零。
|
||||
- **视频录制缺少 max/min 标记**:实时画面显示的两个极值没有烧进录像帧,
|
||||
现在 `probesAsMarks()` 一并返回(录像因此与实时画面一致)。
|
||||
- **屏幕熄灭时的行为(实测)**:渲染线程随 SurfaceView 停止绘制(无空转),
|
||||
USB 读取继续,整机 CPU 占用 3.7%——后台不烧电、不崩溃。
|
||||
|
||||
**本轮真机验证(小米 22041211AC / Android 12 / MIUI,无线 adb 192.168.88.137:44323)**:
|
||||
|
||||
- [x] 渲染帧率 6.5 → **15.1 帧/秒**,单帧 134ms → **6.4ms**(开增强 11.3ms)
|
||||
- [x] 拍照:`capture: nuc=yes probes=2 mirror(h=false,v=true) extremes=2 saved=true`
|
||||
@@ -580,7 +606,9 @@ extremes **合并成一次 draw**(原来分两次调用,彼此看不见)
|
||||
`min 22.0℃` 在冷区、Pt1/Pt2 带白底标签,互不压字
|
||||
- [x] 分析界面:标点与照片烧录位置对齐,**只有一个 min、一个 max**
|
||||
- [x] 分析面板数值可见且与照片一致(最高 32.9 / 最低 22.0 / 中心 24.4℃)
|
||||
- [x] 图像增强 2 级:画面细节明显增强,帧率不掉
|
||||
- [x] 图像增强:档位生效、修正后不再放大噪声、15.1fps 不掉帧
|
||||
- [x] 设置持久化跨冷启动(`mag160c_settings.xml`:enhanceLevel / imageFlipV)
|
||||
- [x] 屏幕熄灭时无空转(CPU 3.7%)、USB 读取继续、不崩溃
|
||||
|
||||
**教训记录**:
|
||||
- `dumpsys gfxinfo` 不统计 SurfaceView 的 lockCanvas 绘制。判断自绘画面性能
|
||||
|
||||
Reference in New Issue
Block a user