Python實戰(zhàn):從源碼環(huán)境到參數(shù)調(diào)優(yōu))
簡介面向圖像處理學(xué)習(xí)者和開發(fā)者的GFPGAN老照片修復(fù)Python源碼工程以泛用性人臉先驗引導(dǎo)修復(fù)網(wǎng)絡(luò)為核心結(jié)合GAN生成對抗機制增強人臉細節(jié)可用于老照片人像修復(fù)、畫面清晰度恢復(fù)等場景。壓縮包共51個文件、約6.09MB包含21個Python腳本、7個YAML配置文件、6個PNG與2個JPG樣例圖、2個Markdown文檔以及2個MDB數(shù)據(jù)庫文件等。Python腳本覆蓋推理、訓(xùn)練與網(wǎng)絡(luò)結(jié)構(gòu)實現(xiàn)涉及gfpganv1_clean_arch、stylegan2_clean_arch、arcface_arch等核心模塊YAML用于參數(shù)配置與數(shù)據(jù)集說明圖片提供修復(fù)前后對比效果工程內(nèi)還附帶pth模型權(quán)重、VERSION版本文件與license許可說明。項目另含CI工作流、代碼規(guī)范及PaperModel論文筆記目錄劃分清晰便于二次開發(fā)與算法復(fù)現(xiàn)。已有491人學(xué)習(xí)瀏覽適合具備Python和深度學(xué)習(xí)基礎(chǔ)、想快速上手人臉修復(fù)算法的開發(fā)者。1. 老照片修復(fù)為什么繞不開GFPGAN從現(xiàn)實需求到源碼設(shè)計的起點如果你手頭有一批褪色、有折痕的人臉老照片又不滿足于美圖秀秀那種全局調(diào)色那基于GFPGAN算法的Python老照片修復(fù)設(shè)計源碼這條路值得認真走一遍。GFPGANGenerative Facial Prior GAN是目前把“人臉先驗”融入GAN修復(fù)的代表方案它專門解決人臉區(qū)域反復(fù)重繪出奇怪五官的痛點比起直接拿通用超分模型去修修復(fù)結(jié)果更接近“原來的那個人”。這篇文章我來拆一個可直接運行的老照片修復(fù)項目源碼從環(huán)境配置、模型加載到參數(shù)調(diào)優(yōu)和排錯都按我實際踩坑的經(jīng)驗寫。適合正在做圖像修復(fù)項目的Python開發(fā)者、AI應(yīng)用工程師以及想自己動手修復(fù)全家福老照片的玩家。2. 從零搭一個GFPGAN項目目錄設(shè)計與環(huán)境準備2.1 項目目錄設(shè)計與文件職責(zé)老照片修復(fù)項目看著就一個推理腳本真做起來遠不是“裝個庫、跑一段代碼”那么簡單。模型權(quán)重放在哪、輸入輸出怎么組織、日志寫到哪里、后續(xù)要不要接批量處理這些都得在動手前定好。我一般會搭一個這樣的目錄old_photo_fix/ ├── main.py # 命令行入口支持文件或目錄輸入 ├── requirements.txt # 依賴清單 ├── weights/ │ └── GFPGANv1.4.pth # 預(yù)訓(xùn)練人臉修復(fù)模型 ├── inputs/ # 待修復(fù)的老照片 ├── outputs/ # 修復(fù)結(jié)果輸出目錄 ├── utils/ │ ├── __init__.py │ ├── io_utils.py # 圖片讀寫、路徑校驗 │ └── face_align.py # 人臉檢測輔助可選 └── configs/ └── fix_config.yaml # 參數(shù)配置方便調(diào)參不動代碼為什么要單獨建weights/和configs/因為 GFPGAN 的模型文件在 GitHub Release 和 Hugging Face 上都能找到但不同渠道下載的文件名可能帶后綴大小也可能不一致。固定放在weights/目錄并統(tǒng)一命名為GFPGANv1.4.pth代碼里就只需要維護一個路徑變量不會出現(xiàn)“測試時能跑、換臺機器就跑不了”的尷尬。configs/則把 upscale、strength 這類參數(shù)從代碼里剝離出去后面做參數(shù)掃描時不用反復(fù)改 main.py。2.2 Python 環(huán)境安裝與依賴要求GFPGAN 依賴 PyTorch 和它配套的人臉工具庫官方推理用的是gfpgan包 realesrgan做背景增強。我的環(huán)境踩過幾輪坑最省事的一組命令是conda create -n gfpgan python3.8 -y conda activate gfpgan pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install gfpgan realesrgan opencv-python第一行創(chuàng)建 Python 3.8 環(huán)境不是越新越好GFPGAN 的有些依賴特別是 facexlib在 Python 3.11 上偶爾會因為 setuptools 兼容問題報錯3.8 最穩(wěn)。第二行裝 PyTorchcu118是 CUDA 11.8 版本如果你的顯卡驅(qū)動只支持 CUDA 10.2這里要改成cu102否則導(dǎo)入 torch 時會報libcusparse.so找不到。第三行裝人臉修復(fù)主力庫opencv-python建議裝 4.5.4 之后的新版本老版本配合gfpgan偶爾會出現(xiàn)在cv2.rectangle里畫不出框的詭異問題。裝完后先別急著跑把facexlib也要確認一下它是人臉檢測的后端依賴。gfpgan庫在 pip install 時通常會拉進來但如果你用的是精簡版 Python 鏡像可能缺少可以手動補一條pip install facexlib。檢查環(huán)境用python -c import gfpgan; print(gfpgan.__version__)能正常打印就不是環(huán)境問題。2.3 獲取預(yù)訓(xùn)練模型權(quán)重放置與校驗GFPGAN 的模型文件是一個很大的.pth文件很多老照片修復(fù)教程都會讓你去下載但不告訴你下載完怎么確認文件沒壞。我建議加一道校驗邏輯避免修復(fù)到一半發(fā)現(xiàn)模型損壞白等幾分鐘。import os model_path weights/GFPGANv1.4.pth if not os.path.exists(model_path): raise FileNotFoundError( 模型缺失請把 GFPGANv1.4.pth 放到 weights/ 目錄 ) file_size os.path.getsize(model_path) if file_size 100 * 1024 * 1024: # 100MB 只是第一道門檻 raise ValueError( f模型文件異常大小只有 {file_size / 1024 / 1024:.1f}MB 很可能下載斷點完成請重新下載完整文件 ) print(f模型文件通過基礎(chǔ)校驗大小為 {file_size / 1024 / 1024:.1f}MB)這段邏輯放在 main.py 的最前面比直接跑模型更實在。GFPGANv1.4.pth的實際體積在 300MB 以上如果只有幾 MB 或幾十 MB基本就是下載不完整。用文件大小做第一道校驗好處是簡單明了不用維護繁瑣的哈希表但對追求嚴謹?shù)墓こ袒椖拷ㄗh拿到文件后用官方提供的 SHA256 再算一遍這里就不展開哈希腳本了。3. 核心推理代碼逐段拆解修復(fù)一張老照片的最小可運行實現(xiàn)3.1 先寫 main.py解析參數(shù)與輸入校驗老照片修復(fù)的推理鏈路很清晰讀圖 → 人臉檢測 → GFPGAN 增強人臉 → 貼回原圖 → 保存。但每一環(huán)都有參數(shù)干擾命令行設(shè)計做不好調(diào)參就會變成反復(fù)改代碼。我的做法是把變動最多的參數(shù)全部提到argparse里。import argparse def parse_args(): parser argparse.ArgumentParser(descriptionGFPGAN老照片修復(fù)) parser.add_argument(--input, typestr, requiredTrue, help輸入圖片路徑或包含多張圖片的目錄) parser.add_argument(--output, typestr, defaultoutputs, help修復(fù)結(jié)果存放目錄) parser.add_argument(--model_path, typestr, defaultweights/GFPGANv1.4.pth, helpGFPGAN權(quán)重路徑) parser.add_argument(--upscale, typefloat, default2, help放大倍率建議2老照片不宜過大) parser.add_argument(--strength, typefloat, default0.6, help修復(fù)強度0到1越高人臉重繪越激進) parser.add_argument(--face_size, typeint, default512, help送入GFPGAN的人臉對齊尺寸) return parser.parse_args()這段代碼的用意是把“修復(fù)成什么樣”的控制權(quán)交給使用者。--input是必填參數(shù)支持單張圖片或整個目錄這一點直接決定了腳本能否批量處理一卷老照片。--upscale默認 2 而不是 4是因為老照片本身分辨率低、噪聲多強行放大 4 倍會讓背景區(qū)域的 JPEG 塊狀感更明顯。--face_size是很多人容易忽略的參數(shù)它控制檢測到的人臉區(qū)域會被放大到多大再送入網(wǎng)絡(luò)512 是 GFPGAN v1.4 的推薦值太小會丟失細節(jié)太大容易出現(xiàn)“看圖猜臉”的幻覺。有了參數(shù)解析main.py 的核心入口只需要四行解析參數(shù) → 校驗?zāi)P?→ 初始化修復(fù)器 → 批量處理。我習(xí)慣把初始化單獨拆一個函數(shù)方便后面做 Web 接口時復(fù)用。3.2 初始化 GFPGAN 修復(fù)器關(guān)鍵參數(shù)的含義GFPGAN 的GFPGANer類是所有神經(jīng)網(wǎng)絡(luò)黑盒子的封裝點初始化參數(shù)決定了用哪一版模型、放大幾倍、要不要額外做背景增強。import torch from gfpgan import GFPGANer def init_restorer(args): if not torch.cuda.is_available(): print(警告當(dāng)前沒有可用GPUCPU推理速度會非常慢) restorer GFPGANer( model_pathargs.model_path, upscaleargs.upscale, archclean, # v1.4模型對應(yīng) clean 架構(gòu) channel_multiplier2, # 通道數(shù)系數(shù)v1.4固定為2 bg_upsamplerNone, # 背景增強器None表示不做 ) return restorer這里的archclean是最容易翻車的地方。GFPGAN 早期版本的模型用的是original架構(gòu)v1.4 之后官方把生成器改成clean架構(gòu)兩者的網(wǎng)絡(luò)層配置不一樣。你如果拿 v1.4 的權(quán)重去配archoriginal會直接報state_dict加載失敗。channel_multiplier也是同理v1.4 模型的通道系數(shù)是 2如果誤寫成 1雖然能加載但輸出圖片會有一層灰蒙蒙的偽影。bg_upsamplerNone在本階段是最可控的選擇。它不增強背景部分只處理和貼回人臉區(qū)域避免把背景里的顆粒噪聲也放大。如果你想連背景一起修復(fù)后面會講到怎么接realesrgan但代價是單張圖片的耗時至少翻倍。3.3 修復(fù)單張圖片預(yù)處理與后處理如果把插件的所有花哨功能拋掉核心的單圖修復(fù)代碼就下面這些但它解決了一個非常隱蔽的問題輸入輸出圖像的通道順序。import cv2 def fix_one(restorer, img_path, strength0.6): 修復(fù)單張老照片返回修復(fù)后的BGR圖像 img cv2.imread(img_path, cv2.IMREAD_COLOR) if img is None: raise ValueError(f無法讀取圖片: {img_path}) # 記錄原圖尺寸后面檢查修復(fù)結(jié)果尺寸是否有變化 h, w img.shape[:2] # enhance返回三個對象裁剪臉、恢復(fù)臉、最終貼回圖 _, _, restored restorer.enhance( img, has_alignedFalse, only_center_faceFalse, paste_backTrue, weightstrength, ) if restored is None: print(f注意{img_path} 未檢測到人臉返回原圖) restored img return restoredenhance是 GFPGAN 的推理入口內(nèi)部的流程是先用 RetinaFace 檢測人臉把檢測到的人臉裁剪、對齊、縮放到模型輸入尺寸然后跑一次生成器得到修復(fù)后的人臉最后根據(jù)paste_back參數(shù)決定要不要把修復(fù)臉貼回原圖的對應(yīng)位置。這里的關(guān)鍵是weight參數(shù)它控制生成器的輸出占比相當(dāng)于一個人工“復(fù)原程度”旋鈕。has_alignedFalse表示輸入的是普通照片需要內(nèi)部重新檢測對齊如果你自己已經(jīng)裁剪過只有人臉區(qū)域的圖可以傳True跳過檢測速度更快但必須保證人臉已經(jīng)對齊且居中。paste_backTrue是必須開的特別是在老照片中背景的折痕和噪點如果也被生成器處理會丟失大量原始質(zhì)感開這個參數(shù)才能只換臉、留背景。注意返回值有三個我們只取第三個restored。前兩個分別是裁剪出的人臉和獨立修復(fù)后的人臉?biāo)鼈冇糜谡{(diào)試和人臉對比普通修復(fù)流程用不上。restored是完整的輸出圖像通道順序是 BGR直接用cv2.imwrite保存不會偏色。3.4 批量循環(huán)與文件保存實際拿回家整理老照片不可能一張一張敲命令。我一般會讓腳本自動掃描目錄下所有圖片并給輸出文件加上參數(shù)后綴避免同一張照片用不同參數(shù)修了兩遍后互相覆蓋。import os def batch_fix(restorer, input_path, output_dir, strength): os.makedirs(output_dir, exist_okTrue) if os.path.isfile(input_path): files [input_path] else: files [ os.path.join(input_path, f) for f in os.listdir(input_path) if f.lower().endswith((.jpg, .jpeg, .png, .bmp)) ] if not files: raise ValueError(f輸入目錄中沒有找到圖片: {input_path}) for idx, file_path in enumerate(files): try: restored fix_one(restorer, file_path, strength) base os.path.splitext(os.path.basename(file_path))[0] out_name f{base}_gfpgan_s{strength}.png out_path os.path.join(output_dir, out_name) cv2.imwrite(out_path, restored) print(f[{idx 1}/{len(files)}] 完成: {out_path}) except Exception as e: print(f處理 {file_path} 出錯: {e})批量循環(huán)里最值得注意的有兩個點。第一輸出固定用 PNG 格式因為老照片修復(fù)后的圖片包含更多過渡色階JPG 壓縮會在邊緣引入新的振鈴噪聲PNG 是無損壓縮適合做中間結(jié)果。第二每個文件的處理都包了一層try/except這不是為了掩蓋錯誤而是防止批量任務(wù)運行到一半因為單張損壞圖片中斷導(dǎo)致后面前功盡棄。批處理最忌“單張失敗、全盤停擺”。4. 修復(fù)效果調(diào)優(yōu)的五個必調(diào)參數(shù)讓老照片從能用到可用4.1 upscale放大倍率與老照片分辨率的匹配--upscale控制最終輸出相對原圖放大的倍數(shù)默認 2很多人一上來就拉到 4。如果你修的是幾百像素的證件照4 倍有意義但大部分老照片是掃描件分辨率少說有兩三千像素再放大 4 倍不僅慢還會把背景里的紙張紋理放大成“磨砂濾鏡”。我的建議對 1500 像素以上的圖先用 2 倍看效果對 500 像素以下的縮略圖可以上 4 倍。調(diào)這個參數(shù)不需要重新訓(xùn)練模型直接改命令行參數(shù)即可。4.2 strength修復(fù)強度如何避免“網(wǎng)紅AI臉”strength是 enhance 函數(shù)里的weight值的范圍是 0 到 1。0 表示完全不用生成器只保留原圖1 表示完全用生成器重建人臉。很多老照片修復(fù)教程會默認 0.5 到 0.8但現(xiàn)實中修自家掃描的老照片0.6 已經(jīng)會讓原來有特征的國字臉變成窄下巴的“AI 網(wǎng)紅臉”。# 參數(shù)掃描同一張圖讓strength在0.3~0.8之間出多張結(jié)果 for strength in [0.3, 0.5, 0.6, 0.8]: _, _, restored restorer.enhance( img, has_alignedFalse, only_center_faceFalse, paste_backTrue, weightstrength, ) cv2.imwrite(fretry_s{strength}.png, restored)這段掃描代碼是調(diào)參的“后悔藥”。把同一張照片用 4 個強度各跑一遍用照片查看器標(biāo)清序號肉眼對比哪張最像原圖里的親人。我自己的經(jīng)驗是折痕和污點嚴重的圖0.8 能把污點徹底清掉但會丟掉膚質(zhì)紋理只想去噪、保真0.4 足夠。strength沒有最優(yōu)值它取決于你對“像不像本人”的容忍程度。4.3 face_size人臉對齊尺寸與細節(jié)量GFPGANer內(nèi)部會把檢測到的人臉區(qū)域裁剪后縮放到face_size × face_size再送入生成器。face_size越大生成器看到的細節(jié)越多但前提是裁剪出來的人臉區(qū)域本身清晰。老照片人臉通常只有兩三百像素硬放大到 1024 反而會讓生成器“腦補”出并不存在的皮膚毛孔出現(xiàn)磨皮過度的塑料感。用 512 就夠了這是 GFPGAN 官方推理腳本的默認語義。如果你發(fā)現(xiàn)修復(fù)后眼睛經(jīng)常變成“熊貓眼”把face_size從 512 降到 384 往往能改善。4.4 bg_upsampler要不要開啟背景增強bg_upsampler參數(shù)在初始化時傳入最常見的是傳入realesrgan的 RealESRGANer 實例。開了之后背景區(qū)域也會被超分增強整張照片看起來更清晰。但這個參數(shù)有代價單張圖的推理時間從 2 秒變成 8 秒以上GPU 上而且對滿是噪聲的老照片背景超分算法會把噪點當(dāng)成細節(jié)來強化結(jié)果產(chǎn)生密密麻麻的偽細節(jié)。我一般只在人臉占畫面比例超過三分之一、且背景本身相對干凈的照片上開bg_upsampler。如果只是想快速給全家人看效果保持None是更穩(wěn)的起點。4.5 only_center_face多人合影時的選擇與風(fēng)險GFPGAN 默認會檢測并修復(fù)照片里的所有人臉。但在多人合影里邊緣的人臉經(jīng)常被鼻子、手部遮擋檢測器會漏檢或誤檢反而留下一張沒處理的臉在旁邊對比感很差。把enhance的only_center_faceTrue打開后只處理畫面中心最大的人臉適合單人照偏多的場景。python main.py --input inputs/1978_family.png --output outputs --strength 0.5 --upscale 2如果遇到多人合影建議先跑一次默認參數(shù)然后看輸出圖里漏了哪張臉。漏臉時就只能用更精細的折疊方法先裁剪出每個單人臉區(qū)域分別修復(fù)再拼回去。這個方案確實麻煩但對大合照來說比修正單個整圖參數(shù)更可靠。但注意only_center_faceTrue對只有一個人的老照片沒有任何副作用可以放心用。5. GFPGAN常見問題排查四種最容易翻車的場景及對策5.1 現(xiàn)象修復(fù)后的人臉五官變形嚴重原因strength設(shè)得過高生成器把原圖人臉特征當(dāng)噪聲丟掉直接按照“平均臉”重建了一個新臉或者face_size設(shè)置過大導(dǎo)致人臉區(qū)域被過度放大后局部特征失真。解決先把strength降到 0.4 重新跑同一張圖觀察眼睛距離、顴骨輪廓是否接近原圖。如果還變形把face_size從默認 512 改為 384。我在修 1970 年代黑白照片時發(fā)現(xiàn)這種照片的掃描圖人臉通常只有 200 到 300 像素512 的輸入其實是在強行補一個不存在的清晰度所以調(diào)低face_size反而更安全。5.2 現(xiàn)象輸出圖的顏色與原圖差異很大偏紅或偏青原因GFPGAN 內(nèi)部處理的是 BGR 圖像但在調(diào)試時很多人習(xí)慣用 matplotlib 或 PIL 顯示。如果你用 PIL 的Image.fromarray(restored)直接展示PIL 會默認把 BGR 數(shù)組當(dāng)成 RGB于是人臉就偏藍。另外老照片本身有嚴重的泛黃調(diào)性修復(fù)后的皮膚色更粉嫩視覺上會覺得顏色“不對”。解決顯示時先做一次通道轉(zhuǎn)換cv2.cvtColor(restored, cv2.COLOR_BGR2RGB)。保存時不要轉(zhuǎn)直接用cv2.imwrite寫 BGR 原數(shù)組這樣得到的 PNG 用看圖軟件打開顏色是正常的。如果確認通道沒寫錯還是偏色那就是白平衡問題可先用cv2.xphoto.createSimpleWB()對原圖做一次白平衡再送入修復(fù)但這屬于高級調(diào)參先用通道問題排查。5.3 現(xiàn)象批量修復(fù)時內(nèi)存溢出或速度越來越慢原因輸入圖片分辨率過大。掃描儀導(dǎo)出的老照片動輒 6000×9000 像素GFPGANer會先把整張圖讀進內(nèi)存做人臉檢測批量任務(wù)中一張大圖就能占滿 8GB 顯存。如果開了upscale4顯存占用更是成倍增長。解決在送入enhance之前先把圖片最長邊限制到 2000 像素修復(fù)完成后再用傳統(tǒng)插值放大到所需尺寸這樣模型只需處理一個合適的分辨率。MAX_EDGE 2000 img cv2.imread(path) h, w img.shape[:2] scale min(1.0, MAX_EDGE / max(h, w)) if scale 1.0: img cv2.resize(img, (int(w * scale), int(h * scale)), interpolationcv2.INTER_AREA)這段代碼里的INTER_AREA是下采樣時最常用的插值方式能減少摩爾紋。批量任務(wù)前先統(tǒng)計所有圖的最長邊把超大圖統(tǒng)一壓到 2000 內(nèi)速度問題基本就能解決。5.4 現(xiàn)象人臉沒有被檢測到代碼直接返回原圖原因一張老照片里人臉區(qū)域太小、太糊或者人臉是側(cè)臉、低頭姿勢。RetinaFace 檢測器對“正臉且高度大于 32 像素”的目標(biāo)比較敏感而為掃描壓縮后的老照片人臉寬度常常不足 50 像素檢測器直接漏過。解決不要急著調(diào) GFPGAN 參數(shù)先把原圖放大 2 倍再跑修復(fù)同時對側(cè)臉照片做一次 90° 旋轉(zhuǎn)再試。如果放大后仍檢測不到可以用facexlib底層的檢測器畫出人臉框確認框的位置再決定是不是要把圖片局部裁剪后單獨修。6. 把修復(fù)從腳本變成工具Web調(diào)用與接口封裝的小技巧6.1 用 Flask 封裝一個修復(fù)接口如果只是自己修幾張照片命令行腳本已經(jīng)夠用。一旦要讓不懂 Python 的家人使用或者接入一個小程序后臺就得把它封裝成 HTTP 接口。我一般用 Flask 寫一個最小可用的服務(wù)import io import numpy as np from flask import Flask, request, send_file app Flask(__name__) restorer None def init_global_restorer(model_path): global restorer if restorer is None: restorer init_restorer(model_path) return restorer app.route(/fix, methods[POST]) def fix_image(): photo request.files.get(photo) if photo is None: return {error: 缺少 photo 文件}, 400 img_bytes photo.read() img_array np.frombuffer(img_bytes, np.uint8) img cv2.imdecode(img_array, cv2.IMREAD_COLOR) _, _, restored restorer.enhance( img, has_alignedFalse, only_center_faceFalse, paste_backTrue, weight0.6, ) ok, buffer cv2.imencode(.png, restored) if not ok: return {error: 圖像編碼失敗}, 500 return send_file(io.BytesIO(buffer.tobytes()), mimetypeimage/png, download_namerestored.png)接口里的restorer必須用全局變量持有不要在每次請求時初始化。GFPGAN 的模型加載需要讀入 300MB 權(quán)重單次初始化要花 5 到 10 秒如果每個請求都重新加載一次服務(wù)根本沒法用。cv2.imdecode能把上傳的字節(jié)流直接解碼成圖像數(shù)組比先保存臨時文件再讀取要干凈得多。實際部署時建議在服務(wù)啟動前先調(diào)用一次init_global_restorer做預(yù)熱再對外提供服務(wù)。6.2 兩個驗證技巧先看局部貼臉再算定量指標(biāo)封裝完成后不能只靠用戶說“好像變年輕了”來驗收。老照片修復(fù)沒有真實的高清參考圖所以我的習(xí)慣是先做局部驗證用facexlib檢測出人臉框把修復(fù)前后的兩張圖的同一區(qū)域放大到 200%對比眼角紋理和牙齒輪廓。如果人臉輪廓與原圖一對比差太多說明strength還是太高。定量方面可以算 PSNR但因為處理和原圖不是同一分辨率直接算 PSNR 沒有參考意義。更實用的是把修復(fù)結(jié)果重新壓縮成 JPG再和原圖做結(jié)構(gòu)相似度 SSIM雖然不能用來證明“修得好”至少能衡量本次修復(fù)是否保留了原始構(gòu)圖結(jié)構(gòu)。我自己在項目里加了一個--compare參數(shù)輸出修復(fù)圖和原圖的 SSIM 值低于 0.6 就提示人工復(fù)核。6.3 保留 EXIF 與時間戳給修復(fù)留一份后悔藥最后一個小技巧老照片掃描件可能帶了拍攝時間和掃描參數(shù)等 EXIF 信息而 GFPGAN 輸出圖像不會自動保留。我建議在保存時從原圖讀取 EXIF 寫入輸出文件或者至少把原始文件名、修復(fù)參數(shù)寫進一個manifest.csv。這樣三個月后想換一套參數(shù)重新修復(fù)還能知道上次用的是什么strength不用靠記憶猜。我在一次給客戶做批量老照片修復(fù)時就是因為忘了記錄參數(shù)發(fā)現(xiàn)同一張圖被兩個批次用不同強度處理交給客戶時新老照片分不清最后只好重跑全部批次。從那以后每張輸出圖的名字里都帶上了s和up參數(shù)這也成了我的固定習(xí)慣。這個方案并不復(fù)雜但它能讓你以后翻看結(jié)果時少走很多彎路。希望幫到你。本文還有配套的精品資源點擊獲取