【共创稿事节】HarmonyOS 7重建结果质量评估:SSIM/PSNR 端侧轻量实现
重建结果质量评估SSIM/PSNR 端侧轻量实现3DGS 重建跑完了给用户看之前怎么知道这次重建好不好我们一开始全靠肉眼——重建工程师逐个看觉得糊就重拍。问题是肉眼判断主观、慢、且不可复现。同一组重建结果两个工程师一个说合格一个说不合格评审会开成吵架会。我们需要一个端侧能跑的量化指标重建完立刻给个分数分数低于阈值自动建议重拍。这篇文章记录我们把 SSIM/PSNR 做端侧轻量实现的过程以及在没有 ground truth 时怎么绕过没有参考图这个根本困难。能力面端侧轻量 SSIM/PSNRSSIM结构相似性和 PSNR峰值信噪比是图像质量评估的经典指标。常规用法是有原图I和失真图K按公式算出一个 0-1 的相似度分数。问题是3DGS 重建结果没有 ground truth——你拍了一段视频重建出 3D 场景没有原始 3D 场景可以对比。我们的解法是从采集视频里留出 holdout 帧当参考。采集 60 帧视频重建时用 50 帧训练留 10 帧不参与训练。重建完成后把这 10 帧对应的视角用 3DGS 渲染出来和真实采集的 10 帧对比算 SSIM/PSNR。这 10 帧重建结果没见过相当于考试题分数反映重建的泛化能力。// entry/src/main/ets/quality/QualityAssessor.etsimport{image}fromkit.ImageKit;import{spatialRender}fromkit.SpatialReconKit;exportinterfaceQualityResult{ssim:number;// 0-1越大越好0.85 我们认为可用psnr:number;// dB越大越好28 dB 我们认为可用assessTime:number;// 评估耗时 msholdoutCount:number;}exportclassQualityAssessor{/** * 端侧轻量 SSIM/PSNR 评估 * param gsNode 重建得到的 3DGS 节点 * param holdoutFrames 留出的参考帧视角 真实采集图 */staticasyncassess(gsNode:spatialRender.GSNode,holdoutFrames:HoldoutFrame[]):PromiseQualityResult{constt0:numberDate.now();letssimSum:number0;letpsnrSum:number0;letvalidCount:number0;for(constframeofholdoutFrames){// 1. 用 3DGS 在 holdout 视角下渲染出图constrendered:image.PixelMapawaitgsNode.renderToImage({camera:frame.camera,width:512,// 降采样到 512 加速评估原采集 1080pheight:512});// 2. 把真实采集帧也缩到同尺寸constreference:image.PixelMapawaitdownsample(frame.pixelMap,512,512);// 3. 算 SSIM 和 PSNRconstssim:numberthis.computeSSIM(rendered,reference);constpsnr:numberthis.computePSNR(rendered,reference);if(ssim0psnr0){ssimSumssim;psnrSumpsnr;validCount;}rendered.release();reference.release();}constassessTime:numberDate.now()-t0;return{ssim:validCount0?ssimSum/validCount:0,psnr:validCount0?psnrSum/validCount:0,assessTime,holdoutCount:holdoutFrames.length};}// SSIM 轻量实现分块计算11x11 高斯窗口简化为 8x8 均值窗口privatestaticcomputeSSIM(a:image.PixelMap,b:image.PixelMap):number{// 转灰度constgrayA:Uint8ArraytoGray(a);constgrayB:Uint8ArraytoGray(b);constw:number512;consth:number512;constblockSize:number8;letssimSum:number0;letblockCount:number0;for(lety:number0;yh-blockSize;yblockSize){for(letx:number0;xw-blockSize;xblockSize){conststatsAblockStats(grayA,w,x,y,blockSize);conststatsBblockStats(grayB,w,x,y,blockSize);constcovAB:numberblockCov(grayA,grayB,w,x,y,blockSize,statsA.mean,statsB.mean);// SSIM 常数按 8bit 图标准取值constc1:number(0.01*255)**2;constc2:number(0.03*255)**2;constssim:number((2*statsA.mean*statsB.meanc1)*(2*covABc2))/((statsA.mean**2statsB.mean**2c1)*(statsA.varstatsB.varc2));ssimSumssim;blockCount;}}returnblockCount0?ssimSum/blockCount:0;}// PSNRMSE 越小 PSNR 越大privatestaticcomputePSNR(a:image.PixelMap,b:image.PixelMap):number{constdataA:Uint8ArraytoGray(a);constdataB:Uint8ArraytoGray(b);letmse:number0;for(leti:number0;idataA.length;i){constdiff:numberdataA[i]-dataB[i];msediff*diff;}mse/dataA.length;if(mse0){return100;// 完全相同}return10*Math.log10((255*255)/mse);}}实现上有几处简化窗口从 11x11 高斯改成 8x8 均值标准 SSIM 用 11x11 高斯窗口滑窗计算端侧算力吃不消。8x8 块均值版本精度略低但和标准 SSIM 的相关系数在我们测的 10 组数据上达到 0.94够用。渲染分辨率降到 512x512原采集 1080p 直接算要 4 倍耗时512 下 SSIM 数值变化在 0.01 以内。下面这张图把端侧评估的判定链路串起来。从重建结果到最终入库还是重采每一步都有明确输入输出。达标不达标重建完成得到 3DGS 结果从采集视频留出 holdout 帧当参考在 holdout 视角渲染出图渲染图与真实帧统一降到 512 尺寸分块计算 SSIM 并算 PSNR多帧求均值得到质量分数SSIM 大于 0.75 且 PSNR 大于 26结果入库并展示按 SSIM 区间给具体重采建议触发重新采集或补拍图里从渲染到阈值比较是评估主链路。低于阈值的分支回到采集环节做一次质量兜底。约束面评估耗时与内存端侧评估不能比重建本身还慢否则没意义。我们在麒麟 9030 上测了不同 holdout 帧数下的耗时和内存。holdout 帧数评估耗时内存峰值SSIM 数值稳定性5380 ms42 MB±0.01810720 ms48 MB±0.011151080 ms56 MB±0.008201450 ms64 MB±0.006302310 ms78 MB±0.005我们选了10 帧。5 帧稳定性差30 帧太慢且内存逼近重建本身的占用。10 帧在 720 ms 内完成用户感知是重建完稍等一下分数就出来了。内存峰值 48 MB 看着不大但要叠加在重建过程的内存上。重建峰值已经 800 MB 左右再加 48 MB 不会触发 OOM但如果重建结果没释放就启动评估峰值会到 880 MB在 8 GB 设备上危险。我们的做法是重建完先释放中间张量再启动评估。场景落地10 组重建结果评估我们采集了 10 组不同场景的视频每组用 50 帧训练、10 帧 holdout重建后做端侧评估。同时请 3 位重建工程师盲打分1-5 分做人工对照。真机数据SSIM/PSNR 与人工评分场景SSIMPSNR (dB)人工评分均值评估耗时陶瓷茶壶0.9131.24.3680 ms毛绒玩具0.8829.84.0710 ms皮鞋0.8628.53.8695 ms玻璃杯0.6222.12.1720 ms镜面金属件0.5821.31.9730 ms木雕0.8930.14.1685 ms布艺沙发0.8427.93.6705 ms绿植盆栽0.7926.43.2700 ms强光下石雕0.8127.13.4690 ms弱光下手办0.7325.02.8715 msSSIM 与人工评分的 Pearson 相关系数 0.93PSNR 与人工评分 0.88。SSIM 比 PSNR 更贴合人感这和文献一致——PSNR 对像素误差敏感但人眼对结构误差更敏感SSIM 抓的就是结构。玻璃杯和镜面金属件两组数据是失败 case。SSIM 0.62、0.58人工评分 2.1、1.9都低。这两组是 3DGS 重建的已知弱项透明和反光物体采集时多视角不一致高斯点拟合不了反射光路。SSIM 准确地把这两组标了出来我们据此把阈值定在 0.75——低于 0.75 自动建议重拍。踩坑与取舍坑一SSIM 需要 reference 图但重建结果没有参考这是开头说的根本困难。holdout 帧方案能跑但有个隐含假设holdout 帧和训练帧视角分布接近。如果用户采集时只拍了正面holdout 留的也是正面SSIM 会偏高——正面重建容易侧面才是难点。我们试过强制 holdout 留侧面帧但用户采集路径不可控有时侧面帧本身就模糊。最后改成按视角均匀采样 holdout把 60 帧按相机方位角分到 6 个桶每桶留 1-2 帧做 holdout。这样 holdout 覆盖各视角SSIM 能反映整体重建质量。坑二PSNR 对结构误差不敏感PSNR 算的是像素级 MSE。重建结果如果整体偏了一像素几何漂移人眼看是错的但 PSNR 可能不算太低——因为偏移后像素值差异不大。我们有一组木雕数据PSNR 30.1 看着不错但人工评分只有 4.1原因是纹理对但轮廓偏了。结论是 PSNR 只能当辅助指标主判据用 SSIM。我们最终阈值是 SSIM 0.75 且 PSNR 26 dB双指标都过才算合格。单看 PSNR 会放过几何漂移的 case。坑三弱光场景 SSIM 失真弱光下手办那组 SSIM 0.73人工评分 2.8。看起来 SSIM 准确反映了质量不好。但深入看发现 SSIM 偏低部分原因是采集帧本身噪声大holdout 帧和渲染帧比渲染帧反而更干净3DGS 重建有降噪效果SSIM 把降噪后的干净和带噪的真实比分数被噪声拉低。这意味着弱光场景下SSIM 会低估重建质量。我们的处理是弱光场景采集平均亮度 50单独校准阈值从 0.75 降到 0.68。这是个 hack但比弱光场景全判不合格合理。坑四被放弃的方案——无参考质量评估NRQA我们试过完全不需要 holdout 的无参考质量评估方案用端侧小模型推理给个分数。模型用 BRISQUE 思路训练2 MB 大小。问题是模型在训练分布外场景表现崩塌——训练集是自然图像碰到 3DGS 渲染图高斯点叠加出的图分数完全不可信。陶瓷茶壶重建很好模型给 1.8 分玻璃杯重建很差模型给 4.2 分。这个方案被放弃了。无参考评估在没有 3DGS 渲染图训练集的前提下不可用而构建这样一个训练集成本太高。holdout 帧方案虽然要多留几帧但可靠。评估结果怎么用光算出分数不够要把分数接到产品流程里。// entry/src/main/ets/quality/QualityGate.etsexportclassQualityGate{privatestaticreadonlySSIM_THRESHOLD:number0.75;privatestaticreadonlyPSNR_THRESHOLD:number26;// 弱光场景阈值放宽privatestaticreadonlySSIM_THRESHOLD_LOWLIGHT:number0.68;staticevaluate(result:QualityResult,isLowLight:boolean):QualityVerdict{constssimThreshold:numberisLowLight?this.SSIM_THRESHOLD_LOWLIGHT:this.SSIM_THRESHOLD;if(result.ssimssimThresholdresult.psnrthis.PSNR_THRESHOLD){return{pass:true,score:result.ssim,suggestion:};}// 不通过时给具体建议而不是笼统说质量差letsuggestion:string;if(result.ssim0.6){suggestion重建质量较差建议重新采集注意覆盖多角度且避免反光;}elseif(result.ssimssimThreshold){suggestion部分视角重建模糊建议补拍侧面和背面;}else{suggestion几何精度不足建议采集时放慢移动速度;}return{pass:false,score:result.ssim,suggestion};}}suggestion不是笼统的质量差请重拍而是按 SSIM 区间给具体建议。SSIM 0.6 是整体崩了建议重采0.6-0.75 是部分视角糊建议补拍SSIM 过了但 PSNR 没过是几何漂移建议放慢移动速度。用户看到具体建议才知道怎么改质量差三个字对用户没操作指导意义。总结一下下holdout 帧按视角均匀采样不能只留正面帧否则 SSIM 偏高不反映整体质量SSIM 用 8x8 块均值窗口替代 11x11 高斯窗口精度损失 0.01 以内耗时减半评估分辨率降到 512x512原 1080p 算 SSIM 耗时 4 倍数值变化 0.01 以内主判据用 SSIMPSNR 仅辅助PSNR 对几何漂移不敏感单看会放过结构错误弱光场景 SSIM 阈值从 0.75 降到 0.68弱光下 SSIM 会因采集噪声低估重建质量评估前先释放重建中间张量避免内存峰值叠加触发 OOMholdout 帧数选 105 帧稳定性差30 帧耗时超过 2 秒用户感知等待无参考质量评估在 3DGS 场景不可用训练集分布外分数崩塌holdout 方案更可靠

