00001
00002
00003 #include <iostream>
00004
00005 #include <boost/thread/thread.hpp>
00006 #include <pcl/range_image/range_image.h>
00007 #include <pcl/io/pcd_io.h>
00008 #include <pcl/visualization/range_image_visualizer.h>
00009 #include <pcl/visualization/pcl_visualizer.h>
00010 #include <pcl/features/range_image_border_extractor.h>
00011 #include <pcl/keypoints/narf_keypoint.h>
00012 #include <pcl/features/narf_descriptor.h>
00013 #include <pcl/console/parse.h>
00014
00015 typedef pcl::PointXYZ PointType;
00016
00017
00018
00019
00020 float angular_resolution = 0.5f;
00021 float support_size = 0.2f;
00022 pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;
00023 bool setUnseenToMaxRange = false;
00024 bool rotation_invariant = true;
00025
00026
00027
00028
00029 void
00030 printUsage (const char* progName)
00031 {
00032 std::cout << "\n\nUsage: "<<progName<<" [options] <scene.pcd>\n\n"
00033 << "Options:\n"
00034 << "-------------------------------------------\n"
00035 << "-r <float> angular resolution in degrees (default "<<angular_resolution<<")\n"
00036 << "-c <int> coordinate frame (default "<< (int)coordinate_frame<<")\n"
00037 << "-m Treat all unseen points to max range\n"
00038 << "-s <float> support size for the interest points (diameter of the used sphere - "
00039 "default "<<support_size<<")\n"
00040 << "-o <0/1> switch rotational invariant version of the feature on/off"
00041 << " (default "<< (int)rotation_invariant<<")\n"
00042 << "-h this help\n"
00043 << "\n\n";
00044 }
00045
00046 void
00047 setViewerPose (pcl::visualization::PCLVisualizer& viewer, const Eigen::Affine3f& viewer_pose)
00048 {
00049 Eigen::Vector3f pos_vector = viewer_pose * Eigen::Vector3f (0, 0, 0);
00050 Eigen::Vector3f look_at_vector = viewer_pose.rotation () * Eigen::Vector3f (0, 0, 1) + pos_vector;
00051 Eigen::Vector3f up_vector = viewer_pose.rotation () * Eigen::Vector3f (0, -1, 0);
00052 viewer.setCameraPosition (pos_vector[0], pos_vector[1], pos_vector[2],
00053 look_at_vector[0], look_at_vector[1], look_at_vector[2],
00054 up_vector[0], up_vector[1], up_vector[2]);
00055 }
00056
00057
00058
00059
00060 int
00061 main (int argc, char** argv)
00062 {
00063
00064
00065
00066 if (pcl::console::find_argument (argc, argv, "-h") >= 0)
00067 {
00068 printUsage (argv[0]);
00069 return 0;
00070 }
00071 if (pcl::console::find_argument (argc, argv, "-m") >= 0)
00072 {
00073 setUnseenToMaxRange = true;
00074 cout << "Setting unseen values in range image to maximum range readings.\n";
00075 }
00076 if (pcl::console::parse (argc, argv, "-o", rotation_invariant) >= 0)
00077 cout << "Switching rotation invariant feature version "<< (rotation_invariant ? "on" : "off")<<".\n";
00078 int tmp_coordinate_frame;
00079 if (pcl::console::parse (argc, argv, "-c", tmp_coordinate_frame) >= 0)
00080 {
00081 coordinate_frame = pcl::RangeImage::CoordinateFrame (tmp_coordinate_frame);
00082 cout << "Using coordinate frame "<< (int)coordinate_frame<<".\n";
00083 }
00084 if (pcl::console::parse (argc, argv, "-s", support_size) >= 0)
00085 cout << "Setting support size to "<<support_size<<".\n";
00086 if (pcl::console::parse (argc, argv, "-r", angular_resolution) >= 0)
00087 cout << "Setting angular resolution to "<<angular_resolution<<"deg.\n";
00088 angular_resolution = pcl::deg2rad (angular_resolution);
00089
00090
00091
00092
00093 pcl::PointCloud<PointType>::Ptr point_cloud_ptr (new pcl::PointCloud<PointType>);
00094 pcl::PointCloud<PointType>& point_cloud = *point_cloud_ptr;
00095 pcl::PointCloud<pcl::PointWithViewpoint> far_ranges;
00096 Eigen::Affine3f scene_sensor_pose (Eigen::Affine3f::Identity ());
00097 std::vector<int> pcd_filename_indices = pcl::console::parse_file_extension_argument (argc, argv, "pcd");
00098 if (!pcd_filename_indices.empty ())
00099 {
00100 std::string filename = argv[pcd_filename_indices[0]];
00101 if (pcl::io::loadPCDFile (filename, point_cloud) == -1)
00102 {
00103 cerr << "Was not able to open file \""<<filename<<"\".\n";
00104 printUsage (argv[0]);
00105 return 0;
00106 }
00107 scene_sensor_pose = Eigen::Affine3f (Eigen::Translation3f (point_cloud.sensor_origin_[0],
00108 point_cloud.sensor_origin_[1],
00109 point_cloud.sensor_origin_[2])) *
00110 Eigen::Affine3f (point_cloud.sensor_orientation_);
00111 std::string far_ranges_filename = pcl::getFilenameWithoutExtension (filename)+"_far_ranges.pcd";
00112 if (pcl::io::loadPCDFile (far_ranges_filename.c_str (), far_ranges) == -1)
00113 std::cout << "Far ranges file \""<<far_ranges_filename<<"\" does not exists.\n";
00114 }
00115 else
00116 {
00117 setUnseenToMaxRange = true;
00118 cout << "\nNo *.pcd file given => Genarating example point cloud.\n\n";
00119 for (float x=-0.5f; x<=0.5f; x+=0.01f)
00120 {
00121 for (float y=-0.5f; y<=0.5f; y+=0.01f)
00122 {
00123 PointType point; point.x = x; point.y = y; point.z = 2.0f - y;
00124 point_cloud.points.push_back (point);
00125 }
00126 }
00127 point_cloud.width = (int) point_cloud.points.size (); point_cloud.height = 1;
00128 }
00129
00130
00131
00132
00133 float noise_level = 0.0;
00134 float min_range = 0.0f;
00135 int border_size = 1;
00136 boost::shared_ptr<pcl::RangeImage> range_image_ptr (new pcl::RangeImage);
00137 pcl::RangeImage& range_image = *range_image_ptr;
00138 range_image.createFromPointCloud (point_cloud, angular_resolution, pcl::deg2rad (360.0f), pcl::deg2rad (180.0f),
00139 scene_sensor_pose, coordinate_frame, noise_level, min_range, border_size);
00140 range_image.integrateFarRanges (far_ranges);
00141 if (setUnseenToMaxRange)
00142 range_image.setUnseenToMaxRange ();
00143
00144
00145
00146
00147 pcl::visualization::PCLVisualizer viewer ("3D Viewer");
00148 viewer.setBackgroundColor (1, 1, 1);
00149 pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> range_image_color_handler (range_image_ptr, 0, 0, 0);
00150 viewer.addPointCloud (range_image_ptr, range_image_color_handler, "range image");
00151 viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "range image");
00152
00153
00154
00155 viewer.initCameraParameters ();
00156 setViewerPose (viewer, range_image.getTransformationToWorldSystem ());
00157
00158
00159
00160
00161 pcl::visualization::RangeImageVisualizer range_image_widget ("Range image");
00162 range_image_widget.showRangeImage (range_image);
00163
00164
00165
00166
00167 pcl::RangeImageBorderExtractor range_image_border_extractor;
00168 pcl::NarfKeypoint narf_keypoint_detector;
00169 narf_keypoint_detector.setRangeImageBorderExtractor (&range_image_border_extractor);
00170 narf_keypoint_detector.setRangeImage (&range_image);
00171 narf_keypoint_detector.getParameters ().support_size = support_size;
00172
00173 pcl::PointCloud<int> keypoint_indices;
00174 narf_keypoint_detector.compute (keypoint_indices);
00175 std::cout << "Found "<<keypoint_indices.points.size ()<<" key points.\n";
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints_ptr (new pcl::PointCloud<pcl::PointXYZ>);
00188 pcl::PointCloud<pcl::PointXYZ>& keypoints = *keypoints_ptr;
00189 keypoints.points.resize (keypoint_indices.points.size ());
00190 for (size_t i=0; i<keypoint_indices.points.size (); ++i)
00191 keypoints.points[i].getVector3fMap () = range_image.points[keypoint_indices.points[i]].getVector3fMap ();
00192 pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> keypoints_color_handler (keypoints_ptr, 0, 255, 0);
00193 viewer.addPointCloud<pcl::PointXYZ> (keypoints_ptr, keypoints_color_handler, "keypoints");
00194 viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 7, "keypoints");
00195
00196
00197
00198
00199 std::vector<int> keypoint_indices2;
00200 keypoint_indices2.resize (keypoint_indices.points.size ());
00201 for (unsigned int i=0; i<keypoint_indices.size (); ++i)
00202 keypoint_indices2[i]=keypoint_indices.points[i];
00203 pcl::NarfDescriptor narf_descriptor (&range_image, &keypoint_indices2);
00204 narf_descriptor.getParameters ().support_size = support_size;
00205 narf_descriptor.getParameters ().rotation_invariant = rotation_invariant;
00206 pcl::PointCloud<pcl::Narf36> narf_descriptors;
00207 narf_descriptor.compute (narf_descriptors);
00208 cout << "Extracted "<<narf_descriptors.size ()<<" descriptors for "
00209 <<keypoint_indices.points.size ()<< " keypoints.\n";
00210
00211
00212
00213
00214 while (!viewer.wasStopped ())
00215 {
00216 range_image_widget.spinOnce ();
00217 viewer.spinOnce ();
00218 pcl_sleep(0.01);
00219 }
00220 }