Skip to content

Commit

Permalink
Merge pull request #1610 from alicevision/dev/applyCalibrationOpenGate
Browse files Browse the repository at this point in the history
ApplyCalibration: Lens Calibration is done on Open Gate plates, but camera tracking could be done on cropped plates
  • Loading branch information
fabiencastan authored Mar 13, 2024
2 parents ba9615b + 49871da commit a960bdf
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 7 deletions.
10 changes: 10 additions & 0 deletions src/aliceVision/camera/Undistortion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,20 @@ class Undistortion
_center = {width / 2, height / 2};
}

void setDiagonal(double diagonal)
{
//May be used for plates with a different size than lens grid
_diagonal = diagonal;
}

inline Vec2 getOffset() const { return _offset; }

Vec2 getSize() const { return _size; }

inline double getDiagonal() const { return _diagonal; }



const std::vector<double>& getParameters() const { return _undistortionParams; }

void setParameters(const std::vector<double>& params)
Expand Down
1 change: 1 addition & 0 deletions src/aliceVision/sfmDataIO/AlembicExporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ void AlembicExporter::DataImpl::addCamera(const std::string& name,
ODoubleArrayProperty(userProps, "mvg_undistortionParams").set(undistortion->getParameters());
ODoubleProperty(userProps, "mvg_undistortionOffsetX").set(undistortion->getOffset().x());
ODoubleProperty(userProps, "mvg_undistortionOffsetY").set(undistortion->getOffset().y());
ODoubleProperty(userProps, "mvg_undistortionDiagonal").set(undistortion->getDiagonal());
}

