Skip to content
AI360Xpert
Beta

DPT Transformer for Dense Depth

Convolutions see locally; depth needs the whole room. DPT reads the image with a vision transformer so far walls inform near chairs.

Transformer tokens gather global context before a convolutional decoder rebuilds depth
Transformer tokens gather global context before a convolutional decoder rebuilds depth

Why Does This Exist?

CNN depth backbones grow context slowly through stacked 3×33 \times 3 kernels, so thin structures and far layout stay ambiguous. DPT exists to give dense prediction a global view from the start: a vision-transformer encoder attends across the whole image at every layer, then a lightweight convolutional decoder reassembles tokens from several scales into a sharp high-resolution map. It powers MiDaS v3v3 and the Depth Anything family.

Basics are monocular depth estimation; the mixed-dataset teacher is MiDaS.

Think of It Like This

A survey team with radios

A CNN crew passes notes only to neighbors, so news crosses the field slowly. A DPT crew carries radios: every member hears the far corner instantly, then draws the local map with full context.

Attention is the radio and the decoder is the local drawing. The analogy stops at cost: radios need batteries while global attention needs quadratic memory, tamed here by patch tokens.

How It Actually Works

The image splits into 16×1616 \times 16 patches embedded as tokens with position codes. Transformer blocks apply softmax(QKT/d)V \mathrm{softmax}(QK^T / \sqrt{d})V globally, so each token reads all others. Tokens from four stages reassemble into image-like maps at 1/41/4 to 1/321/32 scale, then RefineNet-style fusion blocks upsample and merge coarse-to-fine into depth at half input resolution. The same head swaps to segmentation or normals by changing the loss, which is why DPT is a dense-task backbone rather than a depth-only trick.

Worked numbers

A 384×384384 \times 384 image gives (384/16)2=576(384/16)^2 = 576 tokens. Attention over 576576 tokens costs 5762≈331000576^2 \approx 331000 pairwise scores per head, trivial next to per-pixel CNN stacks. On the demo edge split, boundary F1 rises from 0.620.62 CNN to 0.710.71 DPT, about a 1515 percent relative gain.

Code

def token_count(size: int, patch: int) -> int:    return (size // patch) ** 2  # patches become transformer tokens

print(token_count(384, 16))  # -> 576

Watch Out For

Running DPT at full megapixels naively

Token count grows with the square of resolution, so 10241024 px images explode memory sixteenfold over 256256 px. The symptom is sudden out-of-memory on phone photos. Tile with overlap or cap the long side near 768768 px, then blend.

The Quick Version

  • DPT encodes patches with a vision transformer for global context.
  • A convolutional decoder fuses four scales into sharp depth.
  • Global attention fixes thin structures that local CNNs smear.
  • Token count is (H/16)×(W/16)(H/16) \times (W/16); watch memory at high resolution.
  • The same backbone serves depth, segmentation, and normals.
  • MiDaS v3v3 and Depth Anything build directly on DPT.