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
00018 this->config_=new_cfg;
00019
00020 this->unlock();
00021 }
00022
00023
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
00031 pcl::compute3DCentroid (*point_cloud, centroid);
00032 ROS_DEBUG("Cluster Centroid: (%f, %f, %f)", centroid(0), centroid(1), centroid(2));
00033
00034
00035
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
00046
00047
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
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
00072 pcl::fromROSMsg(*point_cloud_ConstPtr, roi_pc_);
00073
00074
00075
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
00094 cv::Mat element(3,3,CV_8U,cv::Scalar(1));
00095
00096
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
00101
00102
00103
00104
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
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
00115 }
00116 roi_img_ptr_ = roi_cv_ptr->toImageMsg();
00117
00118
00119
00120
00121
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
00135
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
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