Skip to content

Commit

Permalink
Add lock for scale and offset and distortion
Browse files Browse the repository at this point in the history
  • Loading branch information
servantftechnicolor authored and cbentejac committed Sep 9, 2024
1 parent fc17c88 commit 6bd0438
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 40 deletions.
6 changes: 6 additions & 0 deletions src/aliceVision/camera/Distortion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,16 @@ class Distortion

virtual Eigen::MatrixXd getDerivativeRemoveDistoWrtDisto(const Vec2& p) const { return Eigen::MatrixXd(0, 0); }

inline void setLocked(bool lock) { _isLocked = lock; }

inline bool isLocked() const { return _isLocked; }

virtual ~Distortion() = default;


protected:
std::vector<double> _distortionParams{};
bool _isLocked{false};
};

} // namespace camera
Expand Down
18 changes: 18 additions & 0 deletions src/aliceVision/camera/IntrinsicScaleOffset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,22 @@ class IntrinsicScaleOffset : public IntrinsicBase

inline bool isRatioLocked() const { return _ratioLocked; }

/**
* @brief Lock the offset
* @param lock True if the offset is locked, false otherwise
*/
inline void setOffsetLocked(bool lock) { _offsetLocked = lock; }

inline bool isOffsetLocked() const { return _offsetLocked; }

/**
* @brief Lock the scale
* @param lock True if the scale is locked, false otherwise
*/
inline void setScaleLocked(bool lock) { _scaleLocked = lock; }

inline bool isScaleLocked() const { return _scaleLocked; }

