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 #include <gtest/gtest.h>
00041 #include <pcl/point_cloud.h>
00042 #include <pcl/pcl_tests.h>
00043 #include <pcl/features/normal_3d_omp.h>
00044 #include <pcl/io/pcd_io.h>
00045 #include <pcl/features/board.h>
00046 
00047 using namespace pcl;
00048 using namespace pcl::test;
00049 using namespace pcl::io;
00050 using namespace std;
00051 
00052 typedef search::KdTree<PointXYZ>::Ptr KdTreePtr;
00053 
00054 PointCloud<PointXYZ> cloud;
00055 vector<int> indices;
00056 KdTreePtr tree;
00057 
00059 TEST (PCL, BOARDLocalReferenceFrameEstimation)
00060 {
00061   PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00062   PointCloud<ReferenceFrame> bunny_LRF;
00063 
00064   boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
00065 
00066   
00067   NormalEstimation<PointXYZ, Normal> ne;
00068 
00069   ne.setRadiusSearch (0.01);
00070   ne.setViewPoint (1, 1, 10);
00071   ne.setInputCloud (cloud.makeShared ());
00072   ne.setSearchMethod (tree);
00073   ne.setIndices (indicesptr);
00074 
00075   ne.compute (*normals);
00076 
00077   
00078   BOARDLocalReferenceFrameEstimation<PointXYZ, Normal, ReferenceFrame> lrf_estimator;
00079 
00080   float meshRes = 0.001f;
00081 
00082   lrf_estimator.setFindHoles (true);
00083   lrf_estimator.setRadiusSearch (15 * meshRes);
00084   lrf_estimator.setTangentRadius (15 * meshRes);
00085 
00086   lrf_estimator.setInputCloud (cloud.makeShared ());
00087   lrf_estimator.setInputNormals (normals);
00088   lrf_estimator.setSearchMethod (tree);
00089   lrf_estimator.setIndices (indicesptr);
00090 
00091   lrf_estimator.compute (bunny_LRF);
00092 
00093   
00094   EXPECT_EQ (indices.size (), bunny_LRF.size ());
00095 
00096   EXPECT_FALSE (bunny_LRF.is_dense);
00097   
00098   EXPECT_TRUE (pcl_isnan (bunny_LRF.at (24).x_axis[0]));
00099 
00100   
00101   
00102   Eigen::Vector3f point_15_x (-0.784923f, 0.208529f, 0.583448f);
00103   Eigen::Vector3f point_15_y (0.334206f, -0.650436f, 0.682085f);
00104   Eigen::Vector3f point_15_z (0.52173f, 0.730376f, 0.440851f);
00105 
00106   
00107   Eigen::Vector3f point_45_x (0.909111f, 0.30943f, 0.278874f);
00108   Eigen::Vector3f point_45_y (-0.362239f, 0.917811f, 0.162501f);
00109   Eigen::Vector3f point_45_z (-0.205671f, -0.248751f, 0.946479f);
00110 
00111   
00112   Eigen::Vector3f point_163_x (-0.443962f, -0.890073f, -0.103285f);
00113   Eigen::Vector3f point_163_y (0.746929f, -0.30394f, -0.591369f);
00114   Eigen::Vector3f point_163_z (0.494969f, -0.339693f, 0.799759f);
00115 
00116   
00117   Eigen::Vector3f point_253_x (-0.616855f, 0.757286f, -0.214495f);
00118   Eigen::Vector3f point_253_y (-0.661937f, -0.646584f, -0.379168f);
00119   Eigen::Vector3f point_253_z (-0.425827f, -0.0919098f, 0.900124f);
00120 
00121   
00122   
00123   
00124   
00125   
00126   for (int d = 0; d < 3; ++d)
00127   {
00128     EXPECT_NEAR (point_15_x[d], bunny_LRF.at (15).x_axis[d], 1E-3);
00129     EXPECT_NEAR (point_15_y[d], bunny_LRF.at (15).y_axis[d], 1E-3);
00130     EXPECT_NEAR (point_15_z[d], bunny_LRF.at (15).z_axis[d], 1E-3);
00131 
00132     EXPECT_NEAR (point_45_x[d], bunny_LRF.at (45).x_axis[d], 1E-3);
00133     EXPECT_NEAR (point_45_y[d], bunny_LRF.at (45).y_axis[d], 1E-3);
00134     EXPECT_NEAR (point_45_z[d], bunny_LRF.at (45).z_axis[d], 1E-3);
00135 
00136     EXPECT_NEAR (point_163_x[d], bunny_LRF.at (163).x_axis[d], 1E-3);
00137     EXPECT_NEAR (point_163_y[d], bunny_LRF.at (163).y_axis[d], 1E-3);
00138     EXPECT_NEAR (point_163_z[d], bunny_LRF.at (163).z_axis[d], 1E-3);
00139 
00140     EXPECT_NEAR (point_253_x[d], bunny_LRF.at (253).x_axis[d], 1E-3);
00141     EXPECT_NEAR (point_253_y[d], bunny_LRF.at (253).y_axis[d], 1E-3);
00142     EXPECT_NEAR (point_253_z[d], bunny_LRF.at (253).z_axis[d], 1E-3);
00143   }
00144 }
00145 
00146 
00147 int
00148 main (int argc, char** argv)
00149 {
00150   if (argc < 2)
00151   {
00152     std::cerr << "No test file given. Please download `bun0.pcd` and pass its path to the test." << std::endl;
00153     return (-1);
00154   }
00155 
00156   if (loadPCDFile<PointXYZ> (argv[1], cloud) < 0)
00157   {
00158     std::cerr << "Failed to read test file. Please download `bun0.pcd` and pass its path to the test." << std::endl;
00159     return (-1);
00160   }
00161 
00162   indices.resize (cloud.points.size ());
00163   for (size_t i = 0; i < indices.size (); ++i)
00164     indices[i] = static_cast<int> (i);
00165 
00166   tree.reset (new search::KdTree<PointXYZ> (false));
00167   tree->setInputCloud (cloud.makeShared ());
00168 
00169   testing::InitGoogleTest (&argc, argv);
00170   return (RUN_ALL_TESTS ());
00171 }
00172