Background Removal with rembg and U²-Net: A Complete, Practical Guide

Background Removal with rembg and U²-Net: A Complete, Practical Guide

How the U²-Net salient-object model powers one-line background removal — with real, runnable code.

Removing the background from an image used to mean opening an editor, tracing around the subject, and cleaning up the edges by hand. As of August 7, 2026, you can do it in one line of code — offline, for free — thanks to an open-source tool called rembg and the deep-learning model it rides on, U²-Net. This guide explains what each one is, how they fit together, and gives you copy-paste examples you can run today.

Why now? Background removal is quietly everywhere: e-commerce product shots on white, profile avatars, thumbnails, sticker packs, ID photos, dataset preparation for other models, and app icons. Cloud APIs charge per image and send your pictures to a third party. rembg does the same job locally, which is cheaper, private, and scriptable.

The problem: separating subject from background

The technical name for this task is salient object detection (SOD): finding the pixels that make up the most visually prominent object in an image. Once you have that per-pixel "is this the subject?" map, background removal is just turning everything else transparent. So the hard part is not the erasing — it is producing an accurate mask, especially around tricky edges like hair, fur, and glass.

What is U²-Net?

U²-Net (pronounced "U-squared Net") is a deep neural network published in 2020 for salient object detection. Its key idea is a nested, two-level U-structure. A classic U-Net has an encoder that shrinks the image while learning features, and a decoder that expands it back to a full-resolution mask. U²-Net puts a small U-shaped block — called a ReSidual U-block (RSU) — inside each stage of a larger U-shaped network. That "U inside a U" lets it capture both fine detail and large-scale context without becoming impossibly heavy.

The output is not a colour image. It is a grayscale saliency map: each pixel gets a value from 0 (background) to 1 (subject). rembg takes that map, uses it as the alpha channel, and hands you a transparent PNG.

Two sizes ship widely:

  • u2net — the full model, about 176 MB, best general accuracy.
  • u2netp — a lightweight version, under 5 MB, much faster and smaller, slightly less precise.

What is rembg?

rembg is an open-source (MIT-licensed) Python tool and library that wraps U²-Net — and several newer models — behind a dead-simple interface. It runs the models through ONNX Runtime, so it works on plain CPU and optionally on GPU. On first use it downloads the model weights once and caches them in ~/.u2net/, then runs fully offline afterwards.

You get three ways to use it: a command-line tool, a Python function, and a small HTTP server.

Step 1: Install

# Library + command-line interface
pip install "rembg[cli]"

# Optional: GPU acceleration (needs a CUDA-capable setup)
pip install "rembg[gpu]"

The first time you run any command, rembg fetches the model into ~/.u2net/ (one-time, ~176 MB for the default model). After that it is offline.

Step 2: Remove a background

The command line is the fastest way to try it:

# One image: input can be JPG/PNG/WebP, output should be PNG (needs transparency)
rembg i photo.jpg photo-nobg.png

# A whole folder at once
rembg p ./input-images ./output-images

# Run it as a local HTTP service (great for apps)
rembg s
# then POST an image to http://localhost:7000/api/remove

The Python API is just as short. Working with a PIL image is the cleanest approach:

from rembg import remove
from PIL import Image

with Image.open("photo.jpg") as img:
    result = remove(img)          # returns an RGBA image with the background cut out
    result.save("photo-nobg.png") # PNG preserves transparency

If you prefer raw bytes (for a web handler or a pipeline):

from rembg import remove

with open("photo.jpg", "rb") as src, open("photo-nobg.png", "wb") as dst:
    dst.write(remove(src.read()))

Step 3: Go further — models, clean edges, and new backgrounds

Pick the right model

rembg supports several models; you choose one with -m on the CLI or a session in Python. Different models suit different subjects:

Model Best for Notes
u2net General purpose (default) Balanced accuracy, ~176 MB
u2netp Speed / low memory Tiny (<5 MB), slightly rougher
u2net_human_seg People / portraits Tuned for human figures
isnet-general-use Sharper general masks Often cleaner than u2net
silueta u2net accuracy, smaller size ~43 MB drop-in
birefnet-general Highest quality edges Larger and slower, excellent on hair
# CLI: use the human-segmentation model
rembg i -m u2net_human_seg portrait.jpg portrait-nobg.png
# Python: reuse one session across many images (much faster in a batch)
from rembg import remove, new_session
from PIL import Image

session = new_session("isnet-general-use")
for name in ("a.jpg", "b.jpg", "c.jpg"):
    with Image.open(name) as img:
        remove(img, session=session).save(name.replace(".jpg", "-nobg.png"))

Clean up fine edges with alpha matting

Hair and soft edges are where a raw mask looks cut out with scissors. rembg has built-in alpha matting to soften and refine those transitions:

from rembg import remove
from PIL import Image

with Image.open("hair.jpg") as img:
    result = remove(
        img,
        alpha_matting=True,
        alpha_matting_foreground_threshold=240,
        alpha_matting_background_threshold=10,
        alpha_matting_erode_size=10,
    )
    result.save("hair-nobg.png")

