Reputation: 21
I am using open3d-cpp to process some pointclouds. However, the raw input is a float array (say float pts[3000]
, containing 1000 points), and I didn't find an efficient way to transform it into an open3d::geometry::Pointcloud
, as the only parameterized constructor of Pointcloud
is a copy constructor and only takes std::vector<Eigen::Vector3d>
as input.
I made a naive converter, but I think it is not quite efficient, the first step is converting the float array (arr
of size 40000*3
) into a double array, then do the following:
long t01 = CurrTimeMS;
Eigen::Vector3d *vv = reinterpret_cast<Eigen::Vector3d *>(arr);
vector<Eigen::Vector3d> vec(vv, vv+40000);
geometry::PointCloud pcd(vec);
long t02 = CurrTimeMS;
std::cout << "pcd init took " << t02-t01 << " ms.\n";
cout << (void *) vv << " " << (void *) vec.data() << " " << (void *) pcd.points_.data() << endl;
It turned out taking me 3-4ms, and because std::vector(T *start, T *end)
is also a copy constructor, this code does 3 times of memory copy (all three addressed are different), which is not optimal.
Is there any more efficient way to create Pointcloud directly from memory?
Upvotes: 0
Views: 985
Reputation: 21
I end up finding a relatively efficient approach.
std::shared_ptr<open3d::geometry::PointCloud> convert2pcd(float *data, size_t N, size_t dim=3) {
assert(dim > 2);
double *dd = new double[N*3];
for (int i = 0; i < N; ++i) {
for (int j = 0; j < 3; ++j) {
dd[i*3+j] = (double) data[i*dim+j];
}
}
Eigen::Vector3d *vv = reinterpret_cast<Eigen::Vector3d *>(dd);
auto pcd = std::make_shared<open3d::geometry::PointCloud>();
pcd->points_.assign(vv, vv+N);
delete[] dd;
return pcd;
}
which still takes me around 2-3ms.
Upvotes: 0