Skip to content

Commit

Permalink
Merge pull request #1524 from alicevision/mug/intrinsicsCalibration
Browse files Browse the repository at this point in the history
[software] new intrinsics calibration software
  • Loading branch information
cbentejac authored Oct 5, 2023
2 parents 2c9d45b + ef32a6c commit 4e5e57b
Show file tree
Hide file tree
Showing 6 changed files with 724 additions and 32 deletions.
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

0 comments on commit 4e5e57b

Please sign in to comment.