Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New software for intrinsics and rig calibration using a multiview acquisition of a checkerboard #1524

Merged
merged 15 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions BIBLIOGRAPHY.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,6 @@

[Bok] **Automated checkerboard detection and indexing using circular boundaries**
Yunsu Bok, Hyowon Ha, In So Kweon.

[Zhang] **A flexible new technique for camera calibration**
Zhengyou Zhang (1998).
4 changes: 2 additions & 2 deletions src/aliceVision/sfm/bundle/BundleAdjustmentCeres.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,8 @@ ceres::CostFunction* createRigCostFunctionFromIntrinsics(const IntrinsicBase* in
return new ceres::AutoDiffCostFunction<ResidualErrorFunctor_Pinhole3DEClassicLD, 2, 9, 6, 6, 3>(
new ResidualErrorFunctor_Pinhole3DEClassicLD(w, h, obsUndistorted));
case EINTRINSIC::PINHOLE_CAMERA_3DEANAMORPHIC4:
return new ceres::AutoDiffCostFunction<ResidualErrorFunctor_Pinhole3DEAnamorphic4, 2, 18, 6, 6, 3>(
new ResidualErrorFunctor_Pinhole3DEAnamorphic4(w, h, obsUndistorted));
return new ceres::AutoDiffCostFunction<ResidualErrorFunctor_Pinhole, 2, 4, 6, 6, 3>(
new ResidualErrorFunctor_Pinhole(w, h, obsUndistorted));
case EINTRINSIC::PINHOLE_CAMERA_BROWN:
return new ceres::AutoDiffCostFunction<ResidualErrorFunctor_PinholeBrownT2, 2, 9, 6, 6, 3>(
new ResidualErrorFunctor_PinholeBrownT2(w, h, obsUndistorted));
Expand Down
39 changes: 36 additions & 3 deletions src/aliceVision/sfmDataIO/sfmDataIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,40 @@ namespace sfmDataIO {
bool ValidIds(const sfmData::SfMData& sfmData, ESfMData partFlag)
{
const bool bCheck_Intrinsic = (partFlag & INTRINSICS);
const bool bCheck_Rig = (partFlag & EXTRINSICS);

// Collect intrinsic IDs declared
std::set<IndexT> intrinsicIdsDeclared;
transform(sfmData.getIntrinsics().begin(), sfmData.getIntrinsics().end(),
std::inserter(intrinsicIdsDeclared, intrinsicIdsDeclared.begin()), stl::RetrieveKey());

// Collect id_intrinsic referenced from views
// Collect rig IDs declared
std::set<IndexT> rigIdsDeclared;
transform(sfmData.getRigs().begin(), sfmData.getRigs().end(),
std::inserter(rigIdsDeclared, rigIdsDeclared.begin()), stl::RetrieveKey());

// Collect intrinsic IDs referenced from views
std::set<IndexT> intrinsicIdsReferenced;
for(const auto& v: sfmData.getViews())
{
const IndexT id_intrinsic = v.second.get()->getIntrinsicId();
intrinsicIdsReferenced.insert(id_intrinsic);
}

// We may have some views with undefined Intrinsics,
// Collect rig IDs referenced from views
std::set<IndexT> rigIdsReferenced;
for(const auto& v: sfmData.getViews())
{
const IndexT id_rig = v.second.get()->getRigId();
rigIdsReferenced.insert(id_rig);
}

// We may have some views with undefined intrinsic/rig,
// so erase the UndefinedIndex value if exist.
intrinsicIdsReferenced.erase(UndefinedIndexT);
rigIdsReferenced.erase(UndefinedIndexT);

// Check if defined intrinsic & extrinsic are at least connected to views
// Check if defined intrinsics are at least connected to views
bool bRet = true;
if(bCheck_Intrinsic && intrinsicIdsDeclared != intrinsicIdsReferenced)
{
Expand All @@ -64,6 +80,23 @@ bool ValidIds(const sfmData::SfMData& sfmData, ESfMData partFlag)
bRet = false; // error
}

// Check if defined rigs are at least connected to views
if(bCheck_Rig && rigIdsDeclared != rigIdsReferenced)
{
ALICEVISION_LOG_WARNING("The number of rigs is incoherent:");
ALICEVISION_LOG_WARNING(rigIdsDeclared.size() << " rigs declared and " << rigIdsReferenced.size() << " rigs used.");
std::set<IndexT> undefinedRigIds;
// undefinedRigIds = rigIdsReferenced - rigIdsDeclared
std::set_difference(rigIdsReferenced.begin(), rigIdsReferenced.end(),
rigIdsDeclared.begin(), rigIdsDeclared.end(),
std::inserter(undefinedRigIds, undefinedRigIds.begin()));
// If undefinedRigIds is not empty,
// some rigs are used in Views but never declared.
// So the file structure is invalid and may create troubles.
if(!undefinedRigIds.empty())
bRet = false; // error
}

return bRet;
}

Expand Down
16 changes: 16 additions & 0 deletions src/software/pipeline/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,22 @@ if(ALICEVISION_BUILD_SFM)
Boost::json
)

alicevision_add_software(aliceVision_checkerboardCalibration
SOURCE main_checkerboardCalibration.cpp
FOLDER ${FOLDER_SOFTWARE_PIPELINE}
LINKS aliceVision_dataio
aliceVision_image
aliceVision_calibration
aliceVision_system
aliceVision_cmdline
aliceVision_sfmDataIO
aliceVision_multiview
aliceVision_sfm
Boost::program_options
Boost::json
Boost::boost
)

# Calibrate a rig
alicevision_add_software(aliceVision_rigCalibration
SOURCE main_rigCalibration.cpp
Expand Down
Loading
Loading