# Toward A Better Understanding of Monocular Depth Evaluation This repository contains the source code for our paper: [Toward A Better Understanding of Monocular Depth Evaluation](https://arxiv.org/abs/2510.19814)
[Siyang Wu](https://nj-wusiyang.github.io/), Jack Nugent, Willow Yang, [Jia Deng](https://www.cs.princeton.edu/~jiadeng/) ``` @article{wu2025evaluate, title={Toward A Better Understanding of Monocular Depth Evaluation}, author={Wu, Siyang and Nugent, Jack and Yang, Willow and Deng, Jia}, journal={arXiv preprint arXiv:2510.19814}, year={2025} } ``` ## Installation Instructions Under `EvalMDE`, run: ```bash conda create -n evalmde python=3.10 -y conda activate evalmde pip install torch==2.7.0 torchvision==0.22.0 torchaudio==2.7.0 --index-url https://download.pytorch.org/whl/cu126 pip install -e . pip install bpy==4.0.0 --extra-index-url https://download.blender.org/pypi/ ``` ## Data Format ### Depth map file This repository takes depth map file in `*.npz` format, with keys: `depth, intr, valid`. + `depth`: `(H,W)`-shaped numpy array that stores depth value; + `intr`: `(4,)`-shaped numpy array that stores camera intrinsics `[fx, fy, cx, cy]`, where units are pixels; + `valid`: `(H,W)`-shaped boolean numpy array that stores whether the depth value of a pixel is valid (e.g. a pixel of `inf,nan` or extreme depth value is invalid). `sample_data/gt_depth.npz`, `sample_data/curv_low_freq__0.200_10.0.npz`, `sample_data_2/gt_depth.npz`, `sample_data_2/depthpro_gt_focal.npz` provide examples of depth map files. ### Valid triangle (Required For Textureless Relighting Visualization) In textureless relighting, we induce a textureless mesh from depth map and camera intrinsics. The mesh consists of triangle faces of vertices `(i,j), (i+1,j), (i,j+1)` and `(i+1,j+1), (i+1,j), (i,j+1)`. Triangle faces across occlusion boundaries should be excluded. `valid_triangle.npz` specifies which triangles are included (`True`) and which are not (`False`). It has keys: `valid_triangle`, which is a `(H-1,W-1,2)` shaped boolean numpy array, where `valid_triangle[i,j,0/1]` stands for whether `(i,j), (i+1,j), (i,j+1)` and `(i+1,j+1), (i+1,j), (i,j+1)` are included (`True`) or not included (`False`). `sample_data/valid_triangle.npz` provides an example. **Induce valid triangle from ground truth depth.** Valid triangle can be induced from ground truth depth by inducing occlusion boundaries by some heuristic. In `induce_valid_triangle_from_gt_depth.py`, we provide an example script which detects occlusion boundaries by relative depth between neighboring pixels and set triangles across occlusion boundaries as invalid. Running `python induce_valid_triangle_from_gt_depth.py` generates `sample_data_2/valid_triangle.npz`. ## Compute Metric Please refer to `compute_metrics_example.py` ## Visualization ### Projected Contours ```bash ROOT=sample_data # Path to directory where rgb.png is located # ROOT=sample_data_2 DEPTH_F=gt_depth.npz # Path to depth map to draw visualization, relative to $ROOT # DEPTH_F=curv_low_freq__0.200_10.0.npz # when ROOT=sample_data # DEPTH_F=depthpro_gt_focal.npz # when ROOT=sample_data_2 python evalmde/visualization/render_contour_line.py $ROOT --depth_f $DEPTH_F ``` Running the above command generates projected contours visualization under `sample_data/contour_line` or `sample_data_2/contour_line`. Projected contours of different densities along different axes are generated. ### Textureless Relighting ```bash ROOT=sample_data # Path to directory where rgb.png is located # ROOT=sample_data_2 DEPTH_F=gt_depth.npz # Path to depth map to draw visualization, relative to $ROOT # DEPTH_F=curv_low_freq__0.200_10.0.npz # when ROOT=sample_data # DEPTH_F=depthpro_gt_focal.npz # when ROOT=sample_data_2 LIGHT_L=0 # specifies light direction LIGHT_R=5 # specifies light direction python evalmde/visualization/render_textureless_relighting.py $ROOT --depth_f $DEPTH_F --light_l $LIGHT_L --light_r $LIGHT_R ``` Running the above command generates textureless relighting visualization under `sample_data/visualization`. By default, the script renders visualization using GPU. Add `--cpu` to run everything in cpu. `ROT_LIGHT_NUM_LIGHT,ROT_LIGHT_NUM_LOOP` in `evalmde/visualization/__init__.py` specifies the light configuration. `ROT_LIGHT_NUM_LIGHT` locations of the source of directional light are equally spaced along the path that spirals up from `(0,0,-1)` to `(0,0,1)` along the surface of a unit sphere, rotating around `z`-axis for `ROT_LIGHT_NUM_LOOP` times. Textureless mesh under the `i`-th source of directional light (`LIGHT_L<=i