AI 放大后的图更清楚,但它不能当原图入库

一条图片入库的链路上挂个超分环节是很自然的想法。缩略图糊了就先放大再切,列表页立刻好看。麻烦在后头:放大完的那张图一旦进了库就和用户当初传上来的那张混在一块了。再往后没人分得出哪个像素是相机给的、哪个是模型补的。下游只是列表页的封面图的话混了也没事。下游要做比对、核价和存档的时候混进去的就是事故。

这一轮的数是这么来的。三张 1024×1024 的样张先用 Pillow 11.3.0 的 LANCZOS 缩到 256 或 512,再让各种办法放回 1024 跟原图逐像素比,4× 那一组是八种办法、2× 那一组少一种。插值那边是 Pillow 的 nearest、bicubic 和 Lanczos。经典 CNN 超分走 OpenCV 5.0.0 的 dnn_superres 配官方预训练权重 ESPCN、FSRCNN、EDSR 和 LapSRN。GAN 那一类的数我用的是图映 ImgIng imging.cn/ 工作台的第 1 档快速高清,面板上显示跑的是 Real-ESRGAN General x4v3,五档里只跑了这一档。SSIM 用的是 scikit-image 0.24.0,PSNR 和分块统计是我自己写的。机器是一台 Apple 芯片 Mac 配桌面 Chromium,每种办法各跑一次。降质是人造的这件事得先交代:样张本来就清楚,是缩小以后再放回去的。真实的糊照片还叠着对焦不准、手抖、高 ISO 噪点和转发攒下来的 JPEG 损伤,这套数字搬不到那种图上去。

放大出来的像素不是拍到的像素

拍摄得到的像素有物理来源,一个一个对应着当时落在传感器上的光。超分给出的像素没有这个来源,它是模型在一张低清输入上按先验补出来的。这话听着像哲学,放到这三张样张上却是能数出来的。做法是把两张图都切成 8×8 的块比块内标准差:σ_out > 1.5·σ_gt + 2 记一个「多出块」;σ_out < σ_gt/1.5 − 2 记一个「丢失块」。阈值是这一轮自己定的。不是什么行业标准。系数一改百分比就跟着变,所以公式得和数字一起给出来才有用。

人像 4× 这一栏里那一档的多出块 1.53% 和丢失块 21.09% 两项都是全场最高。Lanczos 在同一栏只有 0.09% 和 11.65%。放到同一张脸上说就是模型一边在加原图没有的东西、一边在抹掉原图已经有的东西。这件事不能扩成「AI 放大一定会编细节」。插值类在人像 2× 上的多出块是 0.00%;经典 CNN 超分也接近零,ESPCN 在人像 4× 上只有 0.04%。会编的是 GAN 那一类。说的时候得说清是哪一类。倍率换一档,这两个数也跟着动,但动多少每格都不一样:同一档模型在人像上多出块从 2× 的 0.22% 涨到 4× 的 1.53%,在文字上只从 4.24% 挪到 4.93%。丢失块那一列的方向更齐,人像 7.32% 涨到 21.09%、文字 0.33% 涨到 2.62%,Lanczos 的人像也从 0.22% 涨到 11.65%。输入少一半边长,要补的就多一截。

脸上多出来的颗粒和原图对不上

这张图要看最右边那一格的鼻梁。五格并排截的都是人像两眼内眼角和鼻梁那一小块,4× 结果按 2.5 倍像素放大。第一格原图上毛孔和一颗小痣数得清,bicubic、lanczos、edsr 三格的鼻梁皮肤糊成一片。最右边那格眼角边缘最锐,鼻梁上也长出了颗粒状纹理,可颗粒的位置和第一格的毛孔、小痣对不上。每格下方标着全图 PSNR 和眼睛睫毛区 PSNR。两张照片样张都来自 Wikimedia Commons,按 CC0 许可发布:人像的作者是 William Stitt,风景的作者是 Bonnie Moreland。文字样张是自己做的。

睫毛那一块是在原图上人工框出来的一个矩形,不是算法分的区。这一档在框里的 PSNR 是 29.56,全场最低,同一栏的 EDSR 是 33.04。全图人像 4× 的 30.28 / 0.8145 两项都低于 Lanczos 的 32.50 / 0.8523。这个结果只在这一张 CC0 人像、最快那一档、人造降质这三个条件下成立,换张图或者换个档位都得重新量一遍。

同一个模型换到文字上表现整个翻过来。文字 4× 的丢失块只有 2.62%(2× 是 0.33%),别的办法都落在 6% 到 18% 之间。SSIM 这一栏是 0.9048 对 Lanczos 的 0.8177。同一个模型在两种内容上做的不是同一件事:一行小字只有一个正确形状,它重画出来还能落回去;一块皮肤没有这种形状可落,它补上去的就是新内容。按「用了 AI 超分」一刀切地信或者不信都不对。下游得知道具体是什么内容、什么办法、什么倍率。判断留给它自己做。这就得靠标记。

标记要带四项才够用

四项:办法属于哪一类、倍率、模型与权重版本、原图还在不在。

