New node to generate sfmData views from folders#2064
New node to generate sfmData views from folders#2064servantftransperfect merged 1 commit intodevelopfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This pull request introduces a new command-line utility aliceVision_generateSfmData that generates SfMData files containing only view information from image files or directories. The PR also refactors view initialization logic by renaming updateIncompleteView to bootstrapView and introduces a new listImages utility function for recursive image discovery.
Changes:
- Added
aliceVision_generateSfmDatautility to create minimal SfMData files from image sets - Introduced
listImages()function for recursive image file discovery in directories - Refactored
updateIncompleteView()tobootstrapView()with improved code organization
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
src/software/utils/main_generateSfmData.cpp |
New command-line tool to generate SfMData from images; creates views with IDs and frame detection |
src/software/utils/CMakeLists.txt |
Build configuration for the new generateSfmData utility |
src/aliceVision/image/io.cpp |
Implementation of listImages() function for recursive image discovery |
src/aliceVision/image/io.hpp |
Declaration of listImages() function |
src/aliceVision/sfmDataIO/viewIO.cpp |
Refactored updateIncompleteView to bootstrapView with extracted helper function |
src/aliceVision/sfmDataIO/viewIO.hpp |
Updated function declaration for bootstrapView |
src/aliceVision/sfmData/View.hpp |
Added isFullySetup() method to check if view has minimal required identifiers |
src/software/pipeline/main_cameraInit.cpp |
Updated to use bootstrapView instead of updateIncompleteView |
src/aliceVision/sfmDataIO/jsonIO.cpp |
Updated to use bootstrapView instead of updateIncompleteView |
src/aliceVision/sfmDataIO/gtIO.cpp |
Updated to use bootstrapView instead of updateIncompleteView |
src/aliceVision/keyframe/KeyframeSelector.cpp |
Updated to use bootstrapView instead of updateIncompleteView |
meshroom/aliceVision/GenerateSfmData.py |
Python pipeline node definition for the new utility |
Comments suppressed due to low confidence (12)
src/aliceVision/sfmData/View.hpp:244
- The
isFullySetup()method should be marked asconstsince it does not modify the object state. This would allow it to be called on const View references and is consistent with best practices for getter methods.
bool isFullySetup()
src/aliceVision/image/io.cpp:1492
- When a file path is provided but it's not a supported image extension, the function should return
falseto indicate an error (similar to how it returnsfalsewhen the path is neither a file nor a directory). Currently, it falls through to check if it's a directory, which will fail for a file with an unsupported extension, but this is less clear. Add anelse { return false; }after line 1491 to handle this case explicitly.
if (fs::is_regular_file(paramPath))
{
if (isSupportedImageExtension(paramPath))
{
images.push_back(path);
return true;
}
}
src/aliceVision/image/io.cpp:1481
- The lambda
isSupportedImageExtensioniterates through all supported extensions for every file checked. For better performance, consider using astd::unordered_setfor O(1) lookups instead of O(n) linear search, especially when processing directories with many files.
auto isSupportedImageExtension = [&oiioExtensions](const fs::path& filePath) -> bool
{
std::string currentExtension = filePath.extension().string();
std::transform(currentExtension.begin(), currentExtension.end(), currentExtension.begin(), ::tolower);
for (const auto& oiioExtension : oiioExtensions)
{
if (oiioExtension == currentExtension)
{
return true;
}
}
return false;
};
src/aliceVision/sfmDataIO/viewIO.cpp:56
- The error message has an extra apostrophe before "to be used as viewId". The message should read "...in the filename " + filename + " to be used as viewId." without the apostrophe after filename.
ALICEVISION_LOG_ERROR("The Regex '" << viewIdRegex << "' must match a unique number in the filename " << filename << "' to be used as viewId.");
src/aliceVision/sfmDataIO/viewIO.hpp:63
- The documentation comment still refers to "update an incomplete view" which was the old function name
updateIncompleteView. Since the function was renamed tobootstrapView, the documentation should be updated to reflect the new name and purpose, such as "Initialize/bootstrap an incomplete view (at least with the image path)".
/**
* @brief update an incomplete view (at least only the image path)
* @param view The given incomplete view
* @param[in] viewIdMethod ViewId generation method to use
* @param[in] viewIdRegex Optional regex used when viewIdMethod is FILENAME
*/
src/aliceVision/sfmDataIO/viewIO.cpp:65
- There are two consecutive spaces between
isFullySetup()and the&&operator. This should be a single space for consistency with the rest of the codebase.
if (view.isFullySetup() && view.getImage().getHeight() > 0 && view.getImage().getWidth() > 0)
src/software/utils/main_generateSfmData.cpp:73
- After processing all input paths, there's no check for whether any images were found. If all input paths are invalid or no images are found, the code will create an empty SfMData file without warning the user. Consider adding a check after line 72 to validate that
allImagesItemsis not empty, and log a warning or error if no images were found.
std::vector<std::string> allImagesItems(allImages.begin(), allImages.end());
src/aliceVision/image/io.cpp:1512
- The
fs::recursive_directory_iteratorcan throw exceptions (e.g., for permission denied, symbolic link loops, or other filesystem errors). Consider wrapping the iteration in a try-catch block or using the error_code overload to handle potential errors gracefully instead of letting exceptions propagate.
for (const auto& entry : fs::recursive_directory_iterator(path))
{
if (!entry.is_regular_file())
{
continue;
}
if (isSupportedImageExtension(entry.path()))
{
images.push_back(entry.path().string());
}
}
src/software/utils/main_generateSfmData.cpp:58
- The loop variable
pathshould be captured by reference (const auto& path) to avoid unnecessary string copies for each iteration. This is a performance optimization that's standard practice when iterating over containers of non-trivial types.
for (const auto path : inputPaths)
src/aliceVision/sfmDataIO/viewIO.cpp:68
- The
bootstrapViewfunction checksview.isFullySetup()which requiresintrinsicId != UndefinedIndexT, butbootstrapViewnever sets the intrinsicId. This means that for views created by this tool (which start with intrinsicId = UndefinedIndexT), the early return condition will never be met, and the function will always read the image metadata even if the view is otherwise complete. While this may be intentional for this use case, consider documenting this behavior or adjusting the early return condition if metadata reading is the only missing piece.
if (view.isFullySetup() && view.getImage().getHeight() > 0 && view.getImage().getWidth() > 0)
{
return;
}
src/aliceVision/sfmDataIO/viewIO.cpp:57
- The error message has an extra apostrophe before "to be used as viewId". The message should read "...in the filename " + filename + " to be used as viewId." without the apostrophe after filename.
throw std::invalid_argument("The Regex '" + viewIdRegex + "' must match a unique number in the filename " + filename + "' to be used as viewId.");
src/software/utils/main_generateSfmData.cpp:43
- The command-line description incorrectly says "AliceVision maskEroding" instead of describing this generateSfmData tool. This should be updated to something like "AliceVision generateSfmData" to accurately reflect the purpose of this utility.
CmdLine cmdline("AliceVision maskEroding");
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
fabiencastan
left a comment
There was a problem hiding this comment.
I would name it "main_listImages".
generateSfmData looks like we are generating synthetic scenes for unit tests.
acd7949 to
4456840
Compare
4456840 to
ee215a8
Compare
This pull request introduces a new utility for generating SfMData files from sets of images, along with improvements to image discovery and view initialization logic throughout the codebase. The most important changes are grouped below by theme.
New SfMData Generation Utility
aliceVision_generateSfmDatacommand-line tool and corresponding pipeline node (GenerateSfmData.py,main_generateSfmData.cpp, and build integration), enabling users to generate an SfMData file from a set of image files or folders. Note that only views are generated with this node. No intrinsics, no colorspace management, etc. [1] [2] [3]Image Discovery Improvements
listImagesfunction inimage/io.cppandimage/io.hpp, which recursively finds all supported image files in a given directory or accepts a single file, improving image input handling for the new tool and other utilities. [1] [2]View Initialization Refactor
Replaced the
updateIncompleteViewfunction withbootstrapViewinviewIO.cppandviewIO.hpp, providing clearer logic for initializing views and ensuring minimal identifiers and metadata are set; updated all usages across the codebase. [1] [2] [3] [4] [5] [6] [7] [8]Added the
isFullySetupmethod to theViewclass, allowing checks for minimal required identifiers before processing, and used it in the refactored view initialization logic.Minor Code Cleanups
image/io.cppto improve organization and remove redundancy. [1] [2]These changes collectively provide a robust utility for generating SfMData from arbitrary sets of images, improve image input handling, and clarify the process of initializing views for SfM pipelines.