Spaces:
Running
on
Zero
Running
on
Zero
app.py first codeblocks
Browse files- README.md +51 -1
- app.py +122 -0
- requirements.txt +9 -0
README.md
CHANGED
|
@@ -10,4 +10,54 @@ pinned: false
|
|
| 10 |
license: mit
|
| 11 |
---
|
| 12 |
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
license: mit
|
| 11 |
---
|
| 12 |
|
| 13 |
+
# UnReflectAnything – Gradio demo
|
| 14 |
+
|
| 15 |
+
Remove specular reflections from images using the UnReflectAnything model.
|
| 16 |
+
|
| 17 |
+
## Run locally
|
| 18 |
+
|
| 19 |
+
From the **repository root** (parent of `gradio_space`):
|
| 20 |
+
|
| 21 |
+
```bash
|
| 22 |
+
# 1. Install the project and Gradio
|
| 23 |
+
pip install -e .
|
| 24 |
+
pip install "gradio>=4.0"
|
| 25 |
+
|
| 26 |
+
# 2. Download weights (once)
|
| 27 |
+
unreflect download --weights
|
| 28 |
+
|
| 29 |
+
# 3. Run the Gradio app from the repo root so Python finds the package
|
| 30 |
+
cd gradio_space && python app.py
|
| 31 |
+
```
|
| 32 |
+
|
| 33 |
+
Then open the URL shown in the terminal (e.g. http://127.0.0.1:7860).
|
| 34 |
+
|
| 35 |
+
Alternatively, from `gradio_space` only (e.g. if the repo root is one level up):
|
| 36 |
+
|
| 37 |
+
```bash
|
| 38 |
+
cd gradio_space
|
| 39 |
+
pip install -r requirements.txt # installs gradio + parent package (-e ..)
|
| 40 |
+
python app.py
|
| 41 |
+
```
|
| 42 |
+
|
| 43 |
+
Weights are downloaded automatically on first run if missing.
|
| 44 |
+
|
| 45 |
+
## Run on Hugging Face Spaces
|
| 46 |
+
|
| 47 |
+
1. Create a new Space, choose **Gradio** SDK, and set the **Root directory** to `gradio_space` (so the Space uses this folder as the app root).
|
| 48 |
+
2. Push this repo (or the `gradio_space` folder and a way to install the parent package). The Space’s `requirements.txt` will run `pip install -e ..`, so the **full repo must be in the Space** (clone the whole repo and set root to `gradio_space`).
|
| 49 |
+
3. On first run, the app will download weights to the Space cache.
|
| 50 |
+
|
| 51 |
+
**To test the live Space:** open the Space URL (e.g. `https://huggingface.co/spaces/<your-username>/<space-name>`), upload an image, optionally adjust the brightness threshold, and click **Remove reflections**.
|
| 52 |
+
|
| 53 |
+
**API / headless test:** use the “View API” link at the bottom of the Space page to get the Gradio API URL (e.g. `https://<space-name>.hf.space`), then call the `/predict` endpoint with your image, or use the Gradio client:
|
| 54 |
+
|
| 55 |
+
```bash
|
| 56 |
+
pip install gradio_client
|
| 57 |
+
python -c "
|
| 58 |
+
from gradio_client import Client
|
| 59 |
+
client = Client('https://YOUR-USER-YOUR-SPACE.hf.space')
|
| 60 |
+
result = client.predict('path/to/image.png', 0.8, api_name='/predict') # adjust api_name if needed
|
| 61 |
+
print(result)
|
| 62 |
+
"
|
| 63 |
+
```
|
app.py
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Gradio demo for UnReflectAnything: remove specular reflections from images."""
|
| 2 |
+
|
| 3 |
+
from __future__ import annotations
|
| 4 |
+
|
| 5 |
+
import sys
|
| 6 |
+
import tempfile
|
| 7 |
+
from pathlib import Path
|
| 8 |
+
|
| 9 |
+
# Allow importing unreflectanything when run from gradio_space (e.g. HF Space with root dir)
|
| 10 |
+
_REPO_ROOT = Path(__file__).resolve().parent.parent
|
| 11 |
+
if _REPO_ROOT not in sys.path:
|
| 12 |
+
sys.path.insert(0, str(_REPO_ROOT))
|
| 13 |
+
|
| 14 |
+
import gradio as gr
|
| 15 |
+
import numpy as np
|
| 16 |
+
import torch
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
def _ensure_weights():
|
| 20 |
+
"""Download weights to cache if not present."""
|
| 21 |
+
from unreflectanything import download
|
| 22 |
+
from unreflectanything._shared import DEFAULT_WEIGHTS_FILENAME, get_cache_dir
|
| 23 |
+
|
| 24 |
+
weights_dir = get_cache_dir("weights")
|
| 25 |
+
if not (weights_dir / DEFAULT_WEIGHTS_FILENAME).exists():
|
| 26 |
+
download("weights")
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def run_inference(
|
| 30 |
+
image: np.ndarray | None,
|
| 31 |
+
brightness_threshold: float,
|
| 32 |
+
) -> np.ndarray | None:
|
| 33 |
+
"""Run reflection removal on a single image. Returns RGB numpy [H,W,3] in 0–255 or None."""
|
| 34 |
+
if image is None:
|
| 35 |
+
return None
|
| 36 |
+
from unreflectanything import inference
|
| 37 |
+
|
| 38 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 39 |
+
with tempfile.TemporaryDirectory() as tmpdir:
|
| 40 |
+
inp_path = Path(tmpdir) / "input.png"
|
| 41 |
+
out_path = Path(tmpdir) / "output.png"
|
| 42 |
+
# Gradio passes RGB numpy (H, W, 3) in 0–255
|
| 43 |
+
from PIL import Image
|
| 44 |
+
|
| 45 |
+
Image.fromarray(image.astype(np.uint8)).save(inp_path)
|
| 46 |
+
try:
|
| 47 |
+
result = inference(
|
| 48 |
+
input=str(inp_path),
|
| 49 |
+
output=None,
|
| 50 |
+
device=device,
|
| 51 |
+
batch_size=1,
|
| 52 |
+
brightness_threshold=brightness_threshold,
|
| 53 |
+
resize_output=True,
|
| 54 |
+
verbose=False,
|
| 55 |
+
)
|
| 56 |
+
except FileNotFoundError as e:
|
| 57 |
+
if "Weights not found" in str(e) or "Run 'unreflect download" in str(e):
|
| 58 |
+
_ensure_weights()
|
| 59 |
+
result = inference(
|
| 60 |
+
input=str(inp_path),
|
| 61 |
+
output=None,
|
| 62 |
+
device=device,
|
| 63 |
+
batch_size=1,
|
| 64 |
+
brightness_threshold=brightness_threshold,
|
| 65 |
+
resize_output=True,
|
| 66 |
+
verbose=False,
|
| 67 |
+
)
|
| 68 |
+
else:
|
| 69 |
+
raise
|
| 70 |
+
# result: [1, 3, H, W], float 0–1
|
| 71 |
+
out = result[0].cpu().numpy().transpose(1, 2, 0)
|
| 72 |
+
out = (np.clip(out, 0.0, 1.0) * 255).astype(np.uint8)
|
| 73 |
+
return out
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
def build_ui():
|
| 77 |
+
_ensure_weights()
|
| 78 |
+
|
| 79 |
+
with gr.Blocks(
|
| 80 |
+
title="UnReflectAnything",
|
| 81 |
+
theme=gr.themes.Soft(primary_hue="green", secondary_hue="purple"),
|
| 82 |
+
) as demo:
|
| 83 |
+
gr.Markdown(
|
| 84 |
+
"""
|
| 85 |
+
# UnReflectAnything
|
| 86 |
+
Remove **specular reflections** from a single image. Upload an image and adjust the highlight threshold if needed.
|
| 87 |
+
"""
|
| 88 |
+
)
|
| 89 |
+
with gr.Row():
|
| 90 |
+
inp = gr.Image(
|
| 91 |
+
label="Input image",
|
| 92 |
+
type="numpy",
|
| 93 |
+
height=360,
|
| 94 |
+
)
|
| 95 |
+
out = gr.Image(
|
| 96 |
+
label="Reflection‑removed (diffuse)",
|
| 97 |
+
type="numpy",
|
| 98 |
+
height=360,
|
| 99 |
+
)
|
| 100 |
+
brightness = gr.Slider(
|
| 101 |
+
minimum=0.0,
|
| 102 |
+
maximum=1.0,
|
| 103 |
+
value=0.8,
|
| 104 |
+
step=0.05,
|
| 105 |
+
label="Brightness threshold (highlight detection)",
|
| 106 |
+
)
|
| 107 |
+
run_btn = gr.Button("Remove reflections", variant="primary")
|
| 108 |
+
run_btn.click(
|
| 109 |
+
fn=run_inference,
|
| 110 |
+
inputs=[inp, brightness],
|
| 111 |
+
outputs=out,
|
| 112 |
+
)
|
| 113 |
+
gr.Markdown(
|
| 114 |
+
"Weights are cached after first run. On CPU inference may be slow."
|
| 115 |
+
)
|
| 116 |
+
return demo
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
demo = build_ui()
|
| 120 |
+
|
| 121 |
+
if __name__ == "__main__":
|
| 122 |
+
demo.launch()
|
requirements.txt
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Gradio app dependencies.
|
| 2 |
+
# Install from repo root so unreflectanything and its deps are available:
|
| 3 |
+
# cd /path/to/UnReflectAnything && pip install -e .
|
| 4 |
+
# Then install Gradio (or use this file when running from gradio_space):
|
| 5 |
+
gradio>=4.0
|
| 6 |
+
|
| 7 |
+
# When running from gradio_space (e.g. Hugging Face Space with root = gradio_space),
|
| 8 |
+
# install the parent package so "unreflectanything" and root-level modules exist:
|
| 9 |
+
-e ..
|