|
import math
|
|
import torch
|
|
import numpy as np
|
|
from torchvision import transforms
|
|
from .latent_math_encoder import linear_encoder
|
|
from .latent_noise_generator import gaussian_latent_noise
|
|
|
|
class MathEncode:
|
|
"""
|
|
Encode latents without using a NN.
|
|
"""
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
return {
|
|
"required": {
|
|
"pixels": ("IMAGE",),
|
|
"latent_ver": (["v1", "xl"],),
|
|
"mode": ([
|
|
"linear_encoder",
|
|
],),
|
|
}
|
|
}
|
|
RETURN_TYPES = ("LATENT",)
|
|
FUNCTION = "encode"
|
|
CATEGORY = "latent"
|
|
TITLE = "Math Encoder"
|
|
|
|
def encode(self, pixels, latent_ver, mode):
|
|
out = []
|
|
for batch, img in enumerate(pixels.numpy()):
|
|
|
|
lat_size = (round(img.shape[0]/8), round(img.shape[1]/8))
|
|
img = img.transpose((2, 0, 1))
|
|
img = torch.from_numpy(img)
|
|
img = transforms.Resize(lat_size, antialias=True)(img)
|
|
|
|
lat = linear_encoder(img, latent_ver)
|
|
out.append(lat)
|
|
return ({"samples":torch.stack(out)},)
|
|
|
|
|
|
class LatentGaussianNoise:
|
|
"""
|
|
Create Gaussian noise directly in latent space.
|
|
"""
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
return {
|
|
"required": {
|
|
"latent_ver": (["v1", "xl"],),
|
|
"width": ("INT", {"default": 768, "min": 64, "max": 8192, "step": 8}),
|
|
"height": ("INT", {"default": 768, "min": 64, "max": 8192, "step": 8}),
|
|
"factor": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.05}),
|
|
"null": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.05}),
|
|
"batch_size": ("INT", {"default": 1, "min": 1, "max": 64}),
|
|
"scale": ("INT", {"default": 1, "min": 1, "max": 8}),
|
|
"random": (["shared", "per channel"],),
|
|
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
|
|
}
|
|
}
|
|
RETURN_TYPES = ("LATENT",)
|
|
FUNCTION = "generate"
|
|
CATEGORY = "noise"
|
|
TITLE = "Gaussian Noise (Latent)"
|
|
|
|
def generate(self, latent_ver, width, height, factor, null, batch_size, scale, random, seed):
|
|
out = []
|
|
for b in range(batch_size):
|
|
lat = gaussian_latent_noise(
|
|
width = round(width/8/scale),
|
|
height = round(height/8/scale),
|
|
ver = latent_ver,
|
|
seed = seed+b,
|
|
fac = factor,
|
|
nul = null,
|
|
srnd = True if random == "shared" else False,
|
|
)
|
|
if scale > 1:
|
|
target = (round(height/8),round(width/8))
|
|
lat = transforms.Resize(target, antialias=True)(lat)
|
|
out.append(lat)
|
|
out = torch.stack(out)
|
|
|
|
return ({"samples":out},)
|
|
|
|
|
|
NODE_CLASS_MAPPINGS = {
|
|
"MathEncode": MathEncode,
|
|
"LatentGaussianNoise": LatentGaussianNoise,
|
|
}
|
|
|
|
NODE_DISPLAY_NAME_MAPPINGS = {
|
|
"MathEncode": MathEncode.TITLE,
|
|
"LatentGaussianNoise": LatentGaussianNoise.TITLE,
|
|
}
|
|
|