zyonz_image_based_leaf_probing_alg.cpp
Go to the documentation of this file.
00001 #include "zyonz_image_based_leaf_probing_alg.h"
00002 #include "segment-image.h"
00003 #include "leaf-fitting.h"
00004 #include "leaf-parameters.h"
00005 #include "find-approach.h"
00006 #include "pnmfile.h"
00007 // [opencv2]                          
00008 #include <opencv2/highgui/highgui.hpp>
00009 #include <opencv2/imgproc/imgproc.hpp>
00010 #include <sensor_msgs/image_encodings.h>
00011 
00012 ZyonzImageBasedLeafProbingAlgorithm::ZyonzImageBasedLeafProbingAlgorithm(void)
00013 {
00014   probing_point_ = Eigen::Vector3f(0.0, 0.0, 0.0);
00015 }
00016 
00017 ZyonzImageBasedLeafProbingAlgorithm::~ZyonzImageBasedLeafProbingAlgorithm(void)
00018 {
00019 }
00020 
00021 void ZyonzImageBasedLeafProbingAlgorithm::config_update(Config& new_cfg, uint32_t level)
00022 {
00023   this->lock();
00024 
00025   ROS_INFO("Reconfigure request: %f, level %d", new_cfg.sigma, level);
00026   ROS_INFO("Reconfigure request: %f, level %d", new_cfg.k, level);
00027   ROS_INFO("Reconfigure request: %d, level %d", new_cfg.min_size, level);
00028 
00029   set_sigma(new_cfg.sigma);
00030   set_k(new_cfg.k);
00031   set_min_size(new_cfg.min_size);
00032   
00033   // save the current configuration
00034   this->config_=new_cfg;
00035   
00036   this->unlock();
00037 }
00038 
00039 // ZyonzImageBasedLeafProbingAlgorithm Public API
00040 
00041 bool ZyonzImageBasedLeafProbingAlgorithm::get_leaf_probing_point(const sensor_msgs::PointCloud2::ConstPtr& msg)
00042 {
00043 
00044   // Convert from msg to algorithm based inputs
00045   pcl::fromROSMsg(*msg, pcl_xyzrgb_);
00046   image<rgb> *input;
00047   image<rgb> *point_cloud;
00048   input = new image<rgb>(pcl_xyzrgb_.height, pcl_xyzrgb_.width);
00049   point_cloud = new image<rgb>(pcl_xyzrgb_.height, pcl_xyzrgb_.width);
00050   pcl::PointCloud<pcl::PointXYZRGB>::iterator pcl_iter = pcl_xyzrgb_.begin();
00051   for (int rr = 0; rr < pcl_xyzrgb_.height; ++rr) {
00052     for (int cc = 0; cc < pcl_xyzrgb_.width; ++cc, ++pcl_iter) {
00053       input->access[rr][cc].r = pcl_iter->r;
00054       input->access[rr][cc].g = pcl_iter->g;
00055       input->access[rr][cc].b = pcl_iter->b;
00056       point_cloud->access[rr][cc].r = pcl_iter->x*100+100;
00057       point_cloud->access[rr][cc].g = pcl_iter->y*100+100;
00058       point_cloud->access[rr][cc].b = pcl_iter->z*100;
00059     }
00060   }
00061 
00062   // SEGMENTATION
00063   
00064   float sigma = get_sigma();
00065   float k = get_k();
00066   int min_size = get_min_size();
00067   //outputs
00068   int ** cluster_labels;
00069   int num_ccs;
00070   int num_ccs_fin;
00071 
00072   image<rgb> *seg = segment_image(input, point_cloud, sigma, k, min_size, &num_ccs, &num_ccs_fin, cluster_labels);
00073   //ROS_INFO("image size: %d, %d ", seg->height(), seg->width());
00074   cv::Mat seg_image(seg->height(), seg->width(), CV_8UC3);
00075   cv::Mat_<cv::Vec3b>::iterator img_iter = seg_image.begin<cv::Vec3b>();
00076   for (int rr = 0; rr < seg_image.rows; ++rr) {
00077     for (int cc = 0; cc < seg_image.cols; ++cc, ++img_iter ) {
00078       (*img_iter)[0] = seg->access[rr][cc].r;
00079       (*img_iter)[1] = seg->access[rr][cc].g;
00080       (*img_iter)[2] = seg->access[rr][cc].b;
00081     }
00082   }
00083   seg_cv_ptr_ = boost::make_shared<cv_bridge::CvImage>();
00084   seg_cv_ptr_->header = msg->header;
00085   seg_cv_ptr_->encoding = sensor_msgs::image_encodings::RGB8;
00086   seg_cv_ptr_->image = seg_image;
00087   
00088 
00089   // LEAF CONFIDENCE
00090 
00091 //  image<rgb> *leaf_model = loadPPM("/home/sfoix/programming/iri/iri-ros-pkg/zyonz_robot/zyonz_image_based_leaf_probing/model/model_F.ppm");
00092 //  image<rgb> *leaf_model_area = loadPPM("/home/sfoix/programming/iri/iri-ros-pkg/zyonz_robot/zyonz_image_based_leaf_probing/model/model_F_bound.ppm");
00093 //  int model_probing_point [2] = {107, 93}; // Calathea Compactstar 
00094 
00095 //  image<rgb> *leaf_model = loadPPM("/home/sfoix/programming/iri/iri-ros-pkg/zyonz_robot/zyonz_image_based_leaf_probing/model/model_E.ppm");
00096 //  image<rgb> *leaf_model_area = loadPPM("/home/sfoix/programming/iri/iri-ros-pkg/zyonz_robot/zyonz_image_based_leaf_probing/model/model_E_bound.ppm");
00097 //  int model_probing_point [2] = {110, 100}; // Anthurium_Andreanum (WHITE)
00098 
00099 //  image<rgb> *leaf_model = loadPPM("/home/sfoix/programming/iri/iri-ros-pkg/zyonz_robot/zyonz_image_based_leaf_probing/model/model_A.ppm");
00100 //  image<rgb> *leaf_model_area = loadPPM("/home/sfoix/programming/iri/iri-ros-pkg/zyonz_robot/zyonz_image_based_leaf_probing/model/model_A_bound.ppm");
00101 //  int model_probing_point [2] = {138, 108}; // Anthurium_Andreanum (RED)
00102 
00103 //  image<rgb> *leaf_model = loadPPM("/home/sfoix/programming/iri/iri-ros-pkg/zyonz_robot/zyonz_image_based_leaf_probing/model/model_T.ppm");
00104 //  image<rgb> *leaf_model_area = loadPPM("/home/sfoix/programming/iri/iri-ros-pkg/zyonz_robot/zyonz_image_based_leaf_probing/model/model_T_bound.ppm");
00105 //  int model_probing_point [2] = {86, 110}; // Tobacco 
00106   
00107   image<rgb> *leaf_model = loadPPM("/home/sfoix/programming/iri/iri-ros-pkg/zyonz_robot/zyonz_image_based_leaf_probing/model/model_P.ppm");
00108   image<rgb> *leaf_model_area = loadPPM("/home/sfoix/programming/iri/iri-ros-pkg/zyonz_robot/zyonz_image_based_leaf_probing/model/model_P_bound.ppm");
00109   int model_probing_point [2] = {107, 103}; // Pothos 
00110   
00111   double *fit_score_list;
00112   double **transformation_parameters;
00113   image<rgb> *leaf_confidence = leaf_fitting(cluster_labels, leaf_model, leaf_model_area, num_ccs_fin, fit_score_list, transformation_parameters);
00114   //ROS_INFO("transformation_paramters[0][0]: %f", transformation_parameters[0][0]);
00115   cv::Mat confidence_image(leaf_confidence->height(), leaf_confidence->width(), CV_8UC3);
00116   cv::Mat_<cv::Vec3b>::iterator conf_img_iter = confidence_image.begin<cv::Vec3b>();
00117   for (int rr = 0; rr < confidence_image.rows; ++rr) {
00118     for (int cc = 0; cc < confidence_image.cols; ++cc, ++conf_img_iter ) {
00119       (*conf_img_iter)[0] = leaf_confidence->access[rr][cc].r;
00120       (*conf_img_iter)[1] = leaf_confidence->access[rr][cc].g;
00121       (*conf_img_iter)[2] = leaf_confidence->access[rr][cc].b;
00122     }
00123   }
00124   confidence_cv_ptr_ = boost::make_shared<cv_bridge::CvImage>();
00125   confidence_cv_ptr_->header = msg->header;
00126   confidence_cv_ptr_->encoding = sensor_msgs::image_encodings::RGB8;
00127   confidence_cv_ptr_->image = confidence_image;
00128 
00129   // LEAF PARAMETERS
00130   goal_parameters_ = leaf_parameters(cluster_labels, point_cloud, num_ccs_fin, fit_score_list);
00131   ROS_INFO("goal_parameters %f x_c ", goal_parameters_[0]-100);
00132   ROS_INFO("goal_parameters %f y_c ", goal_parameters_[1]-100);    
00133   ROS_INFO("goal_parameters %f z_c ", goal_parameters_[2]);
00134   ROS_INFO("goal_parameters %f n_x ", goal_parameters_[3]);
00135   ROS_INFO("goal_parameters %f n_y ", goal_parameters_[4]);
00136   ROS_INFO("goal_parameters %f n_z ", goal_parameters_[5]);
00137   ROS_INFO("goal_parameters %f label ", goal_parameters_[6]);
00138   // Leaf centroid in [m]
00139   Eigen::Vector3d leaf_centroid(goal_parameters_[0]-100, goal_parameters_[1]-100, goal_parameters_[2]);   
00140 
00141 
00142   // PROBING PARAMETERS
00143   double* probing_movement_parameters = find_approach(cluster_labels, point_cloud, goal_parameters_, transformation_parameters, model_probing_point); 
00144  
00145   // Probing point in [m]
00146   probing_movement_parameters[3] = (probing_movement_parameters[3]-100)/100;
00147   probing_movement_parameters[4] = (probing_movement_parameters[4]-100)/100;
00148   probing_movement_parameters[5] = (probing_movement_parameters[5])/100;
00149 
00150   probing_point_ = Eigen::Vector3f(probing_movement_parameters[3], probing_movement_parameters[4], probing_movement_parameters[5]); 
00151   Eigen::Vector3f x_vector(probing_movement_parameters[0], probing_movement_parameters[1], probing_movement_parameters[2]); 
00152   Eigen::Vector3f normal_vector(goal_parameters_[3], goal_parameters_[4], goal_parameters_[5]); 
00153 
00154   Eigen::Quaternionf probing_pose = Eigen::Quaternionf(1.0, 0.0, 0.0, 0.0);
00155   
00156   find_probing_pose_by_PCA( goal_parameters_[6], cluster_labels, point_cloud, probing_pose, normal_vector);
00157 
00158   find_probing_pose( probing_point_, x_vector, normal_vector, probing_pose);
00159 
00160   //Filling in the probing step msg
00161   //
00162   // probing Point
00163   geometry_msgs::PoseStamped temp_pose_st;
00164   temp_pose_st.header = msg->header; 
00165   //ROS_INFO("FRAME_ID: %i", temp_pose_st.header.frame_id);
00166   temp_pose_st.header.stamp = ros::Time::now(); 
00167   temp_pose_st.pose.position.x = probing_point_.x(); 
00168   temp_pose_st.pose.position.y = probing_point_.y(); 
00169   temp_pose_st.pose.position.z = probing_point_.z(); 
00170   temp_pose_st.pose.orientation.x = probing_pose.x()/probing_pose.norm(); 
00171   temp_pose_st.pose.orientation.y = probing_pose.y()/probing_pose.norm(); 
00172   temp_pose_st.pose.orientation.z = probing_pose.z()/probing_pose.norm(); 
00173   temp_pose_st.pose.orientation.w = probing_pose.w()/probing_pose.norm(); 
00174   try{
00175     tf_listener_.waitForTransform(std::string("wam_link0"), temp_pose_st.header.frame_id, ros::Time::now(), ros::Duration(1.0));
00176     tf_listener_.transformPose(std::string("wam_link0"), temp_pose_st, probing_step_.probing);
00177   }catch (tf::TransformException ex){
00178     ROS_ERROR("%s", ex.what());
00179   }
00180 
00181   // pre probing point
00182   temp_pose_st.header = msg->header; 
00183   temp_pose_st.header.stamp = ros::Time::now(); 
00184   temp_pose_st.pose.position.x = probing_point_.x() + x_vector.x()*(x_vector.norm()-0.90)/x_vector.norm();
00185   temp_pose_st.pose.position.y = probing_point_.y() + x_vector.y()*(x_vector.norm()-0.90)/x_vector.norm();
00186   temp_pose_st.pose.position.z = probing_point_.z() + x_vector.z()*(x_vector.norm()-0.90)/x_vector.norm();
00187   temp_pose_st.pose.orientation.x = probing_pose.x()/probing_pose.norm();
00188   temp_pose_st.pose.orientation.y = probing_pose.y()/probing_pose.norm();
00189   temp_pose_st.pose.orientation.z = probing_pose.z()/probing_pose.norm();
00190   temp_pose_st.pose.orientation.w = probing_pose.w()/probing_pose.norm();
00191   geometry_msgs::PoseStamped pre_prob_st; 
00192   try{
00193     tf_listener_.waitForTransform(std::string("wam_link0"), temp_pose_st.header.frame_id, ros::Time::now(), ros::Duration(1.0));
00194     tf_listener_.transformPose(std::string("wam_link0"), temp_pose_st, pre_prob_st);
00195   }catch (tf::TransformException ex){
00196     ROS_ERROR("%s", ex.what());
00197   }
00198   probing_step_.pre_probing.header = msg->header;
00199   probing_step_.pre_probing.header.stamp = ros::Time::now();
00200   probing_step_.pre_probing.header.frame_id = std::string("wam_link0"); 
00201   probing_step_.pre_probing.poses.clear(); 
00202   probing_step_.pre_probing.poses.push_back(pre_prob_st.pose); 
00203 
00204   // post probing point
00205   probing_step_.post_probing = probing_step_.pre_probing;
00206 
00207   // Find grasp point and approach vector
00208   ROS_INFO("probing point(x, y, z): (%f, %f, %f)",  probing_step_.probing.pose.position.x, probing_step_.probing.pose.position.y, probing_step_.probing.pose.position.z);
00209   ROS_INFO("approaching pre point(x, y, z): (%f, %f, %f)",  probing_step_.pre_probing.poses[0].position.x, probing_step_.pre_probing.poses[0].position.y, probing_step_.pre_probing.poses[0].position.z);
00210   ROS_INFO("approaching post point(x, y, z): (%f, %f, %f)",  probing_step_.post_probing.poses[0].position.x, probing_step_.post_probing.poses[0].position.y, probing_step_.post_probing.poses[0].position.z);
00211   ROS_INFO("probing x_vector(x, y, z): (%f, %f, %f)",  x_vector.x(), x_vector.y(), x_vector.z());
00212   ROS_INFO("pose quaternion(x, y, z, w): (%f, %f, %f, %f)",  probing_pose.x(), probing_pose.y(), probing_pose.z(), probing_pose.w());
00213 
00214   return true;
00215 }
00216 
00217 void ZyonzImageBasedLeafProbingAlgorithm::find_probing_pose(const Eigen::Vector3f probing_point, const Eigen::Vector3f x_vector, const Eigen::Vector3f normal_vector, Eigen::Quaternionf &probing_pose){
00218  
00219   Eigen::Vector3f y_vector;
00220   Eigen::Vector3f z_vector;
00221   y_vector = normal_vector.cross(x_vector);
00222   z_vector = x_vector.cross(y_vector);
00223   
00224   // Checking the direction of the Z axis respect the camera
00225   if (z_vector.z()<0){
00226     z_vector = -z_vector;
00227     y_vector = -y_vector;
00228   }
00229 
00230   Eigen::Matrix3f pose_matrix;
00231   pose_matrix << x_vector.x(), y_vector.x(), z_vector.x(),
00232                  x_vector.y(), y_vector.y(), z_vector.y(),
00233                  x_vector.z(), y_vector.z(), z_vector.z();
00234   //pose_matrix << x_vector.x(), x_vector.y(), x_vector.z(),
00235   //               y_vector.x(), y_vector.y(), y_vector.z(),
00236   //               z_vector.x(), z_vector.y(), z_vector.z();
00237   probing_pose = Eigen::Quaternionf(pose_matrix);
00238 }
00239 
00240 
00241 void ZyonzImageBasedLeafProbingAlgorithm::find_probing_pose_by_PCA(const int label, int ** clusters, const image<rgb> *pc, Eigen::Quaternionf &probing_pose, Eigen::Vector3f &normal_vector){
00242 
00243   // Principal Component Analysis (PCA)
00244 
00245   // number of points into the cluster?
00246   int num_points = 0;
00247   for (int cc = 0; cc < pc->width(); cc++)
00248   {
00249     for (int rr = 0; rr < pc->height(); rr++)
00250     {
00251       if (label == clusters[rr][cc])
00252       {
00253         num_points++;
00254       }
00255     }
00256   }
00257   
00258   ROS_INFO("(num_points, width, height): (%i, %d, %d)", num_points, pc->width(), pc->height());
00259   Eigen::MatrixXf B(num_points, 3);
00260   int row_idx = 0;
00261   for (int cc = 0; cc < pc->width(); cc++)
00262   {
00263     for (int rr = 0; rr < pc->height(); rr++)
00264     {
00265       if (clusters[rr][cc] == label)
00266       {
00267         B.row(row_idx)[0] = ((imRef(pc, cc, rr).r)-100.0)/100;
00268         B.row(row_idx)[1] = ((float)(imRef(pc, cc, rr).g)-100.0)/100;
00269         B.row(row_idx)[2] = ((float)(imRef(pc, cc, rr).b))/100;
00270         ROS_INFO("points(x, y, z): (%f, %f, %f)", B.row(row_idx)[0], B.row(row_idx)[1], B.row(row_idx)[2] );
00271         ++row_idx;
00272       }
00273     }
00274   }
00275 
00276   Eigen::JacobiSVD<Eigen::MatrixXf> svd(B, Eigen::ComputeThinU | Eigen::ComputeThinV);
00277   std::cout << "SingularValues are: \n" << svd.singularValues() << std::endl;
00278   //std::cout << "Left Singular Vectors are: \n" << svd.matrixU() << std::endl;
00279   //std::cout << "Right Singular Vectors are: \n" << svd.matrixV() << std::endl;
00280   
00281   Eigen::Vector3f o_v(svd.matrixV().col(0)); //y
00282   Eigen::Vector3f n_v(svd.matrixV().col(1)); //x
00283   Eigen::Vector3f a_v(svd.matrixV().col(2)); //z
00284   // Checking the direction of the Z axis respect the camera
00285   if (a_v.z()<0){
00286     a_v = -a_v;
00287     n_v = -n_v;
00288   }
00289   
00290   Eigen::Matrix3f rot_m;
00291   rot_m << n_v.x(), o_v.x(), a_v.x(),
00292            n_v.y(), o_v.y(), a_v.y(),
00293            n_v.z(), o_v.z(), a_v.z();
00294   probing_pose = Eigen::Quaternionf (rot_m);
00295 
00296   ROS_INFO("Normal(x, y, z): (%f, %f, %f)", a_v.x(), a_v.y(), a_v.z());
00297   ROS_INFO("Quaternion(x, y, z, w): (%f, %f, %f, %f)", probing_pose.x(), probing_pose.y(), probing_pose.z(), probing_pose.w());
00298   
00299   normal_vector = Eigen::Vector3f(o_v.x(), o_v.y(), o_v.z()); 
00300   
00301 }
00302 
00303 
00304 void ZyonzImageBasedLeafProbingAlgorithm::set_sigma(float new_sigma){
00305       sigma_ = new_sigma;
00306 }
00307 
00308 void ZyonzImageBasedLeafProbingAlgorithm::set_k(float new_k){
00309       k_ = new_k;
00310 }
00311 
00312 void ZyonzImageBasedLeafProbingAlgorithm::set_min_size(int new_min_size){
00313       min_size_ = new_min_size;
00314 }
00315 
00316 float ZyonzImageBasedLeafProbingAlgorithm::get_sigma(){
00317       return sigma_;
00318 }
00319 
00320 float ZyonzImageBasedLeafProbingAlgorithm::get_k(){
00321       return k_;
00322 }
00323 
00324 int ZyonzImageBasedLeafProbingAlgorithm::get_min_size(){
00325       return min_size_;
00326 }
00327 
00328 cv_bridge::CvImagePtr ZyonzImageBasedLeafProbingAlgorithm::get_seg_image(){
00329       return seg_cv_ptr_;
00330 }
00331 
00332 cv_bridge::CvImagePtr ZyonzImageBasedLeafProbingAlgorithm::get_confidence_image(){
00333       return confidence_cv_ptr_;
00334 }
00335 
00336 Eigen::Vector3f ZyonzImageBasedLeafProbingAlgorithm::get_probing_point(){
00337 
00338       return probing_point_;
00339 }
00340 
00341 zyonz_msgs::ProbingSteps ZyonzImageBasedLeafProbingAlgorithm::get_probing_step(){
00342       return probing_step_;
00343 }
00344 
00345 
00346 
00347 


zyonz_image_based_leaf_probing
Author(s): Sergi Foix
autogenerated on Fri Dec 6 2013 23:25:27