点云可视化工具2

news2024/9/21 4:34:51

文章目录

  • 1. 序
  • 2. 开发环境
    • 2.1 QT + PCL
  • 3. 程序
    • 3.1 新建项目
    • 3.2 修改.pro文件
      • 3.2.1 添加头文件目录
      • 3.2.2 添加依赖的库文件
    • 3.3 软件界面
      • 3.3.1 ui文件
      • 3.3.2 按钮图标
      • 3.3.3 其他界面设置
    • 3.4 点云处理
      • 3.4.1 点云读取显示
      • 3.4.2 上/下一张显示点云
      • 3.4.3 状态栏显示点云信息
      • 3.4.5 线程相关操作
      • 3.4.6 保存点云
    • 3.5 其他
      • 3.5.1 配置文件
      • 3.5.2 写日志
      • 3.5.3 软件发布
  • 4. 软件

1. 序

哈哈当时弄这个小工具,一方面是常用的点云查看软件不太符合自己的操作习惯,另一方面是可以在按钮上做一些简单点云处理的测试验证比较方便
遥想起一年前开始写博客的初衷,源自一个朋友的一句话“记录技术成长,也方便回顾”,记录也算是一种抗衡遗忘的方式吧,有的时候遇到需要用的的一些方法也会回来翻翻自己的博客(就当作笔记本吧哈哈)
今年心态状态一直都不算好,很是惭愧博客也没怎么更新了。很多时候已经知道需要做什么,但还是止不住的去百度。
那种曾经有过的短暂内心平静如今也难以触及,关于自我、社会、科技、未来,有许多无意义的空想,有时感觉代码可以改变世界(虽然以我的能力不太可能哈哈orz
希望可以做到守护我所珍视的,坚持我所热爱的吧。有时感觉写下情绪表达会令自己有些尴尬所以尽量不表达,但这次随便吧大不了下次编辑删掉:D
回归正题上一篇博客<点云可视化工具>有csdner问到关于点云可视化工具的教程,趁今天星期天找时间更新一下吧=D

2. 开发环境

2.1 QT + PCL

  • 程序界面是使用qt编写的,主要是一些按钮以及外观上的调整
  • 点云的处理主要是借助PCL点云库
  • 关于qt以及pcl的安装以及环境配置可以参考<QT 配置PCL1.8.1>
    • 如果不想自己根据重新编译qt使用的pcl vtk库的话,可以使用和我一样的版本和已经编译好了的库

3. 程序

3.1 新建项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

3.2 修改.pro文件

  • 原本的.pro文件长这样,在下方添加头文件目录与依赖的库文件

在这里插入图片描述

3.2.1 添加头文件目录

  • INCLUDEPATH += 头文件目录路径
  • 可以把pcl、opencv等一些会用到的库加上(路径换成自己的安装路径)

在这里插入图片描述

INCLUDEPATH += D:\PCL\PCL1.8.1\include\pcl-1.8

INCLUDEPATH += D:\PCL\PCL1.8.1\include\pcl-1.8\pcl

INCLUDEPATH += D:\PCL\PCL1.8.1\3rdParty\Boost\include\boost-1_64

INCLUDEPATH += D:\PCL\PCL1.8.1\3rdParty\Boost\include\boost-1_64\boost

INCLUDEPATH += D:\PCL\PCL1.8.1\3rdParty\Eigen\eigen3

INCLUDEPATH += D:\PCL\PCL1.8.1\3rdParty\FLANN\include

INCLUDEPATH += D:\PCL\PCL1.8.1\3rdParty\FLANN\include\flann

INCLUDEPATH += D:\PCL\PCL1.8.1\3rdParty\OpenNI2\Include

INCLUDEPATH += D:\PCL\PCL1.8.1\3rdParty\Qhull\include

INCLUDEPATH += D:\PCL\PCL1.8.1\3rdParty\VTK1\include\vtk-8.0

INCLUDEPATH += D:\OpenCV\opencv\build\include

INCLUDEPATH += D:\pthread\Pre-built.2\include

INCLUDEPATH += D:\log4cpp\include

3.2.2 添加依赖的库文件

  • LIBS += -L lib文件目录路径
  • -l lib文件名

在这里插入图片描述

CONFIG(debug,debug|release){

LIBS += -LD:\PCL\PCL1.8.1\lib\
        -lpcl_common_debug\
        -lpcl_features_debug\
        -lpcl_filters_debug\
        -lpcl_io_debug\
        -lpcl_io_ply_debug\
        -lpcl_kdtree_debug\
        -lpcl_keypoints_debug\
        -lpcl_ml_debug\
        -lpcl_octree_debug\
        -lpcl_outofcore_debug\
        -lpcl_people_debug\
        -lpcl_recognition_debug\
        -lpcl_registration_debug\
        -lpcl_sample_consensus_debug\
        -lpcl_search_debug\
        -lpcl_segmentation_debug\
        -lpcl_stereo_debug\
        -lpcl_surface_debug\
        -lpcl_tracking_debug\
        -lpcl_visualization_debug

LIBS += -LD:\PCL\PCL1.8.1\3rdParty\Boost\lib\
        -llibboost_atomic-vc141-mt-1_64\
        -llibboost_bzip2-vc141-mt-1_64\
        -llibboost_chrono-vc141-mt-1_64\
        -llibboost_container-vc141-mt-1_64\
        -llibboost_context-vc141-mt-1_64\
        -llibboost_coroutine-vc141-mt-1_64\
        -llibboost_date_time-vc141-mt-1_64\
        -llibboost_exception-vc141-mt-1_64\
        -llibboost_fiber-vc141-mt-1_64\
        -llibboost_filesystem-vc141-mt-1_64\
        -llibboost_graph-vc141-mt-1_64\
        -llibboost_graph_parallel-vc141-mt-1_64\
        -llibboost_iostreams-vc141-mt-1_64\
        -llibboost_locale-vc141-mt-1_64\
        -llibboost_log-vc141-mt-1_64\
        -llibboost_log_setup-vc141-mt-1_64\
        -llibboost_math_c99-vc141-mt-1_64\
        -llibboost_math_c99f-vc141-mt-1_64\
        -llibboost_math_c99l-vc141-mt-1_64\
        -llibboost_math_tr1-vc141-mt-1_64\
        -llibboost_math_tr1f-vc141-mt-1_64\
        -llibboost_math_tr1l-vc141-mt-1_64\
        -llibboost_mpi-vc141-mt-1_64\
        -llibboost_numpy-vc141-mt-1_64\
        -llibboost_numpy3-vc141-mt-1_64\
        -llibboost_prg_exec_monitor-vc141-mt-1_64\
        -llibboost_program_options-vc141-mt-1_64\
        -llibboost_python-vc141-mt-1_64\
        -llibboost_python3-vc141-mt-1_64\
        -llibboost_random-vc141-mt-1_64\
        -llibboost_regex-vc141-mt-1_64\
        -llibboost_serialization-vc141-mt-1_64\
        -llibboost_signals-vc141-mt-1_64\
        -llibboost_system-vc141-mt-1_64\
        -llibboost_test_exec_monitor-vc141-mt-1_64\
        -llibboost_thread-vc141-mt-1_64\
        -llibboost_timer-vc141-mt-1_64\
        -llibboost_type_erasure-vc141-mt-1_64\
        -llibboost_unit_test_framework-vc141-mt-1_64\
        -llibboost_wave-vc141-mt-1_64\
        -llibboost_wserialization-vc141-mt-1_64\
        -llibboost_zlib-vc141-mt-1_64

LIBS += -LD:\PCL\PCL1.8.1\3rdParty\FLANN\lib\
        -lflann\
        -lflann_cpp\
        -lflann_cpp_s\
        -lflann_s

LIBS += -LD:\PCL\PCL1.8.1\3rdParty\OpenNI2\Lib\
        -lOpenNI2

LIBS += -LD:\PCL\PCL1.8.1\3rdParty\Qhull\lib\
        -lqhull_d\
        -lqhullcpp_d\
        -lqhullstatic_d\
        -lqhullstatic_r_d\
        -lqhull_p_d\
        -lqhull_r_d

LIBS += -LD:\PCL\PCL1.8.1\3rdParty\VTK1\lib\
        -lvtkalglib-8.0-gd\
        -lvtkChartsCore-8.0-gd\
        -lvtkCommonColor-8.0-gd\
        -lvtkCommonComputationalGeometry-8.0-gd\
        -lvtkCommonCore-8.0-gd\
        -lvtkCommonDataModel-8.0-gd\
        -lvtkCommonExecutionModel-8.0-gd\
        -lvtkCommonMath-8.0-gd\
        -lvtkCommonMisc-8.0-gd\
        -lvtkCommonSystem-8.0-gd\
        -lvtkCommonTransforms-8.0-gd\
        -lvtkDICOMParser-8.0-gd\
        -lvtkDomainsChemistry-8.0-gd\
        -lvtkexoIIc-8.0-gd\
        -lvtkexpat-8.0-gd\
        -lvtkFiltersAMR-8.0-gd\
        -lvtkFiltersCore-8.0-gd\
        -lvtkFiltersExtraction-8.0-gd\
        -lvtkFiltersFlowPaths-8.0-gd\
        -lvtkFiltersGeneral-8.0-gd\
        -lvtkFiltersGeneric-8.0-gd\
        -lvtkFiltersGeometry-8.0-gd\
        -lvtkFiltersHybrid-8.0-gd\
        -lvtkFiltersHyperTree-8.0-gd\
        -lvtkFiltersImaging-8.0-gd\
        -lvtkFiltersModeling-8.0-gd\
        -lvtkFiltersParallel-8.0-gd\
        -lvtkFiltersParallelImaging-8.0-gd\
        -lvtkFiltersPoints-8.0-gd\
        -lvtkFiltersProgrammable-8.0-gd\
        -lvtkFiltersSelection-8.0-gd\
        -lvtkFiltersSMP-8.0-gd\
        -lvtkFiltersSources-8.0-gd\
        -lvtkFiltersStatistics-8.0-gd\
        -lvtkFiltersTexture-8.0-gd\
        -lvtkFiltersTopology-8.0-gd\
        -lvtkFiltersVerdict-8.0-gd\
        -lvtkfreetype-8.0-gd\
        -lvtkGeovisCore-8.0-gd\
        -lvtkgl2ps-8.0-gd\
        -lvtkGUISupportQt-8.0-gd\
#        -lvtkGUISupportQtOpenGL-8.0-gd\
        -lvtkGUISupportQtSQL-8.0-gd\
        -lvtkhdf5-8.0-gd\
        -lvtkhdf5_hl-8.0-gd\
        -lvtkImagingColor-8.0-gd\
        -lvtkImagingCore-8.0-gd\
        -lvtkImagingFourier-8.0-gd\
        -lvtkImagingGeneral-8.0-gd\
        -lvtkImagingHybrid-8.0-gd\
        -lvtkImagingMath-8.0-gd\
        -lvtkImagingMorphological-8.0-gd\
        -lvtkImagingSources-8.0-gd\
        -lvtkImagingStatistics-8.0-gd\
        -lvtkImagingStencil-8.0-gd\
        -lvtkInfovisCore-8.0-gd\
        -lvtkInfovisLayout-8.0-gd\
        -lvtkInteractionImage-8.0-gd\
        -lvtkInteractionStyle-8.0-gd\
        -lvtkInteractionWidgets-8.0-gd\
        -lvtkIOAMR-8.0-gd\
        -lvtkIOCore-8.0-gd\
        -lvtkIOEnSight-8.0-gd\
        -lvtkIOExodus-8.0-gd\
        -lvtkIOExport-8.0-gd\
        -lvtkIOExportOpenGL-8.0-gd\
        -lvtkIOGeometry-8.0-gd\
        -lvtkIOImage-8.0-gd\
        -lvtkIOImport-8.0-gd\
        -lvtkIOInfovis-8.0-gd\
        -lvtkIOLegacy-8.0-gd\
        -lvtkIOLSDyna-8.0-gd\
        -lvtkIOMINC-8.0-gd\
        -lvtkIOMovie-8.0-gd\
        -lvtkIONetCDF-8.0-gd\
        -lvtkIOParallel-8.0-gd\
        -lvtkIOParallelXML-8.0-gd\
        -lvtkIOPLY-8.0-gd\
        -lvtkIOSQL-8.0-gd\
        -lvtkIOTecplotTable-8.0-gd\
        -lvtkIOVideo-8.0-gd\
        -lvtkIOXML-8.0-gd\
        -lvtkIOXMLParser-8.0-gd\
        -lvtkjpeg-8.0-gd\
        -lvtkjsoncpp-8.0-gd\
        -lvtklibharu-8.0-gd\
        -lvtklibxml2-8.0-gd\
        -lvtklz4-8.0-gd\
        -lvtkmetaio-8.0-gd\
        -lvtkNetCDF-8.0-gd\
        -lvtknetcdf_c++-gd\
        -lvtkoggtheora-8.0-gd\
        -lvtkParallelCore-8.0-gd\
        -lvtkpng-8.0-gd\
        -lvtkproj4-8.0-gd\
        -lvtkRenderingAnnotation-8.0-gd\
        -lvtkRenderingContext2D-8.0-gd\
        -lvtkRenderingContextOpenGL-8.0-gd\
        -lvtkRenderingCore-8.0-gd\
        -lvtkRenderingFreeType-8.0-gd\
        -lvtkRenderingGL2PS-8.0-gd\
        -lvtkRenderingImage-8.0-gd\
        -lvtkRenderingLabel-8.0-gd\
        -lvtkRenderingLIC-8.0-gd\
        -lvtkRenderingLOD-8.0-gd\
        -lvtkRenderingOpenGL-8.0-gd\
        -lvtkRenderingQt-8.0-gd\
        -lvtkRenderingVolume-8.0-gd\
        -lvtkRenderingVolumeOpenGL-8.0-gd\
        -lvtksqlite-8.0-gd\
        -lvtksys-8.0-gd\
        -lvtktiff-8.0-gd\
        -lvtkverdict-8.0-gd\
        -lvtkViewsContext2D-8.0-gd\
        -lvtkViewsCore-8.0-gd\
        -lvtkViewsInfovis-8.0-gd\
        -lvtkViewsQt-8.0-gd\
        -lvtkzlib-8.0-gd\

} else {
LIBS += -LD:\PCL\PCL1.8.1\lib\
        -lpcl_common_release\
        -lpcl_features_release\
        -lpcl_filters_release\
        -lpcl_io_ply_release\
        -lpcl_io_release\
        -lpcl_kdtree_release\
        -lpcl_keypoints_release\
        -lpcl_ml_release\
        -lpcl_octree_release\
        -lpcl_outofcore_release\
        -lpcl_people_release\
        -lpcl_recognition_release\
        -lpcl_registration_release\
        -lpcl_sample_consensus_release\
        -lpcl_search_release\
        -lpcl_segmentation_release\
        -lpcl_stereo_release\
        -lpcl_surface_release\
        -lpcl_tracking_release\
        -lpcl_visualization_release

LIBS += -LD:\PCL\PCL1.8.1\3rdParty\Boost\lib\
        -llibboost_atomic-vc141-mt-1_64\
        -llibboost_bzip2-vc141-mt-1_64\
        -llibboost_chrono-vc141-mt-1_64\
        -llibboost_container-vc141-mt-1_64\
        -llibboost_context-vc141-mt-1_64\
        -llibboost_coroutine-vc141-mt-1_64\
        -llibboost_date_time-vc141-mt-1_64\
        -llibboost_exception-vc141-mt-1_64\
        -llibboost_fiber-vc141-mt-1_64\
        -llibboost_filesystem-vc141-mt-1_64\
        -llibboost_graph-vc141-mt-1_64\
        -llibboost_graph_parallel-vc141-mt-1_64\
        -llibboost_iostreams-vc141-mt-1_64\
        -llibboost_locale-vc141-mt-1_64\
        -llibboost_log-vc141-mt-1_64\
        -llibboost_log_setup-vc141-mt-1_64\
        -llibboost_math_c99-vc141-mt-1_64\
        -llibboost_math_c99f-vc141-mt-1_64\
        -llibboost_math_c99l-vc141-mt-1_64\
        -llibboost_math_tr1-vc141-mt-1_64\
        -llibboost_math_tr1f-vc141-mt-1_64\
        -llibboost_math_tr1l-vc141-mt-1_64\
        -llibboost_mpi-vc141-mt-1_64\
        -llibboost_numpy-vc141-mt-1_64\
        -llibboost_numpy3-vc141-mt-1_64\
        -llibboost_prg_exec_monitor-vc141-mt-1_64\
        -llibboost_program_options-vc141-mt-1_64\
        -llibboost_python-vc141-mt-1_64\
        -llibboost_python3-vc141-mt-1_64\
        -llibboost_random-vc141-mt-1_64\
        -llibboost_regex-vc141-mt-1_64\
        -llibboost_serialization-vc141-mt-1_64\
        -llibboost_signals-vc141-mt-1_64\
        -llibboost_system-vc141-mt-1_64\
        -llibboost_test_exec_monitor-vc141-mt-1_64\
        -llibboost_thread-vc141-mt-1_64\
        -llibboost_timer-vc141-mt-1_64\
        -llibboost_type_erasure-vc141-mt-1_64\
        -llibboost_unit_test_framework-vc141-mt-1_64\
        -llibboost_wave-vc141-mt-1_64\
        -llibboost_wserialization-vc141-mt-1_64\
        -llibboost_zlib-vc141-mt-1_64

LIBS += -LD:\PCL\PCL1.8.1\3rdParty\FLANN\lib\
        -lflann\
        -lflann_cpp\
        -lflann_cpp_s\
        -lflann_s

LIBS += -LD:\PCL\PCL1.8.1\3rdParty\OpenNI2\Lib\
        -lOpenNI2

LIBS += -LD:\PCL\PCL1.8.1\3rdParty\Qhull\lib\
        -lqhull\
        -lqhullcpp\
        -lqhullstatic\
        -lqhullstatic_r\
        -lqhull_p\
        -lqhull_r

LIBS += -LD:\PCL\PCL1.8.1\3rdParty\VTK1\lib\
        -lvtkalglib-8.0\
        -lvtkChartsCore-8.0\
        -lvtkCommonColor-8.0\
        -lvtkCommonComputationalGeometry-8.0\
        -lvtkCommonCore-8.0\
        -lvtkCommonDataModel-8.0\
        -lvtkCommonExecutionModel-8.0\
        -lvtkCommonMath-8.0\
        -lvtkCommonMisc-8.0\
        -lvtkCommonSystem-8.0\
        -lvtkCommonTransforms-8.0\
        -lvtkDICOMParser-8.0\
        -lvtkDomainsChemistry-8.0\
        -lvtkexoIIc-8.0\
        -lvtkexpat-8.0\
        -lvtkFiltersAMR-8.0\
        -lvtkFiltersCore-8.0\
        -lvtkFiltersExtraction-8.0\
        -lvtkFiltersFlowPaths-8.0\
        -lvtkFiltersGeneral-8.0\
        -lvtkFiltersGeneric-8.0\
        -lvtkFiltersGeometry-8.0\
        -lvtkFiltersHybrid-8.0\
        -lvtkFiltersHyperTree-8.0\
        -lvtkFiltersImaging-8.0\
        -lvtkFiltersModeling-8.0\
        -lvtkFiltersParallel-8.0\
        -lvtkFiltersParallelImaging-8.0\
        -lvtkFiltersPoints-8.0\
        -lvtkFiltersProgrammable-8.0\
        -lvtkFiltersSelection-8.0\
        -lvtkFiltersSMP-8.0\
        -lvtkFiltersSources-8.0\
        -lvtkFiltersStatistics-8.0\
        -lvtkFiltersTexture-8.0\
        -lvtkFiltersTopology-8.0\
        -lvtkFiltersVerdict-8.0\
        -lvtkfreetype-8.0\
        -lvtkGeovisCore-8.0\
        -lvtkgl2ps-8.0\
        -lvtkGUISupportQt-8.0\
#        -lvtkGUISupportQtOpenGL2-8.0\
        -lvtkGUISupportQtSQL-8.0\
        -lvtkhdf5-8.0\
        -lvtkhdf5_hl-8.0\
        -lvtkImagingColor-8.0\
        -lvtkImagingCore-8.0\
        -lvtkImagingFourier-8.0\
        -lvtkImagingGeneral-8.0\
        -lvtkImagingHybrid-8.0\
        -lvtkImagingMath-8.0\
        -lvtkImagingMorphological-8.0\
        -lvtkImagingSources-8.0\
        -lvtkImagingStatistics-8.0\
        -lvtkImagingStencil-8.0\
        -lvtkInfovisCore-8.0\
        -lvtkInfovisLayout-8.0\
        -lvtkInteractionImage-8.0\
        -lvtkInteractionStyle-8.0\
        -lvtkInteractionWidgets-8.0\
        -lvtkIOAMR-8.0\
        -lvtkIOCore-8.0\
        -lvtkIOEnSight-8.0\
        -lvtkIOExodus-8.0\
        -lvtkIOExport-8.0\
        -lvtkIOExportOpenGL-8.0\
        -lvtkIOGeometry-8.0\
        -lvtkIOImage-8.0\
        -lvtkIOImport-8.0\
        -lvtkIOInfovis-8.0\
        -lvtkIOLegacy-8.0\
        -lvtkIOLSDyna-8.0\
        -lvtkIOMINC-8.0\
        -lvtkIOMovie-8.0\
        -lvtkIONetCDF-8.0\
        -lvtkIOParallel-8.0\
        -lvtkIOParallelXML-8.0\
        -lvtkIOPLY-8.0\
        -lvtkIOSQL-8.0\
        -lvtkIOTecplotTable-8.0\
        -lvtkIOVideo-8.0\
        -lvtkIOXML-8.0\
        -lvtkIOXMLParser-8.0\
        -lvtkjpeg-8.0\
        -lvtkjsoncpp-8.0\
        -lvtklibharu-8.0\
        -lvtklibxml2-8.0\
        -lvtklz4-8.0\
        -lvtkmetaio-8.0\
        -lvtkNetCDF-8.0\
        -lvtknetcdf_c++\
        -lvtkoggtheora-8.0\
        -lvtkParallelCore-8.0\
        -lvtkpng-8.0\
        -lvtkproj4-8.0\
        -lvtkRenderingAnnotation-8.0\
        -lvtkRenderingContext2D-8.0\
        -lvtkRenderingContextOpenGL2-8.0\
        -lvtkRenderingCore-8.0\
        -lvtkRenderingFreeType-8.0\
        -lvtkRenderingGL2PS-8.0\
        -lvtkRenderingGL2PSOpenGL2-8.0\
        -lvtkRenderingImage-8.0\
        -lvtkRenderingLabel-8.0\
        -lvtkRenderingLIC-8.0\
        -lvtkRenderingLOD-8.0\
        -lvtkRenderingOpenGL2-8.0\
        -lvtkRenderingQt-8.0\
        -lvtkRenderingVolume-8.0\
        -lvtkRenderingVolumeOpenGL2-8.0\
        -lvtksqlite-8.0\
        -lvtksys-8.0\
        -lvtktiff-8.0\
        -lvtkverdict-8.0\
        -lvtkViewsContext2D-8.0\
        -lvtkViewsCore-8.0\
        -lvtkViewsInfovis-8.0\
        -lvtkViewsQt-8.0\
        -lvtkzlib-8.0

LIBS += -LD:\OpenCV\opencv\build\x64\vc15\lib\
        -lopencv_world455

LIBS += -LD:\pthread\Pre-built.2\lib\x64\
        -lpthreadVC2

LIBS += -LD:\log4cpp\msvc10\x64\Release\
        -llog4cpp

}

3.3 软件界面

3.3.1 ui文件

  • 双击xxx.ui文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3.2 按钮图标

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3.3 其他界面设置

  • 发现写得有些繁琐了orz,还是快速结束界面相关讲点云的处理吧(但界面为了好看些也确实花了些时间哈哈O_o,比如说无边框、缩放、鼠标悬停显示提示等)

在这里插入图片描述

  • 以下这些操作可以写在mainwindow初始化的地方
    • 鼠标悬停在按钮旁边时提示的信息 ui->pushButton_box->setToolTip(QString("<span style=\"color: #4a90e2; font-size: 12px;\">%1</span>").arg("box"));
    • 设置按钮的背景颜色为透明 ui->pushButton_box->setStyleSheet("background-color:transparent");或者ui->pushButton_box->setStyleSheet("background-color:rgba(0,0,0,0)");
    • 设置为非焦点按钮 ui->pushButton_box->setFocusPolicy(Qt::NoFocus);
    • 设置按钮是否可用 ui->pushButton_previous->setEnabled(false);
      • 有些按钮需等到一定条件后再设置为可点击,这样可以降低误操作,譬如上下一张点云需等打开点云后才能点击(不然将会访问容器中不存在的位置导致错误)
    • 设置背景透明 setAttribute(Qt::WA_TranslucentBackground);
    • 设置无边框 setWindowFlags(Qt::Window|Qt::FramelessWindowHint |Qt::WindowSystemMenuHint|Qt::WindowMinimizeButtonHint|Qt::WindowMaximizeButtonHint);
    • 设置窗口背景颜色和边界弧度 this->setStyleSheet("QWidget{background-color:black;border-radius:10px;}");
  • 由于设置无边框后窗口缩放和拖动存在问题,可添加以下代码
    void resizeEvent(QResizeEvent *e);
    //由于去掉显示界面的菜单栏和标题栏,无法拖动窗口,重写关于窗口拖动用的几个函数
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void showEvent(QShowEvent* event);
void Widget::resizeEvent(QResizeEvent *e)
{
    QWidget::resizeEvent(e);
    QSize sz = e->size();
    QBitmap mask(sz);
    QPainter painter(&mask);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.fillRect(0, 0, sz.width(), sz.height(), Qt::white);
    painter.setBrush(QColor(0, 0, 0));
    painter.drawRoundedRect(0, 0, sz.width(), sz.height(), 10, 10);
    setMask(mask);
}

void Widget::mousePressEvent(QMouseEvent *event)
{
    isPressedWidget = true; // 当前鼠标按下的即是QWidget而非界面上布局的其它控件
    last = event->globalPos();

//    this->setFocus();
//    if(Qt::LeftButton == event->button() && 0 == (Qt::WindowMaximized & this->windowState()))
//    {
//        QPoint temp=event->globalPos();
//        pLast=temp;    //记录鼠标按下的位置
//        event->ignore();
//    }
//    m_bPressed = true; //标记鼠标为按下状态
}

void Widget::mouseMoveEvent(QMouseEvent *event)
{
    if(this->isMaximized()) //如果当前是最大化,则不允许移动
            return;
    if (isPressedWidget)
    {
        int dx = event->globalX() - last.x();
        int dy = event->globalY() - last.y();
        last = event->globalPos();
        move(x()+dx, y()+dy);
    }
//    if(this->isMaximized()) //如果当前是最大化,则不允许移动
//            return;
//    if((event->buttons() & Qt::LeftButton) && m_bPressed)//是否左击
//    {
//        QPoint ptemp=event->globalPos();          //当前鼠标全局位置
//        ptemp=ptemp-pLast;                        //计算移动变量
//        ptemp=ptemp+pos();                        //窗口原始位置(pos()) + 鼠标移动变量(ptemp) = 最终窗口位置
//        move(ptemp);                              //移动窗口到新的位置
//    }
}

void Widget::mouseReleaseEvent(QMouseEvent *event)
{
    int dx = event->globalX() - last.x();
    int dy = event->globalY() - last.y();
    move(x()+dx, y()+dy);
    isPressedWidget = false; // 鼠标松开时,置为false

//    QApplication::restoreOverrideCursor();//恢复鼠标指针性状
//    event->ignore();
    //    m_bPressed = false;
}

void Widget::showEvent(QShowEvent *event)
{
    this->setAttribute(Qt::WA_Mapped);//解决不能及时刷新的bug
    QWidget::showEvent(event);
}
  • 给软件添加图标可以参考博客<QT 如何给QT程序添加图标>
    • 记得在.pro文件添加RC_FILE += logo.rc

3.4 点云处理

3.4.1 点云读取显示

  • 可以参考博客<读取并显示.pcd/.ply/.txt/.bin/.stl格式的点云>
  • 对于在qt中显示点云可以这样操作
    • 在类中设置点云和PCLVisualizer的成员函数
    • pcl::PointCloudpcl::PointXYZ::Ptr cloud_;

    • boost::shared_ptrpcl::visualization::PCLVisualizer viewer_;

    • 在窗口类进行初始化时进行以下操作
cloud_.reset(new pcl::PointCloud<pcl::PointXYZ>);
viewer_.reset(new pcl::visualization::PCLVisualizer("tree&cat",false));
viewer_->setBackgroundColor(0,0,0);
ui->qvtkWidget->SetRenderWindow(viewer_->getRenderWindow());
viewer_->setupInteractor(ui->qvtkWidget->GetInteractor(),ui->qvtkWidget->GetRenderWindow());
viewer_->resetCamera();
ui->qvtkWidget->update();
  • 在需要显示点云的地方调用博客<读取并显示.pcd/.ply/.txt/.bin/.stl格式的点云>中的showPointCloud即可进行点云的可视化

3.4.2 上/下一张显示点云

  • 在头文件中创建目录索引int serialNum = 0;以及文件名列表QList<QFileInfo>* fileInfo;
  • 利用getOpenFileName获取打开的文件名称
  • 通过字符串中的/符号位置获取路径名称
  • 设置过滤器筛选后缀为点云的文件的文件名
  • 获取目录下所有点云的路径存入到文件名列表fileInfo中
  • 并遍历列表找到与当前打开的文件名相同的文件以确定索引serialNum位置
cloudPath_=QFileDialog::getOpenFileName(this,"pleas chose point cloud",/*""*/lastPath,
                                                   "   (*.pcd *.ply *.txt *.bin *.stl);;   (*.*)"/*,&selectedFilter,options*/);

QString temp=cloudPath_;
for(int i=temp.length();i>0;i--)
{
    if (temp[i - 1] == "/")
    {
        cloudDir=temp;
        break;
    }
    else
    {
        temp.chop(1);
    }
}

QStringList filter;
    filter<<"*.pcd"<<"*.ply"<<"*.txt"<<"*.bin"<<"*.stl";
    QDir* dir =new QDir(cloudDir);
    dir->setNameFilters(filter);
    fileInfo=new QList<QFileInfo>(dir->entryInfoList(filter));
    for (int i = 0; i < fileInfo->count(); ++i) {
        if(cloudPath_==fileInfo->at(i).filePath())
        {
            serialNum=i;
            break;
        }
    }
  • 当点击上一张按钮时索引自减、当自减后索引<0时,将索引设置为列表size()-1
  • 根据索引获取路径判断路径不为空后,可以调用<博客>中的readPointCloud和showPointCloud进行点云的读取和显示
    if(--serialNum<0)
    {
        serialNum=fileInfo->count()-1;
    }
    cloudPath_=fileInfo->at(serialNum).filePath();
    if(!cloudPath_.isEmpty())
    {
        ...
    }
  • 当点击下一张按钮索引自增、当自增后索引==0时,将索引设置为0
    if(++serialNum==fileInfo->count())
    {
        serialNum=0;
    }
    cloudPath_=fileInfo->at(serialNum).filePath();
    if(!cloudPath_.isEmpty())
    {
        ...
    }

3.4.3 状态栏显示点云信息

  • 可以在界面顶部增加一个label,每次更新显示点云showPointCloud时,显示点云的当前路径名和点云等信息
  • 也可以利用getMinMax3D计算点云的最大最小点再顶部显示以确定点云的范围(还可以计算点云密度等进行显示)
pcl::getMinMax3D(*cloud,minPoint_,maxPoint_);
QString range="  ("+QString::number(minPoint_.x)+","+QString::number(minPoint_.y)+","+QString::number(minPoint_.z)+") ("+QString::number(maxPoint_.x)+","+QString::number(maxPoint_.y)+","+QString::number(maxPoint_.z)+")";
ui->label->setText(cloudPath_+QString::fromLocal8Bit("  size:")+QString::number(cloud->size())+range);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-96rp8RM7-1690707772337)(19.png#pic_center)]### 3.4.4 点云处理操作

  • 包括点云的滤波、分割、画包围盒等处理方法也都可以写在对应按钮的槽函数中
  • 这个博客里有写过一些相关处理的封装函数可以复制调用<PCL常用可视化/滤波/分割等函数的封装>

3.4.5 线程相关操作

  • 可以利用qt的信号和槽机制
    • 如创建一个新类cloudSegment继承QObject
    • 在窗口类中创建新类对象指针cloudSegment *seg;与QThread线程对象 QThread segThread_;
    • 初始化的时候将指针放到线程中;连接信号和槽并开启线程
    • 析构的时候退出线程
    • (由于子线程不能操作ui,所以需要显示子线程的点云时,需利用信号和槽将子线程的点云发送到主线程进行显示)
//构造
seg=new cloudSegment(this);
seg->moveToThread(&segThread_);
connect(&segThread_,&QThread::finished, base, &QObject::deleteLater);
connect(this,&Widget::segcloud,seg,&cloudSegment::segCloud);
connect(seg,&cloudSegment::segDone,this,&Widget::showSegCloud);
segThread_.start();
//析构
segThread_.quit();
segThread_.wait();

3.4.6 保存点云

  • 可以每次将界面点云赋值给成员变量cloud_,点保存按钮时确认cloud_不为空则选择文件夹及名称进行保存
if(cloud_)
{
    QString filename=QFileDialog::getSaveFileName(this,tr("save point cloud"),"",tr("PointCloud (*.pcd)"));
    if(!filename.isNull())
    {
        pcl::io::savePCDFileBinary(filename.toLocal8Bit().toStdString(),*cloud_);
    }
}

3.5 其他

3.5.1 配置文件

  • 可以通过写配置.ini文件记录最后一次打开的文件夹路径,下次打开时直接打开这个路径不必每次都要从初始路径去找
  • 可以利用QSettings实现,也可以自己写一个操作配置文件的类
//设置为类的成员函数
QSettings setting;
//窗口类初始化时初始化列表加上setting
setting("./Setting.ini", QSettings::IniFormat)
//为setting设置键值
setting.setValue("LastFilePath",cloudPath_);

3.5.2 写日志

  • 可以借助log4cpp日志库
  • <QT使用log4cpp日志库>

3.5.3 软件发布

  • qt的项目软件打包可以参考博客<Qt项目发布打包教程(win10)>
  1. 将release下生成的exe文件复制到一个新的文件夹
  2. 打开你在qt中所使用的编译器如我的就是Qt 5.14.2(MSVC 2017 64-bit)
  3. cd到你存exe的新文件夹输入windeployqt name.exe(这样qt就会将需要的依赖打包到这个文件夹里)
  4. 对于一些外部的dll需要自己复制到文件夹下

在这里插入图片描述

  • 这样生成的软件是一个文件下有软件还有很多别的文件
  • 如果想给别人使用时只用一个文件可以使用EnigmaVirtualBox进行封包
    • 可以参考<QT使用Enigma Virtual Box打包exe>

4. 软件

  • 这次更新可能比较实用的地方是增加了顶部状态栏显示点云文件的路径和点数等比较方便知道显示的是哪个点云以及部分点云信息
  • 其可能是保存功能吧,因为5种格式的点云都可以打开,最后保存这里我保存的是当前界面显示的处理后的pcd点云,即使不做处理也可以保存相当于可以做点云的类型转换吧,5种转存pcd
  • 其他的功能将鼠标悬停在按钮附近便可以显示,例如box是给当前界面点云画包围盒、removeOuter是滤除离群点等
  • 但是某些功能我当时是为了测试项目中部分功能,在代码里写的固定参数,可能会出现不适用情况,例如RgnGrow区域生长、plane平面拟合、cluster聚类等

那就再次存个档吧:D 链接还是之前那个链接 cloud.exe是之前的版本,treeandcat.exe是现在的版本
百度网盘 提取码:2lm2

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/812240.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

0基础五分钟学会使用shardingJDBC实现分表 及测试

1.引入相关依赖 <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>4.1.1</version> </dependency> 2.添加配置 不懂的地方自己看注释 主…

vue基础-虚拟dom

vue基础-虚拟dom 1、真实dom目标2、虚拟dom目标 1、真实dom目标 在真实的document对象上&#xff0c;渲染到浏览器上显示的标签。 2、虚拟dom目标 本质是保存节点信息、属性和内容的一个JS对象 更新会监听变化的部分 给真实的DOM打补丁

SpringBoot多环境开发-配置文件

在Spring Boot中进行多环境开发时&#xff0c;你可以使用配置文件来定义每个环境的属性。Spring Boot提供了一种方便的方式来管理和加载不同环境的配置文件。 以下是一些常见的配置文件命名约定&#xff1a; application.properties: 默认的配置文件&#xff0c;适用于所有环…

Unity 性能优化五:渲染模块压力

CPU压力 Batching 在GPU渲染前&#xff0c;CPU会把数据按batch发送给GPU&#xff0c;每发送一次&#xff0c;都是一个drawcall&#xff0c;GPU在渲染每个batch的时候&#xff0c;会切换渲染状态&#xff0c;这里的渲染状态指的是&#xff1a;影响对象在屏幕上的外观的渲染属性…

【公益】Q学友联合福田人力资源局开展“侨香社区促就业 技能培训强本领”

落实《“十四五”就业促进规划》文件精神&#xff0c;进一步提高就业劳动者就业技能水平&#xff0c;提高居民就业率&#xff0c;侨香社区党委坚持以党建为引领&#xff0c;整合多方资源&#xff0c;深入开展“我为群众办实事”&#xff0c;切合群众实际、满足群众需求&#xf…

Huggingface基本使用

目录 0.install 1.tokenizer 2.datasets 3.metrics 0.install !pip install transformers !pip install datasets 1.tokenizer from transformers import BertTokenizer#加载预训练字典和分词方法 tokenizer BertTokenizer.from_pretrained(pretrained_model_name_or…

力扣 509. 斐波那契数

题目来源&#xff1a;https://leetcode.cn/problems/fibonacci-number/description/ C题解1&#xff1a;根据题意&#xff0c;直接用递归函数。 class Solution { public:int fib(int n) {if(n 0) return 0;else if(n 1) return 1;else return(fib(n-1) fib(n-2));} }; C题…

【物联网无线通信技术】UWB定位从理论到实现(DW1000)

超宽带&#xff08;UWB&#xff09;是一种基于IEEE 802.15.4a和802.15.4z标准的无线电技术&#xff0c;可以非常精确地测量无线电信号的飞行时间&#xff0c;从而实现厘米级精度的距离/位置测量。UWB技术除了提供定位功能外&#xff0c;它本身是一种通信技术&#xff0c;其提供…

Java在线OJ项目(三)、前后端交互API模块

Java在线OJ项目&#xff08;三&#xff09;、前后端交互API模块 1. 客户端向服务器请求所有题目 或者 单个题目前端获取所有题目获取一个题目 后端 2. 后端读取前端提交的代码&#xff0c;进行编译运行&#xff0c;返回结果前端提交代码后端处理 1. 客户端向服务器请求所有题目…

【程序设计】一文讲解程序设计原则SOLDI

前言 设计原则&#xff0c;是指导我们如何设计出低耦合、高内聚的代码&#xff0c;让代码能够更好的应对变化&#xff0c;从而降本提效。 设计原则的关键&#xff0c;是从『使用方的角度』看『提供方』的设计&#xff0c;一句话概括就是&#xff1a;请不要要我知道太多&#…

VBA技术资料MF36:VBA_在Excel中排序

【分享成果&#xff0c;随喜正能量】一个人的气质&#xff0c;并不在容颜和身材&#xff0c;而是所经历过的往事&#xff0c;是内在留下的印迹&#xff0c;令人深沉而安谧。所以&#xff0c;优雅是一种阅历的凝聚&#xff1b;淡然是一段人生的沉淀。时间会让一颗灵魂&#xff0…

IO流(2)-缓冲流

1. 缓冲流的简单介绍 我们上贴说到了 FileInputStream&#xff0c;FileOutputStream&#xff0c;FileReader&#xff0c;FileWriter。 其实这四个流&#xff0c;我们通常把它叫做原始流&#xff0c;它们是比较偏底层的&#xff1b;而今天我们要说的四个缓冲流&#xff0c;如…

自己创建的类,其他类中使用错误

说明&#xff1a;自己创建的类&#xff0c;在其他类中创建&#xff0c;报下面的错误&#xff08;Cannot resolve sysmbol ‘Redishandler’&#xff09;&#xff1b; 解决&#xff1a;看下是不是漏掉了包名 加上包名&#xff0c;问题解决&#xff1b;

第9届Python编程挑战赛初中组初赛真题剖析-2023年全国青少年信息素养大赛

[导读]&#xff1a;超平老师计划推出《全国青少年信息素养大赛Python编程真题解析》50讲&#xff0c;这是超平老师解读Python编程挑战赛系列的第13讲。 全国青少年信息素养大赛&#xff08;原全国青少年电子信息智能创新大赛&#xff09;是“世界机器人大会青少年机器人设计与…

PyCharm安装pip依赖,如何添加国内镜像源?

目录 前言 PyCharm如何安装依赖 PyCharm如何配置国内镜像源 前言 首先我们都知道&#xff0c;使用pip安装依赖的方式&#xff0c;却很少有人知道使用PyCharm如何安装依赖。 PyCharm如何安装依赖 但你会发现&#xff0c;基本都是安装失败的&#xff0c;因为你是去外网下载的…

左神算法之中级提升班(8)

目录 【案例1】 【题目描述】 【思路解析】 【代码实现】 【案例2】 【题目描述】 【思路解析】 【代码实现】 【案例3】 【题目描述】 【思路解析】 【案例4】 【题目描述】 【思路解析】 【代码实现】 【案例5】 【题目描述】 【子序列概念】 【思路解析1 经典…

CTF-MISC:BUUCTF练习汇总(持续更新)

CTF-MISC&#xff1a;BUUCTF练习汇总 1、金三胖2、你竟然赶我走3、二维码4、大白 1、金三胖 解题思路&#xff1a; flag隐藏在gif图片帧中&#xff0c;使用在线GIF拆分工具即可 在线GIF图片帧拆分工具&#xff1a;https://uutool.cn/gif2img/ flag为&#xff1a;flag{he11oho…

应用层协议——https

文章目录 1. HTTPS 是什么2. 什么是"加密"3. 常见的加密方式4. 数据摘要 && 数字签名5. HTTPS 的工作过程探究5.1 方案1 - 只使用对称加密5.2 方案2 - 只使用非对称加密5.3 方案3 - 双方都使用非对称加密5.4 方案4 - 非对称加密 对称加密5.5 中间人攻击5.6 …

【MTI 6.S081 Lab】locks

【MTI 6.S081 Lab】locks Memory allocator (moderate)实验任务Hint解决方案 Buffer cache (hard)实验任务Hint解决方案数据结构设计初始化数据结构getrelse 本实验前去看《操作系统导论》第29章基于锁的并发数据结构&#xff0c;将会是很有帮助的。 在这个实验室中&#xff0…

懒得改变原始对象?JavaScript代理模式教你怎样一步步偷懒!

前言 系列首发gong zhong hao[『非同质前端札记』] &#xff0c;若不想错过更多精彩内容&#xff0c;请“星标”一下&#xff0c;敬请关注gong zhong hao最新消息。 懒得改变原始对象&#xff1f;JavaScript代理模式教你怎样一步步偷懒&#xff01; 何为代理模式 例如&#x…