licornea_tools
evaluate_calibration.cc
Go to the documentation of this file.
1 #include "../lib/common.h"
2 #include "../lib/args.h"
3 #include "../lib/dataset.h"
4 #include "../lib/camera.h"
5 #include "../lib/misc.h"
7 #include "lib/feature_points.h"
8 #include <iostream>
9 #include <cmath>
10 #include <random>
11 #include <fstream>
12 
13 using namespace tlz;
14 
15 constexpr bool verbose = true;
16 constexpr int min_features_count = 10;
17 constexpr real max_reprojection_error = 100.0;
18 
19 int main(int argc, const char* argv[]) {
20  get_args(argc, argv, "dataset_parameters.json cors.json cams.json out_samples.txt [random/all] [random_count=100000]");
21  dataset datas = dataset_arg();
23  camera_array cams = cameras_arg();
24  std::string out_samples_filename = out_filename_arg();
25  std::string mode = enum_opt_arg({"random", "all"}, "all");
26  int random_count = int_opt_arg(10000);
27 
28  auto cams_map = cameras_map(cams);
29 
30  std::ofstream out_samples_stream(out_samples_filename);
31  out_samples_stream << "baseline reprojection_error\n";
32 
33 
34  auto warp = [&](const view_index& from, const view_index& to) -> real {
35  if(cams_map.find(datas.view(from).camera_name()) == cams_map.end()) return NAN;
36  if(cams_map.find(datas.view(to).camera_name()) == cams_map.end()) return NAN;
37 
38  const camera& from_cam = cams_map.at(datas.view(from).camera_name());
39  const camera& to_cam = cams_map.at(datas.view(to).camera_name());
40  intrinsics from_intr = to_undistorted_intrinsics(from_cam, datas.image_width(), datas.image_height());
41  intrinsics to_intr = to_undistorted_intrinsics(to_cam, datas.image_width(), datas.image_height());
42  mat44 pose_transformation = to_cam.extrinsic() * from_cam.extrinsic_inv();
43 
44  const feature_points& from_fpoints = undistorted_feature_points_for_view(cors, from, from_intr);
45  const feature_points& to_fpoints = undistorted_feature_points_for_view(cors, to, to_intr);
46  std::vector<std::string> common_features;
47  for(const auto& kv : from_fpoints.points) {
48  const std::string& feature_name = kv.first;
49  if(to_fpoints.points.find(feature_name) != to_fpoints.points.end())
50  common_features.push_back(feature_name);
51  }
52  if(common_features.size() == 0) return NAN;
53 
54  std::vector<real> reprojection_errors;
55  reprojection_errors.reserve(common_features.size());
56 
57  for(const std::string& feature_name : common_features) {
58  const feature_point& from_fpoint = from_fpoints.points.at(feature_name);
59  const feature_point& to_fpoint = to_fpoints.points.at(feature_name);
60 
61  vec3 from_i = vec3(from_fpoint.position[0], from_fpoint.position[1], 1.0) * from_fpoint.depth;
62  vec3 from_v = from_intr.K_inv * from_i;
63  vec3 to_v = mul_h(pose_transformation, from_v);
64  vec3 to_i = to_intr.K * to_v;
65  to_i /= to_i[2];
66 
67  real reprojection_error = sq(to_i[0] - to_fpoint.position[0]) + sq(to_i[1] - to_fpoint.position[1]);
68  reprojection_errors.push_back(reprojection_error);
69  }
70  if(reprojection_errors.size() < min_features_count) return NAN;
71 
72  std::ptrdiff_t mid = reprojection_errors.size() / 2;
73  std::nth_element(reprojection_errors.begin(), reprojection_errors.begin()+mid, reprojection_errors.end());
74 
75  real err = reprojection_errors[mid];
76  if(err > max_reprojection_error) return NAN;
77 
78  int baseline = std::sqrt(sq(from.x - to.x) + sq(from.y - to.y));
79  //real baseline = std::sqrt(sq(pose_transformation(0,3)) + sq(pose_transformation(1,3)) + sq(pose_transformation(2,3)));
80 
81  #pragma omp critical
82  {
83  out_samples_stream << err << ' ' << baseline << '\n';
84  }
85 
86  if(verbose)
87  std::cout << from << " ->" << to << ": err" << std::endl;
88 
89  return err;
90  };
91 
92 
93  auto indices = datas.indices();
94 
95  if(mode == "random") {
96  std::mt19937 gen;
97  std::uniform_int_distribution<std::ptrdiff_t> dist(0, indices.size() - 1);
98 
99  #pragma omp parallel for
100  for(int i = 0; i < random_count; ++i) {
101  const view_index& from_idx = indices[dist(gen)];
102  const view_index& to_idx = indices[dist(gen)];
103  warp(from_idx, to_idx);
104  std::cout << '.' << std::flush;
105  }
106 
107 
108  } else if(mode == "all") {
109  #pragma omp parallel for
110  for(int from = 0; from < indices.size(); ++from) {
111  for(int to = from + 1; to < indices.size(); ++to) {
112  const view_index& from_idx = indices[from];
113  const view_index& to_idx = indices[to];
114  warp(from_idx, to_idx);
115  std::cout << '.' << std::flush;
116  }
117  }
118  }
119 }
long int_opt_arg(long def)
Definition: args.h:50
Numeric sq(Numeric n)
Compute square of a number.
Definition: misc.h:17
constexpr bool verbose
feature_points undistorted_feature_points_for_view(const image_correspondences &cors, view_index idx, const intrinsics &intr)
Set of features, each on set of views.
std::map< std::string, camera > cameras_map(const camera_array &arr)
Definition: camera.cc:112
int image_width() const
Definition: dataset.cc:153
mat44 extrinsic_inv() const
Definition: camera.cc:34
Points of different features, on one view.
constexpr real max_reprojection_error
constexpr int min_features_count
std::map< std::string, feature_point > points
camera_array cameras_arg()
Definition: camera.cc:107
vec3 mul_h(const mat44 &mat, const vec3 &vec)
Definition: common.h:29
dataset_view view(int x) const
Definition: dataset.cc:243
std::string enum_opt_arg(const std::vector< std::string > &options, const std::string &def)
Definition: args.h:58
mat44 extrinsic() const
Definition: camera.cc:24
int main(int argc, const char *argv[])
dataset dataset_arg()
Definition: dataset.cc:297
int image_height() const
Definition: dataset.cc:157
double real
Definition: common.h:16
cv::Vec< real, 3 > vec3
Definition: common.h:23
image_correspondences image_correspondences_arg()
intrinsics to_undistorted_intrinsics(const camera &cam, int width, int height)
Definition: camera.cc:119
std::string camera_name() const
Definition: dataset.cc:60
std::string out_filename_arg()
Definition: args.cc:104
std::string mode
std::vector< camera > camera_array
Definition: camera.h:26
std::vector< view_index > indices() const
Definition: dataset.cc:235
cv::Matx< real, 4, 4 > mat44
Definition: common.h:27
void get_args(int argc, const char *argv[], const std::string &usage)
Definition: args.cc:49