Depth Estimation with Depth Anything V3

Depth Anything V3 is a monocular depth model built on the DINOv2 foundation backbone. LightlyTrain’s version is a faithful implementation of the official code.

This notebook shows both relative depth (up-to-scale) and metric depth (in meters).

Open In Colab

Important: When running on Google Colab make sure to select a GPU runtime for faster processing. You can do this by going to Runtime > Change runtime type and selecting a GPU hardware accelerator.

Installation

LightlyTrain can be installed directly via pip:

!pip install lightly-train

Important: LightlyTrain is officially supported on

  • Linux: CPU or CUDA

  • MacOS: CPU only

  • Windows (experimental): CPU or CUDA

We are planning to support MPS for MacOS.

Check the installation instructions for more details on installation.

Prediction using LightlyTrain’s model weights

Download an example image

Download an example image for inference with the following command:

!wget -O image.jpg http://images.cocodataset.org/val2017/000000039769.jpg

Relative depth estimation

Relative depth is predicted up to scale: values are consistent within an image (larger means farther) but have no absolute unit.

Load the model weights

Then load the model with LightlyTrain’s load_model function. This will automatically download the model weights and load the model.

import lightly_train

model = lightly_train.load_model("dinov2/dav3-relative-large")

Predict relative depth map

Call predict on the image to obtain the relative depth map.

depth = model.predict(
    "image.jpg"
)  # Depth map as a tensor of shape (H, W). Larger values mean farther from the camera.

Visualize the results

Finally, we visualize the input image alongside the predicted depth map.

import matplotlib.pyplot as plt
from PIL import Image

image = Image.open("image.jpg")

fig, axes = plt.subplots(1, 2, figsize=(14, 6))
axes[0].imshow(image)
axes[0].set_title("Input")
axes[0].axis("off")
depth_vis = axes[1].imshow(depth.cpu(), cmap="Spectral_r")
axes[1].set_title("Relative depth (larger = farther)")
axes[1].axis("off")
fig.colorbar(depth_vis, ax=axes[1], fraction=0.046, pad=0.04)
plt.show()

Metric depth estimation

The metric model predicts depth in meters and needs the camera intrinsics as a (3, 3) matrix [[fx, 0, cx], [0, fy, cy], [0, 0, 1]]. If you don’t know them, approximate from an assumed field of view - the metric scale is only as accurate as that guess.

Load the model weights

Then load the model with LightlyTrain’s load_model function. This will automatically download the model weights and load the model.

metric_model = lightly_train.load_model("dinov2/dav3-metric-large")

Predict metric depth map

Pass the intrinsics to predict to obtain depth in meters.

import math

import torch

# Approximate intrinsics from an assumed 60° horizontal field of view.
width, height = image.size
focal_px = (width / 2) / math.tan(math.radians(60.0) / 2)
intrinsics = torch.tensor(
    [
        [focal_px, 0.0, width / 2],
        [0.0, focal_px, height / 2],
        [0.0, 0.0, 1.0],
    ]
)

depth_m = metric_model.predict("image.jpg", intrinsics=intrinsics)
print(f"depth range: {depth_m.min():.2f} m – {depth_m.max():.2f} m")

Visualize the results

Finally, we visualize the input image alongside the predicted metric depth map.

fig, axes = plt.subplots(1, 2, figsize=(14, 6))
axes[0].imshow(image)
axes[0].set_title("Input")
axes[0].axis("off")
depth_vis = axes[1].imshow(depth_m.cpu(), cmap="Spectral_r")
axes[1].set_title("Metric depth [m]")
axes[1].axis("off")
fig.colorbar(depth_vis, ax=axes[1], fraction=0.046, pad=0.04, label="meters")
plt.show()

Next Steps