hysts HF Staff commited on
Commit
e8dd4c2
·
1 Parent(s): 7eeaacc
Files changed (7) hide show
  1. .pre-commit-config.yaml +1 -1
  2. .python-version +1 -1
  3. README.md +2 -1
  4. app.py +124 -174
  5. pyproject.toml +19 -11
  6. requirements.txt +144 -84
  7. uv.lock +0 -0
.pre-commit-config.yaml CHANGED
@@ -14,7 +14,7 @@ repos:
14
  - id: requirements-txt-fixer
15
  - id: trailing-whitespace
16
  - repo: https://github.com/astral-sh/ruff-pre-commit
17
- rev: v0.11.10
18
  hooks:
19
  - id: ruff
20
  args: ["--fix"]
 
14
  - id: requirements-txt-fixer
15
  - id: trailing-whitespace
16
  - repo: https://github.com/astral-sh/ruff-pre-commit
17
+ rev: v0.15.4
18
  hooks:
19
  - id: ruff
20
  args: ["--fix"]
.python-version CHANGED
@@ -1 +1 @@
1
- 3.10
 
1
+ 3.12
README.md CHANGED
@@ -4,7 +4,8 @@ emoji: 📉
4
  colorFrom: indigo
5
  colorTo: blue
6
  sdk: gradio
7
- sdk_version: 5.39.0
 
8
  app_file: app.py
9
  pinned: false
10
  license: mit
 
4
  colorFrom: indigo
5
  colorTo: blue
6
  sdk: gradio
7
+ sdk_version: 6.8.0
8
+ python_version: 3.12.12
9
  app_file: app.py
10
  pinned: false
11
  license: mit
app.py CHANGED
@@ -1,6 +1,12 @@
1
- #!/usr/bin/env python
2
 
 
 
 
 
3
  import os
 
 
4
 
5
  import gradio as gr
6
  import numpy as np
@@ -8,41 +14,22 @@ import PIL.Image
8
  import spaces
9
  import torch
10
  from transformers import VitMatteForImageMatting, VitMatteImageProcessor
 
11
 
12
  DESCRIPTION = """\
13
  # [ViTMatte](https://github.com/hustvl/ViTMatte)
14
 
15
- This is a demo of [ViTMatte](https://github.com/hustvl/ViTMatte), an image matting method that uses Vision Transformers (ViT) to accurately extract the foreground from an image.
16
- It predicts a soft alpha matte to help separate the subject from the background even tricky areas like hair and fur!
17
-
18
- You've got two ways to get started:
19
-
20
- ### 🖼️ Option 1: Upload Image & Trimap
21
- - Upload your original image.
22
- - Upload a **trimap**: a helper image that labels regions as **foreground (white)**, **background (black)**, and **unknown (gray)**.
23
- - The trimap must be a **grayscale image** containing only three pixel values:
24
- - `0` for **background**
25
- - `128` for **unknown**
26
- - `255` for **foreground**
27
- - The model will use this trimap to generate the alpha matte and extract the foreground.
28
-
29
- ### ✏️ Option 2: Draw Your Own Trimap
30
- - Upload just your image.
31
- - Go to the **"Draw Trimap"** tab to start drawing masks.
32
- - Use the tools to mark:
33
- - **Foreground** (e.g. the subject),
34
- - **Unknown** (areas where the boundary is unclear).
35
- - Once you're done, click the **"Generate Trimap"** button to generate the trimap from your drawing.
36
-
37
- ### ✨ Optional: Replace Background
38
- Want to swap the background? Just check the **"Replace Background"** option and choose a new background image.
39
- The app will blend your extracted subject with the new background seamlessly!
40
-
41
 
 
 
 
42
  """
43
 
44
- device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
45
 
 
46
  MAX_IMAGE_SIZE = int(os.getenv("MAX_IMAGE_SIZE", "1500"))
47
  MODEL_ID = os.getenv("MODEL_ID", "hustvl/vitmatte-small-distinctions-646")
48
 
@@ -50,93 +37,90 @@ processor = VitMatteImageProcessor.from_pretrained(MODEL_ID)
50
  model = VitMatteForImageMatting.from_pretrained(MODEL_ID).to(device)
51
 
52
 
