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
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
00034 this->config_=new_cfg;
00035
00036 this->unlock();
00037 }
00038
00039
00040
00041 bool ZyonzImageBasedLeafProbingAlgorithm::get_leaf_probing_point(const sensor_msgs::PointCloud2::ConstPtr& msg)
00042 {
00043
00044
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
00063
00064 float sigma = get_sigma();
00065 float k = get_k();
00066 int min_size = get_min_size();
00067
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
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
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
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};
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
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
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
00139 Eigen::Vector3d leaf_centroid(goal_parameters_[0]-100, goal_parameters_[1]-100, goal_parameters_[2]);
00140
00141
00142
00143 double* probing_movement_parameters = find_approach(cluster_labels, point_cloud, goal_parameters_, transformation_parameters, model_probing_point);
00144
00145
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
00161
00162
00163 geometry_msgs::PoseStamped temp_pose_st;
00164 temp_pose_st.header = msg->header;
00165
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
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
00205 probing_step_.post_probing = probing_step_.pre_probing;
00206
00207
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
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
00235
00236
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
00244
00245
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
00279
00280
00281 Eigen::Vector3f o_v(svd.matrixV().col(0));
00282 Eigen::Vector3f n_v(svd.matrixV().col(1));
00283 Eigen::Vector3f a_v(svd.matrixV().col(2));
00284
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