Files
MAG160C/docs/android_app/pc_official_compare_20261006.md
T

7.2 KiB
Raw Blame History

官方 PC 端 vs 逆向 SDK:同一帧逐像素对比(2026-10-06)

目的:热像仪接 PC 后,用官方 Windows 软件采图,与逆向出来的 SDK/App 管线 渲染同一帧做逐像素对比,找出"照片到底差在哪些细节上"。 证据图:docs/android_app/pc_vs_ours_20261006.png(官方 / 我们 / 差异×8 / 灰度 ×16)。

结论速览

环节 一致性 证据
NUC(端点插值 + 增益/阈值表 + 盲元补偿 + ref) 逐像素完全一致 抽检 4 帧:19200/19200 像素相等,max diff = 0
调色板 完全一致 官方 .pal、官方彩色图颜色集合、我们的 PALETTE256_ARGB 三者 256/256 相同
灰度映射(窗口 + 直方图 LUT + 2× 上采样) 平均 +1.3 级、最大 10 级(/255) 320×240 灰度逐像素;本轮场景计数 9600–11000
彩色输出 60.9–72 % 字节完全相同,平均 |Δ| 1.4–1.9/255,最大 20 官方 .rgb(BGR24)vs 我们导出的 PNG
细节增强(7×7 DDE) 官方这份渲染没开;我们默认等级 0 也关 官方彩色 = palette(官方灰度),逐像素 max diff = 0
显示窗口 下界规则不同 官方 20/20 帧 winHi = 数据max;12/20 帧 winLo = 数据min,其余仅低 1–7 计数。我们 winLo = mean−500,本例比数据 min 低 188 计数
温度换算 系统差:+0.1 ℃ @27 ℃ → −0.7 ℃ @38 ℃ 官方 t32 是 NUC 计数的精确直线(k=8.539 mC/count,残差 ≤0.5 mC),我们的固定 T2E 表斜率 8.26→7.67 递减

一句话:渲染管线(NUC/调色板/灰度)已经和官方 PC SDK 对得上,肉眼几乎无差别; 真正还差的是温度曲线(最高到 0.7 ℃)和窗口下界规则(造成约 1 级亮度偏差)。

1. 官方 Windows 侧用谁

