实现效果
步骤拆分
- 环境准备,我们要准备VS2019和PCL1.11.1还有QT8.10.1
- 新建一个QT项目
- 导入依赖,我们QT项目要导入PCL和VTK的依赖
- 绘制UI
- 读取点云文件
- 读取不同后缀名(TXT。PLY。PCD)的点云
项目结构
环境准备
环境准备相对比较复杂,这里不打算专门展开来讲,所以我会提供一个链接,上面详细的介绍了PCL+QT+vtk的环境配置。【如果你还是配不好你可以评论区留言交流下。我们后续专门开一章来讲环境】
#--------------------------------------------PCL dependence-------------------------------------------
INCLUDEPATH += D:/PCL/PCL1.11.1/include/pcl-1.11\
INCLUDEPATH += D:/PCL/PCL1.11.1/include/pcl-1.11/pcl\
INCLUDEPATH += D:/PCL/PCL1.11.1/include/pcl-1.11/gr\
INCLUDEPATH += D:/PCL/PCL1.11.1/3rdParty/Boost/include/boost-1_74\
INCLUDEPATH += D:/PCL/PCL1.11.1/3rdParty/Eigen/eigen3\
INCLUDEPATH += D:/PCL/PCL1.11.1/3rdParty/FLANN/include\
INCLUDEPATH += D:/PCL/PCL1.11.1/3rdParty/FLANN/include/flann\
INCLUDEPATH += D:/PCL/PCL1.11.1/3rdParty/OpenNI2/Include\
INCLUDEPATH += D:/PCL/PCL1.11.1/3rdParty/Qhull/include\
INCLUDEPATH += D:/PCL/PCL1.11.1/3rdParty/vtk_QT/include/vtk-8.2\
LIBS += -LD:/PCL/PCL1.11.1/lib\
-lpcl_common\
-lpcl_features\
-lpcl_filters\
-lpcl_io\
-lpcl_io_ply\
-lpcl_kdtree\
-lpcl_keypoints\
-lpcl_ml\
-lpcl_octree\
-lpcl_outofcore\
-lpcl_people\
-lpcl_recognition\
-lpcl_registration\
-lpcl_sample_consensus\
-lpcl_search\
-lpcl_segmentation\
-lpcl_stereo\
-lpcl_surface\
-lpcl_tracking\
-lpcl_visualization\
LIBS += -LD:/PCL/PCL1.11.1/3rdParty/Boost/lib\
-llibboost_atomic-vc142-mt-x64-1_74\
-llibboost_bzip2-vc142-mt-x64-1_74\
-llibboost_chrono-vc142-mt-x64-1_74\
-llibboost_container-vc142-mt-x64-1_74\
-llibboost_context-vc142-mt-x64-1_74\
-llibboost_contract-vc142-mt-x64-1_74\
-llibboost_coroutine-vc142-mt-x64-1_74\
-llibboost_date_time-vc142-mt-x64-1_74\
-llibboost_exception-vc142-mt-x64-1_74\
-llibboost_fiber-vc142-mt-x64-1_74\
-llibboost_filesystem-vc142-mt-x64-1_74\
-llibboost_graph-vc142-mt-x64-1_74\
-llibboost_graph_parallel-vc142-mt-x64-1_74\
-llibboost_iostreams-vc142-mt-x64-1_74\
-llibboost_locale-vc142-mt-x64-1_74\
-llibboost_log-vc142-mt-x64-1_74\
-llibboost_log_setup-vc142-mt-x64-1_74\
-llibboost_math_c99-vc142-mt-x64-1_74\
-llibboost_math_c99f-vc142-mt-x64-1_74\
-llibboost_math_c99l-vc142-mt-x64-1_74\
-llibboost_math_tr1-vc142-mt-x64-1_74\
-llibboost_math_tr1f-vc142-mt-x64-1_74\
-llibboost_math_tr1l-vc142-mt-x64-1_74\
-llibboost_mpi-vc142-mt-x64-1_74\
-llibboost_nowide-vc142-mt-x64-1_74\
-llibboost_numpy38-vc142-mt-x64-1_74\
-llibboost_prg_exec_monitor-vc142-mt-x64-1_74\
-llibboost_program_options-vc142-mt-x64-1_74\
-llibboost_python38-vc142-mt-x64-1_74\
-llibboost_random-vc142-mt-x64-1_74\
-llibboost_regex-vc142-mt-x64-1_74\
-llibboost_serialization-vc142-mt-x64-1_74\
-llibboost_stacktrace_noop-vc142-mt-x64-1_74\
-llibboost_stacktrace_windbg-vc142-mt-x64-1_74\
-llibboost_stacktrace_windbg_cached-vc142-mt-x64-1_74\
-llibboost_system-vc142-mt-x64-1_74\
-llibboost_test_exec_monitor-vc142-mt-x64-1_74\
-llibboost_thread-vc142-mt-x64-1_74\
-llibboost_timer-vc142-mt-x64-1_74\
-llibboost_type_erasure-vc142-mt-x64-1_74\
-llibboost_unit_test_framework-vc142-mt-x64-1_74\
-llibboost_wave-vc142-mt-x64-1_74\
-llibboost_wserialization-vc142-mt-x64-1_74\
-llibboost_zlib-vc142-mt-x64-1_74
LIBS += -LD:/PCL/PCL1.11.1/3rdParty/FLANN/lib\
-lflann\
-lflann_cpp\
-lflann_cpp_s\
-lflann_s
LIBS += -LD:/PCL/PCL1.11.1/3rdParty/OpenNI2/Lib\
-lOpenNI2
LIBS += -LD:/PCL/PCL1.11.1/3rdParty/Qhull/lib\
-lqhull\
-lqhullcpp\
-lqhullstatic\
-lqhullstatic_r\
-lqhull_p\
-lqhull_r
LIBS += -LD:/PCL/PCL1.11.1/3rdParty/VTK_QT/lib\
-lQVTKWidgetPlugin\
-lvtkChartsCore-8.2\
-lvtkCommonColor-8.2\
-lvtkCommonComputationalGeometry-8.2\
-lvtkCommonCore-8.2\
-lvtkCommonDataModel-8.2\
-lvtkCommonExecutionModel-8.2\
-lvtkCommonMath-8.2\
-lvtkCommonMisc-8.2\
-lvtkCommonSystem-8.2\
-lvtkCommonTransforms-8.2\
-lvtkDICOMParser-8.2\
-lvtkDomainsChemistry-8.2\
-lvtkDomainsChemistryOpenGL2-8.2\
-lvtkdoubleconversion-8.2\
-lvtkexodusII-8.2\
-lvtkexpat-8.2\
-lvtkFiltersAMR-8.2\
-lvtkFiltersCore-8.2\
-lvtkFiltersExtraction-8.2\
-lvtkFiltersFlowPaths-8.2\
-lvtkFiltersGeneral-8.2\
-lvtkFiltersGeneric-8.2\
-lvtkFiltersGeometry-8.2\
-lvtkFiltersHybrid-8.2\
-lvtkFiltersHyperTree-8.2\
-lvtkFiltersImaging-8.2\
-lvtkFiltersModeling-8.2\
-lvtkFiltersParallel-8.2\
-lvtkFiltersParallelImaging-8.2\
-lvtkFiltersPoints-8.2\
-lvtkFiltersProgrammable-8.2\
-lvtkFiltersSelection-8.2\
-lvtkFiltersSMP-8.2\
-lvtkFiltersSources-8.2\
-lvtkFiltersStatistics-8.2\
-lvtkFiltersTexture-8.2\
-lvtkFiltersTopology-8.2\
-lvtkFiltersVerdict-8.2\
-lvtkfreetype-8.2\
-lvtkGeovisCore-8.2\
-lvtkgl2ps-8.2\
-lvtkglew-8.2\
-lvtkGUISupportQt-8.2\
-lvtkGUISupportQtOpenGL-8.2\
-lvtkGUISupportQtSQL-8.2\
-lvtkhdf5-8.2\
-lvtkhdf5_hl-8.2\
-lvtkImagingColor-8.2\
-lvtkImagingCore-8.2\
-lvtkImagingFourier-8.2\
-lvtkImagingGeneral-8.2\
-lvtkImagingHybrid-8.2\
-lvtkImagingMath-8.2\
-lvtkImagingMorphological-8.2\
-lvtkImagingSources-8.2\
-lvtkImagingStatistics-8.2\
-lvtkImagingStencil-8.2\
-lvtkInfovisCore-8.2\
-lvtkInfovisLayout-8.2\
-lvtkInteractionImage-8.2\
-lvtkInteractionStyle-8.2\
-lvtkInteractionWidgets-8.2\
-lvtkIOAMR-8.2\
-lvtkIOAsynchronous-8.2\
-lvtkIOCityGML-8.2\
-lvtkIOCore-8.2\
-lvtkIOEnSight-8.2\
-lvtkIOExodus-8.2\
-lvtkIOExport-8.2\
-lvtkIOExportOpenGL2-8.2\
-lvtkIOExportPDF-8.2\
-lvtkIOGeometry-8.2\
-lvtkIOImage-8.2\
-lvtkIOImport-8.2\
-lvtkIOInfovis-8.2\
-lvtkIOLegacy-8.2\
-lvtkIOLSDyna-8.2\
-lvtkIOMINC-8.2\
-lvtkIOMovie-8.2\
-lvtkIONetCDF-8.2\
-lvtkIOParallel-8.2\
-lvtkIOParallelXML-8.2\
-lvtkIOPLY-8.2\
-lvtkIOSegY-8.2\
-lvtkIOSQL-8.2\
-lvtkIOTecplotTable-8.2\
-lvtkIOVeraOut-8.2\
-lvtkIOVideo-8.2\
-lvtkIOXML-8.2\
-lvtkIOXMLParser-8.2\
-lvtkjpeg-8.2\
-lvtkjsoncpp-8.2\
-lvtklibharu-8.2\
-lvtklibxml2-8.2\
-lvtklz4-8.2\
-lvtklzma-8.2\
-lvtkmetaio-8.2\
-lvtkNetCDF-8.2\
-lvtkogg-8.2\
-lvtkParallelCore-8.2\
-lvtkpng-8.2\
-lvtkproj-8.2\
-lvtkpugixml-8.2\
-lvtkRenderingAnnotation-8.2\
-lvtkRenderingContext2D-8.2\
-lvtkRenderingContextOpenGL2-8.2\
-lvtkRenderingCore-8.2\
-lvtkRenderingFreeType-8.2\
-lvtkRenderingGL2PSOpenGL2-8.2\
-lvtkRenderingImage-8.2\
-lvtkRenderingLabel-8.2\
-lvtkRenderingLOD-8.2\
-lvtkRenderingOpenGL2-8.2\
-lvtkRenderingQt-8.2\
-lvtkRenderingVolume-8.2\
-lvtkRenderingVolumeOpenGL2-8.2\
-lvtksqlite-8.2\
-lvtksys-8.2\
-lvtktheora-8.2\
-lvtktiff-8.2\
-lvtkverdict-8.2\
-lvtkViewsContext2D-8.2\
-lvtkViewsCore-8.2\
-lvtkViewsInfovis-8.2\
-lvtkViewsQt-8.2\
-lvtkzlib-8.2
UI编写
在项目中引入PCL+VTK的头文件
PCL
// pcl_function.h
#ifndef PCL_FUNCTION_H
#define PCL_FUNCTION_H
#endif // PCL_FUNCTION_H
//-----------------------------pcl------------------------------------
/**********************************pcl格式*****************************/
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
/**********************************pcl显示***************************/
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/visualization/histogram_visualizer.h>
#include <pcl/visualization/pcl_plotter.h>
/**********************************pcl滤波***************************/
//------------------------------------------filter--------------------------------
QT
#pragma execution_character_set("utf-8")
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <vector>
#include <pcl_function.h>
//----filter
//-----------------------------vtk---------------------------------
#include "QVTKWidget.h"
#include <vtkRenderWindow.h>
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)
VTK_MODULE_INIT(vtkRenderingFreeType)
//-----------------------------vtk---------------------------------
/**********************************qt*****************************/
#include <QMainWindow>
#include <QDebug>
#include <QColorDialog>
#include <QMessageBox>
#include <QFileDialog>
#include <QTime>
#include <QDir>
#include <QFile>
#include <QtMath>
#include <QDirIterator>
#include <QFuture>
#include <QFutureWatcher>
#include <QtConcurrent/QtConcurrentRun>
//-----------------------------qt------------------------------------
//----------------------------各个模块--------------------------------------
#include <pcl_view_select_color.h>
#include <view_rendering.h>
#include <view_slider.h>
点云读取
void MainWindow::Open_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("open file"),
"", tr("pcb files(*.pcd *.ply *.txt) ;;All files (*.*)"));
if(fileName.isEmpty())
{
return;
}
if(fileName.endsWith("ply"))
{
qDebug()<<fileName;
if (pcl::io::loadPLYFile<pcl::PointXYZ>(fileName.toStdString(), cloud) == -1) //* load the file
{
qDebug()<<"Couldn't read file \n";
return ;
}
}
else if (fileName.endsWith("pcd"))
{
qDebug()<<fileName;
if (pcl::io::loadPCDFile<pcl::PointXYZ>(fileName.toStdString(), cloud) == -1) //* load the file
{
qDebug()<<"Couldn't read pcd file \n";
return ;
}
}
else if (fileName.endsWith("txt"))
{
qDebug()<<fileName;
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudTemp(new pcl::PointCloud<pcl::PointXYZ>);
CreateCloudFromTxt(fileName.toStdString(),cloudTemp);
cloud = *cloudTemp;
}
else {
QMessageBox::warning(this, "Warning","点云读取格式错误!");
}
int size = static_cast<int>(cloud.size());
QString PointSize = QString("%1").arg(size);
ui->textBrowser->clear();
ui->textBrowser_2->clear();
ui->textBrowser->insertPlainText("点云数量: "+PointSize);
ui->textBrowser->setFont(QFont( "Arial" , 9 ,QFont::Normal ));
//移除窗口点云
viewer->removeAllPointClouds();
viewer->removeAllShapes();
//点云设置
viewer->addPointCloud(cloud.makeShared() ,cloud_name[0]);
//设置点云大小
viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, point_size, cloud_name[0]);
viewer->resetCamera();
ui->qvtkWidget->update();
}
点云保存
void MainWindow::Save_clicked()
{
QString filename = QFileDialog::getSaveFileName(this, tr ("Open point cloud"), "", tr ("Point cloud data (*.pcd *.ply)"));
if(cloud.empty())
{
return;
}
else
{
if (filename.isEmpty ())
return;
int return_status;
if (filename.endsWith (".pcd", Qt::CaseInsensitive))
return_status = pcl::io::savePCDFileBinary (filename.toStdString (), *cloud.makeShared());
else if (filename.endsWith (".ply", Qt::CaseInsensitive))
return_status = pcl::io::savePLYFileBinary (filename.toStdString (), *cloud.makeShared());
else
{
filename.append(".ply");
return_status = pcl::io::savePLYFileBinary (filename.toStdString (), *cloud.makeShared());
}
if (return_status != 0)
{
PCL_ERROR("Error writing point cloud %s\n", filename.toStdString ().c_str ());
return;
}
}
}