Spaces:
Sleeping
Sleeping
""" | |
""" | |
import os | |
import pydiffvg | |
import torch as th | |
import scipy.ndimage.filters as F | |
def render(canvas_width, canvas_height, shapes, shape_groups): | |
_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) | |
return img | |
def main(): | |
pydiffvg.set_device(th.device('cuda:1')) | |
# Load SVG | |
svg = os.path.join("imgs", "peppers.svg") | |
canvas_width, canvas_height, shapes, shape_groups = \ | |
pydiffvg.svg_to_scene(svg) | |
# Save initial state | |
ref = render(canvas_width, canvas_height, shapes, shape_groups) | |
pydiffvg.imwrite(ref.cpu(), 'results/gaussian_blur/init.png', gamma=2.2) | |
target = F.gaussian_filter(ref.cpu().numpy(), [10, 10, 0]) | |
target = th.from_numpy(target).to(ref.device) | |
pydiffvg.imwrite(target.cpu(), 'results/gaussian_blur/target.png', gamma=2.2) | |
# Collect variables to optimize | |
points_vars = [] | |
width_vars = [] | |
for path in shapes: | |
path.points.requires_grad = True | |
points_vars.append(path.points) | |
path.stroke_width.requires_grad = True | |
width_vars.append(path.stroke_width) | |
color_vars = [] | |
for group in shape_groups: | |
# do not optimize alpha | |
group.fill_color[..., :3].requires_grad = True | |
color_vars.append(group.fill_color) | |
# Optimize | |
points_optim = th.optim.Adam(points_vars, lr=1.0) | |
width_optim = th.optim.Adam(width_vars, lr=1.0) | |
color_optim = th.optim.Adam(color_vars, lr=0.01) | |
for t in range(20): | |
print('\niteration:', t) | |
points_optim.zero_grad() | |
width_optim.zero_grad() | |
color_optim.zero_grad() | |
# Forward pass: render the image. | |
img = render(canvas_width, canvas_height, shapes, shape_groups) | |
# Save the intermediate render. | |
pydiffvg.imwrite(img.cpu(), 'results/gaussian_blur/iter_{}.png'.format(t), gamma=2.2) | |
loss = (img - target)[..., :3].pow(2).mean() | |
print('alpha:', img[..., 3].mean().item()) | |
print('render loss:', loss.item()) | |
# Backpropagate the gradients. | |
loss.backward() | |
# Take a gradient descent step. | |
points_optim.step() | |
width_optim.step() | |
color_optim.step() | |
for group in shape_groups: | |
group.fill_color.data.clamp_(0.0, 1.0) | |
# Final render | |
img = render(canvas_width, canvas_height, shapes, shape_groups) | |
pydiffvg.imwrite(img.cpu(), 'results/gaussian_blur/final.png', gamma=2.2) | |
# Convert the intermediate renderings to a video. | |
from subprocess import call | |
call(["ffmpeg", "-framerate", "24", "-i", | |
"results/gaussian_blur/iter_%d.png", "-vb", "20M", | |
"results/gaussian_blur/out.mp4"]) | |
if __name__ == "__main__": | |
main() | |