Browse Source

v0.7.17 优化茎节位置识别,不存在显著茎节的用平均茎节高度替代,否则用识别到的茎节位置

chenhongjiang 1 year ago
parent
commit
ed200705e6
5 changed files with 89 additions and 53 deletions
  1. 2 1
      ReadMe.txt
  2. 51 51
      grab_point_rs.cpp
  3. 1 1
      graft_cv_api.cpp
  4. 28 0
      peak_finder.cpp
  5. 7 0
      peak_finder.h

+ 2 - 1
ReadMe.txt

@@ -101,4 +101,5 @@ v0.7.12 
 v0.7.13 修改sc_grab_offset不起作用的bug
 v0.7.14 增加指定抓取位置的功能,抓取位置在ymax向下指定距离为抓取位置
 v0.7.15 优化茎节位置识别
-v0.7.16 优化茎节位置识别,增加平均茎节高度约束,10mm范围
+v0.7.16 优化茎节位置识别,增加平均茎节高度约束,10mm范围
+v0.7.17 优化茎节位置识别,不存在显著茎节的用平均茎节高度替代,否则用识别到的茎节位置

+ 51 - 51
grab_point_rs.cpp

@@ -2440,76 +2440,76 @@ void CRootStockGrabPoint::line_filter(
 
 		//peak finder
 		std::vector<int> peak_indices;
+		std::vector<float> peak_power;
 		findPeaks(stem_width, peak_indices, false);
+		indexPeaks(stem_width, peak_indices, mu, peak_power);
+		float max_power = 0.0;
 		if(peak_indices.size() > 0) {
 			int tmp_max_pos = peak_indices[0];
-			float max_v = stem_width[tmp_max_pos];
-			for (auto&pid : peak_indices) {
-				if (stem_width[pid] > max_v) {
+			max_power = peak_power[0];
+			for (int i = 0; i < peak_indices.size();++i) {
+				int pid = peak_indices.at(i);
+				if (peak_power[i] > max_power) {
 					tmp_max_pos = pid;
-					max_v = stem_width[tmp_max_pos];
+					max_power = peak_power[i];
 				}
 			}
 			max_pos = tmp_max_pos;
 			max_pos_ref = max_pos;			
 		}
-		//保存历史茎节位置
-		m_stem_fork_ys.insert(m_stem_fork_ys.begin(), max_pos);
-		if (m_stem_fork_ys.size() > m_stem_fork_ys_size) { m_stem_fork_ys.pop_back(); }
-		int max_pos_mu = int(get_hist_mean<int>(m_stem_fork_ys) + 0.5);
+		//保存历史茎节位置		
+		if (max_power > 0.5) {
+			m_stem_fork_ys.insert(m_stem_fork_ys.begin(), max_pos);
+			if (m_stem_fork_ys.size() > m_stem_fork_ys_size) { m_stem_fork_ys.pop_back(); }
+			
+		}
+		int max_pos_mu = 0;
+		if (m_stem_fork_ys.size() > 0) {
+			max_pos_mu = int(get_hist_mean<int>(m_stem_fork_ys) + 0.5);
+		}
 
-		float max_val = stem_width.at(max_pos);
-		float th = mu + th_ratio * stdv;
-		if(m_dtype == 0){
-			//穗苗尽量找高点
-			if (th < max_val) {
-				int i = max_pos-10;
-				if (i < 0) { i = 0; }
-				for (; i < stem_width.size(); ++i) {
-					if (stem_width.at(i) >= th) {
-						break;
-					}
-				}
-				max_pos = i;
+		//float max_val = stem_width.at(max_pos);
+		//float th = mu + th_ratio * stdv;
+		if(m_dtype == 0){			
+			if (max_power > 0.5) {
+				max_pos_ref = max_pos;
+				max_pos += static_cast<int>(m_cparam.sc_grab_offset);
 			}
 			else {
-				//从上往下10mm
-				int i = stem_width.size() - 10;
-				for (; i >=0; --i) {
-					if (stem_width.at(i) >= mu) {
-						break;
-					}
+				if (max_pos_mu > 0) {
+					max_pos_ref = max_pos_mu;
+					max_pos = max_pos_mu;
 				}
-				max_pos = i;
-			}
-			max_pos_ref = max_pos;
-			max_pos += static_cast<int>(m_cparam.sc_grab_offset);
-			max_pos_mu += static_cast<int>(m_cparam.sc_grab_offset);
-		}
-		else{
-			//砧木可以按低点
-			if (th < max_val) {				
-				int i = max_pos - 10;
-				if (i < 0) { i = 0; }
-				for (; i < stem_width.size(); ++i) {
-					if (stem_width.at(i) >= th) {
-						break;
-					}
+				else {
+					max_pos_ref = max_pos;
+					max_pos += static_cast<int>(m_cparam.sc_grab_offset);
 				}
-				max_pos = i;
+			}			
+		}
+		else{			
+			if (max_power > 0.5) {
+				max_pos_ref = max_pos;
+				max_pos += static_cast<int>(m_cparam.rs_grab_offset);
 			}
-			max_pos_ref = max_pos;
-			max_pos += static_cast<int>(m_cparam.rs_grab_offset);
-			max_pos_mu += static_cast<int>(m_cparam.rs_grab_offset);
+			else {
+				if (max_pos_mu > 0) {
+					max_pos_ref = max_pos_mu;
+					max_pos = max_pos_mu;
+				}
+				else {
+					max_pos_ref = max_pos;
+					max_pos += static_cast<int>(m_cparam.rs_grab_offset);
+				}
+			}			
 		}
 		if (max_pos < 0) { max_pos = 0;	}
 		if (max_pos >= online_points.size()) { max_pos = online_points.size() - 1; }
 
-		//用历史均值进行约束,如果偏差大于10mm,采用历史均值
-		if (abs(max_pos - max_pos_mu) > 10) {
-			max_pos = max_pos_mu;
-			max_pos_ref = max_pos;
-		}
+		////用历史均值进行约束,如果偏差大于10mm,采用历史均值
+		//if (abs(max_pos - max_pos_mu) > 10) {
+		//	max_pos = max_pos_mu;
+		//	max_pos_ref = max_pos;
+		//}
 
 		/////////////////////////////////////////////////////////////////////
 		//直线点云,获取指定区域的dx_line,dz_line

+ 1 - 1
graft_cv_api.cpp

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

+ 28 - 0
peak_finder.cpp

@@ -254,4 +254,32 @@ namespace graft_cv {
 		//input signal length <= 2
 		//}
 	}
+
+	void indexPeaks(
+		std::vector<float>&stem_width,
+		std::vector<int>&peak_indices,
+		float mu,
+		std::vector<float>& peak_power)
+	{
+		int radius = 5;
+		for (int& pos : peak_indices) {
+			float left_min, right_min;
+			left_min = right_min = stem_width.at(pos);
+			for (int i = pos - radius; i < pos; ++i) {
+				if (i < 0) { continue; }
+				if (stem_width.at(i) <= 0) { continue; }
+				if (stem_width.at(i) < left_min) { left_min = stem_width.at(i); }
+			}
+			for (int i = pos+1 ; i <= pos- radius; ++i) {
+				if (i >= stem_width.size()) { break; }
+				if (stem_width.at(i) <= 0) { continue; }
+				if (stem_width.at(i) < right_min) { right_min = stem_width.at(i); }
+			}
+			left_min = 0.5 * (right_min + left_min);
+			float h = stem_width.at(pos) - left_min;
+			float r = 1.0 - fabs(left_min - mu) / mu;
+			float power = h*r;
+			peak_power.push_back(power);
+		}
+	}
 }

+ 7 - 0
peak_finder.h

@@ -28,4 +28,11 @@ namespace graft_cv {
 	*/
 	void findPeaks(std::vector<float> x0, std::vector<int>& peakInds, bool includeEndpoints = true, float extrema = 1);
 
+	void indexPeaks(
+		std::vector<float>&stem_width,
+		std::vector<int>&peak_indices, 
+		float mu, 
+		std::vector<float>& peak_power);
+		
+	
 }