Go to the documentation of this file.00001 #include <numeric>
00002 #include <ros/ros.h>
00003 #include "sensor_msgs/PointCloud2.h"
00004 #include <pcl/features/normal_3d.h>
00005 #include <pcl/kdtree/kdtree_flann.h>
00006 #include "pcl/point_types.h"
00007 #include <pcl_ros/point_cloud.h>
00008 #include <pcl/point_cloud.h>
00009 #include <pcl/features/principal_curvatures.h>
00010
00011 #include <tf/transform_listener.h>
00012 #include "pcl_ros/transforms.h"
00013 #include <boost/make_shared.hpp>
00014 #include <boost/thread/mutex.hpp>
00015 #include <cv_bridge/cv_bridge.h>
00016 #include <opencv/cv.h>
00017 #include <opencv2/imgproc/imgproc.hpp>
00018 #include <opencv2/highgui/highgui.hpp>
00019 #include <image_transport/image_transport.h>
00020 #include <sensor_msgs/image_encodings.h>
00021 #include <geometry_msgs/PoseArray.h>
00022 #include <hrl_table_detect/DetectTableStart.h>
00023 #include <hrl_table_detect/DetectTableStop.h>
00024 #include <hrl_table_detect/DetectTableInst.h>
00025 #include <LinearMath/btMatrix3x3.h>
00026 #include <LinearMath/btQuaternion.h>
00027 #include <hrl_cvblobslib/Blob.h>
00028 #include <hrl_cvblobslib/BlobResult.h>
00029 #include <image_geometry/pinhole_camera_model.h>
00030
00031 using namespace sensor_msgs;
00032 using namespace std;
00033 namespace enc = sensor_msgs::image_encodings;
00034 namespace hrl_table_detect {
00035
00036 class TestNormals {
00037 public:
00038 ros::Subscriber pc_sub, cam_sub;
00039 ros::NodeHandle nh;
00040 ros::Publisher pc_pub, pc_pub2, pc_pub3;
00041 tf::TransformListener tf_listener;
00042 image_geometry::PinholeCameraModel cam_model;
00043
00044 TestNormals();
00045 void onInit();
00046 void pcCallback(sensor_msgs::PointCloud2::ConstPtr pc_msg);
00047
00048 };
00049
00050 TestNormals::TestNormals() {
00051 }
00052
00053 void TestNormals::onInit() {
00054 pc_pub = nh.advertise<pcl::PointCloud<pcl::PointXYZRGB> >("/normal_vis", 1);
00055 pc_pub2 = nh.advertise<pcl::PointCloud<pcl::PointXYZRGB> >("/normal_vis2", 1);
00056 pc_pub3 = nh.advertise<pcl::PointCloud<pcl::PointXYZRGB> >("/normal_vis3", 1);
00057 pc_sub = nh.subscribe("/kinect_head/rgb/points", 1, &TestNormals::pcCallback, this);
00058
00059 ros::Duration(1.0).sleep();
00060 }
00061
00062 void TestNormals::pcCallback(sensor_msgs::PointCloud2::ConstPtr pc_msg) {
00063 pcl::PointCloud<pcl::PointXYZRGB>::Ptr pc_full_ptr (new pcl::PointCloud<pcl::PointXYZRGB>());
00064 pcl::PointCloud<pcl::PointXYZRGB>::Ptr pc_full_frame_ptr (new pcl::PointCloud<pcl::PointXYZRGB>());
00065 pcl::fromROSMsg(*pc_msg, *pc_full_ptr);
00066 string base_frame("/base_link");
00067 ros::Time now = ros::Time::now();
00068
00069 tf_listener.waitForTransform(pc_msg->header.frame_id, base_frame, now, ros::Duration(3.0));
00070 pcl_ros::transformPointCloud(base_frame, *pc_full_ptr, *pc_full_frame_ptr, tf_listener);
00071
00072
00073 pcl::KdTree<pcl::PointXYZRGB>::Ptr normals_tree (new pcl::KdTreeFLANN<pcl::PointXYZRGB>());
00074 pcl::NormalEstimation<pcl::PointXYZRGB, pcl::Normal> n3d;
00075 n3d.setKSearch(15);
00076 n3d.setSearchMethod(normals_tree);
00077 n3d.setInputCloud(pc_full_frame_ptr);
00078 pcl::PointCloud<pcl::Normal>::Ptr cloud_normals_ptr (new pcl::PointCloud<pcl::Normal>());
00079 n3d.compute(*cloud_normals_ptr);
00080 pcl::PrincipalCurvaturesEstimation<pcl::PointXYZRGB, pcl::Normal, pcl::PrincipalCurvatures> pce;
00081 pce.setKSearch(15);
00082 pce.setSearchMethod(normals_tree);
00083 pce.setInputCloud(pc_full_frame_ptr);
00084 pcl::PointCloud<pcl::PrincipalCurvatures> princip_curves;
00085 pce.setInputNormals(cloud_normals_ptr);
00086 pce.compute(princip_curves);
00087 pcl::PointCloud<pcl::PointXYZRGB> cloud_normals_colors, princip_curves_colors;
00088
00089 int i=0;
00090 BOOST_FOREACH(const pcl::Normal& pt, cloud_normals_ptr->points) {
00091 i++;
00092 if(pt.normal[0] != pt.normal[0] || pt.normal[1] != pt.normal[1] || pt.normal[2] != pt.normal[2])
00093 continue;
00094 pcl::PointXYZRGB cur_pt = pc_full_frame_ptr->at(i-1, 0);
00095 double ang = fabs((acos(pt.normal[2]) - CV_PI/2)/CV_PI*2);
00096
00097 double thresh = 0.5;
00098
00099 if(ang > thresh)
00100 ((uint32_t*) &cur_pt.rgb)[0] = ((uint32_t) ((ang-thresh)/(CV_PI/2)*256))<<16 | 0xFF000000;
00101 else
00102 ((uint32_t*) &cur_pt.rgb)[0] = ((uint32_t) ((thresh-ang)/thresh*256)) | 0xFF000000;
00103
00104 cloud_normals_colors.push_back(cur_pt);
00105
00106 pcl::PointXYZRGB p_cur_pt = pc_full_frame_ptr->at(i-1, 0);
00107 pcl::PrincipalCurvatures pcurves = princip_curves.at(i-1, 0);
00108
00109 if(pcurves.pc1 < 0.8)
00110 ((uint32_t*) &p_cur_pt.rgb)[0] = 0xFF0000FF;
00111 else if(pcurves.pc2 > 0.0001)
00112 ((uint32_t*) &p_cur_pt.rgb)[0] = ((uint32_t) (min(fabs((double)pcurves.pc1/pcurves.pc2), 30.0)/30.0*256))<<16 | 0xFF000000;
00113 else
00114 ((uint32_t*) &p_cur_pt.rgb)[0] = (256)<<16 | 0xFF00FF00;
00115
00116 ((uint32_t*) &p_cur_pt.rgb)[0] = ((uint32_t) min((double)fabs(pcurves.pc1*300),255.0))<<16 | 0xFF00FF00;
00117 princip_curves_colors.push_back(p_cur_pt);
00118 }
00119 cloud_normals_colors.header.stamp = ros::Time::now();
00120 cloud_normals_colors.header.frame_id = base_frame;
00121 pc_pub.publish(cloud_normals_colors);
00122
00123 princip_curves_colors.header.stamp = ros::Time::now();
00124 princip_curves_colors.header.frame_id = base_frame;
00125 pc_pub2.publish(princip_curves_colors);
00126
00127
00128 geometry_msgs::PoseStamped plane_pose;
00129 plane_pose.pose.position.x=0; plane_pose.pose.position.y=0; plane_pose.pose.position.z=0.542;
00130 plane_pose.pose.orientation.x=0; plane_pose.pose.orientation.y=0;
00131 plane_pose.pose.orientation.z=0; plane_pose.pose.orientation.w=1;
00132 plane_pose.header.stamp = now; plane_pose.header.frame_id = base_frame;
00133 tf_listener.transformPose(pc_msg->header.frame_id, plane_pose, plane_pose);
00134 btQuaternion plane_quat(plane_pose.pose.orientation.x,
00135 plane_pose.pose.orientation.y,
00136 plane_pose.pose.orientation.z,
00137 plane_pose.pose.orientation.w);
00138 btMatrix3x3 plane_rot(plane_quat);
00139 btVector3 plane_norm = plane_rot.getColumn(2);
00140 btVector3 plane_pt(plane_pose.pose.position.x,plane_pose.pose.position.y,
00141 plane_pose.pose.position.z);
00142 i=0;
00143 pcl::PointCloud<pcl::PointXYZRGB> flat_pc;
00144 BOOST_FOREACH(const pcl::PointXYZRGB& pt, pc_full_ptr->points) {
00145 i++;
00146 if(pt.x != pt.x || pt.y != pt.y || pt.z != pt.z)
00147 continue;
00148 btVector3 pc_pt(pt.x,pt.y,pt.z);
00149 double t = plane_norm.dot(plane_pt)/plane_norm.dot(pc_pt);
00150 btVector3 surf_pt = pc_pt*t;
00151 pcl::PointXYZRGB n_pt;
00152 n_pt.x = surf_pt.x(); n_pt.y = surf_pt.y(); n_pt.z = surf_pt.z();
00153 n_pt.rgb = pt.rgb;
00154 if(t > 1.01) {
00155 uint32_t red = 0xFFFF0000;
00156 ((uint32_t*) &n_pt.rgb)[0] = red;
00157 } else if (t < 0.99) {
00158 uint32_t blue = 0xFF0000FF;
00159 ((uint32_t*) &n_pt.rgb)[0] = blue;
00160 } else {
00161 uint32_t green = 0xFF00FF00;
00162 ((uint32_t*) &n_pt.rgb)[0] = green;
00163 }
00164 flat_pc.push_back(n_pt);
00165 }
00166 flat_pc.header.stamp = ros::Time::now();
00167 flat_pc.header.frame_id = pc_full_ptr->header.frame_id;
00168 pc_pub3.publish(flat_pc);
00169
00170 }
00171
00172
00173
00174
00175 };
00176
00177 using namespace hrl_table_detect;
00178
00179 int main(int argc, char **argv)
00180 {
00181 ros::init(argc, argv, "test_normals");
00182 TestNormals ta;
00183 ta.onInit();
00184 ros::spin();
00185 return 0;
00186 }
00187
00188
00189