opt
parent
df3824aa6c
commit
3fd644f9d7
|
|
@ -1,3 +1,7 @@
|
|||
### v2.2.4 - 2024 Aug.28
|
||||
- Optimization *(`internal`)*
|
||||
- Improve Color **Accuracy** ~~Slightly~~
|
||||
|
||||
### v2.2.3 - 2024 Aug.27
|
||||
- Lib *(`internal`)*
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ allowing you to adjust the brightness, contrast, and color of the generations.
|
|||
After installing this Extension, you will see a new section in both **txt2img** and **img2img** tabs.
|
||||
Refer to the parameters and sample images below and play around with the values.
|
||||
|
||||
**Note:** Since this modifies the underlying latent noise, the composition may change drastically.
|
||||
> **Note:** Since this modifies the underlying latent noise, the composition may change drastically
|
||||
|
||||
#### Parameters
|
||||
- **Enable:** Turn on / off this Extension
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
class VectorscopeCC {
|
||||
|
||||
static dot = { 'txt': null, 'img': null };
|
||||
static dot = { 'txt': undefined, 'img': undefined };
|
||||
|
||||
/**
|
||||
* @param {number} r @param {number} g @param {number} b
|
||||
* @param {string} mode "txt" | "img"
|
||||
*/
|
||||
static updateCursor(r, g, b, mode) {
|
||||
const mag = Math.abs(r) + Math.abs(g) + Math.abs(b);
|
||||
var condX, condY;
|
||||
|
|
@ -18,6 +22,11 @@ class VectorscopeCC {
|
|||
this.dot[mode].style.top = `calc(50% + ${condY - 12}px)`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLImageElement} wheel
|
||||
* @param {HTMLInputElement[]} sliders
|
||||
* @param {HTMLImageElement} dot
|
||||
*/
|
||||
static registerPicker(wheel, sliders, dot) {
|
||||
['mousemove', 'click'].forEach((event) => {
|
||||
wheel.addEventListener(event, (e) => {
|
||||
|
|
@ -35,20 +44,7 @@ class VectorscopeCC {
|
|||
const x = ((e.clientX - rect.left) - 100.0) / 25;
|
||||
const y = ((e.clientY - rect.top) - 100.0) / 25;
|
||||
|
||||
const zeta = Math.atan(y / x);
|
||||
var degree = 0;
|
||||
|
||||
if (x >= 0) {
|
||||
if (y >= 0)
|
||||
degree = zeta * 180 / Math.PI;
|
||||
else
|
||||
degree = 360 + zeta * 180 / Math.PI;
|
||||
}
|
||||
else if (x < 0) {
|
||||
degree = 180 + zeta * 180 / Math.PI;
|
||||
}
|
||||
|
||||
var r = -(0.00077 * (433 * x * degree + 750 * y * degree) / degree);
|
||||
var r = -0.077 * (4.33 * x + 7.5 * y);
|
||||
var g = y / 0.866 + r;
|
||||
var b = x + 0.5 * r + 0.5 * g;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from modules.sd_samplers_kdiffusion import KDiffusionSampler
|
||||
from modules import script_callbacks, devices
|
||||
from modules.script_callbacks import on_script_unloaded
|
||||
from functools import wraps
|
||||
from random import random
|
||||
import torch
|
||||
|
|
@ -45,19 +45,19 @@ class NoiseMethods:
|
|||
"""
|
||||
|
||||
noise = NoiseMethods.zeros(latent) if use_zero else NoiseMethods.ones(latent)
|
||||
batchSize, c, w, h = noise.shape
|
||||
b, c, w, h = noise.shape
|
||||
|
||||
device = devices.get_optimal_device()
|
||||
device = latent.device
|
||||
upsampler = torch.nn.Upsample(size=(w, h), mode="bilinear").to(device)
|
||||
|
||||
for b in range(batchSize):
|
||||
for batch in range(b):
|
||||
for i in range(iterations):
|
||||
r = random() * 2 + 2
|
||||
|
||||
wn = max(1, int(w / (r**i)))
|
||||
hn = max(1, int(h / (r**i)))
|
||||
|
||||
noise[b] += (
|
||||
noise[batch] += (
|
||||
upsampler(torch.randn(1, c, hn, wn).to(device)) * discount**i
|
||||
)[0]
|
||||
|
||||
|
|
@ -67,10 +67,10 @@ class NoiseMethods:
|
|||
return noise / noise.std()
|
||||
|
||||
|
||||
def RGB_2_CbCr(r: float, g: float, b: float) -> float:
|
||||
def RGB_2_CbCr(r: float, g: float, b: float) -> tuple[float, float]:
|
||||
"""Convert RGB channels into YCbCr for SDXL"""
|
||||
cb = -0.15 * r - 0.29 * g + 0.44 * b
|
||||
cr = 0.44 * r - 0.37 * g - 0.07 * b
|
||||
cb = -0.17 * r - 0.33 * g + 0.5 * b
|
||||
cr = 0.5 * r - 0.41 * g - 0.08 * b
|
||||
|
||||
return cb, cr
|
||||
|
||||
|
|
@ -94,7 +94,8 @@ def cc_callback(self, d):
|
|||
|
||||
mode = str(self.vec_cc["mode"])
|
||||
method = str(self.vec_cc["method"])
|
||||
source = d[mode]
|
||||
source: torch.Tensor = d[mode]
|
||||
target: torch.Tensor = None
|
||||
|
||||
if "Straight" in method:
|
||||
target = d[mode].detach().clone()
|
||||
|
|
@ -175,4 +176,4 @@ def restore_callback():
|
|||
KDiffusionSampler.callback_state = original_callback
|
||||
|
||||
|
||||
script_callbacks.on_script_unloaded(restore_callback)
|
||||
on_script_unloaded(restore_callback)
|
||||
|
|
|
|||
|
|
@ -7,17 +7,17 @@ DOT = os.path.join(scripts.basedir(), "scripts", "dot.png")
|
|||
|
||||
|
||||
def create_colorpicker(is_img: bool):
|
||||
m = "img" if is_img else "txt"
|
||||
m: str = "img" if is_img else "txt"
|
||||
|
||||
gr.Image(
|
||||
WHEEL,
|
||||
value=WHEEL,
|
||||
interactive=False,
|
||||
container=False,
|
||||
elem_id=f"cc-colorwheel-{m}",
|
||||
)
|
||||
|
||||
gr.Image(
|
||||
DOT,
|
||||
value=DOT,
|
||||
interactive=False,
|
||||
container=False,
|
||||
elem_id=f"cc-temp-{m}",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ EMPTY_STYLE = {"styles": {}, "deleted": {}}
|
|||
|
||||
class StyleManager:
|
||||
def __init__(self):
|
||||
self.STYLE_SHEET = None
|
||||
self.STYLE_SHEET: dict = None
|
||||
|
||||
def load_styles(self):
|
||||
if os.path.isfile(STYLE_FILE):
|
||||
|
|
@ -27,10 +27,10 @@ class StyleManager:
|
|||
|
||||
return self.list_style()
|
||||
|
||||
def list_style(self):
|
||||
def list_style(self) -> list[str]:
|
||||
return list(self.STYLE_SHEET["styles"].keys())
|
||||
|
||||
def get_style(self, style_name: str):
|
||||
def get_style(self, style_name: str) -> tuple[bool | str | float]:
|
||||
style: dict = self.STYLE_SHEET["styles"].get(style_name, None)
|
||||
|
||||
if not style:
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ def grid_reference():
|
|||
|
||||
|
||||
def xyz_support(cache: dict):
|
||||
|
||||
def apply_field(field):
|
||||
def _(p, x, xs):
|
||||
cache.update({field: x})
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 166 KiB |
100
scripts/cc.py
100
scripts/cc.py
|
|
@ -11,7 +11,7 @@ import gradio as gr
|
|||
import lib_cc
|
||||
|
||||
|
||||
VERSION = "v2.2.3"
|
||||
VERSION = "2.2.4"
|
||||
|
||||
|
||||
style_manager = StyleManager()
|
||||
|
|
@ -19,6 +19,7 @@ style_manager.load_styles()
|
|||
|
||||
|
||||
class VectorscopeCC(scripts.Script):
|
||||
|
||||
def __init__(self):
|
||||
self.xyzCache = {}
|
||||
xyz_support(self.xyzCache)
|
||||
|
|
@ -30,11 +31,11 @@ class VectorscopeCC(scripts.Script):
|
|||
return scripts.AlwaysVisible
|
||||
|
||||
def ui(self, is_img2img):
|
||||
mode = "img" if is_img2img else "txt"
|
||||
m = f'"{mode}"'
|
||||
mode: str = "img" if is_img2img else "txt"
|
||||
m: str = f'"{mode}"'
|
||||
|
||||
with gr.Accordion(
|
||||
f"Vectorscope CC {VERSION}", elem_id=f"vec-cc-{mode}", open=False
|
||||
f"Vectorscope CC v{VERSION}", elem_id=f"vec-cc-{mode}", open=False
|
||||
):
|
||||
|
||||
with gr.Row():
|
||||
|
|
@ -151,13 +152,14 @@ class VectorscopeCC(scripts.Script):
|
|||
label="Noise Settings",
|
||||
value="Straight Abs.",
|
||||
)
|
||||
|
||||
scaling = gr.Radio(
|
||||
["Flat", "Cos", "Sin", "1 - Cos", "1 - Sin"],
|
||||
label="Scaling Settings",
|
||||
value="Flat",
|
||||
)
|
||||
|
||||
comps = (
|
||||
comps: tuple[gr.components.Component] = (
|
||||
latent,
|
||||
bri,
|
||||
con,
|
||||
|
|
@ -297,49 +299,40 @@ class VectorscopeCC(scripts.Script):
|
|||
enable = self.xyzCache["Enable"].lower().strip() == "true"
|
||||
|
||||
if not enable:
|
||||
if "Enable" not in self.xyzCache.keys():
|
||||
if len(self.xyzCache) > 0:
|
||||
if "Enable" not in self.xyzCache.keys():
|
||||
print("\n[Vec.CC] x [X/Y/Z Plot] Extension is not Enabled!\n")
|
||||
|
||||
self.xyzCache.clear()
|
||||
|
||||
KDiffusionSampler.vec_cc = {"enable": False}
|
||||
return p
|
||||
|
||||
if "Random" in self.xyzCache.keys():
|
||||
print("[X/Y/Z Plot] x [Vec.CC] Randomize is Enabled.")
|
||||
if len(self.xyzCache) > 1:
|
||||
print(
|
||||
"\n[X/Y/Z Plot] x [Vec.CC] Randomize is Enabled.\nSome settings will not apply!\n"
|
||||
)
|
||||
else:
|
||||
print("\n[X/Y/Z Plot] x [Vec.CC] Randomize is Enabled.\n")
|
||||
print("Some parameters will not apply!")
|
||||
|
||||
cc_seed = int(seeds[0]) if doRN else None
|
||||
|
||||
for k, v in self.xyzCache.items():
|
||||
match k:
|
||||
case "Alt":
|
||||
if "Alt" in self.xyzCache.keys():
|
||||
latent = self.xyzCache["Alt"].lower().strip() == "true"
|
||||
case "Brightness":
|
||||
bri = float(v)
|
||||
case "Contrast":
|
||||
con = float(v)
|
||||
case "Saturation":
|
||||
sat = float(v)
|
||||
case "R":
|
||||
r = float(v)
|
||||
case "G":
|
||||
g = float(v)
|
||||
case "B":
|
||||
b = float(v)
|
||||
case "DoHR":
|
||||
|
||||
if "DoHR" in self.xyzCache.keys():
|
||||
doHR = self.xyzCache["DoHR"].lower().strip() == "true"
|
||||
case "Method":
|
||||
method = str(v)
|
||||
case "Scaling":
|
||||
scaling = str(v)
|
||||
case "Random":
|
||||
cc_seed = int(v)
|
||||
|
||||
if "Random" in self.xyzCache.keys():
|
||||
cc_seed = int(self.xyzCache["Random"])
|
||||
|
||||
bri = float(self.xyzCache.get("Brightness", bri))
|
||||
con = float(self.xyzCache.get("Contrast", con))
|
||||
sat = float(self.xyzCache.get("Saturation", sat))
|
||||
|
||||
r = float(self.xyzCache.get("R", r))
|
||||
g = float(self.xyzCache.get("G", g))
|
||||
b = float(self.xyzCache.get("B", b))
|
||||
|
||||
method = str(self.xyzCache.get("Method", method))
|
||||
scaling = str(self.xyzCache.get("Scaling", scaling))
|
||||
|
||||
self.xyzCache.clear()
|
||||
|
||||
|
|
@ -347,11 +340,7 @@ class VectorscopeCC(scripts.Script):
|
|||
KDiffusionSampler.vec_cc = {"enable": False}
|
||||
return p
|
||||
|
||||
steps: int = p.steps
|
||||
# is img2img & do full steps
|
||||
if not hasattr(p, "enable_hr") and not shared.opts.img2img_fix_steps:
|
||||
if getattr(p, "denoising_strength", 1.0) < 1.0:
|
||||
steps = int(steps * getattr(p, "denoising_strength", 1.0) + 1.0)
|
||||
steps: int = getattr(p, "firstpass_steps", None) or p.steps
|
||||
|
||||
if cc_seed:
|
||||
seed(cc_seed)
|
||||
|
|
@ -373,19 +362,24 @@ class VectorscopeCC(scripts.Script):
|
|||
print(f"B:\t\t{b}\n")
|
||||
|
||||
if getattr(shared.opts, "cc_metadata", True):
|
||||
p.extra_generation_params["Vec CC Enabled"] = enable
|
||||
p.extra_generation_params["Vec CC Alt"] = latent
|
||||
p.extra_generation_params["Vec CC Brightness"] = bri
|
||||
p.extra_generation_params["Vec CC Contrast"] = con
|
||||
p.extra_generation_params["Vec CC Saturation"] = sat
|
||||
p.extra_generation_params["Vec CC R"] = r
|
||||
p.extra_generation_params["Vec CC G"] = g
|
||||
p.extra_generation_params["Vec CC B"] = b
|
||||
p.extra_generation_params["Vec CC Noise"] = method
|
||||
p.extra_generation_params["Vec CC Proc HrF"] = doHR
|
||||
p.extra_generation_params["Vec CC Proc Ade"] = doAD
|
||||
p.extra_generation_params["Vec CC Scaling"] = scaling
|
||||
p.extra_generation_params["Vec CC Version"] = VERSION
|
||||
p.extra_generation_params.update(
|
||||
{
|
||||
"Vec CC Enabled": enable,
|
||||
"Vec CC Alt": latent,
|
||||
"Vec CC Brightness": bri,
|
||||
"Vec CC Contrast": con,
|
||||
"Vec CC Saturation": sat,
|
||||
"Vec CC R": r,
|
||||
"Vec CC G": g,
|
||||
"Vec CC B": b,
|
||||
"Vec CC Noise": method,
|
||||
"Vec CC Proc HrF": doHR,
|
||||
"Vec CC Proc Ade": doAD,
|
||||
"Vec CC Seed Randomize": doRN,
|
||||
"Vec CC Scaling": scaling,
|
||||
"Vec CC Version": VERSION,
|
||||
}
|
||||
)
|
||||
|
||||
bri /= steps
|
||||
con /= steps
|
||||
|
|
@ -394,7 +388,7 @@ class VectorscopeCC(scripts.Script):
|
|||
g /= steps
|
||||
b /= steps
|
||||
|
||||
mode = "x" if latent else "denoised"
|
||||
mode: str = "x" if latent else "denoised"
|
||||
|
||||
KDiffusionSampler.vec_cc = {
|
||||
"enable": True,
|
||||
|
|
|
|||
|
|
@ -7,16 +7,15 @@ import cv2 as cv
|
|||
|
||||
|
||||
# https://docs.opencv.org/4.8.0/d2/df0/tutorial_py_hdr.html
|
||||
def merge_HDR(imgs: list, path: str, depth: str, fmt: str, gamma: float):
|
||||
def merge_HDR(imgs: list, path: str, depth: str, fmt: str, gamma: float) -> np.ndarray:
|
||||
import datetime
|
||||
import math
|
||||
import os
|
||||
|
||||
output_folder = os.path.join(path, "hdr")
|
||||
if not os.path.exists(output_folder):
|
||||
os.makedirs(output_folder)
|
||||
os.makedirs(output_folder, exist_ok=True)
|
||||
|
||||
imgs_np = [np.array(img, dtype=np.uint8) for img in imgs]
|
||||
imgs_np = [np.asarray(img).astype(np.uint8) for img in imgs]
|
||||
|
||||
merge = cv.createMergeMertens()
|
||||
hdr = merge.process(imgs_np)
|
||||
|
|
@ -39,8 +38,11 @@ def merge_HDR(imgs: list, path: str, depth: str, fmt: str, gamma: float):
|
|||
rgb,
|
||||
)
|
||||
|
||||
return ldr
|
||||
|
||||
|
||||
class VectorHDR(scripts.Script):
|
||||
|
||||
def title(self):
|
||||
return "High Dynamic Range"
|
||||
|
||||
|
|
@ -49,14 +51,14 @@ class VectorHDR(scripts.Script):
|
|||
|
||||
def ui(self, is_img2img):
|
||||
with gr.Row():
|
||||
count = gr.Slider(label="Brackets", minimum=3, maximum=9, step=2, value=7)
|
||||
count = gr.Slider(label="Brackets", minimum=3, maximum=9, step=2, value=5)
|
||||
gap = gr.Slider(
|
||||
label="Gaps", minimum=0.50, maximum=2.50, step=0.25, value=1.50
|
||||
label="Gaps", minimum=0.50, maximum=2.50, step=0.25, value=1.25
|
||||
)
|
||||
|
||||
with gr.Accordion(
|
||||
"Merge Options",
|
||||
elem_id="vec-hdr-" + ("img" if is_img2img else "txt"),
|
||||
elem_id=f'vec-hdr-{"img" if is_img2img else "txt"}',
|
||||
open=False,
|
||||
):
|
||||
auto = gr.Checkbox(label="Automatically Merge", value=True)
|
||||
|
|
@ -85,16 +87,7 @@ class VectorHDR(scripts.Script):
|
|||
center = count // 2
|
||||
|
||||
p.seed = get_fixed_seed(p.seed)
|
||||
p.scripts.script("vectorscope cc").xyzCache.update(
|
||||
{
|
||||
"Enable": "True",
|
||||
"Alt": "True",
|
||||
"Brightness": 0,
|
||||
"DoHR": "False",
|
||||
"Method": "Ones",
|
||||
"Scaling": "1 - Cos",
|
||||
}
|
||||
)
|
||||
p.scripts.script("vectorscope cc").xyzCache.update({"Enable": "False"})
|
||||
|
||||
baseline = process_images(p)
|
||||
pc = copy(p)
|
||||
|
|
@ -109,7 +102,14 @@ class VectorHDR(scripts.Script):
|
|||
continue
|
||||
|
||||
pc.scripts.script("vectorscope cc").xyzCache.update(
|
||||
{"Brightness": brackets[it]}
|
||||
{
|
||||
"Enable": "True",
|
||||
"Alt": "True",
|
||||
"Brightness": brackets[it],
|
||||
"DoHR": "False",
|
||||
"Method": "Ones",
|
||||
"Scaling": "1 - Cos",
|
||||
}
|
||||
)
|
||||
|
||||
proc = process_images(pc)
|
||||
|
|
@ -117,13 +117,12 @@ class VectorHDR(scripts.Script):
|
|||
|
||||
if not auto:
|
||||
baseline.images = imgs
|
||||
return baseline
|
||||
|
||||
else:
|
||||
merge_HDR(imgs, p.outpath_samples, depth, fmt, gamma)
|
||||
baseline.images = [merge_HDR(imgs, p.outpath_samples, depth, fmt, gamma)]
|
||||
|
||||
return baseline
|
||||
|
||||
|
||||
def brightness_brackets(count, gap):
|
||||
def brightness_brackets(count: int, gap: int) -> list[int]:
|
||||
half = count // 2
|
||||
return [gap * (i - half) for i in range(count)]
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 178 KiB |
Loading…
Reference in New Issue