IOPaint:一句话抹掉照片里的杂物,开源图像修复与擦除工具
📖 简介
📝 详细介绍
用 IOPaint 十分钟做一个"擦除照片杂物"的命令行工具
这篇教程带你把 IOPaint 跑起来,并完成一件具体的事:给一张照片生成掩码,用一条命令把指定区域的内容抹掉,输出一张看不出修补痕迹的新图。全程不需要 GPU,笔记本 CPU 就能跑完。
前置条件
- Python 3.10 或 3.11(3.12 上部分依赖的预编译轮子可能缺失,装起来会多花时间)。
- 建议在虚拟环境里操作,避免和系统里已有的 torch 打架。
- CPU 可跑,内存建议 8GB 以上;有 NVIDIA 显卡时用 CUDA 会快 5~10 倍。
- 能访问外网或配置好国内镜像,首次运行需要下载模型权重(LaMa 约 200MB)。
- 一张待处理的图片,以及 OpenCV(用来生成掩码)。
安装部署
第一步:建虚拟环境并安装
python -m venv venv
source venv/bin/activate # Windows 用 venv\Scripts\activate
pip install --upgrade pip
pip install iopaint opencv-python
如果你要跑 GPU,先单独装带 CUDA 的 torch,再装 iopaint,否则 pip 会给你装 CPU 版:
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121
pip install iopaint opencv-python
第二步:初始化(首次拉模型)
IOPaint 没有单独的 init 命令,模型在第一次启动时自动下载。国内网络建议先设镜像:
export HF_ENDPOINT=https://hf-mirror.com
第三步:启动 Web UI 验证装好了
iopaint start --model=lama --device=cpu --port=8080
浏览器打开 http://localhost:8080,能看到涂鸦擦除界面就说明环境没问题。有显卡就把 --device=cpu 换成 --device=cuda,Mac M 系列用 --device=mps。
第一个 Demo:命令行擦掉照片右下角的水印
这一步要做什么:造一张掩码图
IOPaint 的规则很简单——掩码里白色(255)的区域被擦除,黑色(0)的区域原样保留。掩码必须是单通道灰度图,尺寸和原图完全一致。下面用 OpenCV 圈出右下角一块矩形:
import cv2
import numpy as np
img = cv2.imread("photo.jpg")
h, w = img.shape[:2]
# 全黑掩码,单通道
mask = np.zeros((h, w), dtype=np.uint8)
# 把右下角 40%x20% 的区域涂白(换成你自己的坐标即可)
x1, y1, x2, y2 = int(w * 0.6), int(h * 0.8), w, h
mask[y1:y2, x1:x2] = 255
cv2.imwrite("mask.png", mask)
print("mask size:", mask.shape, "white pixels:", int((mask == 255).sum()))
预期输出:mask size: (H, W) white pixels: ...,同时目录下多出一个 mask.png,打开看应该是黑底 + 右下角一块白。
这一步要做什么:调用 IOPaint 执行擦除
iopaint run --model=lama --device=cpu \
--image=photo.jpg \
--mask=mask.png \
--output=result.png
跑完终端会打印处理进度,目录下出现 result.png。打开对比:原本水印所在的矩形区域已经被周围的天空/地面纹理填满,边界处有轻微过渡,不会出现明显的方块感——这正是 LaMa 这类模型和"高斯模糊涂掉"的本质区别。
批量处理(可选)
--image 和 --mask 都支持传目录,IOPaint 会按同名文件一一配对:
iopaint run --model=lama --device=cuda \
--image=./images --mask=./masks --output=./results
注意:此时 --output 必须是目录,传文件名会报错。
配置与调优
1. 换模型:速度和质量取舍
--model=lama 是最快的通用选择,一次推理几百毫秒。追求质量可以换 --model=mat 或 --model=zits,纹理连续性更好,但慢一个数量级。如果需求是"擦掉之后放个新东西进去",那要切换到 Stable Diffusion 系模型(如 BrushNet、PowerPaint),这时 --model 直接填 HuggingFace 上的模型 ID。
2. 显存不够就加 --low-mem
iopaint start --model=lama --device=cuda --low-mem --port=8080
它会用更省显存的推理路径,代价是慢一些。显存 4GB 以下基本必开。
3. 掩码做得比目标区域大一点
这是最容易被忽略的调优点。掩码刚好贴着物体边缘时,模型缺少上下文,容易留下"影子"。把掩码向外扩 5~15 像素(可用 cv2.dilate),修补质量通常会有明显提升:
kernel = np.ones((15, 15), np.uint8)
mask = cv2.dilate(mask, kernel, iterations=1)
常见坑与排错
| 报错信息 | 原因 | 解决办法 |
|---|---|---|
torch.cuda.OutOfMemoryError | 显存不足,模型和图片同时占满了 GPU | 加 --low-mem,或改用 --device=cpu,或先缩小图片尺寸 |
下载模型时 ConnectionError / 卡在 0% | 无法直连 HuggingFace | 设 export HF_ENDPOINT=https://hf-mirror.com 后重新启动 |
| 输出图和原图一模一样,什么都没擦掉 | 掩码不是单通道,或值不是 0/255(比如被保存成了三通道 JPG) | 用 cv2.imwrite 保存 PNG,写完打印 mask.shape 确认是 (H, W) |
Mac 上报 NotImplementedError 或结果全黑 | MPS 后端对某些算子(如 half 精度)支持不完整 | 改用 --device=mps --no-half |
下一步
- 自动生成掩码:手动画框终究麻烦。IOPaint 内置了交互式分割(SAM)能力,启动时带上分割模型参数,点一下物体就能出掩码;再配合 GroundingDINO 用文本提示"person"、"dog"直接生成掩码,可以做全自动批处理。
- 接进自己的服务:除了 CLI,IOPaint 也提供 Python API(
ModelManager加载模型后直接对 ndarray 推理)和 HTTP 接口,可以包一层 FastAPI 做内部工具。注意 API 在版本间有变动,锁定版本再写代码。 - 容器化部署:官方仓库里有 Dockerfile,把模型权重挂载成 volume 挂进去,可以避免每次重建镜像都重新下载几百 MB 权重,适合放到内网服务器给团队共用。
AI 项目推荐
AI 设计- 标签
- #图像修复 #物体擦除 #LaMa #老照片 #开源
- 浏览
- 👁️ 3
- 发布日期
- 2026-10-05