Nodes/ComfyUI CV/cv2.calibrationMatrixValues
ComfyUI Node

cv2.calibrationMatrixValues

What your camera matrix actually means in millimetres

By bmad4ever·Created 4 months ago·Updated 15 days ago· 1
cv2.calibrationMatrixValues
  • cameraMatrix
  • imageSize
  • fovx
  • fovy
  • focalLength
  • principalPoint
  • aspectRatio
◄apertureWidth0.0000►
◄apertureHeight0.0000►

A camera matrix is three numbers in pixels - focal lengths and a principal point - and it's useless for talking to a human. "The FOV is 63° and the equivalent focal length is 28 mm" is the same information, in a language photographers, 3D artists and compositors understand. This node does the conversion, and it needs one thing you can't get from the calibration itself: the physical size of the sensor.

It's one of the ~470 raw cv2.* wrappers in comfyui_cv. Unlike most of the catalog it takes no image at all - it's arithmetic over geometry data, and it produces five scalars/composites rather than a picture.

How it works

OpenCV's calibrationMatrixValues(cameraMatrix, imageSize, apertureWidth, apertureHeight) converts intrinsics into physical terms: it takes fx in pixels and the sensor width in millimetres, and reports the focal length in millimetres, the horizontal and vertical field of view in degrees, the principal point, and the aspect ratio. The relation is the pinhole one: the same angular coverage can be described by a big sensor with a long lens or a small sensor with a short one, so the aperture you pass in defines the answer.

That's the whole trap of this node. The intrinsics come from calibration; the sensor size is a fact about the physical camera that calibration cannot tell you. Feed it wrong and every output is confidently wrong.

Inputs and outputs

  • cameraMatrix (required, NPARRAY) - the 3×3 matrix. Data-array socket, so it's an array, not an image: this is what the pack's CV Calibrate Camera (Chessboard) node produces after you feed it chessboard views.
  • imageSize (required, default (0,0)) - the resolution the calibration was done at, as one composite CV_TUPLE in (w, h) order. It must match, or the fields of view come out wrong.
  • apertureWidth, apertureHeight (required, default 0) - the physical sensor dimensions in millimetres. Full frame is 36.0 × 24.0; a 1/2.3" phone sensor is around 6.17 × 4.55. Zeros are not a neutral default here, they're a divide-by-zero.

Five outputs: fovx and fovy (degrees), focalLength (millimetres - a single number, so it's the x-axis focal length in practice), principalPoint (a CV_TUPLE composite, subpixel (x, y), which wires straight into any cv2 point input or into CV Split Tuple for the separate numbers), and aspectRatio.

Why you'd want it in ComfyUI

Three reasons, in descending order of how often they apply.

Camera-matching for generation. If you're reproducing a shot - or writing a camera prompt with a specific lens character - knowing that your reference render covers 63° horizontally turns "cinematic lens" into "35 mm equivalent", and that's a much more useful thing to put in a prompt or a 3D scene setup.

Geometry work. The pack's 3D nodes (CV Preview 3D, CV Rasterize Mesh) rasterise meshes through an OpenCV camera, and anything that has to look right in that camera needs a plausible FOV. Same for rectifying a perspective or building a projection for a composite.

Sanity-checking a calibration. If your chessboard calibration says the phone you shot with has a 140° field of view, you mis-set something - usually the image size, or you mixed up the pattern size. Two numbers tell you immediately.

It is not a node most workflows need. If you've never calibrated a camera in ComfyUI, you have no camera matrix, and this node has nothing to chew on.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv

Restart, or install via ComfyUI Manager (search "comfyui_cv"). Requires Python ≥ 3.12, a recent ComfyUI on the V3 node API, and:

pip install "opencv-contrib-python-headless~=5.0.0.93"

Behaviour is curated against that OpenCV version; no models are involved.

Common issues

Infinite or absurd outputs. apertureWidth or apertureHeight is 0, or imageSize is left at (0,0).

Plausible but wrong numbers. The usual cause is calibrating on downscaled images and then passing the native resolution - the matrix is resolution-specific. Pass the size the calibration actually ran at, or rescale the matrix to match.

The matrix won't connect. cameraMatrix is NPARRAY-only: an IMAGE link is refused. Feed it from a calibration node, or reconstruct the array.

The results don't match a lens database. Expected, at the margins. OpenCV reports a straightforward pinhole conversion; lens specs often quote a diagonal field of view, and distortion isn't part of this calculation at all. Use it for gross reasoning about a lens, not for pitch-perfect matching.

Categoryimage/CV/low-level/cv2 C

Inputs (4)

NameTypeDefaultDescription
cameraMatrixNPARRAY - - - A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here.
imageSizeCV_TUPLE0,0One value with 2 components (w, h) - it travels as a whole, so it cannot arrive half-connected. Wire it from 'CV Tuple' or type the components in place.
apertureWidthFLOAT0.0000-1e+38–1e+38 - - -
apertureHeightFLOAT0.0000-1e+38–1e+38 - - -

Outputs (5)

NameTypeDescription
fovxFLOAT—
fovyFLOAT—
focalLengthFLOAT—
principalPointCV_TUPLE- - - Subpixel coordinates (x, y) as ONE composite value - wire it straight into any cv2 point input, or into 'CV Split Tuple' for the separate numbers.
aspectRatioFLOAT—