1. 程式人生 > >QT框架下進行pcl點選功能

QT框架下進行pcl點選功能

首先感謝學長的幫助,關於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();
};