PCD点云文件框选代码

本文介绍了如何使用PCL和VTK库结合,实现在3D点云可视化中进行区域选择,并通过AreaPickingEvent获取索引,从而导出选定区域的点云数据。重点讲解了AreaPickingCallback注册、事件处理以及点云筛选的实现步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:

PCL + VTK 

项目地址:https://github.com/dezbracaty/PCD_Area_cut_tool

后期添加其他功能maybe

通过PVL_VISUALIZATION显示点云图像,然后通过按X进入框选模式,然后接受PCL::VISUALIZATION返回的点云索引,然后通过索引将所选择的点云文件导出。

函数介绍:

pcl::visualization::PCLVisualizer::Ptr 
viewer(new pcl::visualization::PCLVisualizer("Carviewer"));
viewer->registerAreaPickingCallback(areapickingcallback);

 registerAreaPickingCallback介绍:

/** \brief Register a callback function for area picking events
  * \param[in] cb a boost function that will be registered as a callback for an area picking event
  * \return a connection object that allows to disconnect the callback function.
  */
boost::signals2::connection
registerAreaPickingCallback (boost::function<void (const pcl::visualization::AreaPickingEvent&)> cb);

函数的参数是一个回调函数,这个函数主要针对的是picking 事件。

接下来是自己写的回调函数:

void areapickingcallback(const pcl::visualization::AreaPickingEvent &event,void *userdata); 

接受event,以及一个空指针。

 再来看一下AreaPickingEvent的函数内容:

namespace pcl
{
  namespace visualization
  {
    /** /brief Class representing 3D area picking events. */
    class PCL_EXPORTS AreaPickingEvent
    {
      public:
        AreaPickingEvent (int nb_points, const std::vector<int>& indices)
          : nb_points_ (nb_points)
          , indices_ (indices)
        {}

        /** \brief For situations where a whole are is selected, return the points indices.
          * \param[out] indices indices of the points under the area selected by user.
          * \return true, if the area selected by the user contains points, false otherwise
          */
        inline bool
        getPointsIndices (std::vector<int>& indices) const
        {
          if (nb_points_ <= 0)
            return (false);
          indices = indices_;
          return (true);
        }

      private:
        int nb_points_;
        std::vector<int> indices_;
    };
  } //namespace visualization
} //namespace pcl

event只提供一个返回点云索引的函数,所以通过event获取索引,然后通过索引从点云提取所需要的点 即可。

通过点云索引提取点云需要使用 pcl::ExtractIndices,他的使用方式是:

pcl::ExtractIndices<pcl::PointXYZ> extract;
    extract.setInputCloud(cloud);            //导入点云数据
    extract.setIndices(ind_plane);           //设置点云索引
    extract.setNegative(false);              //设置为false,选择索引指向的点导出
    extract.filter(*secloud);                //输出所选点云

这里的索引他的类属性是pcl::IndicesPtr,但是event返回的是一个std::vector<int>的容器,所以需要添加一步转换操作:

    pcl::IndicesPtr ind_plane=boost::make_shared<std::vector<int>>(indices);

至此程序的代码逻辑已经结束,下面是完整的代码:

main.cpp

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/common/common.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/extract_indices.h>
#include <vtkAreaPicker.h>
#include <string>
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());
typedef pcl::PointXYZ PointType;
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("Carviewer"));

void areapickingcallback(const pcl::visualization::AreaPickingEvent &event,void *userdata)
{
    pcl::PointCloud<PointType>::Ptr  secloud(new pcl::PointCloud<PointType>());
    std::cout<<"Into here"<<std::endl;
    std::vector<int> indices;
    event.getPointsIndices(indices);
    pcl::IndicesPtr ind_plane=boost::make_shared<std::vector<int>>(indices);
    pcl::ExtractIndices<pcl::PointXYZ> extract;
    extract.setInputCloud(cloud);                       //导入点云数据
    extract.setIndices(ind_plane);                      //设置点云索引
    extract.setNegative(false);                  //设置为false,选择索引指向的点导出
    extract.filter(*secloud);                         //输出所选点云
    std::cout<<"Nums selected\t"<<secloud->points.size()<<std::endl;
    pcl::io::savePCDFile("car.pcd",*secloud);

}
int main() {
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("Carviewer"));
    pcl::io::loadPCDFile("car6.pcd",*cloud);
    viewer->setBackgroundColor(0,0,0);
    viewer->addPointCloud(cloud,"car");
    viewer->registerAreaPickingCallback(areapickingcallback);
    while (!viewer->wasStopped ())
    {
        viewer->spinOnce (100);
        boost::this_thread::sleep (boost::posix_time::microseconds (100000));
    }
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

CMakeList.txt

cmake_minimum_required(VERSION 3.17)
project(pcdtools)
find_package(PCL REQUIRED)
set(CMAKE_CXX_STANDARD 11)

include_directories(${PCL_INClUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

add_executable(pcdtools main.cpp)
target_link_libraries(pcdtools ${PCL_LIBRARIES})

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值