Procházet zdrojové kódy

v0.8.12 优化茎粗检测功能,采用xy面投影茎粗统计结果

chenhongjiang před 1 rokem
rodič
revize
30afd57a01
4 změnil soubory, kde provedl 19 přidání a 11 odebrání
  1. 2 1
      ReadMe.txt
  2. 13 7
      grab_point_rs.cpp
  3. 3 2
      grab_point_rs.h
  4. 1 1
      graft_cv_api.cpp

+ 2 - 1
ReadMe.txt

@@ -120,4 +120,5 @@ v0.8.7 抓取顺
 v0.8.8 砧木固定抓取位置,输出茎节高度;
 v0.8.9 输出多个茎节高度(最多3个);穗苗抓取逻辑修改;
 v0.8.10 优化茎节识别,实现邻域对比过滤,最近距离过滤,增加xx_grab_fork_ratio控制茎节检出;增加扩展茎粗检测茎节功能
-v0.8.11 优化增加扩展茎粗检测茎节功能,减小ex范围从单侧1.5到1.05
+v0.8.11 优化增加扩展茎粗检测茎节功能,减小ex范围从单侧1.5到1.05
+v0.8.12 优化茎粗检测功能,采用xy面投影茎粗统计结果

+ 13 - 7
grab_point_rs.cpp

@@ -2541,13 +2541,12 @@ void CRootStockGrabPoint::line_filter(
 				valid_stem_width.push_back(w);
 			}
 		}
-		float mu = get_hist_mean(valid_stem_width);
-		stem_width_mu = mu;
+		float mu = get_hist_mean(valid_stem_width);		
 		float stdv = get_hist_std(valid_stem_width, mu);
 		
 		//找到茎节
 		std::vector<int> fork_positions;
-		find_fork(in_line_cloud, stem_width_mu, stem_width, fork_positions);
+		find_fork(in_line_cloud, mu, stem_width, fork_positions, stem_width_mu);
 		for (auto&y : fork_positions) {
 			fork_ys.push_back(y + ymin);
 		}
@@ -2713,12 +2712,14 @@ void CRootStockGrabPoint::line_filter(
 		pcl::PointCloud<pcl::PointXYZ>::Ptr in_line_cloud,
 		//float& max_dist,
 		//int& max_idx,
-		float stem_width_mu,
+		float stem_width_ex_mu,//输入, 通过外沿矩形得到的x方向茎粗均值
 		const std::vector<float>& stem_width_ex,//输入, 通过外沿矩形得到的x方向茎粗
-		std::vector<int>&fork_pos //输出, 多个fork位置
+		std::vector<int>&fork_pos,  //输出, 多个fork位置
+		float& stem_width_mu //输出, xy投影上x方向的茎粗均值
 	) 
 	{
 		fork_pos.clear();
+		stem_width_mu = 0.0;
 		//1 project to xy plane
 		pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_line_2d(new pcl::PointCloud<pcl::PointXYZ>);
 		pcl::copyPointCloud(*in_line_cloud, *cloud_line_2d);
@@ -2807,7 +2808,8 @@ void CRootStockGrabPoint::line_filter(
 		float mean_r = 0.0;
 		float cnt = 0.0;
 		for (auto&r : stem_diameters) {
-			if (r > 0.0) {
+			if (r > 0.5) {
+				//边缘点有可能被遗漏造成半径很小,将很小的半径去除(即小于直径1.0的苗,认为是异常,剔除异常数据)
 				mean_r += r;
 				cnt += 1.0;
 			}
@@ -2815,6 +2817,10 @@ void CRootStockGrabPoint::line_filter(
 		if (cnt > 0.0) {
 			mean_r /= cnt;
 		}
+		std::vector<float> stem_diameters_cpy(stem_diameters);
+		std::sort(stem_diameters_cpy.begin(),stem_diameters_cpy.end());
+		int idx80 = int(0.8*stem_diameters_cpy.size());
+		stem_width_mu = 2.0 * stem_diameters_cpy.at(idx80);
 
 		int del_radius = 4;
 		int security_r = (int)(stemd / 2.0 + 0.5);//保护半径
@@ -2859,7 +2865,7 @@ void CRootStockGrabPoint::line_filter(
 		while (true) {
 			//找到最大值的位置和最大值
 			int midx = max_element(stem_width_ex_cp.begin(), stem_width_ex_cp.end()) - stem_width_ex_cp.begin();
-			if (stem_width_ex_cp.at(midx) > th_fork * stem_width_mu) {				
+			if (stem_width_ex_cp.at(midx) > th_fork * stem_width_ex_mu) {
 				//检测fork_pos中的近邻是否存在
 				bool has_nn = false;
 				for (auto& fy : fork_pos) {

+ 3 - 2
grab_point_rs.h

@@ -74,9 +74,10 @@ namespace graft_cv {
 		//////////////////////////////////////////////////////////////////////////////////////
 		void  CRootStockGrabPoint::find_fork(
 			pcl::PointCloud<pcl::PointXYZ>::Ptr in_line_cloud,	
-			float stem_width_mu,//输入,stem_width_ex中有效值的均值
+			float stem_width_ex_mu,//输入,stem_width_ex中有效值的均值
 			const std::vector<float>& stem_width_ex,//输入, 通过外沿矩形得到的x方向茎粗
-			std::vector<int>&fork_pos //输出, 多个fork位置
+			std::vector<int>&fork_pos, //输出, 多个fork位置
+			float& stem_width_mu //输出, xy投影上x方向的茎粗均值
 		);
 
 

+ 1 - 1
graft_cv_api.cpp

@@ -15,7 +15,7 @@ extern CRITICAL_SECTION g_cs;
 namespace graft_cv
 {
 
-	char *g_version_str = "0.8.11";
+	char *g_version_str = "0.8.12";
 
 	//configure
 	string g_conf_file = "./gcv_conf.yml";