办法那一项要写到类,不是只写「超分」。人像那几格的多出块 0.00% 和 1.53% 不在一个量级上,这两件事挂同一个标签标记就白做了。倍率要单写的理由是上面那几对数字:同一个模型同一张图,2× 和 4× 加进去、抹掉的量不在一个档上。模型与权重版本得带,因为同一个名字底下结果能差出很远。EDSR x4 在这份文字样张上 PSNR 只有 18.74,比最笨的 nearest 的 19.27 还低。那是预训练权重留下的振铃重影,放大到招牌那几个字上能直接看见:拉丁字母右侧挂一条虚影、汉字出双重笔画。这只是这一套权重在这一份样本上的表现,不是开源超分不行。最后一项是可逆:原图留着这条标记才有用,原图删了它就只是个 label。

json 复制代码
{
  "pixel_origin": "model",
  "sr_family": "gan",
  "sr_model": "real-esrgan-general-x4v3",
  "scale": 4,
  "source_asset": "raw/7f21c0.jpg",
  "reversible": true,
  "not_for": ["forensics", "ocr_verify"]
}

字段名是我自己起的,不是什么标准,叫什么随各家的库。要紧的是四项都在,并且 not_for 这种硬约束由产生它的那一步写死而不留给调用方去记。最后那一行也不是我发明的要求------图映的说明页上自己就写着超分会由模型推测部分细节、这类场景应当保留并核对原图(说明页 2026-11-12 查阅)。

标记落在资产记录那一层

别只写进图片文件头,EXIF 和 XMP 这一层经不起折腾。格式一换、再压一道,字段可能就不在了。这一条是我的判断,这一轮没测元数据的存活率。

稳的位置是资产记录本身:库里那一行,或者对象存储里挨着原文件的 sidecar。读图的接口把它和 URL 一起返回。别让调用方自己去猜。派生图继承父图的标记再追加自己这一步。缩略图是从 4× 结果切出来的,就该一路带着「父亲是模型产物」这句话传下去。写的时机只有一个合适的点:谁产生这张图谁写。产生那一步才知道用的是哪个权重文件、哪个倍率,让下游事后补写等于让它猜。

有个地方我还没想清楚。一张图里一部分区域放大过、另一部分是原始像素,局部重绘和拼图都会出这种情况。这种混合资产该怎么标我没有干净的写法。眼下只能整张按最「重」的那一块算。宁可标过头。

校验只能当兜底

链路上还可以加一道不需要原图的检查:把成品按同倍率缩回去和当初那张低清图比 PSNR。这三张图上次序每一类内容里都一样:人像和风景 4× 的插值类给到 44 到 49 dB、经典 CNN 超分 40 到 46 dB、GAN 那一档只有 33 到 35 dB。中间两族的区间会挨在一起甚至互相压过,真正单独掉出一截的只有 GAN 那一档。阈值得按内容分开定:文字那一列整条往下挪,插值类也只有 34 到 36 dB。拿它当入库前的闸够用,能把一批没标记就溜进来的图拦下来。

闸拦住之后还得有人看图。这一项低只说明像素被动过,动的是不是有用的东西它答不上来:EDSR 的文字 4× 在这一项上掉到 27.86 dB,和 GAN 那一档一个量级,可它的 PSNR 18.74、SSIM 0.8018 在全场垫底,低分里装的是双重笔画。所以它只能当筛网,筛完要回去补标记,替代不了标记本身。

手头已经有一批放大过、又没留来源的图的话可以先按这条跑一遍:缩回去比一次 PSNR,把明显偏低的挑出来单独标上。再决定哪些不许进比对和存档流程。这件事越早做越便宜,等派生图生了三层再回头追就只能一张一张人工认了。上面所有数都只有三张样张、一台机器、各跑一次。没做重复。误差区间不知道。

相关推荐
Swot1 小时前
SvelteKit 数据流研究:`+page.js` 和 `+page.server.js` 到底谁在跑,数据又去了哪儿
前端·后端
用户4147679304151 小时前
Windows 触摸屏上 Swiper 轮播滑不动?可能是内部滚动容器抢走了你的手势
前端
张明君644511 小时前
从一个 Referer 引发的 403,到 SSR 服务失稳:Astro 流式渲染与缓存失效分析
前端
律宏阔1 小时前
微信小程序 + Taro + TDesign 去掉 [&&&],让普通 Tailwind 类接管局部样式
前端·微信小程序·taro
费曼学习法1 小时前
把 3 个内部服务封装成 MCP Server 的工程复盘:进程模型、超时与错误契约
前端
Captaincc1 小时前
转译:《软件工程师现在该怎么办》
前端·后端·ai编程
天才熊猫君1 小时前
给 Vue 的 reactive 套 Proxy,为什么响应式会失灵?
前端·javascript
htzyl2061 小时前
别急着上微前端:从 6 个场景倒推 Module Federation 2.0 与 qiankun 2.x 的选型
前端·微服务
verohh1 小时前
Cesium 多业务页面切换的资源隔离与架构设计:单 Viewer 复用还是多实例隔离
前端