pcl-helper.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #include "pcl-helper.hpp"
  2. // Get RGB values based on normals - texcoords, normals value [u v]
  3. std::tuple<uint8_t, uint8_t, uint8_t> PCLHelper::get_texcolor(rs2::video_frame texture, rs2::texture_coordinate texcoords)
  4. {
  5. const int w = texture.get_width(), h = texture.get_height();
  6. // convert normals [u v] to basic coords [x y]
  7. int x = std::min(std::max(int(texcoords.u * w + .5f), 0), w - 1);
  8. int y = std::min(std::max(int(texcoords.v * h + .5f), 0), h - 1);
  9. int idx = x * texture.get_bytes_per_pixel() + y * texture.get_stride_in_bytes();
  10. const auto texture_data = reinterpret_cast<const uint8_t *>(texture.get_data());
  11. return std::tuple<uint8_t, uint8_t, uint8_t>(texture_data[idx], texture_data[idx + 1], texture_data[idx + 2]);
  12. }
  13. PtrCloud PCLHelper::points_to_pcl(const rs2::points &points, const rs2::video_frame &color)
  14. {
  15. auto sp = points.get_profile().as<rs2::video_stream_profile>();
  16. PtrCloud cloud(new PointCloudRGB);
  17. // Config of PCL Cloud object
  18. cloud->width = static_cast<uint32_t>(sp.width());
  19. cloud->height = static_cast<uint32_t>(sp.height());
  20. cloud->is_dense = false;
  21. cloud->points.resize(points.size());
  22. auto tex_coords = points.get_texture_coordinates();
  23. auto vertices = points.get_vertices();
  24. // Iterating through all points and setting XYZ coordinates and RGB values
  25. for (int i = 0; i < points.size(); ++i)
  26. {
  27. cloud->points[i].x = vertices[i].x;
  28. cloud->points[i].y = vertices[i].y;
  29. cloud->points[i].z = vertices[i].z;
  30. std::tuple<uint8_t, uint8_t, uint8_t> current_color;
  31. current_color = get_texcolor(color, tex_coords[i]);
  32. // Reversed order- 2-1-0 because of BGR (Blue, Green, Red) model used in camera
  33. cloud->points[i].r = std::get<2>(current_color);
  34. cloud->points[i].g = std::get<1>(current_color);
  35. cloud->points[i].b = std::get<0>(current_color);
  36. }
  37. return cloud;
  38. }
  39. void PCLHelper::convert_and_save_ply(const std::string &fileName, const rs2::points &points, const rs2::video_frame &color)
  40. {
  41. PtrCloud cloud = points_to_pcl(points, color);
  42. pcl::io::savePLYFile(fileName, *cloud);
  43. }
  44. void PCLHelper::save_to_ply(const std::string folderPath, const std::string &fileName, const PtrCloud &cloud)
  45. {
  46. std::filesystem::create_directories(folderPath);
  47. pcl::io::savePLYFile(folderPath + fileName, *cloud);
  48. }
  49. int PCLHelper::icp(PtrCloud &cloud_target, PtrCloud &cloud_source, int iterations)
  50. {
  51. std::cout << "\ntarget cloud size is: " << cloud_target->size() << std::endl;
  52. std::cout << "\nsource cloud size is: " << cloud_source->size() << std::endl;
  53. // TODO: make this faster
  54. // icp algo will align source pointcloud to fit target pointcloud
  55. pcl::IterativeClosestPoint<PointRGB, PointRGB> icp;
  56. icp.setMaximumIterations(iterations);
  57. icp.setInputSource(cloud_source); // will be transformed to fit target
  58. icp.setInputTarget(cloud_target); // will be the base cloud
  59. icp.align(*cloud_source);
  60. if (icp.hasConverged())
  61. {
  62. std::cout << "\nICP has converged, score is " << icp.getFitnessScore() << std::endl;
  63. return 0;
  64. }
  65. else
  66. {
  67. PCL_ERROR("\nICP has not converged.\n");
  68. return (-1);
  69. }
  70. }
  71. PtrCloud PCLHelper::crop_cloud(PtrCloud &cloud, float min_x, float min_y, float min_z, float max_x, float max_y, float max_z)
  72. {
  73. Eigen::Vector4f minPoint(min_x, min_y, min_z, 1);
  74. Eigen::Vector4f maxPoint(max_x, max_y, max_z, 1);
  75. pcl::CropBox<PointRGB> cropFilter;
  76. cropFilter.setInputCloud(cloud);
  77. cropFilter.setMin(minPoint);
  78. cropFilter.setMax(maxPoint);
  79. // cropFilter.setKeepOrganized(true);
  80. PtrCloud cropped_cloud(new PointCloudRGB);
  81. cropFilter.filter(*cropped_cloud);
  82. return cropped_cloud;
  83. }