ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | Q&A answers.ros.org

How can I construct convex hull from point cloud?

This post is a wiki. Anyone with karma >75 is welcome to improve it.

I want to construct convex hull from point cloud, but it gave error. I am new in PCL. Below my sample code is given. The line where error message is given indicated by error message.

int main(.......)
{
..................
pcl::PointCloud<pcl::PointXYZ> cloud;

// Fill in the cloud data
cloud.width    = 5;
cloud.height   = 1;
cloud.is_dense = false;
cloud.points.resize (cloud.width * cloud.height);

for (size_t i = 0; i < cloud.points.size (); ++i)
{
cloud.points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);
cloud.points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
cloud.points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);

}

std::cerr << "Saved " << cloud.points.size () << " data points to test_pcd.pcd." << std::endl;

for (size_t i = 0; i < cloud.points.size (); ++i)
std::cerr << "    " << cloud.points[i].x << " " << cloud.points[i].y << " " << cloud.points[i].z << std::endl;

pcl::ConvexHull< pcl::PointXYZ >::reconstruct(cloud);  // error message

..................
}
edit retag close merge delete

Sort by » oldest newest most voted

You need to call the pcl::ConvexHull::reconstruct() function as a member function, not a static function. See the example here.

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
... do some stuff to fill cloud with data ...

pcl::ConvexHull<pcl::PointXYZ> cHull;
pcl::PointCloud<pcl::PointXYZ> cHull_points;
cHull.setInputCloud(cloud);
cHull.reconstruct (cHull_points);
more

I wrote pcl::PointCloud<pcl::PointXYZ> cloud instead of pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>). Now it gave error on cHull.setInputCloud(cloud). What is the difference between pcl::PointCloud<pcl::PointXYZ> cloud and your point cloud declaration?

( 2013-03-28 02:56:00 -0500 )edit

cHull.setInputCloud() requires a boost::shared_ptr to the original point cloud. If you don't want to change your declaration to a shared_ptr (as I showed above), you can keep your original declaration and change this line: cHull.setInputCloud(cloud.makeShared()). Beware: this makes a COPY of data!

( 2013-03-28 03:03:32 -0500 )edit

Thnx for ur help. Now it gives linker error like error LNK2019: unresolved external symbol "public: void __thiscall pcl::ConvexHull<struct pcl::PointXYZ>::reconstruct(class pcl::PointCloud<struct pcl::PointXYZ> &)" (?reconstruct@?$ConvexHull@UPointXYZ@pcl@@@pcl@@QAEXAAV?$PointCloud@UPointXYZ@pcl@@@2

( 2013-03-28 03:09:14 -0500 )edit

Moreover, if I only declare pcl::ConvexHull<pcl::PointXYZ> cHull and omitting last three lines, it also gives error.

( 2013-03-28 03:14:37 -0500 )edit

The linker error means that you have not linked in the required PCL libraries. You'll need to update your question with more details: how are you compiling (e.g. relevant lines from CMakeLists.txt), how is PCL installed, etc. Make sure you have "pcl" as a package dependency to auto-link the libs.

( 2013-03-28 03:46:26 -0500 )edit

( 2013-03-28 20:10:15 -0500 )edit

Oh! You're using Windows? At this point, it sounds like you're only using PCL (not ROS). Maybe the folks at http://www.pcl-users.org/ could help you better. If you plan on using ROS, know that running ROS under windows is experimental. See http://www.ros.org/wiki/win_ros/Tutorials.

( 2013-03-29 03:01:35 -0500 )edit

In particular, the setup of CMakeLists.txt and how you go about linking in the required libraries to your executable will be different depending on whether you use "pure PCL" or PCL in ROS". If you want to use ROS, you may have an easier time working in Linux (Ubuntu) rather than Windows.

( 2013-03-29 03:04:02 -0500 )edit

This post is a wiki. Anyone with karma >75 is welcome to improve it.

@Jeremy Zoss, Thnx. Now it works fine. Moreover, I included two more lines for calculating area and volume, but output gave 0 & 0. Regarding input, I explained in my first post.

..............
pcl::ConvexHull<pcl::PointXYZ> cHull;
pcl::PointCloud<pcl::PointXYZ> cHull_points;
cHull.setInputCloud(cloud.makeShared());
cHull.reconstruct (cHull_points);
cout<<cHull.getTotalArea();
cout<<cHull.getTotalVolume();

.............
more

2

According to the PCL docs for ConvexHull, you'll need to call: cHull.setComputeAreaVolume(true) for the Area and Volume measurements to be calculated by the ConvexHull library. That's why you're getting invalid values. Set this flag before the call to cHull.reconstruct().

( 2013-03-31 17:13:25 -0500 )edit

Thnx. It works well.

( 2013-03-31 19:34:09 -0500 )edit

i got this errors: 1- ‘class pcl::ConcaveHull<pcl::pointxyz>’ has no member named ‘setComputeAreaVolume’ hull.setComputeAreaVolume(true); 2- ‘class pcl::ConcaveHull<pcl::pointxyz>’ has no member named ‘getTotalArea’ Area_planes[i]= hull.getTotalArea();

( 2015-11-12 19:14:36 -0500 )edit

@kerollosghobrial : you are trying to use a ConcaveHull, not a ConvexHull. That class does not provide support for calculating the enclosed volume/area. Please post your question in a new thread, if needed.

( 2015-11-13 10:08:16 -0500 )edit