It is slower, but the difference on portraits and furry animals is dramatic.

Replace the background instead of removing it

A transparent PNG is often step one. To place the subject on a solid colour (for example, a white e-commerce background), composite it:

from rembg import remove
from PIL import Image

foreground = remove(Image.open("product.jpg"))          # RGBA subject
background = Image.new("RGBA", foreground.size, (255, 255, 255, 255))
Image.alpha_composite(background, foreground).convert("RGB").save("product-white.jpg")

Swap the colour, or use another photo as the background, and you have a full compositing pipeline in a handful of lines.

A real example: a transparent profile badge

Here is an end-to-end scenario. Say you want to turn a portrait into a round, transparent "badge" — the person cut out, framed in a circle, with everything else see-through, so it looks like a floating sticker.

from rembg import remove, new_session
from PIL import Image, ImageDraw

# 1. Cut out the person with the human model + alpha matting for clean hair edges
session = new_session("u2net_human_seg")
with Image.open("me.jpg") as img:
    cut = remove(img, session=session, alpha_matting=True).convert("RGBA")

# 2. Center-crop to a square
side = min(cut.size)
left, top = (cut.width - side) // 2, (cut.height - side) // 2
square = cut.crop((left, top, left + side, top + side))

# 3. Apply a circular mask so only a disc remains
mask = Image.new("L", square.size, 0)
ImageDraw.Draw(mask).ellipse((0, 0, side, side), fill=255)
square.putalpha(mask)

square.save("badge.png")  # transparent circular badge, ready to use

That is the exact pattern behind photo-based app icons and profile badges: rembg does the heavy lifting (finding the person), and a few lines of PIL do the framing.

How it works, end to end

  1. rembg resizes your image and feeds it to the U²-Net model through ONNX Runtime.
  2. U²-Net outputs a saliency map — a grayscale guess of which pixels are the subject.
  3. rembg resizes that map back to the original dimensions and uses it as the alpha channel.
  4. Optionally, alpha matting refines the boundary between subject and background.
  5. You get an RGBA image with the background gone.

Performance and practical tips

  • CPU is fine for occasional use; expect roughly a second or a few per image depending on size and model. Install rembg[gpu] and use a CUDA setup for batches.
  • Reuse a session (new_session(...)) across many images — creating it is the slow part, so do it once.
  • Downscale huge inputs before processing if you only need a web-sized result; it is faster and the mask is usually just as good.
  • Cache lives in ~/.u2net/ — pre-download models in your Docker image so production never fetches at runtime.
  • Output must be PNG (or WebP) to keep transparency; JPG will fill the transparent area with black.

Why it matters in 2026

Local, open-source models like U²-Net have made a task that once needed a designer or a paid API into a scriptable, private, zero-cost step. That unlocks batch pipelines (thousands of product images overnight), on-device apps that never upload your photos, and creative automation like avatars and stickers. rembg is the friendly front door to that capability.

Conclusion

rembg gives you production-grade background removal in one line, and U²-Net is the salient-object model doing the real work underneath. Start with the default u2net, switch to u2net_human_seg for people, reach for alpha matting when edges matter, and composite onto a new background when you need more than a cut-out.

Merits

  • One line to remove a background; free and open source (MIT).
  • Runs offline and locally — private and cheap, no per-image API fees.
  • Multiple models for different subjects, plus alpha matting for fine edges.
  • Works as a CLI, a Python library, or an HTTP server; CPU or GPU.

Demerits

  • The first run downloads a large model (~176 MB for the default).
  • CPU processing of very large images or big batches can be slow.
  • Very fine detail (fly-away hair, transparent glass) still needs alpha matting or a heavier model like BiRefNet.
  • Accuracy drops on cluttered scenes with no single clear subject.

Caution

This article is for educational purposes. Replace the example file names and paths with your own, verify model names against the current rembg documentation before relying on them, and respect the copyright and privacy of any images you process. Model behaviour and package options can change between versions.

Frequently asked questions

  • What is rembg? — An open-source Python tool and library that removes image backgrounds using deep-learning models, primarily U²-Net.
  • What model does rembg use by default?u2net, the full U²-Net salient-object-detection model.
  • What is U²-Net? — A 2020 neural network with a nested two-level U-structure that predicts which pixels belong to the most prominent object, output as a saliency mask.
  • Is rembg free and open source? — Yes, it is MIT-licensed and free to use.
  • Do I need a GPU? — No. It runs on CPU via ONNX Runtime; a GPU only makes large batches faster.
  • How do I get cleaner edges around hair? — Enable alpha_matting=True, or use a higher-quality model such as isnet-general-use or birefnet-general.
  • Which model is best for people?u2net_human_seg, which is tuned for human figures.
  • Where are the models stored? — In ~/.u2net/, downloaded once on first use and then used offline.

Tags

#python #machine-learning #image-processing #rembg #u2net #computer-vision #deep-learning #background-removal #onnx #open-source

Free field guide

Linux Server Hardening Checklist

30 practical steps to take a fresh Linux box from default to defensible. Enter your email — you'll get the PDF instantly, plus new posts on Linux, security & AI.