Skip to content
Snippets Groups Projects
Commit 56e86a47 authored by Sebastian Hahta's avatar Sebastian Hahta
Browse files

scaling missing in calibration

parent 8be40171
No related branches found
No related tags found
No related merge requests found
Pipeline #21566 passed
...@@ -110,6 +110,8 @@ double ftl::calibration::computeExtrinsicParameters(const Mat &K1, const Mat &D1 ...@@ -110,6 +110,8 @@ double ftl::calibration::computeExtrinsicParameters(const Mat &K1, const Mat &D1
for (size_t i = 0; i < points_out.size(); i++) { for (size_t i = 0; i < points_out.size(); i++) {
ba.addPoint({points1[i], points2[i]}, points_out[i]); ba.addPoint({points1[i], points2[i]}, points_out[i]);
} }
ba.addObject(object_points);
double error_before = ba.reprojectionError(); double error_before = ba.reprojectionError();
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include <ftl/rgbd/source.hpp> #include <ftl/rgbd/source.hpp>
#include <ftl/rgbd/group.hpp> #include <ftl/rgbd/group.hpp>
#include <ftl/calibration.hpp>
#include <ftl/master.hpp> #include <ftl/master.hpp>
#include <ftl/streams/receiver.hpp> #include <ftl/streams/receiver.hpp>
#include <ftl/streams/netstream.hpp> #include <ftl/streams/netstream.hpp>
...@@ -231,14 +233,18 @@ void calibrateRPC( ftl::net::Universe* net, ...@@ -231,14 +233,18 @@ void calibrateRPC( ftl::net::Universe* net,
auto *nstream = nstreams[c/2]; auto *nstream = nstreams[c/2];
while(true) { while(true) {
try { try {
if (params.optimize_intrinsic) { if (params.save_intrinsic && params.optimize_intrinsic) {
// never update distortion during extrinsic calibration // never update distortion during extrinsic calibration
setIntrinsicsRPC(net, nstream, params.size, {K1, K2}, {Mat(0, 0, CV_64FC1), Mat(0, 0, CV_64FC1)}); setIntrinsicsRPC(net, nstream, params.size, {K1, K2}, {Mat(0, 0, CV_64FC1), Mat(0, 0, CV_64FC1)});
} }
setExtrinsicsRPC(net, nstream, R_c1c2, T_c1c2); if (params.save_extrinsic) {
setPoseRPC(net, nstream, getMat4x4(R[c], t[c])); setExtrinsicsRPC(net, nstream, R_c1c2, T_c1c2);
saveCalibrationRPC(net, nstream); setPoseRPC(net, nstream, getMat4x4(R[c], t[c]));
LOG(INFO) << "CALIBRATION SENT"; }
if (params.save_intrinsic || params.save_extrinsic) {
saveCalibrationRPC(net, nstream);
LOG(INFO) << "CALIBRATION SENT";
}
break; break;
} catch (std::exception &ex) { } catch (std::exception &ex) {
...@@ -382,8 +388,11 @@ void runCameraCalibration( ftl::Configurable* root, ...@@ -382,8 +388,11 @@ void runCameraCalibration( ftl::Configurable* root,
cv::cvtColor(left, rgb_new[2*idx], cv::COLOR_BGRA2BGR); cv::cvtColor(left, rgb_new[2*idx], cv::COLOR_BGRA2BGR);
cv::cvtColor(right, rgb_new[2*idx+1], cv::COLOR_BGRA2BGR); cv::cvtColor(right, rgb_new[2*idx+1], cv::COLOR_BGRA2BGR);
camera_parameters[2*idx] = createCameraMatrix(fs.frames[i].getLeftCamera()); camera_parameters[2*idx] = ftl::calibration::scaleCameraMatrix(createCameraMatrix(fs.frames[i].getLeftCamera()),
camera_parameters[2*idx+1] = createCameraMatrix(fs.frames[i].getRightCamera()); rgb_new[2*idx].size(), Size(fs.frames[i].getLeftCamera().width, fs.frames[i].getLeftCamera().height));
camera_parameters[2*idx+1] = ftl::calibration::scaleCameraMatrix(createCameraMatrix(fs.frames[i].getRightCamera()),
rgb_new[2*idx].size(), Size(fs.frames[i].getRightCamera().width, fs.frames[i].getRightCamera().height));
if (res.empty()) res = rgb_new[2*idx].size(); if (res.empty()) res = rgb_new[2*idx].size();
} }
} }
...@@ -667,10 +676,13 @@ void runCameraCalibrationPath( ftl::Configurable* root, ...@@ -667,10 +676,13 @@ void runCameraCalibrationPath( ftl::Configurable* root,
cv::cvtColor(left, rgb_new[2*idx], cv::COLOR_BGRA2BGR); cv::cvtColor(left, rgb_new[2*idx], cv::COLOR_BGRA2BGR);
cv::cvtColor(right, rgb_new[2*idx+1], cv::COLOR_BGRA2BGR); cv::cvtColor(right, rgb_new[2*idx+1], cv::COLOR_BGRA2BGR);
/*
camera_parameters[2*idx] = ftl::calibration::scaleCameraMatrix(createCameraMatrix(fs.frames[i].getLeftCamera()),
rgb_new[2*idx].size(), Size(fs.frames[i].getLeftCamera().width, fs.frames[i].getLeftCamera().height));
camera_parameters[2*idx+1] = ftl::calibration::scaleCameraMatrix(createCameraMatrix(fs.frames[i].getRightCamera()),
rgb_new[2*idx].size(), Size(fs.frames[i].getRightCamera().width, fs.frames[i].getRightCamera().height));
camera_parameters[2*idx] = createCameraMatrix(fs.frames[i].getLeftCamera()); if (res.empty()) res = rgb_new[2*idx].size();*/
camera_parameters[2*idx+1] = createCameraMatrix(fs.frames[i].getRightCamera());
if (res.empty()) res = rgb_new[2*idx].size();
} }
} }
catch (std::exception ex) { catch (std::exception ex) {
...@@ -687,14 +699,6 @@ void runCameraCalibrationPath( ftl::Configurable* root, ...@@ -687,14 +699,6 @@ void runCameraCalibrationPath( ftl::Configurable* root,
stream->begin(); stream->begin();
ftl::timer::start(false); ftl::timer::start(false);
while(true) {
if (!res.empty()) {
LOG(INFO) << "Camera resolution: " << params.size;
break;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
for (auto *nstream: nstreams) { for (auto *nstream: nstreams) {
bool res = true; bool res = true;
...@@ -724,7 +728,7 @@ void runCameraCalibrationPath( ftl::Configurable* root, ...@@ -724,7 +728,7 @@ void runCameraCalibrationPath( ftl::Configurable* root,
std::iota(params.idx_cameras.begin(), params.idx_cameras.end(), 0); std::iota(params.idx_cameras.begin(), params.idx_cameras.end(), 0);
calib.loadInput(path + filename, params.idx_cameras); calib.loadInput(path + filename, params.idx_cameras);
for (size_t i = 0; i < nstreams.size(); i++) { /*for (size_t i = 0; i < nstreams.size(); i++) {
while(true) { while(true) {
try { try {
if (camera_parameters[2*i].empty() || camera_parameters[2*i+1].empty()) { if (camera_parameters[2*i].empty() || camera_parameters[2*i+1].empty()) {
...@@ -742,7 +746,7 @@ void runCameraCalibrationPath( ftl::Configurable* root, ...@@ -742,7 +746,7 @@ void runCameraCalibrationPath( ftl::Configurable* root,
} }
catch (...) {} catch (...) {}
} }
} }*/
Mat out; Mat out;
......
...@@ -700,7 +700,6 @@ double MultiCameraCalibrationNew::calibrateAll(int reference_camera) { ...@@ -700,7 +700,6 @@ double MultiCameraCalibrationNew::calibrateAll(int reference_camera) {
calculateInverse(R_[c_from], t_[c_from], R, t); calculateInverse(R_[c_from], t_[c_from], R, t);
LOG(INFO) << "Error before BA, cameras " << reference_camera_ << " and " << c_from << ": " LOG(INFO) << "Error before BA, cameras " << reference_camera_ << " and " << c_from << ": "
<< getReprojectionErrorOptimized(c_from, K_[c_from], R, t); << getReprojectionErrorOptimized(c_from, K_[c_from], R, t);
} }
double err; double err;
...@@ -739,13 +738,17 @@ double MultiCameraCalibrationNew::calibrateAll(int reference_camera) { ...@@ -739,13 +738,17 @@ double MultiCameraCalibrationNew::calibrateAll(int reference_camera) {
ba.addPoint(visible, points2d, p); ba.addPoint(visible, points2d, p);
} }
ba.addObject(object_points_);
ftl::calibration::BundleAdjustment::Options options; ftl::calibration::BundleAdjustment::Options options;
options.loss = ftl::calibration::BundleAdjustment::Options::Loss::CAUCHY;
options.optimize_intrinsic = !fix_intrinsics_; options.optimize_intrinsic = !fix_intrinsics_;
options.fix_distortion = true; options.fix_distortion = true;
options.max_iter = 50; options.max_iter = 50;
options.fix_camera_extrinsic = {reference_camera}; options.fix_camera_extrinsic = {reference_camera};
options.verbose = true; options.verbose = true;
options.max_iter = 500;
err = ba.reprojectionError(); err = ba.reprojectionError();
ba.run(options); ba.run(options);
......
...@@ -108,8 +108,7 @@ public: ...@@ -108,8 +108,7 @@ public:
void addPoint(const std::vector<cv::Point2d>& observations, cv::Point3d& point); void addPoint(const std::vector<cv::Point2d>& observations, cv::Point3d& point);
void addPoints(const std::vector<std::vector<cv::Point2d>>& observations, std::vector<cv::Point3d>& points); void addPoints(const std::vector<std::vector<cv::Point2d>>& observations, std::vector<cv::Point3d>& points);
void addConstraintPlane(int group_size); void addObject(const std::vector<cv::Point3d>& object_points);
void addConstraintObject(const std::vector<cv::Point3d>& object_points);
/** @brief Perform bundle adjustment with custom options. /** @brief Perform bundle adjustment with custom options.
*/ */
...@@ -119,11 +118,11 @@ public: ...@@ -119,11 +118,11 @@ public:
*/ */
void run(); void run();
/** @brief Calculate RMS error (for one camera) /** @brief Calculate MSE error (for one camera)
*/ */
double reprojectionError(const int camera) const; double reprojectionError(const int camera) const;
/** @brief Calculate RMS error for all cameras /** @brief Calculate MSE error for all cameras
*/ */
double reprojectionError() const; double reprojectionError() const;
...@@ -134,6 +133,11 @@ protected: ...@@ -134,6 +133,11 @@ protected:
*/ */
void _reprojectionErrorMSE(const int camera, double &error, double &npoints) const; void _reprojectionErrorMSE(const int camera, double &error, double &npoints) const;
/** @brief Set camera parametrization (fixed parameters/cameras)
*/
void _setCameraParametrization(ceres::Problem& problem, const BundleAdjustment::Options& options);
void _setStructureParametrization(ceres::Problem& problem, const BundleAdjustment::Options& options);
void _buildProblem(ceres::Problem& problem, const BundleAdjustment::Options& options); void _buildProblem(ceres::Problem& problem, const BundleAdjustment::Options& options);
void _buildBundleAdjustmentProblem(ceres::Problem& problem, const BundleAdjustment::Options& options); void _buildBundleAdjustmentProblem(ceres::Problem& problem, const BundleAdjustment::Options& options);
void _buildLengthProblem(ceres::Problem& problem, const BundleAdjustment::Options& options); void _buildLengthProblem(ceres::Problem& problem, const BundleAdjustment::Options& options);
...@@ -150,24 +154,17 @@ private: ...@@ -150,24 +154,17 @@ private:
double* point; double* point;
}; };
// object shape based constraint for group of points from idx_start to idx_end // group of points with known structure; from idx_start to idx_end
struct ConstraintObject { struct Object {
int idx_start; int idx_start;
int idx_end; int idx_end;
std::vector<cv::Point3d> object_points; std::vector<cv::Point3d> object_points;
}; };
// planar constraint for group of points from idx_start to idx_end
struct ConstraintPlane {
int idx_start;
int idx_end;
int group_size;
};
// camera paramters (as pointers) // camera paramters (as pointers)
std::vector<Camera*> cameras_; std::vector<Camera*> cameras_;
std::vector<BundleAdjustment::Point> points_; std::vector<BundleAdjustment::Point> points_;
std::vector<BundleAdjustment::ConstraintObject> constraints_object_; std::vector<BundleAdjustment::Object> objects_;
}; };
#endif #endif
......
...@@ -237,37 +237,13 @@ void BundleAdjustment::addPoints(const vector<vector<Point2d>>& observations, st ...@@ -237,37 +237,13 @@ void BundleAdjustment::addPoints(const vector<vector<Point2d>>& observations, st
} }
} }
void BundleAdjustment::addConstraintObject(const vector<Point3d> &object_points) { void BundleAdjustment::addObject(const vector<Point3d> &object_points) {
if (points_.size() % object_points.size() != 0) { throw std::exception(); } if (points_.size() % object_points.size() != 0) { throw std::exception(); }
constraints_object_.push_back(BundleAdjustment::ConstraintObject {0, (int) points_.size(), object_points}); objects_.push_back(BundleAdjustment::Object {0, (int) points_.size(), object_points});
} }
void BundleAdjustment::_buildBundleAdjustmentProblem(ceres::Problem &problem, const BundleAdjustment::Options &options) { void BundleAdjustment::_setCameraParametrization(ceres::Problem &problem, const BundleAdjustment::Options &options) {
ceres::LossFunction *loss_function = nullptr;
if (options.loss == Options::Loss::HUBER) {
loss_function = new ceres::HuberLoss(1.0);
}
else if (options.loss == Options::Loss::CAUCHY) {
loss_function = new ceres::CauchyLoss(1.0);
}
for (auto point : points_) {
for (size_t i = 0; i < point.observations.size(); i++) {
if (!point.visibility[i]) { continue; }
ceres::CostFunction* cost_function =
ReprojectionError::Create(point.observations[i]);
problem.AddResidualBlock(cost_function,
loss_function,
getCameraPtr(i),
point.point);
}
}
// apply options
vector<int> constant_camera_parameters; vector<int> constant_camera_parameters;
// extrinsic paramters // extrinsic paramters
...@@ -336,6 +312,7 @@ void BundleAdjustment::_buildBundleAdjustmentProblem(ceres::Problem &problem, co ...@@ -336,6 +312,7 @@ void BundleAdjustment::_buildBundleAdjustmentProblem(ceres::Problem &problem, co
if (params.size() == Camera::n_parameters) { if (params.size() == Camera::n_parameters) {
// Ceres crashes if all parameters are set constant using // Ceres crashes if all parameters are set constant using
// SubsetParameterization() // SubsetParameterization()
// https://github.com/ceres-solver/ceres-solver/issues/347
problem.SetParameterBlockConstant(getCameraPtr(i)); problem.SetParameterBlockConstant(getCameraPtr(i));
} }
else if (params.size() > 0) { else if (params.size() > 0) {
...@@ -344,6 +321,35 @@ void BundleAdjustment::_buildBundleAdjustmentProblem(ceres::Problem &problem, co ...@@ -344,6 +321,35 @@ void BundleAdjustment::_buildBundleAdjustmentProblem(ceres::Problem &problem, co
} }
} }
} }
}
void BundleAdjustment::_buildBundleAdjustmentProblem(ceres::Problem &problem, const BundleAdjustment::Options &options) {
ceres::LossFunction *loss_function = nullptr;
if (options.loss == Options::Loss::HUBER) {
loss_function = new ceres::HuberLoss(1.0);
}
else if (options.loss == Options::Loss::CAUCHY) {
loss_function = new ceres::CauchyLoss(1.0);
}
for (auto point : points_) {
for (size_t i = 0; i < point.observations.size(); i++) {
if (!point.visibility[i]) { continue; }
ceres::CostFunction* cost_function =
ReprojectionError::Create(point.observations[i]);
problem.AddResidualBlock(cost_function,
loss_function,
getCameraPtr(i),
point.point);
}
}
// apply options
_setCameraParametrization(problem, options);
if (!options.optmize_structure) { if (!options.optmize_structure) {
// do not optimize points // do not optimize points
...@@ -353,9 +359,23 @@ void BundleAdjustment::_buildBundleAdjustmentProblem(ceres::Problem &problem, co ...@@ -353,9 +359,23 @@ void BundleAdjustment::_buildBundleAdjustmentProblem(ceres::Problem &problem, co
void BundleAdjustment::_buildLengthProblem(ceres::Problem &problem, const BundleAdjustment::Options &options) { void BundleAdjustment::_buildLengthProblem(ceres::Problem &problem, const BundleAdjustment::Options &options) {
for (auto &constraint : constraints_object_) { // same idea as in scale optimization
int npoints = constraint.object_points.size();
auto &object_points = constraint.object_points; ceres::LossFunction *loss_function = nullptr;
// should use separate configuration option
/*
if (options.loss == Options::Loss::HUBER) {
loss_function = new ceres::HuberLoss(1.0);
}
else if (options.loss == Options::Loss::CAUCHY) {
loss_function = new ceres::CauchyLoss(1.0);
}
*/
for (auto &object : objects_) {
int npoints = object.object_points.size();
auto &object_points = object.object_points;
vector<double> d; vector<double> d;
for (int i = 0; i < npoints; i++) { for (int i = 0; i < npoints; i++) {
...@@ -364,7 +384,7 @@ void BundleAdjustment::_buildLengthProblem(ceres::Problem &problem, const Bundle ...@@ -364,7 +384,7 @@ void BundleAdjustment::_buildLengthProblem(ceres::Problem &problem, const Bundle
} }
} }
for (int p = constraint.idx_start; p < constraint.idx_end; p += npoints) { for (int p = object.idx_start; p < object.idx_end; p += npoints) {
size_t i_d = 0; size_t i_d = 0;
for (size_t i = 0; i < object_points.size(); i++) { for (size_t i = 0; i < object_points.size(); i++) {
for (size_t j = i + 1; j < object_points.size(); j++) { for (size_t j = i + 1; j < object_points.size(); j++) {
...@@ -373,7 +393,7 @@ void BundleAdjustment::_buildLengthProblem(ceres::Problem &problem, const Bundle ...@@ -373,7 +393,7 @@ void BundleAdjustment::_buildLengthProblem(ceres::Problem &problem, const Bundle
auto cost_function = LengthError::Create(d[i_d++]); auto cost_function = LengthError::Create(d[i_d++]);
problem.AddResidualBlock(cost_function, nullptr, p1, p2); problem.AddResidualBlock(cost_function, loss_function, p1, p2);
} }
} }
} }
...@@ -442,7 +462,7 @@ void BundleAdjustment::_reprojectionErrorMSE(const int camera, double &error, do ...@@ -442,7 +462,7 @@ void BundleAdjustment::_reprojectionErrorMSE(const int camera, double &error, do
double BundleAdjustment::reprojectionError(const int camera) const { double BundleAdjustment::reprojectionError(const int camera) const {
double error, ncameras; double error, ncameras;
_reprojectionErrorMSE(camera, ncameras, error); _reprojectionErrorMSE(camera, ncameras, error);
return sqrt(error); return error / ncameras;
} }
double BundleAdjustment::reprojectionError() const { double BundleAdjustment::reprojectionError() const {
...@@ -454,5 +474,5 @@ double BundleAdjustment::reprojectionError() const { ...@@ -454,5 +474,5 @@ double BundleAdjustment::reprojectionError() const {
error += e * n; error += e * n;
npoints += n; npoints += n;
} }
return sqrt(error / npoints); return error / npoints;
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment