Tejaswi Tripathi commited on
Commit
cec4d26
Β·
1 Parent(s): 83aacdb

Updated README

Browse files
Files changed (1) hide show
  1. README.md +193 -1
README.md CHANGED
@@ -11,4 +11,196 @@ pinned: false
11
  short_description: An improved portrait mode renderer for pictures.
12
  ---
13
 
14
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  short_description: An improved portrait mode renderer for pictures.
12
  ---
13
 
14
+ # Physically-Based Portrait Mode Engine
15
+
16
+ A Gradio demo that simulates **shallow depth-of-field** (portrait mode) on ordinary photos. Instead of applying a flat Gaussian blur to the background, it estimates scene depth, builds a **circle-of-confusion (CoC)** map, and uses a trained neural renderer (**RendererNet**) to produce physically motivated defocus. In-focus regions are preserved by blending the render back onto the original image.
17
+
18
+ The app is designed to run as a [Hugging Face Space](https://huggingface.co/docs/hub/spaces) and is self-contained: model definitions and inference code live in a single `app.py` file.
19
+
20
+ ## What it does
21
+
22
+ Given an input photograph and camera parameters (f-stop, focal length), the pipeline:
23
+
24
+ 1. **Estimates relative depth** with [Depth Anything V2](https://huggingface.co/depth-anything/Depth-Anything-V2-Base-hf) via the Hugging Face `transformers` library.
25
+ 2. **Builds a pseudo CoC map** by measuring how far each pixel's depth deviates from the depth at the **image center** (the assumed focus point). Pixels closer to the focus depth get a CoC near zero; pixels farther away get larger CoC values.
26
+ 3. **Renders defocus with RendererNet**, a U-Net that takes the RGB image plus normalized f-stop, focal length, and CoC channels and outputs a blurred RGB image at the chosen aperture settings.
27
+ 4. **Blends the NN render onto the original** using a smooth CoC-based weight so that in-focus areas (CoC below a threshold) remain untouched.
28
+ 5. **Produces a non-NN baseline** for comparison: a flat Gaussian blur applied only where CoC exceeds a separate threshold.
29
+
30
+ Three outputs are shown:
31
+
32
+ | Output | Description |
33
+ |--------|-------------|
34
+ | **Rendered (NN)** | RendererNet defocus, blended with the original in in-focus regions |
35
+ | **Gaussian baseline** | Simple background blur for comparison against the learned renderer |
36
+ | **Pseudo CoC map** | Colorized circle-of-confusion visualization (inferno colormap) |
37
+
38
+ ## Pipeline overview
39
+
40
+ ```
41
+ Input image
42
+ β”‚
43
+ β–Ό
44
+ Resize (longest side ≀ 1024 px)
45
+ β”‚
46
+ β–Ό
47
+ Depth Anything V2 ──► relative depth [0, 1]
48
+ β”‚
49
+ β–Ό
50
+ Pseudo CoC map (focus = image center, max 4 px)
51
+ β”‚
52
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
53
+ β–Ό β–Ό
54
+ RendererNet (512Γ—512) Gaussian blur baseline
55
+ f-stop + focal length + CoC (CoC > threshold)
56
+ β”‚ β”‚
57
+ β–Ό β”‚
58
+ CoC-weighted blend β—„β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
59
+ β”‚
60
+ β–Ό
61
+ Final outputs (NN render, baseline, CoC map)
62
+ ```
63
+
64
+ ### Pseudo CoC
65
+
66
+ Because the demo has no interactive focus point, focus is fixed at the **center of the image** (`h // 2`, `w // 2`). The CoC at each pixel is proportional to the absolute difference between that pixel's relative depth and the depth at the focus point, scaled to a maximum of **4 px** (`COC_MAX_PX`).
67
+
68
+ ### RendererNet input
69
+
70
+ RendererNet is a U-Net with **6 input channels** and **3 output channels** (RGB):
71
+
72
+ | Channel(s) | Content |
73
+ |------------|---------|
74
+ | 0–2 | RGB image, resized to 512Γ—512 |
75
+ | 3 | f-stop map, normalized by `F_STOP_MAX` (22.0) |
76
+ | 4 | Focal length map, normalized by `FOCAL_LENGTH_MM_MAX` (200.0) |
77
+ | 5 | CoC map, clipped to [0, 25] px and normalized by `COC_PX_NORM` (25.0) |
78
+
79
+ The network output is resized back to the working resolution and blended with the original using a smoothstep weight derived from the CoC map and the **in-focus CoC threshold** slider.
80
+
81
+ ### Blending
82
+
83
+ The blend weight uses a smoothstep on CoC values above the focus threshold, so transitions between sharp and blurred regions are gradual rather than hard-edged. Where CoC is near zero, the original pixels are kept; where CoC is large, the RendererNet output dominates.
84
+
85
+ ## Models
86
+
87
+ ### Depth Anything V2
88
+
89
+ - **Default checkpoint:** `depth-anything/Depth-Anything-V2-Base-hf`
90
+ - Loaded at startup via `AutoImageProcessor` and `AutoModelForDepthEstimation` from `transformers`.
91
+ - Returns relative (not metric) depth, normalized per image to [0, 1].
92
+ - Requires **torch** and **torchvision**.
93
+
94
+ Swap to a different variant via the `DEPTH_MODEL_ID` environment variable:
95
+
96
+ | Model ID | Trade-off |
97
+ |----------|-----------|
98
+ | `depth-anything/Depth-Anything-V2-Small-hf` | Faster, lower quality β€” good for CPU Spaces |
99
+ | `depth-anything/Depth-Anything-V2-Base-hf` | Default; balanced speed and quality |
100
+ | `depth-anything/Depth-Anything-V2-Large-hf` | Best quality, slowest |
101
+
102
+ ### RendererNet
103
+
104
+ - A U-Net architecture (inlined in `app.py`) trained to render defocus given RGB + camera parameters + CoC.
105
+ - Weights are loaded from **`renderer/best_renderer.pth`** by default.
106
+ - Can alternatively be fetched from the Hugging Face Hub when `RENDERER_REPO_ID` is set.
107
+
108
+ ## Using the demo
109
+
110
+ 1. Upload an image (JPEG or PNG).
111
+ 2. Adjust **f-stop** (0.95–22.0) β€” lower values produce stronger background blur.
112
+ 3. Adjust **focal length** (4–200 mm) β€” longer focal lengths increase the shallow-DoF effect.
113
+ 4. Tune **in-focus CoC threshold** β€” pixels with CoC below this value suppress the NN render and keep the original sharp.
114
+ 5. Optionally expand **Gaussian baseline** to configure the comparison blur (CoC threshold and sigma).
115
+ 6. Click **Render**.
116
+
117
+ If a `cache/` directory with example images exists, sample images appear in the Examples panel.
118
+
119
+ ## Configuration
120
+
121
+ All settings below can be overridden with environment variables (useful for Hugging Face Space **Settings β†’ Repository secrets / Variables** without editing code).
122
+
123
+ | Variable | Default | Description |
124
+ |----------|---------|-------------|
125
+ | `DEPTH_MODEL_ID` | `depth-anything/Depth-Anything-V2-Base-hf` | Hugging Face model ID for depth estimation |
126
+ | `RENDERER_LOCAL_PATH` | `renderer/best_renderer.pth` | Path to RendererNet weights on disk |
127
+ | `RENDERER_REPO_ID` | *(empty)* | Hugging Face repo to download weights from |
128
+ | `RENDERER_FILENAME` | `best_renderer.pth` | Filename within the Hub repo |
129
+ | `HF_TOKEN` | *(empty)* | Token for private Hub repos (only needed with `RENDERER_REPO_ID`) |
130
+
131
+ ### Internal constants
132
+
133
+ These are fixed in code and must match RendererNet's training setup:
134
+
135
+ | Constant | Value | Purpose |
136
+ |----------|-------|---------|
137
+ | `F_STOP_MAX` | 22.0 | f-stop normalization divisor |
138
+ | `FOCAL_LENGTH_MM_MAX` | 200.0 | Focal length normalization divisor |
139
+ | `COC_PX_NORM` | 25.0 | CoC channel clip and normalize |
140
+ | `TARGET_SIZE` | 512 | RendererNet spatial resolution |
141
+ | `COC_MAX_PX` | 4.0 | Maximum pseudo CoC magnitude |
142
+ | `MAX_SIDE` | 1024 | Longest image side before inference |
143
+
144
+ ## Local development
145
+
146
+ ### Requirements
147
+
148
+ - Python 3.10+ (3.13 on Hugging Face Spaces)
149
+ - CUDA optional (falls back to CPU)
150
+
151
+ ### Install and run
152
+
153
+ ```bash
154
+ git clone https://github.com/<your-username>/Physically-Based-Portrait-Mode-Engine.git
155
+ cd Physically-Based-Portrait-Mode-Engine
156
+
157
+ pip install -r requirements.txt
158
+
159
+ # Ensure RendererNet weights are present
160
+ # (renderer/best_renderer.pth is included in the repo)
161
+
162
+ python app.py
163
+ ```
164
+
165
+ Gradio will print a local URL (typically `http://127.0.0.1:7860`).
166
+
167
+ ### Dependencies
168
+
169
+ ```
170
+ gradio>=4.44.0
171
+ torch>=2.1.0
172
+ torchvision>=0.16.0
173
+ transformers>=4.45.0
174
+ huggingface_hub>=0.24.0
175
+ numpy>=1.26.0
176
+ pillow>=10.0.0
177
+ scikit-image>=0.22.0
178
+ matplotlib>=3.7.0
179
+ ```
180
+
181
+ On first run, Depth Anything V2 weights are downloaded from the Hugging Face Hub (~370 MB for the Base model).
182
+
183
+ ## Project structure
184
+
185
+ ```
186
+ .
187
+ β”œβ”€β”€ app.py # Gradio app, RendererNet definition, full inference pipeline
188
+ β”œβ”€β”€ requirements.txt # Python dependencies
189
+ β”œβ”€β”€ renderer/
190
+ β”‚ └── best_renderer.pth # Trained RendererNet weights
191
+ └── cache/ # Optional example images for Gradio Examples
192
+ ```
193
+
194
+ ## Limitations
195
+
196
+ - **Fixed focus point:** Focus is always the image center; there is no click-to-focus or subject detection.
197
+ - **Relative depth only:** Depth Anything V2 outputs ordinal depth, not metric distances, so the CoC map is a heuristic rather than a physically exact optical simulation.
198
+ - **Resolution cap:** Images are downscaled so the longest side is at most 1024 px to keep CPU inference responsive.
199
+ - **RendererNet runs at 512Γ—512:** Fine detail may be softened; output is upsampled to the working resolution.
200
+ - **CPU Spaces are slow:** First inference after startup can take tens of seconds; consider the Small depth model or a GPU Space for faster turnaround.
201
+
202
+ ## Acknowledgments
203
+
204
+ - [Depth Anything V2](https://github.com/DepthAnything/Depth-Anything-V2) β€” monocular depth estimation ([Lihe Yang et al.](https://huggingface.co/depth-anything/Depth-Anything-V2-Base-hf))
205
+ - [Hugging Face Transformers](https://github.com/huggingface/transformers) β€” model loading and inference
206
+ - [Gradio](https://gradio.app/) β€” web UI