Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
@@ -22,45 +22,60 @@ model.to(device)
|
|
22 |
|
23 |
# Функция для проверки изображения
|
24 |
def check_input_image(input_image):
|
25 |
-
|
26 |
-
|
|
|
|
|
|
|
|
|
27 |
|
28 |
|
29 |
# Функция обработки изображения
|
30 |
def preprocess(input_image, do_remove_background, foreground_ratio):
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
else:
|
43 |
-
image = input_image
|
44 |
-
if image.mode == "RGBA":
|
45 |
image = fill_background(image)
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
|
48 |
|
49 |
# Функция генерации 3D модели
|
50 |
def generate(image):
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
|
|
|
|
|
|
|
|
|
|
60 |
def start_loading():
|
|
|
61 |
return gr.HTML.update(visible=True)
|
62 |
|
63 |
def stop_loading():
|
|
|
64 |
return gr.HTML.update(visible=False)
|
65 |
|
66 |
|
@@ -101,54 +116,23 @@ h1, h2, h3, h4, h5, h6 {
|
|
101 |
font-weight: 700;
|
102 |
color: #FFFFFF;
|
103 |
}
|
104 |
-
/*
|
105 |
-
input[type="text"], textarea {
|
106 |
-
background-color: #191a1e !important;
|
107 |
-
color: #FFFFFF;
|
108 |
-
border: 1px solid #FFFFFF;
|
109 |
-
}
|
110 |
-
/* Слайдер */
|
111 |
-
.gr-slider {
|
112 |
-
height: 40px !important; /* Увеличение высоты слайдера */
|
113 |
-
transition: all 0.3s ease !important; /* Плавные переходы */
|
114 |
-
}
|
115 |
-
.gr-slider .slider-value {
|
116 |
-
display: none !important; /* Прячем текст значения */
|
117 |
-
}
|
118 |
-
.gr-slider .slider::-webkit-slider-thumb {
|
119 |
-
height: 15px !important;
|
120 |
-
width: 15px !important;
|
121 |
-
background-color: #5271FF !important; /* Цвет совпадает с кнопкой */
|
122 |
-
border-radius: 50%;
|
123 |
-
}
|
124 |
-
.gr-slider .slider::-webkit-slider-runnable-track {
|
125 |
-
background: #5271FF !important; /* Цвет заполнения слайдера */
|
126 |
-
}
|
127 |
-
/* Кнопка Generate */
|
128 |
-
.generate-button {
|
129 |
-
background-color: #5271FF !important;
|
130 |
-
color: #FFFFFF !important;
|
131 |
-
border: none;
|
132 |
-
font-weight: bold;
|
133 |
-
}
|
134 |
-
.generate-button:hover {
|
135 |
-
background-color: #405BBF !important; /* Цвет при наведении */
|
136 |
-
}
|
137 |
.generate-button {
|
138 |
position: relative; /* Кнопка становится родительским контейнером */
|
|
|
|
|
|
|
139 |
}
|
140 |
-
|
141 |
-
|
142 |
-
font-weight: bold;
|
143 |
-
color: #FFFFFF;
|
144 |
-
}
|
145 |
-
/* Лоадер (анимация) */
|
146 |
#loading-bar {
|
147 |
display: none; /* Скрыт по умолчанию */
|
148 |
-
position:
|
149 |
-
|
150 |
-
|
151 |
-
|
|
|
|
|
152 |
border: 4px solid #f3f3f3;
|
153 |
border-top: 4px solid #5271FF; /* Цвет лоадера */
|
154 |
border-radius: 50%;
|
@@ -156,12 +140,8 @@ input[type="text"], textarea {
|
|
156 |
}
|
157 |
/* Анимация вращения */
|
158 |
@keyframes spin {
|
159 |
-
0% { transform:
|
160 |
-
100% { transform:
|
161 |
-
}
|
162 |
-
/* Текст CheckBox в белый */
|
163 |
-
.gr-checkbox label {
|
164 |
-
color: #FFFFFF !important;
|
165 |
}
|
166 |
"""
|
167 |
|
@@ -192,11 +172,11 @@ with gr.Blocks(theme=CustomTheme(), css=css) as demo:
|
|
192 |
step=0.05,
|
193 |
)
|
194 |
do_remove_background = gr.Checkbox(
|
195 |
-
label="Remove Background",
|
196 |
value=True,
|
197 |
)
|
198 |
submit = gr.Button("Generate", elem_classes="generate-button")
|
199 |
-
loading_bar = gr.HTML("<div id='loading-bar'></div>")
|
200 |
output_model = gr.Model3D(
|
201 |
label="Generated GLB Model",
|
202 |
interactive=False,
|
@@ -204,29 +184,30 @@ with gr.Blocks(theme=CustomTheme(), css=css) as demo:
|
|
204 |
)
|
205 |
|
206 |
submit.click(
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
).then(
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
).then(
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
).then(
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
).then(
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
)
|
|
|
227 |
# Запуск приложения
|
228 |
demo.launch(
|
229 |
server_name="0.0.0.0",
|
230 |
server_port=7860,
|
231 |
share=True,
|
232 |
-
)
|
|
|
22 |
|
23 |
# Функция для проверки изображения
|
24 |
def check_input_image(input_image):
|
25 |
+
try:
|
26 |
+
if input_image is None:
|
27 |
+
raise gr.Error("No image uploaded!")
|
28 |
+
except Exception as e:
|
29 |
+
print(f"Error in check_input_image: {e}")
|
30 |
+
raise
|
31 |
|
32 |
|
33 |
# Функция обработки изображения
|
34 |
def preprocess(input_image, do_remove_background, foreground_ratio):
|
35 |
+
try:
|
36 |
+
def fill_background(image):
|
37 |
+
image = np.array(image).astype(np.float32) / 255.0
|
38 |
+
image = image[:, :, :3] * image[:, :, 3:4] + (1 - image[:, :, 3:4]) * 0.5
|
39 |
+
image = Image.fromarray((image * 255.0).astype(np.uint8))
|
40 |
+
return image
|
41 |
+
|
42 |
+
if do_remove_background:
|
43 |
+
image = input_image.convert("RGB")
|
44 |
+
image = remove_background(image)
|
45 |
+
image = resize_foreground(image, foreground_ratio)
|
|
|
|
|
|
|
46 |
image = fill_background(image)
|
47 |
+
else:
|
48 |
+
image = input_image
|
49 |
+
if image.mode == "RGBA":
|
50 |
+
image = fill_background(image)
|
51 |
+
return image
|
52 |
+
except Exception as e:
|
53 |
+
print(f"Error in preprocess: {e}")
|
54 |
+
raise
|
55 |
|
56 |
|
57 |
# Функция генерации 3D модели
|
58 |
def generate(image):
|
59 |
+
try:
|
60 |
+
time.sleep(3) # Эмуляция времени обработки
|
61 |
+
scene_codes = model(image, device=device)
|
62 |
+
mesh = model.extract_mesh(scene_codes)[0]
|
63 |
+
mesh = to_gradio_3d_orientation(mesh)
|
64 |
+
mesh_path2 = tempfile.NamedTemporaryFile(suffix=".glb", delete=False)
|
65 |
+
mesh.export(mesh_path2.name)
|
66 |
+
return mesh_path2.name
|
67 |
+
except Exception as e:
|
68 |
+
print(f"Error in generate: {e}")
|
69 |
+
raise
|
70 |
+
|
71 |
+
|
72 |
+
# Функции управления лоадером
|
73 |
def start_loading():
|
74 |
+
print("Start loading triggered")
|
75 |
return gr.HTML.update(visible=True)
|
76 |
|
77 |
def stop_loading():
|
78 |
+
print("Stop loading triggered")
|
79 |
return gr.HTML.update(visible=False)
|
80 |
|
81 |
|
|
|
116 |
font-weight: 700;
|
117 |
color: #FFFFFF;
|
118 |
}
|
119 |
+
/* Лоадер внутри кнопки */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
.generate-button {
|
121 |
position: relative; /* Кнопка становится родительским контейнером */
|
122 |
+
display: flex;
|
123 |
+
align-items: center;
|
124 |
+
justify-content: center;
|
125 |
}
|
126 |
+
|
127 |
+
/* Лоадер внутри кнопки */
|
|
|
|
|
|
|
|
|
128 |
#loading-bar {
|
129 |
display: none; /* Скрыт по умолчанию */
|
130 |
+
position: absolute; /* Абсолютная позиция внутри кнопки */
|
131 |
+
top: 50%;
|
132 |
+
left: 50%;
|
133 |
+
transform: translate(-50%, -50%);
|
134 |
+
width: 20px;
|
135 |
+
height: 20px;
|
136 |
border: 4px solid #f3f3f3;
|
137 |
border-top: 4px solid #5271FF; /* Цвет лоадера */
|
138 |
border-radius: 50%;
|
|
|
140 |
}
|
141 |
/* Анимация вращения */
|
142 |
@keyframes spin {
|
143 |
+
0% { transform: rotate(0deg); }
|
144 |
+
100% { transform: rotate(360deg); }
|
|
|
|
|
|
|
|
|
145 |
}
|
146 |
"""
|
147 |
|
|
|
172 |
step=0.05,
|
173 |
)
|
174 |
do_remove_background = gr.Checkbox(
|
175 |
+
label="Remove Background",
|
176 |
value=True,
|
177 |
)
|
178 |
submit = gr.Button("Generate", elem_classes="generate-button")
|
179 |
+
loading_bar = gr.HTML("<div id='loading-bar'></div>", visible=False)
|
180 |
output_model = gr.Model3D(
|
181 |
label="Generated GLB Model",
|
182 |
interactive=False,
|
|
|
184 |
)
|
185 |
|
186 |
submit.click(
|
187 |
+
fn=start_loading, # Включить прогресс-бар
|
188 |
+
inputs=[],
|
189 |
+
outputs=[loading_bar]
|
190 |
+
).then(
|
191 |
+
fn=check_input_image,
|
192 |
+
inputs=[input_image],
|
193 |
+
outputs=[]
|
194 |
+
).then(
|
195 |
+
fn=preprocess,
|
196 |
+
inputs=[input_image, do_remove_background, foreground_ratio],
|
197 |
+
outputs=[processed_image]
|
198 |
+
).then(
|
199 |
+
fn=generate,
|
200 |
+
inputs=[processed_image],
|
201 |
+
outputs=[output_model]
|
202 |
+
).then(
|
203 |
+
fn=stop_loading, # Отключаем прогресс-бар после завершения генерации
|
204 |
+
inputs=[],
|
205 |
+
outputs=[loading_bar]
|
206 |
+
)
|
207 |
+
|
208 |
# Запуск приложения
|
209 |
demo.launch(
|
210 |
server_name="0.0.0.0",
|
211 |
server_port=7860,
|
212 |
share=True,
|
213 |
+
)
|