首先感谢学长的帮助,关于pcl点选网上有源码,但是如何移植到qt里面呢,通过将回调函数设定为静态函数便可以实现这一功能,然后需要注意的是在初始化函数中,需要对点选功能进行操作
viewer->registerPointPickingCallback(point_callback, this);
这里面利用this指针将类成员传给函数,这样就可以使用类里面的成员了。
需要注意的是,初始化函数这么写,
void pcl_test::initialvtk()
{
pointptr.reset(new pcl::PointCloud<pcl::PointXYZ>);
viewer.reset(new pcl::visualization::PCLVisualizer("viewer", false));
viewer->addPointCloud(pointptr, "cloud");
viewer->registerPointPickingCallback(point_callback, this);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr clicked_points_3d_(new pcl::PointCloud<pcl::PointXYZRGB>);
this->clicked_points_3d = clicked_points_3d_;
ui.qvtkWidget->SetRenderWindow(viewer->getRenderWindow());
viewer->setupInteractor(ui.qvtkWidget->GetInteractor(), ui.qvtkWidget->GetRenderWindow());
ui.qvtkWidget->update();
}
这里面将类成员函数clicked_points_3d进行初始化,为了调用回调函数时,避免内存泄露。但是直接初始化会崩溃,需要引入另外的参数来进行初始化,至于为什么还不知道。
然后回调函数是这样的
void pcl_test::point_callback(const pcl::visualization::PointPickingEvent& event, void* args)
{
//struct callback_args* data = (struct callback_args *)args;
pcl_test *p = (pcl_test *)args;
pcl::PointXYZRGB current_point;
event.getPoint(current_point.x, current_point.y, current_point.z);
p->clicked_points_3d->points.push_back(current_point);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZRGB> red(p->clicked_points_3d, 255, 0, 0);
p->viewer->removePointCloud("clicked_points");
p->viewer->addPointCloud(p->clicked_points_3d, red, "clicked_points");
p->viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 10, "clicked_points");
}
这个就是和pcl给的源码差不多了,这里主要是将传入的参数args用当前类实例化然后传递。以上是实现这个功能的.cpp
下面给出.h文件
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_pcl_test.h"
//vtk控件
#include <vtkRenderWindow.h>
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
//pcl依赖项
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
//体素滤波
#include <pcl/filters/voxel_grid.h>
#include <pcl/visualization/cloud_viewer.h>
//高斯滤波
#include <pcl/filters/statistical_outlier_removal.h>
//半径滤波
#include<pcl/filters/radius_outlier_removal.h>
//直通滤波
#include <pcl/filters/passthrough.h>
//typedef pcl::PointCloud<pcl::PointXYZ> pointcloud;
//typedef pcl::PointCloud<pcl::PointXYZ> pointcloudrgb;
class pcl_test : public QMainWindow
{
Q_OBJECT
public:
pcl_test(QWidget *parent = Q_NULLPTR);
~pcl_test();
private:
Ui::pcl_testClass ui;
//定义点云指针
pcl::PointCloud<pcl::PointXYZ>::Ptr pointptr;
//定义显示器
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;
//初始化vtk
void initialvtk();
//撤销
void initialize();
//创建打开槽
//private slots:
//打开文件
void openfile();
//体素滤波
void voxelgridfilter();
//初始化全局点云
//新建一个全局点云以及当前输入点云的储存结果用来存放每次动作后的结果,以便于撤销
void globalpoint();
pcl::PointCloud<pcl::PointXYZ>::Ptr globalptr;
pcl::PointCloud<pcl::PointXYZ>::Ptr local_1ptr;
pcl::PointCloud<pcl::PointXYZ>::Ptr local_2ptr;
//局部撤销
void localinitialize();
//高斯滤波
void gaussfilter();
//半径滤波
void radiusfilter();
//直通滤波
void passthfilter();
//创建回调函数,用来相应点的读取
static void point_callback(const pcl::visualization::PointPickingEvent& event,void* args);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr clicked_points_3d;
//void point_read();
};