/**
* @brief get focal length in mm
* @return focal length in mm
Expand All @@ -123,6 +139,8 @@ class IntrinsicScaleOffset : public IntrinsicBase
Vec2 _offset{0.0, 0.0};
Vec2 _initialScale{-1.0, -1.0};
bool _ratioLocked{true};
bool _offsetLocked{false};
bool _scaleLocked{false};
};

} // namespace camera
Expand Down
56 changes: 36 additions & 20 deletions src/aliceVision/sfm/bundle/BundleAdjustmentCeres.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,13 @@ void BundleAdjustmentCeres::addIntrinsicsToProblem(const sfmData::SfMData& sfmDa
continue;
}

std::shared_ptr<camera::IntrinsicScaleOffset> intrinsicScaleOffset =
std::dynamic_pointer_cast<camera::IntrinsicScaleOffset>(intrinsicPtr);
if (!intrinsicScaleOffset)
{
continue;
}

assert(isValid(intrinsicPtr->getType()));

std::vector<double>& intrinsicBlock = _intrinsicsBlocks[intrinsicId];
Expand Down Expand Up @@ -559,11 +566,11 @@ void BundleAdjustmentCeres::addIntrinsicsToProblem(const sfmData::SfMData& sfmDa
bool lockDistortion = false;
double focalRatio = 1.0;

lockFocal = (!refineIntrinsicsFocalLength) || intrinsicScaleOffset->isScaleLocked();

// refine the focal length
if (refineIntrinsicsFocalLength)
if (lockFocal)
{
std::shared_ptr<camera::IntrinsicScaleOffset> intrinsicScaleOffset =
std::dynamic_pointer_cast<camera::IntrinsicScaleOffset>(intrinsicPtr);
if (intrinsicScaleOffset->getInitialScale().x() > 0 && intrinsicScaleOffset->getInitialScale().y() > 0)
{

Expand Down Expand Up @@ -593,22 +600,22 @@ void BundleAdjustmentCeres::addIntrinsicsToProblem(const sfmData::SfMData& sfmDa
}

focalRatio = intrinsicBlockPtr[0] / intrinsicBlockPtr[1];
std::shared_ptr<camera::IntrinsicScaleOffset> castedcam_iso = std::dynamic_pointer_cast<camera::IntrinsicScaleOffset>(intrinsicPtr);
if (castedcam_iso)
{
lockRatio = castedcam_iso->isRatioLocked();
}
lockRatio = intrinsicScaleOffset->isRatioLocked();
}
else

// optical center
lockCenter = intrinsicScaleOffset->isOffsetLocked();

bool validRefineCenter = (refineOptions & REFINE_INTRINSICS_OPTICALOFFSET_ALWAYS) ||
((refineOptions & REFINE_INTRINSICS_OPTICALOFFSET_IF_ENOUGH_DATA)
&& _minNbImagesToRefineOpticalCenter > 0
&& usageCount >= _minNbImagesToRefineOpticalCenter);
if (!validRefineCenter)
{
// set focal length as constant
lockFocal = true;
lockCenter = true;
}

// optical center
if ((refineOptions & REFINE_INTRINSICS_OPTICALOFFSET_ALWAYS) ||
((refineOptions & REFINE_INTRINSICS_OPTICALOFFSET_IF_ENOUGH_DATA) && _minNbImagesToRefineOpticalCenter > 0 &&
usageCount >= _minNbImagesToRefineOpticalCenter))
if (!lockCenter)
{
// refine optical center within 10% of the image size.
assert(intrinsicBlock.size() >= 3);
Expand All @@ -622,18 +629,27 @@ void BundleAdjustmentCeres::addIntrinsicsToProblem(const sfmData::SfMData& sfmDa
problem.SetParameterLowerBound(intrinsicBlockPtr, 3, opticalCenterMinPercent * intrinsicPtr->h());
problem.SetParameterUpperBound(intrinsicBlockPtr, 3, opticalCenterMaxPercent * intrinsicPtr->h());
}
else
{
// don't refine the optical center
lockCenter = true;
}

// lens distortion
if (!refineIntrinsicsDistortion || intrinsicPtr->getDistortionInitializationMode() == camera::EInitMode::CALIBRATED)
{
lockDistortion = true;
}

//Check if this particular distortion is locked
std::shared_ptr<camera::IntrinsicScaleOffsetDisto> intrinsicScaleOffsetDisto =
std::dynamic_pointer_cast<camera::IntrinsicScaleOffsetDisto>(intrinsicPtr);
if (intrinsicScaleOffsetDisto)
{
if (intrinsicScaleOffsetDisto->getDistortion())
{
if (intrinsicScaleOffsetDisto->getDistortion()->isLocked())
{
lockDistortion = true;
}
}
}

IntrinsicsManifold* subsetManifold =
new IntrinsicsManifold(intrinsicBlock.size(), focalRatio, lockFocal, lockRatio, lockCenter, lockDistortion);
problem.SetManifold(intrinsicBlockPtr, subsetManifold);
Expand Down
54 changes: 36 additions & 18 deletions src/aliceVision/sfm/bundle/BundleAdjustmentSymbolicCeres.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,13 @@ void BundleAdjustmentSymbolicCeres::addIntrinsicsToProblem(const sfmData::SfMDat
continue;
}

std::shared_ptr<camera::IntrinsicScaleOffset> intrinsicScaleOffset =
std::dynamic_pointer_cast<camera::IntrinsicScaleOffset>(intrinsicPtr);
if (!intrinsicScaleOffset)
{
continue;
}

assert(isValid(intrinsicPtr->getType()));

_intrinsicObjects[intrinsicId].reset(intrinsicPtr->clone());
Expand Down Expand Up @@ -377,8 +384,10 @@ void BundleAdjustmentSymbolicCeres::addIntrinsicsToProblem(const sfmData::SfMDat
bool lockDistortion = false;
double focalRatio = 1.0;

lockFocal = (!refineIntrinsicsFocalLength) || intrinsicScaleOffset->isScaleLocked();

// refine the focal length
if (refineIntrinsicsFocalLength)
if (!lockFocal)
{
std::shared_ptr<camera::IntrinsicScaleOffset> intrinsicScaleOffset =
std::dynamic_pointer_cast<camera::IntrinsicScaleOffset>(intrinsicPtr);
Expand Down Expand Up @@ -410,22 +419,22 @@ void BundleAdjustmentSymbolicCeres::addIntrinsicsToProblem(const sfmData::SfMDat
}

focalRatio = intrinsicBlockPtr[0] / intrinsicBlockPtr[1];

std::shared_ptr<camera::IntrinsicScaleOffset> castedcam_iso = std::dynamic_pointer_cast<camera::IntrinsicScaleOffset>(intrinsicPtr);
if (castedcam_iso)
{
lockRatio = castedcam_iso->isRatioLocked();
}
lockRatio = intrinsicScaleOffset->isRatioLocked();
}
else

// optical center
lockCenter = intrinsicScaleOffset->isOffsetLocked();

bool validRefineCenter = (refineOptions & REFINE_INTRINSICS_OPTICALOFFSET_ALWAYS) ||
((refineOptions & REFINE_INTRINSICS_OPTICALOFFSET_IF_ENOUGH_DATA)
&& _minNbImagesToRefineOpticalCenter > 0
&& usageCount >= _minNbImagesToRefineOpticalCenter);
if (!validRefineCenter)
{
// set focal length as constant
lockFocal = true;
lockCenter = true;
}

const bool optional_center =
((refineOptions & REFINE_INTRINSICS_OPTICALOFFSET_IF_ENOUGH_DATA) && (usageCount > _minNbImagesToRefineOpticalCenter));
if ((refineOptions & REFINE_INTRINSICS_OPTICALOFFSET_ALWAYS) || optional_center)
if (!lockCenter)
{
// refine optical center within 10% of the image size.
assert(intrinsicBlock.size() >= 4);
Expand All @@ -439,18 +448,27 @@ void BundleAdjustmentSymbolicCeres::addIntrinsicsToProblem(const sfmData::SfMDat
problem.SetParameterLowerBound(intrinsicBlockPtr, 3, opticalCenterMinPercent * intrinsicPtr->h());
problem.SetParameterUpperBound(intrinsicBlockPtr, 3, opticalCenterMaxPercent * intrinsicPtr->h());
}
else
{
// don't refine the optical center
lockCenter = true;
}

// lens distortion
if (!refineIntrinsicsDistortion)
{
lockDistortion = true;
}

//Check if this particular distortion is locked
std::shared_ptr<camera::IntrinsicScaleOffsetDisto> intrinsicScaleOffsetDisto =
std::dynamic_pointer_cast<camera::IntrinsicScaleOffsetDisto>(intrinsicPtr);
if (intrinsicScaleOffsetDisto)
{
if (intrinsicScaleOffsetDisto->getDistortion())
{
if (intrinsicScaleOffsetDisto->getDistortion()->isLocked())
{
lockDistortion = true;
}
}
}

IntrinsicsManifold* subsetManifold =
new IntrinsicsManifold(intrinsicBlock.size(), focalRatio, lockFocal, lockRatio, lockCenter, lockDistortion);
problem.SetManifold(intrinsicBlockPtr, subsetManifold);
Expand Down
3 changes: 3 additions & 0 deletions src/aliceVision/sfmDataIO/AlembicExporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ void AlembicExporter::DataImpl::addCamera(const std::string& name,
ODoubleProperty(userProps, "mvg_initialFocalLength").set(initialFocalLength);
OBoolProperty(userProps, "mvg_intrinsicLocked").set(intrinsicCasted->isLocked());
OBoolProperty(userProps, "mvg_intrinsicPixelRatioLocked").set(intrinsicCasted->isRatioLocked());
OBoolProperty(userProps, "mvg_intrinsicOffsetLocked").set(intrinsicCasted->isOffsetLocked());
OBoolProperty(userProps, "mvg_intrinsicScaleLocked").set(intrinsicCasted->isOffsetLocked());
OStringProperty(userProps, "mvg_intrinsicDistortionInitializationMode")
.set(camera::EInitMode_enumToString(intrinsicCasted->getDistortionInitializationMode()));

Expand All @@ -246,6 +248,7 @@ void AlembicExporter::DataImpl::addCamera(const std::string& name,
{
distortionType = distortion->getType();
ODoubleArrayProperty(userProps, "mvg_distortionParams").set(distortion->getParameters());
OBoolProperty(userProps, "mvg_distortionLocked").set(distortion->isLocked());
}

// Undistortion parameters and offset
Expand Down
24 changes: 23 additions & 1 deletion src/aliceVision/sfmDataIO/AlembicImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,9 @@ bool readCamera(const Version& abcVersion,
bool poseLocked = false;
bool poseIndependant = true;
bool lockRatio = true;
bool lockOffset = false;
bool lockScale = false;
bool lockDistortion = false;
std::vector<double> distortionParams;
std::vector<double> undistortionParams;
Vec2 undistortionOffset = {0, 0};
Expand Down Expand Up @@ -469,6 +472,14 @@ bool readCamera(const Version& abcVersion,
{
lockRatio = getAbcProp<Alembic::Abc::IBoolProperty>(userProps, *propHeader, "mvg_intrinsicPixelRatioLocked", sampleFrame);
}
if (const Alembic::Abc::PropertyHeader* propHeader = userProps.getPropertyHeader("mvg_intrinsicOffsetLocked"))
{
lockOffset = getAbcProp<Alembic::Abc::IBoolProperty>(userProps, *propHeader, "mvg_intrinsicOffsetLocked", sampleFrame);
}
if (const Alembic::Abc::PropertyHeader* propHeader = userProps.getPropertyHeader("mvg_intrinsicScaleLocked"))
{
lockScale = getAbcProp<Alembic::Abc::IBoolProperty>(userProps, *propHeader, "mvg_intrinsicScaleLocked", sampleFrame);
}
if (const Alembic::Abc::PropertyHeader* propHeader = userProps.getPropertyHeader("mvg_poseLocked"))
{
poseLocked = getAbcProp<Alembic::Abc::IBoolProperty>(userProps, *propHeader, "mvg_poseLocked", sampleFrame);
Expand Down Expand Up @@ -577,6 +588,10 @@ bool readCamera(const Version& abcVersion,
prop.get(sample, ISampleSelector(sampleFrame));
distortionParams.assign(sample->get(), sample->get() + sample->size());
}
if (const Alembic::Abc::PropertyHeader* propHeader = userProps.getPropertyHeader("mvg_distortionLocked"))
{
lockDistortion = getAbcProp<Alembic::Abc::IBoolProperty>(userProps, *propHeader, "mvg_distortionLocked", sampleFrame);
}
if (userProps.getPropertyHeader("mvg_undistortionParams"))
{
// Undistortion parameters
Expand Down Expand Up @@ -656,11 +671,18 @@ bool readCamera(const Version& abcVersion,
(initialFocalLengthPix(0) > 0) ? initialFocalLengthPix(0) * mvg_intrinsicParams[1] / mvg_intrinsicParams[0] : -1;
intrinsicCasted->setInitialScale(initialFocalLengthPix);
intrinsicCasted->setRatioLocked(lockRatio);
intrinsicCasted->setOffsetLocked(lockOffset);
intrinsicCasted->setScaleLocked(lockScale);

std::shared_ptr<camera::Distortion> distortion = intrinsicCasted->getDistortion();
if (distortion)
{
distortion->setParameters(distortionParams);
distortion->setParameters(distortionParams);

if (abcVersion >= Version(1, 2, 10))
{
distortion->setLocked(lockDistortion);
}
}

std::shared_ptr<camera::Undistortion> undistortion = intrinsicCasted->getUndistortion();
Expand Down
17 changes: 17 additions & 0 deletions src/aliceVision/sfmDataIO/jsonIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ void saveIntrinsic(const std::string& name, IndexT intrinsicId, const std::share

intrinsicTree.put("pixelRatio", pixelRatio);
intrinsicTree.put("pixelRatioLocked", intrinsicScaleOffset->isRatioLocked());
intrinsicTree.put("offsetLocked", intrinsicScaleOffset->isOffsetLocked());
intrinsicTree.put("scaleLocked", intrinsicScaleOffset->isScaleLocked());


saveMatrix("principalPoint", intrinsicScaleOffset->getOffset(), intrinsicTree);
}
Expand All @@ -197,7 +200,10 @@ void saveIntrinsic(const std::string& name, IndexT intrinsicId, const std::share
paramTree.put("", param);
distParamsTree.push_back(std::make_pair("", paramTree));
}

intrinsicTree.put("distortionLocked", distortionObject->isLocked());
}

intrinsicTree.put("distortionInitializationMode",
camera::EInitMode_enumToString(intrinsicScaleOffsetDisto->getDistortionInitializationMode()));

Expand Down Expand Up @@ -360,6 +366,12 @@ void loadIntrinsic(const Version& version, IndexT& intrinsicId, std::shared_ptr<
intrinsicWithScale->setInitialScale(initialFocalLengthPx);
intrinsicWithScale->setRatioLocked(intrinsicTree.get<bool>("pixelRatioLocked"));
}

if (version >= Version(1, 2, 10))
{
intrinsicWithScale->setOffsetLocked(intrinsicTree.get<bool>("offsetLocked"));
intrinsicWithScale->setScaleLocked(intrinsicTree.get<bool>("scaleLocked"));
}
}

// Load distortion
Expand Down Expand Up @@ -416,6 +428,11 @@ void loadIntrinsic(const Version& version, IndexT& intrinsicId, std::shared_ptr<
{
distortionObject->setParameters(distortionParams);
}

if (version >= Version(1, 2, 10))
{
distortionObject->setLocked(intrinsicTree.get<bool>("distortionLocked"));
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/aliceVision/sfmDataIO/sfmDataIO.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

#define ALICEVISION_SFMDATAIO_VERSION_MAJOR 1
#define ALICEVISION_SFMDATAIO_VERSION_MINOR 2
#define ALICEVISION_SFMDATAIO_VERSION_REVISION 9
#define ALICEVISION_SFMDATAIO_VERSION_REVISION 10

// AliceVision version as a string; for example "0.9.0".
#define ALICEVISION_SFMDATAIO_VERSION_STRING \
Expand Down

0 comments on commit 6bd0438

Please sign in to comment.