grab_point_rs.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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. #include "grab_occlusion.h"
  10. namespace graft_cv {
  11. class CRootStockGrabPoint {
  12. public:
  13. CRootStockGrabPoint(ConfigParam&c, CGcvLogger*pLog = 0);
  14. ~CRootStockGrabPoint();
  15. int grab_point_detect(PositionInfo& posinfo);
  16. float* get_raw_point_cloud(int &data_size);
  17. int load_data(float*pPoint, int pixel_size, int pt_size, int dtype, const char* fn = 0);
  18. void set_image_saver(CImStoreManager** ppis) { m_ppImgSaver = ppis; }
  19. private:
  20. //global configure parameters
  21. ConfigParam& m_cparam;
  22. CGcvLogger * m_pLogger;
  23. int m_dtype;
  24. string m_pcdId;
  25. //历史植株位置信息
  26. CStemResultInfos* m_pStemInfos;
  27. std::string m_stem_info_file;
  28. std::vector<CStemResult> m_root_centers; //通过m_pStemInfos获取到历史根中心位置
  29. std::vector<int> m_root_center_pcd_size;
  30. std::vector<bool> m_root_center_with_seedling; //m_root_centers位置上是否含有植株
  31. //用于记录第一排z均值,用来辅助判别1、2排的苗
  32. float m_1st_row_zmean_rs = -1.0;
  33. float m_1st_row_zmean_sc = -1.0;
  34. CImStoreManager** m_ppImgSaver;
  35. //返回图片,用于调试
  36. ImgInfo* m_pImginfoResult;//识别结果的图片
  37. pcl::PointCloud<pcl::PointXYZ>::Ptr m_raw_cloud;
  38. double m_cloud_mean_dist;
  39. void clear_imginfo();
  40. int read_ply_file(const char* fn);
  41. double compute_nearest_neighbor_distance(pcl::PointCloud<pcl::PointXYZ>::Ptr);
  42. /////////////////////////////////////////////////////////////////////////////////////
  43. //叶子剔除,通过欧式距离聚类,然后判断每一个类别是否是叶子
  44. // 出现的问题:叶子和茎通过叶柄连接时,会误判
  45. void leaf_filter(
  46. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud,
  47. std::vector<int> &stem_cloud_idx
  48. );
  49. void leaf_filter_ror(
  50. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud, //input 输入点云数据
  51. std::vector<int> &stem_cloud_idx, //output, 过滤后的点云序号
  52. std::vector<int>& leaf_idx //output, 叶子的点云序号
  53. );
  54. void cloud_mean_dist(
  55. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud, //input 输入点云数据
  56. double& mean_dist
  57. );
  58. //////////////////////////////////////////////////////////////////////////////////////
  59. void CRootStockGrabPoint::find_fork(
  60. pcl::PointCloud<pcl::PointXYZ>::Ptr in_line_cloud,
  61. float& max_dist,//最大距离
  62. int& max_idx //距离边界最大的点序号
  63. );
  64. void gen_all_seedling_positions(
  65. pcl::PointXYZ&key_center, //输入,已知的苗的坐标
  66. std::vector<pcl::PointXYZ>&candidate_center //输出,有倾斜苗的坐标
  67. );
  68. bool find_seedling_position_key(
  69. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud,
  70. std::vector<int> &first_seedling_cloud_idx,
  71. pcl::PointXYZ&xz_center,
  72. pcl::ModelCoefficients::Ptr& lmodel,
  73. int& first_row_size //返回第一排植株的数量
  74. );
  75. // 邻域最小抑制
  76. void nms_box(
  77. std::vector<pcl::PointXYZ>&clt_root_v, //目标点的可能位置
  78. std::vector<float>&valid_box_cc_dist, //目标点的重心到中心的距离,距离越近越好
  79. float hole_step_radius, //目标点搜索半径
  80. std::vector<pcl::PointXYZ>& target_toot // 返回值
  81. );
  82. //通过指定位置内,取部分点云分析是否存在真正的茎,真茎位置保存到target_filtered
  83. void line_filter(pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud, //输入点云
  84. float radius, //输入,取点半径
  85. float ymin, //输入,y最小值
  86. float ymax, //输入,y最大值
  87. std::vector<pcl::PointXYZ>&target_root, //输入,位置
  88. std::vector<pcl::PointXYZ>&target_filtered, //输出,位置
  89. std::vector<pcl::PointXYZ>&target_filtered_root, //输出,茎上根部点坐标
  90. std::vector<std::vector<int>>&target_filtered_element, //输出,茎上点index
  91. std::vector<pcl::ModelCoefficients::Ptr>& target_filtered_models//输出,茎直线模型
  92. );
  93. void get_line_project_hist(
  94. pcl::PointCloud<pcl::PointXYZ>::Ptr in_line_cloud, //input 茎上直线点云
  95. pcl::ModelCoefficients::Ptr line_model, //input
  96. std::vector<int>& count_hist // 返回有效直线1mm内点云数量
  97. );
  98. /////////////////////////////////////////////////
  99. void find_seedling_position(
  100. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud,
  101. std::vector<int> &first_seedling_cloud_idx,
  102. pcl::PointXYZ&xz_center
  103. );
  104. void crop_nn_analysis(
  105. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud,
  106. pcl::PointCloud<pcl::PointXYZ>::Ptr seed_cloud,
  107. double dist_mean,
  108. std::vector<double>&mass_indices,
  109. std::vector<int>& idx
  110. );
  111. void euclidean_clustering_ttsas(
  112. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud,
  113. double d1, double d2,
  114. std::vector<pcl::PointXYZ>&cluster_center,
  115. std::vector<std::vector<int>> &clustr_member
  116. );
  117. void cal_obb_2d(
  118. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud,
  119. int axis,
  120. double &dx_obb,
  121. double &dy_obb,
  122. double &angle_obb);
  123. //已知检测出苗的位置,找出有可能有苗的位置
  124. void tilted_seedling_discover(
  125. std::vector<pcl::PointXYZ>&cluster_center, //输入,已知的苗的坐标
  126. std::vector<pcl::PointXYZ>&tilted_center //输出,有倾斜苗的坐标
  127. );
  128. //通过比较直线点云和原始点云相同位置邻域内xz的范围,确定此点是否是无干扰点的茎
  129. void get_optimal_seed_compare(
  130. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud, //input
  131. pcl::PointCloud<pcl::PointXYZ>::Ptr in_line_cloud, //input
  132. pcl::ModelCoefficients::Ptr line_model, //input
  133. pcl::PointXYZ&pt, //输出,
  134. pcl::PointXYZ &pt_ref, //输出, 返回点茎节的参考点
  135. float& stem_width_mu, //输出,茎宽度,直径
  136. float& stem_deflection //输出,茎的最大挠度,最大弯曲处的偏离直径轴心的距离,毫米
  137. );
  138. //计算茎的弯曲度:点云到直线距离的95分位
  139. double calculate_deflection(
  140. pcl::PointCloud<pcl::PointXYZ>::Ptr in_line_cloud, //input
  141. pcl::ModelCoefficients::Ptr line_model //input
  142. );
  143. //在一株苗的空间范围内找出直线(茎,假设茎是直线分布的),并返回直线上的点index
  144. void find_line_in_cube(
  145. pcl::PointCloud<pcl::PointXYZ>::Ptr, //输入,整体点云
  146. pcl::PointXYZ& min_pt_ex, //输入,
  147. pcl::PointXYZ& max_pt_ex, //输入,
  148. std::vector<int>& out_idx //输出,直线上点的index, 基于输入整体点云
  149. );
  150. //生成结果图片
  151. void gen_result_img(
  152. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud_raw,//输入,未经过滤的整体点云in_cloud_raw,
  153. pcl::PointCloud<pcl::PointXYZ>::Ptr, //输入,整体点云cloud_dowm_sampled,
  154. pcl::PointXYZ& selected_pt, //输入,selected_pt,
  155. pcl::PointXYZ& selected_pt_ref, //输入,selected_pt_ref,
  156. const PositionInfo& posinfo, //输入,
  157. cv::Mat& rst_img //输出,图片, 640*1280
  158. );
  159. //根据历史根的位置,计算对应位置点云数量,进而判断此位置是否有苗
  160. void occluded_seedling_detect_by_leaf(
  161. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud, //input 输入点云数据
  162. std::vector<int>& leaf_idx); //input
  163. int get_point_count_inbox(const CStemResult& sr, //input
  164. pcl::PointXYZ& aabb_min, //output
  165. pcl::PointXYZ& aabb_max, //output
  166. pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud //input 输入点云数据
  167. );
  168. //没有检测到苗的情况,后处理
  169. void no_seedling_detected_post_process(
  170. int first_row_seedling_number, //input
  171. int& selected_idx, //output, 选择root_center的序号
  172. pcl::PointXYZ& selected_pt, //output
  173. pcl::PointXYZ& selected_pt_ref, //output
  174. PositionInfo& posinfo //output
  175. );
  176. //检测到苗的情况,后处理
  177. void had_seedling_detected_post_process(
  178. int first_row_seedling_number, //input
  179. float stem_width_mu, //input
  180. float stem_deflection, //input
  181. int& selected_idx, //output, 选择root_center的序号
  182. pcl::PointXYZ& selected_pt, //input-output
  183. pcl::PointXYZ& selected_pt_ref, //input-output
  184. PositionInfo& posinfo //output
  185. );
  186. void viewer_cloud(pcl::PointCloud<pcl::PointXYZ>::Ptr, std::string&winname);
  187. void viewer_cloud(pcl::PointCloud<pcl::PointXYZRGB>::Ptr, std::string&winname);
  188. void viewer_cloud_debug(
  189. pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud,
  190. pcl::PointXYZ&p,//抓取点
  191. pcl::PointXYZ &p_ref,//分叉点
  192. pcl::PointXYZ &root_pt,
  193. std::string&winname);
  194. void viewer_cloud_cluster(pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud, std::vector<pcl::PointXYZ>cluster_center, std::string&winname);
  195. void viewer_cloud_cluster_box(
  196. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
  197. std::vector<pcl::PointXYZ>&cluster_center,
  198. std::vector<pcl::PointXYZ>&cluster_box,
  199. std::vector<std::vector<int> >& clt_line_idx,
  200. std::string&winname);
  201. };
  202. };