UNet输出结果自动保存,再也不怕丢图了
你是不是也经历过这样的崩溃时刻:辛辛苦苦调好参数,等了5秒生成一张融合效果惊艳的人脸图,刚想右键保存——页面刷新了?浏览器卡死了?或者一不小心点到了其他标签页?结果融合结果消失得无影无踪,连历史记录都找不到……更糟的是,WebUI界面根本没提供“一键下载全部”或“自动归档”功能,每次都要手动右键→另存为→选路径→确认,重复十次就手酸。
别再靠运气保存图片了。这篇实操指南,不讲原理、不堆参数,只聚焦一个工程师最真实的需求:让UNet人脸融合的结果稳稳落盘,一次生成,永久可查,彻底告别“刚生成就丢失”的焦虑。我们基于科哥开发的unet image Face Fusion人脸融合人脸合成镜像(WebUI版),从底层文件结构出发,手把手教你三套落地方案:一是修改默认保存路径实现集中管理;二是编写轻量脚本自动监听并归档新图;三是扩展WebUI按钮,一键触发本地+云端双备份。所有操作均在镜像内完成,无需重装、不改模型、不碰CUDA配置,10分钟即可生效。
1. 先搞清:UNet融合结果到底存在哪?
很多用户以为“图片显示在网页上,就一定在浏览器缓存里”,这是最大误区。实际上,Face Fusion WebUI 的输出行为是明确分离的:前端展示用临时内存流,后端落盘走固定目录。而这个“固定目录”,正是我们自动化保存的起点。
1.1 默认输出路径定位
进入容器终端(或SSH登录服务器),执行:
find /root -name "outputs" -type d 2>/dev/null你会看到类似输出:
/root/cv_unet-image-face-fusion_damo/outputs这就是科哥镜像中UNet融合结果的默认根目录。进一步查看其子结构:
ls -la /root/cv_unet-image-face-fusion_damo/outputs/典型输出如下:
total 12 drwxr-xr-x 3 root root 4096 Jan 5 14:22 . drwxr-xr-x 8 root root 4096 Jan 5 14:22 .. drwxr-xr-x 2 root root 4096 Jan 5 14:22 2026-01-05注意:2026-01-05是按日期自动生成的子目录,每次融合结果都会写入当天文件夹,文件名形如face_fusion_20260105_142233.png(含时间戳)。这说明系统已具备基础的时间组织能力,但缺乏统一入口和防覆盖机制。
1.2 关键发现:保存逻辑藏在Python源码里
打开核心脚本:
nano /root/cv_unet-image-face-fusion_damo/app.py搜索关键词save或outputs,定位到关键函数(通常在process_face_fusion或run_inference附近):
def save_result(image, base_dir="/root/cv_unet-image-face-fusion_damo/outputs"): os.makedirs(base_dir, exist_ok=True) timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") filename = f"face_fusion_{timestamp}.png" filepath = os.path.join(base_dir, filename) image.save(filepath) return filepath结论清晰:
- 所有融合结果均由该函数统一写入磁盘;
base_dir是硬编码路径,修改此处即可全局生效;- 文件名含精确时间戳,天然避免覆盖;
- 但当前未做权限加固、无失败重试、无格式校验。
小贴士:不要直接改
app.py!我们采用更安全的“配置外挂”方式,既保留原生逻辑,又实现路径定制。
2. 方案一:安全替换默认路径(推荐新手)
不改代码、不重启服务,仅通过环境变量接管输出路径。这是最稳妥、可逆性最强的方案。
2.1 创建专用存储区
新建一个带读写权限、独立于系统盘的目录(防止/root空间满导致融合失败):
mkdir -p /data/face_fusion_outputs chown -R root:root /data/face_fusion_outputs chmod 755 /data/face_fusion_outputs优势:
/data通常是挂载的大容量盘,且与系统隔离,安全性高。
2.2 注入环境变量接管路径
编辑镜像启动脚本/root/run.sh:
nano /root/run.sh找到类似python app.py的启动命令行,在其上方新增一行:
export FACE_FUSION_OUTPUT_DIR="/data/face_fusion_outputs"完整示例如下:
#!/bin/bash export FACE_FUSION_OUTPUT_DIR="/data/face_fusion_outputs" cd /root/cv_unet-image-face-fusion_damo gradio app.py --server-name 0.0.0.0 --server-port 78602.3 修改Python代码适配环境变量
打开app.py,找到save_result函数,将其改为:
import os from datetime import datetime def save_result(image, base_dir=None): if base_dir is None: base_dir = os.environ.get("FACE_FUSION_OUTPUT_DIR", "/root/cv_unet-image-face-fusion_damo/outputs") # 按日期创建子目录(保持原有逻辑) date_str = datetime.now().strftime("%Y-%m-%d") full_dir = os.path.join(base_dir, date_str) os.makedirs(full_dir, exist_ok=True) timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") filename = f"face_fusion_{timestamp}.png" filepath = os.path.join(full_dir, filename) # 增加容错:检查磁盘空间 & 写入权限 try: if not os.access(full_dir, os.W_OK): raise PermissionError(f"No write permission to {full_dir}") free_space = shutil.disk_usage(full_dir).free if free_space < 100 * 1024 * 1024: # 小于100MB报警 raise OSError(f"Low disk space in {full_dir}: {free_space} bytes left") image.save(filepath) return filepath except Exception as e: print(f"[ERROR] Failed to save result: {e}") # 降级保存到原路径 fallback_dir = "/root/cv_unet-image-face-fusion_damo/outputs" os.makedirs(fallback_dir, exist_ok=True) fallback_path = os.path.join(fallback_dir, f"fallback_{timestamp}.png") image.save(fallback_path) return fallback_path注意:需在文件顶部添加import shutil。
2.4 重启服务验证
/bin/bash /root/run.sh访问http://localhost:7860,执行一次融合。然后检查:
ls -lt /data/face_fusion_outputs/$(date +%Y-%m-%d)/你会看到新生成的PNG文件,且时间戳与WebUI显示的处理时间一致。此时,所有后续融合结果将自动落入/data目录,彻底脱离/root的空间风险与权限隐患。
3. 方案二:自动归档脚本(解决“忘记下载”痛点)
即使路径改了,仍可能遇到“生成了但没及时下载,过几天清理磁盘时误删”的情况。本方案用一个常驻脚本,实时监控输出目录,自动将新图复制到带分类标签的归档区,并生成简易索引页。
3.1 构建归档目录结构
mkdir -p /archive/face_fusion/{by_date,by_person,latest} touch /archive/face_fusion/index.htmlby_date/:按YYYY-MM-DD存原始文件(与UNet默认一致)by_person/:人工标记后存放(如张三_会议照.png)latest/:软链接指向最新生成图,方便快速访问
3.2 编写监控脚本auto_archive.py
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import time import os import shutil import glob from datetime import datetime OUTPUT_ROOT = "/data/face_fusion_outputs" ARCHIVE_ROOT = "/archive/face_fusion" def get_latest_files(directory, pattern="*.png", minutes=1): """获取最近minutes分钟内生成的文件""" cutoff = time.time() - minutes * 60 files = [] for f in glob.glob(os.path.join(directory, "**", pattern), recursive=True): if os.path.getctime(f) > cutoff: files.append(f) return sorted(files, key=os.path.getctime) def archive_new_files(): today = datetime.now().strftime("%Y-%m-%d") today_output = os.path.join(OUTPUT_ROOT, today) if not os.path.exists(today_output): return new_files = get_latest_files(today_output) if not new_files: return # 复制到 by_date(保持原名) date_archive = os.path.join(ARCHIVE_ROOT, "by_date", today) os.makedirs(date_archive, exist_ok=True) for src in new_files: dst = os.path.join(date_archive, os.path.basename(src)) if not os.path.exists(dst): shutil.copy2(src, dst) print(f"✓ Archived to date: {os.path.basename(src)}") # 更新 latest 软链接 latest_link = os.path.join(ARCHIVE_ROOT, "latest", "latest.png") os.makedirs(os.path.dirname(latest_link), exist_ok=True) if os.path.lexists(latest_link): os.remove(latest_link) os.symlink(new_files[-1], latest_link) print(f"→ Updated latest symlink to {os.path.basename(new_files[-1])}") if __name__ == "__main__": print("Starting face fusion auto-archive daemon...") while True: try: archive_new_files() except Exception as e: print(f"[ERR] {e}") time.sleep(30) # 每30秒扫描一次3.3 后台运行脚本
赋予执行权限并后台启动:
chmod +x /root/auto_archive.py nohup python3 /root/auto_archive.py > /var/log/face_fusion_archive.log 2>&1 & echo $! > /var/run/face_fusion_archive.pid效果:
- 新图生成后30秒内,自动同步至
/archive/face_fusion/by_date/; /archive/face_fusion/latest/latest.png始终指向最新成果,双击即可预览;- 日志清晰记录每次归档动作,故障可追溯。
4. 方案三:WebUI增强——增加“批量导出”按钮
前两方案解决了“存哪”和“存住”,但工程师真正想要的是“一键带走”。本节教你如何在不重写Gradio前端的前提下,向现有WebUI注入一个原生风格的“导出今日全部”按钮,点击即打包下载ZIP。
4.1 创建导出后端接口
在app.py中,于gradio.Interface创建之前,添加新函数:
import zipfile import io def export_today_zip(): """打包今日所有融合结果为ZIP""" today = datetime.now().strftime("%Y-%m-%d") today_dir = os.path.join("/data/face_fusion_outputs", today) if not os.path.exists(today_dir): return None, "今日暂无融合结果" png_files = [f for f in os.listdir(today_dir) if f.lower().endswith('.png')] if not png_files: return None, "今日目录为空" # 内存中构建ZIP zip_buffer = io.BytesIO() with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zf: for f in png_files: file_path = os.path.join(today_dir, f) zf.write(file_path, f) # 直接存原始文件名 zip_buffer.seek(0) zip_filename = f"face_fusion_{today}.zip" return zip_buffer.getvalue(), f"已打包 {len(png_files)} 张图:{zip_filename}"4.2 在Gradio界面中添加按钮
找到gradio.Interface(...)的inputs=和outputs=定义处,在outputs列表末尾追加:
gr.File(label=" 今日成果ZIP包", type="binary"), gr.Textbox(label="状态", interactive=False),并在fn=对应的函数中(通常是inference或process),于返回值末尾添加:
export_today_zip(),最后,在界面构建部分(gr.Blocks()内),添加按钮组件:
with gr.Row(): export_btn = gr.Button("📦 导出今日全部(ZIP)") export_btn.click( fn=export_today_zip, inputs=[], outputs=[output_file, status_text] )4.3 重启生效
/bin/bash /root/run.sh刷新页面,你会在底部看到醒目的蓝色按钮。点击后,浏览器自动触发下载,ZIP包内含当日所有融合图,命名清晰、无需解压即用。
5. 进阶建议:建立你的融合作品库
以上三步已解决“不丢图”问题,但真正的效率提升在于让图片可检索、可复用、可分享。这里给出两个轻量级实践建议:
5.1 命名规范化(人工+脚本)
每次融合前,在WebUI的“高级参数”中填写简短描述(如张三_年会演讲_背景虚化),然后运行以下脚本重命名最新文件:
# rename_latest.sh LATEST=$(ls -t /data/face_fusion_outputs/$(date +%Y-%m-%d)/*.png | head -1) DESC="张三_年会演讲_背景虚化" NEWNAME=$(dirname "$LATEST")/$(basename "$LATEST" .png)_${DESC}.png mv "$LATEST" "$NEWNAME"5.2 构建简易图库网页
用5行代码生成静态HTML相册:
cd /archive/face_fusion find by_date -name "*.png" | sort -r | head -20 | \ awk '{print "<div><img src=\"'"$(pwd)"'/" $0 "\" width=\"300\"></div>"}' > index.html sed -i '1i <!DOCTYPE html><html><body><h1>我的融合作品库</h1>' index.html sed -i '$a </body></html>' index.html访问file:///archive/face_fusion/index.html,即可获得滚动式缩略图墙,支持直接点击放大。
6. 总结:从“怕丢图”到“图找你”
本文没有讨论UNet的网络结构、损失函数或训练技巧,因为对绝大多数使用者而言,模型只是工具,结果才是资产。我们围绕“UNet输出结果自动保存”这一具体痛点,提供了三层递进式解决方案:
- 第一层(稳):通过环境变量接管输出路径,将结果从易损的
/root迁移至可靠的/data,消除空间与权限风险; - 第二层(全):部署轻量监控脚本,实现新图自动归档、软链接快速预览、日志全程追踪,确保“生成即留存”;
- 第三层(快):增强WebUI,添加原生风格的“导出今日全部”按钮,一键生成ZIP,彻底终结右键保存的机械劳动。
这三步做完,你将获得一个自我维护、自我归档、自我交付的人脸融合工作流。下次当同事问“上次那张换脸图在哪”,你可以直接回复:“在/archive/face_fusion/latest,或者点WebUI的📦按钮重新下载。”
技术的价值,从来不在多炫酷,而在多省心。
--- > **获取更多AI镜像** > > 想探索更多AI镜像和应用场景?访问 [CSDN星图镜像广场](https://ai.csdn.net/?utm_source=mirror_blog_end),提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。