有段时间我翻家里的旧相册看到几张上世纪的老照片长辈们还很年轻但画面里全是灰蒙蒙的——衣服灰、天灰、连脸上的笑容都像隔着雾气。当时就动了“给照片上色”的念头。一查才发现黑白照片上色这个事远不是拿画笔涂几笔那么简单照片在拍摄那刻就已经把颜色信息丢得一干二净只剩亮度我们要做的是凭借各种线索把颜色“猜”回来。这个“猜”的过程纯手工操作一张照片要几个小时用成熟的上色模型几分钟就能出一版能看的草稿。今天这篇就从原理讲到实操把我自己踩过的坑和摸索出来的流程完整写出来适合手头攒了一批老照片想复原的朋友也适合刚接触图像处理、想找个具体项目练手的人。1. 上色前先搞清楚黑白照片上色到底在解决什么问题1.1 灰度图里没有颜色上色本质是“猜”先想一个问题一张黑白照片它的每个像素只记录了一个数值也就是亮度。颜色信息由色调和饱和度组成这两个维度在拍摄瞬间就彻底丢失了靠任何算法都找不回来。所以所有上色方案的本质都是“条件概率推断”——在给定灰度图案的情况下推断最可能的颜色分布。我举个例子你就明白了豆腐和馒头在灰度图里可以一模一样都是白花花一片天空和石灰墙也可能落在同一个亮度区间。算法看到的是一堆深浅不一的灰色块它要做的是结合上下文判断“这个灰块大概率是天空天空该是蓝色”“这片区域有五官轮廓这是皮肤皮肤该是偏暖色调的”。你意识到这一点之后就会理解为什么任何上色工具都可能出错——它不是“恢复颜色”而是在“猜颜色”只是猜得准不准的差别。工程上这个“猜”的过程一般放在Lab色彩空间里做。L通道是灰度也就是我们手上有的信息a通道和b通道记录颜色。模型的套路很简单输入L通道预测a和b通道再把三个通道拼回去得到彩色图。听起来不难但同一个灰度值可以对应无数种颜色模型必须依赖上下文线索才能锁定一个合理答案这就是难点所在。1.2 为什么说上色是“图像分割 语义理解 参考迁移”早年的上色模型结构很简单就一个自编码器把灰度图压缩再还原同时预测ab通道。但这样出来的效果是颜色发糊边缘渗色严重天空和建筑物交界处经常糊成一团。后来业界逐步把这个问题拆成了三个层次来做第一层是图像分割。先把图片划分成“天空、地面、人脸、衣服、头发”等区域让模型在每个区域内部单独做色彩推断避免跨区域的颜色干扰。第二层是语义理解。模型要认出“这是一片树叶”“这是水面反光”“这是人脸”因为不同类别的物体有不同的颜色先验。树叶大概率是绿色系水面会根据环境色变化人脸肤色虽然五花八门但也集中在某个色域范围。语义理解越准颜色越靠谱。第三层是参考迁移。如果用户额外提供一张彩色照片作为参考算法会把参考图的色调风格迁移到对应区域上。比如你把一张暖调老照片的色彩风格迁到另一张图上整体氛围就能保持统一。这其实和人手动上色的思路一模一样先判断这是什么物体再决定涂什么颜色。先判断哪一步、后判断哪一步决定了最终效果的上限。你自己上手试两次就会明白越是能准确说出一张图里“有什么”最后的颜色就越自然。1.3 全自动管线 vs 人工介入两条路线怎么取舍市面上所有上色方案本质都落在“全自动”和“人工介入”两个极端之间。全自动把判断全交给模型速度快但对于颜色本身就不确定的老照片容易出现离谱的“幻觉”——比如把深色军装染成白色把国旗涂成紫色。人工介入的方案虽然费时但能把“猜”变成“确认”你告诉模型“这里是人脸肤色偏深黄”它按你的提示精修。以我个人的习惯一直是两条腿走路先用全自动模型跑一版初稿快速看到整体效果再用分区指定颜色或者手工画笔做局部修正。纯自动适合批量浏览、筛选哪些照片值得细修人工介入适合最终输出、展览级修复。明白自己手上的照片属于哪种需求再选路线能少走很多弯路。2. 工具选型三套主流上色方案怎么挑2.1 目前社区用得最多的DeOldify效果自然适合一键出图DeOldify是一套基于生成对抗网络的开源图像复原模型社区使用量非常大。它最突出的特点是色彩过渡柔和肤色、天空、树叶这些大面积区域很少出现条纹伪影而且模型自带老照片修复能力能顺带处理一部分划痕和噪点。为什么它的颜色比老模型自然关键在对抗训练。生成器在尝试上色的同时有一个判别器在挑毛病颜色敷衍、边界模糊、色块斑驳都会被视为“不合格”。生成器为了骗过判别器就必须把颜色落在正确区域、让边界锐利起来。这种对抗压力逼出来的结果观感自然比单纯自编码器好一个档次。实际使用中DeOldify对人物肖像的肤色还原相当稳定建筑、风景这类大色块区域也没有明显翻车。缺点有两个一是对“稀有物体”容易产生颜色幻觉比如特定年代的军装、特殊徽章它会按常见物体的颜色先验去填二是对显卡有要求建议6G以上显存纯CPU跑一张照片要几分钟甚至十几分钟批量处理会很痛苦。2.2 经典开源方案可控性强适合指定配色除了DeOldify还有个经典选择是某高校实验室早年发布的彩色化模型。这个方案的优势只有两个字可控。它支持在图片上手动框选区域然后指定颜色。比如你选中“天空”区域告诉它填蓝色选中“草地”告诉它填绿色。这相当于把模型从“全图盲猜”降级成“分区确认”思路和我们前面讲的人工介入逻辑完全一致。我实际测试下来这个模型的稳定性很好同一张图跑多次结果基本一致不会出现DeOldify那种“这次偏暖、下次偏冷”的波动。缺点是色彩饱和度偏低出来的图有点“灰蒙蒙”的需要导入照片编辑软件再拉一下饱和度和对比度。如果你的照片里有明显的语义区域大块天空、大片水面、整面墙壁用这个方案会非常顺手。2.3 照片编辑软件手工上色灵活度最高但门槛也高如果你追求完全可控老式的手工上色并没有过时。操作流程大概这样打开照片编辑软件在灰度图上新建图层把混合模式改成“颜色”或“叠加”然后用画笔按区域涂抹颜色配合低流量、低不透明度反复叠加用蒙版控制颜色的作用范围。这个方法一张照片动辄两三个小时但结果完全由你掌控而且配合“参考色板”可以做到非常贴近真实。说实话我平时给家里人修复照片最终版本基本都是手工精修过的——模型初版再自然放大后也总有一种“一眼AI”的塑料感尤其是人脸和手部。手工上色的本质是“用时间换确定性”适合理科基础薄弱但审美在线、愿意慢慢打磨的同学。我整理了一张方案对比表方便你快速对号入座方案上手难度单张耗时色彩自然度可控性适合场景DeOldify低分钟级高中批量预览、快速出图经典开源方案中分钟级中较高需要指定区域配色手工上色高小时级取决于操作者极高精细修复、展览级输出3. 实操过程单张老照片从上色到出图的完整流程3.1 预处理先把照片从“脏乱差”里救出来上色不是第一步修复才是。老照片的常见问题有划痕、污渍、折痕、褪色导致的对比度不足、扫描噪声。我每次的固定顺序是这样的第一步扫描分辨率建议不低于600dpi太低的话后期放大全是马赛克上色模型也更容易出错。第二步裁剪把白边和无关信息去掉避免干扰模型判断。第三步去噪和修划痕这里千万注意顺序——先修划痕再去噪因为去噪算法会把划痕边缘处理得更脏反而不利于后续修复。第四步调整灰度图对比度让主体轮廓清晰起来这一步能直接提升模型的分割准确率。如果遇到严重折痕用内容感知填充或仿制图章手工补一下。预处理的意义被很多人低估了。上色模型是拿灰度图做语义分类的图越干净判断越准。你喂进去一张满是噪点的图模型会把噪点误判成纹理然后把这些噪声区域染得五颜六色最后你还以为是模型出了问题其实是前一步偷了懒。3.2 基于DeOldify跑全自动上色DeOldify的上手方式大体有两种用官方开源的笔记本环境在云端跑或者用社区封装的桌面工具直接运行。云端跑的好处是内存分配和依赖安装都不用操心缺点是要来回传图桌面工具双击即用但版本可能滞后。两种方式我实测下来都很稳选哪种看你自己的网络条件和习惯。真正需要动手调的参数主要是render_factor。这个值控制渲染时的采样尺度数值越小采样越精细色彩过渡越细腻但耗时成倍上升。默认16就能出不错的效果。如果觉得颜色偏淡可以调到20或者22反之如果颜色浓到有“油腻感”就降到12到14。跑完初版先别急着导出要放大到100%看细节重点盯人脸、眼睛、嘴唇肤色模型经常在这几个位置翻车。有个小细节值得留意DeOldify默认输出的色彩空间可能不是sRGB直接拿到浏览器或手机上看会偏色。我习惯在导出设置里确认色彩空间转成sRGB再保存避免“自己看挺好发给别人颜色不对”的尴尬。3.3 局部精修用分割和参考色修肤色模型跑出来的初稿人脸往往是重灾区——肤色偏橘、眼睛变色、嘴巴边缘发虚。这种情况下用带交互分割的上色工具做局部精修是最有效的。操作流程大致分四步第一步用分割功能把照片自动切成人脸、衣服、背景等区域。第二步单独选中“人脸”区域给它指定一个参考肤色。我一般以RGB230, 180, 160这个偏自然黄种人肤色作为起点再根据照片拍摄年代做微调。第三步处理衣服和背景用参考图或手动调色板指定颜色。第四步观察区域边界如果颜色渗出到相邻区域用画笔在蒙版上修掉。这一步的原理就是把我前面说的“全图盲猜”变成“分区确认”。模型在每个区域内只处理色相变化难度大大降低边界也不容易渗色。你可以把它理解成辅导孩子做作业直接扔一整张卷子他容易蒙你帮他圈出每道题的类型他答对的概率就高得多。3.4 质量检测与导出别在最后一步翻车上色完成后不要直接存jpg了事。我的固定流程是先展开图层检查有没有颜色溢出到相邻区域再用自然肤色色板对比一下人脸的色值偏色严重的就拉回来然后检查有没有模型幻觉导致的诡异色块比如紫色的舌头、蓝色的牙齿这些在黑白老照片里尤其常见因为模型少见了牙齿和舌头的彩色样本。最后导出时如果后期还要继续修建议导出PNG或TIFF无损格式如果只是分享到社交平台jpg质量设90以上就够png体积太大反而没必要。导出前记得把色彩空间转成sRGB这一步很多人忽略结果在手机、电脑、朋友圈三个地方看到三个颜色。4. 上色实操经验与踩坑记录这些坑我替你踩过了4.1 人脸肤色最容易翻车的区域人脸是上色任务里翻车概率最高的区域没有之一。我踩过的坑可以列出一串。最常见的是模型把苍白肤色染成橘红色原因是模型在低分辨率下把人脸误判成了强光下的“柿子色”解决方法是分区上色重新指定肤色或者把render_factor调低重新渲染。第二常见的是眼睛被染成蓝色或绿色像西方人的瞳色——但老照片里的亚洲面孔眼睛默认应该是深棕或黑色遇到染蓝的直接用画笔在“颜色”模式下覆盖即可。第三类坑比较隐蔽就是肤色过亮。很多模型默认人脸是高光的出来的肤色白得发飘像一个瓷娃娃。我遇到这种情况一般把肤色参考调暗一档RGB约200, 150, 130看上去反而自然。记住一个规律老照片的胶卷对肤色表达偏黄偏暖模型输出往往偏粉偏亮手动向“黄暗”方向修正基本不会错。4.2 天空、水面、植物的“颜色污染”大色块物体之间的边界是第二高发翻车区。天空和植物之间如果有锐利边界颜色很容易互相“渗”。水面最麻烦因为它反射的是环境色模型经常把它染成纯蓝色但实际老照片里的水面可能是灰绿色也可能是偏黄的浊色完全取决于拍摄环境。我处理水面的固定套路是选中水面区域、填充中性灰、再叠加一层冷色调。这样既保留了水面该有的反射感又不会像模型那样一口咬定“水面蓝色”。植物的绿色偏青还是偏黄跟胶卷型号、保存条件、褪色程度都有关系我一般参考同一卷胶卷里其他彩色照片的色调来定而不是上来就涂一片浓绿。4.3 噪点带来的颜色闪烁老照片扫描后往往有大量颗粒噪点上色模型会把这种颗粒放大导致上色后整个画面像撒了一层彩色雪花。这种情况的处理手段分两步上色前先做一次适度降噪但别降太狠否则文字、纽扣、头发丝等细节会糊掉上色后如果还有噪点用降噪类功能针对“颜色噪点”通道单独处理不动亮度通道。这样一来细节还在颜色也干净了相当于把噪点里的颜色信息抽离而不是整个磨皮。4.4 批量照片的时间成本控制如果手里不是一张老照片而是一整本相册每张都精修不现实。我自己是按三批处理的。第一批预览级全自动模型跑一遍快速筛出哪些照片值得细修第二批精修级对值得修复的照片逐张做预处理、上色、手工修正第三批归档级统一调整色调、导出、备份。时间成本大概是纯自动每张3到5分钟含预处理精修级每张20分钟到1小时不等取决于照片“病情”严重程度。批量场景下先出预览稿再决定投入时间这个顺序不要反过来。5. 常见问题速查表症状可能原因解决方案颜色边缘虚化、渗色渲染分辨率过低调低render_factor重新渲染人脸偏橘或偏青模型肤色判断失误分区指定肤色或手动画笔覆盖天空出现条纹压缩伪影被放大预处理阶段先修划痕再上色输出颜色发灰色彩空间转换错误导出时确认sRGB色彩空间衣服被染成怪异颜色罕见物体颜色先验不足手动指定区域颜色或用参考图噪点变成彩色雪花上色前未降噪先降噪再上色或单独去除颜色噪点跑一张图特别慢显存不足或CPU渲染降低输入分辨率或改用云端环境最后再分享一个小技巧处理拍摄于上世纪五六十年代之前的老照片尽量不要拿现代照片作为参考色。那个年代的胶卷颜色普遍偏暖、饱和度偏低直接把现代标准色板套上去出来的效果会非常“塑料”。我自己常备几组“年代色板”——不同时代分别对应偏黄的肤色、偏青的绿色、偏灰的蓝色手动精修的时候用这些色板约束模型的输出整体氛围一下就对了。记住上色这件事技术决定下限审美决定上限而审美恰恰藏在那些细节里。