PCL点云之旅04-点云读取

253 阅读3分钟

实现效果

image.png

步骤拆分

  • 环境准备,我们要准备VS2019和PCL1.11.1还有QT8.10.1
  • 新建一个QT项目
  • 导入依赖,我们QT项目要导入PCL和VTK的依赖
  • 绘制UI
  • 读取点云文件
  • 读取不同后缀名(TXT。PLY。PCD)的点云

项目结构

image.png

环境准备

环境准备相对比较复杂,这里不打算专门展开来讲,所以我会提供一个链接,上面详细的介绍了PCL+QT+vtk的环境配置。【如果你还是配不好你可以评论区留言交流下。我们后续专门开一章来讲环境】

blog.csdn.net/me117111577…

#--------------------------------------------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编写

image.png

在项目中引入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;
            }
        }

}