瀏覽代碼

v0.8.3 叶子遮挡识别优化:解决叶子遮挡不计数问题;修改点云密度计算方法

chenhongjiang 1 年之前
父節點
當前提交
d3afbfcd6c
共有 3 個文件被更改,包括 50 次插入16 次删除
  1. 2 1
      ReadMe.txt
  2. 47 14
      grab_point_rs.cpp
  3. 1 1
      graft_cv_api.cpp

+ 2 - 1
ReadMe.txt

@@ -111,4 +111,5 @@ v0.7.22 
 v0.7.23 识别接口返回图片,返回茎的弯曲度,当前苗的数量
 v0.8.0 叶子遮挡识别;去除原来图片识别的内容;修改配置参数仅保留3d相关参数
 v0.8.1 叶子遮挡识别优化:通过x截取范围和穴位个数直接确定茎根中心位置
-v0.8.2 叶子遮挡识别优化:用叶子点云数量判断是否有遮挡,加上识别的茎的位置,统计植株的个数
+v0.8.2 叶子遮挡识别优化:用叶子点云数量判断是否有遮挡,加上识别的茎的位置,统计植株的个数
+v0.8.3 叶子遮挡识别优化:解决叶子遮挡不计数问题;修改点云密度计算方法

+ 47 - 14
grab_point_rs.cpp

@@ -148,6 +148,26 @@ namespace graft_cv {
 			viewer.setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_REPRESENTATION,
 				pcl::visualization::PCL_VISUALIZER_REPRESENTATION_WIREFRAME, "AABB_");
 
+			pcl::PointXYZ px0, px1, py1, pz1;
+			px0.x = 0;
+			px0.y = 0;
+			px0.z = 0;
+			px1.x = 10.0;
+			px1.y = 0;
+			px1.z = 0;
+
+			
+			py1.x = 0;
+			py1.y = 10.0;
+			py1.z = 0;
+			pz1.x = 0;
+			pz1.y = 0;
+			pz1.z = 10.0;
+
+			viewer.addLine(px0, px1, 255, 0, 0, "x");
+			viewer.addLine(px0, py1, 0, 255, 0, "y");
+			viewer.addLine(px0, pz1, 0, 0, 255, "z");
+
 			while (!viewer.wasStopped()) {
 				viewer.spinOnce(100);
 				boost::this_thread::sleep(boost::posix_time::microseconds(100000));
@@ -674,7 +694,7 @@ obstructed:
 			y_min = m_cparam.sc_grab_ymin;
 			y_max = m_cparam.sc_grab_ymax;
 		}