相关新闻

【共创稿事节】HarmonyOS 7重建失败的 6 种典型 case 与降级路径

【共创稿事节】HarmonyOS 7重建失败的 6 种典型 case 与降级路径

重建失败的 6 种典型 case 与降级路径 3DGS 重建失败的原因五花八门:输入拍得太烂、物体本身没特征、机器内存不够、重建跑超时、设备不支持、结果出来质量太差。每种失败的降级方案不一样——OOM 该清数据还是保留?超时该用部分结果还是直接放弃&#x…

2026/10/11 8:45:08 阅读更多 →
Appium WebView自动化实战:从环境搭建到context切换全解析

Appium WebView自动化实战:从环境搭建到context切换全解析

跑过两个混合应用项目之后我意识到,Appium基础教程里最容易被一笔带过、实战里又最折磨人的部分,就是WebView。原生页面用uiautomator看控件、点控件,一切都很顺;可一旦进入App内嵌的H5页面,脚本要么找不到元素&#x…

2026/10/11 8:44:37 阅读更多 →
PHP+Vue+微信小程序学习交流平台毕设全流程开发实战

PHP+Vue+微信小程序学习交流平台毕设全流程开发实战

当年我做“基于PHPVue的微信小程序学习交流平台”这个毕业设计的时候,最大的感受不是技术有多难,而是“系统怎么从零到一跑通”这件事远比想象中琐碎。选题要求很直接:用户端用微信小程序,后台管理系统用 Web 页面,后端…

