Spaces:
Running on Zero
Running on Zero
Upload app.py with huggingface_hub
Browse files
app.py
CHANGED
|
@@ -221,16 +221,16 @@ def parse_points_json(points_json: str, width: int, height: int) -> List[Tuple[f
|
|
| 221 |
# Event handlers. #
|
| 222 |
# --------------------------------------------------------------------------- #
|
| 223 |
def on_image_change(image: np.ndarray):
|
| 224 |
-
"""
|
| 225 |
if image is None:
|
| 226 |
-
return
|
| 227 |
-
return
|
| 228 |
|
| 229 |
|
| 230 |
def on_image_select(image: np.ndarray, points_json: str, evt: gr.SelectData):
|
| 231 |
"""Append the clicked point (original-image pixel coords) to the annotation list."""
|
| 232 |
if image is None:
|
| 233 |
-
|
| 234 |
x, y = evt.index
|
| 235 |
try:
|
| 236 |
points = json.loads(points_json) if points_json else []
|
|
@@ -240,29 +240,23 @@ def on_image_select(image: np.ndarray, points_json: str, evt: gr.SelectData):
|
|
| 240 |
return json.dumps(points), draw_annotations(image, points)
|
| 241 |
|
| 242 |
|
| 243 |
-
def on_clear(points_json: str):
|
| 244 |
"""Clear all annotations."""
|
| 245 |
-
|
|
|
|
|
|
|
| 246 |
|
| 247 |
|
| 248 |
-
def on_undo(points_json: str):
|
| 249 |
"""Remove the most recent annotation."""
|
|
|
|
|
|
|
| 250 |
try:
|
| 251 |
points = json.loads(points_json) if points_json else []
|
| 252 |
except json.JSONDecodeError:
|
| 253 |
points = []
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
def run_rmbg(image: np.ndarray):
|
| 258 |
-
"""Remove the background from the current image (GPU-light step)."""
|
| 259 |
-
if image is None:
|
| 260 |
-
return None, "[]", None, gr.Warning("Upload an image first.")
|
| 261 |
-
if len(image.shape) == 3 and image.shape[2] == 4:
|
| 262 |
-
return image, "[]", image, None # already has alpha
|
| 263 |
-
pil = remove_background(Image.fromarray(image))
|
| 264 |
-
out = np.array(pil) # RGBA
|
| 265 |
-
return out, "[]", out, None
|
| 266 |
|
| 267 |
|
| 268 |
@spaces.GPU(duration=300)
|
|
@@ -386,12 +380,10 @@ with gr.Blocks(theme=gr.themes.Citrus(), css=css, title="FlexPart — Image-to-3
|
|
| 386 |
elem_classes=["annot-preview"],
|
| 387 |
)
|
| 388 |
points_state = gr.State("[]")
|
| 389 |
-
current_image = gr.State(None)
|
| 390 |
|
| 391 |
with gr.Row():
|
| 392 |
undo_btn = gr.Button("↩ Undo last")
|
| 393 |
clear_btn = gr.Button("🗑 Clear all")
|
| 394 |
-
rmbg_btn = gr.Button("🧹 Remove background", variant="secondary")
|
| 395 |
|
| 396 |
with gr.Accordion("Advanced settings", open=False):
|
| 397 |
seed = gr.Number(value=1000, label="Seed", precision=0)
|
|
@@ -439,10 +431,9 @@ with gr.Blocks(theme=gr.themes.Citrus(), css=css, title="FlexPart — Image-to-3
|
|
| 439 |
|
| 440 |
# Wiring
|
| 441 |
input_image.select(on_image_select, inputs=[input_image, points_state], outputs=[points_state, annotated_preview])
|
| 442 |
-
input_image.change(on_image_change, inputs=[input_image], outputs=[
|
| 443 |
-
undo_btn.click(on_undo, inputs=[points_state], outputs=[points_state])
|
| 444 |
-
clear_btn.click(on_clear, inputs=[points_state], outputs=[points_state])
|
| 445 |
-
rmbg_btn.click(run_rmbg, inputs=[input_image], outputs=[input_image, points_state, annotated_preview, annotated_preview])
|
| 446 |
gen_btn.click(
|
| 447 |
generate,
|
| 448 |
inputs=[input_image, points_state, seed, guidance, steps],
|
|
|
|
| 221 |
# Event handlers. #
|
| 222 |
# --------------------------------------------------------------------------- #
|
| 223 |
def on_image_change(image: np.ndarray):
|
| 224 |
+
"""Reset annotations whenever a new image is loaded."""
|
| 225 |
if image is None:
|
| 226 |
+
return "[]", None
|
| 227 |
+
return "[]", draw_annotations(image, [])
|
| 228 |
|
| 229 |
|
| 230 |
def on_image_select(image: np.ndarray, points_json: str, evt: gr.SelectData):
|
| 231 |
"""Append the clicked point (original-image pixel coords) to the annotation list."""
|
| 232 |
if image is None:
|
| 233 |
+
raise gr.Error("Upload an image first.")
|
| 234 |
x, y = evt.index
|
| 235 |
try:
|
| 236 |
points = json.loads(points_json) if points_json else []
|
|
|
|
| 240 |
return json.dumps(points), draw_annotations(image, points)
|
| 241 |
|
| 242 |
|
| 243 |
+
def on_clear(points_json: str, image: np.ndarray):
|
| 244 |
"""Clear all annotations."""
|
| 245 |
+
if image is None:
|
| 246 |
+
return "[]", None
|
| 247 |
+
return "[]", draw_annotations(image, [])
|
| 248 |
|
| 249 |
|
| 250 |
+
def on_undo(points_json: str, image: np.ndarray):
|
| 251 |
"""Remove the most recent annotation."""
|
| 252 |
+
if image is None:
|
| 253 |
+
raise gr.Error("Upload an image first.")
|
| 254 |
try:
|
| 255 |
points = json.loads(points_json) if points_json else []
|
| 256 |
except json.JSONDecodeError:
|
| 257 |
points = []
|
| 258 |
+
points = points[:-1] if points else []
|
| 259 |
+
return json.dumps(points), draw_annotations(image, points)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 260 |
|
| 261 |
|
| 262 |
@spaces.GPU(duration=300)
|
|
|
|
| 380 |
elem_classes=["annot-preview"],
|
| 381 |
)
|
| 382 |
points_state = gr.State("[]")
|
|
|
|
| 383 |
|
| 384 |
with gr.Row():
|
| 385 |
undo_btn = gr.Button("↩ Undo last")
|
| 386 |
clear_btn = gr.Button("🗑 Clear all")
|
|
|
|
| 387 |
|
| 388 |
with gr.Accordion("Advanced settings", open=False):
|
| 389 |
seed = gr.Number(value=1000, label="Seed", precision=0)
|
|
|
|
| 431 |
|
| 432 |
# Wiring
|
| 433 |
input_image.select(on_image_select, inputs=[input_image, points_state], outputs=[points_state, annotated_preview])
|
| 434 |
+
input_image.change(on_image_change, inputs=[input_image], outputs=[points_state, annotated_preview])
|
| 435 |
+
undo_btn.click(on_undo, inputs=[points_state, input_image], outputs=[points_state, annotated_preview])
|
| 436 |
+
clear_btn.click(on_clear, inputs=[points_state, input_image], outputs=[points_state, annotated_preview])
|
|
|
|
| 437 |
gen_btn.click(
|
| 438 |
generate,
|
| 439 |
inputs=[input_image, points_state, seed, guidance, steps],
|