test_normals.cpp
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         //void modelCallback(image_geometry::PinholeCameraModel::ConstPtr pin_msg);
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         //cam_sub = nh.subscribe("/kinect_head/rgb/camera_info", 1, &TestNormals::modelCallback, this);
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         // pc_full_frame is in torso lift frame
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             //cout << ang << " ";
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             //cout << pcurves << " ";
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         // define a plane to project onto
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     //void TestNormals::modelCallback(image_geometry::PinholeCameraModel::ConstPtr pin_msg) {
00173     //    cam_model.fromCameraInfo(pin_msg);
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 


hrl_table_detect
Author(s): kelsey
autogenerated on Wed Nov 27 2013 12:15:26