2026/10/11 8:44:41 阅读更多 →

最新新闻

MySQL 64学时教学大纲拆解:从E-R图到PetStore建库全链路

MySQL 64学时教学大纲拆解:从E-R图到PetStore建库全链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 2:55:40 阅读更多 →
MySQL与PostgreSQL整数类型选型:从INT到BIGINT的避坑指南

MySQL与PostgreSQL整数类型选型:从INT到BIGINT的避坑指南

搞数据库的人,十有八九都遇到过这种场景:建表时图省事顺手写了个INT,看着挺正常,结果业务量上来之后,主键突然撞到天花板,或者磁盘空间莫名暴涨。选整数类型这件事,在 MySQL 和 PostgreSQL 里看…

2026/10/12 2:55:40 阅读更多 →
互联网医院+居家养老:医养协同闭环如何落地

互联网医院+居家养老:医养协同闭环如何落地

晚上九点多,同事给我打电话,说她父亲在老家测出血压180/110,人有点晕。她自己在外地出差,隔着几百公里,语音那头全是慌张。这种场景,做互联网医院和居家养老医养结合项目之前,基本只能干着急&am…

2026/10/12 2:55:40 阅读更多 →
消息队列如何保证数据不丢失?生产、存储、消费三端全解析

消息队列如何保证数据不丢失?生产、存储、消费三端全解析

面试题这东西,十有八九是套路,但“消息队列如何保证数据不丢失”是我见过最容易“背了配置但答不出本质”的一道。很多人上来就背:Kafka 开 acksall、副本设 3、消费者别自动提交,听起来很全,但面试官只要换个问法——…

2026/10/12 2:55:40 阅读更多 →
Git常用命令实战:从核心设计逻辑到高频操作指南

Git常用命令实战:从核心设计逻辑到高频操作指南

每个写代码的人,早晚都要面对版本管理这件事。刚开始我不太在意,直到有一次熬夜改了三天代码,因为一次误操作把整个项目覆盖,才真正体会到版本管理的分量。后来把Git当成每日必用工具,才发现真正高频的“常用命令”就二…

2026/10/12 2:55:40 阅读更多 →
PLC程序质量四层评估模型:从能运行到可维护可演进

PLC程序质量四层评估模型:从能运行到可维护可演进

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 2:54:40 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →