swayamshetkar commited on
Commit
f560293
·
1 Parent(s): 8754ea7

Initial commit - RMBG background remover FastAPI app

Browse files
Dockerfile ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Base image
2
+ FROM python:3.10-slim
3
+
4
+ # Set working directory
5
+ WORKDIR /app
6
+
7
+ # Copy files
8
+ COPY . .
9
+
10
+ # Install dependencies
11
+ RUN pip install --no-cache-dir -r requirements.txt
12
+
13
+ # Expose port
14
+ EXPOSE 7860
15
+
16
+ # Run FastAPI app
17
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -1,12 +1,12 @@
 
 
 
 
 
1
  ---
2
- title: Removeit
3
- emoji: 🐠
4
- colorFrom: yellow
5
- colorTo: red
6
- sdk: docker
7
- pinned: false
8
- license: mit
9
- short_description: Ai powered background remover
10
- ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
1
+ # 🧠 Background Remover (RMBG-1.4)
2
+
3
+ A FastAPI-based background-removal AI using the **BriaAI RMBG-1.4** model
4
+ (Improved U²-Net, deployed on Hugging Face Spaces).
5
+
6
  ---
 
 
 
 
 
 
 
 
 
7
 
8
+ ## 🚀 Run locally
9
+
10
+ ```bash
11
+ pip install -r requirements.txt
12
+ uvicorn app:app --reload
app.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, File, UploadFile
2
+ from fastapi.responses import StreamingResponse
3
+ from utils.rmbg_model import RMBGRemover
4
+
5
+ app = FastAPI(title="Background Remover (RMBG-1.4)")
6
+ remover = RMBGRemover()
7
+
8
+ @app.get("/")
9
+ def root():
10
+ return {"message": "RMBG-1.4 Background Remover is running 🚀"}
11
+
12
+ @app.post("/remove-bg")
13
+ async def remove_bg(file: UploadFile = File(...)):
14
+ image_bytes = await file.read()
15
+ output = remover.remove_background(image_bytes)
16
+ return StreamingResponse(output, media_type="image/png")
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ torch
2
+ torchvision
3
+ numpy
4
+ pillow
5
+ fastapi
6
+ uvicorn
7
+ python-multipart
8
+ scikit-image
9
+ transformers
utils/__init__.py ADDED
File without changes
utils/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (137 Bytes). View file
 
utils/__pycache__/rmbg_model.cpython-312.pyc ADDED
Binary file (4.36 kB). View file
 
utils/rmbg_model.py ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import numpy as np
3
+ import torch.nn.functional as F
4
+ from torchvision.transforms.functional import normalize
5
+ from transformers import AutoModelForImageSegmentation
6
+ from PIL import Image
7
+ from skimage import io
8
+ import io as sysio
9
+
10
+
11
+ class RMBGRemover:
12
+ def __init__(self):
13
+ self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
14
+ self.model = AutoModelForImageSegmentation.from_pretrained(
15
+ "briaai/RMBG-1.4", trust_remote_code=True
16
+ ).to(self.device)
17
+ self.model.eval()
18
+
19
+ def preprocess(self, im: np.ndarray, model_input_size: list) -> torch.Tensor:
20
+ if len(im.shape) < 3:
21
+ im = im[:, :, np.newaxis]
22
+ im_tensor = torch.tensor(im, dtype=torch.float32).permute(2, 0, 1)
23
+ im_tensor = F.interpolate(im_tensor.unsqueeze(0), size=model_input_size, mode="bilinear")
24
+ image = im_tensor / 255.0
25
+ image = normalize(image, [0.5, 0.5, 0.5], [1.0, 1.0, 1.0])
26
+ return image
27
+
28
+ def postprocess(self, result: torch.Tensor, im_size: list) -> np.ndarray:
29
+ result = F.interpolate(result, size=im_size, mode="bilinear").squeeze(0)
30
+ result = (result - result.min()) / (result.max() - result.min())
31
+ im_array = (result * 255).permute(1, 2, 0).cpu().numpy().astype(np.uint8)
32
+ return np.squeeze(im_array)
33
+
34
+ def remove_background(self, image_bytes: bytes) -> bytes:
35
+ im = Image.open(sysio.BytesIO(image_bytes)).convert("RGB")
36
+ np_im = np.array(im)
37
+ im_size = np_im.shape[0:2]
38
+
39
+ model_input_size = [1024, 1024]
40
+ image = self.preprocess(np_im, model_input_size).to(self.device)
41
+
42
+ with torch.no_grad():
43
+ result = self.model(image)
44
+
45
+ mask = self.postprocess(result[0][0], im_size)
46
+ pil_mask = Image.fromarray(mask)
47
+ im.putalpha(pil_mask)
48
+
49
+ out_bytes = sysio.BytesIO()
50
+ im.save(out_bytes, format="PNG")
51
+ out_bytes.seek(0)
52
+ return out_bytes