Python से बल्क में इमेज बैकग्राउंड हटाएं: rembg बनाम API

इमेज के पूरे फ़ोल्डर से बैकग्राउंड हटाने के लिए दो पूरी स्क्रिप्ट: एक आपके अपने हार्डवेयर पर ओपन-सोर्स rembg लाइब्रेरी के साथ, एक ऐसे HTTP API के साथ जो रीट्राई, रेट लिमिट और दोहरे चार्ज को सही ढंग से संभालती है।

23 अक्टूबर 2026 को अपडेट · 9 मिनट में पढ़ें

आपके पास कुछ सौ प्रोडक्ट फोटो, हेडशॉट या लिस्टिंग इमेज का फ़ोल्डर है, और हर एक का बैकग्राउंड हटाना है। एडिटर में हाथ से करना पूरे दिन क्लिक करने का काम है। Python में यह एक लूप है, और असली फ़ैसला यह है कि लूप के अंदर क्या चलेगा: आपकी अपनी मशीन पर ओपन-सोर्स मॉडल, या HTTP API।

यह गाइड दोनों बनाती है, पूरी स्क्रिप्ट के साथ जिन्हें आप आज ही किसी फ़ोल्डर पर चला सकते हैं, और उन हिस्सों को कवर करती है जो बैच जॉब को भरोसेमंद बनाते हैं: मॉडल चुनना, CPU बनाम GPU, रीट्राई, रेट लिमिट, idempotency और क्रैश के बाद फिर से शुरू करना।

विकल्प A या विकल्प B?

लोकल मॉडल (rembg)HTTP API
लागतमुफ़्त सॉफ़्टवेयर; आप हार्डवेयर और समय में चुकाते हैंहर इमेज के हिसाब से
सेटअपPython 3.11 से 3.13, मॉडल डाउनलोड, वैकल्पिक CUDAएक API की और requests
स्पीडआपके CPU या GPU और मॉडल पर निर्भरसेवा और पैरेलल रिक्वेस्ट पर निर्भर
क्वालिटीआपके चुने मॉडल पर निर्भरसेवा पर निर्भर
प्राइवेसीइमेज कभी आपकी मशीन से बाहर नहीं जातींइमेज किसी तीसरे पक्ष पर अपलोड होती हैं
रखरखावमॉडल, ड्राइवर और लाइसेंस आप संभालते हैंप्रोवाइडर संभालता है
किसके लिए अच्छाऑफ़लाइन काम, संवेदनशील इमेज, प्रयोगप्रोडक्शन पाइपलाइन, बिना GPU वाले सर्वर

कई टीमें दोनों इस्तेमाल करती हैं: प्रयोगों और अंदरूनी टूल के लिए लोकल मॉडल, और प्रोडक्शन के लिए API जहां अनुमान लायक क्वालिटी और GPU सर्वर न होना ज़्यादा मायने रखता है।

विकल्प A: rembg, ओपन-सोर्स रास्ता

rembg एक MIT-लाइसेंस वाली Python लाइब्रेरी और CLI है जो कई बैकग्राउंड रिमूवल मॉडल को लपेटती है और उन्हें ONNX Runtime से चलाती है। इसे लिखते समय मौजूदा रिलीज़ 2.0.86 है, और इसके लिए Python 3.11 या बाद का और 3.14 से पहले का चाहिए।

इंस्टॉल करें

अपने हार्डवेयर से मेल खाता बैकएंड चुनें। CPU बिल्ड हर जगह चलता है:

python -m venv .venv && source .venv/bin/activate
pip install "rembg[cpu]"        # library only
pip install "rembg[cpu,cli]"    # library plus the rembg command

NVIDIA GPU के लिए इसके बजाय rembg[gpu] इंस्टॉल करें। प्रोजेक्ट बताता है कि इसके लिए onnxruntime-gpu और मेल खाते CUDA और cuDNN चाहिए, और सुझाव देता है कि अगर आप इन्हें इंस्टॉल न कर सकें तो CPU बिल्ड पर लौट जाएं। Linux पर AMD GPU onnxruntime-rocm के साथ rembg[rocm] इस्तेमाल करते हैं।

जब ONNX Runtime CUDA (या ROCm) execution provider को उपलब्ध बताता है तो rembg उसे अपने आप चुन लेता है, और CPU पर लौटने पर चेतावनी देता है। ONNX Runtime क्या देख सकता है, यह जांचने के लिए:

