camera_calibrator_impl.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #ifndef DEPTHGUIDE_CAMERA_CALIBRATOR_IMPL_H
  2. #define DEPTHGUIDE_CAMERA_CALIBRATOR_IMPL_H
  3. #include "image_process/camera_calibrator.h"
  4. #include "core/image_utility_v2.h"
  5. #include "core/math_helper.hpp"
  6. #include "render/render_utility.h"
  7. #include <opencv2/core/mat.hpp>
  8. #include <nanovg.h>
  9. #include <BS_thread_pool.hpp>
  10. #include <atomic>
  11. #include <list>
  12. namespace camera_calibrator_impl {
  13. // TODO: make configurable
  14. static constexpr auto sharpness_threshold = 4.f;
  15. static constexpr auto track_err_threshold = 0.25f;
  16. using corner_type = std::vector<cv::Point2f>;
  17. cv::Mat to_cv_mat(const glm::mat3 &mat);
  18. cv::Mat to_cv_mat(const glm::vec3 &vec);
  19. glm::mat3 rodrigues_to_mat(const cv::Mat &vec);
  20. cv::Mat to_cv_rodigues(const glm::mat3 &mat);
  21. glm::mat3 to_mat3(const cv::Mat &mat);
  22. glm::vec3 to_vec3(const cv::Mat &mat);
  23. struct hand_eye_calib {
  24. // fill before use
  25. transform_buffer track_pool;
  26. struct image_store_type {
  27. corner_type corner;
  28. timestamp_type sample_ts;
  29. };
  30. using image_pool_type =
  31. std::vector<image_store_type>;
  32. image_pool_type img_pool;
  33. cv::Size img_size;
  34. // fill by member functions
  35. using object_points_type =
  36. std::vector<cv::Vec3f>;
  37. object_points_type obj_ps;
  38. // result
  39. glm::mat3 intrinsic_mat; // intrinsic matrix
  40. using dist_coeffs_type = std::vector<float>;
  41. dist_coeffs_type dist_coeffs; // distortion coefficients
  42. glm::mat4 result_mat; // result matrix, camera in camera reference
  43. int result_ts_offset; // temporal latency between tracker and camera
  44. // result error
  45. float obj_reproj_err; // average error of spacial corners after hand-eye calibration, in mm
  46. float img_reproj_err; // average error of image corners after hand-eye calibration, in pixel
  47. void set_object_points(cv::Size size, float dis); // dis: in mm
  48. void calc();
  49. camera_intrinsic_v0 intrinsic_v0();
  50. private:
  51. // interpolate track matrix
  52. glm::mat4 calc_track_mat(timestamp_type t);
  53. // p: in the normalized plane
  54. glm::vec2 distort_point(glm::vec2 p);
  55. // p: in camera coordinate
  56. // result: in pixel
  57. // duplicate cv::projectPoints
  58. glm::vec2 project_point(glm::vec3 p);
  59. // average distance between two sets of corner points
  60. static float corner_distance(const corner_type &c1,
  61. const corner_type &c2);
  62. // do hand-eye calibration
  63. // return reference in camera
  64. glm::mat4 calib_hand_eye();
  65. // evaluate hand-eye calibration result
  66. cv::Scalar evaluate_hand_eye(const glm::mat4 &ret_mat);
  67. size_t sample_num, corner_num;
  68. cv::Mat intrinsic_cv_mat, dist_coeffs_mat;
  69. int ts_offset = 0; // timestamp offset
  70. std::vector<cv::Mat> cam_r_vec; // chess board in camera
  71. std::vector<cv::Mat> cam_t_vec;
  72. cv::Mat aux_r, aux_t; // tracker in chess board
  73. };
  74. }
  75. using namespace camera_calibrator_impl;
  76. struct camera_calibrator::impl {
  77. create_config conf;
  78. using conn_type = boost::signals2::connection;
  79. conn_type img_conn;
  80. struct img_store_type {
  81. image_ptr img;
  82. cv::Mat img_mat;
  83. timestamp_type sample_ts;
  84. corner_type corners;
  85. float corner_sharpness;
  86. bool process_finished: 1 = false;
  87. bool corners_detected: 1 = false;
  88. };
  89. using img_pool_type = std::list<img_store_type>;
  90. img_pool_type img_pool;
  91. std::atomic_int img_ok_cnt = 0;
  92. struct track_store_type {
  93. glm::mat4 ref_mat;
  94. float track_error;
  95. timestamp_type sample_ts;
  96. };
  97. using track_pool_type = std::vector<track_store_type>;
  98. track_pool_type track_pool;
  99. std::atomic<img_store_type *> last_finish = nullptr;
  100. float last_track_err = std::numeric_limits<float>::quiet_NaN();
  101. std::unique_ptr<smart_frame_buffer> coverage_fbo;
  102. NVGcontext *vg = nullptr;
  103. std::unique_ptr<BS::thread_pool> tp; // thread pool
  104. cv::Size img_size;
  105. std::unique_ptr<hand_eye_calib> calib;
  106. explicit impl(const create_config &conf);
  107. ~impl();
  108. void per_image_process(img_store_type *st);
  109. void img_callback(obj_name_type name);
  110. void save_track_data();
  111. void load_track_data(const std::string &path);
  112. void process(); // do calibration
  113. void simulate_process(const simulate_info_type &info);
  114. void start();
  115. void stop(bool on_exit = false);
  116. void render_corners(const corner_type &corner, NVGcolor color);
  117. void render();
  118. void show();
  119. };
  120. #endif //DEPTHGUIDE_CAMERA_CALIBRATOR_IMPL_H