Skip to content

Conversation

@CedricThebault
Copy link
Member

This pull request introduces a temporal smoothness constraint to the bundle adjustment process in the Structure-from-Motion (SfM) pipeline. The main changes add new parameters for temporal constraints, update the bundle adjustment implementation to support these constraints, and provide more granular evaluation and debugging capabilities. The changes also include a minor addition of a random noise variance option per view in track simulation.

Key changes:

Temporal Smoothness Constraint Integration

  • Added a new TemporalConstraintParams struct and corresponding parameters (e.g., position/ orientation weights, regularization weights) to configure temporal smoothness constraints in bundle adjustment (BundleAdjustment.hpp, BundleAdjustmentCeres.hpp). [1] [2]
  • Introduced a new refinement option flag REFINE_TEMPORAL_SMOOTHNESS_CONSTRAINT to enable temporal constraints during optimization (BundleAdjustment.hpp).
  • Implemented the logic to add temporal smoothness constraints as residual blocks in the Ceres problem, including support for regularization and evaluation of these constraints separately (BundleAdjustmentCeres.cpp). [1] [2] [3] [4] [5] [6]

User Interface and Parameterization

  • Extended the SfMExpanding node with new parameters to control temporal constraints (e.g., enable/disable, weights for position/orientation, regularization, and debug option to exit after pose interpolation). These parameters are only enabled if temporal constraints are active (SfmExpanding.py).

Evaluation and Debugging Enhancements

  • Modified the bundle adjustment process to separately track and log costs for landmark and temporal constraint residual blocks, aiding in debugging and analysis (BundleAdjustmentCeres.cpp). [1] [2]

Track Simulation

  • Added an advanced parameter to optionally use random noise variance per view in the TracksSimulating node (TracksSimulating.py).

Infrastructure and Minor Fixes

  • Updated function signatures and internal logic to pass and manage residual block IDs for more granular control over Ceres problem components (BundleAdjustmentCeres.cpp). [1] [2] [3] [4] [5]
  • Included necessary headers for temporal constraints and pose filtering (BundleAdjustmentCeres.cpp).

These changes collectively enable temporal regularization in SfM bundle adjustment, providing greater flexibility and control for handling sequential data, such as video frames, and improving the robustness and quality of the resulting reconstructions.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request introduces temporal smoothness constraints to the bundle adjustment process in the Structure-from-Motion (SfM) pipeline, enabling better handling of sequential data such as video frames. The implementation adds new cost functions that constrain camera pose trajectories to be smooth over time, along with configuration parameters and debugging capabilities.

Key changes:

  • Adds temporal constraint cost functions supporting C0 (continuity), C1 (velocity), and C2 (acceleration) smoothness with configurable weights
  • Implements pose interpolation to fill missing poses using temporal filtering before bundle adjustment
  • Extends the SfM expanding node with new UI parameters for temporal constraint configuration
  • Adds separate cost evaluation and logging for landmark and temporal constraint residuals

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 24 comments.

Show a summary per file
File Description
src/aliceVision/sfm/bundle/costfunctions/temporalConstraint.hpp New file implementing temporal constraint cost functors and regularization terms
src/aliceVision/sfm/bundle/BundleAdjustment.hpp Adds TemporalConstraintParams struct and REFINE_TEMPORAL_SMOOTHNESS_CONSTRAINT flag
src/aliceVision/sfm/bundle/BundleAdjustmentCeres.hpp Updates function signatures to support temporal constraints and separate residual block tracking
src/aliceVision/sfm/bundle/BundleAdjustmentCeres.cpp Implements temporal constraint integration, residual block ID tracking, and separate cost evaluation
src/aliceVision/sfm/pipeline/expanding/SfmBundle.hpp Adds temporal constraint parameter storage and configuration methods
src/aliceVision/sfm/pipeline/expanding/SfmBundle.cpp Integrates pose interpolation and temporal constraints into the bundle adjustment workflow
src/aliceVision/sfm/utils/poseFilter.hpp Adds interpolateMissingPoses method and updates filter signature
src/aliceVision/sfm/utils/poseFilter.cpp Implements pose interpolation and helper functions for ordered pose retrieval
src/software/pipeline/main_sfmExpanding.cpp Adds CLI parameters for temporal constraint configuration
src/software/utils/main_tracksSimulating.cpp Adds random noise variance per view option for track simulation
src/aliceVision/sfmDataIO/sceneSample.cpp Updates sphere scene generation with observations and modified focal lengths
meshroom/aliceVision/SfmExpanding.py Adds UI parameters for temporal constraint weights and debugging options
meshroom/aliceVision/TracksSimulating.py Adds UI parameter for random noise variance per view

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

