add easing_type

This commit is contained in:
Chan
2024-03-14 10:14:06 +08:00
parent c4734a310e
commit 04a1eea3c8
2 changed files with 184 additions and 16 deletions
+13 -11
View File
@@ -1,10 +1,9 @@
from nodes import VAEDecode, VAEEncode
import comfy
from .utils import image_2dtransform
from .utils import image_2dtransform, apply_easing, easing_functions
import torch
from tqdm import tqdm
import random
@@ -21,6 +20,7 @@ class Easy2DDeforum:
"positive": ("CONDITIONING", ),
"negative": ("CONDITIONING", ),
"image": ("IMAGE", ),
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
"steps": ("INT", {"default": 20, "min": 1, "max": 10000}),
"cfg": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0, "step":0.1, "round": 0.01}),
"sampler_name": (comfy.samplers.KSampler.SAMPLERS, ),
@@ -32,6 +32,7 @@ class Easy2DDeforum:
"angle": ("INT", {"default": -1, "step": 1, "min": -360, "max": 360}),
"denoise_min": ("FLOAT", {"default": 0.40, "min": 0.00, "max": 1.00, "step":0.01}),
"denoise_max": ("FLOAT", {"default": 0.60, "min": 0.00, "max": 1.00, "step":0.01}),
"easing_type": (list(easing_functions.keys()), ),
}
}
@@ -41,35 +42,36 @@ class Easy2DDeforum:
CATEGORY = "easyDeforum"
def apply(self, model, vae, positive, negative, image, frame, steps, cfg, sampler_name, scheduler, x, y, zoom, angle, denoise_min, denoise_max):
def apply(self, model, vae, positive, negative, image, frame, seed, steps, cfg, sampler_name, scheduler, x, y, zoom, angle, denoise_min, denoise_max, easing_type):
# 初始化模型
vaedecode = VAEDecode()
vaeencode = VAEEncode()
res = [image]
seed = random.randint(0, 1000000000)
pbar = comfy.utils.ProgressBar(frame)
for i in tqdm(range(frame)):
# 计算噪声
denoise = (denoise_max - denoise_min) * apply_easing((i+1)/frame, easing_type) + denoise_min
denoise = (denoise_max - denoise_min) * (i+1) / frame + denoise_min
# 变换
image = image_2dtransform(image, x, y, zoom, angle, 0, "reflect")
# 编码
latent = vaeencode.encode(vae, image)[0]
# 这里得关闭进度
# latent = ksampler.sample(model, i, steps, cfg, sampler_name, scheduler, positive, negative, latent, denoise)[0]
# 这里是关闭
# 计算噪声
noise = comfy.sample.prepare_noise(latent["samples"], i, None)
# 采样
samples = comfy.sample.sample(model, noise, steps, cfg, sampler_name, scheduler, positive, negative, latent["samples"],
denoise=denoise, disable_noise=False, start_step=None, last_step=None,
force_full_denoise=False, noise_mask=None, callback=None, disable_pbar=True, seed=seed+i)
# 解码
image = vaedecode.decode(vae, {"samples": samples})[0]
# 这里还能加预览图片
+171 -5
View File
@@ -1,13 +1,13 @@
from typing import List, Union
import numpy as np
import torch
import torch, math
from PIL import Image
import torch
import torchvision.transforms.functional as TF
from math import sqrt, ceil
from typing import cast
def tensor2pil(image: torch.Tensor) -> List[Image.Image]:
batch_count = image.size(0) if len(image.shape) > 3 else 1
if batch_count > 1:
@@ -50,8 +50,8 @@ def image_2dtransform(
new_height, new_width = int(frame_height * zoom), int(frame_width * zoom)
# - Calculate diagonal of the original image
diagonal = sqrt(frame_width**2 + frame_height**2)
max_padding = ceil(diagonal * zoom - min(frame_width, frame_height))
diagonal = math.sqrt(frame_width**2 + frame_height**2)
max_padding = math.ceil(diagonal * zoom - min(frame_width, frame_height))
# Calculate padding for zoom
pw = int(frame_width - new_width)
ph = int(frame_height - new_height)
@@ -81,4 +81,170 @@ def image_2dtransform(
img = img.crop((left, upper, right, bottom))
return pil2tensor(img)
return pil2tensor(img)
# --------------------------- Easing functions
def easeInBack(t):
s = 1.70158
return t * t * ((s + 1) * t - s)
def easeOutBack(t):
s = 1.70158
return ((t - 1) * t * ((s + 1) * t + s)) + 1
def easeInOutBack(t):
s = 1.70158 * 1.525
if t < 0.5:
return (t * t * (t * (s + 1) - s)) * 2
return ((t - 2) * t * ((s + 1) * t + s) + 2) * 2
# Elastic easing functions
def easeInElastic(t):
if t == 0:
return 0
if t == 1:
return 1
p = 0.3
s = p / 4
return -(math.pow(2, 10 * (t - 1)) * math.sin((t - 1 - s) * (2 * math.pi) / p))
def easeOutElastic(t):
if t == 0:
return 0
if t == 1:
return 1
p = 0.3
s = p / 4
return math.pow(2, -10 * t) * math.sin((t - s) * (2 * math.pi) / p) + 1
def easeInOutElastic(t):
if t == 0:
return 0
if t == 1:
return 1
p = 0.3 * 1.5
s = p / 4
t = t * 2
if t < 1:
return -0.5 * (
math.pow(2, 10 * (t - 1)) * math.sin((t - 1 - s) * (2 * math.pi) / p)
)
return (
0.5 * math.pow(2, -10 * (t - 1)) * math.sin((t - 1 - s) * (2 * math.pi) / p)
+ 1
)
# Bounce easing functions
def easeInBounce(t):
return 1 - easeOutBounce(1 - t)
def easeOutBounce(t):
if t < (1 / 2.75):
return 7.5625 * t * t
elif t < (2 / 2.75):
t -= 1.5 / 2.75
return 7.5625 * t * t + 0.75
elif t < (2.5 / 2.75):
t -= 2.25 / 2.75
return 7.5625 * t * t + 0.9375
else:
t -= 2.625 / 2.75
return 7.5625 * t * t + 0.984375
def easeInOutBounce(t):
if t < 0.5:
return easeInBounce(t * 2) * 0.5
return easeOutBounce(t * 2 - 1) * 0.5 + 0.5
# Quart easing functions
def easeInQuart(t):
return t * t * t * t
def easeOutQuart(t):
t -= 1
return -(t**2 * t * t - 1)
def easeInOutQuart(t):
t *= 2
if t < 1:
return 0.5 * t * t * t * t
t -= 2
return -0.5 * (t**2 * t * t - 2)
# Cubic easing functions
def easeInCubic(t):
return t * t * t
def easeOutCubic(t):
t -= 1
return t**2 * t + 1
def easeInOutCubic(t):
t *= 2
if t < 1:
return 0.5 * t * t * t
t -= 2
return 0.5 * (t**2 * t + 2)
# Circ easing functions
def easeInCirc(t):
return -(math.sqrt(1 - t * t) - 1)
def easeOutCirc(t):
t -= 1
return math.sqrt(1 - t**2)
def easeInOutCirc(t):
t *= 2
if t < 1:
return -0.5 * (math.sqrt(1 - t**2) - 1)
t -= 2
return 0.5 * (math.sqrt(1 - t**2) + 1)
# Sine easing functions
def easeInSine(t):
return -math.cos(t * (math.pi / 2)) + 1
def easeOutSine(t):
return math.sin(t * (math.pi / 2))
def easeInOutSine(t):
return -0.5 * (math.cos(math.pi * t) - 1)
def easeLinear(t):
return t
easing_functions = {
"Linear": easeLinear,
"Sine In": easeInSine,
"Sine Out": easeOutSine,
"Sine In/Out": easeInOutSine,
"Quart In": easeInQuart,
"Quart Out": easeOutQuart,
"Quart In/Out": easeInOutQuart,
"Cubic In": easeInCubic,
"Cubic Out": easeOutCubic,
"Cubic In/Out": easeInOutCubic,
"Circ In": easeInCirc,
"Circ Out": easeOutCirc,
"Circ In/Out": easeInOutCirc,
"Back In": easeInBack,
"Back Out": easeOutBack,
"Back In/Out": easeInOutBack,
"Elastic In": easeInElastic,
"Elastic Out": easeOutElastic,
"Elastic In/Out": easeInOutElastic,
"Bounce In": easeInBounce,
"Bounce Out": easeOutBounce,
"Bounce In/Out": easeInOutBounce,
}
def apply_easing(value, easing_type):
function_ease = easing_functions.get(easing_type)
if function_ease:
return function_ease(value)
raise ValueError(f"Unknown easing type: {easing_type}")
# --------------------------- Easing functions