Nodes/ComfyUI FOV Estimator/FOV & Tilt Estimator (RGB)
ComfyUI Node

FOV & Tilt Estimator (RGB)

The quick-and-dirty way to pull FOV and tilt off a plain photo

By gitcapoom·Created 10 months ago·Updated 10 months ago· 1
FOV & Tilt Estimator (RGB)
  • image
  • annotated_image
  • fov_degrees
  • tilt_degrees
  • info
edge_threshold_low50
edge_threshold_high150
line_threshold100
visualizetrue

Drop an image in, get two numbers out: field of view in degrees and camera tilt (horizon angle). No depth map, no preprocessing, no model download - this node reads the camera geometry straight off the RGB pixels. It's the zero-friction half of the ComfyUI FOV Estimator pack, and it exists for the moments when you want a quick read on a photo's viewpoint without standing up a whole depth-estimation pipeline.

Use it when you're matching a generation to a reference shot's lens, reasoning about perspective for a composition, or roughly placing a virtual object so it sits convincingly in a scene - the "what lens is this?" question. The catch, up front: pixels lie. Shadows, textures, and busy clutter masquerade as edges - which is exactly why the pack's other node, FOV & Tilt Estimator (Depth), is the author's recommended path. This one trades accuracy for convenience.

How it works

It's textbook vanishing-point geometry, the kind of thing you can draw on a napkin:

  1. Canny edge detection finds edges (edge_threshold_low / edge_threshold_high control the sensitivity).
  2. A Hough transform converts those edges into straight lines.
  3. Near-horizontal lines get filtered out - you want the converging ones, like road edges, railway tracks, and building corners.
  4. Every pair of lines is intersected, and the intersections are clustered with a RANSAC-style voting scheme to find the dominant vanishing point.
  5. The vanishing point's distance from the image center approximates the focal length in pixels, and hfov = 2 × arctan(width / (2 × focal_length)) turns that into degrees.

Tilt is simpler: find near-horizontal lines (candidate horizons), take the median horizon position relative to frame center, and convert that pixel offset to degrees using the vertical FOV. Horizon dead center means ~0° tilt.

Under the hood it's pure OpenCV - this node adds no model, no weights, no network call. The whole pack installs in seconds.

Inputs and outputs that matter

One required input: image, and that's the whole point - it's the only thing this node needs.

Three optional knobs, of which you'll realistically tune one:

  • edge_threshold_low (default 50) / edge_threshold_high (default 150) - the Canny hysteresis pair. Low threshold too high and you lose faint edges; on noisy photos, raise the low one to 70–100 to cut the grain.
  • line_threshold (default 100) - how many edge points a line needs to survive Hough detection. Drop it toward 50–70 on outdoor scenes where lines are weak.
  • visualize (default True) - draws the detected lines, vanishing point, and horizon onto the output so you can see what the node saw.

Outputs: annotated_image (overlay, or the plain image with visualize off), fov_degrees, tilt_degrees, and info - a ready-to-read FOV: xx°, Tilt: yy° string. On multi-frame batches it averages the per-frame results.

Installing it

Same pack as the depth variant, so the steps are identical. In ComfyUI Manager search "FOV Estimator" (repo: gitcapoom/comfyui_fovestimator) and install, or manually:

cd ComfyUI/custom_nodes/
git clone https://github.com/gitcapoom/comfyui_fovestimator.git
cd comfyui_fovestimator
pip install -r requirements.txt

Restart ComfyUI afterward. Requirements are numpy, opencv-python, torch - torch is already in your ComfyUI environment, so opencv-python is the only thing pip actually has to fetch. There are no model files to download, which makes this the rare custom node you can install on a whim.

Where people get burned

  • Organic scenes. Forests, clouds, skin, anything without straight converging lines - the vanishing point search comes up empty and you get a fallback value based on aspect ratio (45–90°) rather than a measurement. The annotated_image overlay shows you which happened: no markers, you're reading a guess.
  • Missing horizons. Tilt needs a visible horizon. No horizon, and the number is unreliable - the depth variant has a better fallback here.
  • Lens distortion. Both assume a pinhole camera. Fisheye and badly corrected wide-angle shots produce numbers that are wrong in ways you won't notice until you've trusted them.
  • Cluttered, low-contrast scenes. Few clean lines or weak contrast means Hough finds nothing useful. That's when you reach for the depth node instead - or walk away.

Honestly? This is the node you use to get a ballpark in ten seconds, not the one you bet a pipeline on. The depth-based sibling is more robust for anything important. But when you just need to know if a photo is a wide shot or a crop, this is the fastest answer in the graph - and the overlay makes it easy to see exactly how much to trust it.

Categoryimage/analysis

Inputs (5)

NameTypeDefaultDescription
imageIMAGE
edge_threshold_lowoptINT500–255
edge_threshold_highoptINT1500–255
line_thresholdoptINT10010–500
visualizeoptBOOLEANtrue

Outputs (4)

NameTypeDescription
annotated_imageIMAGE
fov_degreesFLOAT
tilt_degreesFLOAT
infoSTRING