-		int th_pcd_size = stem_diameter * (y_max - y_min) * m_cloud_mean_dist;
+		int th_pcd_size = stem_diameter * (y_max - y_min) / m_cloud_mean_dist / m_cloud_mean_dist;
 		std::vector<pcl::PointXYZ> aabb_mins_maxs;		
 		for (int i = 0; i < m_root_centers.size(); ++i) {
 			CStemResult& rc = m_root_centers.at(i);
@@ -989,8 +1009,8 @@ void CRootStockGrabPoint::leaf_filter_ror(
 )
 {
 	//计算点云平均间距
-	double mean_dist = 0.0;
-	cloud_mean_dist(in_cloud, mean_dist);
+	//double mean_dist = 0.0;
+	//cloud_mean_dist(in_cloud, mean_dist);
 
 	//计算点云过滤半径和点数阈值
 	double stem_diameter = m_cparam.rs_grab_stem_diameter;
@@ -999,7 +1019,7 @@ void CRootStockGrabPoint::leaf_filter_ror(
 	double remove_radius = stem_diameter;
 	double ror_ratio = m_cparam.rs_grab_ror_ratio;
 	if (m_dtype == 0){ror_ratio = m_cparam.sc_grab_ror_ratio;}
-	int nb_points = ror_ratio*  stem_diameter * stem_diameter * 2.0 / mean_dist / mean_dist; // (2d*d + pi *d*d) /2
+	int nb_points = ror_ratio*  stem_diameter * stem_diameter * 2.0 / m_cloud_mean_dist / m_cloud_mean_dist; // (2d*d + pi *d*d) /2
 	if (m_pLogger) {
 		stringstream buff;
 		buff << m_pcdId << ": ror_ratio=" << ror_ratio << ", ror filter nb_points=" << nb_points;
@@ -1077,20 +1097,23 @@ void CRootStockGrabPoint::cloud_mean_dist(
 	std::vector<float> sqr_distances(2);
 	pcl::search::KdTree<pcl::PointXYZ> tree;
 	tree.setInputCloud(in_cloud);
+	std::vector<double> distances;
+	double dist;
 	for (size_t i = 0; i < in_cloud->size(); ++i)
 	{		
 		//Considering the second neighbor since the first is the point itself.
 		nres = tree.nearestKSearch(i, 2, indices, sqr_distances);
 		if (nres == 2)
 		{
-			mean_dist +=std::sqrt(sqr_distances[1]);
+			dist = std::sqrt(sqr_distances[1]);
+			mean_dist += dist;
 			++n_points;
+			distances.push_back(dist);
 		}
 	}
-	if (n_points != 0)
-	{
-		mean_dist /= n_points;
-	}
+	std::sort(distances.begin(), distances.end());
+	int per10 = int(distances.size() * 0.1);
+	mean_dist = distances.at(per10);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -1550,6 +1573,11 @@ void CRootStockGrabPoint::line_filter(
 				buff << m_pcdId << ": line_filter reuslt cluster is empty" ;
 				m_pLogger->INFO(buff.str());
 			}
+			//统计苗数量
+			first_row_size = 0;
+			for (auto&has_seedling : m_root_center_with_seedling) {
+				if (has_seedling) { first_row_size += 1; }
+			}
 			return false;
 		}
 
@@ -1647,6 +1675,11 @@ void CRootStockGrabPoint::line_filter(
 				buff << m_pcdId << ": NOT found valid seedlings";
 				m_pLogger->INFO(buff.str());
 			}
+			//统计苗数量
+			first_row_size = 0;
+			for (auto&has_seedling : m_root_center_with_seedling) {
+				if (has_seedling) { first_row_size += 1; }
+			}
 			return false;
 		}
 
@@ -2609,7 +2642,7 @@ void CRootStockGrabPoint::line_filter(
 	void CRootStockGrabPoint::viewer_cloud(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, std::string&winname)
 	{
 		pcl::visualization::CloudViewer viewer(winname);
-		//viewer.runOnVisualizationThreadOnce(viewerOneOff);	
+		//viewer.runOnVisualizationThreadOnce(viewerOneOff);		
 		viewer.showCloud(cloud);
 		while (!viewer.wasStopped()) {
 			boost::this_thread::sleep(boost::posix_time::microseconds(100000));
@@ -2717,18 +2750,18 @@ void CRootStockGrabPoint::line_filter(
 		char buf[8];
 		for (auto& p : cluster_center) {
 			pcl::PointXYZ px0, px1, py1, py0;
-			px0.x = p.x-5.0;
+			px0.x = p.x;
 			px0.y = p.y;
 			px0.z = p.z;
-			px1.x = p.x + 5.0;
+			px1.x = p.x + 10.0;
 			px1.y = p.y;
 			px1.z = p.z;
 
 			py0.x = p.x;
-			py0.y = p.y - 5.0;
+			py0.y = p.y;
 			py0.z = p.z;
 			py1.x = p.x;
-			py1.y = p.y + 5.0;
+			py1.y = p.y + 10.0;
 			py1.z = p.z;
 
 			viewer.addLine(px0, px1, 255, 0, 0, "x" + string(_itoa(cnt, buf,10)));

+ 1 - 1
graft_cv_api.cpp

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