Kaynağa Gözat

v0.8.8 砧木固定抓取位置,输出茎节高度

chenhongjiang 1 yıl önce
ebeveyn
işleme
93e9583f82
6 değiştirilmiş dosya ile 110 ekleme ve 32 silme
  1. 2 1
      ReadMe.txt
  2. 7 0
      data_def_api.h
  3. 93 30
      grab_point_rs.cpp
  4. 4 0
      grab_point_rs.h
  5. 1 1
      graft_cv_api.cpp
  6. 3 0
      graft_cv_api.h

+ 2 - 1
ReadMe.txt

@@ -116,4 +116,5 @@ v0.8.3 叶
 v0.8.4 叶子遮挡识别优化:小叶遮挡,茎没有识别出来,植株误判问题
 v0.8.5 叶子遮挡识别优化:修改叶子遮挡识别位置偏离问题,增加历史抓取信息约束
 v0.8.6 抓取位置调整
-v0.8.7 抓取顺序调整:先抓取有明确茎的位置,然后再去抓取遮挡位置的
+v0.8.7 抓取顺序调整:先抓取有明确茎的位置,然后再去抓取遮挡位置的
+v0.8.8 砧木固定抓取位置,输出茎节高度;

+ 7 - 0
data_def_api.h

@@ -63,13 +63,20 @@ typedef struct
 	double rs_grab_x;//砧木上苗抓取位置x,毫米
 	double rs_grab_y;//砧木上苗抓取位置y,毫米
 	double rs_grab_z;//砧木上苗抓取位置z,毫米
+	double rs_fork_x;//砧木上苗茎节位置x,毫米
+	double rs_fork_y;//砧木上苗茎节位置y,毫米
+	double rs_fork_z;//砧木上苗茎节位置z,毫米
 	double rs_width;		//茎的宽度(直径),毫米
 	double rs_tortuosity;	//弯曲度,离茎中心轴线最大距离,毫米
 	double rs_count;		//当前第一排共有多少株
 
+
 	double sc_grab_x;//穗苗上苗抓取位置x,毫米
 	double sc_grab_y;//穗苗上苗抓取位置y,毫米
 	double sc_grab_z;//穗苗上苗抓取位置z,毫米
+	//double sc_fork_x;//砧木上苗茎节位置x,毫米
+	//double sc_fork_y;//砧木上苗茎节位置y,毫米
+	//double sc_fork_z;//砧木上苗茎节位置z,毫米
 	double sc_width;		//茎的宽度(直径),毫米
 	double sc_tortuosity;	//弯曲度,离茎中心轴线最大距离,毫米
 	double sc_count;		//当前第一排共有多少株	

+ 93 - 30
grab_point_rs.cpp

