add easing_type
This commit is contained in:
@@ -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]
|
||||
|
||||
# 这里还能加预览图片
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user