repos
/ ai-art master

ai-art

mirror archived upstream

Art generation with VQGAN + CLIP in Docker, with a simple web UI for anyone with a GPU. A simplified and expanded take on Kevin Costa's work.

aiai-artclipdockerdocker-composegpuhandcodedimagenetpythonpytorchtorchtorchvisionvqganvqgan-clip

3.1 KB · 100 lines · Python Raw History
 1import numpy as np
 2
 3from PIL import Image
 4
 5
 6def perlin_noise_2d(shape, res):
 7    def interpolant(t):
 8        return t * t * t * (t * (t * 6 - 15) + 10)
 9
10    delta = (res[0] / shape[0], res[1] / shape[1])
11    d = (shape[0] // res[0], shape[1] // res[1])
12    grid = np.mgrid[0 : res[0] : delta[0], 0 : res[1] : delta[1]].transpose(1, 2, 0) % 1
13
14    # Gradients
15    angles = 2 * np.pi * np.random.rand(res[0] + 1, res[1] + 1)
16    gradients = np.dstack((np.cos(angles), np.sin(angles)))
17    gradients = gradients.repeat(d[0], 0).repeat(d[1], 1)
18    g00 = gradients[: -d[0], : -d[1]]
19    g10 = gradients[d[0] :, : -d[1]]
20    g01 = gradients[: -d[0], d[1] :]
21    g11 = gradients[d[0] :, d[1] :]
22
23    # Ramps
24    n00 = np.sum(np.dstack((grid[:, :, 0], grid[:, :, 1])) * g00, 2)
25    n10 = np.sum(np.dstack((grid[:, :, 0] - 1, grid[:, :, 1])) * g10, 2)
26    n01 = np.sum(np.dstack((grid[:, :, 0], grid[:, :, 1] - 1)) * g01, 2)
27    n11 = np.sum(np.dstack((grid[:, :, 0] - 1, grid[:, :, 1] - 1)) * g11, 2)
28
29    # Interpolation
30    t = interpolant(grid)
31    n0 = n00 * (1 - t[:, :, 0]) + t[:, :, 0] * n10
32    n1 = n01 * (1 - t[:, :, 0]) + t[:, :, 0] * n11
33    return np.sqrt(2) * ((1 - t[:, :, 1]) * n0 + t[:, :, 1] * n1)
34
35
36def fractal_noise_2d(shape, res, octaves=1, persistence=0.5, lacunarity=2):
37    noise = np.zeros(shape)
38    frequency = 1
39    amplitude = 1
40
41    for _ in range(octaves):
42        noise += amplitude * perlin_noise_2d(
43            shape, (frequency * res[0], frequency * res[1])
44        )
45        frequency *= lacunarity
46        amplitude *= persistence
47    return (noise - np.min(noise)) / (np.max(noise) - np.min(noise))
48
49
50def random_fractal_image(width, height):
51    _pow = int(np.ceil(np.log(max(width, height)) / np.log(2)))
52    octaves = _pow - 4
53    size = 2**_pow
54    r = fractal_noise_2d((size, size), (32, 32), octaves=octaves)
55    g = fractal_noise_2d((size, size), (32, 32), octaves=octaves)
56    b = fractal_noise_2d((size, size), (32, 32), octaves=octaves)
57
58    tile = np.dstack((r, g, b))[:height, :width, :]
59    return Image.fromarray((255.9 * tile).astype("uint8"))
60
61
62def random_noise_image(width, height):
63    return Image.fromarray(
64        np.random.randint(0, 255, (width, height, 3), dtype=np.dtype("uint8"))
65    )
66
67
68def gradient_2d(start, stop, width, height, is_horizontal):
69    if is_horizontal:
70        return np.tile(np.linspace(start, stop, width), (height, 1))
71    else:
72        return np.tile(np.linspace(start, stop, height), (width, 1)).T
73
74
75def gradient_3d(width, height, starts, stops, is_horizontal_list):
76    result = np.zeros((height, width, len(starts)), dtype=float)
77
78    for i, (start, stop, is_horizontal) in enumerate(
79        zip(starts, stops, is_horizontal_list)
80    ):
81        result[:, :, i] = gradient_2d(start, stop, width, height, is_horizontal)
82
83    return result
84
85
86def random_gradient_image(width, height):
87    array = gradient_3d(
88        width,
89        height,
90        (0, 0, np.random.randint(0, 255)),
91        (
92            np.random.randint(1, 255),
93            np.random.randint(2, 255),
94            np.random.randint(3, 128),
95        ),
96        (True, False, False),
97    )
98    random_image = Image.fromarray(np.uint8(array))
99    return random_image