Skip to content

Commit 725ac5b

Browse files
Merge pull request #11 from OlafenwaMoses/moses/stereo-depth-camera-config-input
DepthEstimation advanced config for improved results + Stereo depth estimation
2 parents fc31a70 + 1f669e2 commit 725ac5b

54 files changed

Lines changed: 6149 additions & 383 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ on:
55
branches: [main]
66
pull_request:
77

8+
permissions:
9+
contents: read
10+
811
# Cancel in-progress runs for the same branch on new pushes.
912
# Never cancel runs on main (every merge must be fully tested).
1013
concurrency:
@@ -78,11 +81,25 @@ jobs:
7881
uses: actions/cache@v4
7982
with:
8083
path: ${{ env.VIZION3D_MODEL_CACHE }}
81-
# Key is tied to the model filename — bump if the model changes
82-
key: depth-anything-v2-vitb-pth
84+
# Key is tied to the model filenames — bump if either model changes
85+
key: depth-anything-v2-vitb-stereo-depth-s2m2-l-pth
86+
87+
- name: Show integration timing limits
88+
env:
89+
VIZION3D_TEST_DEPTH_COLD_LIMIT: ${{ vars.VIZION3D_TEST_DEPTH_COLD_LIMIT || vars.VIZION3D_TEST_COLD_LIMIT || '10' }}
90+
VIZION3D_TEST_DEPTH_WARM_LIMIT: ${{ vars.VIZION3D_TEST_DEPTH_WARM_LIMIT || vars.VIZION3D_TEST_WARM_LIMIT || '1' }}
91+
VIZION3D_TEST_STEREO_COLD_LIMIT: ${{ vars.VIZION3D_TEST_STEREO_COLD_LIMIT || '60' }}
92+
VIZION3D_TEST_STEREO_WARM_LIMIT: ${{ vars.VIZION3D_TEST_STEREO_WARM_LIMIT || '5' }}
93+
run: |
94+
echo "VIZION3D_TEST_DEPTH_COLD_LIMIT=$VIZION3D_TEST_DEPTH_COLD_LIMIT"
95+
echo "VIZION3D_TEST_DEPTH_WARM_LIMIT=$VIZION3D_TEST_DEPTH_WARM_LIMIT"
96+
echo "VIZION3D_TEST_STEREO_COLD_LIMIT=$VIZION3D_TEST_STEREO_COLD_LIMIT"
97+
echo "VIZION3D_TEST_STEREO_WARM_LIMIT=$VIZION3D_TEST_STEREO_WARM_LIMIT"
8398
8499
- name: Run integration tests
85100
env:
86-
VIZION3D_TEST_COLD_LIMIT: ${{ vars.VIZION3D_TEST_COLD_LIMIT }}
87-
VIZION3D_TEST_WARM_LIMIT: ${{ vars.VIZION3D_TEST_WARM_LIMIT }}
101+
VIZION3D_TEST_DEPTH_COLD_LIMIT: ${{ vars.VIZION3D_TEST_DEPTH_COLD_LIMIT || vars.VIZION3D_TEST_COLD_LIMIT || '10' }}
102+
VIZION3D_TEST_DEPTH_WARM_LIMIT: ${{ vars.VIZION3D_TEST_DEPTH_WARM_LIMIT || vars.VIZION3D_TEST_WARM_LIMIT || '1' }}
103+
VIZION3D_TEST_STEREO_COLD_LIMIT: ${{ vars.VIZION3D_TEST_STEREO_COLD_LIMIT || '60' }}
104+
VIZION3D_TEST_STEREO_WARM_LIMIT: ${{ vars.VIZION3D_TEST_STEREO_WARM_LIMIT || '5' }}
88105
run: uv run pytest tests/integration/ -v

.github/workflows/enforce-release-branch.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ on:
55
branches:
66
- release
77

8+
permissions:
9+
contents: read
10+
811
jobs:
912
check-source:
1013
name: Source branch check

.github/workflows/publish.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ on:
66
workflow_dispatch:
77
inputs:
88
version:
9+
10+
permissions:
11+
contents: read
912
description: "Release version (e.g. 1.2.0)"
1013
required: true
1114
type: string