候选 判定
app/【PC分析软件】…exe(内部名 ThermoX 2.5.3.6,巨哥电子) 是网络码流软件:面板是"指定IP / 启用DHCP Server / 传输混合/纯视频/纯温度码流",刷新扫不到 USB 相机,运行期不加载任何 USB 库 → 不吃本机 USB 机芯
IR_Camera_SDK-1.0.1/windows/windows/app/EloThermal.exe(官方 SDK 演示,C# 源码在仓库) 能连 USB 出图(CameraSDK/ThermalSDK + libusb0),但没有任何存图功能(全源码无 Encoder/Save)→ 只能截屏
build-artifacts/tsdk_pair3.exe(本仓库工具,调用官方 ThermalSDK.dll + CoreSDKLib.dll) ✅ 采用:一次采集给出官方渲染图、原始帧、温度、调色板、LUT、DDT 全套

2. 方法(可复现)

# 1) 设备驱动(本机原来没装,CM_PROB_FAILED_INSTALL)
#    厂商 INF:IR_Camera_SDK-1.0.1/windows/windows/drivers/amd64/ThermoCube_stream.inf
#    (libusb-win32 1.2.6.0,cat 是 libwdi 自签证书) → 需先把该证书导入
#    "受信任的根证书颁发机构" + "受信任的发布者",再:
pnputil /add-driver ThermoCube_stream.inf /install     # 设备变 OK,libusb0 服务 RUNNING

# 2) 官方基准采集(输出目录用第 1 个参数,勿落在仓库里)
cd <temp>
tsdk_pair3.exe <temp>\off20 20 6000 > off20_stdout.txt
#   每帧产出 19 个文件:gray / rgb / cbrgb(BGR24) / raw / f20 / ref / t32 / pal /
#   lut / h1024 / cdf / hist / thr0 / thr1 / thrw / g0 / g1 / gw / blind (+official.ddt)

# 3) 用我们的管线离线渲染同一批帧(临时 JVM 单测,用完已删)
#    RenderPipeline.loadDdt(official.ddt) 后:
#      repeat(4){ frameRemote(pair.ref, phase=2, shutter) }   // ref = 官方的参考帧
#      frameRemote(pair.f20,   phase=0, shutter)              // 渲染
#    产出 our_XXX.png / .nuc / .t32,再用 Python 与官方逐像素比

新解码出的官方内部缓存语义(供后续逆向用):

缓冲 地址 含义
帧输入 dev+0x41f20 官方喂给 NUC 的帧数据(= USB 帧 payload 域,均值 ~12000)
参考帧 dev+0x41ef0 NUC 用的 ref
传感器温度 dev+0x54 端点插值用的 FPA 温度(与 DDT 锚点同量纲,m℃)
NUC 输出 dev+0x270 校正后计数(均值 ~9600–11000);MAG_GetTemperatureData_Raw 的输入
端点选择 dev+0x41840 官方的 sel,与我们的 endpoint() 取值完全一致

关键验证:把 dev54 当帧尾 FPA 温度喂进我们的管线,NUC 输出与官方 pair_*.raw 19200/19200 像素逐位相等——这同时锁定了帧尾 FPA 字段的语义。

3. 温度:官方是"每设备线性响应",我们用的是固定曲线

官方 t32(19200 像素 × int32 毫度)与 NUC 计数之间是精确直线:

t_mC = 8.539 * counts - 55688      # 残差 ≤ 0.5 mC;逐帧斜率 8.5358–8.5424(≈常数)

同一计数下不同像素的温度离散为 0 mC(无逐像素差异)→ 说明官方对"已校正计数" 只做一次全局线性换算(对应 ConvertResponse2Temperature 一族,csdk 里已有实现 mag160c_temp_convert_response,但安卓 App 未使用)。

我们的 TempMath.countsToTempMc 是固定 T2E 反查表,局部斜率随计数递减:

计数区间 官方斜率 我们的斜率 比值
9600–9900 8.5390 8.2581 1.034
9900–10200 8.5391 8.1993 1.041
10200–10600 8.5390 7.9505 1.074
10600–11000 8.5390 7.6706 1.113

→ 温度读数偏差:≈27 ℃ 处 +0.1 ℃,≈38 ℃ 处 −0.62 ℃(累计最大 −0.70 ℃)。

4. 建议的下一步

  1. 温度(优先):安卓端改用设备响应换算。官方 PC 侧对已校正计数是线性映射, 系数随设备(本机实测 k=8.539 mC/count、b≈−55.7 k mC,随 FPA 温度微动 ~±50 mC)。 需要先定位系数的来源(DDT / BasePara 里的标定字段),再按官方公式实现; csdk/src/mag160c_temp.c::mag160c_temp_convert_response 已是同款算法,可作参照。
  2. 窗口:把 statsWindow() 从"mean ± (dev24*1000>>dev4cShift)/2 向外扩"改成官方行为 (上界 = 数据 max、下界 = 数据 min,20 帧实测 20/20 与 12/20 如此,其余差 ≤7 计数)。 这一项解释了灰度上 ~1.3 级的系统性偏差。
  3. 手机侧对照照(未完成):本轮只覆盖"渲染",没覆盖官方手机 App 的拍照路径。 建议:同一静止场景,官方手机 App 与我们的 App 各拍一张同调色板照片; 官方 MDT 里存的就是 NUC 后帧,可以直接喂我们的显示阶段逐像素比 (需要给管线加一个"只跑显示阶段"的离线入口)。
  4. PC 端 C 工具链:本机 libusb-1.0 1.0.19 对 libusb0.sys 绑定不可用 (claim_interface → Win32 错误 87;官方走 libusb0.dll API 正常)。 若要在这台机器跑 csdk 的 demo3/render_offline,需要换 libusb-1.0 版本, 或把设备改绑 WinUSB/libusbK。

5. 复现清单(临时文件不在仓库)

  • 官方基准数据(20 帧全套,35 MB)与差异图在 %TEMP%\mag160c_wincmp\off20\(compare_visual.png / compare_tempdiff.png / compare.txt); 仓库内只保留 docs/android_app/pc_vs_ours_20261006.png 一张证据图。
  • 驱动安装脚本痕迹:%TEMP%\mag160c_wincmp\pnputil*.log、cert.log。