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.camera_.pos[0] = pos_vector[0];
00053 viewer.camera_.pos[1] = pos_vector[1];
00054 viewer.camera_.pos[2] = pos_vector[2];
00055 viewer.camera_.focal[0] = look_at_vector[0];
00056 viewer.camera_.focal[1] = look_at_vector[1];
00057 viewer.camera_.focal[2] = look_at_vector[2];
00058 viewer.camera_.view[0] = up_vector[0];
00059 viewer.camera_.view[1] = up_vector[1];
00060 viewer.camera_.view[2] = up_vector[2];
00061 viewer.updateCamera ();
00062 }
00063
00064
00065
00066
00067 int
00068 main (int argc, char** argv)
00069 {
00070
00071
00072
00073 if (pcl::console::find_argument (argc, argv, "-h") >= 0)
00074 {
00075 printUsage (argv[0]);
00076 return 0;
00077 }
00078 if (pcl::console::find_argument (argc, argv, "-m") >= 0)
00079 {
00080 setUnseenToMaxRange = true;
00081 cout << "Setting unseen values in range image to maximum range readings.\n";
00082 }
00083 if (pcl::console::parse (argc, argv, "-o", rotation_invariant) >= 0)
00084 cout << "Switching rotation invariant feature version "<< (rotation_invariant ? "on" : "off")<<".\n";
00085 int tmp_coordinate_frame;
00086 if (pcl::console::parse (argc, argv, "-c", tmp_coordinate_frame) >= 0)
00087 {
00088 coordinate_frame = pcl::RangeImage::CoordinateFrame (tmp_coordinate_frame);
00089 cout << "Using coordinate frame "<< (int)coordinate_frame<<".\n";
00090 }
00091 if (pcl::console::parse (argc, argv, "-s", support_size) >= 0)
00092 cout << "Setting support size to "<<support_size<<".\n";
00093 if (pcl::console::parse (argc, argv, "-r", angular_resolution) >= 0)
00094 cout << "Setting angular resolution to "<<angular_resolution<<"deg.\n";
00095 angular_resolution = pcl::deg2rad (angular_resolution);
00096
00097
00098
00099
00100 pcl::PointCloud<PointType>::Ptr point_cloud_ptr (new pcl::PointCloud<PointType>);
00101 pcl::PointCloud<PointType>& point_cloud = *point_cloud_ptr;
00102 pcl::PointCloud<pcl::PointWithViewpoint> far_ranges;
00103 Eigen::Affine3f scene_sensor_pose (Eigen::Affine3f::Identity ());
00104 std::vector<int> pcd_filename_indices = pcl::console::parse_file_extension_argument (argc, argv, "pcd");
00105 if (!pcd_filename_indices.empty ())
00106 {
00107 std::string filename = argv[pcd_filename_indices[0]];
00108 if (pcl::io::loadPCDFile (filename, point_cloud) == -1)
00109 {
00110 cerr << "Was not able to open file \""<<filename<<"\".\n";
00111 printUsage (argv[0]);
00112 return 0;
00113 }
00114 scene_sensor_pose = Eigen::Affine3f (Eigen::Translation3f (point_cloud.sensor_origin_[0],
00115 point_cloud.sensor_origin_[1],
00116 point_cloud.sensor_origin_[2])) *
00117 Eigen::Affine3f (point_cloud.sensor_orientation_);
00118 std::string far_ranges_filename = pcl::getFilenameWithoutExtension (filename)+"_far_ranges.pcd";
00119 if (pcl::io::loadPCDFile (far_ranges_filename.c_str (), far_ranges) == -1)
00120 std::cout << "Far ranges file \""<<far_ranges_filename<<"\" does not exists.\n";
00121 }
00122 else
00123 {
00124 setUnseenToMaxRange = true;
00125 cout << "\nNo *.pcd file given => Genarating example point cloud.\n\n";
00126 for (float x=-0.5f; x<=0.5f; x+=0.01f)
00127 {
00128 for (float y=-0.5f; y<=0.5f; y+=0.01f)
00129 {
00130 PointType point; point.x = x; point.y = y; point.z = 2.0f - y;
00131 point_cloud.points.push_back (point);
00132 }
00133 }
00134 point_cloud.width = (int) point_cloud.points.size (); point_cloud.height = 1;
00135 }
00136
00137
00138
00139
00140 float noise_level = 0.0;
00141 float min_range = 0.0f;
00142 int border_size = 1;
00143 boost::shared_ptr<pcl::RangeImage> range_image_ptr (new pcl::RangeImage);
00144 pcl::RangeImage& range_image = *range_image_ptr;
00145 range_image.createFromPointCloud (point_cloud, angular_resolution, pcl::deg2rad (360.0f), pcl::deg2rad (180.0f),
00146 scene_sensor_pose, coordinate_frame, noise_level, min_range, border_size);
00147 range_image.integrateFarRanges (far_ranges);
00148 if (setUnseenToMaxRange)
00149 range_image.setUnseenToMaxRange ();
00150
00151
00152
00153
00154 pcl::visualization::PCLVisualizer viewer ("3D Viewer");
00155 viewer.setBackgroundColor (1, 1, 1);
00156 pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> range_image_color_handler (range_image_ptr, 0, 0, 0);
00157 viewer.addPointCloud (range_image_ptr, range_image_color_handler, "range image");
00158 viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "range image");
00159
00160
00161
00162 viewer.initCameraParameters ();
00163 setViewerPose (viewer, range_image.getTransformationToWorldSystem ());
00164
00165
00166
00167
00168 pcl::visualization::RangeImageVisualizer range_image_widget ("Range image");
00169 range_image_widget.showRangeImage (range_image);
00170
00171
00172
00173
00174 pcl::RangeImageBorderExtractor range_image_border_extractor;
00175 pcl::NarfKeypoint narf_keypoint_detector;
00176 narf_keypoint_detector.setRangeImageBorderExtractor (&range_image_border_extractor);
00177 narf_keypoint_detector.setRangeImage (&range_image);
00178 narf_keypoint_detector.getParameters ().support_size = support_size;
00179
00180 pcl::PointCloud<int> keypoint_indices;
00181 narf_keypoint_detector.compute (keypoint_indices);
00182 std::cout << "Found "<<keypoint_indices.points.size ()<<" key points.\n";
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints_ptr (new pcl::PointCloud<pcl::PointXYZ>);
00195 pcl::PointCloud<pcl::PointXYZ>& keypoints = *keypoints_ptr;
00196 keypoints.points.resize (keypoint_indices.points.size ());
00197 for (size_t i=0; i<keypoint_indices.points.size (); ++i)
00198 keypoints.points[i].getVector3fMap () = range_image.points[keypoint_indices.points[i]].getVector3fMap ();
00199 pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> keypoints_color_handler (keypoints_ptr, 0, 255, 0);
00200 viewer.addPointCloud<pcl::PointXYZ> (keypoints_ptr, keypoints_color_handler, "keypoints");
00201 viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 7, "keypoints");
00202
00203
00204
00205
00206 std::vector<int> keypoint_indices2;
00207 keypoint_indices2.resize (keypoint_indices.points.size ());
00208 for (unsigned int i=0; i<keypoint_indices.size (); ++i)
00209 keypoint_indices2[i]=keypoint_indices.points[i];
00210 pcl::NarfDescriptor narf_descriptor (&range_image, &keypoint_indices2);
00211 narf_descriptor.getParameters ().support_size = support_size;
00212 narf_descriptor.getParameters ().rotation_invariant = rotation_invariant;
00213 pcl::PointCloud<pcl::Narf36> narf_descriptors;
00214 narf_descriptor.compute (narf_descriptors);
00215 cout << "Extracted "<<narf_descriptors.size ()<<" descriptors for "
00216 <<keypoint_indices.points.size ()<< " keypoints.\n";
00217
00218
00219
00220
00221 while (!viewer.wasStopped ())
00222 {
00223 range_image_widget.spinOnce ();
00224 viewer.spinOnce ();
00225 pcl_sleep(0.01);
00226 }
00227 }