Skip to content

jhakrraman/Adaptive_Keyframe_Selection

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Adaptive Keyframe Selection

This repository contains the code for the paper "Adaptive Keyframe Selection for Scalable 3D Scene Reconstruction in Dynamic Environments," accepted at ROBOVIS 2026.

A lightweight, framework-agnostic front-end that decides online whether each incoming RGB-D frame should become a keyframe. It warps the most recent keyframe into the current view via depth-based reprojection, measures a hybrid photometric + structural (SSIM) error over the co-visible region, and thresholds it against a momentum-aware moving statistic so that redundant frames (static scenes, pure ego-motion) are skipped while genuinely novel or dynamic content triggers a keyframe. Pure NumPy + SciPy — no deep learning framework required, so it drops in front of pipelines such as Spann3r / CUT3R.

Files

File Description
adaptive_keyframe_selection.py Core method. Warping, hybrid error (Algorithm 1) and the momentum-aware selector (Algorithm 2). This is the only file you need to integrate.
demo_keyframe_selection.py Self-contained synthetic RGB-D demo (static → slow motion → fast motion → dynamic object). Runs the selector and saves a diagnostic plot.
keyframe_selection_demo.png Example output plot produced by the demo.

Requirements

numpy
scipy      # SSIM Gaussian window only
matplotlib # demo plot only
pip install numpy scipy matplotlib

Usage

Online (streaming) — the intended integration:

import numpy as np
from adaptive_keyframe_selection import AdaptiveKeyframeSelector

# intrinsics: 3x3 K ; pose: 4x4 camera-to-world ; depth in metric units
selector = AdaptiveKeyframeSelector(intrinsics_K)

for rgb, depth, pose in rgbd_stream:          # rgb (H,W,3) or (H,W); depth (H,W)
    if selector.update(rgb, depth, pose):     # -> bool
        reconstruction.add_keyframe(rgb, depth, pose)

print(f"KFCR = {selector.result.kfcr:.1f}%")  # compression ratio

Batch (offline) over a list of frames:

result = AdaptiveKeyframeSelector(intrinsics_K).run(frames)  # frames: [(rgb, depth, pose), ...]
print(result.keyframe_indices)   # selected frame indices (first frame always kept)
print(result.errors, result.thresholds)   # per-frame logs for analysis / plotting

Run the demo and the built-in geometry self-test:

python demo_keyframe_selection.py            # writes keyframe_selection_demo.png
python adaptive_keyframe_selection.py --test # validates the reprojection/warp math

Key hyperparameters

Constructor arguments map to the paper's symbols (defaults shown):

Argument Symbol Default Meaning
alpha, beta α, β 0.7, 0.3 photometric / structural weights (Eq. 3)
window_size W 5 sliding window for the moving statistics (Eq. 4–5)
sensitivity k 1.5 std multiplier in θ = μ + k·σ (Eq. 6)
decay γ 0.95 post-selection refractory factor (Eq. 7); set 1.0 to disable
base_threshold θ₀ 0.05 floor threshold — dataset-dependent, tune to your error scale
init_threshold θ_init 0.15 warm-up threshold before the window fills

Notes

  • base_threshold (θ₀) is dataset-dependent (grid-searched per dataset in the paper) and should be tuned to the scale of your images/depth. Defaults assume intensities in [0, 1].
  • Refractory decay (Eq. 7): taken literally, θ ← γ·θ (γ<1) lowers the threshold and has no lasting effect (θ is recomputed from the window each step). This implementation follows the described intent — after a selection the threshold is briefly raised and relaxes back by γ per frame, suppressing bursty selection. See the docstring for details; decay=1.0 turns it off.

About

[ROBOVIS 2026] Code for the Adaptive Keyframe Selection for Scalable 3D Scene Reconstruction in Dynamic Environments paper.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages