void FloorAxisAlignment::alignCloudPrincipleAxis (const PointCloudConstPtr input_cloud_ptr,
      const PointCloudPtr output_cloud_ptr,
      Eigen::Matrix4f& transform_output)
  {
//        Visualization visualizer;
    Eigen::Matrix4f inital_guess;
    inital_guess.block<3,3>(0,0) = Eigen::AngleAxisf(angle_, axis_).toRotationMatrix();
//    inital_guess = Eigen::Matrix4f::Zero(4,4);
//    inital_guess(0,0) = 1.0;
//    inital_guess(1,2) = 1.0;
//    inital_guess(2,1) = -1.0;
//    inital_guess(3,3) = 1.0;
    PointCloudPtr rotated_cloud_ptr (new PointCloud);
    transformPointCloud (*input_cloud_ptr, *rotated_cloud_ptr, inital_guess);
//    std::vector<PointCloudConstPtr> vis_cloud_ptrs;
//    vis_cloud_ptrs.push_back(rotated_cloud_ptr);
    //transformPointCloud (*input_cloud_ptr, *output_cloud_ptr, inital_guess);

    //assume the model is approx correct, i.e. z is height
    // find the largest plane perpendicular to z axis and use this to align cloud
    pcl17::ModelCoefficients::Ptr coefficients (new pcl17::ModelCoefficients);
    pcl17::PointIndices::Ptr inliers (new pcl17::PointIndices);
    pcl17::SACSegmentation<PointType> seg;
    seg.setOptimizeCoefficients (true);
    seg.setModelType (pcl17::SACMODEL_PERPENDICULAR_PLANE);
    seg.setMethodType (pcl17::SAC_RANSAC);
    seg.setDistanceThreshold (ransac_threshold_);
    seg.setMaxIterations(max_iterations_);
    //seg.setProbability(0.1);

    seg.setAxis (Eigen::Vector3f (0, 0, 1));
    seg.setEpsAngle (30.0 * (M_PI / 180));//radians
    seg.setInputCloud (rotated_cloud_ptr);
    seg.segment (*inliers, *coefficients);

    if (inliers->indices.size () == 0)
    {
      PCL17_ERROR("Could not estimate a planar model for the given dataset.");
      // I had some issues with pcl on a different computer to where I normally dev.  This is a workaround to be removed
      coefficients->values.push_back(-0.0370391);
      coefficients->values.push_back(0.0777064);
      coefficients->values.push_back(0.996288);
      coefficients->values.push_back(2.63374);
    }


    std::cerr << "Model coefficients: " << coefficients->values[0] << " " << coefficients->values[1]
    << " " << coefficients->values[2] << " " << coefficients->values[3] << std::endl;

    // calculate angle and axis from dot product
    double rotate = acos (coefficients->values[2]);
    Eigen::Vector3f axis_to_rotate_about (-coefficients->values[1], coefficients->values[0], 0.0);
    axis_to_rotate_about.normalize ();

    //convert axis and angle to rotation matrix and apply to pointcloud
    Eigen::AngleAxis<float> angle_axis (rotate, axis_to_rotate_about);
    transform_output = Eigen::Matrix4f::Identity (4, 4);
    transform_output.block<3, 3> (0, 0) = angle_axis.toRotationMatrix ().inverse ();

    // apply translation to bring the floor to z = 0
    transform_output(2, 3) = coefficients->values[3];
    transformPointCloud (*rotated_cloud_ptr, *output_cloud_ptr, transform_output);

//  pcl17::ExtractIndices<PointType> eifilter;
//   eifilter.setInputCloud (rotated_cloud_ptr);
//   eifilter.setIndices (inliers);
//   eifilter.filter (*output_cloud_ptr);
//   vis_cloud_ptrs.push_back(output_cloud_ptr);
//   visualizer.visualizeCloud(vis_cloud_ptrs);
  }
