Dhanrajtz5rt commited on
Commit
f8ef94b
·
verified ·
1 Parent(s): 5712772

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -292
app.py CHANGED
@@ -1,300 +1,48 @@
1
- """
2
- Background Remover Tool
3
- ========================
4
- A fully open-source background removal app powered by rembg + Gradio.
5
- Runs on CPU. Ready for HuggingFace Spaces deployment.
6
-
7
- Supported models:
8
- - u2net → General purpose (best overall quality)
9
- - u2netp → Lightweight/fast (lower RAM usage)
10
- - u2net_human_seg → Optimised for people / portraits
11
- - isnet-general-use → High-resolution dichotomous segmentation
12
- - birefnet-general → State-of-the-art bilateral-reference net
13
- """
14
-
15
- import os
16
- import io
17
- import time
18
- import numpy as np
19
  import gradio as gr
20
- from PIL import Image, ImageColor
21
- from rembg import remove, new_session
22
-
23
- # ─────────────────────────────────────────────
24
- # Model registry
25
- # ─────────────────────────────────────────────
26
- MODELS = {
27
- "u2net (General – best quality)": "u2net",
28
- "u2netp (Lightweight – fastest)": "u2netp",
29
- "u2net_human_seg (People / Portraits)": "u2net_human_seg",
30
- "isnet-general-use (High-res objects)": "isnet-general-use",
31
- "birefnet-general (State-of-the-art)": "birefnet-general",
32
- }
33
-
34
- # Cache sessions so we don't reload the model on every call
35
- _session_cache: dict = {}
36
-
37
- def get_session(model_key: str):
38
- model_name = MODELS[model_key]
39
- if model_name not in _session_cache:
40
- _session_cache[model_name] = new_session(model_name)
41
- return _session_cache[model_name]
42
-
43
-
44
- # ─────────────────────────────────────────────
45
- # Core processing
46
- # ─────────────────────────────────────────────
47
- def remove_background(
48
- input_image: Image.Image,
49
- model_key: str,
50
- bg_mode: str,
51
- bg_color_hex: str,
52
- bg_image: Image.Image | None,
53
- alpha_matting: bool,
54
- alpha_fg: int,
55
- alpha_bg: int,
56
- alpha_erode: int,
57
- post_process: bool,
58
- ) -> tuple[Image.Image, Image.Image, str]:
59
- """Remove the background and optionally replace it."""
60
-
61
  if input_image is None:
62
- raise gr.Error("Please upload an image first.")
63
-
64
- # Ensure RGBA input
65
- src = input_image.convert("RGBA")
66
- start = time.time()
67
-
68
- session = get_session(model_key)
69
-
70
- # Build rembg kwargs
71
- kwargs: dict = dict(
72
- session=session,
73
- alpha_matting=alpha_matting,
74
- post_process_mask=post_process,
75
  )
