Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
@@ -14,23 +14,19 @@ from PIL import Image
|
|
14 |
import sf3d.utils as sf3d_utils
|
15 |
from sf3d.system import SF3D
|
16 |
|
17 |
-
# Initialize the rembg session
|
18 |
rembg_session = rembg.new_session()
|
19 |
|
20 |
-
# Constants
|
21 |
COND_WIDTH = 512
|
22 |
COND_HEIGHT = 512
|
23 |
COND_DISTANCE = 1.6
|
24 |
COND_FOVY_DEG = 40
|
25 |
BACKGROUND_COLOR = [0.5, 0.5, 0.5]
|
26 |
|
27 |
-
# Cached camera parameters
|
28 |
c2w_cond = sf3d_utils.default_cond_c2w(COND_DISTANCE)
|
29 |
intrinsic, intrinsic_normed_cond = sf3d_utils.create_intrinsic_from_fov_deg(
|
30 |
COND_FOVY_DEG, COND_HEIGHT, COND_WIDTH
|
31 |
)
|
32 |
|
33 |
-
# Load the model
|
34 |
model = SF3D.from_pretrained(
|
35 |
"stabilityai/stable-fast-3d",
|
36 |
config_name="config.yaml",
|
@@ -38,9 +34,7 @@ model = SF3D.from_pretrained(
|
|
38 |
)
|
39 |
model.eval().cuda()
|
40 |
|
41 |
-
example_files = [
|
42 |
-
os.path.join("demo_files/examples", f) for f in os.listdir("demo_files/examples")
|
43 |
-
]
|
44 |
|
45 |
def run_model(input_image):
|
46 |
start = time.time()
|
@@ -53,23 +47,15 @@ def run_model(input_image):
|
|
53 |
|
54 |
tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".glb")
|
55 |
trimesh_mesh.export(tmp_file.name, file_type="glb", include_normals=True)
|
56 |
-
|
57 |
print("Generation took:", time.time() - start, "s")
|
58 |
return tmp_file.name
|
59 |
|
60 |
def create_batch(input_image: Image) -> dict[str, Any]:
|
61 |
-
img_cond = (
|
62 |
-
|
63 |
-
|
64 |
-
/ 255.0
|
65 |
-
)
|
66 |
-
.float()
|
67 |
-
.clip(0, 1)
|
68 |
-
)
|
69 |
mask_cond = img_cond[:, :, -1:]
|
70 |
-
rgb_cond = torch.lerp(
|
71 |
-
torch.tensor(BACKGROUND_COLOR)[None, None, :], img_cond[:, :, :3], mask_cond
|
72 |
-
)
|
73 |
|
74 |
batch_elem = {
|
75 |
"rgb_cond": rgb_cond,
|
@@ -87,11 +73,7 @@ def checkerboard(squares: int, size: int, min_value: float = 0.5):
|
|
87 |
base[1::2, ::2] = 1
|
88 |
base[::2, 1::2] = 1
|
89 |
repeat_mult = size // squares
|
90 |
-
return (
|
91 |
-
base.repeat(repeat_mult, axis=0)
|
92 |
-
.repeat(repeat_mult, axis=1)[:, :, None]
|
93 |
-
.repeat(3, axis=-1)
|
94 |
-
)
|
95 |
|
96 |
def remove_background(input_image: Image) -> Image:
|
97 |
return rembg.remove(input_image, session=rembg_session)
|
@@ -105,22 +87,12 @@ def resize_foreground(image: Image, ratio: float) -> Image:
|
|
105 |
size = max(fg.shape[0], fg.shape[1])
|
106 |
ph0, pw0 = (size - fg.shape[0]) // 2, (size - fg.shape[1]) // 2
|
107 |
ph1, pw1 = size - fg.shape[0] - ph0, size - fg.shape[1] - pw0
|
108 |
-
new_image = np.pad(
|
109 |
-
fg,
|
110 |
-
((ph0, ph1), (pw0, pw1), (0, 0)),
|
111 |
-
mode="constant",
|
112 |
-
constant_values=0,
|
113 |
-
)
|
114 |
|
115 |
new_size = int(new_image.shape[0] / ratio)
|
116 |
ph0, pw0 = (new_size - size) // 2, (new_size - size) // 2
|
117 |
ph1, pw1 = new_size - size - ph0, new_size - size - pw0
|
118 |
-
new_image = np.pad(
|
119 |
-
new_image,
|
120 |
-
((ph0, ph1), (pw0, pw1), (0, 0)),
|
121 |
-
mode="constant",
|
122 |
-
constant_values=0,
|
123 |
-
)
|
124 |
new_image = Image.fromarray(new_image, mode="RGBA").resize((COND_WIDTH, COND_HEIGHT))
|
125 |
return new_image
|
126 |
|
@@ -221,78 +193,47 @@ class CustomTheme(gr.themes.Base):
|
|
221 |
)
|
222 |
|
223 |
css = """
|
224 |
-
html, body {
|
225 |
-
margin: 0;
|
226 |
-
padding: 0;
|
227 |
background-color: #191a1e !important;
|
228 |
-
|
229 |
-
|
230 |
-
}
|
231 |
-
|
232 |
-
:root {
|
233 |
-
--background-fill-primary: #191a1e !important;
|
234 |
-
--background-fill-secondary: #191a1e !important;
|
235 |
-
--background-fill-tertiary: #191a1e !important;
|
236 |
-
}
|
237 |
-
|
238 |
-
.gradio-container, .gr-app {
|
239 |
-
background-color: #191a1e !important;
|
240 |
-
color: #FFFFFF !important;
|
241 |
height: 100%;
|
242 |
width: 100%;
|
243 |
}
|
244 |
|
245 |
-
|
246 |
-
.gr-block {
|
247 |
background-color: #191a1e !important;
|
248 |
-
border: none !important;
|
249 |
-
}
|
250 |
-
|
251 |
-
/* Hide the footer */
|
252 |
-
footer {
|
253 |
-
visibility: hidden;
|
254 |
-
height: 0;
|
255 |
-
margin: 0;
|
256 |
-
padding: 0;
|
257 |
-
overflow: hidden;
|
258 |
}
|
259 |
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
}
|
264 |
-
|
265 |
-
/* Header styles */
|
266 |
-
h1, h2, h3, h4, h5, h6 {
|
267 |
-
font-family: 'Poppins', sans-serif;
|
268 |
-
font-weight: 700;
|
269 |
-
color: #FFFFFF;
|
270 |
}
|
271 |
|
272 |
-
/* Increase button size */
|
273 |
.generate-button {
|
274 |
background-color: #5271FF !important;
|
275 |
color: #FFFFFF !important;
|
276 |
border: none;
|
277 |
font-weight: bold;
|
278 |
-
font-size: 1.2em;
|
279 |
-
padding: 0.75em 2em;
|
280 |
-
border-radius: 0.3em;
|
281 |
-
}
|
282 |
-
|
283 |
-
/* Examples container */
|
284 |
-
.gr-examples, .gr-examples .gr-box, .gr-examples .gr-card {
|
285 |
-
background-color: #191a1e !important;
|
286 |
-
border: none !important;
|
287 |
}
|
288 |
|
289 |
-
|
290 |
-
|
291 |
-
|
|
|
|
|
|
|
292 |
}
|
293 |
"""
|
294 |
|
295 |
-
with gr.Blocks(
|
|
|
|
|
|
|
|
|
296 |
img_proc_state = gr.State()
|
297 |
background_remove_state = gr.State()
|
298 |
|
|
|
14 |
import sf3d.utils as sf3d_utils
|
15 |
from sf3d.system import SF3D
|
16 |
|
|
|
17 |
rembg_session = rembg.new_session()
|
18 |
|
|
|
19 |
COND_WIDTH = 512
|
20 |
COND_HEIGHT = 512
|
21 |
COND_DISTANCE = 1.6
|
22 |
COND_FOVY_DEG = 40
|
23 |
BACKGROUND_COLOR = [0.5, 0.5, 0.5]
|
24 |
|
|
|
25 |
c2w_cond = sf3d_utils.default_cond_c2w(COND_DISTANCE)
|
26 |
intrinsic, intrinsic_normed_cond = sf3d_utils.create_intrinsic_from_fov_deg(
|
27 |
COND_FOVY_DEG, COND_HEIGHT, COND_WIDTH
|
28 |
)
|
29 |
|
|
|
30 |
model = SF3D.from_pretrained(
|
31 |
"stabilityai/stable-fast-3d",
|
32 |
config_name="config.yaml",
|
|
|
34 |
)
|
35 |
model.eval().cuda()
|
36 |
|
37 |
+
example_files = [os.path.join("demo_files/examples", f) for f in os.listdir("demo_files/examples")]
|
|
|
|
|
38 |
|
39 |
def run_model(input_image):
|
40 |
start = time.time()
|
|
|
47 |
|
48 |
tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".glb")
|
49 |
trimesh_mesh.export(tmp_file.name, file_type="glb", include_normals=True)
|
|
|
50 |
print("Generation took:", time.time() - start, "s")
|
51 |
return tmp_file.name
|
52 |
|
53 |
def create_batch(input_image: Image) -> dict[str, Any]:
|
54 |
+
img_cond = (torch.from_numpy(
|
55 |
+
np.asarray(input_image.resize((COND_WIDTH, COND_HEIGHT))).astype(np.float32) / 255.0
|
56 |
+
).float().clip(0, 1))
|
|
|
|
|
|
|
|
|
|
|
57 |
mask_cond = img_cond[:, :, -1:]
|
58 |
+
rgb_cond = torch.lerp(torch.tensor(BACKGROUND_COLOR)[None, None, :], img_cond[:, :, :3], mask_cond)
|
|
|
|
|
59 |
|
60 |
batch_elem = {
|
61 |
"rgb_cond": rgb_cond,
|
|
|
73 |
base[1::2, ::2] = 1
|
74 |
base[::2, 1::2] = 1
|
75 |
repeat_mult = size // squares
|
76 |
+
return (base.repeat(repeat_mult, axis=0).repeat(repeat_mult, axis=1)[:, :, None].repeat(3, axis=-1))
|
|
|
|
|
|
|
|
|
77 |
|
78 |
def remove_background(input_image: Image) -> Image:
|
79 |
return rembg.remove(input_image, session=rembg_session)
|
|
|
87 |
size = max(fg.shape[0], fg.shape[1])
|
88 |
ph0, pw0 = (size - fg.shape[0]) // 2, (size - fg.shape[1]) // 2
|
89 |
ph1, pw1 = size - fg.shape[0] - ph0, size - fg.shape[1] - pw0
|
90 |
+
new_image = np.pad(fg, ((ph0, ph1), (pw0, pw1), (0, 0)), mode="constant", constant_values=0)
|
|
|
|
|
|
|
|
|
|
|
91 |
|
92 |
new_size = int(new_image.shape[0] / ratio)
|
93 |
ph0, pw0 = (new_size - size) // 2, (new_size - size) // 2
|
94 |
ph1, pw1 = new_size - size - ph0, new_size - size - pw0
|
95 |
+
new_image = np.pad(new_image, ((ph0, ph1), (pw0, pw1), (0, 0)), mode="constant", constant_values=0)
|
|
|
|
|
|
|
|
|
|
|
96 |
new_image = Image.fromarray(new_image, mode="RGBA").resize((COND_WIDTH, COND_HEIGHT))
|
97 |
return new_image
|
98 |
|
|
|
193 |
)
|
194 |
|
195 |
css = """
|
196 |
+
html, body, #root, #__next, .gradio-container, .gr-app {
|
|
|
|
|
197 |
background-color: #191a1e !important;
|
198 |
+
margin: 0 !important;
|
199 |
+
padding: 0 !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
height: 100%;
|
201 |
width: 100%;
|
202 |
}
|
203 |
|
204 |
+
body > div {
|
|
|
205 |
background-color: #191a1e !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
206 |
}
|
207 |
|
208 |
+
.gr-block, .gr-row, .gr-column, .gr-box, .gr-examples, .gr-examples .gr-box, .gr-examples .gr-card {
|
209 |
+
background-color: #191a1e !important;
|
210 |
+
border: none !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
211 |
}
|
212 |
|
|
|
213 |
.generate-button {
|
214 |
background-color: #5271FF !important;
|
215 |
color: #FFFFFF !important;
|
216 |
border: none;
|
217 |
font-weight: bold;
|
218 |
+
font-size: 1.2em;
|
219 |
+
padding: 0.75em 2em;
|
220 |
+
border-radius: 0.3em;
|
|
|
|
|
|
|
|
|
|
|
|
|
221 |
}
|
222 |
|
223 |
+
footer {
|
224 |
+
visibility: hidden;
|
225 |
+
height: 0;
|
226 |
+
margin: 0;
|
227 |
+
padding: 0;
|
228 |
+
overflow: hidden;
|
229 |
}
|
230 |
"""
|
231 |
|
232 |
+
with gr.Blocks(
|
233 |
+
theme=CustomTheme(),
|
234 |
+
css=css,
|
235 |
+
style={"width":"100vw","height":"100vh","background":"#191a1e","margin":"0","padding":"0"}
|
236 |
+
) as demo:
|
237 |
img_proc_state = gr.State()
|
238 |
background_remove_state = gr.State()
|
239 |
|