53
- def resize_input_image(image: PIL.Image.Image | None) -> PIL.Image.Image:
54
- if image is None:
55
- return None
56
- if max(image.size) > MAX_IMAGE_SIZE:
57
- w, h = image.size
58
- scale = MAX_IMAGE_SIZE / max(w, h)
59
- new_w = int(w * scale)
60
- new_h = int(h * scale)
61
- gr.Info(
62
- f"The uploaded image exceeded the maximum resolution limit of {MAX_IMAGE_SIZE}px. It has been resized to {new_w}x{new_h}."
63
- )
64
- return image.resize((new_w, new_h))
65
- return image
66
-
67
-
68
- def binarize_mask(mask: np.ndarray) -> np.ndarray:
69
- mask[mask > 0] = 1
70
- return mask
71
-
72
-
73
- def update_trimap(mask_editor: dict) -> np.ndarray:
74
- foreground = mask_editor["layers"][0]
75
- foreground = binarize_mask(foreground)
76
-
77
- unknown = mask_editor["layers"][1]
78
- unknown = binarize_mask(unknown)
79
-
80
- trimap = np.zeros_like(foreground)
81
- trimap[unknown > 0] = 128
82
- trimap[foreground > 0] = 255
83
- return trimap
84
-
85
-
86
- def adjust_background_image(background_image: PIL.Image.Image, target_size: tuple[int, int]) -> PIL.Image.Image:
87
- target_w, target_h = target_size
88
- bg_w, bg_h = background_image.size
89
-
90
- scale = max(target_w / bg_w, target_h / bg_h)
91
- new_bg_w = int(bg_w * scale)
92
- new_bg_h = int(bg_h * scale)
93
- background_image = background_image.resize((new_bg_w, new_bg_h))
94
- left = (new_bg_w - target_w) // 2
95
- top = (new_bg_h - target_h) // 2
96
- right = left + target_w
97
- bottom = top + target_h
98
- return background_image.crop((left, top, right, bottom))
99
-
100
-
101
- def replace_background(
102
- image: PIL.Image.Image, alpha: np.ndarray, background_image: PIL.Image.Image | None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  ) -> PIL.Image.Image | None:
104
- if background_image is None:
105
  return None
106
-
107
- if image.mode != "RGB":
108
- raise gr.Error("Image must be RGB.")
109
-
110
- background_image = background_image.convert("RGB")
111
- background_image = adjust_background_image(background_image, image.size)
112
-
113
- image = np.array(image).astype(float) / 255
114
- background_image = np.array(background_image).astype(float) / 255
115
- result = image * alpha[:, :, None] + background_image * (1 - alpha[:, :, None])
116
- return (result * 255).astype(np.uint8)
117
 
118
 
119
  @spaces.GPU
120
  @torch.inference_mode()
121
  def run(
122
- image: PIL.Image.Image,
123
- trimap: PIL.Image.Image,
124
- apply_background_replacement: bool,
125
  background_image: PIL.Image.Image | None,
126
- ) -> tuple[
127
- tuple[PIL.Image.Image, np.ndarray],
128
- tuple[PIL.Image.Image, PIL.Image.Image],
129
- tuple[PIL.Image.Image, PIL.Image.Image] | None,
130
- ]:
131
- if image.size != trimap.size:
132
- raise gr.Error("Image and trimap must have the same size.")
133
- if max(image.size) > MAX_IMAGE_SIZE:
134
- error_message = f"Image size is too large. Max image size is {MAX_IMAGE_SIZE} pixels."
135
- raise gr.Error(error_message)
136
- if image.mode != "RGB":
137
- raise gr.Error("Image must be RGB.")
138
- if trimap.mode != "L":
139
- raise gr.Error("Trimap must be grayscale.")
140
 
141
  pixel_values = processor(images=image, trimaps=trimap, return_tensors="pt").to(device).pixel_values
142
  out = model(pixel_values=pixel_values)