Example #2
0
int main(int argc, char** argv)
{

  if (argc < 5)
  {
    PCL17_INFO ("Usage %s -input_dir /dir/with/models -output_dir /output/dir [options]\n", argv[0]);
    PCL17_INFO (" * where options are:\n"
        "         -height <X>            : simulate scans with sensor mounted on height X\n"
        "         -noise_std <X>         : std of gaussian noise added to pointcloud. Default value 0.0001.\n"
        "         -distance <X>          : simulate scans with object located on a distance X. Can be used multiple times. Default value 4.\n"
        "         -tilt <X>              : tilt sensor for X degrees. X == 0 - sensor looks strait. X < 0 Sensor looks down. X > 0 Sensor looks up . Can be used multiple times. Default value -15.\n"
        "         -shift <X>             : shift object from the straight line. Can be used multiple times. Default value 0.\n"
        "         -num_views <X>         : how many times rotate the object in for every distance, tilt and shift. Default value 6.\n"

        "");
    return -1;
  }

  std::string input_dir, output_dir;
  double height = 1.5;
  double num_views = 6;
  double noise_std = 0.0001;
  std::vector<double> distances;
  std::vector<double> tilt;
  std::vector<double> shift;
  int full_model_n_points = 30000;

  pcl17::console::parse_argument(argc, argv, "-input_dir", input_dir);
  pcl17::console::parse_argument(argc, argv, "-output_dir", output_dir);
  pcl17::console::parse_argument(argc, argv, "-num_views", num_views);
  pcl17::console::parse_argument(argc, argv, "-height", height);
  pcl17::console::parse_argument(argc, argv, "-noise_std", noise_std);
  pcl17::console::parse_multiple_arguments(argc, argv, "-distance", distances);
  pcl17::console::parse_multiple_arguments(argc, argv, "-tilt", tilt);
  pcl17::console::parse_multiple_arguments(argc, argv, "-shift", shift);

  PCL17_INFO("distances size: %d\n", distances.size());
  for (size_t i = 0; i < distances.size(); i++)
  {
    PCL17_INFO("distance: %f\n", distances[i]);
  }

  // Set default values if user didn't provide any
  if (distances.size() == 0)
    distances.push_back(4);
  if (tilt.size() == 0)
    tilt.push_back(-15);
  if (shift.size() == 0)
    shift.push_back(0);

  // Check if input path exists
  boost::filesystem::path input_path(input_dir);
  if (!boost::filesystem::exists(input_path))
  {
    PCL17_ERROR("Input directory doesnt exists.");
    return -1;
  }

  // Check if input path is a directory
  if (!boost::filesystem::is_directory(input_path))
  {
    PCL17_ERROR("%s is not directory.", input_path.c_str());
    return -1;
  }

  // Check if output directory exists
  boost::filesystem::path output_path(output_dir);
  if (!boost::filesystem::exists(output_path) || !boost::filesystem::is_directory(output_path))
  {
    if (!boost::filesystem::create_directories(output_path))
    {
      PCL17_ERROR ("Error creating directory %s.\n", output_path.c_str ());
      return -1;
    }
  }

  // Find all .vtk files in the input directory
  std::vector<std::string> files_to_process;
  PCL17_INFO("Processing following files:\n");
  boost::filesystem::directory_iterator end_iter;
  for (boost::filesystem::directory_iterator iter(input_path); iter != end_iter; iter++)
  {
    boost::filesystem::path class_dir_path(*iter);
    for (boost::filesystem::directory_iterator iter2(class_dir_path); iter2 != end_iter; iter2++)
    {
      boost::filesystem::path file(*iter2);
      if (file.extension() == ".vtk")
      {
        files_to_process.push_back(file.c_str());
        PCL17_INFO("\t%s\n", file.c_str());
      }
    }

  }

  // Check if there are any .vtk files to process
  if (files_to_process.size() == 0)
  {
    PCL17_ERROR("Directory %s has no .vtk files.", input_path.c_str());
    return -1;
  }

  // Iterate over all files
  for (size_t i = 0; i < files_to_process.size(); i++)
  {
    vtkSmartPointer<vtkPolyData> model;
    vtkSmartPointer<vtkPolyDataReader> reader = vtkPolyDataReader::New();
    vtkSmartPointer<vtkTransform> transform = vtkTransform::New();
    pcl17::PointCloud<pcl17::PointXYZ>::Ptr cloud(new pcl17::PointCloud<pcl17::PointXYZ>());

    // Compute output directory for this model
    std::vector<std::string> st;
    boost::split(st, files_to_process.at(i), boost::is_any_of("/"), boost::token_compress_on);
    std::string class_dirname = st.at(st.size() - 2);
    std::string dirname = st.at(st.size() - 1);
    dirname = dirname.substr(0, dirname.size() - 4);
    dirname = output_dir + class_dirname + "/" + dirname;

    // Check if output directory for this model exists. If not create
    boost::filesystem::path dirpath(dirname);
    if (!boost::filesystem::exists(dirpath))
    {
      if (!boost::filesystem::create_directories(dirpath))
      {
        PCL17_ERROR ("Error creating directory %s.\n", dirpath.c_str ());
        return -1;
      }
    }

    // Load model from file
    reader->SetFileName(files_to_process.at(i).c_str());
    reader->Update();
    model = reader->GetOutput();
    PCL17_INFO("Number of points %d\n",model->GetNumberOfPoints());

    // Coumpute bounds and center of the model
    double bounds[6];
    model->GetBounds(bounds);
    double min_z_value = bounds[4];

    double center[3];
    model->GetCenter(center);

    createFullModelPointcloud(model, full_model_n_points, *cloud);
    pcl17::io::savePCDFile(dirname + "/full.pcd", *cloud);

    // Initialize PCLVisualizer. Add model to scene.
    pcl17::visualization::PCLVisualizer viz;
    viz.initCameraParameters();
    viz.updateCamera();
    viz.setCameraPosition(0, 0, 0, 1, 0, 0, 0, 0, 1);
    viz.addModelFromPolyData(model, transform);
    viz.setRepresentationToSurfaceForAllActors();

    // Iterate over all shifts
    for (size_t shift_index = 0; shift_index < shift.size(); shift_index++)
    {

      // Iterate over all tilts
      for (size_t tilt_index = 0; tilt_index < tilt.size(); tilt_index++)
      {

        // Iterate over all distances
        for (size_t distance_index = 0; distance_index < distances.size(); distance_index++)
        {

          // Iterate over all angles
          double angle = 0;
          double angle_step = 360.0 / num_views;
          for (int angle_index = 0; angle_index < num_views; angle_index++)
          {

            // Set transformation with distance, shift, tilt and angle parameters.
            transform->Identity();
            transform->RotateY(tilt[tilt_index]);
            transform->Translate(distances[distance_index], shift[shift_index], -(height + min_z_value));
            transform->RotateZ(angle);

		/*		

            // Render pointcloud
            viz.renderView(640, 480, cloud);

            //Add noise
            addNoise(cloud, noise_std);

            // Compute new coordinates of the model center
            double new_center[3];
            transform->TransformPoint(center, new_center);

            // Shift origin of the poincloud to the model center and align with initial coordinate system.
            pcl17::PointCloud<pcl17::PointXYZ>::Ptr cloud_transformed(new pcl17::PointCloud<pcl17::PointXYZ>());
            moveToNewCenterAndAlign(cloud, cloud_transformed, new_center, tilt[tilt_index]);

            // Compute file name for this pointcloud and save it
            std::stringstream ss;
            ss << dirname << "/rotation" << angle << "_distance" << distances[distance_index] << "_tilt"
                << tilt[tilt_index] << "_shift" << shift[shift_index] << ".pcd";
            PCL17_INFO("Writing %d points to file %s\n", cloud->points.size(), ss.str().c_str());
            pcl17::io::savePCDFile(ss.str(), *cloud_transformed);

		*/

            // increment angle by step
            angle += angle_step;
	
	

          }

        }
      }
    }

  }

  return 0;
}
Example #3
0
// --------------
// -----Main-----
// --------------
int main(int argc, char** argv)
{
  // --------------------------------------
  // -----Parse Command Line Arguments-----
  // --------------------------------------
  if (pcl17::console::find_argument(argc, argv, "-h") >= 0)
  {
    printUsage(argv[0]);
    return 0;
  }
  bool simple(false), rgb(false), custom_c(false), normals(false), shapes(false), viewports(false),
       interaction_customization(false);
  if (pcl17::console::find_argument(argc, argv, "-s") >= 0)
  {
    simple = true;
    std::cout << "Simple visualisation example\n";
  }
  else if (pcl17::console::find_argument(argc, argv, "-c") >= 0)
  {
    custom_c = true;
    std::cout << "Custom colour visualisation example\n";
  }
  else if (pcl17::console::find_argument(argc, argv, "-r") >= 0)
  {
    rgb = true;
    std::cout << "RGB colour visualisation example\n";
  }
  else if (pcl17::console::find_argument(argc, argv, "-n") >= 0)
  {
    normals = true;
    std::cout << "Normals visualisation example\n";
  }
  else if (pcl17::console::find_argument(argc, argv, "-a") >= 0)
  {
    shapes = true;
    std::cout << "Shapes visualisation example\n";
  }
  else if (pcl17::console::find_argument(argc, argv, "-v") >= 0)
  {
    viewports = true;
    std::cout << "Viewports example\n";
  }
  else if (pcl17::console::find_argument(argc, argv, "-i") >= 0)
  {
    interaction_customization = true;
    std::cout << "Interaction Customization example\n";
  }
  else
  {
    printUsage(argv[0]);
    return 0;
  }

  // ------------------------------------
  // -----Create example point cloud-----
  // ------------------------------------
  pcl17::PointCloud<pcl17::PointXYZRGB>::Ptr basic_cloud_ptr(new pcl17::PointCloud<pcl17::PointXYZRGB>);
  pcl17::PointCloud<pcl17::PointXYZRGB>::Ptr point_cloud_ptr(new pcl17::PointCloud<pcl17::PointXYZRGB>);
  pcl17::PointCloud<pcl17::PointXYZRGB>::Ptr cloud_f(new pcl17::PointCloud<pcl17::PointXYZRGB>);
  pcl17::VoxelGrid<pcl17::PointXYZRGB > sor;
  //pcl17::PLYReader reader;
  //reader.read("box.ply",*point_cloud_ptr,0);
  //pcl17::PointXYZRGB point;

  if (pcl17::io::loadPCDFile<pcl17::PointXYZRGB>(argv[1], *point_cloud_ptr) == -1) //* load the file
  {
    PCL17_ERROR("Couldn't read file test_pcd.pcd \n");
    return (-1);
  }
  basic_cloud_ptr = point_cloud_ptr;
  /*
  std::cout << "Loaded " << point_cloud_ptr->width * point_cloud_ptr->height << " data points" << std::endl;
  cout << "gobbel" << endl;
  sor.setInputCloud(point_cloud_ptr);
  std::cerr << "PointCloud before filtering: " << point_cloud_ptr->width * point_cloud_ptr->height << " data points ("
      << pcl17::getFieldsList(*point_cloud_ptr) << ").";
  std::cout << std::endl;
  sor.setLeafSize(0.01, 0.01, 0.01);
  sor.filter(*cloud_f);
  pcl17::io::savePCDFileASCII("BoxFiltered.pcd", *cloud_f); */
  /* for (size_t i = 0; i < point_cloud_ptr->points.size (); ++i)
   std::cout << "    " << point_cloud_ptr->points[i].x
   << " "    << point_cloud_ptr->points[i].y
   << " "    << point_cloud_ptr->points[i].z << std::endl;
   cout << point_cloud_ptr->width << endl;
   cout << point_cloud_ptr->height << endl;
   for(int i=0;i<point_cloud_ptr->width * point_cloud_ptr->height;i++)
   {
   point=point_cloud_ptr->points.at(i);
   point.r = 255;
   point.g = 0;
   point.b = 0;
   basic_cloud_ptr->points.at(i)=point;
   }
   cout << basic_cloud_ptr->width << endl;
   cout << basic_cloud_ptr->height << endl;
   pcl17::PCDWriter writer;
   writer.write<pcl17::PointXYZRGB> (argv[1], *basic_cloud_ptr, false);
   point_cloud_ptr=basic_cloud_ptr; */
  // ----------------------------------------------------------------
  // -----Calculate surface normals with a search radius of 0.05-----
  // ----------------------------------------------------------------
  pcl17::NormalEstimation<pcl17::PointXYZRGB, pcl17::Normal> ne;
  ne.setInputCloud(point_cloud_ptr);
  pcl17::search::KdTree<pcl17::PointXYZRGB>::Ptr tree(new pcl17::search::KdTree<pcl17::PointXYZRGB>());
  ne.setSearchMethod(tree);
  pcl17::PointCloud<pcl17::Normal>::Ptr cloud_normals1(new pcl17::PointCloud<pcl17::Normal>);
  ne.setRadiusSearch(0.05);
  ne.compute(*cloud_normals1);

  // ---------------------------------------------------------------
  // -----Calculate surface normals with a search radius of 0.1-----
  // ---------------------------------------------------------------
  pcl17::PointCloud<pcl17::Normal>::Ptr cloud_normals2(new pcl17::PointCloud<pcl17::Normal>);
  ne.setRadiusSearch(0.1);
  ne.compute(*cloud_normals2);

  boost::shared_ptr<pcl17::visualization::PCLVisualizer> viewer;
  if (simple)
  {
    viewer = simpleVis(basic_cloud_ptr);
  }
  else if (rgb)
  {
    viewer = rgbVis(point_cloud_ptr);
  }
  else if (custom_c)
  {
    viewer = customColourVis(basic_cloud_ptr);
  }
  else if (normals)
  {
    viewer = normalsVis(point_cloud_ptr, cloud_normals2);
  }
  else if (shapes)
  {
    viewer = shapesVis(point_cloud_ptr);
  }
  else if (viewports)
  {
    viewer = viewportsVis(point_cloud_ptr, cloud_normals1, cloud_normals2);
  }
  else if (interaction_customization)
  {
    viewer = interactionCustomizationVis();
  }

  //--------------------
  // -----Main loop-----
  //--------------------
  while (!viewer->wasStopped())
  {
    viewer->spinOnce(100);
    boost::this_thread::sleep(boost::posix_time::microseconds(100000));
  }
}