Files
2024-07-04 11:34:32 +08:00

234 lines
11 KiB
Markdown

# Documentation
- Class name: HighRes-Fix Script
- Category: Efficiency Nodes/Scripts
- Output node: False
HighRes-Fix Script节点旨在以可定制的方式提升图像分辨率和质量。它利用各种放大技术、控制网络和预处理步骤来优化图像,提供种子一致性、去噪和迭代细化的选项。该节点与动画和控制网络脚本集成,适应特定的高分辨率增强需求,同时保持与不同放大模型和预处理器配合使用的灵活性。
# Input types
## Required
- upscale_type
- 指定要使用的放大方法,影响高分辨率输出的质量和方法。
- Comfy dtype: COMBO[STRING]
- Python dtype: str
- hires_ckpt_name
- 高分辨率模型的检查点名称,表示用于放大的特定模型版本或配置。
- Comfy dtype: COMBO[STRING]
- Python dtype: str
- latent_upscaler
- 标识潜在空间放大方法,在进行像素级调整之前在基础层面上增强图像细节。
- Comfy dtype: COMBO[STRING]
- Python dtype: str
- pixel_upscaler
- 定义像素级放大方法,在潜在空间增强后进一步细化图像细节。
- Comfy dtype: COMBO[STRING]
- Python dtype: str
- upscale_by
- 确定放大过程的缩放因子,直接影响最终图像的大小和细节。
- Comfy dtype: FLOAT
- Python dtype: float
- use_same_seed
- 控制是否在整个放大过程中使用相同的种子,确保随机元素的一致性。
- Comfy dtype: BOOLEAN
- Python dtype: bool
- seed
- 随机过程的初始种子值,为可重复性和变化控制提供起点。
- Comfy dtype: INT
- Python dtype: int
- hires_steps
- 指定在高分辨率增强过程中要执行的步骤数,影响细化的深度。
- Comfy dtype: INT
- Python dtype: int
- denoise
- 表示在放大过程中是否应用去噪,通过减少噪声来改善图像清晰度。
- Comfy dtype: FLOAT
- Python dtype: bool
- iterations
- 运行放大过程的迭代次数,允许多次细化。
- Comfy dtype: INT
- Python dtype: int
- use_controlnet
- 确定是否使用控制网络进行引导放大,影响增强的方向和质量。
- Comfy dtype: BOOLEAN
- Python dtype: bool
- control_net_name
- 要使用的控制网络的名称,指定用于引导放大的模型。
- Comfy dtype: COMBO[STRING]
- Python dtype: str
- strength
- 控制网络对放大过程影响的强度,调整引导的程度。
- Comfy dtype: FLOAT
- Python dtype: float
- preprocessor
- 用于准备图像进行放大的预处理方法,影响初始质量和兼容性。
- Comfy dtype: COMBO[STRING]
- Python dtype: str
- preprocessor_imgs
- 准备好进行放大的预处理图像,作为增强过程的输入。
- Comfy dtype: BOOLEAN
- Python dtype: list
## Optional
- script
- 包含放大过程的附加参数或配置的可选脚本。
- Comfy dtype: SCRIPT
- Python dtype: dict
# Output types
- script
- 应用高分辨率修复后产生的脚本配置,封装了过程中指定的所有参数和进行的调整。
- Comfy dtype: SCRIPT
- Python dtype: dict
## Usage tips
- Infra type: `GPU`
- Common nodes:
- [KSampler SDXL (Eff.)](../../efficiency-nodes-comfyui/Nodes/KSampler SDXL (Eff.).md)
## Source code
```python
class TSC_HighRes_Fix:
default_latent_upscalers = LatentUpscaleBy.INPUT_TYPES()["required"]["upscale_method"][0]
city96_upscale_methods =\
["city96." + ver for ver in city96_latent_upscaler.LatentUpscaler.INPUT_TYPES()["required"]["latent_ver"][0]]
city96_scalings_raw = city96_latent_upscaler.LatentUpscaler.INPUT_TYPES()["required"]["scale_factor"][0]
city96_scalings_float = [float(scale) for scale in city96_scalings_raw]
ttl_nn_upscale_methods = \
["ttl_nn." + ver for ver in
ttl_nn_latent_upscaler.NNLatentUpscale.INPUT_TYPES()["required"]["version"][0]]
latent_upscalers = default_latent_upscalers + city96_upscale_methods + ttl_nn_upscale_methods
pixel_upscalers = folder_paths.get_filename_list("upscale_models")
@classmethod
def INPUT_TYPES(cls):
return {"required": {"upscale_type": (["latent","pixel","both"],),
"hires_ckpt_name": (["(use same)"] + folder_paths.get_filename_list("checkpoints"),),
"latent_upscaler": (cls.latent_upscalers,),
"pixel_upscaler": (cls.pixel_upscalers,),
"upscale_by": ("FLOAT", {"default": 1.25, "min": 0.01, "max": 8.0, "step": 0.05}),
"use_same_seed": ("BOOLEAN", {"default": True}),
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
"hires_steps": ("INT", {"default": 12, "min": 1, "max": 10000}),
"denoise": ("FLOAT", {"default": .56, "min": 0.00, "max": 1.00, "step": 0.01}),
"iterations": ("INT", {"default": 1, "min": 0, "max": 5, "step": 1}),
"use_controlnet": use_controlnet_widget,
"control_net_name": (folder_paths.get_filename_list("controlnet"),),
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
"preprocessor": preprocessor_widget,
"preprocessor_imgs": ("BOOLEAN", {"default": False})
},
"optional": {"script": ("SCRIPT",)},
"hidden": {"my_unique_id": "UNIQUE_ID"}
}
RETURN_TYPES = ("SCRIPT",)
FUNCTION = "hires_fix_script"
CATEGORY = "Efficiency Nodes/Scripts"
def hires_fix_script(self, upscale_type, hires_ckpt_name, latent_upscaler, pixel_upscaler, upscale_by,
use_same_seed, seed, hires_steps, denoise, iterations, use_controlnet, control_net_name,
strength, preprocessor, preprocessor_imgs, script=None, my_unique_id=None):
latent_upscale_function = None
latent_upscale_model = None
pixel_upscale_model = None
def float_to_string(num):
if num == int(num):
return "{:.1f}".format(num)
else:
return str(num)
if iterations > 0 and upscale_by > 0:
if upscale_type == "latent":
# For latent methods from city96
if latent_upscaler in self.city96_upscale_methods:
# Remove extra characters added
latent_upscaler = latent_upscaler.replace("city96.", "")
# Set function to city96_latent_upscaler.LatentUpscaler
latent_upscale_function = city96_latent_upscaler.LatentUpscaler
# Find the nearest valid scaling in city96_scalings_float
nearest_scaling = min(self.city96_scalings_float, key=lambda x: abs(x - upscale_by))
# Retrieve the index of the nearest scaling
nearest_scaling_index = self.city96_scalings_float.index(nearest_scaling)
# Use the index to get the raw string representation
nearest_scaling_raw = self.city96_scalings_raw[nearest_scaling_index]
upscale_by = float_to_string(upscale_by)
# Check if the input upscale_by value was different from the nearest valid value
if upscale_by != nearest_scaling_raw:
print(f"{warning('HighRes-Fix Warning:')} "
f"When using 'city96.{latent_upscaler}', 'upscale_by' must be one of {self.city96_scalings_raw}.\n"
f"Rounding to the nearest valid value ({nearest_scaling_raw}).\033[0m")
upscale_by = nearest_scaling_raw
# For ttl upscale methods
elif latent_upscaler in self.ttl_nn_upscale_methods:
# Remove extra characters added
latent_upscaler = latent_upscaler.replace("ttl_nn.", "")
# Bound to min/max limits
upscale_by_clamped = min(max(upscale_by, 1), 2)
if upscale_by != upscale_by_clamped:
print(f"{warning('HighRes-Fix Warning:')} "
f"When using 'ttl_nn.{latent_upscaler}', 'upscale_by' must be between 1 and 2.\n"
f"Rounding to the nearest valid value ({upscale_by_clamped}).\033[0m")
upscale_by = upscale_by_clamped
latent_upscale_function = ttl_nn_latent_upscaler.NNLatentUpscale
# For default upscale methods
elif latent_upscaler in self.default_latent_upscalers:
latent_upscale_function = LatentUpscaleBy
else: # Default
latent_upscale_function = LatentUpscaleBy
latent_upscaler = self.default_latent_upscalers[0]
print(f"{warning('HiResFix Script Warning:')} Chosen latent upscale method not found! "
f"defaulting to '{latent_upscaler}'.\n")
# Load Checkpoint if defined
if hires_ckpt_name == "(use same)":
clear_cache(my_unique_id, 0, "ckpt")
else:
latent_upscale_model, _, _ = \
load_checkpoint(hires_ckpt_name, my_unique_id, output_vae=False, cache=1, cache_overwrite=True)
elif upscale_type == "pixel":
pixel_upscale_model = UpscaleModelLoader().load_model(pixel_upscaler)[0]
elif upscale_type == "both":
latent_upscale_function = LatentUpscaleBy
latent_upscaler = self.default_latent_upscalers[0]
pixel_upscale_model = UpscaleModelLoader().load_model(pixel_upscaler)[0]
if hires_ckpt_name == "(use same)":
clear_cache(my_unique_id, 0, "ckpt")
else:
latent_upscale_model, _, _ = \
load_checkpoint(hires_ckpt_name, my_unique_id, output_vae=False, cache=1, cache_overwrite=True)
control_net = ControlNetLoader().load_controlnet(control_net_name)[0] if use_controlnet is True else None
# Construct the script output
script = script or {}
script["hiresfix"] = (upscale_type, latent_upscaler, upscale_by, use_same_seed, seed, hires_steps,
denoise, iterations, control_net, strength, preprocessor, preprocessor_imgs,
latent_upscale_function, latent_upscale_model, pixel_upscale_model)
return (script,)
```