-
-
Notifications
You must be signed in to change notification settings - Fork 851
landmarks can now be defined with respect to a camera geometric frame instead of the world geometric frame #1896
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
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -281,6 +281,130 @@ struct ProjectionErrorFunctor | |||||||||||||||||||||||||||||||||||||||||||||||
ceres::DynamicCostFunctionToFunctorTmp _intrinsicFunctor; | ||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
struct ProjectionRelativeErrorFunctor | ||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||
explicit ProjectionRelativeErrorFunctor(const sfmData::Observation& obs | ||||||||||||||||||||||||||||||||||||||||||||||||
, const std::shared_ptr<camera::IntrinsicBase>& intrinsics | ||||||||||||||||||||||||||||||||||||||||||||||||
, bool noPose) | ||||||||||||||||||||||||||||||||||||||||||||||||
: _intrinsicFunctor(new CostIntrinsicsProject(obs, intrinsics)) | ||||||||||||||||||||||||||||||||||||||||||||||||
, withoutPose(noPose) | ||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
template<typename T> | ||||||||||||||||||||||||||||||||||||||||||||||||
bool operator()(T const* const* parameters, T* residuals) const | ||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||
const T* parameter_intrinsics = parameters[0]; | ||||||||||||||||||||||||||||||||||||||||||||||||
const T* parameter_distortion = parameters[1]; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
T transformedPoint[3]; | ||||||||||||||||||||||||||||||||||||||||||||||||
if (withoutPose) | ||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||
//withoutPose is used if reference view and current view are the same views | ||||||||||||||||||||||||||||||||||||||||||||||||
const T* parameter_relativepoint = parameters[2]; | ||||||||||||||||||||||||||||||||||||||||||||||||
transformedPoint[0] = parameter_relativepoint[0]; | ||||||||||||||||||||||||||||||||||||||||||||||||
transformedPoint[1] = parameter_relativepoint[1]; | ||||||||||||||||||||||||||||||||||||||||||||||||
transformedPoint[2] = parameter_relativepoint[2]; | ||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||
else | ||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||
const T* parameter_pose = parameters[2]; | ||||||||||||||||||||||||||||||||||||||||||||||||
const T* parameter_refpose = parameters[3]; | ||||||||||||||||||||||||||||||||||||||||||||||||
const T* parameter_relativepoint = parameters[4]; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
//Retrieve point | ||||||||||||||||||||||||||||||||||||||||||||||||
T relpoint[3]; | ||||||||||||||||||||||||||||||||||||||||||||||||
relpoint[0] = parameter_relativepoint[0]; | ||||||||||||||||||||||||||||||||||||||||||||||||
relpoint[1] = parameter_relativepoint[1]; | ||||||||||||||||||||||||||||||||||||||||||||||||
relpoint[2] = parameter_relativepoint[2]; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
const T* refcam_R = parameter_refpose; | ||||||||||||||||||||||||||||||||||||||||||||||||
const T* refcam_t = ¶meter_refpose[3]; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
// Apply transformation such that the point | ||||||||||||||||||||||||||||||||||||||||||||||||
// Which was defined in the camera geometric frame | ||||||||||||||||||||||||||||||||||||||||||||||||
// is now defined in the world frame | ||||||||||||||||||||||||||||||||||||||||||||||||
relpoint[0] = relpoint[0] - refcam_t[0]; | ||||||||||||||||||||||||||||||||||||||||||||||||
relpoint[1] = relpoint[1] - refcam_t[1]; | ||||||||||||||||||||||||||||||||||||||||||||||||
relpoint[2] = relpoint[2] - refcam_t[2]; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
T invrefcam_R[3]; | ||||||||||||||||||||||||||||||||||||||||||||||||
invrefcam_R[0] = -refcam_R[0]; | ||||||||||||||||||||||||||||||||||||||||||||||||
invrefcam_R[1] = -refcam_R[1]; | ||||||||||||||||||||||||||||||||||||||||||||||||
invrefcam_R[2] = -refcam_R[2]; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
T absolutePoint[3]; | ||||||||||||||||||||||||||||||||||||||||||||||||
ceres::AngleAxisRotatePoint(invrefcam_R, relpoint, absolutePoint); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+328
to
+339
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The coordinate transformation logic is incorrect. The proper transformation from camera frame to world frame should first apply the inverse rotation, then subtract the translation. Currently, translation is subtracted before rotation, which will produce incorrect world coordinates.
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||||||||||||||||||||||||||||||||||||||||||||
//-- | ||||||||||||||||||||||||||||||||||||||||||||||||
// Apply external parameters (Pose) | ||||||||||||||||||||||||||||||||||||||||||||||||
//-- | ||||||||||||||||||||||||||||||||||||||||||||||||
const T* cam_R = parameter_pose; | ||||||||||||||||||||||||||||||||||||||||||||||||
const T* cam_t = ¶meter_pose[3]; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
// Rotate the point according the camera rotation | ||||||||||||||||||||||||||||||||||||||||||||||||
ceres::AngleAxisRotatePoint(cam_R, absolutePoint, transformedPoint); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
// Apply the camera translation | ||||||||||||||||||||||||||||||||||||||||||||||||
transformedPoint[0] += cam_t[0]; | ||||||||||||||||||||||||||||||||||||||||||||||||
transformedPoint[1] += cam_t[1]; | ||||||||||||||||||||||||||||||||||||||||||||||||
transformedPoint[2] += cam_t[2]; | ||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
const T * innerParameters[3]; | ||||||||||||||||||||||||||||||||||||||||||||||||
innerParameters[0] = parameter_intrinsics; | ||||||||||||||||||||||||||||||||||||||||||||||||
innerParameters[1] = parameter_distortion; | ||||||||||||||||||||||||||||||||||||||||||||||||
innerParameters[2] = transformedPoint; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
return _intrinsicFunctor(innerParameters, residuals); | ||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||
* @brief Create the appropriate cost functor according the provided input camera intrinsic model | ||||||||||||||||||||||||||||||||||||||||||||||||
* @param[in] intrinsicPtr The intrinsic pointer | ||||||||||||||||||||||||||||||||||||||||||||||||
* @param[in] observation The corresponding observation | ||||||||||||||||||||||||||||||||||||||||||||||||
* @param[in] withoutPose When reference view and current view are the same, poses must be ignored | ||||||||||||||||||||||||||||||||||||||||||||||||
* @return cost functor | ||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||
inline static ceres::CostFunction* createCostFunction( | ||||||||||||||||||||||||||||||||||||||||||||||||
const std::shared_ptr<camera::IntrinsicBase> intrinsic, | ||||||||||||||||||||||||||||||||||||||||||||||||
const sfmData::Observation& observation, | ||||||||||||||||||||||||||||||||||||||||||||||||
bool withoutPose) | ||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||
auto costFunction = new ceres::DynamicAutoDiffCostFunction<ProjectionRelativeErrorFunctor>(new ProjectionRelativeErrorFunctor(observation, intrinsic, withoutPose)); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
int distortionSize = 1; | ||||||||||||||||||||||||||||||||||||||||||||||||
auto isod = camera::IntrinsicScaleOffsetDisto::cast(intrinsic); | ||||||||||||||||||||||||||||||||||||||||||||||||
if (isod) | ||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||
auto distortion = isod->getDistortion(); | ||||||||||||||||||||||||||||||||||||||||||||||||
if (distortion) | ||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||
distortionSize = distortion->getParameters().size(); | ||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
costFunction->AddParameterBlock(intrinsic->getParameters().size()); | ||||||||||||||||||||||||||||||||||||||||||||||||
costFunction->AddParameterBlock(distortionSize); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
if (!withoutPose) | ||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||
costFunction->AddParameterBlock(6); | ||||||||||||||||||||||||||||||||||||||||||||||||
costFunction->AddParameterBlock(6); | ||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
costFunction->AddParameterBlock(3); | ||||||||||||||||||||||||||||||||||||||||||||||||
costFunction->SetNumResiduals(2); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
return costFunction; | ||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
ceres::DynamicCostFunctionToFunctorTmp _intrinsicFunctor; | ||||||||||||||||||||||||||||||||||||||||||||||||
bool withoutPose; | ||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
} // namespace sfm | ||||||||||||||||||||||||||||||||||||||||||||||||
} // namespace aliceVision |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -186,6 +186,18 @@ bool readPointCloud(const Version& abcVersion, IObject iObj, M44d mat, sfmData:: | |||||
} | ||||||
} | ||||||
|
||||||
AV_UInt32ArraySamplePtr sampleReferenceViewIndices; | ||||||
if (userProps && userProps.getPropertyHeader("mvg_referenceViewIndices")) | ||||||
{ | ||||||
sampleReferenceViewIndices.read(userProps, "mvg_referenceViewIndices"); | ||||||
if (sampleReferenceViewIndices.size() != positions->size()) | ||||||
{ | ||||||
ALICEVISION_LOG_WARNING("[Alembic Importer] Describer type will be ignored. describerType vector size: " | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The warning message incorrectly states 'Describer type will be ignored' when the issue is with reference view indices. It should say 'Reference view indices will be ignored' to accurately reflect what is being discarded.
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||
<< sampleReferenceViewIndices.size() << ", positions vector size: " << positions->size()); | ||||||
sampleReferenceViewIndices.reset(); | ||||||
} | ||||||
} | ||||||
|
||||||
// Number of points before adding the Alembic data | ||||||
const std::size_t nbPointsInit = sfmdata.getLandmarks().size(); | ||||||
for (std::size_t point3d_i = 0; point3d_i < positions->size(); ++point3d_i) | ||||||
|
@@ -217,6 +229,11 @@ bool readPointCloud(const Version& abcVersion, IObject iObj, M44d mat, sfmData:: | |||||
const std::size_t descType_i = sampleDescs[point3d_i]; | ||||||
landmark.descType = static_cast<feature::EImageDescriberType>(descType_i); | ||||||
} | ||||||
|
||||||
if (sampleReferenceViewIndices) | ||||||
{ | ||||||
landmark.referenceViewIndex = sampleReferenceViewIndices[point3d_i]; | ||||||
} | ||||||
} | ||||||
|
||||||
// for compatibility with files generated with a previous version | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The conditional logic creates duplicate residual blocks - one for relative landmarks and another for absolute landmarks. This should be an if-else structure to avoid adding two residual blocks for the same observation when referencePoseBlockPtr is not null.
Copilot uses AI. Check for mistakes.