Spaces:
Running
Running
File size: 5,065 Bytes
966ae59 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
import os
import numpy as np
import pydiffvg
import torch
from scipy.optimize import curve_fit
def get_svg_file(path):
files = os.listdir(path)
files = [f for f in files if "best.svg" in f]
return files[0]
def get_seed(filename):
filename = filename[:-9]
keyword = 'seed'
before_keyword, keyword, after_keyword = filename.partition(keyword)
return after_keyword
def get_clip_loss(path, layer):
path_config = path / "config.npy"
config = np.load(path_config, allow_pickle=True)[()]
loss_clip = np.array(config[f"loss_eval"])
best_iter = np.argsort(loss_clip)[0]
loss_clip_layer = np.array(config[f"clip_vit_l{layer}_original_eval"])
return loss_clip, best_iter, loss_clip_layer
def ratios_to_str(ratios):
ratios_str = ""
for r_ in ratios:
r_str = f"{r_:.3f}"
ratios_str += f"{float(r_str)},"
ratios_str = ratios_str[:-1]
return ratios_str
def func(x, a, c, d):
return a * np.exp(c * x)
def func_inv(y, a, c, d):
return np.log(y / a) * (1 / c)
def get_func(ratios_rel, start_x, start_ys):
target_ys = ratios_rel[start_ys:]
x = np.linspace(start_x, start_x + len(target_ys) - 1, len(target_ys))
# calculate exponent
popt, pcov = curve_fit(func, x, target_ys, maxfev=3000)
return popt
def get_clip_loss2(path, layer, object_or_background):
path_config = path / "config.npy"
config = np.load(path_config, allow_pickle=True)[()]
loss_clip = np.array(config[f"loss_eval"])
best_iter = np.argsort(loss_clip)[0]
loss_clip_layer = np.array(config[f"clip_vit_l{layer}_original_eval"])
if object_or_background == "object":
loss_clip_layer4 = np.array(config[f"clip_vit_l4_original_eval"])
loss_clip_layer = 1 * loss_clip_layer4 + loss_clip_layer
return best_iter, loss_clip_layer
def get_ratios_dict(path_to_initial_sketches, folder_name_l, layer, im_name, object_or_background, step_size_l,
num_ratios=8):
# get the sketch of the given layer, and get L_clip_i
svg_filename = get_svg_file(path_to_initial_sketches / folder_name_l)
seed = get_seed(svg_filename)
path_li = path_to_initial_sketches / folder_name_l / f"{folder_name_l}_seed{seed}"
best_iter, loss_clip_layer = get_clip_loss2(path_li, layer, object_or_background)
best_lclip_layer = loss_clip_layer[best_iter]
r_1_k = 1 / best_lclip_layer
# get the next ratios by jumping by 2
r_j_k = r_1_k
ratios_k = [r_1_k]
for j in range(4):
r_j_k = r_j_k / 2
ratios_k.append(r_j_k)
start_ys, start_x, end_x_addition = 0, 0, 0
popt = get_func(ratios_k, start_x=0, start_ys=0) # fit the function to ratios_k
x_1_k = func_inv([r_1_k], *popt)
step_size = step_size_l
num_steps = num_ratios - start_x + end_x_addition
start_ = x_1_k[0]
end = num_steps * step_size
# sample the function from the initial scaled r_1 with the corresponding step size
new_xs_layer_l = np.linspace(start_, end - step_size + start_, num_steps)
# print("new_xs_layer_l", new_xs_layer_l)
ratios_li = func(new_xs_layer_l, *popt)
ratios_str = ratios_to_str(ratios_li)
xs_layer_l_str = ratios_to_str(new_xs_layer_l)
print(f"layer {layer} r_1_k {r_1_k} \n new {ratios_str} \n x {xs_layer_l_str}\n")
return ratios_str
def read_svg(path_svg, multiply=0, resize_obj=False, params=None, opacity=1, device=None):
pydiffvg.set_device(device)
canvas_width, canvas_height, shapes, shape_groups = pydiffvg.svg_to_scene(path_svg)
for group in shape_groups:
group.stroke_color = torch.tensor([0, 0, 0, opacity])
if resize_obj and params:
w, h = params["scale_w"], params["scale_h"]
for path in shapes:
path.points = path.points / canvas_width
path.points = 2 * path.points - 1
path.points[:, 0] /= (w) # / canvas_width)
path.points[:, 1] /= (h) # / canvas_height)
path.points = 0.5 * (path.points + 1.0) * canvas_width
center_x, center_y = canvas_width / 2, canvas_height / 2
path.points[:, 0] += (params["original_center_x"] * canvas_width - center_x)
path.points[:, 1] += (params["original_center_y"] * canvas_height - center_y)
if multiply:
canvas_width *= 2
canvas_height *= 2
for path in shapes:
path.points *= 2
path.stroke_width *= multiply
_render = pydiffvg.RenderFunction.apply
scene_args = pydiffvg.RenderFunction.serialize_scene(
canvas_width, canvas_height, shapes, shape_groups)
img = _render(canvas_width, # width
canvas_height, # height
2, # num_samples_x
2, # num_samples_y
0, # seed
None,
*scene_args)
img = img[:, :, 3:4] * img[:, :, :3] + \
torch.ones(img.shape[0], img.shape[1], 3,
device=device) * (1 - img[:, :, 3:4])
img = img[:, :, :3].cpu().numpy()
return img
|