Nodes/ComfyUI-SplatKit/Load Dataset Images (Ordered)
ComfyUI Node

Load Dataset Images (Ordered)

Feed a temporal upscaler one coherent view at a time

By mickmumpitz·Created about a month ago·Updated about 19 hours ago· 17
Load Dataset Images (Ordered)
  • meta_batch
  • images
  • order_names
  • canonical_dir
  • group_sizes
  • batch_size
  • passthrough_json
  • job
dataset_namemy_scene
dataset_path
lowres_suffix_lowres
camera_index-1
on_size_mismatcherror
prepare_in_placefalse
select_every_nth1
drop_partial_stridefalse

A SphereSfM dataset's images are six cube faces per frame (front, back, left, right, up, down). If you load them in plain lexical order and hand them to a temporal upscaler like SeedVR2, the view direction flips six times per frame - the model sees a coherent bit of front wall, then sky, then floor, and its temporal context is worthless. Load Dataset Images (Ordered) fixes that by reading the dataset's p2s_dataset.json marker and loading each cube face as its own coherent per-view sub-video (camera-major order), so SeedVR2 gets a fixed view per sequence. This is the difference between upscaled frames that look like they came from the same camera and frames that look like six different videos stitched together.

It's also where you set the upscale's VRAM strategy. The generic loader + Meta Batch Manager pattern streams frames in chunks; this node's meta_batch input takes a VHS Batch Manager and streams frames_per_batch frames at a time instead of loading the whole dataset into RAM - the stated fix for "the upscaled result does not fit in RAM." Set frames_per_batch to a divisor of the per-view length (81 → 81, 27, 9, 3, 1) so no chunk straddles a view boundary.

Inputs that matter

  • dataset_name / dataset_path - the SphereSfM dataset, same as the other upscale nodes.
  • camera_index - -1 loads all cameras; 0..N-1 loads one view/trajectory's sub-video. The console lists available cameras each run.
  • select_every_nth / drop_partial_stride - thin the sequence inside each view group (never across the flat list), so the loop still sees coherent sub-videos. The warning in the tooltip is real: skipped frames are not written by the saver while sparse/0/images.bin still registers them - reconcile with tools/stride_dataset.py (--mode prune or --mode keep-lowres) before training.
  • on_size_mismatch - default error (a batch needs one size). resize_and_passthrough resizes the odd images down and lists them on passthrough_json - frame 00000 is usually the original panorama, a separate larger COLMAP camera, and gets passed through untouched.
  • prepare_in_place - does the originals-preserving swap (images → images_lowres) here before the first read, if you want an in-place COLMAP upscale without a separate Prepare node.

Outputs

images (camera-major batch of pristine originals), order_names (JSON list of filenames in exact loaded order - wire into the Save node so each upscaled frame maps back to its filename), canonical_dir (the COLMAP images folder), group_sizes (per-view lengths), batch_size, passthrough_json, and job - which bundles everything the streaming saver needs down one link.

Install & gotchas

cd ComfyUI/custom_nodes
git clone https://github.com/mickmumpitz/ComfyUI-SplatKit
python_embeded\python.exe -m pip install -r ComfyUI-SplatKit/requirements.txt

Restart; the pack's requirements (opencv, trimesh, etc.) are light and this node needs nothing else - your upscaler does. The one footgun: don't wire the loader's batch_size output into the Batch Manager that drives it - that's a dependency cycle ComfyUI refuses, which is exactly why the separate DatasetUpscalePlan node exists.

CategorySplatKit

Inputs (9)

NameTypeDefaultDescription
dataset_nameSTRINGmy_sceneName of the SphereSfM dataset folder under ComfyUI/output.
dataset_pathoptSTRINGOptional explicit path to the dataset root or images folder. Overrides dataset_name.
lowres_suffixoptSTRING_lowresOriginals-folder suffix; must match the Save node's suffix.
camera_indexoptINT-1-1–4096-1 = load all cameras. 0..N-1 = load only that camera's sub-video (one coherent view/trajectory). The console lists the available cameras on each run.
meta_batchoptVHS_BatchManagerOptional VHS Meta Batch Manager. When wired, the camera-major sequence is STREAMED frames_per_batch frames at a time instead of loaded whole -- the fix for 'the upscaled result does not fit in RAM'. Set frames_per_batch to a divisor of the per-view length (81 -> 81, 27, 9, 3, 1) so no chunk straddles a view boundary. The order_names / canonical_dir outputs stay whole-dataset.
on_size_mismatchoptCOMBOerrorWhat to do when the folder holds more than one image size. error: refuse (a batch needs one size). resize_and_passthrough: resize the odd images DOWN to the majority size so they still give the temporal model its context, and list them on the passthrough_json output. Frame 00000 is normally the ORIGINAL panorama (a separate, larger COLMAP camera) -- wire passthrough_json into Save Upscaled Frames (Streaming) and its untouched original is copied to the output instead of the generated upscale.
prepare_in_placeoptBOOLEANfalseDo the originals-preserving swap here, before the first read: images/ -> images_lowres/ (once, atomically) and a fresh empty images/ for the saver to fill. Idempotent, so a re-run renames nothing. Turn this ON for an in-place COLMAP dataset upscale and you do not need a separate Prepare node.
select_every_nthoptINT11–1000Thin the sequence: keep every Nth frame. Applied INSIDE each view group, never across the flat list -- 24 views of 81 at N=3 become 24 views of 27, so no chunk ever straddles a view boundary and the loop still sees coherent sub-videos. Counting starts at each view's first frame, so frame 00000 (the real panorama) is always kept. group_sizes and suggested_batch_size are recomputed for you. WARNING: the skipped frames are then NOT written by the saver, while sparse/0/images.bin still registers them. Reconcile the dataset afterwards with tools/stride_dataset.py (--mode prune or --mode keep-lowres) before training on it.
drop_partial_strideoptBOOLEANfalseWhat to do with the frame that falls out of the stride. 81 frames at N=5 is 16 complete 5-frame windows plus 1 leftover: off keeps it (17 per view), on omits it (16 per view). CAUTION: 17 is 4n+1 so it can be one clean SeedVR2 batch, while 16's only 4n+1 divisor is 1 -- turning this on can collapse suggested_batch_size to 1 and cost you all temporal context. Check the printed suggested_batch_size after changing it, and match tools/stride_dataset.py --drop-partial.

Outputs (7)

NameTypeDescription
imagesIMAGE
order_namesSTRING
canonical_dirSTRING
group_sizesSTRING
batch_sizeINT
passthrough_jsonSTRING
jobSTRING