camera_calibrator_impl.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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. struct camera_calib_result {
  63. cv::Mat intrinsic, dist_coeffs;
  64. };
  65. using img_index_list_type = std::vector<size_t>;
  66. camera_calib_result camera_calib(const img_index_list_type &index);
  67. float reproject_error(const camera_calib_result &cam,
  68. const corner_type &img_ps);
  69. camera_calib_result camera_calib_ransac();
  70. // do hand-eye calibration
  71. // return reference in camera
  72. glm::mat4 calib_hand_eye();
  73. // evaluate hand-eye calibration result
  74. cv::Scalar evaluate_hand_eye(const glm::mat4 &ret_mat);
  75. size_t sample_num, corner_num;
  76. camera_calib_result cam_cv;
  77. int ts_offset = 0; // timestamp offset
  78. std::vector<cv::Mat> cam_r_vec; // chess board in camera
  79. std::vector<cv::Mat> cam_t_vec;
  80. cv::Mat aux_r, aux_t; // tracker in chess board
  81. };
  82. }
  83. using namespace camera_calibrator_impl;
  84. struct camera_calibrator::impl {
  85. create_config conf;
  86. using conn_type = boost::signals2::connection;
  87. conn_type img_conn;
  88. struct img_store_type {
  89. image_ptr img;
  90. cv::Mat img_mat;
  91. timestamp_type sample_ts;
  92. corner_type corners;
  93. float corner_sharpness;
  94. bool process_finished: 1 = false;
  95. bool corners_detected: 1 = false;
  96. };
  97. using img_pool_type = std::list<img_store_type>;
  98. img_pool_type img_pool;
  99. std::atomic_int img_ok_cnt = 0;
  100. struct track_store_type {
  101. glm::mat4 ref_mat;
  102. float track_error;
  103. timestamp_type sample_ts;
  104. };
  105. using track_pool_type = std::vector<track_store_type>;
  106. track_pool_type track_pool;
  107. std::atomic<img_store_type *> last_finish = nullptr;
  108. float last_track_err = std::numeric_limits<float>::quiet_NaN();
  109. std::unique_ptr<smart_frame_buffer> coverage_fbo;
  110. NVGcontext *vg = nullptr;
  111. std::unique_ptr<BS::thread_pool> tp; // thread pool
  112. cv::Size img_size;
  113. std::unique_ptr<hand_eye_calib> calib;
  114. explicit impl(const create_config &conf);
  115. ~impl();
  116. void per_image_process(img_store_type *st);
  117. void img_callback(obj_name_type name);
  118. void save_track_data();
  119. void load_track_data(const std::string &path);
  120. void process(); // do calibration
  121. void simulate_process(const simulate_info_type &info);
  122. void start();
  123. void stop(bool on_exit = false);
  124. void render_corners(const corner_type &corner, NVGcolor color);
  125. void render();
  126. void show();
  127. };
  128. #endif //DEPTHGUIDE_CAMERA_CALIBRATOR_IMPL_H