Nodes/ComfyUI-SimpleLogics/GeoCalib → fSpy JSON
ComfyUI Node

GeoCalib → fSpy JSON

GeoCalib → fSpy JSON, explained

By danipisca07·Created 6 months ago·Updated 6 months ago· 0
GeoCalib → fSpy JSON
    • fspy_json
    image_width1920
    image_height1080
    roll0.00
    pitch0.00
    vfov60.00

    Here's the odd one out. GeoCalibToFSpy has nothing to do with booleans or integers. It's the node that takes a photograph - or an AI-generated image - and turns it into a camera calibration your 3D software can read. It's a bridge from image generation into Blender, and it's the only node in SimpleLogics that needs a second, unrelated pack to do anything.

    The workflow it serves: people who generate or shoot an image, then want to reconstruct it as a 3D scene - putting objects, walls, and lights into Blender so they line up with the photo. The standard tool for that is fSpy, the open-source app where you click vanishing points on a photo and it computes where the camera must have been. It's a genuinely popular trick in the community for turning 2D images into 3D scenes. The catch is that clicking vanishing points by hand is fiddly. This node automates it: instead of you eyeballing the geometry in fSpy's GUI, a vision model estimates the camera, and this node formats that estimate as an fSpy file.

    Specifically, it expects the outputs of the GeoCalib Estimator node (from the separate ComfyUI-GeoCalib pack, based on the GeoCalib single-image camera calibration model) - roll, pitch, and vfov - plus the image dimensions. GeoCalib looks at one frame and guesses how the camera was tilted and how wide its field of view was, which is exactly the information fSpy needs.

    How it works under the hood

    Reading the source, it builds an fSpy JSON structure:

    • principalPoint at the image center (normalized {x: 0, y: 0})
    • relativeFocalLength = 0.5 / tan(vfov/2), the fSpy convention normalized to half the image height
    • horizontal FoV derived from vfov and the aspect ratio
    • camera/view transform matrices built from roll and pitch rotation (yaw is left at 0 - GeoCalib doesn't estimate heading, so the scene has no compass direction)
    • vanishingPoints set to null placeholders, with a note that GeoCalib doesn't estimate them

    The output is a single STRING - a JSON document you save to a .fspy file and open in Blender with the fSpy addon enabled. Import it, and Blender places a camera that matches the photo's perspective.

    Inputs:

    • image_width, image_height (INT) - from your Load Image node or primitives. Defaults 1920×1080.
    • roll, pitch, vfov (FLOAT) - wire these straight from the GeoCalib Estimator node.

    Installing it

    The node itself is in ComfyUI-SimpleLogics (Manager → search "SimpleLogics", or manual clone below), and the pack itself has zero dependencies:

    cd ComfyUI/custom_nodes
    git clone https://github.com/danipisca07/ComfyUI-SimpleLogics
    

    But to actually use it you also need ComfyUI-GeoCalib installed (that's the pack that provides the Estimator node and its model weights), plus Blender and the free fSpy addon. No pip install needed for SimpleLogics itself - it's pure Python - but GeoCalib is a separate install with its own model download.

    Where people get tripped up

    • You still need to build the geometry. fSpy gives you the camera, not the scene. Once the camera is placed, the modeling, texturing, and lighting are on you. This node only automates the calibration step.
    • No yaw, no vanishing points. Because GeoCalib only estimates roll, pitch, and vfov, the transform has no heading and the vanishing points are null placeholders. For straight-on or slightly tilted shots that's usually fine; for dramatic angled shots you may need to nudge the camera in Blender afterward.
    • It's a JSON string, not a file. Nothing writes a .fspy for you. You save the output to disk (paste into a text file named something.fspy) and import that in Blender.

    Niche, yes. But if your thing is feeding generated images into a real 3D pipeline, this node collapses a tedious manual step into one wire.

    CategoryGeoCalib

    Inputs (5)

    NameTypeDefaultDescription
    image_widthINT19201–65536
    image_heightINT10801–65536
    rollFLOAT0.00-180–180
    pitchFLOAT0.00-90–90
    vfovFLOAT60.001–179

    Outputs (1)

    NameTypeDescription
    fspy_jsonSTRING