Nodes/ComfyUI-PanoTools/Camera Calibration
ComfyUI Node

Camera Calibration

Guess a camera's roll, pitch, and FOV from one image (no checkerboard required)

By 9nate-drake·Created 8 months ago·Updated 8 months ago· 7
Camera Calibration
  • image
  • roll
  • pitch
  • vfov
  • focal_length
  • focal_length_mm
  • calibration_info
calibration_method
manual_roll0.00
manual_pitch0.00
manual_vfov60.0
horizon_roi_top0.30
horizon_roi_bottom0.70
min_line_length100
angle_threshold5.0

The name is a lie, and that's fine. You're not calibrating a lens rig or waving a checkerboard - this node answers one dumb-sounding question: how is the camera tilted, and how wide is it looking? If that sounds trivial, remember the whole point is to hand those three numbers to its sibling, Perspective to Panorama, so a flat video frame can be re-projected into a proper 360° equirectangular image. Get the roll, pitch, and vertical field of view even slightly wrong and your panorama comes out tilted, off-center, or warped at the edges. This node does that measurement for you, automatically, from a single frame.

It's part of ComfyUI-PanoTools, an open re-implementation of the perspective-to-panorama method hybridworkflow posted to r/StableDiffusion in late 2025 - the one that became the community's standard first step for turning ordinary footage into VR-ready panoramas before a model outpaints the missing sky and ground.

How it works

Four calibration methods, all in one node:

  • geocalib_auto - the one you should use first. It's a deep network called GeoCalib (ECCV 2024, ETH Zurich) that predicts gravity direction and field of view straight from the image content. No horizon needed, works on any scene. The code is vendored inside the pack, and the model weights (~110–220 MB) download automatically from GitHub on your first run.
  • horizon_detection - classic computer vision: edge detection plus a Hough transform to find the horizon line in a region of interest. Roll comes from the line's slope, pitch from where it sits vertically. Great for ocean/sky shots, but the README is candid that this path is "mostly untested."
  • vertical_lines - the architectural twin. Finds near-vertical lines (building edges) via Hough and uses their deviation from true vertical to estimate roll.
  • manual - skips all the guessing and just passes through your manual_roll, manual_pitch, and manual_vfov values, which the output wiring then feeds downstream. Handy when you know the lens.

For anything that isn't a clean horizon or a block of buildings, geocalib_auto wins. The geometric methods are the "I want zero extra downloads" fallback, not the recommendation.

Inputs and outputs that matter

You only need image and calibration_method. Everything else is optional, and only manual_roll, manual_pitch, and manual_vfov are used unless you pick manual. horizon_roi_top/horizon_roi_bottom (0–1 fractions of image height) narrow where the horizon search happens; min_line_length and angle_threshold tune how picky vertical-line detection is. Most people never touch them.

The outputs are the payoff, and they wire straight into Perspective to Panorama:

  • roll, pitch, vfov - the three numbers you care about.
  • focal_length (in pixels) and focal_length_mm (35mm-equivalent) - informative extras; Perspective to Panorama can take the pixel focal length directly.
  • calibration_info - a text string describing what the node detected, handy for debugging.

Typical workflow: load your video, pull frame 0, calibrate it, and pipe the outputs into Perspective to Panorama while it processes the full clip. One calibration for the whole video - no need to run it per frame.

Installation

cd ComfyUI/custom_nodes
git clone https://github.com/9nate-drake/ComfyUI-PanoTools.git
cd ComfyUI-PanoTools
pip install -r requirements.txt

Then restart ComfyUI and look under Add Node > PanoTools. The requirements are light - opencv-python, kornia, matplotlib - and numpy/torch/torchvision are already in any ComfyUI install. ComfyUI Manager support is listed as "coming soon" in the README, so the git route is the reliable one for now.

Common issues

  • "ERROR: GeoCalib failed to load" - a dependency is missing or the first-run weight download (from GitHub, so it needs network access) didn't finish. Run pip install -r requirements.txt, restart, retry.
  • "WARNING: No horizon/lines detected" - the geometric method came up empty. That's not a bug in your setup; just switch to geocalib_auto, or widen the ROI / lower min_line_length.
  • Calibration seems off - GeoCalib's estimate is good but not gospel, especially on heavily cropped or very unusual frames. Nudge roll/pitch/vfov manually in Perspective to Panorama afterward; that's the "manual control" the pack advertises.

The honest take: this is a one-trick node, but it's the trick that makes the whole pack work. Feed it the first frame, and it saves you from the slow, frustrating process of eyeballing roll and pitch until the panorama stops looking drunk.

CategoryPanoTools

Inputs (9)

NameTypeDefaultDescription
imageIMAGESingle image or first frame to analyze for camera calibration parameters
calibration_methodCOMBOCalibration method: 'geocalib_auto' (AI-based, works for all scenes - recommended), 'horizon_detection' (for outdoor/ocean scenes), 'vertical_lines' (for architecture/buildings), or 'manual' (specify values manually)
manual_rolloptFLOAT0.00-180–180Camera roll (rotation around viewing axis) in degrees. Positive = clockwise tilt. Only used when method is 'manual'.
manual_pitchoptFLOAT0.00-180–180Camera pitch (up/down angle) in degrees. Positive = tilted up, negative = tilted down. Only used when method is 'manual'.
manual_vfovoptFLOAT60.010–170Vertical field of view in degrees. Typical values: 40-60° (standard lens), 70-90° (wide angle), 10-30° (telephoto). Used when method is 'manual' or as fallback for geometric methods.
horizon_roi_topoptFLOAT0.300–1Top boundary of search region for horizon (0.0 = image top, 1.0 = image bottom). Adjust to focus on area where horizon is expected. Only for 'horizon_detection' method.
horizon_roi_bottomoptFLOAT0.700–1Bottom boundary of search region for horizon (0.0 = image top, 1.0 = image bottom). Should be below the horizon line. Only for 'horizon_detection' method.
min_line_lengthoptINT10020–500Minimum length (in pixels) for lines to be detected. Increase for images with noise or small details. Only for 'vertical_lines' method.
angle_thresholdoptFLOAT5.00.1–15Maximum angle deviation from perfectly vertical (in degrees). Lower = stricter vertical alignment. Increase if camera has significant roll. Only for 'vertical_lines' method.

Outputs (6)

NameTypeDescription
rollFLOATCamera roll rotation in degrees
pitchFLOATCamera pitch rotation in degrees
vfovFLOATVertical field of view in degrees
focal_lengthFLOATFocal length in pixels (used for projection calculations)
focal_length_mmFLOAT35mm equivalent focal length (e.g., 24mm wide, 50mm standard, 85mm portrait). Useful for comparing with real camera lenses.
calibration_infoSTRINGDiagnostic information about the calibration method used and detected parameters