chenhongjiang 1 年間 前
コミット
8c129a3776
8 ファイル変更87 行追加59 行削除
  1. 2 1
      ReadMe.txt
  2. 3 0
      config.cpp
  3. 1 1
      data_def.h
  4. 1 0
      data_def_api.h
  5. 1 0
      tcv_conf.yml
  6. 1 1
      tea_cv_api.cpp
  7. 1 0
      tea_detect.cpp
  8. 77 56
      tea_sorter.cpp

+ 2 - 1
ReadMe.txt

@@ -4,4 +4,5 @@ v0.1.2 
 v0.1.3 增加图片切分功能
 v0.1.4 支持单通道图片
 v0.1.5 支持grab图片上下镜像检测
-v0.1.6 去除支持grab图片上下镜像检测,因为夹爪旋转角度只有180度范围
+v0.1.6 去除支持grab图片上下镜像检测,因为夹爪旋转角度只有180度范围
+v0.1.7 恢复支持grab图片上下镜像检测,增加抓取最小间隔设置

+ 3 - 0
config.cpp

@@ -32,6 +32,7 @@ namespace graft_cv{
 			<< "grid_col_grab" << m_cparam->grid_col_grab
 			<< "grid_padding_grab" << m_cparam->grid_padding_grab
 			<< "offset_grab" << m_cparam->offset_grab
+			<< "min_distance_grab" << m_cparam->min_distance_grab
 
 			<< "model_path_cut" << m_cparam->model_path_cut
 			<< "object_threshold_cut" << m_cparam->object_threshold_cut
@@ -59,6 +60,7 @@ namespace graft_cv{
 		m_cparam->grid_col_grab	= (int)node["grid_col_grab"];
 		m_cparam->grid_padding_grab	= (int)node["grid_padding_grab"];
 		m_cparam->offset_grab = (int)node["offset_grab"];
+		m_cparam->min_distance_grab = (double)node["min_distance_grab"];
 		
 		m_cparam->model_path_cut = (string)node["model_path_cut"];
 		m_cparam->object_threshold_cut = (float)node["object_threshold_cut"];
@@ -88,6 +90,7 @@ namespace graft_cv{
 			<< "grid_col_grab:\t" << m_cparam->grid_col_grab << endl
 			<< "grid_padding_grab:\t" << m_cparam->grid_padding_grab << endl
 			<< "offset_grab:\t" << m_cparam->offset_grab << endl
+			<< "min_distance_grab:\t" << m_cparam->min_distance_grab << endl
 
 
 			<< "model_path_cut:\t" << m_cparam->model_path_cut << endl

+ 1 - 1
data_def.h

@@ -88,6 +88,6 @@ namespace graft_cv{
 		int y2;
 		float ppoint[10]; //(x,y) 5 key points	
 		float area; //像素面积
-		int status;	// 墨滴状态:正常=0;缺失=-1;偏离=-2
+		int status;	// 状态:未选中=0;被选中=1;
 	};
 };

+ 1 - 0
data_def_api.h

@@ -25,6 +25,7 @@ typedef struct{
 	int grid_col_grab;
 	int grid_padding_grab;
 	int offset_grab; //抓取点相对参考点(标注的点5)的偏移像素数
+	double min_distance_grab;//抓取两个目标最小中心距离,像素距离
 
 	std::string model_path_cut;
 	float object_threshold_cut;

+ 1 - 0
tcv_conf.yml

@@ -12,6 +12,7 @@ conf_parameters:
    grid_col_grab: 3
    grid_padding_grab: 100
    offset_grab: 10
+   min_distance_grab: 500.0
 
    model_path_cut: "D:/projects/graft/py_code/retina_tea5/TeaDetector_op9.onnx"
    object_threshold_cut: 0.45

+ 1 - 1
tea_cv_api.cpp

@@ -18,7 +18,7 @@ extern CRITICAL_SECTION g_cs;
 namespace graft_cv
 {
 
-	char *g_version_str = "0.1.6";
+	char *g_version_str = "0.1.7";
 
 	//configure
 	string g_conf_file = "./tcv_conf.yml";	

+ 1 - 0
tea_detect.cpp

@@ -123,6 +123,7 @@ namespace graft_cv {
 			box.ppoint[9] = rect.keypoints[4].y;
 
 			box.area = 0.0;
+			box.status = 0;
 			result.push_back(box);
 		}
 		if (pInstanceLogger) {

+ 77 - 56
tea_sorter.cpp

@@ -88,33 +88,33 @@ int CTeaSort::detect(
 	//5 detect	
 	vector<Bbox> droplets_raw;
 	int dn = detect_impl(m_raw_img, drop_regions, droplets_raw);
-	//if (dn < 2 && m_dtype == img_type::tea_grab) {
-	//	//up-down flip
-	//	cv::Mat flip_img;
-	//	cv::flip(m_raw_img, flip_img, 0);
-	//	if (m_cp.image_show) {			
-	//		imshow_wait("flip_img", flip_img);
-	//	}
-
-	//	vector<Bbox> droplets_flip;
-	//	int dn_flip = detect_impl(flip_img, drop_regions, droplets_flip);
-	//	for (auto&b: droplets_flip) {			
-	//		int y2 = flip_img.rows - b.y1;
-	//		int y1 = flip_img.rows - b.y2;
-	//		b.y1 = y1;
-	//		b.y2 = y2;
-	//		
-	//		for (int i = 0; i < 5; ++i) {				
-	//			b.ppoint[2 * i + 1] = flip_img.rows - b.ppoint[2 * i + 1];
-	//		}
-	//	}
-	//	if (dn_flip > 0) {
-	//		droplets_raw.insert(
-	//			droplets_raw.end(),
-	//			droplets_flip.begin(),
-	//			droplets_flip.end());
-	//	}
-	//}
+	if (dn < 2 && m_dtype == img_type::tea_grab) {
+		//up-down flip
+		cv::Mat flip_img;
+		cv::flip(m_raw_img, flip_img, 0);
+		if (m_cp.image_show) {			
+			imshow_wait("flip_img", flip_img);
+		}
+
+		vector<Bbox> droplets_flip;
+		int dn_flip = detect_impl(flip_img, drop_regions, droplets_flip);
+		for (auto&b: droplets_flip) {			
+			int y2 = flip_img.rows - b.y1;
+			int y1 = flip_img.rows - b.y2;
+			b.y1 = y1;
+			b.y2 = y2;
+			
+			for (int i = 0; i < 5; ++i) {				
+				b.ppoint[2 * i + 1] = flip_img.rows - b.ppoint[2 * i + 1];
+			}
+		}
+		if (dn_flip > 0) {
+			droplets_raw.insert(
+				droplets_raw.end(),
+				droplets_flip.begin(),
+				droplets_flip.end());
+		}
+	}
 	/*for (auto rect : drop_regions) {
 		Mat roi = m_raw_img(rect);
 		vector<Bbox> head_droplets = m_drop_detector.RunModel(roi, m_pLogger);
@@ -164,51 +164,75 @@ int CTeaSort::detect(
 	
 	
 	int valid_cnt = 0;
-	for (int i = 0; i < droplets.size();++i) {
-		if (i > 1) { break; }
-		Bbox&b = droplets.at(i);
-		double grab_x, grab_y;
-		double angle = calalate_angle(b, grab_x, grab_y);
-		valid_cnt += 1;
-		//grab point 
-		if (i == 0) {
-			if (m_dtype == img_type::tea_grab) {
+	if (m_dtype == img_type::tea_grab) {
+		//grab
+		double pre_cx, pre_cy;
+		double min_dist_grab = m_cp.min_distance_grab;
+		pre_cx = -min_dist_grab;
+		pre_cy = -min_dist_grab;
+
+		for (int i = 0; i < droplets.size(); ++i) {
+			if (valid_cnt > 1) { break; }
+			Bbox&b = droplets.at(i);
+			double cx = 0.5*(b.x1 + b.x2);
+			double cy = 0.5*(b.y1 + b.y2);
+			double dist = sqrt((cx - pre_cx)*(cx - pre_cx) + (cy - pre_cy)*(cy - pre_cy));
+			if (dist < min_dist_grab) {
+				continue;
+			}
+			double grab_x, grab_y;
+			double angle = calalate_angle(b, grab_x, grab_y);
+			
+			//grab point 
+			if (valid_cnt == 0) {
 				posinfo.tea_grab_x1 = grab_x;
 				posinfo.tea_grab_y1 = grab_y;
-				posinfo.tea_grab_angle1 = angle;
+				posinfo.tea_grab_angle1 = angle;				
 			}
 			else {
-				// 切割点是3、4的中间的点
-				posinfo.tea_cut_x1 = 0.5 * (b.ppoint[4] + b.ppoint[6]);
-				posinfo.tea_cut_y1 = 0.5 * (b.ppoint[5] + b.ppoint[7]);
-				posinfo.tea_cut_angle1 = angle;
-			}			
-		}
-		else {
-			if (m_dtype == img_type::tea_grab) {
 				posinfo.tea_grab_x2 = grab_x;
 				posinfo.tea_grab_y2 = grab_y;
 				posinfo.tea_grab_angle2 = angle;
 			}
-			else {
+			pre_cx = cx;
+			pre_cy = cy;
+			b.status = 1;
+			valid_cnt += 1;
+		}
+	}
+	else {
+		//cut
+		for (int i = 0; i < droplets.size();++i) {
+			if (i > 1) { break; }
+			Bbox&b = droplets.at(i);
+			b.status = 1; // selected
+			double grab_x, grab_y;
+			double angle = calalate_angle(b, grab_x, grab_y);
+			valid_cnt += 1;			
+			if (i == 0) {				
+				// 切割点是3、4的中间的点
+				posinfo.tea_cut_x1 = 0.5 * (b.ppoint[4] + b.ppoint[6]);
+				posinfo.tea_cut_y1 = 0.5 * (b.ppoint[5] + b.ppoint[7]);
+				posinfo.tea_cut_angle1 = angle;						
+			}
+			else {				
 				// 切割点是3、4的中间的点
 				posinfo.tea_cut_x2 = 0.5 * (b.ppoint[4] + b.ppoint[6]);
 				posinfo.tea_cut_y2 = 0.5 * (b.ppoint[5] + b.ppoint[7]);
 				posinfo.tea_cut_angle2 = angle;
-			}
-
-		}		
+			}		
+		}
 	}
+	
 
 	//6 draw
 	if (m_cp.image_return) {
 		this->clear_imginfo();
-		cv::Mat img_rst = m_raw_img.clone();
-		int cnt = 0;
+		cv::Mat img_rst = m_raw_img.clone();		
 		for (auto& b : droplets) {			
 			//rectangle
 			cv::Rect r = cv::Rect(cv::Point2i(b.x1, b.y1), cv::Point2i(b.x2, b.y2));
-			if (cnt < 2) {
+			if (b.status > 0) {
 				cv::rectangle(img_rst, r, cv::Scalar(0, 0, 255),2);
 			}
 			else {
@@ -266,11 +290,8 @@ int CTeaSort::detect(
 				cv::line(img_rst, cv::Point(cx - radius, cy - radius), cv::Point(cx + radius, cy + radius), cv::Scalar(0, 215, 255),2);
 				cv::line(img_rst, cv::Point(cx - radius, cy + radius), cv::Point(cx + radius, cy - radius), cv::Scalar(0, 215, 255),2);
 			}
-			
-			
-			cnt += 1;
-
 		}
+
 		if (m_cp.image_show) {
 			imshow_wait("result_img", img_rst);
 		}