Depth Anything V3 in FiftyOne: From One Photo to a 3D Scene

Sep 16, 2026
7 min read
Author
Adonai Vera
Adonai Vera
Adonai Vera is a Machine Learning Engineer & DevRel at Voxel51 with over 7 years of experience building computer vision and machine learning models using TensorFlow, Docker, and OpenCV. Adonai started as a software developer, moved into AI, led teams, and served as CTO. Today, he connect code and community to build open, production-ready AI — making technology simple, accessible, and reliable. LinkedIn | GitHub
See all articles by Adonai Vera

Talk to an AI expert

FiftyOne 1.22.0 improves the support for Depth Anything V3: confidence scored depth, a sky mask, and a 3D scene you can open and rotate right inside FiftyOne, from one ordinary photo, no stereo rig or LiDAR unit required. A simple check across model sizes shows exactly where the small model gets confused, a mirror, and where the bigger model earns its extra cost, the same question a robotics or AV team has to answer before trusting a depth model on hardware they cannot swap out mid deployment.

Key takeaways

  • FiftyOne 1.22.0 adds reference view selection, pose and scale alignment, metric depth flagging, confidence and sky masks, and 3D export for Depth Anything V3.
  • A five-line near and far check tells you whether a monocular depth model has the ordering right on your own data, without eyeballing a single heatmap.
  • Depth Anything V3 small passed the check on 5 of 6 Quickstart images, and Depth Anything V3 base passed on 6 of 6, at 1.6 times the cost per image.
  • The one image both models found hard was a cat looking into a mirror, because a reflection has no real surface to measure, which is a known failure mode for monocular depth.
  • compute_3d_exports() turns a single photo into a point cloud you can open in FiftyOne's own 3D viewer, with no stereo rig and no LiDAR.

FiftyOne 1.22.0 added real support for Depth Anything V3

FiftyOne 1.22.0, released September 11, 2026, added more Depth Anything V3 features: a way to pick a reference view across multiple images, pose scale alignment, metric depth flagging, confidence and sky masks next to the depth map, and 3D export. Depth Anything is a popular model family for monocular depth, depth from a single image, no stereo pair or LiDAR needed. This release is FiftyOne building real support for a model teams already use, not a name in a changelog.

A cheap check tells you when a lightweight depth model is trustworthy

A model card reports accuracy on a benchmark you don't control. Before you trust a depth model on your own data, you need a fast way to check it's actually right. The check in this post costs five lines: pick a point you already know is close, pick a point you already know is far, and check that the model's depth agrees, across a handful of images, with no heatmap you have to eyeball.
The rest of this post is one worked example: run two Depth Anything V3 sizes on six FiftyOne Quickstart images, run that check on both, export one photo to a real 3D scene, and report what we found.

Six images, two model sizes, one selection rule

We picked six images from the FiftyOne Quickstart dataset with one rule, set before looking at any depth output: keep images where the largest ground_truth box covers 20 to 50 percent of the frame. That means a clear subject in the foreground, not a box that covers the whole photo. That gives us a near point (the center of that box) and a far point (the average of the top 10 percent of the image, usually sky or background outdoors) for each photo, with no manual labeling.
import fiftyone as fo
import fiftyone.zoo as foz

dataset = foz.load_zoo_dataset("quickstart")
model = foz.load_zoo_model("depth-anything-v3-small-torch")
dataset.apply_model(model, label_field="depth_small")
Config options like ref_view_strategy, process_res, and the 3D export settings used later in this post are documented at https://docs.voxel51.com/api/fiftyone.utils.depth_anything.html.
Six Quickstart samples in the FiftyOne App with the depth_small heatmap overlaid. Selected by one rule (largest ground truth box 20 to 50 percent of the frame), decided before looking at any depth output.

Depth Anything V3 small vs. base: speed and disk cost

Depth Anything V3 small vs. base on six FiftyOne Quickstart images, measured on CPU
Depth Anything V3 small vs. base on six FiftyOne Quickstart images, measured on CPU
ModelImagesTotal time (s)Time per image (s)Cache on disk (MB)
depth-anything-v3-small-torch621.163.53137.3
depth-anything-v3-base-torch633.585.6541.5
Measured by us, on CPU, n=6 images, single run, no warmup excluded. The base model was 1.6x slower per image and 3.9x heavier on disk than small. That's too small a sample to prove a general rule, but it's the real cost we paid on this machine.
For the near/far check: depth_small got 5 of 6 images right, depth_base got 6 of 6. Both models saw the same six images, and only one image tripped up either of them, the same one for both.

Where the small model's depth ordering breaks: a mirror

The image where depth_small got it wrong is a cat looking into a round mirror. Our near point landed inside the mirror, on the cat's own reflection, because that region was the largest box in the frame. A mirror reflection has no depth of its own, it just shows whatever is on the other side of the room. Mirrors and glass are a known weak spot for monocular depth models in general: there's no real surface at that pixel to measure. depth_small's predicted value there was close to its background estimate, so the check flagged it. depth_base got this same image right.
depth_small on the mirror photo. Two ground truth boxes are visible: one on the cat's real body in the extreme foreground, one on its reflection inside the mirror. The reflection is where the check's near point landed.
The same photo with depth_base. Both models had to deal with the same reflection; only depth_base ordered near and far the way the check expected.
On the other five images, both models agreed with the check. The clearest case was two bear cubs filling the frame against open grass, real physical near and far with nothing ambiguous in between.
depth_small on the clearest pass: near value 0.43, far value 0.91, the biggest gap of the six images.

