Skip to content

Commit

Permalink
Added PointCloud i/o utilities; updated examples and README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
kzampog committed May 5, 2018
1 parent 4730728 commit 2f83f33
Show file tree
Hide file tree
Showing 15 changed files with 126 additions and 70 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@
- General dimension k-means clustering that supports all distance metrics supported by [nanoflann](https://github.com/jlblancoc/nanoflann)
- Spectral clustering based on various graph Laplacian types (using bundled [Spectra](https://github.com/yixuan/spectra))
- Flat kernel mean-shift clustering
- Connected component based point cloud segmentation, with pairwise similarities capturing any combination of spatial proximity, normal smoothness, and color similarity
- Connected component based point cloud segmentation that supports generic point-wise similarity functions

#### Model estimation and point set registration:
- A RANSAC estimator template and instantiations thereof for robust plane estimation and rigid 6DOF point cloud registration
- Generic Iterative Closest Point implementations for point-to-point and point-to-plane metrics (and combinations thereof) that support arbitrary correspondence types on any kind of point features
- Fully generic Iterative Closest Point implementations for point-to-point and point-to-plane metrics (and combinations thereof) that support arbitrary correspondence search methods in arbitrary point feature spaces

#### Visualization:
- A fast, powerful, and easy to use 3D visualizer
- A powerful, extensible, and easy to use 3D visualizer
- RGBD images to/from point cloud utility functions

## Dependencies
Expand Down
10 changes: 7 additions & 3 deletions examples/connected_component_segmentation_example.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
#include <cilantro/common_similarity_evaluators.hpp>
#include <cilantro/connected_component_segmentation.hpp>
#include <cilantro/io.hpp>
#include <cilantro/point_cloud.hpp>
#include <cilantro/visualizer.hpp>
#include <cilantro/common_renderables.hpp>

int main(int argc, char ** argv) {
cilantro::PointCloud3f cloud;
cilantro::readPointCloudFromPLYFile(argv[1], cloud);
if (argc < 2) {
std::cout << "Please provide path to PLY file" << std::endl;
return 0;
}

cilantro::PointCloud3f cloud(argv[1]);

cloud.gridDownsample(0.005f).removeInvalidData();

Expand Down
10 changes: 6 additions & 4 deletions examples/convex_hull_example.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include <cilantro/flat_convex_hull_3d.hpp>
#include <cilantro/io.hpp>
#include <cilantro/point_cloud.hpp>
#include <cilantro/visualizer.hpp>
#include <cilantro/common_renderables.hpp>

Expand Down Expand Up @@ -45,10 +45,12 @@ int main(int argc, char ** argv) {
// }
// std::cout << std::endl;
// }
if (argc < 2) {
std::cout << "Please provide path to PLY file" << std::endl;
return 0;
}


cilantro::PointCloud3f cloud;
cilantro::readPointCloudFromPLYFile(argv[1], cloud);
cilantro::PointCloud3f cloud(argv[1]);

cilantro::ConvexHull3f ch(cloud.points, true, true);
cilantro::PointCloud3f hc(cloud, ch.getVertexPointIndices());
Expand Down
12 changes: 8 additions & 4 deletions examples/grid_downsampler_example.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
#include <cilantro/grid_downsampler.hpp>
#include <cilantro/io.hpp>
//#include <cilantro/grid_downsampler.hpp>
#include <cilantro/point_cloud.hpp>
#include <cilantro/visualizer.hpp>
#include <cilantro/common_renderables.hpp>

int main(int argc, char ** argv) {
cilantro::PointCloud3f cloud;
readPointCloudFromPLYFile(argv[1], cloud);
if (argc < 2) {
std::cout << "Please provide path to PLY file" << std::endl;
return 0;
}

cilantro::PointCloud3f cloud(argv[1]);

auto start = std::chrono::high_resolution_clock::now();
cilantro::PointCloud3f cloud_d(cloud.gridDownsampled(0.01f));
Expand Down
12 changes: 8 additions & 4 deletions examples/iterative_closest_point_example.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include <cilantro/icp_common_instances.hpp>
#include <cilantro/io.hpp>
#include <cilantro/point_cloud.hpp>
#include <cilantro/visualizer.hpp>
#include <cilantro/common_renderables.hpp>

Expand All @@ -8,13 +8,17 @@ void callback(bool &proceed) {
}

int main(int argc, char ** argv) {
cilantro::PointCloud3f dst, src;
cilantro::readPointCloudFromPLYFile(argv[1], dst);
if (argc < 2) {
std::cout << "Please provide path to PLY file" << std::endl;
return 0;
}

cilantro::PointCloud3f dst(argv[1]);

dst.gridDownsample(0.005f);

// Create a distorted and transformed version of the point cloud
src = dst;
cilantro::PointCloud3f src(dst);
for (size_t i = 0; i < src.size(); i++) {
src.points.col(i) += 0.01f*Eigen::Vector3f::Random();
src.normals.col(i) += 0.02f*Eigen::Vector3f::Random();
Expand Down
10 changes: 7 additions & 3 deletions examples/kmeans_example.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
#include <cilantro/kmeans.hpp>
#include <cilantro/io.hpp>
#include <cilantro/point_cloud.hpp>
#include <cilantro/visualizer.hpp>
#include <cilantro/common_renderables.hpp>

int main(int argc, char ** argv) {
cilantro::PointCloud3f cloud;
cilantro::readPointCloudFromPLYFile(argv[1], cloud);
if (argc < 2) {
std::cout << "Please provide path to PLY file" << std::endl;
return 0;
}

cilantro::PointCloud3f cloud(argv[1]);

cloud.gridDownsample(0.005f).removeInvalidData();

Expand Down
10 changes: 7 additions & 3 deletions examples/normal_estimation_example.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
#include <cilantro/normal_estimation.hpp>
#include <cilantro/io.hpp>
#include <cilantro/point_cloud.hpp>
#include <cilantro/visualizer.hpp>
#include <cilantro/common_renderables.hpp>

int main(int argc, char ** argv) {
cilantro::PointCloud3f cloud;
readPointCloudFromPLYFile(argv[1], cloud);
if (argc < 2) {
std::cout << "Please provide path to PLY file" << std::endl;
return 0;
}

cilantro::PointCloud3f cloud(argv[1]);

// Clear input normals
cloud.normals.resize(Eigen::NoChange, 0);
Expand Down
8 changes: 6 additions & 2 deletions examples/plane_estimator_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@ void callback(bool &re_estimate) {
}

int main(int argc, char **argv) {
cilantro::PointCloud3f cloud;
readPointCloudFromPLYFile(argv[1], cloud);
if (argc < 2) {
std::cout << "Please provide path to PLY file" << std::endl;
return 0;
}

cilantro::PointCloud3f cloud(argv[1]);

cilantro::Visualizer viz("PlaneEstimator example", "disp");
bool re_estimate = false;
Expand Down
9 changes: 4 additions & 5 deletions examples/ply_io_example.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include <iostream>
#include <pangolin/utils/file_utils.h>
#include <cilantro/io.hpp>

#include <cilantro/point_cloud.hpp>

int main(int argc, char **argv) {
cilantro::PointCloud3f cloud;
Expand All @@ -11,7 +10,7 @@ int main(int argc, char **argv) {
if (argc < 3) {
std::cout << "No input path provided. Using default test cloud location." << std::endl;
fileInPath = "../examples/test_clouds/test.ply";
fileOutPath = "./kustas_copy.ply";
fileOutPath = "./test_copy.ply";
} else {
fileInPath = std::string(argv[1]);
fileOutPath = std::string(argv[2]);
Expand All @@ -27,7 +26,7 @@ int main(int argc, char **argv) {
return -1;
}

readPointCloudFromPLYFile(fileInPath, cloud);
cloud.fromPLYFile(fileInPath);
std::cout << cloud.points.cols() << " points read" << std::endl;
std::cout << cloud.normals.cols() << " normals read" << std::endl;
std::cout << cloud.colors.cols() << " colors read" << std::endl;
Expand All @@ -46,7 +45,7 @@ int main(int argc, char **argv) {
return -1;
}

writePointCloudToPLYFile(fileOutPath, pc);
pc.toPLYFile(fileOutPath);
std::cout << pc.points.cols() << " points written" << std::endl;
std::cout << pc.normals.cols() << " normals written" << std::endl;
std::cout << pc.colors.cols() << " colors written" << std::endl;
Expand Down
8 changes: 5 additions & 3 deletions examples/rigid_transformation_estimator_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ void callback(unsigned char key, bool &re_estimate, bool &randomize) {
}

int main(int argc, char **argv) {
if (argc < 2) {
std::cout << "Please provide path to PLY file" << std::endl;
return 0;
}

cilantro::PointCloud3f dst;
readPointCloudFromPLYFile(argv[1], dst);

cilantro::PointCloud3f dst(argv[1]);
cilantro::PointCloud3f src(dst);

cilantro::Visualizer viz("RigidTransformationEstimator example", "disp");
Expand Down
10 changes: 7 additions & 3 deletions examples/space_region_3d_example.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include <cilantro/space_region.hpp>
#include <cilantro/io.hpp>
#include <cilantro/point_cloud.hpp>
#include <cilantro/visualizer.hpp>
#include <cilantro/common_renderables.hpp>

Expand All @@ -12,8 +12,12 @@ void callback(cilantro::Visualizer &viz, int key) {
}

int main(int argc, char* argv[]) {
cilantro::PointCloud3f cloud1;
cilantro::readPointCloudFromPLYFile(argv[1], cloud1);
if (argc < 2) {
std::cout << "Please provide path to PLY file" << std::endl;
return 0;
}

cilantro::PointCloud3f cloud1(argv[1]);

// Shift to the right
cilantro::PointCloud3f cloud2(cloud1);
Expand Down
21 changes: 6 additions & 15 deletions examples/visualizer_example.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
#include <cilantro/visualizer.hpp>
#include <cilantro/common_renderables.hpp>
#include <cilantro/io.hpp>
#include <cilantro/point_cloud.hpp>

void callback(cilantro::Visualizer &viz, const std::string &name) {
std::cout << "Toggling visibility for " << name << std::endl;
viz.toggleVisibility(name);
}

int main(int argc, char ** argv) {
cilantro::PointCloud3f cloud;
readPointCloudFromPLYFile(argv[1], cloud);
if (argc < 2) {
std::cout << "Please provide path to PLY file" << std::endl;
return 0;
}

// cilantro::VoxelGrid vg(cloud, 0.01);
// cloud = vg.getDownsampledCloud();
cilantro::PointCloud3f cloud(argv[1]);

// pangolin::CreateWindowAndBind("VIS_WIN",640,480);
// pangolin::Display("multi").SetBounds(0.0, 1.0, 0.0, 1.0).SetLayout(pangolin::LayoutEqual)
Expand Down Expand Up @@ -47,17 +48,7 @@ int main(int argc, char ** argv) {
viz2.registerKeyboardCallback('c', std::bind(callback, std::ref(viz2), "correspondences"));

std::cout << "Press 'n' to toggle rendering of normals" << std::endl;
// clock_t t0 = clock();
// Eigen::Vector3f cam_pos(0,0,0), look_at(0,0,1), up_dir(0,-1,0);
while (!viz1.wasStopped() && !viz2.wasStopped()) {
// double t = 1000.0*double(clock() - t0)/CLOCKS_PER_SEC;
//
// cam_pos(0) = 0.0 + 2.0*std::cos(t/20.0);
// cam_pos(2) = 1.0 + 2.0*std::sin(t/20.0);
// cam_pos(1) = 0.3*std::sin(t/10.0);
//
// viz1.setCameraPose(cam_pos, look_at, up_dir);

viz1.spinOnce();
viz2.spinOnce();
}
Expand Down
13 changes: 10 additions & 3 deletions include/cilantro/io.hpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
#pragma once

#include <cilantro/point_cloud.hpp>
#include <cilantro/data_containers.hpp>
#include <fstream>

namespace cilantro {
void readPointCloudFromPLYFile(const std::string &file_name, PointCloud<float,3> &cloud);
void readPointCloudFromPLYFile(const std::string &file_name,
VectorSet<float,3> &points,
VectorSet<float,3> &normals,
VectorSet<float,3> &colors);

void writePointCloudToPLYFile(const std::string &file_name, const PointCloud<float,3> &cloud, bool binary = true);
void writePointCloudToPLYFile(const std::string &file_name,
const ConstVectorSetMatrixMap<float,3> &points,
const ConstVectorSetMatrixMap<float,3> &normals,
const ConstVectorSetMatrixMap<float,3> &colors,
bool binary = true);

template<class Matrix>
void readEigenMatrixFromFile(const std::string &file_name, Matrix &matrix, bool binary = true) {
Expand Down
18 changes: 18 additions & 0 deletions include/cilantro/point_cloud.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <cilantro/image_point_cloud_conversions.hpp>
#include <cilantro/grid_downsampler.hpp>
#include <cilantro/normal_estimation.hpp>
#include <cilantro/io.hpp>

namespace cilantro {
template <typename ScalarT, ptrdiff_t EigenDim>
Expand Down Expand Up @@ -75,6 +76,11 @@ namespace cilantro {
}
}

template <ptrdiff_t Dim = EigenDim, class = typename std::enable_if<Dim == 3>::type>
PointCloud(const std::string &file_name) {
readPointCloudFromPLYFile(file_name, points, normals, colors);
}

inline size_t size() const { return points.cols(); }

inline bool hasNormals() const { return points.cols() > 0 && normals.cols() == points.cols(); }
Expand Down Expand Up @@ -362,6 +368,18 @@ namespace cilantro {
RGBDImagesToPointsColors<DepthT,ScalarT,DepthConverterT>(rgb_data, depth_data, image_w, image_h, intrinsics, res.points, res.colors, keep_invalid, depth_converter);
return res;
}

template <ptrdiff_t Dim = EigenDim, class = typename std::enable_if<Dim == 3>::type>
inline PointCloud& fromPLYFile(const std::string &file_name) {
readPointCloudFromPLYFile(file_name, points, normals, colors);
return *this;
}

template <ptrdiff_t Dim = EigenDim, class = typename std::enable_if<Dim == 3>::type>
inline PointCloud& toPLYFile(const std::string &file_name, bool binary = true) {
writePointCloudToPLYFile(file_name, points, normals, colors, binary);
return *this;
}
};

typedef PointCloud<float,2> PointCloud2f;
Expand Down

0 comments on commit 2f83f33

Please sign in to comment.