Evaluation & Metrics
Chamfer Distance
The average distance from each point of one point set to the nearest point of another, in both directions; the conventions that make published values incomparable, its sensitivity to sampling density and outliers, and how it relates to the Hausdorff distance, the Earth Mover's Distance and the F-score.
intermediate
The Chamfer distance compares two point clouds without knowing which point corresponds to which. Every point of each set is paired with its nearest neighbour in the other set, and the distances (or their squares) are averaged or summed over both directions. It is widely used as a score and as a training loss for 3D shape prediction, wherever a reconstruction, a mesh or a neural field can be sampled into points. The 3D reconstruction article introduces it next to accuracy, completeness and the F-score; this article covers what the number depends on (the definition used, the number and density of sampled points, the outliers) and when the Hausdorff distance, the Earth Mover’s Distance or the F-score answer the question better.
Formula
For finite point sets and , let be the distance from a point to the nearest point of the other set. A one-sided term averages a power of these distances,
and the Chamfer distance combines the two directions. With and an average of the two terms this is the “Chamfer-” distance of Occupancy Networks (Mescheder et al., 2019):
When is a prediction and the ground truth, is the mean accuracy distance and the mean completeness distance. The value range is , in units of length for and of squared length for ; lower is better. It is zero exactly when the two sets are equal as sets.
Conventions in use
Papers differ in all three choices: the power , sum or mean over points, and sum or mean over the two directions. As printed:
| Source | Per-point distance | Over points | Directions |
|---|---|---|---|
| Barrow et al. (1977), chamfer matching | Euclidean, approximated on the pixel grid | sum | one: model features to image features |
| Fan et al. (2017), Eq. 3 | squared Euclidean | sum | both, added |
| Mescheder et al. (2019), Chamfer- | Euclidean | mean | both, averaged |
| DTU (Aanæs et al., 2016) | Euclidean, distances above 20 mm discarded | mean and median | each reported separately |
PyTorch3D v0.7.9 chamfer_distance default |
squared Euclidean | mean | both, added |
The conventions convert into each other only in part. Averaging the directions gives half of adding them, and a sum equals times a mean only for that set’s size; with sets of different sizes, the sum weights the larger set more. Between and there is no conversion: the mean of squared distances is at least the square of the mean distance, with equality only when all distances are equal, so the two can rank methods differently (the example below shows such a reversal). A table that says only “CD” has not given its definition, and values copied from papers that used different conventions cannot be compared.
Intuition
The name comes from image matching. Barrow et al. (1977) matched a predicted set of map features, projected into an image for an assumed camera pose, against the edge points extracted from the image. They first converted the binary feature image into an array of distances to the nearest feature point, computed in two raster passes with steps of 2 and 3 approximating distances 1 and , a process they cite as “chamfering”. The match score is then the sum of the array values at the predicted feature locations, so evaluating a pose costs one lookup per predicted point, a cost proportional to the length of the curves rather than to image area. That score is a one-sided Chamfer term: it penalizes predicted points far from any edge but not edges far from any predicted point. Borgefors (1988) developed it into a hierarchical algorithm for matching edges. Fan et al. (2017) later used the symmetric form on 3D point sets as a training loss for point-set generation.
The two directions answer different questions: “is each predicted point near the true surface?” catches stray points and misplaced parts, and “is each true point near some prediction?” catches holes. No correspondence is enforced, and many predicted points may share one nearest reference point.
Interpretation
A floor set by sampling. Two independent samplings of the same surface do not score zero, because their points do not coincide. Treating each sampling as a uniform random process of density points per unit area on a surface of area , the standard nearest-neighbour results for a planar Poisson process give, for small spacing, a mean distance and a mean squared distance . So, in our derivation, the floor of falls as , the mean-squared version as , and the sum of squared distances over both directions, Fan et al.’s form, tends to whatever is. A method’s score therefore cannot be judged without the number of points sampled from both shapes, and a difference smaller than the floor at that says little.
Units. Each paper fixes its own scale. Fan et al. defined unit 1 as a tenth of the length of the voxel grid of the 3D-R2N2 dataset, and Mescheder et al. as a tenth of the longest edge of each object’s bounding box, following Fan et al.; Tatarchenko et al. (2019) gave F-score thresholds as a percentage of the side length of the reconstructed volume. A value is comparable only with values in the same unit, from the same number of samples, under the same definition.
Alignment. The metric measures shape and pose together. Benchmarks bring a reconstruction into the reference frame and scale before scoring it, as the 3D reconstruction article describes; the one-sided mean squared term is also the objective that point-to-point iterative closest point reduces over rigid motions.
When to Use It
- As a training loss for networks that output point sets. Fan et al. noted that it is differentiable almost everywhere, that each point’s nearest-neighbour search is independent and parallel, and that a k-d tree speeds it up. They also showed its bias as a loss: minimized in expectation over synthetic shape distributions, it blurs a continuously varying shape and places some points at each possible location of a part that may or may not be present (their Fig. 3), and their network trained with it scattered points in uncertain regions while preserving fine detail better than one trained with the Earth Mover’s Distance (Fig. 13).
- To compare representations on one footing. Meshes, depth maps, voxel grids and neural fields can all be sampled into points (3D representations), a property Tatarchenko et al. used to argue for point-based measures.
- As a diagnostic, with the two one-sided terms reported separately, so that a reader can tell missing geometry from stray geometry.
For ranking reconstructions, Tatarchenko et al. recommend the F-score at a strict threshold instead (below), and the large benchmarks rank by it or by separate accuracy and completeness statistics.
Failure Cases
Outliers. A mean of distances grows linearly with how far wrong points lie, and a mean of squared distances quadratically. Tatarchenko et al. (2019, Fig. 9) show two predicted chairs that match a reference in the lower part and are wrong in the upper part: both have an F-score at a 1% threshold of 0.56, but Chamfer distances of 0.21 and 0.15, because their wrong parts lie at different distances from the truth. They argued that a measure should not depend on the detailed layout of outliers. DTU’s 20 mm cut-off and median (multi-view stereo) exist for this reason: Aanæs et al. (2016) discarded larger distances so that a few large outliers would not dominate, and added the median as a standard robust measure.
Sampling density. Both terms are averages over points, so densely sampled regions count more. Aanæs et al. found that comparing point clouds point by point weights up well-textured, prominent regions, where multi-view stereo returns more points, and preferred an area integral; they thinned both clouds by visiting the points in random order and keeping a point only if no previously considered point lay within 0.2 mm (§4.3 of the authors’ manuscript). Tanks and Temples resamples the reference and the reconstruction onto a voxel grid of size , keeping the mean of the points in each voxel (Knapitsch et al., 2017, authors’ version). Point-based F-scores share the problem, since precision and recall are per-point averages too.
Missing parts against small errors everywhere. A hole raises only the completeness term, by the distance from the missing region to the nearest remaining surface, averaged over the fraction of the reference that is missing. Noise raises both terms everywhere, by a small amount. Depending on , the two can tie or swap order, and the F-score, which counts points within a threshold, can rank them the other way. Mescheder et al.‘s comparison of single-image reconstruction on ShapeNet shows such a split between measures: their Occupancy Network had the highest mean volumetric IoU (0.571) and normal consistency (0.834), while AtlasNet, trained with a Chamfer loss, had the lowest mean Chamfer- (0.175, against 0.215 for the Occupancy Network; Table 1; AtlasNet was evaluated with its authors’ pretrained model on the intersection of two test splits).
Not a metric. The squared-sum form does not satisfy the triangle inequality, as Fan et al. note, and the mean-based forms do not either: on a line, and are at , but each is at 0.5 from (our example). Two dissimilar shapes can therefore both be close to a third. Nor does the measure see how points are distributed: extra points in one region do not change whether every point has a near neighbour, so a prediction that covers the surface with points concentrated in some regions scores almost like one spread like the reference (shown with the Earth Mover’s Distance below).
Variants
Hausdorff distance. Replacing the mean by a maximum gives the directed Hausdorff distance , and the Hausdorff distance , which is a true metric on closed bounded sets (Huttenlocher et al., 1993). It reports the single worst point, so one outlier sets its value. Huttenlocher et al. extended it to compare portions of the sets (their Section III), and Middlebury’s 90th-percentile accuracy, given in the multi-view stereo article, is a percentile between the median and the maximum. In PyTorch3D v0.7.9, point_reduction="max" returns the larger of the two directed maxima of its per-point values, which its documentation calls the Hausdorff distance; with the default norm=2 those values are squared, so the result is the square of .
Earth Mover’s Distance (EMD). Fan et al. define it for sets of equal size as the minimum, over bijections , of . Each point must be matched to a different point, so the EMD also measures whether the points are distributed over the surface like the reference’s. Its optimal matching solves an assignment problem; Fan et al. called exact computation too expensive for deep learning and used a approximation with errors around 1%. Rubner et al. (2000) used the EMD for image retrieval, formulated as a transportation problem between distributions; it is a true metric between distributions of equal total mass and allows partial matching when the masses differ. As a loss, Fan et al. found that it gives more compact predictions but sometimes shrinks local structures.
F-score at a threshold . The F-score of Tanks and Temples (Knapitsch et al., 2017) is the harmonic mean of the fractions of predicted and of reference points within of the other set (3D reconstruction, precision and recall). It thresholds the same nearest-neighbour distances that the Chamfer distance averages, so it is bounded in and indifferent to how far beyond a wrong point lies. Tatarchenko et al. suggested evaluating it at thresholds of 1% of the volume’s side length and below, because at 2% its values for single-view reconstruction were in the same range as mean IoU, which they had argued says little about shape quality at those levels.
Normal consistency. Mescheder et al. define it as the mean absolute dot product between the normal at each point of one mesh and the normal at its nearest neighbour in the other, to measure how well a method captures what they call higher-order information. PyTorch3D’s chamfer_distance returns a related term when normals are given: one minus the absolute cosine similarity, ignoring orientation by default.
Volumetric IoU. For closed meshes or occupancy fields, Mescheder et al. estimate intersection and union volumes from 100,000 random points in the bounding volume tested for inside or outside each mesh (their sentence names the quotient the other way round); it is intersection over union in 3D. It needs closed surfaces: Mescheder et al. could not evaluate it for PSGN and AtlasNet, which do not produce watertight meshes, and Tatarchenko et al. note that point clouds have no straightforward IoU.
Computation
The cost is two nearest-neighbour searches. A brute-force search computes all distances; a k-d tree (described in the point cloud article) built over one set answers each query from the other in about logarithmic time, and Huttenlocher et al. note that the Hausdorff distance, which needs the same queries, can be computed in for planar point sets of sizes and . Mescheder et al. sample 100,000 points from each mesh and use a k-d tree.
Library defaults must be read, not assumed. In PyTorch3D v0.7.9, chamfer_distance(x, y) returns, per cloud, the mean squared Euclidean distance from x to y plus the same from y to x, then averages over the batch. point_reduction takes "mean", "sum", "max" or None (per-point values), batch_reduction takes "mean", "sum" or None, and single_directional=True keeps only the term from x to y. The argument norm=1 does not give the “Chamfer-” of Occupancy Networks: its per-point distance is the sum of absolute coordinate differences (the Manhattan distance) computed by knn_points, while norm=2 gives squared Euclidean distances, and the two directions are still added rather than averaged.
Example
The script samples a torus (tube radius 0.25 around a circle of radius 0.6, inside the cube ) and scores seven predictions against 20,000 reference samples with SciPy’s cKDTree. The predictions are a fresh sampling of the same surface; Gaussian noise of standard deviation 0.02 on every coordinate; the surface with a 45° sector of the ring removed; 1% of the points moved outward along the surface normal by 0.2 or by 1.0; and noise on the half only, with that half sampled uniformly or four times as densely. Columns give the mean accuracy and completeness distances, , the PyTorch3D default (mean squared, added), Fan et al.’s sum of squares, the PyTorch3D norm=1 value (Manhattan, mean, added), the Hausdorff distance, and the F-score at three thresholds.
import numpy as np
from scipy.spatial import cKDTree
R_MAJ, R_MIN = 0.6, 0.25 # torus inside the cube [-1, 1]^3
def torus(n, rng):
"""Area-uniform samples on the torus surface (rejection on the tube angle)."""
out = []
while sum(len(o) for o in out) < n:
u, v = rng.uniform(0, 2 * np.pi, (2, 2 * n))
keep = rng.uniform(0, 1, 2 * n) < (R_MAJ + R_MIN * np.cos(v)) / (R_MAJ + R_MIN)
rho = R_MAJ + R_MIN * np.cos(v[keep])
out.append(np.stack([rho * np.cos(u[keep]), rho * np.sin(u[keep]),
R_MIN * np.sin(v[keep])], 1))
return np.concatenate(out)[:n]
def nn_dist(a, b, p=2):
"""Distance from each point of a to its nearest point of b (k-d tree)."""
return cKDTree(b).query(a, p=p)[0]
def scores(P, G, taus=(0.01, 0.02, 0.05)):
da, dc = nn_dist(P, G), nn_dist(G, P) # accuracy and completeness distances
m1a, m1c = nn_dist(P, G, p=1), nn_dist(G, P, p=1) # Manhattan, as norm=1 in PyTorch3D
s = dict(acc=da.mean(), comp=dc.mean(),
cd_l1=(da.mean() + dc.mean()) / 2, # Mescheder et al. (2019)
cd_sq=(da**2).mean() + (dc**2).mean(), # PyTorch3D default
cd_fan=(da**2).sum() + (dc**2).sum(), # Fan et al. (2017), Eq. 3
p3d_l1=m1a.mean() + m1c.mean(), # PyTorch3D with norm=1
haus=max(da.max(), dc.max()))
for t in taus:
prec, rec = np.mean(da < t), np.mean(dc < t)
s[f"F@{t}"] = 2 * prec * rec / (prec + rec)
return s
G = torus(20_000, np.random.default_rng(0)) # reference samples
X = torus(80_000, np.random.default_rng(1)) # pool of surface samples for predictions
rng = np.random.default_rng(2)
base = X[:20_000]
def outliers(P, dist, frac=0.01):
"""Move a fraction of the points dist along the outward surface normal."""
P = P.copy()
k = rng.choice(len(P), int(frac * len(P)), replace=False)
rho = np.hypot(P[k, 0], P[k, 1])
centre = np.stack([P[k, 0] / rho * R_MAJ, P[k, 1] / rho * R_MAJ, 0 * rho], 1)
P[k] += dist * (P[k] - centre) / R_MIN
return P
def half_noisy(weight):
"""Noise (sigma 0.02) on the half x > 0, sampled `weight` times more densely there."""
pr = np.where(X[:, 0] > 0, weight, 1.0)
P = X[rng.choice(len(X), 20_000, replace=False, p=pr / pr.sum())]
return P + (P[:, :1] > 0) * rng.normal(0, 0.02, P.shape)
angle = np.degrees(np.arctan2(base[:, 1], base[:, 0]))
cases = {
"resampled": base, # same surface, new samples
"noise 0.02": base + rng.normal(0, 0.02, base.shape),
"missing 45 deg": base[np.abs(angle) > 22.5], # a sector of the ring removed
"1% out at 0.2": outliers(base, 0.2),
"1% out at 1.0": outliers(base, 1.0),
"half noisy, 1x": half_noisy(1.0),
"half noisy, 4x": half_noisy(4.0),
}
results = {name: scores(P, G) for name, P in cases.items()}
print(f"{'case':15s}{'n':>6s}{'acc':>8s}{'comp':>8s}{'CD-L1':>8s}{'CD-sq':>9s}"
f"{'Fan':>8s}{'p3d-L1':>8s}{'Haus':>7s}")
for name, s in results.items():
print(f"{name:15s}{len(cases[name]):6d}{s['acc']:8.4f}{s['comp']:8.4f}{s['cd_l1']:8.4f}"
f"{s['cd_sq']:9.2e}{s['cd_fan']:8.1f}{s['p3d_l1']:8.4f}{s['haus']:7.3f}")
print(f"\n{'case':15s}{'F@0.01':>8s}{'F@0.02':>8s}{'F@0.05':>8s}")
for name, s in results.items():
print(f"{name:15s}{s['F@0.01']:8.3f}{s['F@0.02']:8.3f}{s['F@0.05']:8.3f}")
Output (NumPy 2.3.5, SciPy 1.16.3):
case n acc comp CD-L1 CD-sq Fan p3d-L1 Haus
resampled 20000 0.0086 0.0085 0.0086 1.87e-04 3.7 0.0249 0.034
noise 0.02 20000 0.0194 0.0139 0.0166 7.13e-04 14.3 0.0477 0.091
missing 45 deg 17478 0.0086 0.0237 0.0161 3.10e-03 61.7 0.0438 0.332
1% out at 0.2 20000 0.0105 0.0086 0.0095 5.88e-04 11.8 0.0274 0.201
1% out at 1.0 20000 0.0173 0.0086 0.0129 8.61e-03 172.2 0.0365 1.001
half noisy, 1x 20000 0.0141 0.0113 0.0127 4.55e-04 9.1 0.0365 0.082
half noisy, 4x 20000 0.0168 0.0122 0.0145 5.79e-04 11.6 0.0418 0.087
case F@0.01 F@0.02 F@0.05
resampled 0.656 0.986 1.000
noise 0.02 0.210 0.715 0.993
missing 45 deg 0.614 0.925 0.947
1% out at 0.2 0.651 0.981 0.995
1% out at 1.0 0.650 0.981 0.995
half noisy, 1x 0.436 0.854 0.996
half noisy, 4x 0.330 0.788 0.994
The fresh sampling of the exact surface is the floor: its matches the Poisson estimate with , and its F-score at is only 0.66, close to the fraction of points that have a neighbour within , so a strict threshold needs denser sampling than this. The noisy and the incomplete torus are a tie under , with noise slightly worse; squaring the distances makes the missing sector four times worse, because its completeness distances reach a third of a unit. The F-score at 0.01 and 0.02 ranks noise far worse; at 0.05 it agrees with the squared form. Which reconstruction is “better” is decided by the convention and the threshold, not by the data. Moving the same 1% of points from 0.2 to 1.0 away leaves every F-score unchanged, raises by a third and the squared forms by a factor of about 15, and sets the Hausdorff distance to the outlier distance. The two half-noisy predictions have the same error on the same half of the surface; sampling that half four times as densely raises by 14% and lowers at 0.01 by a quarter, the per-point weighting that DTU and Tanks and Temples resample to remove. The norm=1 column is not : it is about 2.9 times larger, a factor 2 from adding rather than averaging and the rest from Manhattan distances.
The next block, continuing the script, scores two independent samplings of the same torus against each other for several sizes , five pairs each, and prints the range over the five.
print(f"{'n':>6s} {'CD-L1':13s} {'CD-sq':17s} {'Fan':9s} {'F@0.01'}")
for n in [1_000, 4_000, 16_000, 64_000]:
rows = []
for seed in range(5): # five independent pairs per n
A = torus(n, np.random.default_rng(100 + 2 * seed))
B = torus(n, np.random.default_rng(101 + 2 * seed))
s = scores(A, B, taus=(0.01,))
rows.append([s["cd_l1"], s["cd_sq"], s["cd_fan"], s["F@0.01"]])
lo, hi = np.min(rows, 0), np.max(rows, 0)
print(f"{n:6d} {lo[0]:.4f}-{hi[0]:.4f} {lo[1]:.2e}-{hi[1]:.2e} {lo[2]:4.2f}-{hi[2]:4.2f}"
f" {lo[3]:.3f}-{hi[3]:.3f}")
n CD-L1 CD-sq Fan F@0.01
1000 0.0371-0.0396 3.49e-03-3.93e-03 3.49-3.93 0.045-0.070
4000 0.0190-0.0194 9.28e-04-9.55e-04 3.71-3.82 0.184-0.195
16000 0.0095-0.0097 2.31e-04-2.38e-04 3.70-3.81 0.567-0.581
64000 0.0048-0.0048 5.87e-05-5.93e-05 3.76-3.79 0.966-0.967
Every quadrupling of halves and quarters the mean-squared form, as the and rates predict, while Fan et al.’s sum stays near at every size: summing over more points exactly offsets their smaller spacing. The spread over pairs shrinks with as well. Under the mean-based forms, a perfect shape scores worse at 1,000 points than a noisy one at 20,000 in the table above, so scores computed from different sample counts cannot be compared.
The last block compares the Chamfer distance with an exact EMD on 500 points of a unit sphere, using SciPy’s linear_sum_assignment, a modified Jonker–Volgenant solver for the assignment problem (SciPy 1.16 documentation). The predictions are a fresh sampling, the same with noise of 0.03, a sampling three times as dense on the upper half, and a sampling with the cap empty and the other points spread over the rest.
from scipy.optimize import linear_sum_assignment
def sphere(n, rng):
x = rng.normal(size=(n, 3))
return x / np.linalg.norm(x, axis=1, keepdims=True)
def emd(A, B):
"""Mean distance under the optimal one-to-one matching (Fan et al.'s Eq. 4 / n)."""
C = np.linalg.norm(A[:, None] - B[None], axis=2) # n x n cost matrix
i, j = linear_sum_assignment(C)
return C[i, j].mean()
n = 500
G = sphere(n, np.random.default_rng(10))
pool = sphere(4 * n, np.random.default_rng(13))
top = np.where(pool[:, 2] > 0, 3.0, 1.0) # upper half three times as dense
sets = {
"resampled": sphere(n, np.random.default_rng(11)),
"noise 0.03": sphere(n, np.random.default_rng(11)) + rng.normal(0, 0.03, (n, 3)),
"top-heavy": pool[rng.choice(4 * n, n, replace=False, p=top / top.sum())],
"no cap": pool[pool[:, 2] < 0.5][:n], # cap z > 0.5 empty, rest denser
}
for name, P in sets.items():
print(f"{name:11s} CD-L1 {scores(P, G)['cd_l1']:.4f} EMD {emd(P, G):.4f}")
resampled CD-L1 0.0793 EMD 0.1556
noise 0.03 CD-L1 0.0862 EMD 0.1611
top-heavy CD-L1 0.0815 EMD 0.3005
no cap CD-L1 0.1266 EMD 0.2749
Both distances have a large floor at 500 points, and noise moves both a little. The top-heavy sampling covers the whole sphere, so every point still has a near neighbour and the Chamfer distance barely changes; the EMD nearly doubles, because a one-to-one matching must carry the surplus from the upper half to the lower one. The empty cap raises both. The EMD sees the distribution of points over the surface, which the Chamfer distance cannot, at the price of an cost matrix: 250,000 entries here, for two clouds of 100,000 points.
Related Metrics
- Accuracy and completeness, the two one-sided terms with benchmark-specific statistics: 3D reconstruction, multi-view stereo.
- F-score at : the thresholded counterpart, preferred for ranking at a stated ; the Chamfer distance alongside it reports the size of errors beyond .
- Hausdorff distance (worst case) and Earth Mover’s Distance (one-to-one matching), under Variants above.
- Volumetric IoU and normal consistency, for closed meshes and implicit surfaces (neural implicit representations).
- Mean squared error, the analogue when correspondences are known, as for images on the same pixel grid.
Related
- 3D Reconstruction
Recovering the 3D shape of objects and scenes from images, depth maps, or range scans, as point clouds, meshes, volumes, or implicit and radiance fields, and measuring how accurate and complete the result is.
- Multi-View Stereo
Recovering dense 3D geometry, as depth maps, point clouds, meshes, or volumes, from many images whose camera poses and intrinsics are known.
- 3D Representations
The main ways to store 3D shape and scenes, from depth maps, point clouds and meshes to voxel grids, distance and occupancy fields, radiance fields and 3D Gaussians, and what each makes easy or hard.
- Precision and Recall
Two complementary measures of a classifier or detector, the fraction of its positive predictions that are correct and the fraction of true positives it finds, with the F-score, the confusion matrix, and the precision–recall and ROC curves built from them.
- Iterative Closest Point (ICP)
An algorithm that rigidly aligns two point clouds without known correspondences by alternating closest-point matching with a least-squares estimate of the rotation and translation.
- Neural Implicit Representations
Coordinate-based networks that store a shape, an image or another field in their weights, answering a query at any continuous point; how they are conditioned, trained from 3D data, raw points or images, why plain ReLU networks blur detail, and how surfaces are extracted from them.
References
- Barrow, H. G., Tenenbaum, J. M., Bolles, R. C. & Wolf, H. C. (1977). Parametric Correspondence and Chamfer Matching: Two New Techniques for Image Matching. Proceedings of the 5th International Joint Conference on Artificial Intelligence (IJCAI), 659–662.
- Borgefors, G. (1988). Hierarchical Chamfer Matching: A Parametric Edge Matching Algorithm. IEEE Transactions on Pattern Analysis and Machine Intelligence, 10(6), 849–865.
- Huttenlocher, D. P., Klanderman, G. A. & Rucklidge, W. J. (1993). Comparing Images Using the Hausdorff Distance. IEEE Transactions on Pattern Analysis and Machine Intelligence, 15(9), 850–863.
- Rubner, Y., Tomasi, C. & Guibas, L. J. (2000). The Earth Mover's Distance as a Metric for Image Retrieval. International Journal of Computer Vision, 40(2), 99–121.
- Fan, H., Su, H. & Guibas, L. (2017). A Point Set Generation Network for 3D Object Reconstruction from a Single Image. IEEE Conference on Computer Vision and Pattern Recognition (CVPR), 2463–2471.
- Aanæs, H., Jensen, R. R., Vogiatzis, G., Tola, E. & Dahl, A. B. (2016). Large-Scale Data for Multiple-View Stereopsis. International Journal of Computer Vision, 120(2), 153–168.
- Knapitsch, A., Park, J., Zhou, Q.-Y. & Koltun, V. (2017). Tanks and Temples: Benchmarking Large-Scale Scene Reconstruction. ACM Transactions on Graphics, 36(4), Article 78.
- Mescheder, L., Oechsle, M., Niemeyer, M., Nowozin, S. & Geiger, A. (2019). Occupancy Networks: Learning 3D Reconstruction in Function Space. IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR), 4455–4465.
- Tatarchenko, M., Richter, S. R., Ranftl, R., Li, Z., Koltun, V. & Brox, T. (2019). What Do Single-View 3D Reconstruction Networks Learn? IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR), 3400–3409.
- PyTorch3D developers (2025). pytorch3d.loss.chamfer_distance, source code at release v0.7.9.
- SciPy developers. scipy.optimize.linear_sum_assignment. SciPy 1.16.2 API reference.