1
\$\begingroup\$

I am trying to pass a point cloud to a function. Since the point cloud data is huge, I don't want the compiler to make a copy of it while passing. Hence I passed the reference of it as shown below-

void box_filter(pcl::PointCloud<pcl::PointXYZRGB>& in_cloud, pcl::PointCloud<pcl::PointXYZRGB>& out_cloud)
{
  pcl::CropBox<pcl::PointXYZRGB> filter;
  filter.setMin(Eigen::Vector4f(x_min, y_min, z_min, 1.0));
  filter.setMax(Eigen::Vector4f(x_max, y_max, z_max, 1.0));
  filter.setInputCloud(in_cloud);
  filter.filter(out_cloud);
}

I defined the point clouds as following-

pcl::PointCloud<pcl::PointXYZRGB> raw_cloud, filterd_cloud;

Later, I am visualizing the filtered cloud using PCLVisualizer. Please see the code snippet-

pcl::PointCloud<pcl::PointXYZRGB> raw_cloud, filterd_cloud;
pcl::io::loadPCDFile(pcd_filename, raw_cloud);
box_filter(raw_cloud, filterd_cloud);
pcl::visualization::PCLVisualizer viewer("Cloud Viewer");
viewer.addPointCloud(filterd_cloud, "filterd_cloud");
viewer.spin();

Unfortunately, the code throws following compilation errors-

In function ‘void box_filter(pcl::PointCloud<pcl::PointXYZRGB>&, pcl::PointCloud<pcl::PointXYZRGB>&)’:
error: no matching function for call to ‘pcl::CropBox<pcl::PointXYZRGB>::setInputCloud(pcl::PointCloud<pcl::PointXYZRGB>&)’
   filter.setInputCloud(in_cloud);
                                ^
candidate is: void pcl::PCLBase<PointT>::setInputCloud(const PointCloudConstPtr&) [with PointT = pcl::PointXYZRGB; pcl::PCLBase<PointT>::PointCloudConstPtr = boost::shared_ptr<const pcl::PointCloud<pcl::PointXYZRGB> >]
       setInputCloud (const PointCloudConstPtr &cloud);
       ^
error: no matching function for call to ‘pcl::visualization::PCLVisualizer::addPointCloud(pcl::PointCloud<pcl::PointXYZRGB>&, const char [14])’
   viewer.addPointCloud(filterd_cloud, "filterd_cloud");
                                                      ^
candidates are: template<class PointT> bool pcl::visualization::PCLVisualizer::addPointCloud(const typename pcl::PointCloud<PointT>::ConstPtr&, const string&, int)
         addPointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
         ^

It is clear that there is a mismatch between datatype as it is expecting for pcl::PointCloud<PointT>::ConstPtr instead of pcl::PointCloud<PointT>.

I modified the code as shown below-

void box_filter(pcl::PointCloud<pcl::PointXYZRGB>::Ptr in_cloud, pcl::PointCloud<pcl::PointXYZRGB>::Ptr out_cloud)
{
  pcl::CropBox<pcl::PointXYZRGB> filter;
  filter.setMin(Eigen::Vector4f(x_min, y_min, z_min, 1.0));
  filter.setMax(Eigen::Vector4f(x_max, y_max, z_max, 1.0));
  filter.setInputCloud(in_cloud);
  filter.filter(*out_cloud);
}

and this too-

pcl::PointCloud<pcl::PointXYZRGB>::Ptr raw_cloud (new pcl::PointCloud<pcl::PointXYZRGB>);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr filterd_cloud (new pcl::PointCloud<pcl::PointXYZRGB>);
pcl::io::loadPCDFile(pcd_filename, *raw_cloud);
box_filter(raw_cloud, filterd_cloud);
pcl::visualization::PCLVisualizer viewer("Cloud Viewer");
viewer.addPointCloud(filterd_cloud, "filterd_cloud");
viewer.spin();

It works but Is it fine? I am looking for best practices while dealing with pcl::PointCloud<PointT> as it is making use of Boost Pointers.

\$\endgroup\$
  • 1
    \$\begingroup\$ That isn't a problem of best practices. You have to respect the library function signature, which asks for a pointer. Pointers and references have their pros and cons, but the choice was made for you by the library's author. Neither copies the data, luckily for you :-) \$\endgroup\$ – papagaga Feb 9 '18 at 8:50
  • \$\begingroup\$ @papagaga: respect library function signature ... that's what I want to know. I used Ptr shown above in the code but it that fine? Thanks! \$\endgroup\$ – Ravi Joshi Feb 9 '18 at 9:05
  • 1
    \$\begingroup\$ Yes, that's as fine as can be. Boost::shared_ptr isn't an optimal choice anymore since it has been superseded by std::shared_ptr but you're stuck with it. You're also correct to create the shared_ptr before calling the function on them, since that could lead to memory leaks. See: boost.org/doc/libs/1_62_0/libs/smart_ptr/shared_ptr.htm, even though using boost::make_shared would still be better, for the same reasons as std::make_shared \$\endgroup\$ – papagaga Feb 9 '18 at 10:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.