76
- if alpha_matting:
77
- kwargs["alpha_matting_foreground_threshold"] = alpha_fg
78
- kwargs["alpha_matting_background_threshold"] = alpha_bg
79
- kwargs["alpha_matting_erode_size"] = alpha_erode
80
-
81
- result: Image.Image = remove(src, **kwargs) # RGBA, transparent BG
82
-
83
- elapsed = time.time() - start
84
-
85
- # ── Compose background ────────────────────
86
- if bg_mode == "Transparent (PNG)":
87
- final = result
88
- elif bg_mode == "Solid colour":
89
- try:
90
- colour = ImageColor.getrgb(bg_color_hex)
91
- except ValueError:
92
- colour = (255, 255, 255)
93
- bg = Image.new("RGBA", result.size, colour + (255,))
94
- bg.paste(result, mask=result.split()[3])
95
- final = bg.convert("RGB")
96
- elif bg_mode == "Custom image" and bg_image is not None:
97
- bg = bg_image.convert("RGBA").resize(result.size, Image.LANCZOS)
98
- bg.paste(result, mask=result.split()[3])
99
- final = bg.convert("RGB")
100
- else:
101
- # fallback: white
102
- bg = Image.new("RGBA", result.size, (255, 255, 255, 255))
103
- bg.paste(result, mask=result.split()[3])
104
- final = bg.convert("RGB")
105
-
106
- # ── Alpha mask preview ────────────────────
107
- mask_preview = result.split()[3].convert("RGB")
108
-
109
- status = (
110
- f"✅ Done in {elapsed:.2f}s | "
111
- f"Model: {MODELS[model_key]} | "
112
- f"Size: {input_image.width}×{input_image.height}px"
113
- )
114
- return result, final, mask_preview, status
115
-
116
-
117
- # ─────────────────────────────────────────────
118
- # UI helpers
119
- # ─────────────────────────────────────────────
120
- DESCRIPTION = """
121
- # 🖼️ AI Background Remover
122
- **Remove backgrounds instantly — 100 % open-source, runs on CPU.**
123
-
124
- Choose a model, upload your photo, and hit **Remove Background**.
125
- You can replace the background with a solid colour, a custom image, or keep it transparent.
126
- """
127
-
128
- TIPS = """
129
- ### 💡 Tips
130
- - **u2net** gives the best overall results for mixed content.
131
- - **u2net_human_seg** is optimised for portraits & selfies.
132
- - **birefnet-general** is the most accurate but slowest on CPU.
133
- - Enable **Alpha matting** for fine hair / fur details.
134
- - Download the transparent PNG to use in design tools.
135
- """
136
-
137
-
138
- # ─────────────────────────────────────────────
139
- # Gradio Blocks UI
140
- # ─────────────────────────────────────────────
141
- with gr.Blocks(
142
- title="AI Background Remover",
143
- theme=gr.themes.Soft(
144
- primary_hue=gr.themes.colors.violet,
145
- secondary_hue=gr.themes.colors.blue,
146
- neutral_hue=gr.themes.colors.slate,
147
- font=[gr.themes.GoogleFont("Inter"), "ui-sans-serif", "system-ui"],
148
- ),
149
- css="""
150
- #header { text-align: center; padding: 8px 0 4px 0; }
151
- #status_box { font-size: 0.9rem; color: #555; }
152
- .gr-image { border-radius: 12px; }
153
- footer { display: none !important; }
154
- """,
155
- ) as demo:
156
-
157
- gr.Markdown(DESCRIPTION, elem_id="header")
158
-
159
  with gr.Row():
