图像超分效果页有一个很隐蔽的比较陷阱:左边原图展示的是招牌的中间位置,右边增强图看起来更清晰,却实际上放大了另一块区域。两侧都写着“4×”,滑块也能来回拉,页面看起来很专业;但只要被比较的像素不来自同一处,锐度、文字边缘和噪点判断就没法成立。我给这个问题设计了一个小实验项目 PixelParity。输入是 960×640 的原图,另一侧为由外部超分处理流程提供的 3840×2560 结果图,尺寸关系为 4×;取样框位于归一化坐标 (0.375, 0.375),宽、高各占全图的 25%。示例要比较的是同一个招牌文字区域,不是讨论图像超分算法本身是否更强。本文所有图片及运行数值均为演示,所谓“4×”是样本尺寸条件,并非真实设备性能测量。## 一、两张图都能显示,不代表正在公平比较假设原图使用 ImageFit.Contain,超分图却因为卡片样式变化用了裁剪填充。用户以为两边处于相同放大倍率,但源图边缘和增强图边缘可能根本没有重合。再加上结果图的分辨率更高,简单拿两个组件的像素位置相减,也无法推出源文件中同一位置的像素索引。这里至少有三个坐标系:原始图片像素坐标、超分结果图片像素坐标、屏幕显示容器的 vp 坐标。代码如果把它们揉成一个 x 和 y,在旋转屏幕、页面缩放、容器留白时就会出错。最稳妥的办法是把比较范围先表示为归一化图像区域,再分别映射到两个像素空间。项目约定视口不是以屏幕左上角为基准,而是基于图像有效内容。这样,A/B 两侧即便各自显示成不同尺寸,也能用同一份 (x, y, width, height) 计算出严格对应的采样矩形。UI 组件负责展示,像素几何由独立纯函数负责,方便生成可复查的日志。## 二、第一道门禁:像素矩形由同一份归一化区域导出第一段 ArkTS 只完成坐标映射,不做解码与超分。NormalizedRoi 中四个值都处于 0 到 1 的区间,右、下边界不允许超过 1。输出矩形以原图或结果图的像素为单位。舍入放在最后一步,避免提前截断导致同一视口反复计算时逐次漂移。arktsexport interface NormalizedRoi { x: number; y: number; width: number; height: number; }export interface PixelRect { left: number; top: number; width: number; height: number; }export function toPixelRect(roi: NormalizedRoi, w: number, h: number): PixelRect { const valid = w > 0 && h > 0 && roi.x >= 0 && roi.y >= 0 && roi.width > 0 && roi.height > 0 && roi.x + roi.width <= 1 && roi.y + roi.height <= 1; if (!valid) { throw new Error('INVALID_ROI'); } const left = Math.round(roi.x * w); const top = Math.round(roi.y * h); const right = Math.round((roi.x + roi.width) * w); const bottom = Math.round((roi.y + roi.height) * h); return { left, top, width: right - left, height: bottom - top };}示例输入 roi={x:0.375,y:0.375,width:0.25,height:0.25},原图应得到 left=360, top=240, width=240, height=160;结果图应得到 left=1440, top=960, width=960, height=640。两侧都围绕相同的几何中心,视觉差异才有进一步比较的意义。Math.round 不保证任意非整数倍尺寸都无采样误差,所以真正的裁剪或重采样器还要统一插值、像素中心定义和边缘处理方式。一个容易遗漏的错误是只计算 width=0.25×w,却让两张图的左上角分别来自各自的拖拽值。那样大小比例虽正确,位置却不再同源。解决它不需要更复杂的模型,而是把 ROI 对象视为一份不可分叉的比较请求,两侧都从这份对象映射坐标。## 三、第二道门禁:尺寸关系先于清晰度评分即便输入样本名写着“4×超分”,文件也可能被导出程序补边、裁切或旋转。有些输出图像内容仍然可见,但宽高比例已经改变。此时强行对照会把几何拉伸误当作纹理增强,后续所有主观打分都受到污染。下面这段代码把审核范围缩小到两个条件:输入输出尺寸都合法,宽高比例一致并且放大倍率接近正整数。它不能验证图像内容是否相同,也不能鉴别重采样算法,仅充当进入 A/B 对照之前的尺寸准入门禁。arktsexport interface ImageSize { width: number; height: number; }export interface PairGate { ok: boolean; label: string; scale: number; }export function checkPair(src: ImageSize, dst: ImageSize): PairGate { if (src.width <= 0 || src.height <= 0 || dst.width <= 0 || dst.height <= 0) { return { ok: false, label: 'INVALID_SIZE', scale: 0 }; } const sx: number = dst.width / src.width; const sy: number = dst.height / src.height; const nearest: number = Math.round(sx); const ok: boolean = nearest >= 2 && Math.abs(sx - sy) < 0.000001 && Math.abs(sx - nearest) < 0.000001; return { ok, label: ok ? 'ALIGNED_DIMENSION' : 'CHECK_ASPECT', scale: sx };}这里把“接近整数”设成了演示策略,不是 HarmonyOS 平台或 Image Kit 的系统阈值。比如另外一种产品专门处理 1.5× 上采样,完全可以采用不同准入规则。相反,960×640 → 3840×2560 得到 scale=4,门禁标签 ALIGNED_DIMENSION。这个标签只证明输出尺寸比例符合当前样本约束,绝对不代表图像超分效果通过质量审核。项目中还要保存来源关系:原图与结果图必须属于同一个样本 ID、同一次超分请求和相同方向的图像。只有宽高合格,没有身份一致性,也不能进入严肃的 A/B 比较。本文不使用不存在的“自动确定同源”平台接口;这些核对由业务文件索引或可信任务结果记录完成。## 四、界面只展示同视口,不拿它冒充算法指标演示页面用 Image 组件承接两张预先从同一 ROI 导出的样本小图。纯 ArkTS 几何逻辑先计算像素矩形,再交给接入方调用实际裁剪解码流程;这里不把 Image 显示属性写成图像裁剪 API,也不声称两个静态素材完成了实时 PixelMap 变换。第三段代码把门禁与界面绑在一起,只保留必要状态,按钮触发诊断。为避免把尚未接入的裁剪能力伪装成可运行,两个 app.media 资源明确代表已准备好的示例 ROI 图片。arkts@Entry@Componentstruct ComparePage { @State report: string = '尚未检查'; private inspect(): void { const gate = checkPair({ width: 960, height: 640 }, { width: 3840, height: 2560 }); const roi: NormalizedRoi = { x: 0.375, y: 0.375, width: 0.25, height: 0.25 }; const a: PixelRect = toPixelRect(roi, 960, 640); const b: PixelRect = toPixelRect(roi, 3840, 2560); this.report = gate.ok ? '同视口尺寸已对齐 · 4×' : '尺寸关系待复核'; console.info(`PixelParity ${gate.label} src=${a.left},${a.top},${a.width},${a.height} ` + `dst=${b.left},${b.top},${b.width},${b.height}`); } build() { Column({ space: 12 }) { Text('PixelParity · 同视口对照').fontSize(22) Row({ space: 8 }) { Image($r('app.media.crop_before')).width('49%').objectFit(ImageFit.Contain) Image($r('app.media.crop_after')).width('49%').objectFit(ImageFit.Contain) } Text('ROI (0.375, 0.375) · 25% × 25%') Text(this.report) Button('检查同视口').onClick(() => this.inspect()) }.padding(16) }}这段简化视图没有计算图像的噪声、PSNR、SSIM 或耗时,更没有调用设备超分推理能力。真正把 Image Kit 接进来时,开发者可以在入参解码之后根据 PixelMap 的实际尺寸计算 ROI,再通过符合目标 SDK 文档的图像操作生成对应的两份小图。若有异步加载,要把样本 ID 和 ROI 版本一起带上,旧结果不允许覆盖新的比较请求。## 五、把预期结果写成可追踪的判断为了让项目评审不被视觉海报带跑,示例统一使用样本 PP-042、时间 18:18、放大倍率 4×、ROI 0.375/0.375/0.25/0.25。按纯函数推演,点击“检查同视口”之后应显示 同视口尺寸已对齐 · 4×,日志文本应是 PixelParity ALIGNED_DIMENSION src=360,240,240,160 dst=1440,960,960,640。这里的“应显示”仍是示例预期,不是一次已经完成的 HiLog 采集。实测时我会把问题拆开:先人为制造一份尺寸错误的结果图,看准入门禁是否拒绝;再把 ROI 从中心移动到边角,检验两个结果矩形是否继续同源;最后才让视觉负责人判断文字笔画、纹理及噪点。如果在前两步就发现位置不一致,讨论“超分是否更锐”没有意义。示意手机页上可以把源图像素矩形和结果图像素矩形直接展示出来,让审阅者知道比较区从哪里来。边界也必须明确。图像内容若发生非均匀几何变形、局部 AI 重绘、方向纠正或自动裁切,仅靠归一化矩形无法保证内容重合;这时需要引入特征配准或可信的几何映射记录,而不应继续使用简单 4× 映射。对颜色和动态范围敏感的素材,还应另行验证像素格式、色彩空间与编码回读,这与这里的几何同源门禁是不同层次的问题。## 六、结语与官方依据这件事的价值并不在于写了多少图像 API,而在于把主观对照前提变成一个可以复算的合同。放大倍率、样本身份、归一化 ROI、输出像素矩形应当先一致;完成这些以后才有资格评估增强效果。任何宣称“锐度提升百分之多少”的结论,都需要真实样本、固定评价方法及设备运行数据,不能从演示界面或示意图直接推出来。文章仅核对 ArkTS 数值逻辑以及 ArkUI Image 组件和官方 Image Kit、ArkGraphics 2D 所描述的图片解码与绘制职责。本文的超分结果是输入条件而非文中执行的 SDK 调用,没有编造图像超分接口、模型配置、推理耗时或真机效果。迁入真实工程前需要按目标 SDK 文档补齐图片读取、裁切、像素释放、异常资源回收以及硬件实测。官方参考:Image Kit 图片绘制与 PixelMap 说明、ArkGraphics 2D Canvas 绘制指南、ArkUI 开发资源。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