Nodes/ComfyUI-CameraPack/Camera Intrinsics
ComfyUI Node

Camera Intrinsics

The Camera Intrinsics node

By PozzettiAndrea·Created 7 months ago·Updated 9 days ago· 1
Camera Intrinsics
    • intrinsics
    matrix[[1000, 0, 960], [0, 1000, 540], [0, 0, 1]]

    The Camera Intrinsics node does exactly one thing: it turns a camera's intrinsics matrix, pasted in as text, into a typed INTRINSICS value ComfyUI can route around a graph. It sounds almost too dumb to need a node - until you've got a K matrix printed in a paper, copied out of a calibration tool, or pasted straight from a PyTorch terminal and there's no typed slot on the graph to hold it.

    Why this exists

    Modern geometry models like Depth Anything V3 don't just hand you a depth map anymore. They also estimate the camera: where it was, which way it looked, and what its lens was doing - the so-called intrinsics (the 3×3 K matrix: focal lengths fx/fy in pixels and the principal point cx/cy) and extrinsics (the 4×4 position + orientation pose). Other packs in the same camera pipeline (like ComfyUI-CameraPack's DA3ToLoad3DCamera) want those values as typed tensors, and this node is the manual entry point: you have the numbers, you paste them in, you get a tensor out.

    How it works

    Under the hood it's almost embarrassingly simple, and that's the point. You type (or paste) the matrix into a multiline text box, the node runs ast.literal_eval to parse it as a Python literal, coerces it to a float32 numpy array, and checks it's really 3×3. Then it wraps it in a PyTorch tensor with a batch dimension so the rest of the graph sees a [1, 3, 3] tensor.

    One genuinely handy detail: it tolerates tensor(...) pastes. If you copy an intrinsics matrix straight out of a PyTorch printout, the node strips the tensor( wrapper before parsing. Fewer "why is this a string" moments than you'd expect from a text-input node.

    The one input and the output

    There's a single required input, matrix (a multiline text field), and one output, intrinsics (INTRINSICS).

    The only field you'll ever set is matrix. The default is a sane placeholder:

    [[1000, 0, 960],
     [1000, 0, 540],
     [0, 0, 1]]
    

    The author's own tooltip gives the format: [[fx, 0, cx], [0, fy, cy], [0, 0, 1]]. Remember fx/fy are focal length in pixels, not millimeters - for a real camera, fx = f_mm * width / sensor_width_mm. The 960/540 defaults are just a 1920×1080 principal point. If you're feeding this from a depth-model output you'll usually grab the model's numbers instead, but for a known, fixed camera (your phone, a calibrated rig) hardcoding the matrix and reusing it is a perfectly legit workflow.

    Installing

    This is part of ComfyUI-CameraPack by PozzettiAndrea. In ComfyUI Manager, search "CameraPack", install, and restart. Or, the manual way:

    cd ComfyUI/custom_nodes
    git clone https://github.com/PozzettiAndrea/ComfyUI-CameraPack.git
    

    Then restart ComfyUI. The pack is pure Python - its declared dependencies (numpy, torch) are already part of ComfyUI, so there are no extra model downloads or heavy installs. The node shows up under the 3d/camera category.

    Where it bites

    If the node throws, it's almost always because the paste isn't a clean literal: stray text, trailing commas, or a tensor(...) paste that already has a [1, 3, 3] shape baked in. It handles the (1, 3, 3) case by stripping the leading batch dim, but a [N, 3, 3] with N > 1 will fail with a "Expected 3×3 matrix" error - that's what the batch-slicing nodes in this pack are for. Keep the paste clean and it just works.

    Category3d/camera

    Inputs (1)

    NameTypeDefaultDescription
    matrixSTRING[[1000, 0, 960], [0, 1000, 540], [0, 0, 1]]3x3 intrinsics matrix [[fx, 0, cx], [0, fy, cy], [0, 0, 1]]

    Outputs (1)

    NameTypeDescription
    intrinsicsINTRINSICS