desc.FloatParam(
name="tscC2positionWeight",
label="Temporal Constraint C2 Position Weight",
description="",
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty description field for user-facing parameter. Add a meaningful description explaining what C2 (second derivative/acceleration) position weight controls.

Suggested change
description="",
description="Controls the influence of the second derivative (acceleration) of camera position in temporal constraints. Higher values enforce smoother changes in acceleration between consecutive frames.",

Copilot uses AI. Check for mistakes.
continue;
}

std::cout << point3D.transpose() << " -- " << landmark.X.transpose() << std::endl;
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug std::cout statement should be removed. This appears to be leftover debug code that prints landmark coordinates for every landmark and view combination, which could produce excessive output for large scenes (1000 points × 240 poses = 240,000 lines). Either remove this line or replace it with a conditional debug log.

Suggested change
std::cout << point3D.transpose() << " -- " << landmark.X.transpose() << std::endl;

Copilot uses AI. Check for mistakes.
Comment on lines +834 to +835
ALICEVISION_LOG_WARNING("Unable to get ordered frameIDs.");
throw std::runtime_error("Unable to get ordered frameIDs.");
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent error messages. Line 834 logs "Unable to get ordered frameIDs" as a warning, and then line 835 throws an exception with the same message. Either the warning is redundant (if we're throwing anyway), or the message should be more specific. Consider:

ALICEVISION_LOG_ERROR("Unable to get ordered frameIDs for temporal constraints.");
throw std::runtime_error("Unable to get ordered frameIDs for temporal constraints.");
Suggested change
ALICEVISION_LOG_WARNING("Unable to get ordered frameIDs.");
throw std::runtime_error("Unable to get ordered frameIDs.");
ALICEVISION_LOG_ERROR("Unable to get ordered frameIDs for temporal constraints.");
throw std::runtime_error("Unable to get ordered frameIDs for temporal constraints.");

Copilot uses AI. Check for mistakes.
desc.FloatParam(
name="tscC0orientationWeight",
label="Temporal Constraint C0 Orientation Weight",
description="",
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty description field for user-facing parameter. Add a meaningful description explaining what C0 (continuity) orientation weight controls.

Suggested change
description="",
description="Weight for enforcing C0 (continuity) in camera orientation between consecutive frames. Higher values increase the smoothness of orientation transitions.",

Copilot uses AI. Check for mistakes.
desc.FloatParam(
name="tscC1orientationWeight",
label="Temporal Constraint C1 Orientation Weight",
description="",
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty description field for user-facing parameter. Add a meaningful description explaining what C1 (first derivative/velocity) orientation weight controls.

Suggested change
description="",
description="Weight for enforcing smoothness of camera orientation changes (first derivative/velocity) over time.",

Copilot uses AI. Check for mistakes.
desc.FloatParam(
name="tscC2orientationWeight",
label="Temporal Constraint C2 Orientation Weight",
description="",
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty description field for user-facing parameter. Add a meaningful description explaining what C2 (second derivative/acceleration) orientation weight controls.

Suggested change
description="",
description="Weight for the temporal constraint on the second derivative (acceleration) of camera orientation. Higher values enforce smoother changes in orientation over time, reducing abrupt rotational accelerations between consecutive frames.",

Copilot uses AI. Check for mistakes.
std::shared_ptr<camera::Pinhole> camPinHole = std::dynamic_pointer_cast<camera::Pinhole>(cam);
if (!camPinHole)
{
std::cout << "Camera is not pinhole in getInputRigScene" << std::endl;
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error message contains incorrect function name. The message says "getInputRigScene" but this is in the function generateSphereScene. The error message should be:

std::cout << "Camera is not pinhole in generateSphereScene" << std::endl;

Also consider using ALICEVISION_LOG_ERROR for consistency with the rest of the codebase instead of std::cout.

Copilot uses AI. Check for mistakes.
desc.FloatParam(
name="tscPositionWeight",
label="Temporal Constraint Position Weight",
description="",
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty description field for user-facing parameter. All the temporal constraint weight parameters (lines 89, 98, 107, 116, 125, 134, 143, 152, 161) have empty descriptions. Users will not understand what these parameters control without documentation. Add meaningful descriptions explaining what each weight controls (C0 = continuity, C1 = velocity, C2 = acceleration constraints).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants