Update app.py
Browse files
app.py
CHANGED
|
@@ -42,27 +42,6 @@ def create_face_mask(image, bbox_coords, face_preserve):
|
|
| 42 |
|
| 43 |
return mask
|
| 44 |
|
| 45 |
-
def create_mask_preview(image, bbox_x1, bbox_y1, bbox_x2, bbox_y2, face_preserve):
|
| 46 |
-
"""Erstellt eine Vorschau der Maske auf dem Originalbild"""
|
| 47 |
-
if image is None or None in [bbox_x1, bbox_y1, bbox_x2, bbox_y2]:
|
| 48 |
-
return None
|
| 49 |
-
|
| 50 |
-
# Bild kopieren für Vorschau
|
| 51 |
-
preview = image.copy()
|
| 52 |
-
draw = ImageDraw.Draw(preview)
|
| 53 |
-
|
| 54 |
-
# Rechteck zeichnen basierend auf face_preserve
|
| 55 |
-
if face_preserve:
|
| 56 |
-
# GESICHTSERHALTUNG: Roter Rahmen um geschützten Bereich
|
| 57 |
-
draw.rectangle([bbox_x1, bbox_y1, bbox_x2, bbox_y2], outline="red", width=3)
|
| 58 |
-
draw.text((bbox_x1, bbox_y1-25), "GESCHÜTZT", fill="red")
|
| 59 |
-
else:
|
| 60 |
-
# NUR GESICHT VERÄNDERN: Grüner Rahmen um Veränderungsbereich
|
| 61 |
-
draw.rectangle([bbox_x1, bbox_y1, bbox_x2, bbox_y2], outline="green", width=3)
|
| 62 |
-
draw.text((bbox_x1, bbox_y1-25), "WIRD VERÄNDERT", fill="green")
|
| 63 |
-
|
| 64 |
-
return preview
|
| 65 |
-
|
| 66 |
def auto_detect_face_area(image):
|
| 67 |
"""Optimierten Vorschlag für Gesichtsbereich ohne externe Bibliotheken"""
|
| 68 |
width, height = image.size
|
|
@@ -344,14 +323,12 @@ def img_to_image(image, prompt, neg_prompt, strength, steps, guidance_scale,
|
|
| 344 |
|
| 345 |
|
| 346 |
def update_bbox_from_image(image):
|
| 347 |
-
"""Aktualisiert die Bounding-Box-Koordinaten
|
| 348 |
if image is None:
|
| 349 |
-
return None, None, None, None
|
| 350 |
|
| 351 |
bbox = auto_detect_face_area(image)
|
| 352 |
-
|
| 353 |
-
preview = create_mask_preview(image, bbox[0], bbox[1], bbox[2], bbox[3], True)
|
| 354 |
-
return bbox[0], bbox[1], bbox[2], bbox[3], preview
|
| 355 |
|
| 356 |
def main_ui():
|
| 357 |
with gr.Blocks(
|
|
@@ -449,30 +426,12 @@ def main_ui():
|
|
| 449 |
gr.Markdown("**Lade ein Bild hoch und beschreibe die gewünschte Veränderung:**")
|
| 450 |
|
| 451 |
with gr.Row():
|
| 452 |
-
|
| 453 |
-
|
| 454 |
-
|
| 455 |
-
|
| 456 |
-
|
| 457 |
-
|
| 458 |
-
)
|
| 459 |
-
with gr.Column():
|
| 460 |
-
img_preview = gr.Image(
|
| 461 |
-
type="pil",
|
| 462 |
-
label="Masken-Vorschau",
|
| 463 |
-
height=300,
|
| 464 |
-
interactive=False
|
| 465 |
-
)
|
| 466 |
-
|
| 467 |
-
with gr.Row():
|
| 468 |
-
with gr.Column():
|
| 469 |
-
gr.Markdown("**📐 Masken-Koordinaten**")
|
| 470 |
-
with gr.Row():
|
| 471 |
-
bbox_x1 = gr.Number(label="Links (x1)", value=100, precision=0)
|
| 472 |
-
bbox_y1 = gr.Number(label="Oben (y1)", value=100, precision=0)
|
| 473 |
-
with gr.Row():
|
| 474 |
-
bbox_x2 = gr.Number(label="Rechts (x2)", value=300, precision=0)
|
| 475 |
-
bbox_y2 = gr.Number(label="Unten (y2)", value=300, precision=0)
|
| 476 |
|
| 477 |
with gr.Row():
|
| 478 |
with gr.Column():
|
|
@@ -515,15 +474,43 @@ def main_ui():
|
|
| 515 |
face_preserve = gr.Checkbox(
|
| 516 |
label="Gesicht, Tier, Gegenstand beibehalten",
|
| 517 |
value=True,
|
| 518 |
-
info="
|
| 519 |
)
|
| 520 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 521 |
with gr.Row():
|
| 522 |
gr.Markdown(
|
| 523 |
"**Achtung:**\n"
|
| 524 |
"• **Automatische Bildelementerkennung** setzt Koordinaten beim Upload\n"
|
| 525 |
-
"• **Koordinaten anpassen**
|
| 526 |
-
"• **Farbiger Rahmen** zeigt an was geschützt/verändert wird"
|
| 527 |
)
|
| 528 |
|
| 529 |
|
|
@@ -536,23 +523,13 @@ def main_ui():
|
|
| 536 |
type="pil"
|
| 537 |
)
|
| 538 |
|
| 539 |
-
# Event-Handler für Bild-Upload
|
| 540 |
img_input.change(
|
| 541 |
fn=update_bbox_from_image,
|
| 542 |
inputs=[img_input],
|
| 543 |
-
outputs=[bbox_x1, bbox_y1, bbox_x2, bbox_y2
|
| 544 |
)
|
| 545 |
|
| 546 |
-
# Event-Handler für Live-Masken-Vorschau bei Koordinaten-Änderungen
|
| 547 |
-
coordinates_inputs = [bbox_x1, bbox_y1, bbox_x2, bbox_y2, face_preserve]
|
| 548 |
-
|
| 549 |
-
for coordinate in coordinates_inputs:
|
| 550 |
-
coordinate.change(
|
| 551 |
-
fn=create_mask_preview,
|
| 552 |
-
inputs=[img_input] + coordinates_inputs,
|
| 553 |
-
outputs=img_preview
|
| 554 |
-
)
|
| 555 |
-
|
| 556 |
transform_btn.click(
|
| 557 |
fn=img_to_image,
|
| 558 |
inputs=[
|
|
|
|
| 42 |
|
| 43 |
return mask
|
| 44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
def auto_detect_face_area(image):
|
| 46 |
"""Optimierten Vorschlag für Gesichtsbereich ohne externe Bibliotheken"""
|
| 47 |
width, height = image.size
|
|
|
|
| 323 |
|
| 324 |
|
| 325 |
def update_bbox_from_image(image):
|
| 326 |
+
"""Aktualisiert die Bounding-Box-Koordinaten wenn ein Bild hochgeladen wird"""
|
| 327 |
if image is None:
|
| 328 |
+
return None, None, None, None
|
| 329 |
|
| 330 |
bbox = auto_detect_face_area(image)
|
| 331 |
+
return bbox[0], bbox[1], bbox[2], bbox[3]
|
|
|
|
|
|
|
| 332 |
|
| 333 |
def main_ui():
|
| 334 |
with gr.Blocks(
|
|
|
|
| 426 |
gr.Markdown("**Lade ein Bild hoch und beschreibe die gewünschte Veränderung:**")
|
| 427 |
|
| 428 |
with gr.Row():
|
| 429 |
+
img_input = gr.Image(
|
| 430 |
+
type="pil",
|
| 431 |
+
label="Eingabebild",
|
| 432 |
+
height=300,
|
| 433 |
+
sources=["upload"] # Nur Upload-Button anzeigen
|
| 434 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 435 |
|
| 436 |
with gr.Row():
|
| 437 |
with gr.Column():
|
|
|
|
| 474 |
face_preserve = gr.Checkbox(
|
| 475 |
label="Gesicht, Tier, Gegenstand beibehalten",
|
| 476 |
value=True,
|
| 477 |
+
info="Aktiviert: Bildelement bleibt erhalten, Hintergrund wird verändert | Deaktiviert: Nur Bildelement wird verändert"
|
| 478 |
)
|
| 479 |
|
| 480 |
+
with gr.Row():
|
| 481 |
+
gr.Markdown("**Bildelementbereich anpassen**")
|
| 482 |
+
|
| 483 |
+
with gr.Row():
|
| 484 |
+
bbox_x1 = gr.Number(
|
| 485 |
+
label="Links (x1)",
|
| 486 |
+
value=100,
|
| 487 |
+
precision=0,
|
| 488 |
+
info="Linke Kante des Gesichtsbereichs"
|
| 489 |
+
)
|
| 490 |
+
bbox_y1 = gr.Number(
|
| 491 |
+
label="Oben (y1)",
|
| 492 |
+
value=100,
|
| 493 |
+
precision=0,
|
| 494 |
+
info="Obere Kante des Gesichtsbereichs"
|
| 495 |
+
)
|
| 496 |
+
bbox_x2 = gr.Number(
|
| 497 |
+
label="Rechts (x2)",
|
| 498 |
+
value=300,
|
| 499 |
+
precision=0,
|
| 500 |
+
info="Rechte Kante des Gesichtsbereichs"
|
| 501 |
+
)
|
| 502 |
+
bbox_y2 = gr.Number(
|
| 503 |
+
label="Unten (y2)",
|
| 504 |
+
value=300,
|
| 505 |
+
precision=0,
|
| 506 |
+
info="Untere Kante des Gesichtsbereichs"
|
| 507 |
+
)
|
| 508 |
+
|
| 509 |
with gr.Row():
|
| 510 |
gr.Markdown(
|
| 511 |
"**Achtung:**\n"
|
| 512 |
"• **Automatische Bildelementerkennung** setzt Koordinaten beim Upload\n"
|
| 513 |
+
"• **Koordinaten nur bei erkennbaren Verzerrungen anpassen** (Bereiche leicht verschieben)"
|
|
|
|
| 514 |
)
|
| 515 |
|
| 516 |
|
|
|
|
| 523 |
type="pil"
|
| 524 |
)
|
| 525 |
|
| 526 |
+
# Event-Handler für Bild-Upload
|
| 527 |
img_input.change(
|
| 528 |
fn=update_bbox_from_image,
|
| 529 |
inputs=[img_input],
|
| 530 |
+
outputs=[bbox_x1, bbox_y1, bbox_x2, bbox_y2]
|
| 531 |
)
|
| 532 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 533 |
transform_btn.click(
|
| 534 |
fn=img_to_image,
|
| 535 |
inputs=[
|