00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <pcl/common/time.h>
00042 #include <pcl/point_cloud.h>
00043 #include <pcl/point_types.h>
00044 #include <pcl/PCLPointCloud2.h>
00045
00046 #include <pcl/io/pcd_io.h>
00047 #include <pcl/pcl_macros.h>
00048
00049 #include <pcl/console/print.h>
00050 #include <pcl/console/parse.h>
00051
00052 #include <pcl/outofcore/outofcore.h>
00053 #include <pcl/outofcore/outofcore_impl.h>
00054
00055 #include <boost/accumulators/accumulators.hpp>
00056 #include <boost/accumulators/statistics/min.hpp>
00057 #include <boost/accumulators/statistics/max.hpp>
00058 #include <boost/accumulators/statistics/mean.hpp>
00059 #include <boost/accumulators/statistics/variance.hpp>
00060
00061 namespace ba = boost::accumulators;
00062
00063
00064
00065 typedef pcl::PointXYZ PointT;
00066
00067 using namespace pcl;
00068 using namespace pcl::outofcore;
00069
00070 using pcl::console::parse_argument;
00071 using pcl::console::parse_file_extension_argument;
00072 using pcl::console::find_switch;
00073 using pcl::console::print_error;
00074 using pcl::console::print_warn;
00075 using pcl::console::print_info;
00076 using pcl::console::print;
00077
00078 #include <boost/foreach.hpp>
00079
00080 typedef OutofcoreOctreeBase<> OctreeDisk;
00081 typedef OutofcoreOctreeBaseNode<> OctreeDiskNode;
00082 typedef OutofcoreBreadthFirstIterator<> OctreeBreadthFirstIterator;
00083 typedef OutofcoreDepthFirstIterator<> OctreeDepthFirstIterator;
00084
00085 typedef Eigen::aligned_allocator<PointT> AlignedPointT;
00086
00087 void
00088 printDepth(size_t depth)
00089 {
00090 for (int i=0; i < depth; i++)
00091 PCL_INFO (" ");
00092 }
00093
00094 void
00095 printNode(OctreeDiskNode *)
00096 {
00097
00098 }
00099
00100 int
00101 outofcorePrint (boost::filesystem::path tree_root, size_t print_depth, bool bounding_box=false, bool pcd=false,
00102 bool point_count=false, bool breadth_first=false)
00103 {
00104 std::cout << boost::filesystem::absolute (tree_root) << std::endl;
00105
00106 OctreeDisk* octree;
00107 octree = new OctreeDisk (tree_root, true);
00108
00109 Eigen::Vector3d min, max;
00110 octree->getBoundingBox(min, max);
00111
00112
00113 PCL_INFO (" Bounding Box: <%lf, %lf, %lf> - <%lf, %lf, %lf>\n", min[0], min[1], min[2], max[0], max[1], max[2]);
00114
00115
00116 uint64_t depth = octree->getTreeDepth ();
00117 PCL_INFO (" Depth: %ld\n", depth);
00118 if (print_depth > depth)
00119 print_depth = depth;
00120
00121
00122 std::vector<boost::uint64_t> lodPoints = octree->getNumPointsVector ();
00123 PCL_INFO (" Points:\n");
00124 for (boost::uint64_t i = 0; i < lodPoints.size (); i++)
00125 PCL_INFO (" %d: %d\n", i, lodPoints[i]);
00126
00127
00128 PCL_INFO(" Voxel Side Length: %d\n", octree->getVoxelSideLength ());
00129
00130
00131 std::vector<PointT, AlignedPointT> voxel_centers;
00132 octree->getOccupiedVoxelCenters(voxel_centers);
00133 PCL_INFO(" Voxel Count: %d\n", voxel_centers.size ());
00134
00135
00136 std::vector<boost::uint64_t> pointsPerVoxel;
00137 ba::accumulator_set<boost::uint64_t, ba::features< ba::tag::min, ba::tag::max, ba::tag::mean, ba::tag::variance> > acc;
00138
00139 if (!breadth_first)
00140 {
00141 OctreeDisk::DepthFirstIterator depth_first_it (*octree);
00142
00143 while ( *depth_first_it !=0 )
00144 {
00145 OctreeDiskNode *node = *depth_first_it;
00146 size_t node_depth = node->getDepth();
00147
00148 printDepth(node_depth);
00149 std::string metadata_relative_file = node->getMetadataFilename ().string ();
00150 boost::replace_first(metadata_relative_file, tree_root.parent_path ().string (), "");
00151 PCL_INFO ("..%s\n", metadata_relative_file.c_str());
00152
00153 printDepth(node_depth);
00154
00155 if (pcd)
00156 {
00157 std::string pcd_relative_file = node->getPCDFilename ().string ();
00158 boost::replace_first(pcd_relative_file, tree_root.parent_path ().string (), "");
00159 PCL_INFO (" PCD: ..%s\n", pcd_relative_file.c_str());
00160 }
00161
00162 if (bounding_box)
00163 {
00164 Eigen::Vector3d min, max;
00165 node->getBoundingBox(min, max);
00166
00167 printDepth(node_depth);
00168 PCL_INFO (" Bounding Box: <%lf, %lf, %lf> - <%lf, %lf, %lf>\n", min[0], min[1], min[2], max[0], max[1], max[2]);
00169 }
00170
00171 if (point_count)
00172 {
00173 printDepth(node_depth);
00174 PCL_INFO (" Points: %lu\n", node->getDataSize());
00175 pointsPerVoxel.push_back( node->getDataSize());
00176 acc(node->getDataSize());
00177 }
00178
00179 depth_first_it++;
00180 }
00181 }
00182 else
00183 {
00184 OctreeDisk::BreadthFirstIterator breadth_first_it (*octree);
00185 breadth_first_it.setMaxDepth (static_cast<unsigned int> (print_depth));
00186 while ( *breadth_first_it !=0 )
00187 {
00188 OctreeDiskNode *node = *breadth_first_it;
00189 size_t node_depth = node->getDepth();
00190
00191 printDepth(node_depth);
00192 std::string metadata_relative_file = node->getMetadataFilename ().string ();
00193 boost::replace_first(metadata_relative_file, tree_root.parent_path ().string (), "");
00194 PCL_INFO ("..%s\n", metadata_relative_file.c_str());
00195
00196 printDepth(node_depth);
00197
00198 if(pcd)
00199 {
00200 std::string pcd_relative_file = node->getPCDFilename ().string ();
00201 boost::replace_first(pcd_relative_file, tree_root.parent_path ().string (), "");
00202 PCL_INFO (" PCD: ..%s\n", pcd_relative_file.c_str());
00203 }
00204
00205 if (bounding_box)
00206 {
00207 Eigen::Vector3d min, max;
00208 node->getBoundingBox(min, max);
00209
00210 printDepth(node_depth);
00211 PCL_INFO (" Bounding Box: <%lf, %lf, %lf> - <%lf, %lf, %lf>\n", min[0], min[1], min[2], max[0], max[1], max[2]);
00212 }
00213
00214 if (point_count)
00215 {
00216 printDepth(node_depth);
00217 PCL_INFO (" Points: %lu\n", node->getDataSize());
00218 pointsPerVoxel.push_back( node->getDataSize());
00219 acc(node->getDataSize());
00220 }
00221
00222 breadth_first_it++;
00223 }
00224 }
00225
00226 if(point_count)
00227 {
00228 PCL_INFO("Points per Voxel:\n");
00229 PCL_INFO("Min: %u, Max: %u, Mean: %f, StdDev %f\n", ba::min(acc),
00230 ba::max(acc), ba::mean(acc), sqrt(ba::variance(acc)));
00231 }
00232
00233 return 0;
00234 }
00235
00236
00237 void
00238 printHelp (int, char **argv)
00239 {
00240 print_info ("This program is used to process pcd fiels into an outofcore data structure viewable by the");
00241 print_info ("pcl_outofcore_viewer\n\n");
00242 print_info ("%s <options> <input_tree_dir> \n", argv[0]);
00243 print_info ("\n");
00244 print_info ("Options:\n");
00245 print_info ("\t -depth <depth> \t Octree depth\n");
00246 print_info ("\t -bounding_box \t Print bounding box info\n");
00247 print_info ("\t -point_count \t Print point count info\n");
00248 print_info ("\t -pcd \t Print pcd file info\n");
00249 print_info ("\t -breadth \t Print nodes in breadth-first (Default depth-first)\n");
00250 print_info ("\t -h \t Display help\n");
00251 print_info ("\n");
00252 }
00253
00254 int
00255 main (int argc, char* argv[])
00256 {
00257
00258
00259 if (argc > 1)
00260 {
00261 if (find_switch (argc, argv, "-h"))
00262 {
00263 printHelp (argc, argv);
00264 return (-1);
00265 }
00266 }
00267
00268
00269 if (argc - 1 < 1)
00270 {
00271 printHelp (argc, argv);
00272 return (-1);
00273 }
00274
00275 if (find_switch (argc, argv, "-v"))
00276 console::setVerbosityLevel (console::L_DEBUG);
00277
00278
00279 int depth = INT_MAX;
00280 bool breadth_first = find_switch (argc, argv, "-breadth");
00281 bool bounding_box = find_switch (argc, argv, "-bounding_box");
00282 bool pcd = find_switch (argc, argv, "-pcd");
00283 bool point_count = find_switch (argc, argv, "-point_count");
00284
00285
00286 parse_argument (argc, argv, "-depth", depth);
00287
00288
00289 boost::filesystem::path tree_root (argv[argc - 1]);
00290
00291
00292 if (boost::filesystem::is_directory (tree_root))
00293 {
00294 boost::filesystem::directory_iterator diterend;
00295 for (boost::filesystem::directory_iterator diter (tree_root); diter != diterend; ++diter)
00296 {
00297 const boost::filesystem::path& file = *diter;
00298 if (!boost::filesystem::is_directory (file))
00299 {
00300 if (boost::filesystem::extension (file) == OctreeDiskNode::node_index_extension)
00301 {
00302 tree_root = file;
00303 }
00304 }
00305 }
00306 }
00307
00308 return outofcorePrint (tree_root, depth, bounding_box, pcd, point_count, breadth_first);
00309 }