@@ -146,15 +130,14 @@ def run(
146
  alpha = alpha[:h, :w]
147
 
148
  foreground = np.array(image).astype(float) / 255 * alpha[:, :, None] + (1 - alpha[:, :, None])
149
- foreground = (foreground * 255).astype(np.uint8)
150
- foreground = PIL.Image.fromarray(foreground)
151
 
152
- res_bg_replacement = replace_background(image, alpha, background_image) if apply_background_replacement else None
153
 
154
  return (
155
  (image, alpha),
156
  (image, foreground),
157
- ((image, res_bg_replacement) if res_bg_replacement is not None else None),
158
  )
159
 
160
 
@@ -163,49 +146,31 @@ with gr.Blocks(css_paths="style.css") as demo:
163
 
164
  with gr.Row():
165
  with gr.Column():
 
166
  with gr.Group():
167
- image = gr.Image(label="Input image", type="pil")
168
- with gr.Tabs():
169
- with gr.Tab(label="Trimap"):
170
- trimap = gr.Image(label="Trimap", type="pil", image_mode="L")
171
- with gr.Tab(label="Draw trimap"):
172
- mask_editor = gr.ImageEditor(
173
- label="Masks",
174
- type="numpy",
175
- sources=("upload",),
176
- transforms=(),
177
- image_mode="L",
178
- height=500,
179
- brush=gr.Brush(default_color=("#00ff00", 0.6)),
180
- layers=gr.LayerOptions(
181
- allow_additional_layers=False, layers=["Foreground mask", "Unknown mask"]
182
- ),
183
- )
184
- generate_trimap_button = gr.Button("Generate trimap")
185
- apply_background_replacement = gr.Checkbox(label="Replace background", value=False)
186
- background_image = gr.Image(label="Background image", type="pil", visible=False)
187
- run_button = gr.Button("Run")
188
  with gr.Column():
189
- with gr.Group():
190
- out_alpha = gr.ImageSlider(label="Alpha")
191
- out_foreground = gr.ImageSlider(label="Foreground")
192
- out_background_replacement = gr.ImageSlider(label="Background replacement", visible=False)
193
-
194
- inputs = [
195
- image,
196
- trimap,
197
- apply_background_replacement,
198
- background_image,
199
- ]
200
- outputs = [
201
- out_alpha,
202
- out_foreground,
203
- out_background_replacement,
204
- ]
205
  gr.Examples(
206
  examples=[
207
- ["assets/retriever_rgb.png", "assets/retriever_trimap.png", False, None],
208
- ["assets/bulb_rgb.png", "assets/bulb_trimap.png", True, "assets/new_bg.jpg"],
 
 
 
 
 
 
 
 
209
  ],
210
  inputs=inputs,
211
  outputs=outputs,
@@ -213,35 +178,20 @@ with gr.Blocks(css_paths="style.css") as demo:
213
  cache_examples=False,
214
  )
215
 
216
- image.input(
217
- fn=resize_input_image,
218
- inputs=image,
219
- outputs=image,
220
- api_name=False,
221
- ).then(
222
- fn=lambda image: image,
223
- inputs=image,
224
- outputs=mask_editor,
225
- api_name=False,
226
- )
227
- generate_trimap_button.click(
228
- fn=update_trimap,
229
- inputs=mask_editor,
230
- outputs=trimap,
231
  api_name=False,
232
  )
233
- apply_background_replacement.change(
234
- fn=lambda checked: (gr.Image(visible=checked), gr.Image(visible=checked)),
235
- inputs=apply_background_replacement,
236
- outputs=[background_image, out_background_replacement],
237
  api_name=False,
238
  )
239
 
240
- run_button.click(
241
- fn=run,
242
- inputs=inputs,
243
- outputs=outputs,
244
- )
245
 
246
  if __name__ == "__main__":
247
  demo.launch()
 
1
+ """ViTMatte demo using TrimapEditor for trimap input."""
2
 
3
+ from __future__ import annotations
4
+
5
+ import base64
6
+ import json
7
  import os
8
+ from io import BytesIO
9
+ from pathlib import Path
10
 
11
  import gradio as gr
12
  import numpy as np
 
14
  import spaces
15
  import torch
16
  from transformers import VitMatteForImageMatting, VitMatteImageProcessor
17
+ from trimap_editor import TrimapEditor
18
 
19
  DESCRIPTION = """\
20
  # [ViTMatte](https://github.com/hustvl/ViTMatte)
21
 
22
+ Image matting with Vision Transformers accurately extract the foreground
23
+ from an image, even tricky areas like hair and fur!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
+ 1. **Upload** an image (or click an example below).
26
+ 2. **Draw** foreground (green) and unknown (blue) regions. Press **?** for shortcuts.
27
+ 3. Click **Run** to generate the alpha matte.
28
  """
29
 
30
+ _ASSETS_DIR = Path(__file__).parent / "assets"
31
 
32
+ device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
33
  MAX_IMAGE_SIZE = int(os.getenv("MAX_IMAGE_SIZE", "1500"))
34
  MODEL_ID = os.getenv("MODEL_ID", "hustvl/vitmatte-small-distinctions-646")
35
 
 
37
  model = VitMatteForImageMatting.from_pretrained(MODEL_ID).to(device)
38
 
39
 
40
+ def _resize_on_upload(value: str | None) -> PIL.Image.Image:
41
+ """Downscale the image on upload if it exceeds MAX_IMAGE_SIZE.
42
+
43
+ Only fires for fresh uploads (no trimapBase64 yet).
44
+ Returns gr.skip() when no resize is needed so the editor is untouched.
45
+ """
46
+ if not value:
47
+ return gr.skip()
48
+ d = json.loads(value)
49
+ if "trimapBase64" in d:
50
+ return gr.skip()
51
+ w, h = d.get("width", 0), d.get("height", 0)
52
+ if max(w, h) <= MAX_IMAGE_SIZE:
53
+ return gr.skip()
54
+ image_url = d.get("image", "")
55
+ if not image_url:
56
+ return gr.skip()
57
+ # .change() receives raw postprocess() values which still have the
58
+ # Gradio file-serving prefix (JS strips it only in commitValue()).
59
+ image_path = image_url.removeprefix("/gradio_api/file=")
60
+ image = PIL.Image.open(image_path).convert("RGB")
61
+ scale = MAX_IMAGE_SIZE / max(w, h)
62
+ new_w, new_h = int(w * scale), int(h * scale)
63
+ gr.Info(f"Image resized from {w}x{h} to {new_w}x{new_h} (max {MAX_IMAGE_SIZE}px).")
64
+ return image.resize((new_w, new_h))
65
+
66
+
67
+ def _parse_editor(value: str | None) -> tuple[PIL.Image.Image, PIL.Image.Image]:
68
+ """Extract image and trimap from TrimapEditor JSON value."""
69
+ if not value:
70
+ raise gr.Error("Upload an image and draw a trimap first.")
71
+ d = json.loads(value)
72
+
73
+ # Image
74
+ image_url = d.get("image", "")
75
+ if not image_url:
76
+ raise gr.Error("No image loaded.")
77
+ image = PIL.Image.open(image_url).convert("RGB")
78
+
79
+ # Trimap: prefer trimapBase64 (user-drawn), fall back to trimap URL (from example)
80
+ if "trimapBase64" in d:
81
+ b64 = d["trimapBase64"]
82
+ if "," in b64:
83
+ b64 = b64.split(",", 1)[1]
84
+ trimap = PIL.Image.open(BytesIO(base64.b64decode(b64))).convert("L")
85
+ elif "trimap" in d:
86
+ trimap = PIL.Image.open(d["trimap"]).convert("L")
87
+ else:
88
+ raise gr.Error("Draw a trimap first (mark foreground and unknown regions).")
89
+
90
+ return image, trimap
91
+
92
+
93
+ def _adjust_background(bg: PIL.Image.Image, target_size: tuple[int, int]) -> PIL.Image.Image:
94
+ """Crop-resize background to match target dimensions."""
95
+ tw, th = target_size
96
+ bw, bh = bg.size
97
+ scale = max(tw / bw, th / bh)
98
+ bg = bg.resize((int(bw * scale), int(bh * scale)))
99
+ left = (bg.width - tw) // 2
100
+ top = (bg.height - th) // 2
101
+ return bg.crop((left, top, left + tw, top + th))
102
+
103
+
104
+ def _replace_background(
105
+ image: PIL.Image.Image, alpha: np.ndarray, bg: PIL.Image.Image | None
106
  ) -> PIL.Image.Image | None:
107
+ if bg is None:
108
  return None
109
+ bg = _adjust_background(bg.convert("RGB"), image.size)
110
+ fg = np.array(image).astype(float) / 255
111
+ bg_arr = np.array(bg).astype(float) / 255
112
+ result = fg * alpha[:, :, None] + bg_arr * (1 - alpha[:, :, None])
113
+ return PIL.Image.fromarray((result * 255).astype(np.uint8))
 
 
 
 
 
 
114
 
115
 
116
  @spaces.GPU
117
  @torch.inference_mode()
118
  def run(
119
+ editor_value: str | None,
120
+ apply_bg: bool,
 
121
  background_image: PIL.Image.Image | None,
122
+ ) -> tuple:
123
+ image, trimap = _parse_editor(editor_value)
 
 
 
 
 
 
 
 
 
 
 
 
124
 
125
  pixel_values = processor(images=image, trimaps=trimap, return_tensors="pt").to(device).pixel_values
126
  out = model(pixel_values=pixel_values)
 
130
  alpha = alpha[:h, :w]
131
 
132
  foreground = np.array(image).astype(float) / 255 * alpha[:, :, None] + (1 - alpha[:, :, None])
133
+ foreground = PIL.Image.fromarray((foreground * 255).astype(np.uint8))
 
134
 
135
+ res_bg = _replace_background(image, alpha, background_image) if apply_bg else None
136
 
137
  return (
138
  (image, alpha),
139
  (image, foreground),
140
+ (image, res_bg) if res_bg is not None else None,
141
  )
142
 
143
 
 
146
 
147
  with gr.Row():
148
  with gr.Column():
149
+ editor = TrimapEditor(label="Image & Trimap")
150
  with gr.Group():
151
+ apply_bg = gr.Checkbox(label="Replace background", value=False)
152
+ bg_image = gr.Image(label="Background image", type="pil", visible=False)
153
+ run_btn = gr.Button("Run", variant="primary")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  with gr.Column():
155
+ out_alpha = gr.ImageSlider(label="Alpha")
156
+ out_foreground = gr.ImageSlider(label="Foreground")
157
+ out_bg = gr.ImageSlider(label="Background replacement", visible=False)
158
+
159
+ inputs = [editor, apply_bg, bg_image]
160
+ outputs = [out_alpha, out_foreground, out_bg]
161
+
 
 
 
 
 
 
 
 
 
162
  gr.Examples(
163
  examples=[
164
+ [
165
+ [str(_ASSETS_DIR / "retriever_rgb.png"), str(_ASSETS_DIR / "retriever_trimap.png")],
166
+ False,
167
+ None,
168
+ ],
169
+ [
170
+ [str(_ASSETS_DIR / "bulb_rgb.png"), str(_ASSETS_DIR / "bulb_trimap.png")],
171
+ True,
172
+ str(_ASSETS_DIR / "new_bg.jpg"),
173
+ ],
174
  ],
175
  inputs=inputs,
176
  outputs=outputs,
 
178
  cache_examples=False,
179
  )
180
 
181
+ editor.input(
182
+ fn=_resize_on_upload,
183
+ inputs=editor,
184
+ outputs=editor,
 
 
 
 
 
 
 
 
 
 
 
185
  api_name=False,
186
  )
187
+ apply_bg.change(
188
+ fn=lambda checked: (gr.Image(visible=checked), gr.ImageSlider(visible=checked)),
189
+ inputs=apply_bg,
190
+ outputs=[bg_image, out_bg],
191
  api_name=False,
192
  )
193
 
194
+ run_btn.click(fn=run, inputs=inputs, outputs=outputs)
 
 
 
 
195
 
196
  if __name__ == "__main__":
197
  demo.launch()
pyproject.toml CHANGED
@@ -1,15 +1,15 @@
1
  [project]
2
  name = "vitmatte"
3
  version = "0.1.0"
4
- description = "Add your description here"
5
  readme = "README.md"
6
- requires-python = ">=3.10"
7
  dependencies = [
8
- "gradio>=5.39.0",
9
- "hf-transfer>=0.1.9",
10
- "spaces>=0.39.0",
11
- "torch==2.5.1",
12
- "transformers>=4.54.1",
13
  ]
14
 
15
  [tool.ruff]
@@ -34,7 +34,6 @@ ignore = [
34
  "EM101", # raw-string-in-exception
35
  "FBT001", # boolean-type-hint-positional-argument
36
  "FBT002", # boolean-default-value-positional-argument
37
- "PD901", # pandas-df-variable-name
38
  "PGH003", # blanket-type-ignore
39
  "PLR0913", # too-many-arguments
40
  "PLR0915", # too-many-statements
@@ -47,8 +46,17 @@ unfixable = [
47
  [tool.ruff.lint.pydocstyle]
48
  convention = "google"
49
 
50
- [tool.ruff.lint.per-file-ignores]
51
- "*.ipynb" = ["T201", "T203"]
52
-
53
  [tool.ruff.format]
54
  docstring-code-format = true
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  [project]
2
  name = "vitmatte"
3
  version = "0.1.0"
4
+ description = "ViTMatte image matting demo with Trimap Editor"
5
  readme = "README.md"
6
+ requires-python = ">=3.12"
7
  dependencies = [
8
+ "gradio>=6.8.0",
9
+ "spaces>=0.47.0",
10
+ "torch==2.9.1",
11
+ "transformers>=5.2.0",
12
+ "trimap-editor",
13
  ]
14
 
15
  [tool.ruff]
 
34
  "EM101", # raw-string-in-exception
35
  "FBT001", # boolean-type-hint-positional-argument
36
  "FBT002", # boolean-default-value-positional-argument
 
37
  "PGH003", # blanket-type-ignore
38
  "PLR0913", # too-many-arguments
39
  "PLR0915", # too-many-statements
 
46
  [tool.ruff.lint.pydocstyle]
47
  convention = "google"
48
 
 
 
 
49
  [tool.ruff.format]
50
  docstring-code-format = true
51
+
52
+ [tool.uv.sources]
53
+ trimap-editor = { url = "https://github.com/hysts/gradio-trimap-editor/releases/download/v0.1.0/trimap_editor-0.1.0-py3-none-any.whl" }
54
+
55
+ [dependency-groups]
56
+ dev = [
57
+ "pre-commit>=4.5.1",
58
+ "ruff>=0.15.4",
59
+ ]
60
+ hf-spaces = [
61
+ "datasets>=4.6.0",
62
+ ]
requirements.txt CHANGED
@@ -1,49 +1,75 @@
1
  # This file was autogenerated by uv via the following command:
2
- # uv pip compile pyproject.toml -o requirements.txt
3
  aiofiles==24.1.0
4
  # via gradio
 
 
 
 
 
 
 
 
 
 
5
  annotated-types==0.7.0
6
  # via pydantic
7
- anyio==4.9.0
8
  # via
9
  # gradio
10
  # httpx
11
  # starlette
12
- brotli==1.1.0
 
 
13
  # via gradio
14
- certifi==2025.8.3
 
 
15
  # via
16
  # httpcore
17
  # httpx
18
  # requests
19
- charset-normalizer==3.4.2
20
  # via requests
21
- click==8.2.1
22
  # via
23
  # typer
24
  # uvicorn
25
- exceptiongroup==1.3.0
26
- # via anyio
27
- fastapi==0.116.1
 
 
 
 
 
 
 
28
  # via gradio
29
- ffmpy==0.6.1
30
  # via gradio
31
- filelock==3.18.0
32
  # via
 
33
  # huggingface-hub
34
  # torch
35
- # transformers
36
- # triton
37
- fsspec==2025.7.0
38
  # via
 
 
 
 
 
39
  # gradio-client
40
  # huggingface-hub
41
  # torch
42
- gradio==5.39.0
43
  # via
44
- # vitmatte (pyproject.toml)
45
  # spaces
46
- gradio-client==1.11.0
 
 
47
  # via gradio
48
  groovy==0.1.2
49
  # via gradio
@@ -51,36 +77,38 @@ h11==0.16.0
51
  # via
52
  # httpcore
53
  # uvicorn
54
- hf-transfer==0.1.9
55
- # via vitmatte (pyproject.toml)
56
- hf-xet==1.1.5
57
  # via huggingface-hub
58
  httpcore==1.0.9
59
  # via httpx
60
  httpx==0.28.1
61
  # via
 
62
  # gradio
63
  # gradio-client
 
64
  # safehttpx
65
  # spaces
66
- huggingface-hub==0.34.3
67
  # via
 
68
  # gradio
69
  # gradio-client
70
  # tokenizers
71
  # transformers
72
- idna==3.10
73
  # via
74
  # anyio
75
  # httpx
76
  # requests
 
77
  jinja2==3.1.6
78
  # via
79
  # gradio
80
  # torch
81
- markdown-it-py==3.0.0
82
  # via rich
83
- markupsafe==3.0.2
84
  # via
85
  # gradio
86
  # jinja2
@@ -88,66 +116,91 @@ mdurl==0.1.2
88
  # via markdown-it-py
89
  mpmath==1.3.0
90
  # via sympy
91
- networkx==3.4.2
 
 
 
 
 
 
92
  # via torch
93
- numpy==2.2.6
94
  # via
 
95
  # gradio
96
  # pandas
97
  # transformers
98
- nvidia-cublas-cu12==12.4.5.8
99
  # via
100
  # nvidia-cudnn-cu12
101
  # nvidia-cusolver-cu12
102
  # torch
103
- nvidia-cuda-cupti-cu12==12.4.127
 
 
104
  # via torch
105
- nvidia-cuda-nvrtc-cu12==12.4.127
106
  # via torch
107
- nvidia-cuda-runtime-cu12==12.4.127
108
  # via torch
109
- nvidia-cudnn-cu12==9.1.0.70
110
  # via torch
111
- nvidia-cufft-cu12==11.2.1.3
112
  # via torch
113
- nvidia-curand-cu12==10.3.5.147
114
  # via torch
115
- nvidia-cusolver-cu12==11.6.1.9
116
  # via torch
117
- nvidia-cusparse-cu12==12.3.1.170
118
  # via
119
  # nvidia-cusolver-cu12
120
  # torch
121
- nvidia-nccl-cu12==2.21.5
 
 
122
  # via torch
123
- nvidia-nvjitlink-cu12==12.4.127
124
  # via
 
125
  # nvidia-cusolver-cu12
126
  # nvidia-cusparse-cu12
127
  # torch
128
- nvidia-nvtx-cu12==12.4.127
129
  # via torch
130
- orjson==3.11.1
 
 
131
  # via gradio
132
- packaging==25.0
133
  # via
 
134
  # gradio
135
  # gradio-client
136
  # huggingface-hub
137
  # spaces
138
  # transformers
139
- pandas==2.3.1
140
- # via gradio
141
- pillow==11.3.0
142
- # via gradio
 
 
 
 
 
 
 
 
143
  psutil==5.9.8
144
  # via spaces
145
- pydantic==2.11.7
 
 
146
  # via
147
  # fastapi
148
  # gradio
149
  # spaces
150
- pydantic-core==2.33.2
151
  # via pydantic
152
  pydub==0.25.1
153
  # via gradio
@@ -155,66 +208,71 @@ pygments==2.19.2
155
  # via rich
156
  python-dateutil==2.9.0.post0
157
  # via pandas
158
- python-multipart==0.0.20
159
  # via gradio
160
  pytz==2025.2
161
- # via pandas
162
- pyyaml==6.0.2
163
  # via
 
164
  # gradio
165
  # huggingface-hub
166
  # transformers
167
- regex==2025.7.34
168
  # via transformers
169
- requests==2.32.4
170
  # via
171
- # huggingface-hub
172
  # spaces
173
- # transformers
174
- rich==14.1.0
175
  # via typer
176
- ruff==0.12.7
177
- # via gradio
178
- safehttpx==0.1.6
179
  # via gradio
180
- safetensors==0.5.3
181
  # via transformers
182
  semantic-version==2.10.0
183
  # via gradio
 
 
184
  shellingham==1.5.4
185
  # via typer
186
  six==1.17.0
187
  # via python-dateutil
188
- sniffio==1.3.1
189
- # via anyio
190
- spaces==0.39.0
191
- # via vitmatte (pyproject.toml)
192
- starlette==0.47.2
193
  # via
194
  # fastapi
195
  # gradio
196
- sympy==1.13.1
197
  # via torch
198
- tokenizers==0.21.4
199
  # via transformers
200
  tomlkit==0.13.3
201
  # via gradio
202
- torch==2.5.1
203
- # via vitmatte (pyproject.toml)
204
- tqdm==4.67.1
205
  # via
 
206
  # huggingface-hub
207
  # transformers
208
- transformers==4.54.1
209
- # via vitmatte (pyproject.toml)
210
- triton==3.1.0
 
 
211
  # via torch
212
- typer==0.16.0
213
- # via gradio
214
- typing-extensions==4.14.1
215
  # via
 
 
 
 
 
 
216
  # anyio
217
- # exceptiongroup
218
  # fastapi
219
  # gradio
220
  # gradio-client
@@ -224,16 +282,18 @@ typing-extensions==4.14.1
224
  # spaces
225
  # starlette
226
  # torch
227
- # typer
228
  # typing-inspection
229
- # uvicorn
230
- typing-inspection==0.4.1
231
- # via pydantic
232
- tzdata==2025.2
 
233
  # via pandas
234
- urllib3==2.5.0
235
  # via requests
236
- uvicorn==0.35.0
237
  # via gradio
238
- websockets==15.0.1
239
- # via gradio-client
 
 
 
1
  # This file was autogenerated by uv via the following command:
2
+ # uv export --no-hashes --group hf-spaces --no-emit-package typer-slim -o requirements.txt
3
  aiofiles==24.1.0
4
  # via gradio
5
+ aiohappyeyeballs==2.6.1
6
+ # via aiohttp
7
+ aiohttp==3.13.3
8
+ # via fsspec
9
+ aiosignal==1.4.0
10
+ # via aiohttp
11
+ annotated-doc==0.0.4
12
+ # via
13
+ # fastapi
14
+ # typer
15
  annotated-types==0.7.0
16
  # via pydantic
17
+ anyio==4.12.1
18
  # via
19
  # gradio
20
  # httpx
21
  # starlette
22
+ attrs==25.4.0
23
+ # via aiohttp
24
+ audioop-lts==0.2.2 ; python_full_version >= '3.13'
25
  # via gradio
26
+ brotli==1.2.0
27
+ # via gradio
28
+ certifi==2026.2.25
29
  # via
30
  # httpcore
31
  # httpx
32
  # requests
33
+ charset-normalizer==3.4.4
34
  # via requests
35
+ click==8.3.1
36
  # via
37
  # typer
38
  # uvicorn
39
+ colorama==0.4.6 ; sys_platform == 'win32'
40
+ # via
41
+ # click
42
+ # tqdm
43
+ datasets==4.6.1
44
+ dill==0.4.0
45
+ # via
46
+ # datasets
47
+ # multiprocess
48
+ fastapi==0.134.0
49
  # via gradio
50
+ ffmpy==1.0.0
51
  # via gradio
52
+ filelock==3.24.3
53
  # via
54
+ # datasets
55
  # huggingface-hub
56
  # torch
57
+ frozenlist==1.8.0
 
 
58
  # via
59
+ # aiohttp
60
+ # aiosignal
61
+ fsspec==2026.2.0
62
+ # via
63
+ # datasets
64
  # gradio-client
65
  # huggingface-hub
66
  # torch
67
+ gradio==6.8.0
68
  # via
 
69
  # spaces
70
+ # trimap-editor
71
+ # vitmatte
72
+ gradio-client==2.2.0
73
  # via gradio
74
  groovy==0.1.2
75
  # via gradio
 
77
  # via
78
  # httpcore
79
  # uvicorn
80
+ hf-xet==1.3.2 ; platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'
 
 
81
  # via huggingface-hub
82
  httpcore==1.0.9
83
  # via httpx
84
  httpx==0.28.1
85
  # via
86
+ # datasets
87
  # gradio
88
  # gradio-client
89
+ # huggingface-hub
90
  # safehttpx
91
  # spaces
92
+ huggingface-hub==1.5.0
93
  # via
94
+ # datasets
95
  # gradio
96
  # gradio-client
97
  # tokenizers
98
  # transformers
99
+ idna==3.11
100
  # via
101
  # anyio
102
  # httpx
103
  # requests
104
+ # yarl
105
  jinja2==3.1.6
106
  # via
107
  # gradio
108
  # torch
109
+ markdown-it-py==4.0.0
110
  # via rich
111
+ markupsafe==3.0.3
112
  # via
113
  # gradio
114
  # jinja2
 
116
  # via markdown-it-py
117
  mpmath==1.3.0
118
  # via sympy
119
+ multidict==6.7.1
120
+ # via
121
+ # aiohttp
122
+ # yarl
123
+ multiprocess==0.70.18
124
+ # via datasets
125
+ networkx==3.6.1
126
  # via torch
127
+ numpy==2.4.2
128
  # via
129
+ # datasets
130
  # gradio
131
  # pandas
132
  # transformers
133
+ nvidia-cublas-cu12==12.8.4.1 ; platform_machine == 'x86_64' and sys_platform == 'linux'
134
  # via
135
  # nvidia-cudnn-cu12
136
  # nvidia-cusolver-cu12
137
  # torch
138
+ nvidia-cuda-cupti-cu12==12.8.90 ; platform_machine == 'x86_64' and sys_platform == 'linux'
139
+ # via torch
140
+ nvidia-cuda-nvrtc-cu12==12.8.93 ; platform_machine == 'x86_64' and sys_platform == 'linux'
141
  # via torch
142
+ nvidia-cuda-runtime-cu12==12.8.90 ; platform_machine == 'x86_64' and sys_platform == 'linux'
143
  # via torch
144
+ nvidia-cudnn-cu12==9.10.2.21 ; platform_machine == 'x86_64' and sys_platform == 'linux'
145
  # via torch
146
+ nvidia-cufft-cu12==11.3.3.83 ; platform_machine == 'x86_64' and sys_platform == 'linux'
147
  # via torch
148
+ nvidia-cufile-cu12==1.13.1.3 ; platform_machine == 'x86_64' and sys_platform == 'linux'
149
  # via torch
150
+ nvidia-curand-cu12==10.3.9.90 ; platform_machine == 'x86_64' and sys_platform == 'linux'
151
  # via torch
152
+ nvidia-cusolver-cu12==11.7.3.90 ; platform_machine == 'x86_64' and sys_platform == 'linux'
153
  # via torch
154
+ nvidia-cusparse-cu12==12.5.8.93 ; platform_machine == 'x86_64' and sys_platform == 'linux'
155
  # via
156
  # nvidia-cusolver-cu12
157
  # torch
158
+ nvidia-cusparselt-cu12==0.7.1 ; platform_machine == 'x86_64' and sys_platform == 'linux'
159
+ # via torch
160
+ nvidia-nccl-cu12==2.27.5 ; platform_machine == 'x86_64' and sys_platform == 'linux'
161
  # via torch
162
+ nvidia-nvjitlink-cu12==12.8.93 ; platform_machine == 'x86_64' and sys_platform == 'linux'
163
  # via
164
+ # nvidia-cufft-cu12
165
  # nvidia-cusolver-cu12
166
  # nvidia-cusparse-cu12
167
  # torch
168
+ nvidia-nvshmem-cu12==3.3.20 ; platform_machine == 'x86_64' and sys_platform == 'linux'
169
  # via torch
170
+ nvidia-nvtx-cu12==12.8.90 ; platform_machine == 'x86_64' and sys_platform == 'linux'
171
+ # via torch
172
+ orjson==3.11.7
173
  # via gradio
174
+ packaging==26.0
175
  # via
176
+ # datasets
177
  # gradio
178
  # gradio-client
179
  # huggingface-hub
180
  # spaces
181
  # transformers
182
+ pandas==3.0.1
183
+ # via
184
+ # datasets
185
+ # gradio
186
+ pillow==12.1.1
187
+ # via
188
+ # gradio
189
+ # trimap-editor
190
+ propcache==0.4.1
191
+ # via
192
+ # aiohttp
193
+ # yarl
194
  psutil==5.9.8
195
  # via spaces
196
+ pyarrow==23.0.1
197
+ # via datasets
198
+ pydantic==2.12.5
199
  # via
200
  # fastapi
201
  # gradio
202
  # spaces
203
+ pydantic-core==2.41.5
204
  # via pydantic
205
  pydub==0.25.1
206
  # via gradio
 
208
  # via rich
209
  python-dateutil==2.9.0.post0
210
  # via pandas
211
+ python-multipart==0.0.22
212
  # via gradio
213
  pytz==2025.2
214
+ # via gradio
215
+ pyyaml==6.0.3
216
  # via
217
+ # datasets
218
  # gradio
219
  # huggingface-hub
220
  # transformers
221
+ regex==2026.2.28
222
  # via transformers
223
+ requests==2.32.5
224
  # via
225
+ # datasets
226
  # spaces
227
+ rich==14.3.3
 
228
  # via typer
229
+ ruff==0.15.4
230
+ safehttpx==0.1.7
 
231
  # via gradio
232
+ safetensors==0.7.0
233
  # via transformers
234
  semantic-version==2.10.0
235
  # via gradio
236
+ setuptools==82.0.0
237
+ # via torch
238
  shellingham==1.5.4
239
  # via typer
240
  six==1.17.0
241
  # via python-dateutil
242
+ spaces==0.47.0
243
+ # via vitmatte
244
+ starlette==0.52.1
 
 
245
  # via
246
  # fastapi
247
  # gradio
248
+ sympy==1.14.0
249
  # via torch
250
+ tokenizers==0.22.2
251
  # via transformers
252
  tomlkit==0.13.3
253
  # via gradio
254
+ torch==2.9.1
255
+ # via vitmatte
256
+ tqdm==4.67.3
257
  # via
258
+ # datasets
259
  # huggingface-hub
260
  # transformers
261
+ transformers==5.2.0
262
+ # via vitmatte
263
+ trimap-editor @ https://github.com/hysts/gradio-trimap-editor/releases/download/v0.1.0/trimap_editor-0.1.0-py3-none-any.whl
264
+ # via vitmatte
265
+ triton==3.5.1 ; platform_machine == 'x86_64' and sys_platform == 'linux'
266
  # via torch
267
+ typer==0.24.1
 
 
268
  # via
269
+ # gradio
270
+ # huggingface-hub
271
+ # typer-slim
272
+ typing-extensions==4.15.0
273
+ # via
274
+ # aiosignal
275
  # anyio
 
276
  # fastapi
277
  # gradio
278
  # gradio-client
 
282
  # spaces
283
  # starlette
284
  # torch
 
285
  # typing-inspection
286
+ typing-inspection==0.4.2
287
+ # via
288
+ # fastapi
289
+ # pydantic
290
+ tzdata==2025.3 ; sys_platform == 'emscripten' or sys_platform == 'win32'
291
  # via pandas
292
+ urllib3==2.6.3
293
  # via requests
294
+ uvicorn==0.41.0
295
  # via gradio
296
+ xxhash==3.6.0
297
+ # via datasets
298
+ yarl==1.22.0
299
+ # via aiohttp
uv.lock CHANGED
The diff for this file is too large to render. See raw diff