PandaArtStation commited on
Commit
5c10f54
·
verified ·
1 Parent(s): e9d3a3c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +174 -33
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
- # Проверяем наличие object_remover
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
- margin = int(min(width, height) * (0.5 - mask_precision/2))
475
- draw.ellipse([margin, margin, width-margin, height-margin], fill=255)
476
- mask = mask.filter(ImageFilter.GaussianBlur(radius=5))
477
-
478
- # Быстрый inpainting
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
479
  if designer.inpaint_pipe:
480
  result = designer.inpaint_pipe(
481
- prompt="empty clean background",
 
482
  image=image,
483
  mask_image=mask,
484
- strength=0.95,
485
- num_inference_steps=25,
486
- guidance_scale=5.0
487
  ).images[0]
488
  else:
489
- # Fallback на OpenCV
490
- result = cv2.inpaint(
491
- np.array(image),
492
- np.array(mask.convert('L')),
493
- 3,
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"✅ Обработано за ~25 сек"
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>