grab_point_rs.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #pragma once
  2. #include <pcl\point_types.h>
  3. #include <pcl\point_cloud.h>
  4. #include <pcl\segmentation\sac_segmentation.h>
  5. #include "data_def_api.h"
  6. #include "data_def.h"
  7. #include "logger.h"
  8. #include "imstorage_manager.h"
  9. namespace graft_cv {
  10. class CRootStockGrabPoint {
  11. public:
  12. CRootStockGrabPoint(ConfigParam&c, CGcvLogger*pLog = 0);
  13. ~CRootStockGrabPoint();
  14. int grab_point_detect(PositionInfo& posinfo);
  15. float* get_raw_point_cloud(int &data_size);
  16. int load_data(float*pPoint, int pixel_size, int pt_size, int dtype, const char* fn = 0);
  17. void set_image_saver(CImStoreManager** ppis) { m_ppImgSaver = ppis; }
  18. private:
  19. //global configure parameters
  20. ConfigParam& m_cparam;
  21. CGcvLogger * m_pLogger;
  22. int m_dtype;
  23. string m_pcdId;
  24. //用于记录第一排z均值,用来辅助判别1、2排的苗
  25. float m_1st_row_zmean_rs = -1.0;
  26. float m_1st_row_zmean_sc = -1.0;
  27. CImStoreManager** m_ppImgSaver;
  28. pcl::PointCloud<pcl::PointXYZ>::Ptr m_raw_cloud;
  29. int read_ply_file(const char* fn);
  30. double compute_nearest_neighbor_distance(pcl::PointCloud<pcl::PointXYZ>::Ptr);
  31. ////////////////////////////////////////////////
  32. //---> 2023-8-8优化,seedling order识别错误问题
  33. /*void CRootStockGrabPoint::find_tray_top_edge(
  34. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud,
  35. float & tray_top_edge_y
  36. );
  37. void CRootStockGrabPoint::find_seedling_position_line_based(
  38. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud,
  39. std::vector<int> &first_seedling_cloud_idx,
  40. pcl::PointXYZ&xz_center
  41. );
  42. void segement_line(
  43. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud
  44. );*/
  45. //<---------
  46. /////////////////////////////////////////////////////////////////////////////////////
  47. //叶子剔除,通过欧式距离聚类,然后判断每一个类别是否是叶子
  48. // 出现的问题:叶子和茎通过叶柄连接时,会误判
  49. void leaf_filter(
  50. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud,
  51. std::vector<int> &stem_cloud_idx
  52. );
  53. //////////////////////////////////////////////////////////////////////////////////////
  54. //叶子剔除,通过形态学方法,腐蚀,得到叶子区域,将叶子区域内地的点云去掉
  55. void leaf_filter_morph(
  56. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud, //input 输入点云数据
  57. std::vector<int> &stem_cloud_idx //output, 过滤后的点云序号
  58. );
  59. //生成3d图像
  60. void gen_3d_image(
  61. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud, //input 输入点云数据
  62. pcl::PointXYZ& min_pt, //input 图像下限
  63. pcl::PointXYZ& max_pt, //input 图像上限
  64. float step, //input 图像像素间隔
  65. cv::Mat& bin_3d_img, //output, 生成的binary图像
  66. std::map<int, std::vector<int>>& id2pcdidx
  67. );
  68. //3*3*3内的膨胀
  69. void dilation_3d(
  70. cv::Mat& in_3d_img, //input, 输入图像
  71. cv::Mat& out_3d_img //output, 生成的图像
  72. );
  73. //3*3*3内的腐蚀
  74. void erosion_3d(
  75. cv::Mat& in_3d_img,
  76. int th, //阈值
  77. cv::Mat& out_3d_img
  78. );
  79. //得到点云序号
  80. void get_mass_obj_idx(
  81. cv::Mat& open_3d_img, //input, 开运算后的图像
  82. std::map<int, std::vector<int>>& id2pcdidx, //input 保存的像素位置的点云序号
  83. std::vector<int>& mass_idx //output,
  84. );
  85. //////////////////////////////////////////////////////////////////////////////////////
  86. //叶子剔除,通过形态学方法
  87. void leaf_filter_ror(
  88. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud, //input 输入点云数据
  89. std::vector<int> &stem_cloud_idx //output, 过滤后的点云序号
  90. );
  91. void cloud_mean_dist(
  92. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud, //input 输入点云数据
  93. double& mean_dist
  94. );
  95. //////////////////////////////////////////////////////////////////////////////////////
  96. void gen_all_seedling_positions(
  97. pcl::PointXYZ&key_center, //输入,已知的苗的坐标
  98. std::vector<pcl::PointXYZ>&candidate_center //输出,有倾斜苗的坐标
  99. );
  100. void find_seedling_position_key(
  101. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud,
  102. std::vector<int> &first_seedling_cloud_idx,
  103. pcl::PointXYZ&xz_center,
  104. pcl::ModelCoefficients::Ptr& lmodel
  105. );
  106. // 邻域最小抑制
  107. void nms_box(
  108. std::vector<pcl::PointXYZ>&clt_root_v, //目标点的可能位置
  109. std::vector<float>&valid_box_cc_dist, //目标点的重心到中心的距离,距离越近越好
  110. float hole_step_radius, //目标点搜索半径
  111. std::vector<pcl::PointXYZ>& target_toot // 返回值
  112. );
  113. //通过指定位置内,取部分点云分析是否存在真正的茎,真茎位置保存到target_filtered
  114. void line_filter(pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud, //输入点云
  115. float radius, //输入,取点半径
  116. float ymin, //输入,y最小值
  117. float ymax, //输入,y最大值
  118. std::vector<pcl::PointXYZ>&target_root, //输入,位置
  119. std::vector<pcl::PointXYZ>&target_filtered, //输出,位置
  120. std::vector<pcl::PointXYZ>&target_filtered_root, //输出,茎上根部点坐标
  121. std::vector<std::vector<int>>&target_filtered_element, //输出,茎上点index
  122. std::vector<pcl::ModelCoefficients::Ptr>& target_filtered_models//输出,茎直线模型
  123. );
  124. /////////////////////////////////////////////////
  125. void find_seedling_position(
  126. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud,
  127. std::vector<int> &first_seedling_cloud_idx,
  128. pcl::PointXYZ&xz_center
  129. );
  130. void crop_nn_analysis(
  131. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud,
  132. pcl::PointCloud<pcl::PointXYZ>::Ptr seed_cloud,
  133. double dist_mean,
  134. std::vector<double>&mass_indices,
  135. std::vector<int>& idx
  136. );
  137. void euclidean_clustering_ttsas(
  138. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud,
  139. double d1, double d2,
  140. std::vector<pcl::PointXYZ>&cluster_center,
  141. std::vector<std::vector<int>> &clustr_member
  142. );
  143. void cal_obb_2d(
  144. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud,
  145. int axis,
  146. double &dx_obb,
  147. double &dy_obb,
  148. double &angle_obb);
  149. void get_optimal_seed(
  150. pcl::PointCloud<pcl::PointXYZ>::Ptr,
  151. pcl::PointXYZ&pt,
  152. int &pt_idx);
  153. //已知检测出苗的位置,找出有可能有苗的位置
  154. void tilted_seedling_discover(
  155. std::vector<pcl::PointXYZ>&cluster_center, //输入,已知的苗的坐标
  156. std::vector<pcl::PointXYZ>&tilted_center //输出,有倾斜苗的坐标
  157. );
  158. //通过比较直线点云和原始点云相同位置邻域内xz的范围,确定此点是否是无干扰点的茎
  159. /*void get_optimal_seed_compare(
  160. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud,
  161. pcl::PointCloud<pcl::PointXYZ>::Ptr in_line_cloud,
  162. pcl::PointXYZ&pt,
  163. int &pt_idx,
  164. std::vector<int>& valid_line_index
  165. );*/
  166. //通过比较直线点云和原始点云相同位置邻域内xz的范围,确定此点是否是无干扰点的茎
  167. void get_optimal_seed_compare(
  168. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud, //input
  169. pcl::PointCloud<pcl::PointXYZ>::Ptr in_line_cloud, //input
  170. pcl::ModelCoefficients::Ptr line_model, //input
  171. pcl::PointXYZ&pt,
  172. int &pt_idx,
  173. std::vector<int>& valid_line_index
  174. );
  175. //在一株苗的空间范围内找出直线(茎,假设茎是直线分布的),并返回直线上的点index
  176. void find_line_in_cube(
  177. pcl::PointCloud<pcl::PointXYZ>::Ptr, //输入,整体点云
  178. pcl::PointXYZ& min_pt_ex, //输入,
  179. pcl::PointXYZ& max_pt_ex, //输入,
  180. std::vector<int>& out_idx //输出,直线上点的index, 基于输入整体点云
  181. );
  182. //生成结果图片
  183. void gen_result_img(
  184. pcl::PointCloud<pcl::PointXYZ>::Ptr, //输入,整体点云cloud_dowm_sampled,
  185. pcl::PointXYZ& selected_pt, //输入,selected_pt,
  186. cv::Mat& rst_img //输出,图片, 640*1280
  187. );
  188. void viewer_cloud(pcl::PointCloud<pcl::PointXYZ>::Ptr, std::string&winname);
  189. void viewer_cloud(pcl::PointCloud<pcl::PointXYZRGB>::Ptr, std::string&winname);
  190. void viewer_cloud_debug(
  191. pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud,
  192. pcl::PointXYZ&p,
  193. pcl::PointXYZ &root_pt,
  194. std::string&winname);
  195. void viewer_cloud_cluster(pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud, std::vector<pcl::PointXYZ>cluster_center, std::string&winname);
  196. void viewer_cloud_cluster_box(
  197. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
  198. std::vector<pcl::PointXYZ>&cluster_center,
  199. std::vector<pcl::PointXYZ>&cluster_box,
  200. std::vector<std::vector<int> >& clt_line_idx,
  201. std::string&winname);
  202. };
  203. };