FOV & Tilt Estimator (RGB)
The quick-and-dirty way to pull FOV and tilt off a plain photo
- image
- annotated_image
- fov_degrees
- tilt_degrees
- info
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:
- Canny edge detection finds edges (
edge_threshold_low/edge_threshold_highcontrol the sensitivity). - A Hough transform converts those edges into straight lines.
- Near-horizontal lines get filtered out - you want the converging ones, like road edges, railway tracks, and building corners.
- Every pair of lines is intersected, and the intersections are clustered with a RANSAC-style voting scheme to find the dominant vanishing point.
- 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 (default150) - 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_imageoverlay 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.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| edge_threshold_lowopt | INT | 500–255 | — |
| edge_threshold_highopt | INT | 1500–255 | — |
| line_thresholdopt | INT | 10010–500 | — |
| visualizeopt | BOOLEAN | true | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| annotated_image | IMAGE | — |
| fov_degrees | FLOAT | — |
| tilt_degrees | FLOAT | — |
| info | STRING | — |