IsometricPatternMatcher/HexGridCostFunction.h (94 lines of code) (raw):
// Copyright (c) Facebook, Inc. and its affiliates.
//
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
#pragma once
#include <IsometricPatternMatcher/CameraModels.h>
#include <IsometricPatternMatcher/ray.h>
#include <ceres/autodiff_cost_function.h>
#include <ceres/problem.h>
#include <ceres/solver.h>
#include <Eigen/Core>
#include <sophus/se3.hpp>
// to estimate T_camera_target to transfer the image points to target space that
// the distance between neighrous = 1 please refer to this doc for more details:
// https://docs.google.com/document/d/1qLtr-ibhi1K-JtlnfyqryOUAPMmp5dpB1b3hoIzhtXA/edit
namespace surreal_opensource {
class isometricPatternPoseCost {
public:
isometricPatternPoseCost(const Ray3d rayInCamera,
const Ray3d rayNeighbourInCamera,
const Sophus::Plane3d& plane,
const double& transferSpacing)
: rayInCamera_(rayInCamera),
rayNeighbourInCamera_(rayNeighbourInCamera),
plane_(plane),
transferSpacing_(transferSpacing) {}
template <typename Scalar>
bool operator()(const Scalar* const paramTargetPose,
Scalar* residuals) const {
const Eigen::Map<const Sophus::SE3<Scalar>> T_camera_target(
paramTargetPose);
Ray3<Scalar> rayInTarget =
T_camera_target.inverse() * rayInCamera_.template cast<Scalar>();
Ray3<Scalar> rayNeighbourInTarget =
T_camera_target.inverse() *
rayNeighbourInCamera_.template cast<Scalar>();
Sophus::Vector<Scalar, 3> ptTarget3d =
rayInTarget.line().intersectionPoint(plane_.template cast<Scalar>());
Sophus::Vector<Scalar, 3> ptNeighbourTarget3d =
rayNeighbourInTarget.line().intersectionPoint(
plane_.template cast<Scalar>());
Sophus::Vector<Scalar, 3> delta = ptTarget3d - ptNeighbourTarget3d;
residuals[0] = delta.squaredNorm() - Scalar(transferSpacing_);
return true;
}
private:
const Ray3d rayInCamera_;
const Ray3d rayNeighbourInCamera_;
const Sophus::Plane3d plane_;
const double transferSpacing_;
};
class isometricPatternDistortionCost {
public:
isometricPatternDistortionCost(const Eigen::Vector2d& imageDots,
const Eigen::Vector2d& neighbourDots,
const Eigen::Vector2d& centerXY,
const double& focalLength,
const Sophus::Plane3d& plane)
: imageDots_(imageDots),
neighbourDots_(neighbourDots),
centerXY_(centerXY),
focalLength_(focalLength),
plane_(plane) {}
template <typename Scalar>
bool operator()(const Scalar* const paramTargetPose,
const Scalar* const paramDistortion,
Scalar* residuals) const {
Sophus::Vector<Scalar, KannalaBrandtK3Projection::kNumParams> intrinsics;
intrinsics << Scalar(focalLength_), Scalar(focalLength_),
Scalar(centerXY_(0)), Scalar(centerXY_(1)), paramDistortion[0],
paramDistortion[1], paramDistortion[2], paramDistortion[3];
Ray3<Scalar> rayInCamera = KannalaBrandtK3Projection::unproject(
imageDots_.template cast<Scalar>(),
intrinsics); //.template cast<Scalar>();
Ray3<Scalar> rayNeighbourInCamera = KannalaBrandtK3Projection::unproject(
neighbourDots_.template cast<Scalar>(),
intrinsics); //.template cast<Scalar>();
const Eigen::Map<const Sophus::SE3<Scalar>> T_camera_target(
paramTargetPose);
Ray3<Scalar> rayInTarget =
T_camera_target.inverse() * rayInCamera.template cast<Scalar>();
Ray3<Scalar> rayNeighbourInTarget =
T_camera_target.inverse() *
rayNeighbourInCamera.template cast<Scalar>();
Sophus::Vector<Scalar, 3> ptTarget3d =
rayInTarget.line().intersectionPoint(plane_.template cast<Scalar>());
Sophus::Vector<Scalar, 3> ptNeighbourTarget3d =
rayNeighbourInTarget.line().intersectionPoint(
plane_.template cast<Scalar>());
Sophus::Vector<Scalar, 3> delta = ptTarget3d - ptNeighbourTarget3d;
residuals[0] = delta.squaredNorm() - Scalar(1.0);
return true;
}
private:
const Eigen::Vector2d imageDots_;
const Eigen::Vector2d neighbourDots_;
const Eigen::Vector2d centerXY_;
const double focalLength_;
const Sophus::Plane3d plane_;
};
} // namespace surreal_opensource