import onnxruntime
print(onnxruntime.get_available_providers())  # look for CUDAExecutionProvider

मॉडल चुनें

मॉडल पहली बार इस्तेमाल पर ~/.rembg/models/ में डाउनलोड होते हैं (बदलने के लिए REMBG_HOME सेट करें)। प्रोजेक्ट की सूची से कुछ काम के मॉडल:

मॉडलनोट्स
bria-rmbgडिफ़ॉल्ट। BRIA का RMBG-2.0, लगभग 1.02 GB, 1024 x 1024 पर चलता है। इसका लाइसेंस कमर्शियल इस्तेमाल के लिए पेड एग्रीमेंट मांगता है।
birefnet-generalआम इस्तेमाल वाला BiRefNet मॉडल; अच्छे नरम किनारे
birefnet-general-liteआम इस्तेमाल के लिए हल्का BiRefNet
birefnet-portraitलोगों के लिए ट्यून किया गया
isnet-general-useआम इस्तेमाल वाला IS-Net मॉडल
u2netक्लासिक आम मॉडल; तेज़, ज़्यादा चौकोर किनारे
u2netpहल्का u2net; धीमी मशीनों पर जल्दी के टेस्ट
siluetau2net जैसा ही, 43 MB तक छोटा

दो बातें दिखने से ज़्यादा अहम हैं। पहली, डिफ़ॉल्ट मॉडल कमर्शियल इस्तेमाल के लिए मुफ़्त नहीं है: मॉडल वेट के अपने लाइसेंस होते हैं, rembg के MIT लाइसेंस से अलग, इसलिए जो भी मॉडल आप इस्तेमाल करें उसका सोर्स जांचें। दूसरी, नए मॉडल (bria-rmbg, birefnet-*, isnet-general-use) नरम, अच्छे आकार वाले किनारे देते हैं, जबकि पुराना u2net परिवार ज़्यादा सख़्त, चौकोर किनारे देता है।

किनारे की क्वालिटी के विकल्प

rembg बालों और फ़र जैसे नरम किनारे वाले पिक्सल को संभालने के तीन तरीक़े देता है:

  • डिफ़ॉल्ट: प्रोडक्ट, कार और लोगो जैसे सख़्त किनारे वाले विषयों के लिए ठीक।
  • decontaminate=True (CLI पर -dc): पुराना बैकग्राउंड किनारे के पिक्सल में जो रंगीन हेलो छोड़ता है उसे हटाता है। यह सिर्फ़ रंग बदलता है, मास्क का आकार कभी नहीं, बहुत कम लागत लेता है, और पूरे बैच के लिए चालू छोड़ना सुरक्षित है।
  • alpha_matting=True (-a): जब मास्क का आकार ग़लत हो, जैसे लटें कट गई हों, तो किनारे का फिर से अनुमान लगाता है। यह बहुत धीमा है और converge होने में फ़ेल हो सकता है, जिस स्थिति में rembg डीकंटैमिनेटेड कटआउट पर लौट जाता है।

बिना निगरानी वाले बैच के लिए प्रोजेक्ट -a के बजाय -dc की सलाह देता है क्योंकि यह तेज़ है और फ़ेल नहीं हो सकता। अल्फ़ा चैनल गाइड बताती है कि हेलो क्यों आते हैं।

तेज़ तरीक़ा: CLI

rembg p -m birefnet-general -dc photos/ cutouts/

rembg p पूरा फ़ोल्डर प्रोसेस करता है; फ़ोल्डर पर नज़र रखने और नई फ़ाइलें आते ही प्रोसेस करने के लिए -w जोड़ें।

Python स्क्रिप्ट

यह वर्ज़न मॉडल एक बार लोड करता है, पहले से तैयार फ़ाइलें छोड़ देता है ताकि आप रोककर फिर शुरू कर सकें, और एक फ़ाइल फ़ेल होने पर भी चलता रहता है:

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 से चलाएं। सेशन एक बार बनाना मायने रखता है: मॉडल लोड करने में उसे चलाने से कहीं ज़्यादा समय लगता है, और rembg README बैच परफ़ॉर्मेंस के लिए सेशन दोबारा इस्तेमाल करने की सलाह देता है। आउटपुट हमेशा PNG होते हैं क्योंकि नतीजे में अल्फ़ा चैनल होता है।

