ArithPmd.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #ifndef ARITHPMD_H
  2. #define ARITHPMD_H
  3. #include "inc.h"
  4. #include "nlohmann/json.hpp"
  5. #include <opencv2/core/eigen.hpp>
  6. #include <pcl/point_types.h>
  7. #include <pcl/common/transforms.h>
  8. #include "pcl/common/centroid.h"
  9. // #include <opencv2/aruco.hpp>
  10. struct Screen {
  11. float width; // 屏幕宽度(m)
  12. float height; // 屏幕高度(m)
  13. uint16_t cols; // 屏幕分辨率列数
  14. uint16_t rows; // 屏幕分辨率行数
  15. };
  16. struct ROI {
  17. uint32_t startRow;
  18. uint32_t startCol;
  19. uint32_t blockRows;
  20. uint32_t blockCols;
  21. };
  22. /*
  23. * 重要变量用 Matrix,中间变量要是需要时传 Array
  24. * 能用 row,col,width,height,就不用x,y
  25. * 能用Qt的功能就用Qt的,如目录
  26. * 图像用img,用拍摄图像而非照片表示
  27. * R旋转,TL平移向量,T变换矩阵,CVT将V坐标系的变量变换到C坐标系的变换矩阵
  28. */
  29. bool save_matrix_as_img(const MatrixXf& m, std::string path);
  30. /*
  31. * 矩阵数据输出到文件
  32. * add_index: 是否将第一行或第一列变为索引下标
  33. * orientation:0,第一行变为索引,否则,第一列变为索引
  34. */
  35. bool save_matrix_as_txt(const MatrixXf& m, std::string path, bool add_index = false, int orientation = 0);
  36. /*
  37. * 矩阵保存为 ply 格式的点云文件
  38. * params: 矩阵, file path
  39. */
  40. bool save_matrix_as_ply(const MatrixXf& m, std::string path);
  41. /*
  42. * 将矩阵变为齐次
  43. */
  44. MatrixXf matrix_to_home(const MatrixXf& origin);
  45. /*
  46. * Rays from camera, for every pixel, a line cross this pixel and origin of camera coordinate
  47. * 每个像素拍摄的路径设为一个向量,本函数产生一个矩形平面,为每个像素生成这样一个向量,每个向量用两点定义,第一点为相机原点,
  48. * 第二点(x,y,z)为相机坐标系下给定z所求得的三维坐标,忽略镜头畸变
  49. * 参数:相机内参,相机分辨率,给定Z,camera_rays(相机坐标系下z=给定值的 rays from camera)
  50. * camrea_rays 格式: 3 x (img.h x img.w), 每列格式为(x,y,z),像素保存顺序为从左往右,从上往下
  51. */
  52. bool configCameraRay(const Matrix3f& cameraMatrix, const cv::Size& imageSize, float Z, MatrixXf& camera_rays);
  53. /*
  54. * 计算相机光线与参考平面的交点,参考平面用点法式表达
  55. * 参数:参考平面点,参考平面法线,rays from camera,保存交点矩阵
  56. * refPlane 格式:3 x (img.h x img.w), 每列格式为(x,y,z),像素保存顺序为从左往右,从上往下
  57. */
  58. bool configRefPlane(const Eigen::Vector3f& plane_point, const Eigen::Vector3f& plane_normal, const MatrixXf& camera_rays, MatrixXf& refPlane);
  59. /*
  60. * for every screen pixel, compute their position in world coordinate system
  61. * params: Screen information, rotation of screen relative to world, translation of screen relative to world, matrix save screen pixels postion,
  62. * screen_pix_pos 格式: 3 x (screen.h x screen.w), 每列格式为(x,y,z),像素保存顺序为从左往右,从上往下
  63. */
  64. bool configScreenPixelPos(const Screen& screen, const Matrix4f& WST, MatrixXf& screen_pix_pos);
  65. /*
  66. * 生成四步相移法条纹图案
  67. * 参数:图案尺寸,x,y方向周期,保存结果(size = 16,顺序为高频x,y,低频x,y)
  68. */
  69. // bool pattern_gen(std::vector<uint8_t> pat_size, std::vector<uint8_t> period, std::vector<MatrixXf>& pats);
  70. /* four step phase shifting
  71. * params: images(size=16), result wraped phase map(size=4)
  72. */
  73. bool phase_shifting(const std::vector<MatrixXf>& imgs, std::vector<MatrixXf>& wraped_ps_maps);
  74. /*
  75. * two frequency phase unwrapping
  76. * params: 包裹相位(高频竖条纹,高频横条纹,低频竖条纹,低频横条纹),高频竖条纹周期数,高频横条纹周期数,保存相位结果
  77. */
  78. bool phase_unwrapping(const vector<MatrixXf>& wraped_ps_maps, uint16_t period_width, uint16_t period_height, vector<MatrixXf>& unwrap_ps_maps);
  79. /*
  80. * 求屏幕上相位与相机img对应的像素的三维坐标
  81. * params:相位图,屏幕信息,条纹图宽度方向上周期数,高度方向周期数,屏幕像素位置,
  82. * 与相机img相位匹配的屏幕像素坐标(格式: 3 x (cam_img.w x cam_img.h), 每列格式为(x,y,z),像素保存顺序为从左往右,从上往下)
  83. */
  84. bool screen_camera_phase_match(const vector<MatrixXf>& unwrap_ps_maps, const Screen& screen, uint16_t period_width, uint16_t period_height,
  85. const MatrixXf& screen_pix_pos, MatrixXf& screen_camera_phase_match_pos);
  86. /*
  87. * 斜率计算
  88. * params: 相机光心坐标,参考平面,屏幕相机相位匹配,保存斜率结果X和Y方向,尺寸为1 x img.size
  89. */
  90. bool slope_calculate(const Vector3f& camera_world, const MatrixXf& refPlane, const MatrixXf& screen_camera_phase_match_pos,
  91. std::vector<MatrixXfR>& slope);
  92. /*
  93. * 从斜率恢复相位,modal 法,使用 Zernike polynomials
  94. * params: x方向斜率(M x N),y方向斜率,保存高度结果,x和y方向的物理尺寸范围(mm), Zernike polynomials 项数
  95. */
  96. bool modal_reconstruction(const MatrixXf& sx, const MatrixXf& sy, MatrixXfR& Z, const std::vector<float>& range, uint32_t terms);
  97. double computeReprojectionErrors(
  98. const vector<vector<cv::Point3f>>& objectPoints,
  99. const vector<vector<cv::Point2f>>& imagePoints,
  100. const vector<Mat>& rvecs, const vector<Mat>& tvecs,
  101. const Mat& cameraMatrix, const Mat& distCoeffs,
  102. vector<float>& perViewErrors);
  103. /*
  104. // aruco 标定板参数
  105. struct ArucoBoard {
  106. cv::Size markers_size;
  107. float markerLength; // unit: m
  108. float markerSeparation;
  109. cv::Ptr<cv::aruco::Dictionary> dictionary;
  110. float screenOffset_X;
  111. float screenOffset_Y;
  112. };
  113. bool aruco_analyze(const vector<Mat>& imgs_board, const ArucoBoard& board, const Mat& cameraMatrix, const Mat& distCoeffs, vector<Mat>& Rmats,
  114. vector<cv::Vec3f>& Tvecs, vector<vector<int>>& Ids, vector<vector<vector<cv::Point2f>>>& corners,
  115. vector<vector<vector<cv::Point2f>>>& rejectedCandidates, std::string output_dir);
  116. */
  117. /*
  118. * system geometry calibration
  119. * implement of paper "Flexible geometrical calibration for fringe-reflection
  120. measurement(2012)"
  121. */
  122. bool system_calib(vector<Matrix3f>& CVR, vector<Vector3f>& CVTL, Matrix3f& CSR, VectorXf& CSTL_D, vector<Vector3f>& n);
  123. class ArithPmd
  124. {
  125. public:
  126. ArithPmd();
  127. ~ArithPmd();
  128. public:
  129. cv::Size img_size; // 相机图像分辨率
  130. uint16_t period_width; // 宽度方向条纹周期数
  131. uint16_t period_height; // 高度方向条纹周期数
  132. cv::Mat mask0, mask1, mask2, mask3;
  133. private:
  134. Screen screen; // 屏幕信息
  135. ROI roi0,roi1,roi2,roi3; // 拍摄图片上的重建区域
  136. Matrix4f CTC0,CTC1, CTC2, CTC3;
  137. MatrixXf refPlane0, refPlane1, refPlane2, refPlane3;
  138. Vector3f camera_origin_world0, camera_origin_world1, camera_origin_world2, camera_origin_world3;
  139. MatrixXf screen_pix_pos0, screen_pix_pos1, screen_pix_pos2, screen_pix_pos3;
  140. MatrixXf roi_m0, roi_m1, roi_m2, roi_m3; // mask 区域的矩阵
  141. // std::vector<Matrix4f*> CTC{}; // 旋转平移矩阵
  142. // 计算出来的结果
  143. // std::vector<MatrixXf*> refPlane{}; // 相机光线与参考平面的交点,世界坐标系下,3 x (img.h x img.w)
  144. // std::vector <Vector3f*> camera_origin_world{ }; // 相机坐标系原点在世界坐标系下的表示
  145. // std::vector<MatrixXf*> screen_pix_pos{};// 屏幕像素在世界坐标系下的位置,3 x (screen.h x screen.w)
  146. // std::vector<Mat> patterns; // 投影的条纹图案
  147. // std::vector<Eigen::MatrixXf> img_pats; // 拍摄的条纹图像
  148. // uint16_t screen_delay; // 投影条纹时等待的时间(毫秒)
  149. public:
  150. int Initlization(const nlohmann::json& param);
  151. int Preprocess(const std::vector<cv::Mat>& images, int area_threshold, int32_t camera_index);
  152. int Predict(const std::vector<Eigen::MatrixXf>& img_pats, MatrixXfR& pcl, int32_t camera_index);
  153. int Stitch(const pcl::PointCloud<pcl::PointXYZ>& cloud1, const pcl::PointCloud<pcl::PointXYZ>& cloud2, pcl::PointCloud<pcl::PointXYZ>& cloud_output, int32_t camera_index);
  154. };
  155. #endif // ARITHPMD_H