Elinizde birkaç yüz ürün fotoğrafı, vesikalık ya da ilan görseli olan bir klasör var ve hepsinde arka plan kaldırma gerekiyor. Bunu bir düzenleyicide elle yapmak bütün gününüzü tıklamakla geçirmek demek. Python'da ise bu bir döngüden ibaret; asıl karar döngünün içinde ne çalışacağı: kendi makinenizde açık kaynak bir model mi, yoksa bir HTTP API mi?
Bu rehber ikisini de kuruyor. Bugün bir klasör üzerinde çalıştırabileceğiniz eksiksiz betikler sunuyor ve toplu bir işi güvenilir kılan kısımları ele alıyor: model seçimi, CPU ve GPU, yeniden denemeler, hız sınırları, idempotency ve bir çökmeden sonra kaldığı yerden devam etme.
A seçeneği mi, B seçeneği mi?
| Yerel model (rembg) | HTTP API | |
|---|---|---|
| Maliyet | Yazılım ücretsiz; bedeli donanım ve zamanla ödersiniz | Görsel başına |
| Kurulum | Python 3.11 ile 3.13 arası, model indirmeleri, isteğe bağlı CUDA | Bir API anahtarı ve requests |
| Hız | CPU'nuza ya da GPU'nuza ve modele bağlı | Servise ve paralel isteklere bağlı |
| Kalite | Seçtiğiniz modele bağlı | Servise bağlı |
| Gizlilik | Görseller makinenizden hiç çıkmaz | Görseller üçüncü bir tarafa yüklenir |
| Bakım | Modelleri, sürücüleri ve lisansları siz yönetirsiniz | Sağlayıcı yönetir |
| Uygun olduğu işler | Çevrimdışı çalışma, hassas görseller, denemeler | Üretim ortamındaki iş akışları, GPU'suz sunucular |
Birçok ekip ikisini birlikte kullanır: denemeler ve iç araçlar için yerel bir model, öngörülebilir kalitenin ve GPU sunucusu yönetmemenin daha önemli olduğu üretim ortamı için bir API.
A seçeneği: rembg, açık kaynak yol
rembg, birkaç arka plan kaldırma modelini bir araya getiren ve bunları ONNX Runtime ile çalıştıran, MIT lisanslı bir Python kütüphanesi ve komut satırı aracıdır. Bu yazı hazırlanırken güncel sürüm 2.0.86 ve Python 3.11 ya da daha yenisini, 3.14'ten eskisini gerektiriyor.
Kurulum
Donanımınıza uyan arka ucu seçin. CPU sürümü her yerde çalışır:
python -m venv .venv && source .venv/bin/activate
pip install "rembg[cpu]" # library only
pip install "rembg[cpu,cli]" # library plus the rembg commandNVIDIA GPU'lar için bunun yerine rembg[gpu] kurun. Proje, bunun için onnxruntime-gpu ile uyumlu bir CUDA ve cuDNN gerektiğini belirtiyor ve bunları kuramıyorsanız CPU sürümüne dönmenizi öneriyor. Linux'taki AMD GPU'lar onnxruntime-rocm ile birlikte rembg[rocm] kullanır.
rembg, ONNX Runtime CUDA (ya da ROCm) yürütme sağlayıcısını kullanılabilir gösterdiğinde onu otomatik olarak seçer ve CPU'ya düşerse uyarır. ONNX Runtime'ın neyi gördüğünü kontrol etmek için:
import onnxruntime
print(onnxruntime.get_available_providers()) # look for CUDAExecutionProviderModel seçimi
Modeller ilk kullanımda ~/.rembg/models/ klasörüne iner (değiştirmek için REMBG_HOME değişkenini ayarlayın). Projenin listesinden işe yarayan bazıları:
| Model | Notlar |
|---|---|
bria-rmbg | Varsayılan. BRIA'nın RMBG-2.0 modeli, yaklaşık 1,02 GB, 1024 x 1024 çözünürlükte çalışır. Lisansı ticari kullanım için ücretli bir anlaşma gerektirir. |
birefnet-general | Genel amaçlı BiRefNet modeli; yumuşak kenarlarda başarılı |
birefnet-general-lite | Genel kullanım için daha hafif BiRefNet |
birefnet-portrait | İnsanlar için ayarlanmış |
isnet-general-use | Genel amaçlı IS-Net modeli |
u2net | Klasik genel model; daha hızlı, kenarları daha kaba |
u2netp | Hafif u2net; yavaş makinelerde hızlı testler için |
silueta | u2net ile aynı, 43 MB'a küçültülmüş |
İki nokta göründüğünden daha önemli. Birincisi, varsayılan model ticari kullanım için ücretsiz değildir: model ağırlıklarının rembg'nin MIT lisansından ayrı kendi lisansları vardır, bu yüzden ürününüzde kullandığınız modelin kaynağını kontrol edin. İkincisi, yeni modeller (bria-rmbg, birefnet-*, isnet-general-use) yumuşak ve düzgün şekilli kenarlar üretirken eski u2net ailesi daha sert ve kaba kenarlar verme eğilimindedir.
Kenar kalitesi seçenekleri
rembg, saç ve tüy gibi yumuşak kenar piksellerini işlemek için üç yol sunar:
- Varsayılan: ürünler, arabalar ve logolar gibi keskin kenarlı nesneler için yeterlidir.
decontaminate=True(komut satırında-dc): eski arka planın kenar piksellerinde bıraktığı renkli haleyi temizler. Maskenin şeklini asla değiştirmez, yalnızca rengi değiştirir, çok az maliyetlidir ve bütün bir toplu iş boyunca açık bırakmak güvenlidir.alpha_matting=True(-a): maske şekli yanlış olduğunda, örneğin saç telleri kesildiğinde, kenarın kendisini yeniden hesaplar. Çok daha yavaştır ve yakınsamayabilir; bu durumda rembg renk temizliği yapılmış bir kesime geri döner.
Gözetimsiz toplu işler için proje, daha hızlı olduğu ve başarısız olamayacağı için -a yerine -dc öneriyor. Alfa kanalı rehberi halelerin neden oluştuğunu anlatıyor.
Hızlı yol: komut satırı
rembg p -m birefnet-general -dc photos/ cutouts/rembg p bütün bir klasörü işler; klasörü izleyip yeni dosyaları geldikçe işlemek için -w ekleyin.
Python betiği
Bu sürüm modeli bir kez yükler, durdurup yeniden başlatabilmeniz için tamamlanmış dosyaları atlar ve bir dosya hata verdiğinde çalışmaya devam eder:
import sys
from pathlib import Path
from rembg import new_session, remove
EXTS = {".jpg", ".jpeg", ".png", ".webp"}
def main(in_dir: str, out_dir: str, model: str = "birefnet-general") -> None:
src_dir, dst_dir = Path(in_dir), Path(out_dir)
dst_dir.mkdir(parents=True, exist_ok=True)
session = new_session(model) # load the model once, reuse it for every image
files = sorted(p for p in src_dir.iterdir() if p.suffix.lower() in EXTS)
for i, src in enumerate(files, 1):
dst = dst_dir / f"{src.stem}.png"
if dst.exists():
continue # resume where a previous run stopped
try:
out = remove(src.read_bytes(), session=session, decontaminate=True)
dst.write_bytes(out)
print(f"[{i}/{len(files)}] ok {src.name}")
except Exception as e: # one bad file shouldn't stop the batch
print(f"[{i}/{len(files)}] failed {src.name}: {e}")
if __name__ == "__main__":
main(*sys.argv[1:])python batch_rembg.py photos cutouts birefnet-general komutuyla çalıştırın. Oturumu bir kez oluşturmak önemlidir: bir modeli yüklemek onu çalıştırmaktan çok daha uzun sürer ve rembg README dosyası toplu iş performansı için oturumun yeniden kullanılmasını öneriyor. Sonuçta bir alfa kanalı olduğu için çıktılar her zaman PNG'dir.
rembg'nin yetersiz kaldığı yerler
- İlk çalıştırma yavaştır, çünkü model indirilir; büyük modeller de çok fazla RAM ya da VRAM ister.
- Yüksek kaliteli modellerle CPU hızı mütevazıdır. Bin görsele girişmeden önce temsil edici 20 görselle test edin.
- Lisanslar ve sürücüler sizin sorumluluğunuzdadır. Sonraki bir güncelleme sonuçları sessizce değiştirmesin diye rembg ve model sürümlerinizi sabitleyin.
B seçeneği: bir HTTP API
API ile ağır iş başkasının GPU'larında yapılır ve betiğiniz büyük ölçüde ağı iyi yönetmekle ilgilenir. Örnek, sözleşmesi /openapi.json adresinde OpenAPI 3.1 olarak yayımlandığı için removebackground.dev API'sini kullanıyor; aynı kalıplar benzer her servis için geçerlidir.
Sözleşme
- Anahtarınız
x-api-keybaşlığında olacak şekildePOST https://removebackground.dev/v1/remove. - Görseli
image_fileadlı multipart alanında (JPG, PNG ya da WebP, en fazla 25 MB) ya daimage_urliçeren JSON olarak gönderin. - İsteğe bağlı alanlar arasında
format(png,jpgya dawebp),bg_color,size(preview,medium,hd,full) vecropbulunur. - 200, gövdenin bitmiş görsel olduğu anlamına gelir. 202, yaklaşık 55 saniye sonra hâlâ işlendiği anlamına gelir: gövde bir iş
iddeğeri içeren JSON'dur veGET /v1/jobs/{id}/resultadresini yoklarsınız; bu adres görsel hazır olana kadarRetry-Afterile 409not_readyyanıtı verir. 202 gövdesini asla görsel olarak kaydetmeyin. - Hesap başına dakikada en fazla 60 işleme isteği; bunun üzerinde
Retry-Afterile 429rate_limitedyanıtı alırsınız. Idempotency-Keybaşlığı yeniden denemeleri güvenli kılar: aynı anahtar ve aynı istek, yeniden ücret almak yerine ilk işi döndürür. Aynı anahtar farklı bir istekle gelirse 409idempotency_key_reusedyanıtı verilir.- Sonuçlar 48 saat sonra silinir, bu yüzden aldığınızda kaydedin.
İki kez ödemenizi önleyen yeniden deneme kuralları
| Yanıt | Ne yapmalı |
|---|---|
| 200 | Görseli kaydedin |
| 202 | İş sonucunu yoklayın; yeniden yüklemeyin |
| 400, 401, 402, 413, 422 | İsteği, anahtarı, krediyi ya da görseli düzeltin; döngüye sokmayın |
| 429 | Retry-After kadar saniye bekleyin, aynı anahtarla yeniden gönderin |
| 500, 503, zaman aşımı, kopan bağlantı | Bekleme süresini artırarak aynı anahtarla yeniden gönderin |
| 502 | O görsel başarısız oldu ve ücretlendirilmedi; kaydını tutun |
İşin püf noktası idempotency anahtarını deterministik yapmaktır: görsel baytlarının ve seçeneklerin bir hash değeri. Betik çöker ve yeniden çalıştırırsanız her yeniden gönderim aynı anahtarı taşır, böylece hiçbir şey iki kez işlenmez ya da ücretlendirilmez.
Python betiği
import hashlib
import mimetypes
import os
import sys
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from pathlib import Path
import requests
API = os.environ.get("REMOVEBG_API", "https://removebackground.dev")
KEY = os.environ["REMOVEBG_API_KEY"] # keep the key out of your code
OPTIONS = {"format": "png", "size": "full"} # or {"format": "jpg", "bg_color": "ffffff"}
WORKERS = 4 # the API allows 60 processing requests a minute
EXTS = {".jpg", ".jpeg", ".png", ".webp"}
RETRYABLE = {429, 500, 503}
def idempotency_key(data: bytes) -> str:
# Same image + same options = same key, so a rerun never pays twice.
h = hashlib.sha256(data)
h.update(repr(sorted(OPTIONS.items())).encode())
return h.hexdigest()
def wait(res, default=2.0):
try:
return float(res.headers.get("Retry-After", default))
except ValueError:
return default
def save(res, dst: Path) -> Path:
if res.status_code != 200 or not res.headers.get("Content-Type", "").startswith("image/"):
raise RuntimeError(f"HTTP {res.status_code}: {res.text[:300]}")
dst.write_bytes(res.content)
return dst
def process(src: Path, dst: Path) -> Path:
data = src.read_bytes()
mime = mimetypes.guess_type(src.name)[0] or "application/octet-stream"
headers = {"x-api-key": KEY, "Idempotency-Key": idempotency_key(data)}
for attempt in range(6):
try:
res = requests.post(
f"{API}/v1/remove",
files={"image_file": (src.name, data, mime)},
data=OPTIONS,
headers=headers,
timeout=(10, 120),
)
except (requests.ConnectionError, requests.Timeout):
time.sleep(2 ** attempt) # same key: safe to resend
continue
if res.status_code in RETRYABLE:
time.sleep(wait(res, 2 ** attempt))
continue
break
else:
raise RuntimeError("gave up after retries")
if res.status_code != 202:
return save(res, dst) # 200 is the image; 4xx and 502 raise
# 202: still processing. Poll the same job; never upload the image again.
job_id = res.json()["id"]
deadline = time.monotonic() + 600
while time.monotonic() < deadline:
time.sleep(wait(res))
try:
res = requests.get(f"{API}/v1/jobs/{job_id}/result", headers=headers, timeout=30)
except (requests.ConnectionError, requests.Timeout):
continue # reading a job is free and safe to repeat
if res.status_code == 409 and res.json()["error"]["code"] == "not_ready":
continue
if res.status_code >= 500:
continue
return save(res, dst)
raise TimeoutError(f"job {job_id} still running; fetch it later")
def main(in_dir: str, out_dir: str) -> None:
src_dir, dst_dir = Path(in_dir), Path(out_dir)
dst_dir.mkdir(parents=True, exist_ok=True)
ext = ".jpg" if OPTIONS.get("format") == "jpg" else "." + OPTIONS.get("format", "png")
todo = [
(p, dst_dir / (p.stem + ext))
for p in sorted(src_dir.iterdir())
if p.suffix.lower() in EXTS and not (dst_dir / (p.stem + ext)).exists()
]
print(f"{len(todo)} images to process")
failed = []
with ThreadPoolExecutor(max_workers=WORKERS) as pool:
jobs = {pool.submit(process, s, d): s for s, d in todo}
for fut in as_completed(jobs):
src = jobs[fut]
try:
print("ok ", src.name, "->", fut.result().name)
except Exception as e:
failed.append(src.name)
print("failed", src.name, e)
print(f"done: {len(todo) - len(failed)} ok, {len(failed)} failed")
if __name__ == "__main__":
main(sys.argv[1], sys.argv[2])REMOVEBG_API_KEY=... python batch_api.py photos cutouts komutuyla çalıştırın. Dört işçi temkinli bir başlangıçtır; hızlı yanıtlar sizi dakikalık sınırın üzerine çıkarırsa 429 yönetimi bekler ve aynı anahtarla yeniden gönderir. Dosya yerine URL göndermek için JSON gönderin:
res = requests.post(
f"{API}/v1/remove",
json={"image_url": "https://example.com/shoe.jpg", "format": "png"},
headers={"x-api-key": KEY, "Idempotency-Key": "shoe-front-v1"},
timeout=(10, 120),
)Uzun URL listeleri için aynı API'de, en fazla 100 görsel URL'sini yokladığınız tek bir iş olarak sıraya alan POST /v1/batch uç noktası var.
Her toplu işi sağlamlaştırmak
- Tamamlanmış çıktıları atlayın, böylece yeniden çalıştırma baştan başlamak yerine kaldığı yerden devam eder. İki betik de bunu yapıyor.
- İsim çakışmalarına dikkat edin. Aynı klasördeki
shoe.jpgveshoe.pngdosyalarının ikisi deshoe.pngolur; girdileri yeniden adlandırın ya da özgün uzantıyı çıktı adına ekleyin. - Hataları bir dosyaya kaydedin ve yalnızca onları yeniden çalıştırın.
- Her şeyi işlemeden önce bir örneği koyu ve açık arka planlarda %100 yakınlaştırmayla kontrol edin.
- Orijinallere dokunmayın. Ayrı bir çıktı klasörüne yazın.
- Çıktı biçimini hedefe göre seçin. Şeffaflık için PNG ya da WebP, pazaryerleri için beyaz üzerine JPG. Bkz. PNG, JPEG ve WebP karşılaştırması.
Sorular
rembg ticari kullanım için ücretsiz mi?
rembg'nin kendisi MIT lisanslıdır, ancak her modelin kendi lisansı vardır. Varsayılan model olan BRIA'nın RMBG-2.0'ı (bria-rmbg) ticari kullanım için ücretli bir anlaşma gerektirir; bu yüzden kullandığınız modelin lisansını kontrol edin ya da başka bir model seçin.
rembg GPU'mu otomatik olarak kullanır mı?
Evet, rembg[gpu] kurarsanız ve ONNX Runtime CUDA sağlayıcısını yükleyebilirse (bunun için uyumlu CUDA ve cuDNN gerekir). rembg, varsa CUDA ya da ROCm kullanır ve CPU'ya düştüğünde uyarır. onnxruntime.get_available_providers() ile kontrol edin.
En iyi kaliteyi hangi rembg modeli verir?
Yeni modeller, yani bria-rmbg (varsayılan), birefnet ailesi ve isnet-general-use, eski u2net ailesine göre daha yumuşak ve daha düzgün şekilli kenarlar üretir. İnsanlar için birefnet-portrait iyi bir başlangıçtır. Sonuçlar nesneye göre değiştiği için kendi görsellerinizden bir örnekle test edin.
API çağrılarını yeniden denerken iki kez ücretlendirilmekten nasıl kaçınırım?
Bir Idempotency-Key başlığı gönderin ve aynı görselin her yeniden denemesinde onu tekrar kullanın. Anahtarı görsel baytlarının ve seçeneklerin hash değerinden türetirseniz, betiğin tamamını yeniden çalıştırdığınızda bile aynı anahtarlar kullanılır.
Betiğim 202 yanıtıyla ne yapmalı?
Bunu bir görsel olarak değil, hâlâ işleniyor olarak değerlendirin. JSON gövdesinden iş id değerini okuyun ve GET /v1/jobs/{id}/result adresini yoklayın; 409 not_ready yanıtı geldiğinde her seferinde Retry-After kadar bekleyin. Görseli yeniden yüklemeyin.
removebackground.dev API'sine ne kadar hızlı istek gönderebilirim?
Hesap başına dakikada en fazla 60 işleme isteği. Bunun üzerinde API, Retry-After başlığıyla 429 rate_limited yanıtı verir. Çok sayıda URL için POST /v1/batch istek başına en fazla 100 URL kabul eder.
Kendi görselinizde deneyin
Yeni hesaplara 50 ücretsiz kredi verilir. Görsel başına bir kredi, abonelik yok ve kredilerin süresi hiç dolmaz.
Arka plan kaldırınKaynaklar
- rembg on GitHub (README: installation, models, edge modes)
- rembg on PyPI (version and Python requirement)
- BRIA RMBG-2.0 model card and license
- ONNX Runtime: Get started and installation matrix
- removebackground.dev API reference and guides
- removebackground.dev OpenAPI 3.1 schema
- Requests: Quickstart (multipart file uploads, timeouts)