Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
app.py
CHANGED
@@ -446,7 +446,7 @@ def enhance_image(image, scale, dpi):
|
|
446 |
|
447 |
@spaces.GPU(duration=30)
|
448 |
def remove_objects_by_text(image, objects_text, mask_precision):
|
449 |
-
"""Удаление объектов -
|
450 |
if image is None:
|
451 |
return None, "❌ Загрузите изображение"
|
452 |
|
@@ -455,51 +455,97 @@ def remove_objects_by_text(image, objects_text, mask_precision):
|
|
455 |
if designer is None:
|
456 |
designer = InteriorDesignerPro()
|
457 |
|
458 |
-
# Ресайзим для скорости
|
459 |
original_size = image.size
|
460 |
if image.width > 768 or image.height > 768:
|
461 |
image.thumbnail((768, 768), Image.Resampling.LANCZOS)
|
462 |
|
463 |
-
#
|
464 |
-
if not hasattr(designer, 'object_remover'):
|
465 |
-
from models import ObjectRemover
|
466 |
-
designer.object_remover = ObjectRemover(designer.inpaint_pipe)
|
467 |
-
|
468 |
-
# Простая маска
|
469 |
width, height = image.size
|
470 |
mask = Image.new('L', (width, height), 0)
|
471 |
draw = ImageDraw.Draw(mask)
|
472 |
|
473 |
-
#
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
479 |
if designer.inpaint_pipe:
|
480 |
result = designer.inpaint_pipe(
|
481 |
-
prompt="empty clean
|
|
|
482 |
image=image,
|
483 |
mask_image=mask,
|
484 |
-
strength=0.
|
485 |
-
num_inference_steps=
|
486 |
-
guidance_scale=5
|
487 |
).images[0]
|
488 |
else:
|
489 |
-
# Fallback
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
cv2.INPAINT_TELEA
|
495 |
-
)
|
496 |
-
result = Image.fromarray(result)
|
497 |
|
498 |
# Возвращаем к оригинальному размеру
|
499 |
if result.size != original_size:
|
500 |
result = result.resize(original_size, Image.Resampling.LANCZOS)
|
501 |
|
502 |
-
return result, f"✅
|
503 |
|
504 |
except Exception as e:
|
505 |
import traceback
|
@@ -690,8 +736,84 @@ with gr.Blocks(title="AI Дизайнер интерьера Pro", theme=gr.them
|
|
690 |
detail_output = gr.Image(label="Результат", height=300)
|
691 |
detail_info = gr.Textbox(label="Статус", lines=2)
|
692 |
|
693 |
-
#
|
694 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
695 |
|
696 |
# Обработчики событий
|
697 |
process_btn.click(
|
@@ -719,6 +841,24 @@ with gr.Blocks(title="AI Дизайнер интерьера Pro", theme=gr.them
|
|
719 |
outputs=[remove_output, remove_info]
|
720 |
)
|
721 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
722 |
# Информация внизу
|
723 |
author_info = os.environ.get("AUTHOR_INFO", "")
|
724 |
if author_info:
|
@@ -736,11 +876,12 @@ with gr.Blocks(title="AI Дизайнер интерьера Pro", theme=gr.them
|
|
736 |
4. Нажмите "Преобразить интерьер"
|
737 |
|
738 |
### 🚀 Возможности:
|
739 |
-
- 20 стилей дизайна
|
740 |
- Автоопределение типа комнаты
|
741 |
-
- Создание вариаций
|
742 |
-
-
|
743 |
-
- HDR освещение
|
|
|
744 |
|
745 |
---
|
746 |
<center>Made with ❤️ for interior design enthusiasts</center>
|
|
|
446 |
|
447 |
@spaces.GPU(duration=30)
|
448 |
def remove_objects_by_text(image, objects_text, mask_precision):
|
449 |
+
"""Удаление объектов - улучшенная версия"""
|
450 |
if image is None:
|
451 |
return None, "❌ Загрузите изображение"
|
452 |
|
|
|
455 |
if designer is None:
|
456 |
designer = InteriorDesignerPro()
|
457 |
|
458 |
+
# Ресайзим для скорости
|
459 |
original_size = image.size
|
460 |
if image.width > 768 or image.height > 768:
|
461 |
image.thumbnail((768, 768), Image.Resampling.LANCZOS)
|
462 |
|
463 |
+
# Создаем маску на основе описания
|
|
|
|
|
|
|
|
|
|
|
464 |
width, height = image.size
|
465 |
mask = Image.new('L', (width, height), 0)
|
466 |
draw = ImageDraw.Draw(mask)
|
467 |
|
468 |
+
# Улучшенная логика создания маски
|
469 |
+
objects_lower = objects_text.lower()
|
470 |
+
|
471 |
+
# Проверяем ключевые слова для позиции
|
472 |
+
if any(word in objects_lower for word in ["весь", "все", "полностью"]):
|
473 |
+
# Маска на все изображение
|
474 |
+
draw.rectangle([0, 0, width, height], fill=255)
|
475 |
+
elif any(word in objects_lower for word in ["центр", "середина", "диван", "стол", "кресло"]):
|
476 |
+
# Центральная область (для мебели обычно в центре)
|
477 |
+
margin_x = int(width * 0.2)
|
478 |
+
margin_y = int(height * 0.25)
|
479 |
+
draw.rectangle([margin_x, margin_y, width-margin_x, height-margin_y], fill=255)
|
480 |
+
elif any(word in objects_lower for word in ["лев", "слева"]):
|
481 |
+
# Левая часть
|
482 |
+
draw.rectangle([0, 0, int(width * 0.4), height], fill=255)
|
483 |
+
elif any(word in objects_lower for word in ["прав", "справа"]):
|
484 |
+
# Правая часть
|
485 |
+
draw.rectangle([int(width * 0.6), 0, width, height], fill=255)
|
486 |
+
elif any(word in objects_lower for word in ["верх", "потолок", "люстра"]):
|
487 |
+
# Верхняя часть
|
488 |
+
draw.rectangle([0, 0, width, int(height * 0.4)], fill=255)
|
489 |
+
elif any(word in objects_lower for word in ["низ", "пол", "ковер", "коврик"]):
|
490 |
+
# Нижняя часть
|
491 |
+
draw.rectangle([0, int(height * 0.6), width, height], fill=255)
|
492 |
+
elif any(word in objects_lower for word in ["картин", "рам", "постер"]):
|
493 |
+
# Области на стенах (обычно в верхней половине)
|
494 |
+
# Левая стена
|
495 |
+
draw.rectangle([0, int(height * 0.2), int(width * 0.2), int(height * 0.6)], fill=255)
|
496 |
+
# Правая стена
|
497 |
+
draw.rectangle([int(width * 0.8), int(height * 0.2), width, int(height * 0.6)], fill=255)
|
498 |
+
elif any(word in objects_lower for word in ["угол", "углу"]):
|
499 |
+
# Углы
|
500 |
+
corner_size = int(min(width, height) * 0.3)
|
501 |
+
if "лев" in objects_lower:
|
502 |
+
draw.rectangle([0, 0, corner_size, corner_size], fill=255)
|
503 |
+
elif "прав" in objects_lower:
|
504 |
+
draw.rectangle([width-corner_size, 0, width, corner_size], fill=255)
|
505 |
+
else:
|
506 |
+
# Все углы
|
507 |
+
draw.rectangle([0, 0, corner_size, corner_size], fill=255)
|
508 |
+
draw.rectangle([width-corner_size, 0, width, corner_size], fill=255)
|
509 |
+
else:
|
510 |
+
# По умолчанию - центральная область с учетом precision
|
511 |
+
margin = int(min(width, height) * (0.5 - mask_precision))
|
512 |
+
draw.ellipse([margin, margin, width-margin, height-margin], fill=255)
|
513 |
+
|
514 |
+
# Размываем маску для плавных краев
|
515 |
+
mask = mask.filter(ImageFilter.GaussianBlur(radius=10))
|
516 |
+
|
517 |
+
# Усиливаем inpainting промпт на основе контекста
|
518 |
+
room_type = "interior"
|
519 |
+
if any(word in objects_lower for word in ["гостин", "зал"]):
|
520 |
+
room_type = "living room"
|
521 |
+
elif any(word in objects_lower for word in ["спальн", "кроват"]):
|
522 |
+
room_type = "bedroom"
|
523 |
+
elif any(word in objects_lower for word in ["кухн", "кухон"]):
|
524 |
+
room_type = "kitchen"
|
525 |
+
|
526 |
+
# Проверяем наличие inpaint_pipe
|
527 |
if designer.inpaint_pipe:
|
528 |
result = designer.inpaint_pipe(
|
529 |
+
prompt=f"empty {room_type}, clean walls, seamless floor, no furniture",
|
530 |
+
negative_prompt=f"{objects_text}, furniture, objects, people",
|
531 |
image=image,
|
532 |
mask_image=mask,
|
533 |
+
strength=0.99, # Максимальная сила для полного удаления
|
534 |
+
num_inference_steps=30, # Немного больше шагов для качества
|
535 |
+
guidance_scale=7.5 # Выше для лучшего следования промпту
|
536 |
).images[0]
|
537 |
else:
|
538 |
+
# Fallback
|
539 |
+
from models import ObjectRemover
|
540 |
+
if not hasattr(designer, 'object_remover'):
|
541 |
+
designer.object_remover = ObjectRemover(None)
|
542 |
+
result = designer.object_remover.simple_inpaint(image, mask)
|
|
|
|
|
|
|
543 |
|
544 |
# Возвращаем к оригинальному размеру
|
545 |
if result.size != original_size:
|
546 |
result = result.resize(original_size, Image.Resampling.LANCZOS)
|
547 |
|
548 |
+
return result, f"✅ Удалено: {objects_text}"
|
549 |
|
550 |
except Exception as e:
|
551 |
import traceback
|
|
|
736 |
detail_output = gr.Image(label="Результат", height=300)
|
737 |
detail_info = gr.Textbox(label="Статус", lines=2)
|
738 |
|
739 |
+
# Вкладка сравнения стилей
|
740 |
+
with gr.TabItem("🎭 Сравнение стилей", id=3):
|
741 |
+
with gr.Row():
|
742 |
+
with gr.Column():
|
743 |
+
compare_image = gr.Image(
|
744 |
+
label="Загрузите фото для сравнения стилей",
|
745 |
+
type="pil",
|
746 |
+
height=400
|
747 |
+
)
|
748 |
+
|
749 |
+
selected_styles = gr.CheckboxGroup(
|
750 |
+
label="Выберите стили для сравнения (2-6)",
|
751 |
+
choices=list(DESIGN_STYLES.keys()),
|
752 |
+
value=["Современный минимализм", "Скандинавский"]
|
753 |
+
)
|
754 |
+
|
755 |
+
compare_quality = gr.Radio(
|
756 |
+
label="Скорость генерации",
|
757 |
+
choices=[("Быстро", "fast"), ("Качественно", "balanced")],
|
758 |
+
value="fast"
|
759 |
+
)
|
760 |
+
|
761 |
+
compare_btn = gr.Button("🎭 Сравнить стили", variant="primary")
|
762 |
+
|
763 |
+
with gr.Column():
|
764 |
+
compare_output = gr.Image(label="Сравнение стилей", height=600)
|
765 |
+
compare_info = gr.Textbox(label="Статус", lines=2)
|
766 |
+
|
767 |
+
# Вкладка увеличения разрешения
|
768 |
+
with gr.TabItem("🔍 Увеличение разрешения", id=4):
|
769 |
+
with gr.Row():
|
770 |
+
with gr.Column():
|
771 |
+
upscale_image = gr.Image(
|
772 |
+
label="Изображение для увеличения",
|
773 |
+
type="pil",
|
774 |
+
height=400
|
775 |
+
)
|
776 |
+
|
777 |
+
scale_factor = gr.Radio(
|
778 |
+
label="Масштаб увеличения",
|
779 |
+
choices=[("2x", 2), ("4x", 4)],
|
780 |
+
value=2
|
781 |
+
)
|
782 |
+
|
783 |
+
dpi_setting = gr.Radio(
|
784 |
+
label="DPI для печати",
|
785 |
+
choices=[("Экран (96)", 96), ("Печать (150)", 150), ("Высокое качество (300)", 300)],
|
786 |
+
value=96
|
787 |
+
)
|
788 |
+
|
789 |
+
upscale_btn = gr.Button("🔍 Увеличить разрешение", variant="primary")
|
790 |
+
|
791 |
+
with gr.Column():
|
792 |
+
upscale_output = gr.Image(label="Увеличенное изображение", height=400)
|
793 |
+
upscale_comparison = gr.Image(label="Сравнение", height=200)
|
794 |
+
upscale_info = gr.Markdown()
|
795 |
+
|
796 |
+
# Вкладка рекомендаций
|
797 |
+
with gr.TabItem("💡 Рекомендации", id=5):
|
798 |
+
with gr.Row():
|
799 |
+
with gr.Column():
|
800 |
+
suggest_image = gr.Image(
|
801 |
+
label="Загрузите фото для анализа",
|
802 |
+
type="pil",
|
803 |
+
height=400
|
804 |
+
)
|
805 |
+
|
806 |
+
suggest_btn = gr.Button("Получить рекомендации", variant="primary")
|
807 |
+
|
808 |
+
with gr.Column():
|
809 |
+
suggestions = gr.Markdown()
|
810 |
+
|
811 |
+
# Цветовые палитры для стилей
|
812 |
+
gr.Markdown("### 🎨 Цветовые палитры популярных стилей")
|
813 |
+
for style_name in list(DESIGN_STYLES.keys())[:4]:
|
814 |
+
colors = get_style_colors(style_name)
|
815 |
+
color_blocks = " ".join([f'<span style="background-color:{c}; padding:10px 20px; margin:2px; display:inline-block; border-radius:5px;"></span>' for c in colors])
|
816 |
+
gr.HTML(f"<div class='info-box'><strong>{style_name}:</strong><br>{color_blocks}</div>")
|
817 |
|
818 |
# Обработчики событий
|
819 |
process_btn.click(
|
|
|
841 |
outputs=[remove_output, remove_info]
|
842 |
)
|
843 |
|
844 |
+
compare_btn.click(
|
845 |
+
create_style_comparison,
|
846 |
+
inputs=[compare_image, selected_styles, compare_quality],
|
847 |
+
outputs=[compare_output, compare_info]
|
848 |
+
)
|
849 |
+
|
850 |
+
upscale_btn.click(
|
851 |
+
enhance_image,
|
852 |
+
inputs=[upscale_image, scale_factor, dpi_setting],
|
853 |
+
outputs=[upscale_output, upscale_comparison, upscale_info]
|
854 |
+
)
|
855 |
+
|
856 |
+
suggest_btn.click(
|
857 |
+
suggest_styles,
|
858 |
+
inputs=[suggest_image],
|
859 |
+
outputs=[suggestions]
|
860 |
+
)
|
861 |
+
|
862 |
# Информация внизу
|
863 |
author_info = os.environ.get("AUTHOR_INFO", "")
|
864 |
if author_info:
|
|
|
876 |
4. Нажмите "Преобразить интерьер"
|
877 |
|
878 |
### 🚀 Возможности:
|
879 |
+
- 20 стилей дизайна - от минимализма до ар-деко
|
880 |
- Автоопределение типа комнаты
|
881 |
+
- Создание вариаций - до 8 вариантов за раз
|
882 |
+
- Детальные изменения - меняйте отдельные элементы
|
883 |
+
- HDR освещение - профессиональная обработка света
|
884 |
+
- Анализ цветовой палитры
|
885 |
|
886 |
---
|
887 |
<center>Made with ❤️ for interior design enthusiasts</center>
|