Nodes/Atlas Camera/Atlas Multi-View Burst Solve πŸ“·πŸŽžοΈ
ComfyUI Node

Atlas Multi-View Burst Solve πŸ“·πŸŽžοΈ

A folder of frames becomes a calibrated rig

By mikejamesvfxΒ·Created 3 months agoΒ·Updated a day agoΒ· 1
Atlas Multi-View Burst Solve πŸ“·πŸŽžοΈ
    • solve
    • report
    • registration_json
    • match_overlays
    • anchor_image
    β—„burst_dirCameraRaw/burstβ–Ί
    β—„frame_stride1β–Ί
    β—„max_frames8β–Ί
    β—„half_sizetrueβ–Ί
    β—„capture_modeautoβ–Ί
    β—„camera_height_m0.00β–Ί
    β—„match_qualitybalancedβ–Ί
    β—„seed0β–Ί
    β—„learned_anchor_fallbackfalseβ–Ί
    β—„baseline_m0.00β–Ί
    β—„learned_scale_fallbackfalseβ–Ί
    β—„write_platestrueβ–Ί
    β—„plates_diratlas_exports/burst_platesβ–Ί
    β—„pair_topologyautoβ–Ί

    The sibling of AtlasMultiViewSolve - same registration engine, but instead of wiring images one at a time, you point this node at a folder of 2–16 frames and it recovers one deterministic camera rig from the whole burst. It's the πŸ“·πŸŽžοΈ node in Atlas/01 Β· Input & Camera, and it's the one you reach for after a handheld walk around the subject, phone in burst mode, or a drone orbit that gave you a dozen overlapping frames.

    Where the two-frame node is for deliberate, curated pairs, this is for "I shot a pile of frames and I want the rig out of all of them." The registration is the same engine as the explicit multi-view node - every selected file goes through the same RAW/JPEG import and the same solver - so the outputs are comparable and the same rules about scale apply.

    How it works

    Beyond three frames the solver switches to an anchor-star pair topology: every frame must share overlap with the first file in the folder (sorted by name), which is the natural shape of a walking burst - frame 1 sees the scene, and each subsequent frame overlaps both the anchor and its neighbours. frame_stride thins a dense burst (every Nth frame), max_frames caps how many actually feed the solver, and half_size (default on) halves the demosaic so 36 MP bursts iterate fast.

    The scale story is identical to the two-frame node: baseline_m, when set, is the measured distance between the first two selected frames - your one real metre stick that turns a normalized rig into a metric one. write_plates (default on) writes the developed frames to plates_dir as a side effect.

    Inputs and outputs

    Required: burst_dir - path to the folder of frames (default CameraRaw/burst).

    Optional: frame_stride, max_frames (2–16), half_size, capture_mode (auto/translated/rotation_only), camera_height_m, match_quality (balanced/conservative/permissive/salvage), seed, learned_anchor_fallback, baseline_m, learned_scale_fallback, write_plates, plates_dir, pair_topology.

    Outputs: solve, report, registration_json, match_overlays, and anchor_image - the anchor frame itself, handy for knowing which viewpoint the rig is anchored on.

    Installing it

    Core + vision, same as its sibling - a clone is enough:

    cd <ComfyUI>/custom_nodes
    git clone https://github.com/mikejamesvfx/atlas-camera.git
    

    Restart and it's in Atlas/01 Β· Input & Camera (ComfyUI Manager: "atlas-camera"). If your burst is RAW, add the [raw] extra so each frame gets the same developed decode the single-frame AtlasLoadRAW does.

    Common issues

    The anchor-star shape is the gotcha: every frame needs overlap with the first file in the folder, and "first" means sorted by filename. If your burst's first frame is a black frame or a shot of your feet, the whole topology is poisoned. Rename/sort so a good anchor frame sorts first, and keep the burst to frames that actually see the scene - sparse or disconnected shots just get rejected as unmatched.

    And don't expect rotation-only bursts to measure scale. If you spun in place, baseline_m and camera_height_m are your only anchors, and the result is inferred, not measured. The whole reason to shoot a burst is translation; give it some.

    CategoryAtlas/01 Β· Input & Camera

    Inputs (14)

    NameTypeDefaultDescription
    burst_dirSTRINGCameraRaw/burstβ€”
    frame_strideoptINT11–16β€”
    max_framesoptINT82–16β€”
    half_sizeoptBOOLEANtrueβ€”
    capture_modeoptCOMBOauto3 options: auto, translated, rotation_only
    camera_height_moptFLOAT0.00β€”
    match_qualityoptCOMBObalanced4 options: balanced, conservative, permissive, salvage
    seedoptINT00–18446744073709550000β€”
    learned_anchor_fallbackoptBOOLEANfalseβ€”
    baseline_moptFLOAT0.00β€”
    learned_scale_fallbackoptBOOLEANfalseβ€”
    write_platesoptBOOLEANtrueβ€”
    plates_diroptSTRINGatlas_exports/burst_platesβ€”
    pair_topologyoptCOMBOauto2 options: auto, anchor_star

    Outputs (5)

    NameTypeDescription
    solveATLAS_SOLVEβ€”
    reportSTRINGβ€”
    registration_jsonSTRINGβ€”
    match_overlaysIMAGEβ€”
    anchor_imageIMAGEβ€”