@@ -396,15 +396,17 @@ namespace graft_cv {
 
 		////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 		//5.1 如果没有找到茎,在root_center 中找一个位置
-		pcl::PointXYZ selected_pt;//抓取点坐标,根据茎节点的偏移
-		pcl::PointXYZ selected_pt_ref;	//返回茎节点,作为抓取点偏的基点		
+		pcl::PointXYZ fork_selected_pt;//抓取点坐标,根据茎节点的偏移
+		pcl::PointXYZ fork_selected_pt_ref;	//返回茎节点,作为抓取点偏的基点	
+		pcl::PointXYZ rs_grab_pt;	//v0.8.8修改砧木抓取位置为固定高度,通过yup和ybt均值确定
 		if (!fund_seedling) {
 			int selected_center_idx;
 			no_seedling_detected_post_process(
 				first_row_seedling_number,		//input
 				selected_center_idx,			//output
-				selected_pt,					//output
-				selected_pt_ref,				//output
+				fork_selected_pt,					//output
+				fork_selected_pt_ref,				//output
+				rs_grab_pt,							//output
 				posinfo);
 			if (selected_center_idx < 0) {
 				if (m_pLogger) {
@@ -445,19 +447,21 @@ namespace graft_cv {
 				cloud_dowm_sampled,		//input
 				cloud_seedling_seed,	//input
 				line_model,				//input
-				selected_pt,			//output
-				selected_pt_ref,		//output				
+				fork_selected_pt,			//output
+				fork_selected_pt_ref,		//output
+				rs_grab_pt,					//output
 				stem_width_mu,			//output
 				stem_deflection			//output
 			);		//output
 
-			if (selected_pt.z < 0) {
+			if (fork_selected_pt.z < 0) {
 				int selected_center_idx;
 				no_seedling_detected_post_process(
 					first_row_seedling_number,		//input
 					selected_center_idx,			//output
-					selected_pt,					//output
-					selected_pt_ref,				//output
+					fork_selected_pt,					//output
+					fork_selected_pt_ref,				//output
+					rs_grab_pt,							//output
 					posinfo);
 
 				if (selected_center_idx < 0) {
@@ -476,8 +480,9 @@ namespace graft_cv {
 					stem_width_mu,				//input
 					stem_deflection,				//input
 					selected_center_idx,					//output, 选择root_center的序号
-					selected_pt,			//input-output, 检测到的目标抓取点
-					selected_pt_ref,		//input-output, 检测到的目标抓取参考点
+					fork_selected_pt,			//input-output, 检测到的目标抓取点
+					fork_selected_pt_ref,		//input-output, 检测到的目标抓取参考点
+					rs_grab_pt,
 					posinfo);
 			}
 			
@@ -488,7 +493,7 @@ namespace graft_cv {
 		////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 		//7 保存处理结果到图片
 		cv::Mat rst_img = cv::Mat::zeros(cv::Size(1280,640),CV_8UC3);
-		gen_result_img(cloud_ror, cloud_dowm_sampled, selected_pt, selected_pt_ref, posinfo,rst_img);
+		gen_result_img(cloud_ror, cloud_dowm_sampled, fork_selected_pt, fork_selected_pt_ref, rs_grab_pt, posinfo,rst_img);
 		if (m_ppImgSaver && *m_ppImgSaver) {
 			(*m_ppImgSaver)->saveImage(rst_img, m_pcdId + "_rst_0");
 		}
@@ -510,19 +515,19 @@ namespace graft_cv {
 				pt.b = 255;
 			}			
 			pcl::PointXYZRGB pt_grab = {0,255,0};
-			pt_grab.x = selected_pt.x;
-			pt_grab.y = selected_pt.y;
-			pt_grab.z = selected_pt.z;
+			pt_grab.x = fork_selected_pt.x;
+			pt_grab.y = fork_selected_pt.y;
+			pt_grab.z = fork_selected_pt.z;
 
 			pcl::PointXYZRGB pt_grab_ = { 0,255,120 };
-			pt_grab_.x = selected_pt.x;
-			pt_grab_.y = selected_pt.y+0.2;
-			pt_grab_.z = selected_pt.z;
+			pt_grab_.x = fork_selected_pt.x;
+			pt_grab_.y = fork_selected_pt.y + 0.2;
+			pt_grab_.z = fork_selected_pt.z;
 			cloud_cand_demo->push_back(pt_grab);
 
 
 			//viewer_cloud(cloud_cand_demo, std::string("cloud_cand_demo"));
-			viewer_cloud_debug(cloud_cand_demo, selected_pt, selected_pt_ref, xz_center, std::string("cloud_cand_demo"));
+			viewer_cloud_debug(cloud_cand_demo, fork_selected_pt, fork_selected_pt_ref, xz_center, std::string("cloud_cand_demo"));
 			imshow_wait("rst_img", rst_img);
 		}
 		return 0;
@@ -533,9 +538,13 @@ namespace graft_cv {
 		int& selected_idx,					//output, 选择root_center的序号
 		pcl::PointXYZ& selected_pt,			//output
 		pcl::PointXYZ& selected_pt_ref,		//output
+		pcl::PointXYZ& rs_grab_pt,			//output
 		PositionInfo& posinfo				//output
 	)
 	{
+		rs_grab_pt.x = -1000.0;
+		rs_grab_pt.y = -1000.0;
+		rs_grab_pt.z = -1000.0;
 		//m_dtype == 0 找最大x位置, 否则找最小x位置
 		selected_idx = -1;
 		if (m_dtype == 0) {
@@ -578,6 +587,15 @@ namespace graft_cv {
 		selected_pt = selected_pt_ref;
 		selected_pt.y += static_cast<int>(grab_offset);
 
+		//砧木指定y高度上的确定位置
+		if (m_dtype == 1) {
+			float grab_y = 0.5 * (m_cparam.rs_grab_fork_ybt + m_cparam.rs_grab_fork_yup);
+			rs_grab_pt.x = cx;
+			rs_grab_pt.y = grab_y;
+			rs_grab_pt.z = m_root_centers.at(selected_idx).root_z;
+		}
+
+
 		double stem_width_mu = 0.0;
 		double stem_deflection = 0.0;
 		if (m_dtype == 0) {
@@ -589,9 +607,12 @@ namespace graft_cv {
 			posinfo.sc_tortuosity = (double)stem_deflection;
 		}
 		else {
-			posinfo.rs_grab_x = selected_pt.x;
-			posinfo.rs_grab_y = selected_pt.y;
-			posinfo.rs_grab_z = selected_pt.z;
+			posinfo.rs_grab_x = rs_grab_pt.x;
+			posinfo.rs_grab_y = rs_grab_pt.y;
+			posinfo.rs_grab_z = rs_grab_pt.z;
+			posinfo.rs_fork_x = selected_pt_ref.x;
+			posinfo.rs_fork_y = selected_pt_ref.y;
+			posinfo.rs_fork_z = selected_pt_ref.z;
 			posinfo.rs_count = (double)first_row_seedling_number;
 			posinfo.rs_width = (double)stem_width_mu;
 			posinfo.rs_tortuosity = (double)stem_deflection;
@@ -605,8 +626,9 @@ namespace graft_cv {
 		float stem_width_mu,				//input
 	    float stem_deflection,				//input
 		int& selected_idx,					//output, 选择root_center的序号
-		pcl::PointXYZ& selected_pt,			//input-output, 检测到的目标抓取点
-		pcl::PointXYZ& selected_pt_ref,		//input-output, 检测到的目标抓取参考点
+		pcl::PointXYZ& selected_pt,			//input-output, 检测到的基于茎节抓取点
+		pcl::PointXYZ& selected_pt_ref,		//input-output, 检测到的茎节点
+		pcl::PointXYZ& rs_grab_pt,			//input-output, 检测到的目标抓取点
 		PositionInfo& posinfo				//output
 	)
 	{
@@ -616,15 +638,18 @@ namespace graft_cv {
 		if (m_dtype == 0) {
 			posinfo.sc_grab_x = selected_pt.x;
 			posinfo.sc_grab_y = selected_pt.y;
-			posinfo.sc_grab_z = selected_pt.z;
+			posinfo.sc_grab_z = selected_pt.z;			
 			posinfo.sc_count = (double)first_row_seedling_number;
 			posinfo.sc_width = (double)stem_width_mu;
 			posinfo.sc_tortuosity = (double)stem_deflection;
 		}
 		else {
-			posinfo.rs_grab_x = selected_pt.x;
-			posinfo.rs_grab_y = selected_pt.y;
-			posinfo.rs_grab_z = selected_pt.z;
+			posinfo.rs_grab_x = rs_grab_pt.x;
+			posinfo.rs_grab_y = rs_grab_pt.y;
+			posinfo.rs_grab_z = rs_grab_pt.z;
+			posinfo.rs_fork_x = selected_pt.x;
+			posinfo.rs_fork_y = selected_pt.y;
+			posinfo.rs_fork_z = selected_pt.z;
 			posinfo.rs_count = (double)first_row_seedling_number;
 			posinfo.rs_width = (double)stem_width_mu;
 			posinfo.rs_tortuosity = (double)stem_deflection;
@@ -1001,7 +1026,8 @@ namespace graft_cv {
 		pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud_raw,//输入,未经过滤的整体点云in_cloud_raw, 
 		pcl::PointCloud<pcl::PointXYZ>::Ptr in_cloud,	//输入,整体点云cloud_dowm_sampled, 
 		pcl::PointXYZ& selected_pt,				//输入,selected_pt, 
-		pcl::PointXYZ& selected_pt_ref,        //输入,selected_pt_ref, 
+		pcl::PointXYZ& selected_pt_ref,        //输入,selected_pt_ref,
+		pcl::PointXYZ& rs_grab_pt,        //输入,砧木固定抓取点,
 		const PositionInfo& posinfo,					//输入,
 		cv::Mat& rst_img						//输出,图片, 640*1280
 	)
@@ -1049,6 +1075,11 @@ namespace graft_cv {
 		int grab_x = cx - int(selected_pt.x / res + 0.5);
 		int grab_y = cy - int(selected_pt.y / res + 0.5);
 		int radius = 30;
+		if (m_dtype == 1) {
+			//如果是砧木,固定y值的抓取点
+			grab_x = cx - int(rs_grab_pt.x / res + 0.5);
+			grab_y = cy - int(rs_grab_pt.y / res + 0.5);
+		}
 		cv::line(rst_img, cv::Point(grab_x - radius, grab_y - radius), cv::Point(grab_x + radius, grab_y + radius), cv::Scalar(0, 215, 255));
 		cv::line(rst_img, cv::Point(grab_x - radius, grab_y + radius), cv::Point(grab_x + radius, grab_y - radius), cv::Scalar(0, 215, 255));
 		//如果是遮挡,画一个圆
@@ -1783,6 +1814,8 @@ void CRootStockGrabPoint::line_filter(
 				final_box.push_back(max_point_aabb_ex);
 			}			
 			viewer_cloud_cluster_box(in_cloud, target_filtered_root, final_box, target_member, std::string("line_filter"));
+			std::vector<std::vector<int>>target_member_empty;
+			viewer_cloud_cluster_box(m_raw_cloud, target_filtered_root, final_box, target_member_empty, std::string("stem_box_in_raw_pc"));
 		}
 
 		//保存茎的根部坐标和点云数量
@@ -2456,7 +2489,8 @@ void CRootStockGrabPoint::line_filter(
 		pcl::PointCloud<pcl::PointXYZ>::Ptr in_line_cloud,	//input	茎上直线点云
 		pcl::ModelCoefficients::Ptr line_model,				//input
 		pcl::PointXYZ&pt,									//  返回抓取的点坐标,基于pt_ref的偏移点
-		pcl::PointXYZ &pt_ref,								//	返回点茎节的参考点		
+		pcl::PointXYZ &pt_ref,								//	返回点茎节的参考点	
+		pcl::PointXYZ&pt_rs_grab,							//  返回砧木指定的固定高度位置坐标
 		float& stem_width_mu,									// 茎宽度,直径
 		float& stem_deflection								//茎的最大挠度,最大弯曲处的偏离直径轴心的距离,毫米
 	)
@@ -2468,6 +2502,10 @@ void CRootStockGrabPoint::line_filter(
 		pt.z = -1000.0;
 		stem_width_mu = 0.0;
 		stem_deflection = 0.0;
+		pt_rs_grab.x = -1000.0;
+		pt_rs_grab.y = -1000.0;
+		pt_rs_grab.z = -1000.0;
+
 
 
 		float ymin, ymax;
@@ -2652,6 +2690,31 @@ void CRootStockGrabPoint::line_filter(
 		pt_ref.y = online_points.at(max_pos_ref).y;
 		pt_ref.z = online_points.at(max_pos_ref).z;
 
+		//砧木指定y高度上的确定位置
+		if (m_dtype == 1) {
+			float grab_y = 0.5 * (m_cparam.rs_grab_fork_ybt + m_cparam.rs_grab_fork_yup);
+			int grab_y_pos = int(grab_y - m_cparam.rs_grab_ymin);
+			cx = online_points.at(grab_y_pos).x;
+			cy = online_points.at(grab_y_pos).y;
+			cz = online_points.at(grab_y_pos).z;
+			box_filter_line.setMin(Eigen::Vector4f(cx - rx*radius, cy - 2, cz - rz*radius, 1));
+			box_filter_line.setMax(Eigen::Vector4f(cx + rx*radius, cy + 2, cz + rz*radius, 1));
+			box_filter_line.filter(*cloud_inbox_line);
+
+			z_mu = cz;
+			x_mu = cx;
+			if (cloud_inbox_line->points.size() > 5) {
+				pcl::getMinMax3D(*cloud_inbox_line, min_point, max_point);
+				z_mu = 0.5 * (max_point(2) + min_point(2));
+				x_mu = 0.5 * (max_point(0) + min_point(0));
+			}
+
+			pt_rs_grab.x = x_mu;
+			pt_rs_grab.y = cy;
+			pt_rs_grab.z = z_mu;
+
+		}
+
 		//显示位置
 		if (m_cparam.image_show) {
 			pcl::visualization::PCLVisualizer viewer("grab line");

+ 4 - 0
grab_point_rs.h

@@ -155,6 +155,7 @@ namespace graft_cv {
 			pcl::ModelCoefficients::Ptr line_model,			//input
 			pcl::PointXYZ&pt,								//输出,
 			pcl::PointXYZ &pt_ref,							//输出,	返回点茎节的参考点			
+			pcl::PointXYZ&pt_rs_grab,					    //输出,	返回砧木指定的固定高度位置坐标
 			float& stem_width_mu,								//输出,茎宽度,直径
 			float& stem_deflection							//输出,茎的最大挠度,最大弯曲处的偏离直径轴心的距离,毫米
 		);
@@ -177,6 +178,7 @@ namespace graft_cv {
 			pcl::PointCloud<pcl::PointXYZ>::Ptr,	//输入,整体点云cloud_dowm_sampled, 
 			pcl::PointXYZ& selected_pt,				//输入,selected_pt, 
 			pcl::PointXYZ& selected_pt_ref,        //输入,selected_pt_ref,
+			pcl::PointXYZ& rs_grab_pt,        //输入,砧木固定抓取点,
 			const PositionInfo& posinfo,					//输入,
 			cv::Mat& rst_img						//输出,图片, 640*1280
 		);
@@ -206,6 +208,7 @@ namespace graft_cv {
 			int& selected_idx,					//output, 选择root_center的序号
 			pcl::PointXYZ& selected_pt,			//output
 			pcl::PointXYZ& selected_pt_ref,		//output
+			pcl::PointXYZ& rs_grab_pt,			//output
 			PositionInfo& posinfo				//output
 		);
 		//检测到苗的情况,后处理
@@ -216,6 +219,7 @@ namespace graft_cv {
 			int& selected_idx,					//output, 选择root_center的序号
 			pcl::PointXYZ& selected_pt,			//input-output
 			pcl::PointXYZ& selected_pt_ref,		//input-output
+			pcl::PointXYZ& rs_grab_pt,			//input-output, 检测到的目标抓取参考点
 			PositionInfo& posinfo				//output
 		);
 

+ 1 - 1
graft_cv_api.cpp

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

+ 3 - 0
graft_cv_api.h

@@ -72,6 +72,9 @@ GCV_API void get_version(char* buf);
 //				double rs_grab_x;		//砧木上苗抓取位置x,毫米
 //				double rs_grab_y;		//砧木上苗抓取位置y,毫米
 //				double rs_grab_z;		//砧木上苗抓取位置z,毫米
+//              double rs_fork_x;       //砧木上苗茎节位置x,毫米
+//              double rs_fork_y;       //砧木上苗茎节位置y,毫米
+//              double rs_fork_z;       //砧木上苗茎节位置z,毫米
 //				double rs_width;		//茎的宽度(直径),毫米
 //				double rs_tortuosity;	//弯曲度,离茎中心轴线最大距离,毫米
 //				double rs_count;		//当前第一排共有多少株