point3D_tool.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #pragma once
  2. #include <pcl/point_cloud.h>
  3. #include <pcl/point_types.h>
  4. #include <vector>
  5. #include <opencv4/opencv2/opencv.hpp>
  6. #include "tool/log.hpp"
  7. class Point3D_tool
  8. {
  9. public:
  10. static bool WriteTxtCloud(const std::string &file, pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud) {
  11. DLOG(INFO) << "begain push point data to " << file;
  12. std::fstream fileTxtCloud;
  13. fileTxtCloud.open(file, std::ios_base::trunc | std::ios::in | std::ios::out);
  14. for (auto &point: *cloud) {
  15. fileTxtCloud << point.x << " " << point.y << " " << point.z << std::endl;
  16. }
  17. fileTxtCloud.close();
  18. DLOG(INFO) << "Push point complete, push point number: " << cloud->size();
  19. return true;
  20. }
  21. static bool WriteTxtCloud(const std::string &file, pcl::PointCloud<pcl::PointXYZI>::Ptr &cloud) {
  22. DLOG(INFO) << "begain push point data to " << file;
  23. std::fstream fileTxtCloud;
  24. fileTxtCloud.open(file, std::ios_base::trunc | std::ios::in | std::ios::out);
  25. for (auto &point: *cloud) {
  26. fileTxtCloud << point.x << " " << point.y << " " << point.z << std::endl;
  27. }
  28. fileTxtCloud.close();
  29. DLOG(INFO) << "Push point complete, push point number: " << cloud->size();
  30. return true;
  31. }
  32. static bool ReadTxtCloud(const std::string &file, pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud) {
  33. DLOG(INFO) << "Load point data form file: " << file;
  34. std::ifstream fin(file.c_str());
  35. if (fin.bad()) {
  36. LOG(WARNING) << "File " << file << " don't exist.";
  37. return false;
  38. }
  39. const int line_length = 64;
  40. char str[line_length] = {0};
  41. while (fin.getline(str, line_length)) {
  42. pcl::PointXYZ point{};
  43. if (string2PointXYZ(str, point)) {
  44. cloud->push_back(point);
  45. }
  46. }
  47. DLOG(INFO) << "Load point complete, get point number: " << cloud->size();
  48. return true;
  49. }
  50. template <typename PclPoint>
  51. static int getMinRect(cv::RotatedRect &rect, pcl::shared_ptr<pcl::PointCloud<PclPoint>> &clouds) {
  52. if (clouds->points.size() < 4) {
  53. DLOG(ERROR) << "points to little.";
  54. return false;
  55. }
  56. std::vector<cv::Point2f> cv_clouds;
  57. for (auto &point: clouds->points) {
  58. cv_clouds.emplace_back(point.x, point.y);
  59. }
  60. rect = cv::minAreaRect(cv_clouds);
  61. return true;
  62. }
  63. // template <typename PclPoint>
  64. static int getRectCloud(cv::RotatedRect &rect, pcl::shared_ptr<pcl::PointCloud<pcl::PointXYZ>> &points, float z_value = 0, int numbers = 100) {
  65. cv::Point2f cv_points[4];
  66. rect.points(cv_points);
  67. // PclPoint point;
  68. pcl::PointXYZ point;
  69. // 左侧点
  70. double step_x = (cv_points[1].x - cv_points[0].x) / numbers;
  71. double step_y = (cv_points[1].y - cv_points[0].y) / numbers;
  72. for (int i = 0; i < numbers; i++) {
  73. point.x = cv_points[0].x + i * step_x;
  74. point.y = cv_points[0].y + i * step_y;
  75. point.z = z_value;
  76. points->points.emplace_back(point);
  77. }
  78. // 上侧点
  79. step_x = (cv_points[2].x - cv_points[1].x) / numbers;
  80. step_y = (cv_points[2].y - cv_points[1].y) / numbers;
  81. for (int i = 0; i < numbers; i++) {
  82. point.x = cv_points[1].x + i * step_x;
  83. point.y = cv_points[1].y + i * step_y;
  84. point.z = z_value;
  85. points->points.emplace_back(point);
  86. }
  87. // 右侧点
  88. step_x = (cv_points[3].x - cv_points[2].x) / numbers;
  89. step_y = (cv_points[3].y - cv_points[2].y) / numbers;
  90. for (int i = 0; i < numbers; i++) {
  91. point.x = cv_points[2].x + i * step_x;
  92. point.y = cv_points[2].y + i * step_y;
  93. point.z = z_value;
  94. points->points.emplace_back(point);
  95. }
  96. // 下侧点
  97. step_x = (cv_points[0].x - cv_points[3].x) / numbers;
  98. step_y = (cv_points[0].y - cv_points[3].y) / numbers;
  99. for (int i = 0; i < numbers; i++) {
  100. point.x = cv_points[3].x + i * step_x;
  101. point.y = cv_points[3].y + i * step_y;
  102. point.z = z_value;
  103. points->points.emplace_back(point);
  104. }
  105. return points->size();
  106. }
  107. template <typename PclPoint>
  108. static int getRectCloud(pcl::shared_ptr<pcl::PointCloud<PclPoint>> &clouds, pcl::shared_ptr<pcl::PointCloud<pcl::PointXYZ>> &points, float z_value = 0, int numbers = 100) {
  109. cv::RotatedRect rect = getMinRect(clouds);
  110. getRectCloud(rect, points, z_value, numbers);
  111. return points->size();
  112. }
  113. static void getRectWidthlength(cv::RotatedRect &rect, double &width, double &length) {
  114. cv::Point2f points[4];
  115. rect.points(points);
  116. double a = sqrt((points[1].x - points[0].x) * (points[1].x - points[0].x) + (points[1].y - points[0].y) * (points[1].y - points[0].y));
  117. double b = sqrt((points[2].x - points[1].x) * (points[2].x - points[1].x) + (points[2].y - points[1].y) * (points[2].y - points[1].y));
  118. width = MIN(a, b);
  119. length = MAX(a, b);
  120. }
  121. private:
  122. static bool string2PointXYZ(const std::string &str, pcl::PointXYZ &point) {
  123. std::istringstream iss;
  124. iss.str(str);
  125. float value;
  126. float data[3];
  127. for (int i = 0; i < 3; ++i) {
  128. if (iss >> value) {
  129. data[i] = value;
  130. } else {
  131. return false;
  132. }
  133. }
  134. point.x = data[0];
  135. point.y = data[1];
  136. point.z = data[2];
  137. return true;
  138. }
  139. };