File size: 2,955 Bytes
ac73e0b
 
 
 
 
0f44356
8741690
 
ac73e0b
5b17844
 
 
ac73e0b
 
c1bccc1
ac73e0b
8741690
c1bccc1
ac73e0b
9d6728f
 
 
0d21fa6
9d6728f
0d21fa6
9d6728f
0d21fa6
9d6728f
0d21fa6
c1bccc1
ac73e0b
8741690
 
 
c1bccc1
ac73e0b
c1bccc1
 
 
 
0d21fa6
 
 
ac73e0b
0d21fa6
c1bccc1
0d21fa6
c1bccc1
0d21fa6
 
 
ac73e0b
c1bccc1
 
 
 
 
 
 
 
 
 
 
 
0d21fa6
c1bccc1
 
 
 
 
0d21fa6
c1bccc1
0d21fa6
 
c1bccc1
 
0d21fa6
 
 
c1bccc1
 
0d21fa6
c1bccc1
 
0d21fa6
c1bccc1
 
ac73e0b
c1bccc1
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
import numpy as np
import cv2
import gradio as gr

PCA_MODEL_PATH = "pca_texture_model.npy"
COMPONENT_NAMES_PATH = "component_names.txt"

# Load PCA model
pca = np.load(PCA_MODEL_PATH, allow_pickle=True).item()
mean_texture = pca.mean_
components = pca.components_
explained_variance = pca.explained_variance_

n_components = components.shape[0]
TEXTURE_SIZE = int(np.sqrt(mean_texture.shape[0] // 3))

# Calculate slider ranges
slider_ranges = [3 * np.sqrt(var) for var in explained_variance]

# Load component names if available
try:
    with open(COMPONENT_NAMES_PATH, "r") as f:
        component_names = [f"Component {i+1} ({line.strip()})" if line.strip() else f"Component {i+1}" for i, line in enumerate(f.readlines())]
    if len(component_names) < n_components:
        component_names += [f"Component {i+1}" for i in range(len(component_names), n_components)]
except FileNotFoundError:
    component_names = [f"Component {i+1}" for i in range(n_components)]

def generate_texture(*component_values):
    component_values = np.array(component_values)
    new_texture = mean_texture + np.dot(component_values, components)
    new_texture = np.clip(new_texture, 0, 255).astype(np.uint8)
    new_texture = new_texture.reshape((TEXTURE_SIZE, TEXTURE_SIZE, 3))
    new_texture = cv2.cvtColor(new_texture, cv2.COLOR_BGR2RGB)
    return new_texture

def randomize_texture():
    sampled_coefficients = np.random.normal(0, np.sqrt(explained_variance), size=n_components)
    return sampled_coefficients.tolist()

def update_texture(*component_values):
    texture = generate_texture(*component_values)
    return texture

def on_random_click():
    random_values = randomize_texture()
    texture = generate_texture(*random_values)
    # Prepare updates for sliders and the image
    updates = [gr.update(value=value) for value in random_values]
    updates.append(texture)
    return updates

# Create Gradio interface
with gr.Blocks() as demo:
    with gr.Row():
        with gr.Column():
            sliders = []
            for i in range(n_components):
                range_limit = slider_ranges[i]
                slider = gr.Slider(
                    minimum=-range_limit,
                    maximum=range_limit,
                    step=10,
                    value=0,
                    label=component_names[i]
                )
                sliders.append(slider)
            random_button = gr.Button("Randomize Texture")
        with gr.Column():
            output_image = gr.Image(
                label="Generated Texture"
            )
    
    # Update texture when any slider changes
    for slider in sliders:
        slider.change(
            fn=update_texture,
            inputs=sliders,
            outputs=output_image
        )

    # Randomize texture and update sliders and image
    random_button.click(
        fn=on_random_click,
        inputs=None,
        outputs=[*sliders, output_image]
    )

demo.launch()