8 #include "../lib/args.h" 9 #include "../lib/misc.h" 10 #include "../lib/json.h" 11 #include "../lib/opencv.h" 12 #include "../lib/intrinsics.h" 13 #include "../lib/assert.h" 14 #include "../lib/rotation.h" 20 template<
typename Func>
27 while(std::abs(c - d) > tolerance) {
28 if(f(c) < f(d)) b = d;
36 int main(
int argc,
const char* argv[]) {
37 get_args(argc, argv,
"measured_feature_slopes.json intrinsics.json out_rotation.json");
44 auto rotation_error = [&measured_fslopes, &intr](
real x,
real y,
real z) {
47 real fx = intr.
fx(), fy = intr.
fy(), cx = intr.
cx(), cy = intr.
cy();
48 real r11 = R(0, 0), r21 = R(1, 0), r31 = R(2, 0);
49 real r12 = R(0, 1), r22 = R(1, 1), r32 = R(2, 1);
52 for(
const auto& kv : measured_fslopes.
slopes) {
53 const std::string& feature_name = kv.first;
58 real model_hslope = (fy*r21 + cy*r31 - iy*r31) / (fx*r11 + cx*r31 - ix*r31);
59 real model_vslope = (fx*r12 + cx*r32 - ix*r32) / (fy*r22 + cy*r32 - iy*r32);
64 real err =
sq(model_hslope - measured_hslope) +
sq(model_vslope - measured_vslope);
67 err_sum /= measured_fslopes.
slopes.size();
71 std::cout <<
"minimizing rotations error" << std::endl;
72 real z = 0.0, x = 0.0, y = 0.0;
74 auto f_x = [&](
real x_) {
return rotation_error(x_, y, z); };
75 auto f_y = [&](
real y_) {
return rotation_error(x, y_, z); };
76 auto f_z = [&](
real z_) {
return rotation_error(x, y, z_); };
80 real min_error = 1e-20;
81 real min_error_diff = 1e-20;
82 int max_iterations = 500;
83 real outreach_scaledown = 0.001;
84 real tolerance_scaledown = 0.005;
87 real outreach = initial_outreach;
88 real tolerance = initial_tolerance;
89 real err = rotation_error(x, y, z);
90 while(err > min_error && iterations != max_iterations) {
92 std::cout <<
"iterations = " << iterations <<
"\n";
93 std::cout <<
"err = " << err <<
"\n";
95 std::cout <<
"y = " << y * deg_per_rad <<
"°\n";
96 std::cout <<
"z = " << z * deg_per_rad <<
"°\n";
97 std::cout <<
"outreach = " << outreach <<
"\n";
98 std::cout <<
"tolerance = " << tolerance <<
"\n\n" << std::endl;
100 std::cout <<
'.' << std::flush;
103 real z_min = z - outreach, z_max = z + outreach;
105 z = (z_max + z_min) / 2.0;
107 real x_min = x - outreach, x_max = x + outreach;
109 x = (x_max + x_min) / 2.0;
111 real y_min = y - outreach, y_max = y + outreach;
113 y = (y_max + y_min) / 2.0;
116 outreach = initial_outreach / std::exp(iterations * outreach_scaledown);
117 tolerance = initial_tolerance / std::exp(iterations * tolerance_scaledown);
119 err = rotation_error(x, y, z);
121 if(std::abs(prev_err - err) < min_error_diff)
break;
124 std::cout <<
"\nfound minimum err = " << err <<
"\n";
126 std::cout <<
"y = " << y * deg_per_rad <<
"°\n";
127 std::cout <<
"z = " << z * deg_per_rad <<
"°" << std::endl;
130 std::cout <<
"saving rotation matrix" << std::endl;
Numeric sq(Numeric n)
Compute square of a number.
int main(int argc, const char *argv[])
constexpr real deg_per_rad
constexpr real golden_ratio
void one_dim_search_minimum(Func f, real &a, real &b, real tolerance)
feature_slopes feature_slopes_arg()
std::map< std::string, feature_point > points
intrinsics intrinsics_arg()
cv::Matx< real, 3, 3 > mat33
json encode_mat(const Mat &mat)
void export_json_file(const json &j, const std::string &filename, bool compact)
mat33 to_rotation_matrix(const vec3 &euler)
std::string out_filename_arg()
constexpr real rad_per_deg
std::map< std::string, feature_slope > slopes
void get_args(int argc, const char *argv[], const std::string &usage)