One photo becomes a 3D scene you can open right inside FiftyOne

model.compute_3d_exports() takes the depth prediction plus the model's own estimate of the camera (where it was, and its intrinsics) and turns one photo into a point cloud in 3D space. No stereo rig and no LiDAR, just one image. It also writes a colored depth map next to the original photo, so you can sanity check the shape before going to 3D at all.
For this part we switched to a different photo than the six above: a woman writing in a notebook, with a street receding behind her. Most of our six check images are close crops that fill the frame, good for the near/far check, but they don't leave much room in the scene for a 3D shape to show. This photo has real depth range from front to back, which is what a 3D reconstruction needs to look like anything.
The colored depth map compute_3d_exports() writes automatically. Near is warm (red, orange), far is cool (blue). The woman separates clearly from the street behind her.
FiftyOne can open that 3D scene directly, it does not need a separate viewer. Wrap the exported GLB file in a FiftyOne Scene with fo.GltfMesh, write it to a .fo3d file, and any sample pointing at that file opens in FiftyOne's own 3D viewer, the same one used for LiDAR scans and other point cloud data.
import fiftyone as fo

scene = fo.Scene()
scene.add(fo.GltfMesh("scene", "scene.glb"))
scene.write("scene.fo3d")

dataset = fo.Dataset()
dataset.add_sample(fo.Sample(filepath="scene.fo3d"))
3D scenes, meshes, and point clouds in FiftyOne are covered in the getting started guide: https://docs.voxel51.com/getting_started/threed_visual_ai/01_getting_started_3d.html.
The same photo, now a point cloud, open in FiftyOne's real 3D viewer. compute_3d_exports() wrote this scene in 1.6 seconds (small model, CPU, n=1, includes reloading the model).

Building your own depth model check

The transferable part of this post is not Depth Anything V3 itself, it's the shape of the check and what it tells you when picking a model size: pick a near point and a far point you already know the answer to (a detection box, a known camera setup, a region you chose before seeing any output), and check that the model agrees, with code, across enough images that one bad case doesn't get lost.
  • Pick ground truth you already have. Detection boxes, known camera geometry, a region you picked before seeing any output. Never the model's own prediction.
  • Score with code, not your eyes. One comparison (far > near) turns a heatmap into a pass or fail count across a whole dataset.
  • Read the failing case. Ours was a mirror. Knowing which kinds of scene break a lightweight model is exactly what you need to decide whether to pay for the bigger one.
  • Depth maps are cheap; 3D export costs real setup time. Budget for that separately when you plan a rollout.

Monocular depth is how teams without a depth sensor get to 3D at all

This is not just a demo trick. A few real, common cases where a single camera is the only sensor you get:
  • Low cost robots and manipulators. A stereo rig or a LiDAR unit adds cost, weight, and power draw that many mobile robots and arms cannot spare, so the only camera on board is a single RGB one. Monocular depth is how that robot judges distance to an obstacle or a part at all, and a check like the one in this post, run on the robot's own camera and its own scenes before deployment, is how you catch a mirror, a window, or a shiny floor tripping it up before it happens on the shop floor.
  • Retail and e-commerce 3D catalogs. A "view this couch in your room" feature usually starts from one catalog photo per item, not a 3D scan. Turning that single photo into a point cloud with compute_3d_exports() is the same shape of problem as this post: no scanning rig, one image in, a rough 3D asset out, at catalog scale.
  • Real estate and insurance documentation. Listing photos and damage reports are photos, not point clouds. The same apply_model() call is the difference between a flat photo on file and something you can pull a rough distance or a 3D walkthrough out of, after the fact, with nothing re-shot.
In all three, the model never sees a benchmark, it sees whatever the robot, the product shelf, or the listing photographer actually points a camera at. That is exactly why the check in this post exists: know where your specific model breaks on your specific scenes before it is running unattended.

Try Depth Anything V3 in FiftyOne

foz.load_zoo_model("depth-anything-v3-small-torch") or "-base-torch" loads either size directly from the FiftyOne Model Zoo.
For loading your own depth data, or trying other model sources (DPT, Marigold) alongside Depth Anything, FiftyOne's getting started guide covers the broader workflow: https://docs.voxel51.com/getting_started/depth_estimation/index.html.

Frequently asked questions

Adonai Vera
Adonai Vera
Adonai Vera is a Machine Learning Engineer & DevRel at Voxel51 with over 7 years of experience building computer vision and machine learning models using TensorFlow, Docker, and OpenCV. Adonai started as a software developer, moved into AI, led teams, and served as CTO. Today, he connect code and community to build open, production-ready AI — making technology simple, accessible, and reliable.
See all articles by Adonai Vera

Talk to an AI expert

Loading related posts...