File size: 3,632 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
5c0bb25
 
 
 
 
 
 
 
 
c1bccc1
 
 
 
 
 
 
 
 
 
 
 
0d21fa6
c1bccc1
 
 
 
0d21fa6
c1bccc1
5c0bb25
 
 
cc976c1
5c0bb25
 
0d21fa6
 
c1bccc1
 
0d21fa6
 
 
c1bccc1
 
0d21fa6
c1bccc1
 
0d21fa6
c1bccc1
 
ac73e0b
5c0bb25
 
 
 
 
 
 
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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

def on_image_upload(image):
    # Process the uploaded image and get PCA coefficients
    coefficients = process_uploaded_image(image)
    texture = generate_texture(*coefficients)
    # Update sliders and image
    updates = [gr.update(value=value) for value in coefficients]
    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)
        with gr.Column():
            output_image = gr.Image(
                label="Generated Texture"
            )
            random_button = gr.Button("Randomize Texture")
            upload_image = gr.Image(
                label="Upload Image",
                sources=['upload', 'clipboard'],
                type="numpy"
            )
    
    # 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]
    )

    # Update sliders and image based on uploaded image
    upload_image.change(
        fn=on_image_upload,
        inputs=upload_image,
        outputs=[*sliders, output_image]
    )

demo.launch()