本节是继《点云库PCL学习——QT5.7.0+VS2013+PCL1.8.0环境》章节的应用,将一步步搭建环境实现直通滤波的功能。 最终实现的简单界面如下:
1.在QT的ui界面拉入相应的控件
为了全面实现直通滤波,我拉入了以下控件:
1)现在以"RadioButton"控件为例,如果我要改变对象名称。可以在相应控件,右击,写入相应的标签即可。
2)"pushbutton"控件与其它控件有所区别,因为他要建立起信号与槽之间的通信。因此需要做以下工作: (1)右击主界面,改变信号/槽
如上图,我有一个“clicked()”信号,触发一个"onPassThrough"的槽函数,所有的实现就在这个函数中实现。 (2)编辑信号/槽。 点击“编辑信号/槽”,右击“OK”往下拉动,会出现“配置连接”窗口。在这里选择clicked(),onPassThrough()。
配置完成后,点击OK,会出现如下: 至此,界面设置完毕。 3)保存设置并生成"ui_xxx.h"文件,最终将生成的ui_xxx.h代替以下位置的ui_***.h文件。
那么该文件怎么生成呢?“窗体”->“查看代码”->“保存”,文件名"ui_xxx.h", 保存替换目录中存在的"ui_xxx.h"。
将VS工程中的.ui_***.h文件删除,然后右击“Generated Files”->"添加”->“现有项”,选择保存后的“ui_xxx.h”,重新编译生成即可。
2.在VS中写入相应代码
2.1 ***.h文件
#ifndef
PCLVISUALIZER_H
#define
PCLVISUALIZER_H
#include
"vtkRenderWindow.h"
#include
<QtWidgets
/QMainWindow
>
#include
<pcl
/io
/pcd_io
.h
>
#include
<pcl
/point_types
.h
>
#include
<pcl
/filters
/passthrough
.h
>
#include
<pcl
/visualization
/pcl_visualizer
.h
>
#include
<pcl
/visualization
/cloud_viewer
.h
>
#include
"ui_pclvisualizer.h"
class PCLVisualizer : public QMainWindow
{
Q_OBJECT
public:
PCLVisualizer(QWidget
*parent
= 0, Qt
::WindowFlags flags
= 0);
~PCLVisualizer();
private:
Ui
::PCLVisualizerClass ui
;
pcl
::PointCloud
<pcl
::PointXYZ
>::Ptr cloud
;
boost
::shared_ptr
<pcl
::visualization
::PCLVisualizer
> viewer
;
void initialVtkWidget();
private slots
:
void onOpen();
void onPassThrough();
};
#endif
2.2 ***.cpp文件
#include
<QFileDialog
>
#include
<iostream
>
#include
"pclvisualizer.h"
PCLVisualizer
::PCLVisualizer(QWidget
*parent
, Qt
::WindowFlags flags
)
: QMainWindow(parent
, flags
)
{
ui
.setupUi(this);
initialVtkWidget();
connect(ui
.actionOpen
, SIGNAL(triggered()), this, SLOT(onOpen()));
connect(ui
.pushButton
, SIGNAL(clicked()), this, SLOT(onPassThrough()));
}
PCLVisualizer
::~PCLVisualizer()
{
}
void PCLVisualizer
::initialVtkWidget()
{
cloud
.reset(new pcl::PointCloud
<pcl
::PointXYZ
>);
viewer
.reset(new pcl::visualization
::PCLVisualizer("viewer", false));
viewer
->addPointCloud(cloud
, "cloud1");
ui
.qvtkWidget
->SetRenderWindow(viewer
->getRenderWindow());
viewer
->setupInteractor(ui
.qvtkWidget
->GetInteractor(), ui
.qvtkWidget
->GetRenderWindow());
ui
.qvtkWidget
->update();
}
void PCLVisualizer
::onOpen()
{
QString fileName
= QFileDialog
::getOpenFileName(this,
tr("Open PointCloud"), ".",
tr("Open PCD files(*.pcd)"));
if (!fileName
.isEmpty())
{
std
::string file_name
= fileName
.toStdString();
pcl
::PCLPointCloud2 cloud_1
;
Eigen
::Vector4f origin
;
Eigen
::Quaternionf orientation
;
int pcd_version
;
int data_type
;
unsigned int data_idx
;
int offset
= 0;
pcl
::PCDReader rd
;
rd
.readHeader(file_name
, cloud_1
, origin
, orientation
, pcd_version
, data_type
, data_idx
);
if (data_type
== 0)
{
pcl
::io
::loadPCDFile(fileName
.toStdString(), *cloud
);
}
else if (data_type
== 2)
{
pcl
::PCDReader reader
;
reader
.read
<pcl
::PointXYZ
>(fileName
.toStdString(), *cloud
);
}
viewer
->updatePointCloud(cloud
, "cloud1");
viewer
->resetCamera();
ui
.qvtkWidget
->update();
}
}
void PCLVisualizer
::onPassThrough()
{
bool FilterLimitsNegative
;
std
::string FilterFiledName
;
pcl
::PointCloud
<pcl
::PointXYZ
>::Ptr
cloud_filterd_1(new pcl::PointCloud
<pcl
::PointXYZ
>);
pcl
::PassThrough
<pcl
::PointXYZ
> pass
;
pass
.setInputCloud(cloud
);
if (ui
.radioButton_FilterFieldName_X
->isChecked())
pass
.setFilterFieldName("X");
if (ui
.radioButton_FilterFieldName_Y
->isChecked())
pass
.setFilterFieldName("Y");
if (ui
.radioButton_FilterFieldName_Z
->isChecked())
pass
.setFilterFieldName("Z");
pass
.setFilterLimits(ui
.lineEdit_FilterLimits_from
->text().toFloat(), ui
.lineEdit_FilterLimits_to
->text().toFloat());
if (ui
.radioButton_FilterLimitsNegative
->isChecked())
pass
.setFilterLimitsNegative(true);
else
pass
.setFilterLimitsNegative(false);
}