Files
diffvg/gradientmesh/test.py
2023-05-15 16:22:28 +02:00

178 lines
4.8 KiB
Python

from __future__ import annotations
from time import sleep
import pydiffvg
import torch
import random
from random import uniform
from gmtypes import GradientMesh, Quad, Patch, Point, join_quads
def quads():
return [
Quad.random(),
Quad.random(),
Quad.random(),
Quad.random(),
]
def rand_quad_test(filename='random_quad.png', width=256, height=256,
degree=4, num_control_points=2):
pydiffvg.set_use_gpu(torch.cuda.is_available())
render = pydiffvg.RenderFunction.apply
patch = Patch.random()
shape_groups = [patch.as_shape_group()]
shapes = [patch.as_path(width, height)]
scene_args = pydiffvg.RenderFunction.serialize_scene(width, height,
shapes, shape_groups)
img = render(width, height, 2, 2, 0, None, *scene_args)
pydiffvg.imwrite(img.cpu(), f"test_data/{filename}", gamma=2.2)
return img
def mult_quad_test(filename='multiple_quads.png', width=1024,
height=1024, num_control_points=None, mask=None, seed=None):
random.seed(seed)
mask = mask or [1, 1, 1, 1]
pydiffvg.set_use_gpu(torch.cuda.is_available())
render = pydiffvg.RenderFunction.apply
a, b, c, d = quads()
join_quads(a, b, c, d)
to_render = [a, b, c, d]
to_render = [x for x in to_render if mask[to_render.index(x)]]
shape_groups = [patch.as_shape_group(color=(
uniform(0, 1),
uniform(0, 1),
uniform(0, 1),
0.8
)) for patch in to_render]
for i in range(len(to_render)):
shape_groups[i].shape_ids = torch.tensor([i])
shapes = [patch.as_path(width, height) for patch in to_render]
scene_args = pydiffvg.RenderFunction.serialize_scene(width, height,
shapes, shape_groups)
img = render(width, height, 2, 2, 0, None, *scene_args)
pydiffvg.imwrite(img.cpu(), f"test_data/{filename}", gamma=2.2)
return img.clone()
def om():
filename = 'optimize_test.png'
pydiffvg.set_use_gpu(torch.cuda.is_available())
render = pydiffvg.RenderFunction.apply
target = mult_quad_test(width=256, height=256)
squad = quads()
join_quads(*squad)
gm = GradientMesh(*squad)
points_n = []
for s in squad:
out = []
for pt in s.points:
out.append([pt.x, pt.y])
for cpt in pt.controls:
out.append([cpt.x, cpt.y])
points_n.append(out)
points_n = torch.tensor(points_n, requires_grad=True)
color = torch.tensor([s.color for s in squad], requires_grad=True)
paths = [s.as_path() for s in squad]
path_groups = [pydiffvg.ShapeGroup(shape_ids=torch.tensor([i]),
fill_color=torch.tensor(squad[i].color))
for i in range(len(squad))]
scene_args = pydiffvg.RenderFunction.serialize_scene(
256, 256, paths, path_groups
)
img = render(256, # width
256, # height
2, # num_samples_x
2, # num_samples_y
1, # seed
None,
*scene_args)
points, controls, color = [torch.tensor(x, requires_grad=True)
for x in gm.to_numbers()]
optimizer = torch.optim.Adam([points, color, points_n], lr=1e-2)
for t in range(180):
print(f"iteration {t}")
optimizer.zero_grad()
points_n.data = torch.tensor(
GradientMesh.from_path_points(points_n, color).to_path_points()
)
for i in range(len(paths)):
paths[i].points = points_n[i] * 256
for i in range(len(path_groups)):
path_groups[i].fill_color = color[i]
scene_args = pydiffvg.RenderFunction.serialize_scene(
256, 256, paths, path_groups)
img = render(256, # width
256, # height
2, # num_samples_x
2, # num_samples_y
t+1, # seed
None,
*scene_args)
pydiffvg.imwrite(img.cpu(),
f'test_data/test_curve/iter_{filename}_'
f'{str(t).zfill(5)}.png',
gamma=2.2)
loss = (img - target).pow(2).sum()
loss.backward()
print(f'loss: {loss}')
print(f'points.grad {points.grad}')
print(f'color.grad {color.grad}')
optimizer.step()
def slideshow(n=30, s=1, do_mask=False):
mask = None
for i in range(n):
if do_mask:
mask = [1] * 4
print(i % n)
mask[i % 4] = 0
print(mask)
mult_quad_test(mask=mask)
sleep(s)
def get_mesh():
a, b, c, d = quads()
join_quads(a,b,c,d)
gm = GradientMesh(a, b, c, d)
return gm