rembg कहां कम पड़ता है

  • मॉडल डाउनलोड होते समय पहला रन धीमा होता है, और बड़े मॉडल को बहुत RAM या VRAM चाहिए।
  • ऊंची क्वालिटी वाले मॉडल के साथ CPU थ्रूपुट मामूली है। हज़ार पर लगने से पहले 20 प्रतिनिधि इमेज से टेस्ट करें।
  • लाइसेंस और ड्राइवर आपकी ज़िम्मेदारी हैं। अपने rembg और मॉडल वर्ज़न पिन करें ताकि बाद का अपग्रेड चुपचाप नतीजे न बदल दे।

विकल्प B: HTTP API

API के साथ भारी काम किसी और के GPU पर होता है, और आपकी स्क्रिप्ट ज़्यादातर नेटवर्क को ठीक से संभालने के बारे में है। उदाहरण removebackground.dev API इस्तेमाल करता है क्योंकि इसका कॉन्ट्रैक्ट /openapi.json पर OpenAPI 3.1 के रूप में प्रकाशित है; यही पैटर्न किसी भी मिलती-जुलती सेवा पर लागू होते हैं।

कॉन्ट्रैक्ट

  • x-api-key हेडर में अपनी की के साथ POST https://removebackground.dev/v1/remove।
  • इमेज को multipart फ़ील्ड image_file के रूप में भेजें (JPG, PNG या WebP, 25 MB तक), या image_url के साथ JSON के रूप में।
  • वैकल्पिक फ़ील्ड में format (png, jpg या webp), bg_color, size (preview, medium, hd, full) और crop शामिल हैं।
  • 200 का मतलब है कि बॉडी तैयार इमेज है। 202 का मतलब है कि लगभग 55 सेकंड बाद भी प्रोसेसिंग चल रही है: बॉडी जॉब id वाला JSON है, और आप GET /v1/jobs/{id}/result को पोल करते हैं, जो इमेज तैयार होने तक Retry-After के साथ 409 not_ready जवाब देता है। 202 बॉडी को कभी इमेज के रूप में सेव न करें।
  • हर अकाउंट के लिए एक मिनट में 60 प्रोसेसिंग रिक्वेस्ट तक; इससे ज़्यादा पर आपको Retry-After के साथ 429 rate_limited मिलता है।
  • एक Idempotency-Key हेडर रीट्राई को सुरक्षित बनाता है: उसी रिक्वेस्ट के साथ वही की दोबारा चार्ज करने के बजाय असली जॉब लौटाती है। अलग रिक्वेस्ट के साथ वही की 409 idempotency_key_reused जवाब देती है।
  • नतीजे 48 घंटे बाद डिलीट हो जाते हैं, इसलिए मिलते ही सेव करें।

रीट्राई के नियम जो आपको दोबारा भुगतान से बचाते हैं

रिस्पॉन्सक्या करें
200इमेज सेव करें
202जॉब रिज़ल्ट पोल करें; दोबारा अपलोड न करें
400, 401, 402, 413, 422रिक्वेस्ट, की, क्रेडिट या इमेज ठीक करें; लूप न करें
429Retry-After सेकंड रुकें, उसी की के साथ दोबारा भेजें
500, 503, टाइमआउट, टूटा कनेक्शनरुककर उसी की के साथ दोबारा भेजें
502वह इमेज फ़ेल हुई और चार्ज नहीं हुई; लॉग करें

तरकीब यह है कि idempotency की को निश्चित (deterministic) बनाएं: इमेज बाइट और विकल्पों का हैश। अगर स्क्रिप्ट क्रैश हो और आप उसे दोबारा चलाएं, तो हर दोबारा भेजी गई रिक्वेस्ट में वही की होती है, इसलिए कुछ भी दो बार प्रोसेस या चार्ज नहीं होता।

Python स्क्रिप्ट

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 से चलाएं। चार वर्कर एक मामूली शुरुआत है; अगर तेज़ रिस्पॉन्स आपको प्रति मिनट की सीमा से आगे ले जाएं, तो 429 हैंडलिंग रुककर उसी की के साथ दोबारा भेजती है। फ़ाइलों के बजाय URL भेजने के लिए JSON पोस्ट करें:

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),
)

URL की लंबी सूचियों के लिए उसी API में POST /v1/batch है, जो 100 इमेज URL तक को एक जॉब के रूप में क़तार में रखता है जिसे आप पोल करते हैं।

