ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

高分辨率图像修复又慢又贵?看这个 ComfyUI 插件如何用“先裁剪、再拼接“四两拨千斤

2026/8/14 13:52:03 拓冰建站 浏览量
高分辨率图像修复又慢又贵?看这个 ComfyUI 插件如何用“先裁剪、再拼接“四两拨千斤 高分辨率图像修复又慢又贵看这个 ComfyUI 插件如何用先裁剪、再拼接四两拨千斤【免费下载链接】ComfyUI-Inpaint-CropAndStitchComfyUI nodes to crop before sampling and stitch back after sampling that speed up inpainting项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-Inpaint-CropAndStitch修复一张 4K 照片里的小瑕疵代价却是让扩散模型对整个画面跑一遍采样——这大概是所有 ComfyUI 玩家都踩过的坑显存告急、出图慢、还容易在无关区域生成出惊喜。ComfyUI-Inpaint-CropAndStitch 用两个节点给出了一个朴素却极其有效的答案只在掩码附近的小区域里做修复做完再无缝拼回去。本文从源码出发拆解这条局部修复-全局还原的流水线究竟是如何运转的。一、为什么整图采样是笔糊涂账先算一笔账扩散模型的计算开销与图像像素数近似成正比。一张 2048×2048 的图片如果掩码只占中间 512×512 的一块整图采样意味着 16 倍于必要区域的计算量被白白消耗。更麻烦的是不同模型有自己舒适的分辨率——SD 1.5 偏好 512 附近SDXL 习惯 1024喂一张任意尺寸的大图还得先处理宽高比、对齐、padding 这些琐事。于是这个插件把任务切成两半Inpaint Crop裁剪根据掩码框定一个取景框把修复区域连同周边上下文一起裁出来必要时缩放到模型舒适的分辨率Inpaint Stitch拼接采样完成后把修复好的小块按记录的坐标贴回原图用掩码做柔化过渡。一句话概括把修整张图降级为修一块图其余像素全程不参与 VAE 编解码与采样这也保证了未掩码区域 100% 不被改动。二、取景框怎么摆裁剪前的三连问裁剪绝非沿着掩码边缘切一刀这么简单。打开InpaintCropImproved.inpaint_crop你会发现它在真正落刀之前先回答三个问题。问题一掩码干净吗手绘掩码常常有孔洞、毛边、半透明渐变。源码先用fillholes_iterative_hipass_fill_m把被掩码完全包围的孤岛也标记为修复区——原理是逐级降低阈值做闭运算再填洞# 掩码补洞从高阈值到低阈值逐级逼近 for threshold in [1, 0.99, 0.97, ..., 0.1]: closed binary_closing(mask threshold, structurenp.ones((3, 3))) filled binary_fill_holes(closed) # 把闭合区域内部填满 mask np.maximum(mask, np.where(filled, threshold, 0))随后还可以按需膨胀expand_m扩大修复范围、反相invert_m保留而非抹除以及高通滤波hipassfilter_m忽略接近 0 的噪点掩码。这些操作全部由processor这个抽象对象完成——它是什么取决于你选的设备模式。问题二上下文给多少修复质量极大依赖上下文抹掉一个人物模型总得看到周围的环境才知道该补什么。context_from_mask_extend_factor负责把掩码包围盒按比例向外扩比如 1.5 表示四周各多留 50% 的上下文。如果还想人为指定某块区域必须保留比如背景里的地标可以额外接入optional_context_mask裁剪框会取两者的并集。问题三取景框比例对吗扩散模型对长宽比敏感。假设掩码包围盒是 300×600 的竖条而目标输出是 512×512 的方块直接缩放会变形。crop_magic_im的做法是先扩框、再缩放比较当前框与目标框的宽高比谁不够就沿哪个方向补足补足的策略是围绕原框中心向两侧对称伸展越界时再退回图像边界内。# 取景框扩到目标宽高比伪代码示意 target_ratio target_w / target_h if (w / h) target_ratio: # 框太瘦了横向扩展 new_w int(h * target_ratio) new_x x - (new_w - w) // 2 # 以原框中心为基准对称外扩 else: # 框太扁了纵向扩展 new_h int(w / target_ratio) new_y y - (new_h - h) // 2另外还有一个容易被忽略的细节output_padding。扩散模型通常要求输入尺寸是 8/16/32 的倍数插件通过pad_to_multiple把目标宽高向上取整到 padding 的整数倍——多出来的空白由边缘像素复制填充edge padding拼接阶段会自动还原用户感知不到。图1高分辨率修复工作流——裁出小块采样、外部模型放大后再拼回原始画布三、拼接把补丁焊回原图修复完成的只是一块小图它和原图之间存在缩放差异与接缝问题。InpaintStitchImproved的输入极其精简一个STITCHER数据包裁剪时记录的全部坐标与画布信息加上修复图。stitch_magic_im的逻辑可以浓缩成三步还原尺寸把修复图缩放到裁剪框在画布上的实际尺寸ctc_w × ctc_h放大用 upscale 算法、缩小用 downscale 算法掩码混合不是生硬覆盖而是用模糊过的掩码做加权融合——掩码值 1 的区域完全采用修复结果0 的区域保留画布原样中间地带平滑过渡从而消除接缝切回原图从画布上裁出原始图像对应的区域cto_x/cto_y/cto_w/cto_h作为最终输出。# 拼接核心掩码加权融合简化示意 resized_mask mask_resized.clamp(0, 1).unsqueeze(-1) # 归一化并扩展通道 canvas_crop canvas[:, y:yh, x:xw] # 取画布上将被覆盖的区域 blended resized_mask * inpainted (1 - resized_mask) * canvas_crop canvas[:, y:yh, x:xw] blended # 贴回画布 output canvas[:, oy:oyoh, ox:oxow] # 裁出原始图区域值得一提的设计是STITCHER是一个自包含的上下文对象。裁剪节点把画布、掩码、坐标、算法偏好一股脑打包进去拼接节点无需重新计算任何东西只知道照单操作即可。这既是数据契约也让两个节点可以解耦使用——中间插入任意采样器、放大模型甚至 hiRes 修复流程都不受影响。图2SD 1.5 基础修复流程——掩码只需框住小区域采样也只发生在裁剪块内四、双引擎CPU 与 GPU 的策略模式实战ProcessorLogic是一个抽象基类定义了 11 个核心操作缩放、膨胀、模糊、补洞、裁剪、拼接……下面挂着两套实现。节点本身完全不关心用的是哪套只通过device_mode参数在运行时挑选if device_mode gpu (much faster): processor GPUProcessorLogic() # 张量运算跑在 torch 设备上 else: processor CPUProcessorLogic() # PIL scipy兼容一切环境这是教科书级的策略模式算法家族被统一封装调用方与具体实现解耦新增一套后端比如 MPS只需再继承一个子类。更妙的是两套实现里藏着不同的优化哲学能力CPU 版scipy/PILGPU 版torch掩码膨胀grey_dilation灰度膨胀max_pool2d最大池化近似膨胀掩码模糊gaussian_filter高斯滤波conv2d手动构造高斯核卷积坐标查找逐张torch.nonzero循环向量化max(dim)一次算出包围盒设计取向直白、可读、零依赖风险批处理友好、尽量留在显存其中最有意思的是 GPU 版的两个借刀杀人技巧膨胀 最大池化膨胀的本质是每个像素取邻域最大值而max_pool2d恰好干的就是这件事还天然支持批处理比逐像素遍历快一个数量级模糊 可分离卷积先把一维高斯核的外积构造成二维核再对掩码做一次conv2dreflect padding 保证图像边缘的模糊不会漏气。# GPU 版膨胀用最大池化代替灰度膨胀 sigma pixels / 4 ksize math.ceil(sigma * 1.5 1) | 1 # 保证核大小为奇数 mask_padded TF.pad(mask.unsqueeze(1), (ksize//2,)*4, modereflect) dilated TF.max_pool2d(mask_padded, ksize, stride1) # 池化即膨胀不过源码也坦诚地留了个反直觉的注脚GPU 版的图像缩放依然把张量拷回 CPU 用 PIL 做。原因很实际——torch.nn.functional.interpolate在部分插值模式下与 PIL 存在质量差异而缩放在这个管线里频率不高CPU 的精度收益胜过来回搬运的损耗。性能优化不是一味堆 GPU而是把每一段操作放在它最擅长的地方。图3Flux ControlNet 的高级修复场景裁剪块经复杂条件编码后采样再无缝拼回五、批处理与前端两个容易被忽略的工程细节单图输入批量处理裁剪节点支持一次接收多张图 多张掩码。源码里有一段耐心的对齐逻辑1 张图配 N 张掩码时自动复制图像N 张图配 1 张掩码时自动复制掩码最后逐张处理、按批次收集结果。同时它强制要求批量输入时必须开启output_resize_to_target_size——理由很直白同一批次的输出尺寸必须一致否则拼接无从谈起。这种把边界条件显式抛给用户的做法比静默出错要友好得多。参数太多怎么办前端帮你隐身InpaintCropImproved的输入参数多达二十余个全堆在节点面板上会吓退新手。js/showcontrol.js负责根据开关状态动态隐藏无关参数没勾选preresize就不显示缩放相关控件没开启 outpainting 就不显示四个方向的扩展因子。用户面对的是一个越用越清爽的界面这也是开源插件值得学习的交互设计思路。六、实战建议从源码里读出的最佳实践结合源码实现与README的说明几个能直接落地的建议尽量开启输出对齐到目标尺寸output_resize_to_target_size True并把宽高设为你所用模型的舒适分辨率SD 1.5 用 512SDXL/Flux 用 1024让采样始终发生在模型最擅长的区间mask_blend_pixels不要设 0拼接的无缝感全靠掩码的膨胀模糊过渡设为 16~32 通常能明显改善接缝掩码务必画实源码与文档反复提醒半透明掩码是看得见原图的头号元凶——检查掩码像素是否达到 255 纯白大图先裁剪再放大高分辨率场景可以裁出小块 → 采样 → 用外部放大模型提升细节 → hiRes 修复 → 拼回流程上完全可行参考inpaint_hires工作流设备模式按环境选CPU 模式兼容一切环境GPU 模式在多数现代配置下能获得明显加速若遇报错降级回 CPU 即可。七、回头看这条流水线从整图采样到裁剪-拼接这个插件没有发明任何玄学算法全靠三个工程判断赢得了性能最小化计算域——采样只发生在掩码附近其余像素连 VAE 都不经过坐标即契约——STITCHER把裁剪与拼接解耦成两个可独立替换的环节策略化后端——同一套算法逻辑CPU/GPU 两套实现按需切换。如果你想继续深入源码里还藏着两扇门一扇是extend_for_outpainting通过扩展画布把修复升级为外画另一扇是调试模式打开DEBUG_MODE节点会输出从预缩放到拼接的全过程中间结果把每一步的掩码和取景框可视化出来——亲手跑一遍胜过读十遍源码。仓库可通过git clone https://gitcode.com/gh_mirrors/co/ComfyUI-Inpaint-CropAndStitch获取配合example_workflows/下的三个 JSON 工作流直接上手体验。【免费下载链接】ComfyUI-Inpaint-CropAndStitchComfyUI nodes to crop before sampling and stitch back after sampling that speed up inpainting项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-Inpaint-CropAndStitch创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考