camObj.getSchema().set(camSample);
Expand Down
11 changes: 11 additions & 0 deletions src/aliceVision/sfmDataIO/AlembicImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ bool readCamera(const Version& abcVersion,
std::vector<double> distortionParams;
std::vector<double> undistortionParams;
Vec2 undistortionOffset = {0, 0};
double undistortionDiagonal = 0.0;

if (userProps)
{
Expand Down Expand Up @@ -579,6 +580,10 @@ bool readCamera(const Version& abcVersion,
{
undistortionOffset(1) = getAbcProp<Alembic::Abc::IDoubleProperty>(userProps, *propHeader, "mvg_undistortionOffsetY", sampleFrame);
}
if (const Alembic::Abc::PropertyHeader* propHeader = userProps.getPropertyHeader("mvg_undistortionDiagonal"))
{
undistortionDiagonal = getAbcProp<Alembic::Abc::IDoubleProperty>(userProps, *propHeader, "mvg_undistortionDiagonal", sampleFrame);
}
}
}
}
Expand Down Expand Up @@ -625,6 +630,12 @@ bool readCamera(const Version& abcVersion,
{
undistortion->setParameters(undistortionParams);
undistortion->setOffset(undistortionOffset);

if (abcVersion >= Version(1, 2, 7))
{
undistortion->setDiagonal(undistortionDiagonal);
}

// If undistortion exists, distortion does not
intrinsicCasted->setDistortionObject(nullptr);
}
Expand Down
11 changes: 8 additions & 3 deletions src/aliceVision/sfmDataIO/jsonIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ void saveIntrinsic(const std::string& name, IndexT intrinsicId, const std::share
const double focalLengthMM = intrinsicScaleOffset->sensorWidth() * intrinsicScaleOffset->getScale().x() / double(intrinsic->w());
const double focalRatio = intrinsicScaleOffset->getScale().x() / intrinsicScaleOffset->getScale().y();
const double pixelAspectRatio = 1.0 / focalRatio;

intrinsicTree.put("initialFocalLength", initialFocalLengthMM);
intrinsicTree.put("focalLength", focalLengthMM);
intrinsicTree.put("pixelRatio", pixelAspectRatio);
Expand All @@ -182,7 +182,6 @@ void saveIntrinsic(const std::string& name, IndexT intrinsicId, const std::share
if (intrinsicScaleOffsetDisto)
{
bpt::ptree distParamsTree;

std::shared_ptr<camera::Distortion> distortionObject = intrinsicScaleOffsetDisto->getDistortion();
if (distortionObject)
{
Expand All @@ -202,8 +201,9 @@ void saveIntrinsic(const std::string& name, IndexT intrinsicId, const std::share

std::shared_ptr<camera::Undistortion> undistortionObject = intrinsicScaleOffsetDisto->getUndistortion();
if (undistortionObject)
{
{
saveMatrix("undistortionOffset", undistortionObject->getOffset(), intrinsicTree);
intrinsicTree.put("undistortionDiagonal", undistortionObject->getDiagonal());

for (double param : undistortionObject->getParameters())
{
Expand Down Expand Up @@ -358,6 +358,11 @@ void loadIntrinsic(const Version& version, IndexT& intrinsicId, std::shared_ptr<
Vec2 offset;
loadMatrix("undistortionOffset", offset, intrinsicTree);
undistortionObject->setOffset(offset);

if (version >= Version(1, 2, 7))
{
undistortionObject->setDiagonal(intrinsicTree.get<double>("undistortionDiagonal"));
}
}

// If undistortion exists, distortion does not
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 6
#define ALICEVISION_SFMDATAIO_VERSION_REVISION 7

// AliceVision version as a string; for example "0.9.0".
#define ALICEVISION_SFMDATAIO_VERSION_STRING \
Expand Down
4 changes: 4 additions & 0 deletions src/aliceVision/version.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ class Version

return false;
}
bool operator>=(const Version& other) const
{
return !operator<(other);
}

private:
Vec3i _v;
Expand Down
31 changes: 28 additions & 3 deletions src/software/utils/main_applyCalibration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,34 @@ int aliceVision_main(int argc, char** argv)
const unsigned int calibrationHeight = calibratedIntrinsic->h();
const double calibrationAspect = static_cast<double>(calibrationHeight) / static_cast<double>(calibrationWidth);

// Check that aspect ratios are approximately equal
if(width != calibrationWidth || height != calibrationHeight)
{
ALICEVISION_LOG_WARNING(
"The image size used for the calibration is different from the size of the sequence.\n" <<
"Calibration size: " << calibrationWidth << "x" << calibrationHeight << "\n" <<
"Sequence size: " << width << "x" << height);
ALICEVISION_LOG_WARNING(
"Calibration image ratio: " << calibrationAspect << "\n" <<
"Sequence image ratio: " << aspect);
}

// If aspect ratios are not approximately equal
if (std::abs(aspect - calibrationAspect) > 1e-2)
{
ALICEVISION_LOG_ERROR("Intrinsic from input SfMData and calibrated SfMData are incompatible.");
return EXIT_FAILURE;
ALICEVISION_LOG_WARNING("Image aspect ratios are not approximately equal, so we need more checks.");

const bool distortionOnly = (isDistortionCalibrated && !isIntrinsicCalibrated);
const bool smaller = (width <= calibrationWidth && height <= calibrationHeight);

ALICEVISION_LOG_WARNING("Distorsion is calibrated: " << isDistortionCalibrated);
ALICEVISION_LOG_WARNING("Intrinsics are calibrated: " << isIntrinsicCalibrated);
ALICEVISION_LOG_WARNING("Size is smaller than calibration: " << smaller);

if (distortionOnly == false || smaller == false)
{
ALICEVISION_LOG_ERROR("Intrinsic from input SfMData and calibrated SfMData are incompatible.");
return EXIT_FAILURE;
}
}

// Copy original intrinsic
Expand Down Expand Up @@ -237,6 +260,8 @@ int aliceVision_main(int argc, char** argv)
auto undistortion = camera::createUndistortion(calibratedUndistortion->getType());
undistortion->setSize(width, height);
undistortion->setParameters(calibratedUndistortion->getParameters());


newIntrinsic->setUndistortionObject(undistortion);
newIntrinsic->setDistortionInitializationMode(camera::EInitMode::CALIBRATED);
}
Expand Down

0 comments on commit a960bdf

Please sign in to comment.