Görsel Üzerinde Bölge Düzenleme: Stable Diffusion Inpainting Rehberi
Stable Diffusion ile çalışırken en sık karşılaşılan ihtiyaçlardan biri, ürettiğin bir görselin yalnızca belirli bir bölgesini değiştirmek istemen. Belki yüz ifadesi yanlış çıktı, arka planda istemediğin bir nesne var ya da kıyafet rengi tam aklındaki gibi olmadı. İşte tam bu noktada inpainting devreye giriyor. Bu rehberde inpainting’in ne olduğunu, nasıl çalıştığını ve production ortamında nasıl verimli kullanacağını adım adım ele alacağız.
Inpainting Nedir ve Nasıl Çalışır
Inpainting, bir görselin seçili bölgesini mask (maske) kullanarak yeniden üretme işlemidir. Model, maskelenmemiş alanı bağlam olarak okur ve maskelenen bölgeyi prompt’a uygun şekilde doldurur. Bu işlem sıfırdan görsel üretmekten farklıdır çünkü model mevcut görselin renk paleti, ışık yönü ve genel kompozisyonunu dikkate alarak çalışır.
Teknik olarak bakıldığında, inpainting sırasında şu adımlar gerçekleşir:
- Orijinal görsel latent space’e encode edilir
- Maske bilgisi modele iletilir
- Maskelenen bölge gürültü ile doldurulur
- Denoising işlemi yalnızca maskelenen alanda veya tüm görselde (seçime göre) uygulanır
- Sonuç decode edilerek piksel uzayına geri döndürülür
Masked only modu yalnızca seçili alanı işler, bu yüzden hızlıdır. Whole picture modu ise tüm görseli işleyerek daha tutarlı bir ışıklandırma ve renk geçişi sağlar ancak daha fazla hesaplama gerektirir.
Kurulum Gereksinimleri
Automatic1111 WebUI üzerinde inpainting yapabilmek için temel kurulumun tamamlanmış olması gerekiyor. Eğer henüz kurmadıysan önce bunu halledelim:
# Python sanal ortam oluştur
python3 -m venv sd-venv
source sd-venv/bin/activate
# Temel bağımlılıkları yükle
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
# WebUI'yi klonla
git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
cd stable-diffusion-webui
Inpainting için özelleşmiş model dosyalarına ihtiyacın var. Standart checkpoint’ler inpainting yapabilir ama inpainting’e özel checkpoint’ler çok daha iyi sonuç verir:
# Model klasörüne geç
cd models/Stable-diffusion
# Inpainting modeli indir (örnek - runwayml inpainting)
wget -c "https://huggingface.co/runwayml/stable-diffusion-inpainting/resolve/main/sd-v1-5-inpainting.ckpt"
-O sd-v1-5-inpainting.ckpt
# İndirme tamamlandı mı kontrol et
ls -lh sd-v1-5-inpainting.ckpt
WebUI’yi Inpainting İçin Yapılandırma
WebUI başlatma scriptini inpainting performansı için optimize etmek önemli. webui-user.sh dosyasını düzenle:
# webui-user.sh dosyasını aç
nano webui-user.sh
# İçeriği şu şekilde güncelle
export COMMANDLINE_ARGS="--xformers --medvram --api --listen"
# Eğer 8GB+ VRAM varsa medvram yerine şunu kullan
export COMMANDLINE_ARGS="--xformers --api --listen"
Bayrakların ne işe yaradığına bakalım:
- –xformers: Attention mekanizmasını optimize eder, inpainting’de %30-40 bellek tasarrufu sağlar
- –medvram: 6-8GB VRAM için orta bellek modu
- –api: REST API’yi aktif eder, script ile otomasyona izin verir
- –listen: Tüm network interface’lerden erişim sağlar
API ile Inpainting Otomasyonu
Gerçek dünyada inpainting işlemlerini script ile otomatize etmek sıkça lazım oluyor. Bir batch görsel düzeltme senaryosu düşün: yüzlerce ürün fotoğrafının arka planını değiştirmen gerekiyor. Bunu WebUI’den tek tek yapmak yerine API kullanmak çok daha mantıklı.
Önce API’nin çalıştığını test edelim:
# API erişimini test et
curl -s http://localhost:7860/sdapi/v1/sd-models | python3 -m json.tool | head -20
# Inpainting endpoint'ini kontrol et
curl -s -X POST http://localhost:7860/sdapi/v1/img2img
-H "Content-Type: application/json"
-d '{"prompt": "test", "init_images": [""], "mask": ""}'
2>&1 | head -5
Şimdi gerçek bir inpainting script’i yazalım. Bu script, bir görselin belirli bölgesini yeniden üretir:
#!/bin/bash
# inpaint_region.sh - Belirli bir bölgeyi inpainting ile düzelt
INPUT_IMAGE="$1"
MASK_IMAGE="$2"
PROMPT="$3"
OUTPUT_DIR="./inpaint_output"
mkdir -p "$OUTPUT_DIR"
# Görseli base64'e çevir
IMG_B64=$(base64 -w 0 "$INPUT_IMAGE")
MASK_B64=$(base64 -w 0 "$MASK_IMAGE")
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
OUTPUT_FILE="$OUTPUT_DIR/inpainted_${TIMESTAMP}.png"
# API isteği gönder
RESPONSE=$(curl -s -X POST http://localhost:7860/sdapi/v1/img2img
-H "Content-Type: application/json"
-d "{
"prompt": "$PROMPT",
"negative_prompt": "blurry, low quality, artifacts, distorted",
"init_images": ["$IMG_B64"],
"mask": "$MASK_B64",
"mask_blur": 4,
"inpainting_fill": 1,
"inpaint_full_res": true,
"inpaint_full_res_padding": 32,
"denoising_strength": 0.75,
"steps": 25,
"sampler_name": "DPM++ 2M Karras",
"cfg_scale": 7,
"width": 512,
"height": 512
}")
# Sonucu dosyaya kaydet
echo "$RESPONSE" | python3 -c "
import sys, json, base64
data = json.load(sys.stdin)
img_data = base64.b64decode(data['images'][0])
with open('$OUTPUT_FILE', 'wb') as f:
f.write(img_data)
print('Kaydedildi: $OUTPUT_FILE')
"
Scripti kullanmak için:
chmod +x inpaint_region.sh
./inpaint_region.sh ./product.png ./mask.png "white background, studio lighting, clean"
Mask Oluşturma Teknikleri
Maskenin kalitesi inpainting sonucunu doğrudan etkiliyor. Python ile programatik mask oluşturmak çoğu zaman el ile çizmekten daha hassas sonuçlar veriyor:
# Python ile mask oluşturma scripti
python3 << 'EOF'
from PIL import Image, ImageDraw
import numpy as np
def create_rectangular_mask(img_width, img_height, x1, y1, x2, y2, feather=10):
"""Belirtilen koordinatlarda dikdörtgen mask oluşturur"""
mask = Image.new('L', (img_width, img_height), 0)
draw = ImageDraw.Draw(mask)
# Ana dikdörtgeni doldur
draw.rectangle([x1, y1, x2, y2], fill=255)
# Kenarları yumuşat (feathering)
if feather > 0:
import PIL.ImageFilter as ImageFilter
mask = mask.filter(ImageFilter.GaussianBlur(radius=feather))
return mask
# 512x512 görsel için yüz bölgesi maskesi
mask = create_rectangular_mask(512, 512, 150, 100, 350, 320, feather=8)
mask.save('face_mask.png')
print("Mask oluşturuldu: face_mask.png")
# Maske istatistiklerini göster
mask_array = np.array(mask)
white_pixels = np.sum(mask_array > 128)
total_pixels = mask_array.size
print(f"Maskelenen alan: {white_pixels}/{total_pixels} piksel ({white_pixels/total_pixels*100:.1f}%)")
EOF
Denoising Strength Değerinin Önemi
Inpainting’de en kritik parametre denoising_strength. Bu değeri yanlış ayarlamak en yaygın sorunun kaynağı. Değerin etkileri:
- 0.1 – 0.3: Orijinale çok sadık kalır, ince düzeltmeler için
- 0.4 – 0.6: Dengeli değişim, renk/doku değişimi için ideal
- 0.7 – 0.85: Belirgin değişim, farklı nesneler eklemek için
- 0.9 – 1.0: Neredeyse sıfırdan üretim, orijinalden kopuk sonuçlar
Farklı denoising değerleri ile batch test yapmak için:
#!/bin/bash
# batch_denoising_test.sh - Farklı denoising değerlerini test et
INPUT="$1"
MASK="$2"
PROMPT="$3"
IMG_B64=$(base64 -w 0 "$INPUT")
MASK_B64=$(base64 -w 0 "$MASK")
for DENOISE in 0.3 0.5 0.7 0.85; do
echo "Denoising strength: $DENOISE test ediliyor..."
curl -s -X POST http://localhost:7860/sdapi/v1/img2img
-H "Content-Type: application/json"
-d "{
"prompt": "$PROMPT",
"init_images": ["$IMG_B64"],
"mask": "$MASK_B64",
"denoising_strength": $DENOISE,
"steps": 20,
"cfg_scale": 7,
"sampler_name": "Euler a"
}" | python3 -c "
import sys, json, base64
data = json.load(sys.stdin)
img = base64.b64decode(data['images'][0])
with open('test_denoise_${DENOISE}.png', 'wb') as f:
f.write(img)
print('Kaydedildi: test_denoise_${DENOISE}.png')
"
sleep 2
done
echo "Tüm testler tamamlandı. Sonuçları karşılaştır."
Inpaint Full Resolution Modu
Büyük görsellerde küçük bir bölgeyi düzeltiyorsan inpaint_full_res parametresi hayat kurtarır. Bu mod, maskelenen bölgeyi modelin native çözünürlüğüne (genellikle 512×512 veya 768×768) sığacak şekilde crop edip işler, sonra orijinal yerine yapıştırır. Böylece 1024×1024 bir görselin 100×100 piksellik yüz bölgesini yüksek kalitede düzeltebilirsin.
Padding değeri önemli: çok az padding verirsen model bağlamı göremez, çok fazla verirsen küçük detaylar kaybolur. 32-64 piksel çoğu durumda iyi çalışır.
# Full resolution inpainting - ürün fotoğrafı arka plan düzeltme örneği
python3 << 'EOF'
import requests
import base64
import json
from pathlib import Path
def inpaint_full_res(image_path, mask_path, prompt, padding=32, denoising=0.75):
"""Full resolution modda inpainting uygula"""
with open(image_path, 'rb') as f:
img_b64 = base64.b64encode(f.read()).decode()
with open(mask_path, 'rb') as f:
mask_b64 = base64.b64encode(f.read()).decode()
payload = {
"prompt": prompt,
"negative_prompt": "blurry, low quality, noise, jpeg artifacts",
"init_images": [img_b64],
"mask": mask_b64,
"mask_blur": 4,
"inpainting_fill": 1,
"inpaint_full_res": True,
"inpaint_full_res_padding": padding,
"denoising_strength": denoising,
"steps": 30,
"sampler_name": "DPM++ 2M Karras",
"cfg_scale": 7.5,
"seed": -1,
"restore_faces": False
}
response = requests.post(
"http://localhost:7860/sdapi/v1/img2img",
json=payload,
timeout=120
)
if response.status_code == 200:
result = response.json()
output_path = f"output_{Path(image_path).stem}_inpainted.png"
with open(output_path, 'wb') as f:
f.write(base64.b64decode(result['images'][0]))
print(f"Basarili: {output_path}")
# Seed bilgisini göster (tekrar üretmek için)
if 'info' in result:
info = json.loads(result['info'])
print(f"Kullanilan seed: {info.get('seed', 'bilinmiyor')}")
return output_path
else:
print(f"Hata: {response.status_code} - {response.text}")
return None
# Kullanim örneği
inpaint_full_res(
"product_photo.png",
"background_mask.png",
"clean white studio background, professional product photography",
padding=48,
denoising=0.8
)
EOF
Yaygın Sorunlar ve Çözümleri
Inpainting yaparken karşılaşılan sorunların büyük çoğunluğu birkaç temel nedenden kaynaklanıyor.
Sınır artefaktları: Maskenin kenarında çirkin geçişler oluşuyor. Çözüm: mask_blur değerini artır (4-8 arası), inpaint_full_res kullan.
Renk uyumsuzluğu: Düzeltilen bölge çevresiyle uyumsuz. Çözüm: Denoising değerini düşür, whole picture modunu dene.
Detay kaybı: Düzeltilen bölge bulanık çıkıyor. Çözüm: Inpaint full res aktif et, padding’i azalt.
OOM hatası (Out of Memory): VRAM yetersizliği. Çözüm:
# VRAM durumunu kontrol et
nvidia-smi --query-gpu=memory.used,memory.free,memory.total --format=csv
# WebUI'yi düşük bellek moduyla yeniden başlat
./webui.sh --lowvram --medvram-sdxl
# Tile boyutunu küçült
export COMMANDLINE_ARGS="--xformers --lowvram --opt-split-attention --opt-sub-quad-attention"
Işık tutarsızlığı: Maskelenen bölgenin ışığı orijinalle uyuşmuyor. Çözüm: Prompt’a ışık yönünü ekle (“soft side lighting, same lighting as surrounding”), cfg_scale’i biraz düşür.
Batch Inpainting ile İş Akışı Otomasyonu
E-ticaret görselleri, sosyal medya içerikleri veya veri seti oluşturma gibi senaryolarda yüzlerce görseli otomatik işlemen gerekebilir. Klasör bazlı batch inpainting script’i:
#!/bin/bash
# batch_inpaint.sh - Klasördeki tüm görselleri inpaint et
# Kullanim: ./batch_inpaint.sh ./images/ ./masks/ "prompt" ./output/
IMAGES_DIR="$1"
MASKS_DIR="$2"
PROMPT="$3"
OUTPUT_DIR="${4:-./batch_output}"
LOG_FILE="$OUTPUT_DIR/batch_log.txt"
mkdir -p "$OUTPUT_DIR"
echo "Batch inpainting basliyor: $(date)" | tee "$LOG_FILE"
SUCCESS=0
FAILED=0
for IMAGE in "$IMAGES_DIR"/*.png "$IMAGES_DIR"/*.jpg; do
[ -f "$IMAGE" ] || continue
BASENAME=$(basename "$IMAGE" | sed 's/.[^.]*$//')
MASK="$MASKS_DIR/${BASENAME}_mask.png"
if [ ! -f "$MASK" ]; then
echo "UYARI: $BASENAME icin mask bulunamadi, atlaniyor" | tee -a "$LOG_FILE"
continue
fi
echo "Isleniyor: $BASENAME" | tee -a "$LOG_FILE"
IMG_B64=$(base64 -w 0 "$IMAGE")
MASK_B64=$(base64 -w 0 "$MASK")
RESULT=$(curl -s -X POST http://localhost:7860/sdapi/v1/img2img
-H "Content-Type: application/json"
--max-time 120
-d "{
"prompt": "$PROMPT",
"negative_prompt": "blurry, low quality, artifacts",
"init_images": ["$IMG_B64"],
"mask": "$MASK_B64",
"denoising_strength": 0.75,
"inpaint_full_res": true,
"inpaint_full_res_padding": 32,
"steps": 25,
"cfg_scale": 7
}")
if echo "$RESULT" | python3 -c "
import sys, json, base64
try:
data = json.load(sys.stdin)
img = base64.b64decode(data['images'][0])
with open('$OUTPUT_DIR/${BASENAME}_inpainted.png', 'wb') as f:
f.write(img)
print('OK')
except Exception as e:
print(f'HATA: {e}', file=sys.stderr)
sys.exit(1)
" 2>/dev/null; then
SUCCESS=$((SUCCESS + 1))
else
FAILED=$((FAILED + 1))
echo "HATA: $BASENAME islenemedi" | tee -a "$LOG_FILE"
fi
# API'yi yorma, kısa bekleme
sleep 1
done
echo "Tamamlandi: $SUCCESS basarili, $FAILED basarisiz" | tee -a "$LOG_FILE"
echo "Cikti dizini: $OUTPUT_DIR"
Model Seçimi ve Inpainting Performansı
Inpainting kalitesi doğrudan kullandığın modele bağlı. Genel modeller inpainting yapabilir ama özelleşmiş inpainting checkpoint’leri daha tutarlı kenar geçişleri ve renk uyumu sağlar. SDXL için farklı yaklaşım gerekiyor:
# SDXL inpainting için gerekli model yapısı
ls -la models/Stable-diffusion/ | grep -i "inpaint|xl"
# SDXL için bellek optimizasyonu
export COMMANDLINE_ARGS="--xformers --medvram-sdxl --opt-split-attention"
# VAE modeli de önemli - inpainting için MSE VAE tercih edilir
ls models/VAE/
# Config dosyasını kontrol et (SDXL inpainting farklı config gerektirir)
cat configs/v1-inpainting-inference.yaml | grep -A5 "conditioning"
ControlNet kullanıyorsan inpainting ile birleştirme imkanın da var. Inpaint ControlNet modeli, maskelenen bölgede daha hassas kontrol sağlar ve mevcut yapıyı (kenarlar, derinlik) daha iyi korur.
Sonuç
Inpainting, Stable Diffusion araç setinin en güçlü özelliklerinden biri. Tek bir görseli elle düzeltmekten yüzlerce dosyayı otomatik işlemeye kadar geniş bir kullanım alanı var. Önemli olan doğru parametreleri seçmek: mask kalitesi, denoising strength ve full resolution modu çoğu sorunun cevabı.
Pratikte en çok işe yarayan yaklaşım, önce küçük bir batch ile farklı denoising değerlerini test etmek, sonra production’a geçmek. API üzerinden çalışmak da uzun vadede çok daha verimli: WebUI arayüzünü açmadan script’lerle işleri otomatize edebilir, CI/CD pipeline’larına bile entegre edebilirsin.
ControlNet ile inpainting kombinasyonu ise konunun bir sonraki adımı. Özellikle mimari görüntülerde pencere/kapı gibi yapısal elemanları değiştirirken ControlNet depth veya canny modunu devreye sokmak sonuçları dramatik şekilde iyileştiriyor. O konuyu da ileride ayrıca ele alacağız.