160
- # ── LEFT: inputs ─────────────────────
161
- with gr.Column(scale=1):
162
- gr.Markdown("### 📤 Input")
163
- input_img = gr.Image(
164
- label="Upload Image",
165
- type="pil",
166
- height=340,
167
- sources=["upload", "clipboard"],
168
- )
169
-
170
- model_dd = gr.Dropdown(
171
- label="🤖 Model",
172
- choices=list(MODELS.keys()),
173
- value=list(MODELS.keys())[0],
174
- info="Different models suit different subjects.",
175
- )
176
-
177
- bg_mode_radio = gr.Radio(
178
- label="🎨 Background Mode",
179
- choices=["Transparent (PNG)", "Solid colour", "Custom image"],
180
- value="Transparent (PNG)",
181
- )
182
-
183
- with gr.Group(visible=False) as colour_group:
184
- bg_color = gr.ColorPicker(label="Colour", value="#ffffff")
185
-
186
- with gr.Group(visible=False) as image_group:
187
- bg_img = gr.Image(
188
- label="Background Image",
189
- type="pil",
190
- height=180,
191
- )
192
-
193
- with gr.Accordion("⚙️ Advanced Options", open=False):
194
- alpha_chk = gr.Checkbox(
195
- label="Alpha Matting (better edges for hair/fur)",
196
- value=False,
197
- )
198
- with gr.Group(visible=False) as alpha_group:
199
- alpha_fg_sl = gr.Slider(1, 255, value=240, step=1,
200
- label="Foreground Threshold")
201
- alpha_bg_sl = gr.Slider(1, 255, value=10, step=1,
202
- label="Background Threshold")
203
- alpha_er_sl = gr.Slider(0, 40, value=10, step=1,
204
- label="Erode Size")
205
- post_chk = gr.Checkbox(
206
- label="Post-process mask (smoother edges)",
207
- value=False,
208
- )
209
-
210
- run_btn = gr.Button("✂️ Remove Background", variant="primary", size="lg")
211
-
212
- # ── RIGHT: outputs ────────────────────
213
- with gr.Column(scale=1):
214
- gr.Markdown("### 📥 Output")
215
- with gr.Tabs():
216
- with gr.Tab("Result (transparent)"):
217
- out_transparent = gr.Image(
218
- label="Transparent PNG",
219
- type="pil",
220
- height=280,
221
- format="png",
222
- show_download_button=True,
223
- )
224
- with gr.Tab("Result (with background)"):
225
- out_composed = gr.Image(
226
- label="Composed Result",
227
- type="pil",
228
- height=280,
229
- show_download_button=True,
230
- )
231
- with gr.Tab("Mask preview"):
232
- out_mask = gr.Image(
233
- label="Alpha Mask",
234
- type="pil",
235
- height=280,
236
- )
237
-
238
- status_box = gr.Textbox(
239
- label="",
240
- interactive=False,
241
- elem_id="status_box",
242
- placeholder="Status will appear here after processing…",
243
- )
244
-
245
- gr.Markdown(TIPS)
246
-
247
- # ── Example images ─────────────────────
248
- gr.Examples(
249
- examples=[
250
- ["examples/portrait.jpg", list(MODELS.keys())[2], "Transparent (PNG)", "#ffffff", None, False, 240, 10, 10, False],
251
- ["examples/product.jpg", list(MODELS.keys())[0], "Solid colour", "#f0f0f0", None, False, 240, 10, 10, False],
252
- ["examples/landscape.jpg", list(MODELS.keys())[3], "Transparent (PNG)", "#ffffff", None, True, 240, 10, 10, True],
253
- ],
254
- inputs=[
255
- input_img, model_dd, bg_mode_radio, bg_color, bg_img,
256
- alpha_chk, alpha_fg_sl, alpha_bg_sl, alpha_er_sl, post_chk,
257
- ],
258
- label="📷 Example Images (click to try)",
259
- cache_examples=False,
260
- )
261
-
262
- # ── Wiring ─────────────────────────────
263
- def toggle_bg_mode(mode):
264
- return (
265
- gr.update(visible=mode == "Solid colour"),
266
- gr.update(visible=mode == "Custom image"),
267
- )
268
-
269
- bg_mode_radio.change(
270
- toggle_bg_mode,
271
- inputs=bg_mode_radio,
272
- outputs=[colour_group, image_group],
273
- )
274
-
275
- alpha_chk.change(
276
- lambda v: gr.update(visible=v),
277
- inputs=alpha_chk,
278
- outputs=alpha_group,
279
- )
280
-
281
- run_btn.click(
282
  fn=remove_background,
283
- inputs=[
284
- input_img, model_dd, bg_mode_radio, bg_color, bg_img,
285
- alpha_chk, alpha_fg_sl, alpha_bg_sl, alpha_er_sl, post_chk,
286
- ],
287
- outputs=[out_transparent, out_composed, out_mask, status_box],
288
- api_name="remove_background",
289
  )
 
 
 
290
 
291
-
292
- # ─────────────────────────────────────────────
293
- # Launch
294
- # ─────────────────────────────────────────────
295
  if __name__ == "__main__":
296
- demo.launch(
297
- server_name="0.0.0.0",
298
- server_port=7860,
299
- share=False,
300
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
+ from rembg import remove
3
+ from PIL import Image
4
+
5
+ def remove_background(input_image):
6
+ """
7
+ Takes a PIL Image, removes the background using rembg,
8
+ and returns the processed image with a transparent background.
9
+ """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  if input_image is None:
11
+ return None
12
+
13
+ # The remove() function from rembg handles the heavy lifting
14
+ output_image = remove(input_image)
15
+ return output_image
16
+
17
+ # Build the Gradio UI
18
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
19
+ gr.Markdown(
20
+ """
21
+ # ✂️ AI Background Remover
22
+ Upload any image to instantly remove its background. This tool uses the open-source `rembg` library and runs efficiently on CPU.
23
+ """
24
  )
25
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  with gr.Row():
27
+ with gr.Column():
28
+ input_img = gr.Image(type="pil", label="Original Image")
29
+ submit_btn = gr.Button("Remove Background", variant="primary")
30
+ clear_btn = gr.ClearButton(components=[input_img])
31
+
32
+ with gr.Column():
33
+ # Output format is explicitly set to png to preserve transparency
34
+ output_img = gr.Image(type="pil", label="Transparent Result", format="png")
35
+
36
+ # Connect the button to the function
37
+ submit_btn.click(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  fn=remove_background,
39
+ inputs=input_img,
40
+ outputs=output_img
 
 
 
 
41
  )
42
+
43
+ # Connect the clear button to the output as well
44
+ clear_btn.add(components=[output_img])
45
 
46
+ # Launch the app (Hugging Face Spaces automatically handles the port and server)
 
 
 
47
  if __name__ == "__main__":
48
+ demo.launch()