5 min read
这次让AI帮一下美术生
Image2Body 改造计划:从 Python 到 ComfyUI 的华丽转身 🚀
前言 🌟
大家好!今天我们要进行一个有趣的改造项目:把 Image2Body 这个将普通图片变成人体轮廓和素描的魔法工具,从传统的 Python 程序转变成 ComfyUI 工作流。这就像是给一个老式相机装上了数码芯片,让它焕发新生!✨
代码考古:深入原始实现 🔍
让我们先来挖掘一下原始代码的宝藏!
核心架构分析 📊
# 主要处理流程
def process_image(input_image, mode: str, weight1: float = 0.4, weight2: float = 0.3):
# 1. 图像预处理
# 2. 生成轮廓
# 3. 生成素描
# 4. 混合输出
原始项目使用了一个多层处理架构:
- 图像预处理层 🖼️
def preprocess_image_for_generation(image):
# 确保图像是 RGB 格式
if image.mode != 'RGB':
image = image.convert('RGB')
# 调整图像大小
w, h = image.size
scale = min(512 / w, 512 / h)
new_w, new_h = int(w * scale), int(h * scale)
image = image.resize((new_w, new_h))
return image
这段代码负责图像标准化,就像给照片化妆前的准备工作!
- 轮廓生成引擎 💪
def generate_sotai_image(input_image: Image.Image, output_width: int, output_height: int):
# 使用 ControlNet 生成人体轮廓
controlnet1 = ControlNetModel.from_single_file(
controlnet_path1,
torch_dtype=torch_dtype
).to(device)
# 应用 LoRA 微调
lora_names = [
(os.environ["lora_name1"], 1.0),
]
这是项目的”魔法核心”,将普通图片变成人体轮廓!
- 素描生成器 ✏️
def get_sketch(image, method='scribble_xdog', res=2048, thr=20):
if method == 'scribble_xdog':
processed_image, _ = scribble_xdog(image, res, thr)
elif method == 'anime2sketch':
processed_image = generate_sketch(image, clahe_clip=1.0)
这部分就像是一个数字画家,能用不同的技法创作素描!
- 图像混合魔法师 🎨
def mix_images(sotai_image_data, sketch_image_data, opacity1, opacity2):
# 创建透明图层
mixed_image = Image.new('RGBA', sotai_image.size, (255, 255, 255, 255))
# 设置透明度
sotai_alpha = sotai_image.getchannel('A').point(lambda x: int(x * opacity1))
sketch_alpha = sketch_image.getchannel('A').point(lambda x: int(x * opacity2))
就像调制鸡尾酒一样,将两种图像完美调配!
有趣的技术细节 🤓
- 智能缓存机制 💾
# 全局变量缓存
use_local = False
model = None
device = None
torch_dtype = None
这些全局变量就像项目的”记忆库”,避免重复加载模型。
- 自适应处理 🔄
def pad64(x):
return int(np.ceil(float(x) / 64.0) * 64 - x)
这个小函数确保图像尺寸是 64 的倍数,就像给图片穿上完美合身的衣服!
ComfyUI 改造方案 🛠️
1. 节点映射表 📝
原始代码到 ComfyUI 节点的映射关系:
| 原始函数 | ComfyUI 节点 | 说明 |
|---------|-------------|------|
| preprocess_image | ImageScale | 图像预处理 🖼️ |
| generate_sotai_image | KSampler + ControlNet | 轮廓生成 💪 |
| get_sketch | ControlNet Preprocessor (Scribble) | 素描生成 ✏️ |
| mix_images | ImageBlend | 图像混合 🎨 |
2. 工作流构建步骤 🏗️
2.1 图像输入处理
graph LR
A[LoadImage] --> B[ImageScale]
B --> C1[轮廓分支]
B --> C2[素描分支]
2.2 轮廓生成流程
# 原代码:
def generate_sotai_image(input_image, output_width, output_height):
controlnet = ControlNetModel.from_single_file(controlnet_path)
对应的 ComfyUI 节点设置:
1. ControlNet Preprocessor (Canny)
- Threshold: 100, 200
- Resolution: 512
2. KSampler
- Steps: 20
- CFG: 7
- Sampler: Euler a
2.3 素描生成流程
原代码中的 XDoG 处理:
def scribble_xdog(img, res=512, thr_a=32):
g1 = cv2.GaussianBlur(img.astype(np.float32), (0, 0), 0.5)
g2 = cv2.GaussianBlur(img.astype(np.float32), (0, 0), 5.0)
ComfyUI 中的实现:
1. 使用 Scribble 预处理器
2. 连接到第二个 KSampler
3. 应用相同的模糊参数
优化建议 🚀
1. 性能优化 ⚡
# 原代码中的内存优化
def safer_memory(x):
return np.ascontiguousarray(x.copy()).copy()
ComfyUI 中的对应优化:
-
使用 VAE 缓存
-
启用批处理
-
使用适当的图像尺寸
2. 质量优化 💎
原代码中的图像增强:
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
ComfyUI 中可以使用:
-
图像后处理节点
-
提示词增强
-
多重采样优化
实用技巧 💡
- 快速切换模式
# 原代码的模式切换
if mode == "original":
sotai_image, sketch_image = process_image_as_base64(input_image, mode)
elif mode == "refine":
sotai_image, sketch_image = process_image_as_base64(input_image, mode, weight1, weight2)
在 ComfyUI 中,我们可以使用:
-
条件节点
-
预设工作流
-
快速切换开关
- 参数优化技巧 🎯
# 原代码中的参数设置
def initialize_sotai_model():
lora_names = [
(os.environ["lora_name1"], 1.0),
(os.environ["lora_name2"], 0.3),
]
ComfyUI 中的对应设置:
-
使用滑动条控制权重
-
保存常用预设
-
创建参数组
结论 🎉
通过这次改造,我们不仅保留了 Image2Body 的强大功能,还让它变得更加灵活和易用。就像给一辆老爷车装上了现代引擎,既保留了经典,又增添了新的活力!
记住,改造的过程就像做料理,需要:
-
保持耐心 🧘♂️
-
适当实验 🔬
-
细心调试 🔧
最后,祝大家在 ComfyUI 的海洋中畅游,创造出更多精彩的作品!如果遇到问题,记住:每个 bug 都是一个新的发现,每个错误都是一次学习的机会! 🌈
后续优化建议 🔮
- 创建预设 📦
- 保存常用配置
- 创建风格预设
- 建立快速切换机制
- 添加高级功能 🎯
- 集成更多 ControlNet 模型
- 添加后处理选项
- 实现批量处理
- 性能优化 ⚡
- 模型合并优化
- 预处理流程优化
- 缓存机制优化
让我们一起把 Image2Body 变得更强大、更好用! 🚀