Newer
Older
#include <ftl/config.h>
#include <ftl/configuration.hpp>
#include <iostream>
#include <sstream>
#include <string>
#include <ctime>
#include "calibrate.hpp"
#include <opencv2/core.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/calib3d.hpp>
using cv::FileNode;
using cv::FileNodeIterator;
using cv::cuda::GpuMat;
using cv::cuda::Stream;
using cv::Point2f;
using cv::Point3f;
using cv::Matx33d;
using cv::Scalar;
Calibrate::Calibrate(nlohmann::json &config, cv::Size image_size, cv::cuda::Stream &stream) : ftl::Configurable(config) {
std::pair<Mat, Mat> map1, map2;
calibrated_ = _loadCalibration(image_size, map1, map2);
LOG(INFO) << "Calibration loaded from file";
}
else {
LOG(WARNING) << "Calibration not loaded";
}
this->on("use_intrinsics", [this](const ftl::config::Event &e) {
_updateIntrinsics();
});
}
void Calibrate::_updateIntrinsics() {
Mat R1, R2, P1, P2;
std::pair<Mat, Mat> map1, map2;
if (this->value("use_intrinsics", true)) {
R1 = R1_;
R2 = R2_;
P1 = P1_;
P2 = P2_;
}
else {
R1 = Mat::eye(Size(3, 3), CV_64FC1);
R2 = R1;
P1 = M1_;
P2 = M2_;
}
initUndistortRectifyMap(M1_, D1_, R1, P1, img_size_, CV_32FC1, map1.first, map2.first);
initUndistortRectifyMap(M2_, D2_, R2, P2, img_size_, CV_32FC1, map1.second, map2.second);
map1_gpu_.first.upload(map1.first);
map1_gpu_.second.upload(map1.second);
map2_gpu_.first.upload(map2.first);
map2_gpu_.second.upload(map2.second);
bool Calibrate::_loadCalibration(cv::Size img_size, std::pair<Mat, Mat> &map1, std::pair<Mat, Mat> &map2) {
FileStorage fs;
// reading intrinsic parameters
auto ifile = ftl::locateFile(value("intrinsics", std::string("intrinsics.yml")));
if (ifile) {
fs.open((*ifile).c_str(), FileStorage::READ);
if (!fs.isOpened()) {
LOG(WARNING) << "Could not open intrinsics file";
return false;
}
LOG(INFO) << "Intrinsics from: " << *ifile;
}
else {
LOG(WARNING) << "Calibration intrinsics file not found";
auto efile = ftl::locateFile("extrinsics.yml");
if (efile) {
fs.open((*efile).c_str(), FileStorage::READ);
if (!fs.isOpened()) {
LOG(WARNING) << "Could not open extrinsics file";
return false;
}
LOG(INFO) << "Extrinsics from: " << *efile;
} else {
LOG(WARNING) << "Calibration extrinsics file not found";
return false;

Sebastian Hahta
committed
}
fs["R"] >> R_;
fs["T"] >> T_;
fs["R1"] >> R1_;
fs["R2"] >> R2_;
fs["P1"] >> P1_;
fs["P2"] >> P2_;

Sebastian Hahta
committed
// cv::cuda::remap() works only with CV_32FC1
initUndistortRectifyMap(M1_, D1_, R1_, P1_, img_size_, CV_32FC1, map1.first, map2.first);
initUndistortRectifyMap(M2_, D2_, R2_, P2_, img_size_, CV_32FC1, map1.second, map2.second);
void Calibrate::updateCalibration(const ftl::rgbd::Camera &p) {
std::pair<Mat, Mat> map1, map2;
Q_.at<double>(3,2) = 1.0 / p.baseline;
Q_.at<double>(0,3) = p.cx;
Q_.at<double>(1,3) = p.cy;
initUndistortRectifyMap(M1_, D1_, R1_, P1_, img_size_, CV_32FC1, map1.first, map2.first);
initUndistortRectifyMap(M2_, D2_, R2_, P2_, img_size_, CV_32FC1, map1.second, map2.second);
// CHECK Is this thread safe!!!!
map1_gpu_.first.upload(map1.first);
map1_gpu_.second.upload(map1.second);
map2_gpu_.first.upload(map2.first);
map2_gpu_.second.upload(map2.second);
}
void Calibrate::rectifyStereo(GpuMat &l, GpuMat &r, Stream &stream) {
// cv::cuda::remap() can not use same Mat for input and output
GpuMat l_tmp(l.size(), l.type());
GpuMat r_tmp(r.size(), r.type());
cv::cuda::remap(l, l_tmp, map1_gpu_.first, map2_gpu_.first, cv::INTER_LINEAR, 0, cv::Scalar(), stream);
cv::cuda::remap(r, r_tmp, map1_gpu_.second, map2_gpu_.second, cv::INTER_LINEAR, 0, cv::Scalar(), stream);
stream.waitForCompletion();
l = l_tmp;
r = r_tmp;
}
bool Calibrate::isCalibrated() {
return calibrated_;