zyonz_obtain_roi_jump_edge_based_alg.cpp
Go to the documentation of this file.
00001 #include "zyonz_obtain_roi_jump_edge_based_alg.h"
00002 
00003 ZyonzObtainRoiJumpEdgeBasedAlgorithm::ZyonzObtainRoiJumpEdgeBasedAlgorithm(void):
00004 roi_pose_ptr_(boost::make_shared<geometry_msgs::PoseStamped>()),
00005 viewpoint_pose_ptr_(boost::make_shared<geometry_msgs::PoseStamped>())
00006 {
00007 }
00008 
00009 ZyonzObtainRoiJumpEdgeBasedAlgorithm::~ZyonzObtainRoiJumpEdgeBasedAlgorithm(void)
00010 {
00011 }
00012 
00013 void ZyonzObtainRoiJumpEdgeBasedAlgorithm::config_update(Config& new_cfg, uint32_t level)
00014 {
00015   this->lock();
00016 
00017   // save the current configuration
00018   this->config_=new_cfg;
00019   
00020   this->unlock();
00021 }
00022 
00023 // ZyonzObtainRoiJumpEdgeBasedAlgorithm Public API
00024 bool ZyonzObtainRoiJumpEdgeBasedAlgorithm::principal_component_analysis(pcl::PointCloud<pcl::PointXYZ>::ConstPtr point_cloud, Eigen::Vector4f& centroid, Eigen::Quaternionf& orientation)
00025 {
00026 
00027   if (point_cloud->size()< 10)
00028     return false;
00029 
00030   // Compute the cluster centroid
00031   pcl::compute3DCentroid (*point_cloud, centroid);
00032   ROS_DEBUG("Cluster Centroid: (%f, %f, %f)", centroid(0), centroid(1), centroid(2));
00033   
00034   // Principal Component Analysis (PCA)
00035   // 1) Compute Covariance
00036   Eigen::MatrixXf B(point_cloud->points.size(),3);
00037   int aa = 0;
00038   for (pcl::PointCloud<pcl::PointXYZ>::const_iterator it = point_cloud->begin(); it != point_cloud->end(); ++it, ++aa){
00039     B.row(aa)[0] = it->x - centroid(0);
00040     B.row(aa)[1] = it->y - centroid(1);
00041     B.row(aa)[2] = it->z - centroid(2);
00042   }
00043   
00044   Eigen::JacobiSVD<Eigen::MatrixXf> svd(B, Eigen::ComputeThinU | Eigen::ComputeThinV);
00045   //std::cout << "SingularValues are: \n" << svd.singularValues() << std::endl;
00046   //std::cout << "Left Singular Vectors are: \n" << svd.matrixU() << std::endl;
00047   //std::cout << "Right Singular Vectors are: \n" << svd.matrixV() << std::endl;
00048 
00049   Eigen::Vector3f n_v(svd.matrixV().col(1));
00050   Eigen::Vector3f o_v(svd.matrixV().col(0));
00051   Eigen::Vector3f a_v(svd.matrixV().col(2));
00052   // Checking the direction of the Z axis respect the camera
00053   if (a_v.z()<0){
00054     a_v = -a_v;
00055     n_v = -n_v;
00056   }
00057 
00058   Eigen::Matrix3f rot_m;
00059   rot_m << n_v.x(), o_v.x(), a_v.x(),
00060            n_v.y(), o_v.y(), a_v.y(),
00061            n_v.z(), o_v.z(), a_v.z();
00062   orientation = Eigen::Quaternionf (rot_m);
00063   ROS_DEBUG("Quaternion(x, y, z, w): (%f, %f, %f, %f)", orientation.x(), orientation.y(), orientation.z(), orientation.w());
00064 
00065   return true;
00066 
00067 }
00068 
00069 bool ZyonzObtainRoiJumpEdgeBasedAlgorithm::isRunning(sensor_msgs::PointCloud2::ConstPtr& point_cloud_ConstPtr, sensor_msgs::Image::ConstPtr& cluster_a_img_ConstPtr, sensor_msgs::Image::ConstPtr& cluster_b_img_ConstPtr, sensor_msgs::Image::ConstPtr& residual_img_ConstPtr)
00070 {
00071     // Conversion of ROSPointCloud2 to pcl
00072     pcl::fromROSMsg(*point_cloud_ConstPtr, roi_pc_);
00073     
00074     // Conversion of ROSImages to opencv
00075     //  - So we can play with them
00076     cv_bridge::CvImageConstPtr cluster_a_cv_ptr, cluster_b_cv_ptr, residual_cv_ptr;
00077     cv_bridge::CvImagePtr roi_cv_ptr;
00078     try
00079     {
00080         cluster_a_cv_ptr = cv_bridge::toCvShare(cluster_a_img_ConstPtr, sensor_msgs::image_encodings::MONO8);
00081         cluster_b_cv_ptr = cv_bridge::toCvShare(cluster_b_img_ConstPtr, sensor_msgs::image_encodings::MONO8);
00082         residual_cv_ptr = cv_bridge::toCvShare(residual_img_ConstPtr, sensor_msgs::image_encodings::MONO8);
00083         roi_cv_ptr = cv_bridge::toCvCopy(residual_img_ConstPtr, sensor_msgs::image_encodings::MONO8);
00084     }
00085     catch (cv_bridge::Exception& e)
00086     {  
00087         ROS_ERROR("cv_bridge exception: %s", e.what());
00088         return false;
00089     }
00090     
00091     cv::Mat a_dilated_mat;
00092     cv::Mat b_dilated_mat;
00093     //cv::Mat element(7,7,CV_8U,cv::Scalar(1));
00094     cv::Mat element(3,3,CV_8U,cv::Scalar(1));
00095 
00096     // Dilate both clusters   
00097     cv::dilate(cluster_a_cv_ptr->image, a_dilated_mat, element, cv::Point(-1,-1), 3);
00098     cv::dilate(cluster_b_cv_ptr->image, b_dilated_mat, element, cv::Point(-1,-1), 3);
00099    
00100     //cv::dilate(cluster_a_cv_ptr->image, a_dilated_mat, element);
00101     //cv::dilate(cluster_b_cv_ptr->image, b_dilated_mat, element);
00102    
00103     // Logical AND of both dilated clusters 
00104     //  - So we get the ROI image
00105     cv::Mat temp_roi_mat;
00106     cv::bitwise_and(a_dilated_mat, b_dilated_mat, temp_roi_mat);
00107     cv::bitwise_and(temp_roi_mat, residual_cv_ptr->image, roi_cv_ptr->image);
00108     
00109     //obtain the roi_pc
00110     for (int rr = 0; rr < roi_cv_ptr->image.rows; ++rr)
00111         for (int cc = 0; cc < roi_cv_ptr->image.cols; ++cc)
00112             if (roi_cv_ptr->image.at<uchar>(rr,cc) != 255){
00113                 roi_pc_(cc,rr).z = std::numeric_limits<float>::quiet_NaN ();
00114                 //std::cout << roi_pc_.at(rr,cc).z << std::endl;
00115             }
00116     roi_img_ptr_ = roi_cv_ptr->toImageMsg();
00117 
00118     /* 
00119      * COMPUTING THE ROI POSE
00120      */
00121     // Compute the cluster centroid
00122     if (roi_pc_.size() < 10)
00123     {
00124         ROS_INFO("ZyonzObtainRoiJumpEdgeBasedAlgorithm::isRunning: ERROR: Not enough supporting points in the centroid computation");
00125         return false;
00126     }
00127     Eigen::Vector4f centroid;
00128     pcl::compute3DCentroid (roi_pc_, centroid);
00129 
00130     roi_pose_ptr_->header = point_cloud_ConstPtr->header;
00131     roi_pose_ptr_->pose.position.x = centroid.x();
00132     roi_pose_ptr_->pose.position.y = centroid.y();
00133     roi_pose_ptr_->pose.position.z = centroid.z();
00134     // The orientation is the one of the camera
00135     //   - Why? Because by definition the plane should pass through the camera
00136     roi_pose_ptr_->pose.orientation.x = 0;
00137     roi_pose_ptr_->pose.orientation.y = 0;
00138     roi_pose_ptr_->pose.orientation.z = 0;
00139     roi_pose_ptr_->pose.orientation.w = 1;
00140     ROS_DEBUG("Cluster Centroid: (%f, %f, %f)", roi_pose_ptr_->pose.position.x, roi_pose_ptr_->pose.position.y, roi_pose_ptr_->pose.position.z);
00141     ROS_DEBUG("Quaternion(x, y, z, w): (%f, %f, %f, %f)", roi_pose_ptr_->pose.orientation.x, roi_pose_ptr_->pose.orientation.y, roi_pose_ptr_->pose.orientation.z, roi_pose_ptr_->pose.orientation.w);
00142 
00143 
00144     // Reading the Pose of the pointcloud sensor
00145     tf::TransformListener tf_listener; 
00146     tf::StampedTransform transform;
00147     try
00148     {
00149       tf_listener.waitForTransform(std::string("wam_link0"), roi_pc_.header.frame_id, ros::Time::now(), ros::Duration(1.0));
00150       tf_listener.lookupTransform(std::string("wam_link0"), roi_pc_.header.frame_id, ros::Time(0), transform);
00151     }
00152     catch (tf::TransformException ex)
00153     {
00154       ROS_ERROR("%s", ex.what ());
00155     }
00156     tf::poseTFToMsg(transform, viewpoint_pose_ptr_->pose);
00157     viewpoint_pose_ptr_->header.stamp = transform.stamp_;
00158     viewpoint_pose_ptr_->header.frame_id = transform.frame_id_;
00159 
00160     return true;
00161 } 
00162 
00163 pcl::PointCloud<pcl::PointXYZ>::ConstPtr ZyonzObtainRoiJumpEdgeBasedAlgorithm::get_roi_pc(void)
00164 {
00165     return roi_pc_.makeShared();
00166 }
00167 
00168 sensor_msgs::Image::Ptr ZyonzObtainRoiJumpEdgeBasedAlgorithm::get_roi_img(void)
00169 {
00170     return roi_img_ptr_;
00171 }
00172 
00173 geometry_msgs::PoseStamped::Ptr ZyonzObtainRoiJumpEdgeBasedAlgorithm::get_roi_pose(void)
00174 {
00175     return roi_pose_ptr_;
00176 }
00177 
00178 geometry_msgs::PoseStamped::Ptr ZyonzObtainRoiJumpEdgeBasedAlgorithm::get_viewpoint_pose(void)
00179 {
00180     return viewpoint_pose_ptr_;
00181 }
00182 
00183 


zyonz_obtain_roi_jump_edge_based
Author(s): sfoix
autogenerated on Fri Dec 6 2013 19:57:40