docs/api/lifting.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ Input contract for the depth estimation task. All inference parameters are decla
2020

2121
---
2222

23+
## DepthEstimationAdvanceConfig
24+
25+
Camera intrinsics and depth range settings. Pass an instance of this model as `advanced_config` on `DepthEstimationCommand` to override the PrimeSense defaults used for point cloud unprojection.
26+
27+
::: vizion3d.lifting.models.DepthEstimationAdvanceConfig
28+
29+
---
30+
2331
## DepthEstimationResult
2432

2533
Output contract returned by `DepthEstimation.run()`. All fields are always present; optional geometry fields are `None` when the corresponding `return_*` flag was not set.

docs/features/depth_estimation.md

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@ Depth estimation predicts the per-pixel distance from the camera for every pixel
99

1010
## Model backends
1111

12+
Default checkpoint download:
13+
[depth_anything_v2_vitb.pth](https://github.com/OlafenwaMoses/vizion3D/releases/download/essentials-v1/depth_anything_v2_vitb.pth)
14+
15+
```bash
16+
curl -L \
17+
https://github.com/OlafenwaMoses/vizion3D/releases/download/essentials-v1/depth_anything_v2_vitb.pth \
18+
-o depth_anything_v2_vitb.pth
19+
```
20+
1221
| Value | What happens |
1322
|---|---|
1423
| *(default)* | Downloads the vizion3D release checkpoint (`depth_anything_v2_vitb.pth`) to `~/.cache/vizion3d/models/` on first use, then loads it directly |
@@ -32,6 +41,7 @@ Set `VIZION3D_MODEL_CACHE` in your environment to change the default cache direc
3241
| `return_depth_image` | `bool` | No | `False` | If `True`, the result includes a 16-bit grayscale Open3D Image of the depth map. |
3342
| `return_point_cloud` | `bool` | No | `False` | If `True`, the result includes an Open3D PointCloud unprojected from the RGB-D image. |
3443
| `return_mesh` | `bool` | No | `False` | If `True`, the result includes an Open3D TriangleMesh reconstructed from the point cloud via ball-pivoting. |
44+
| `advanced_config` | `DepthEstimationAdvanceConfig` | No | PrimeSense defaults | Camera intrinsics and depth range settings. See [Advanced config](#10-advanced-config-camera-intrinsics-depth-range) below. |
3545

3646
---
3747

@@ -46,7 +56,7 @@ Set `VIZION3D_MODEL_CACHE` in your environment to change the default cache direc
4656
| `max_depth` | `float` | Yes | Maximum value in `depth_map`. Guaranteed `max_depth >= min_depth`. |
4757
| `backend_used` | `str` | Yes | Resolved model identifier that processed the request (local file path). |
4858
| `depth_image` | `open3d.geometry.Image \| None` | When `return_depth_image=True` | 16-bit grayscale image, dtype `uint16`, shape `(H, W)`. The full 0–65535 range maps to `[min_depth, max_depth]`. |
49-
| `point_cloud` | `open3d.geometry.PointCloud \| None` | When `return_point_cloud=True` | Coloured 3D point cloud unprojected from the RGB-D image using PrimeSense default intrinsics. Coordinates are in metres. |
59+
| `point_cloud` | `open3d.geometry.PointCloud \| None` | When `return_point_cloud=True` | Coloured 3D point cloud unprojected from the RGB-D image using the intrinsics in `advanced_config`. Coordinates are in metres. |
5060
| `mesh` | `open3d.geometry.TriangleMesh \| None` | When `return_mesh=True` | Triangle mesh surface reconstructed from the point cloud via ball-pivoting. Includes vertex colours. |
5161
| `point_cloud_scale` | `float` | Yes | Scale factor: multiply any distance measured between two points in the point cloud by this value to get the equivalent distance in metres. Always `1.0` — Open3D produces point cloud coordinates directly in metres. |
5262

@@ -219,7 +229,10 @@ print(f"Backend: {result.backend_used}")
219229
# Remote checkpoint URL (downloaded and cached on first use)
220230
cmd = DepthEstimationCommand(
221231
image_input="scene.png",
222-
model_backend="https://example.com/weights/depth_anything_v2_vits.pth",
232+
model_backend=(
233+
"https://github.com/OlafenwaMoses/vizion3D/releases/download/"
234+
"essentials-v1/depth_anything_v2_vitb.pth"
235+
),
223236
)
224237
result = DepthEstimation().run(cmd)
225238
print(f"Backend: {result.backend_used}")
@@ -229,7 +242,7 @@ print(f"Backend: {result.backend_used}")
229242

230243
## 8. REST API
231244

232-
Start the server:
245+
Start the server with all REST features enabled:
233246

234247
**pip / Poetry**
235248
```bash
@@ -241,6 +254,31 @@ vizion3d-serve-rest
241254
uv run vizion3d-serve-rest
242255
```
243256

257+
To preload a depth-estimation checkpoint into memory at startup, pass
258+
`--depth_model`. This also enables the depth-estimation endpoint. If this flag
259+
is omitted, the default vizion3D release model is downloaded on first inference
260+
and cached under `~/.cache/vizion3d/models/`.
261+
262+
```bash
263+
uv run vizion3d-serve-rest --depth_model /models/depth_anything_v2_vitb.pth
264+
```
265+
266+
The REST server can also expose only selected features. If none of
267+
`--depth_estimation`, `--stereo_depth`, `--depth_model`, or `--stereo_model` is
268+
provided, all features are enabled. If any of those flags is provided, only the
269+
selected features are enabled. A model path flag selects and preloads its
270+
feature:
271+
272+
```bash
273+
# Only POST /lifting/depth-estimation
274+
uv run vizion3d-serve-rest --depth_estimation
275+
276+
# Only depth estimation, with the model loaded before the first request
277+
uv run vizion3d-serve-rest \
278+
--depth_estimation \
279+
--depth_model /models/depth_anything_v2_vitb.pth
280+
```
281+
244282
Send a request with `multipart/form-data`:
245283

246284
```bash
@@ -294,9 +332,38 @@ print(f"Backend : {response.backend_used}")
294332

295333
---
296334

335+
## 10. Advanced config: camera intrinsics & depth range
336+
337+
`DepthEstimationAdvanceConfig` lets you supply the actual camera intrinsics and depth range for your sensor, replacing the built-in PrimeSense defaults. This is required for accurate metric 3D geometry when your camera is not a 640×480 PrimeSense sensor.
338+
339+
```python
340+
from vizion3d.lifting import (
341+
DepthEstimation,
342+
DepthEstimationAdvanceConfig,
343+
DepthEstimationCommand,
344+
)
345+
346+
result = DepthEstimation().run(
347+
DepthEstimationCommand(
348+
image_input="scene.png",
349+
return_point_cloud=True,
350+
advanced_config=DepthEstimationAdvanceConfig(
351+
fx=909.15,
352+
fy=908.48,
353+
cx=640.0,
354+
cy=360.0,
355+
depth_trunc=6.0,
356+
),
357+
)
358+
)
359+
```
360+
361+
The same config is available in the REST and gRPC entry points. See [Advanced Config](depth_estimation_advanced_config.md) for the full field reference, formulas, entry-point examples, and camera presets.
362+
363+
---
364+
297365
## Known limitations
298366

299367
- **Relative depth only** — the default monocular backend produces relative (inverse) depth, not metric depth. Point cloud distances are internally consistent but not calibrated to real-world scale without a known reference distance.
300-
- **Fixed camera intrinsics** — point cloud unprojection uses `PrimeSenseDefault` (640×480) intrinsics regardless of input image resolution. For accurate metric geometry, supply real camera intrinsics.
301368
- **Ball-pivoting mesh quality** — the mesh reconstructor works best on dense, evenly sampled point clouds. Sparse or noisy clouds may produce gaps or missing faces.
302369
- **Python 3.12 required for Open3D**`return_depth_image`, `return_point_cloud`, and `return_mesh` require Open3D, which currently only supports Python 3.12 in this project.

0 commit comments

Comments
 (0)