किसी भी बैच जॉब को मज़बूत बनाना

  • तैयार आउटपुट छोड़ दें ताकि दोबारा चलाने पर नए सिरे से शुरू करने के बजाय वहीं से आगे बढ़े। दोनों स्क्रिप्ट यह करती हैं।
  • नामों के टकराव पर नज़र रखें। एक ही फ़ोल्डर में shoe.jpg और shoe.png दोनों shoe.png बन जाते हैं; इनपुट का नाम बदलें या आउटपुट नाम में असली एक्सटेंशन शामिल करें।
  • फ़ेल हुई फ़ाइलों को एक फ़ाइल में लॉग करें और सिर्फ़ उन्हें दोबारा चलाएं।
  • सब कुछ प्रोसेस करने से पहले एक सैंपल को गहरे और हल्के बैकग्राउंड पर 100% ज़ूम पर जांचें।
  • असली फ़ाइलों को न छुएं। अलग आउटपुट फ़ोल्डर में लिखें।
  • मंज़िल के हिसाब से आउटपुट फ़ॉर्मैट चुनें। ट्रांसपेरेंसी के लिए PNG या WebP, मार्केटप्लेस के लिए सफ़ेद पर JPG। देखें PNG बनाम JPEG बनाम WebP।

सवाल

क्या rembg कमर्शियल इस्तेमाल के लिए मुफ़्त है?

rembg खुद MIT लाइसेंस वाला है, लेकिन हर मॉडल का अपना लाइसेंस है। डिफ़ॉल्ट मॉडल, BRIA का RMBG-2.0 (bria-rmbg), कमर्शियल इस्तेमाल के लिए पेड एग्रीमेंट मांगता है, इसलिए जो मॉडल इस्तेमाल करें उसका लाइसेंस जांचें या कोई दूसरा चुनें।

क्या rembg अपने आप मेरा GPU इस्तेमाल करता है?

हां, अगर आप rembg[gpu] इंस्टॉल करें और ONNX Runtime CUDA provider लोड कर सके (जिसके लिए मेल खाते CUDA और cuDNN चाहिए)। rembg उपलब्ध होने पर CUDA या ROCm इस्तेमाल करता है और CPU पर लौटने पर चेतावनी देता है। onnxruntime.get_available_providers() जांचें।

कौन सा rembg मॉडल सबसे अच्छी क्वालिटी देता है?

नए मॉडल, bria-rmbg (डिफ़ॉल्ट), birefnet परिवार और isnet-general-use, पुराने u2net परिवार से ज़्यादा नरम और बेहतर आकार वाले किनारे देते हैं। लोगों के लिए birefnet-portrait अच्छी शुरुआत है। अपनी इमेज के एक सैंपल पर टेस्ट करें, क्योंकि नतीजे विषय के हिसाब से बदलते हैं।

API कॉल रीट्राई करते समय दोबारा चार्ज होने से कैसे बचें?

एक Idempotency-Key हेडर भेजें और उसी इमेज के हर रीट्राई पर उसे दोबारा इस्तेमाल करें। इसे इमेज बाइट और विकल्पों के हैश से बनाने का मतलब है कि पूरी स्क्रिप्ट दोबारा चलाने पर भी वही की इस्तेमाल होती हैं।

202 रिस्पॉन्स पर मेरी स्क्रिप्ट को क्या करना चाहिए?

इसे अब भी प्रोसेस हो रहा मानें, इमेज नहीं। JSON बॉडी से जॉब id पढ़ें और GET /v1/jobs/{id}/result को पोल करें, और जब भी वह 409 not_ready जवाब दे तो Retry-After तक रुकें। इमेज दोबारा अपलोड न करें।

removebackground.dev API पर मैं कितनी तेज़ी से रिक्वेस्ट भेज सकता हूं?

हर अकाउंट के लिए एक मिनट में 60 प्रोसेसिंग रिक्वेस्ट तक। इससे ज़्यादा पर API Retry-After हेडर के साथ 429 rate_limited जवाब देता है। कई URL के लिए POST /v1/batch हर रिक्वेस्ट में 100 तक लेता है।

अपनी इमेज पर आज़माएं

नए अकाउंट को 50 मुफ़्त क्रेडिट मिलते हैं। हर इमेज के लिए 1 क्रेडिट, कोई सब्सक्रिप्शन नहीं, और क्रेडिट कभी खत्म नहीं होते।

बैकग्राउंड हटाएं

स्रोत