Nodes/camera-comfyUI/DepthScaleAnchor
ComfyUI Node

DepthScaleAnchor

The robust way to pin one depth map to another's scale

By Alexankharin·Created about a year ago·Updated about a month ago· 36
DepthScaleAnchor
  • new_depth
  • ref_depth
  • valid_mask
  • aligned_depth
  • scale
  • shift
modescale_shift

DepthScaleAnchor is the smarter sibling of DepthRenormalizer. Where DepthRenormalizer does a quick linear scale/offset fit, this node does a robust least-squares fit in the disparity domain - and that difference is exactly what you want when your depth maps are noisy or only partially overlapping, which is the common case once you're stitching views together.

The use case is the same as its sibling: you've got one depth map whose scale you trust and another you need to bring into line before they can share a point cloud. What makes DepthScaleAnchor the one to reach for when it matters is robustness - the "least-squares" fit weights the trustworthy overlap, so a few bad pixels in the intersection don't bend the whole calibration the way a naive fit would.

The inputs

  • new_depth - the map you're aligning (any shape).
  • ref_depth - the reference metric depth map, same shape.
  • valid_mask - 1.0 where both depths are trustworthy. This is the input to get right; the whole point of the node is that the fit only counts regions you vouch for.
  • mode - scale or scale_shift (default scale_shift): fit only a multiplier, or a multiplier plus an offset, both in the disparity (1/d) domain.

The disparity-domain choice is the interesting bit of engineering. Depth estimators tend to have errors that are roughly multiplicative in disparity, and fitting there makes the solution far less sensitive to the typical "close object estimates are noisy" failure mode. Practically: leave mode at scale_shift for general use; drop to scale only when you know the maps share an origin and differ purely by units.

The outputs

Three things come back: aligned_depth (the fixed map), plus scale and shift as plain FLOATs. Those two scalars are a gift - they tell you what was wrong, and you can log them, average them across a video sequence for a single stable calibration, or reuse them as constants on later frames instead of re-running the fit. If you're batch-processing a video, fit once on a good frame and hard-code the result.

Why it's in the "World" category

The pack files this under Camera/World because scale anchoring is the step that turns per-view depth estimates into a single consistent world - it's used in VideoToFusedSplats (aligning SHARP keyframes to metric depth) and throughout the multi-view fusion paths. Every time a splat cloud "doesn't quite line up" between keyframes, the fix is usually this node with a tighter mask.

Install

Shared camera-comfyUI install: Manager → search "camera-comfyUI" → Install, or clone https://github.com/Alexankharin/camera-comfyUI into custom_nodes/ and run python install.py. No models, no CUDA - pure scipy/numpy fit on CPU.

Troubleshooting

  • Fit collapses to nonsense: your valid_mask is covering regions where one depth is garbage. Tighten it to the clean core of both maps.
  • Video jitters between frames: you're re-fitting per frame. Fit once on a trustworthy frame, then reuse the returned scale/shift as fixed values - or average them across frames first.
  • Offset drifts: if scale_shift gives a good scale but a weird shift, your reference map might itself be relative-depth. Use a metric reference (DepthEstimatorNode's Depth Anything V2 output) as ref_depth.
CategoryCamera/World

Inputs (4)

NameTypeDefaultDescription
new_depthTENSORDepth map to be aligned (any shape).
ref_depthTENSORReference metric depth map (same shape).
valid_maskMASK1.0 where both depths are trustworthy.
modeCOMBOscale_shiftFit scale only, or scale + shift, in disparity (1/d) domain.

Outputs (3)

NameTypeDescription
aligned_depthTENSOR
scaleFLOAT
shiftFLOAT