stzhao commited on
Commit
7eb82c5
1 Parent(s): ea0fdab

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +77 -0
app.py ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import skia
2
+ import numpy as np
3
+ import gradio as gr
4
+
5
+ def load_image(path):
6
+ return skia.Image.open(path)
7
+
8
+ def save_image(image, path):
9
+ image.save(path)
10
+
11
+ def image_to_array(image):
12
+ return np.array(image)
13
+
14
+ def array_to_image(array):
15
+ return skia.Image.fromarray(np.uint8(array))
16
+
17
+ def texture_image_with_normal(A, A_normal, B):
18
+ # Load images
19
+ A_img = load_image(A)
20
+ A_normal_img = load_image(A_normal)
21
+ B_img = load_image(B)
22
+
23
+ # Convert images to numpy arrays
24
+ A_array = image_to_array(A_img)
25
+ A_normal_array = image_to_array(A_normal_img)
26
+ B_array = image_to_array(B_img)
27
+
28
+ # Ensure all images have the same dimensions
29
+ assert A_array.shape == A_normal_array.shape == B_array.shape, "All images must have the same dimensions."
30
+
31
+ # Normalize the normal map (values should be between 0 and 1)
32
+ A_normal_array = A_normal_array / 255.0
33
+
34
+ # Create an empty array for the textured image
35
+ textured_array = np.zeros_like(A_array, dtype=np.float32)
36
+
37
+ # Texture the image B onto A based on the normal map
38
+ for y in range(A_array.shape[0]):
39
+ for x in range(A_array.shape[1]):
40
+ # Get the normal vector at this pixel
41
+ normal = A_normal_array[y, x]
42
+
43
+ # Calculate the offset based on the normal vector
44
+ offset_x = int(normal[0] * B_array.shape[1])
45
+ offset_y = int(normal[1] * B_array.shape[0])
46
+
47
+ # Calculate the new coordinates in B
48
+ new_x = (x + offset_x) % B_array.shape[1]
49
+ new_y = (y + offset_y) % B_array.shape[0]
50
+
51
+ # Apply the texture from B to A
52
+ textured_array[y, x] = B_array[new_y, new_x]
53
+
54
+ # Convert the textured array back to an image
55
+ textured_image = array_to_image(textured_array)
56
+
57
+ return textured_image
58
+
59
+ def gradio_interface(A, A_normal, B):
60
+ textured_image = texture_image_with_normal(A, A_normal, B)
61
+ return np.array(textured_image)
62
+
63
+ # Create Gradio interface
64
+ iface = gr.Interface(
65
+ fn=gradio_interface,
66
+ inputs=[
67
+ gr.inputs.Image(type="filepath", label="Image A"),
68
+ gr.inputs.Image(type="filepath", label="Normal Map A_normal"),
69
+ gr.inputs.Image(type="filepath", label="Image B")
70
+ ],
71
+ outputs=gr.outputs.Image(type="numpy", label="Textured Image"),
72
+ title="Image Texturing with Normal Map",
73
+ description="Upload Image A, its Normal Map A_normal, and Image B to texture B onto A based on A_normal."
74
+ )
75
+
76
+ # Launch the interface
77
+ iface.launch()