import os import gradio as gr import torch import logging import sys from PIL import Image, ImageDraw import numpy as np from diffusers import StableDiffusionImg2ImgPipeline from peft import PeftModel # Loglama ayarları logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[ logging.StreamHandler(sys.stdout) ] ) logger = logging.getLogger("app") print("===== Application Startup at", torch.cuda.is_available(), "=====") # Model ve işlem fonksiyonları def load_model(lora_model_id="meryemarpaci/sd2base-inpainting-lora"): """LoRA modelini yükle""" print("Model yükleniyor...") try: # Baz model yükleme print("Baz model yükleniyor...") model_id = "stabilityai/stable-diffusion-2-base" pipe = StableDiffusionImg2ImgPipeline.from_pretrained( model_id, torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32 ) # LoRA ağırlıklarını yükleme print(f"LoRA ağırlıkları yükleniyor: {lora_model_id}") pipe.unet = PeftModel.from_pretrained(pipe.unet, lora_model_id) # GPU'ya taşıma if torch.cuda.is_available(): pipe = pipe.to("cuda") print("Model GPU'ya yüklendi") else: print("xformers mevcut değil, varsayılan dikkat kullanılıyor:", torch.cuda.is_available()) print("Model başarıyla yüklendi!") return pipe except Exception as e: print(f"Model yüklenirken hata: {str(e)}") raise e def create_white_mask(image, mask_points): """Koordinatlara göre beyaz maske oluştur""" if image is None or not mask_points: return None try: # Görüntüyü PIL formatına dönüştür if isinstance(image, np.ndarray): pil_image = Image.fromarray(image) else: pil_image = image.copy() # Boş maske oluştur mask = Image.new("L", pil_image.size, 0) # L modu: 8-bit siyah beyaz draw = ImageDraw.Draw(mask) # Koordinatlara göre maskeyi doldur brush_size = 20 # Fırça boyutu for point in mask_points: x, y = point draw.ellipse((x-brush_size, y-brush_size, x+brush_size, y+brush_size), fill=255) # Maskeyi numpy dizisine dönüştür mask_array = np.array(mask) return mask_array except Exception as e: print(f"Maske oluşturulurken hata: {str(e)}") return None def visualize_mask(image, mask_points): """Maskeyi görselleştir""" if image is None: return None try: # Görüntüyü PIL formatına dönüştür if isinstance(image, np.ndarray): pil_image = Image.fromarray(image).convert("RGBA") else: pil_image = image.convert("RGBA") # Yarı saydam kırmızı maske katmanı oluştur overlay = Image.new("RGBA", pil_image.size, (0, 0, 0, 0)) draw = ImageDraw.Draw(overlay) # Koordinatlara göre maskeyi çiz brush_size = 20 # Fırça boyutu for point in mask_points: x, y = point draw.ellipse((x-brush_size, y-brush_size, x+brush_size, y+brush_size), fill=(255, 0, 0, 128)) # Yarı saydam kırmızı # Katmanları birleştir result = Image.alpha_composite(pil_image, overlay) return result.convert("RGB") # RGB'ye dönüştür except Exception as e: print(f"Maske görselleştirilirken hata: {str(e)}") return image def process_inpainting(image, prompt, negative_prompt, guidance_scale, steps): """İnpainting işlemi gerçekleştir""" try: # Model yükleme pipe = load_model() # Global değişkenden maske noktalarını al global mask_points # Görüntü kontrolü if image is None: return None, "Lütfen bir görüntü yükleyin." if not mask_points: return None, "Lütfen maskeli bölgeleri işaretleyin." # Maskeyi oluştur mask = create_white_mask(image, mask_points) if mask is None: return None, "Maske oluşturulamadı." # Görüntüyü PIL formatına dönüştür if isinstance(image, np.ndarray): image = Image.fromarray(image) # Maskeyi PIL formatına dönüştür mask = Image.fromarray(mask) # İnpainting işlemi result = pipe( prompt=prompt, image=image, strength=0.8, # İnpainting için uygun değer num_inference_steps=steps, guidance_scale=guidance_scale, negative_prompt=negative_prompt if negative_prompt else None, ).images[0] # İşlem tamamlandıktan sonra maske noktalarını temizle mask_points = [] return result, "İnpainting işlemi başarıyla tamamlandı!" except Exception as e: error_msg = f"İnpainting işleminde hata: {str(e)}" print(error_msg) return None, error_msg # Tıklama koordinatlarını kaydet mask_points = [] def add_point(image, evt: gr.SelectData): """Tıklama koordinatlarını kaydet""" global mask_points # Gradio sürümüne göre farklı formatlarda gelebilir if hasattr(evt, 'index'): if isinstance(evt.index, tuple): # Yeni Gradio sürümleri için x, y = evt.index else: # Bazı sürümlerde tek bir indeks olabilir x, y = evt.index, 0 elif hasattr(evt, 'point'): # Eski Gradio sürümleri için x, y = evt.point else: # Diğer durumlar için print("Tıklama koordinatları alınamadı:", evt) return image # Koordinatı kaydet mask_points.append((x, y)) print(f"Nokta eklendi: {x}, {y} - Toplam: {len(mask_points)}") # Maskeyi görselleştir return visualize_mask(image, mask_points) def clear_points(image): """Tüm koordinatları temizle""" global mask_points mask_points = [] return image, "Maske noktaları temizlendi." # Basit arayüz title = "İnpainting LoRA Demo" description = """ # İnpainting LoRA Modeli Demo Bu demo, görüntülerdeki maskelenmiş bölgeleri akıllıca tamamlayan bir LoRA modelini kullanır. **Kullanım:** 1. Bir görüntü yükleyin 2. Değiştirmek istediğiniz bölgelere tıklayın (kırmızı işaretler maskelenecek alanları gösterir) 3. Prompt girin ve "İnpainting Yap" butonuna tıklayın """ # Basit arayüz - tool parametresi olmadan with gr.Blocks(title=title) as demo: gr.Markdown(description) with gr.Row(): with gr.Column(): # Normal resim bileşeni input_image = gr.Image(label="Resim (Değiştirmek istediğiniz bölgelere tıklayın)", type="numpy") # Tıklama olayını yakala input_image.select(add_point, input_image, input_image) clear_btn = gr.Button("Maske Noktalarını Temizle") mask_status = gr.Textbox(label="Maske Durumu", value="Henüz maske noktası eklenmedi.") # Temizleme butonunun hem resmi hem de durumu güncellemesi clear_btn.click(clear_points, inputs=[input_image], outputs=[input_image, mask_status]) prompt = gr.Textbox( label="Prompt", value="Yüksek kaliteli bir fotoğraf", placeholder="İnpainting için kullanılacak prompt" ) negative_prompt = gr.Textbox( label="Negatif Prompt (İsteğe Bağlı)", placeholder="İstenmeyen özellikler" ) with gr.Row(): guidance_scale = gr.Slider( label="Guidance Scale", minimum=1.0, maximum=15.0, value=7.5, step=0.5 ) steps = gr.Slider( label="Adım Sayısı", minimum=20, maximum=100, value=50, step=1 ) run_button = gr.Button("İnpainting Yap", variant="primary") with gr.Column(): output_image = gr.Image(label="Sonuç") output_message = gr.Textbox(label="Durum") run_button.click( fn=process_inpainting, inputs=[input_image, prompt, negative_prompt, guidance_scale, steps], outputs=[output_image, output_message] ) gr.Markdown(""" ### Model Hakkında Bu demo, [meryemarpaci/sd2base-inpainting-lora](https://huggingface.co/meryemarpaci/sd2base-inpainting-lora) modelini kullanmaktadır. - **Taban model**: stabilityai/stable-diffusion-2-base - **LoRA tipi**: UNet attention layers - **Özellik**: Görüntülerdeki maskelenmiş bölgeleri akıllıca tamamlama """) # Ana uygulama if __name__ == "__main__": demo.launch()