QT6+CloudCompare显示3D点云

这篇具有很好参考价值的文章主要介绍了QT6+CloudCompare显示3D点云。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

    CloudCompare是一个三维点云(网格)编辑和处理软件。最初,它被设计用来对稠密的三维点云进行直接比较。它依赖于一种特定的八叉树结构,在进行点云对比这类任务时具有出色的性能。此外,由于大多数点云都是由地面激光扫描仪采集的,CloudCompare的目的是在一台标准笔记本电脑上处理大规模的点云——通常超过1000万个点云。在2005年后,cloudcompare就实现了点云和三角形网格之间的比较。随后,许多其他点云处理算法(配准、重采样、颜色/法线向量/尺度、统计计算、传感器管理、交互式或自动分割等)以及显示增强工具(自定义颜色渐变、颜色和法向量处理,校准图像处理、OpenGL着色器、插件等)

QT6+CloudCompare显示3D点云

1 下载和安装

  CloudCompare软件的下载地址如下:

http://www.cloudcompare.org/

    源码地址如下:

https://github.com/cloudcompare/cloudcompare

QT6+CloudCompare显示3D点云

2 构建Qt工程

 CloudCompare源码是基于Qt5的,如果你要编译Qt5版本,就直接用cmake编译就行。

    先构建如下的文件:

QT6+CloudCompare显示3D点云

    CloudCompare.pro文件改为如下设置。


TEMPLATE    =   subdirs
SUBDIRS += \
            CC \
            contrib \
            libs \
            plugins \
            ccViewer
#            qCC \

 至于每个子项目的.pro怎么设置,可以参考如下代码:


TEMPLATE = lib
TARGET   = CC_CORE_LIB
CONFIG  += c++17
DEFINES += QT_DEPRECATED_WARNINGS
DEFINES += CC_CORE_LIB_EXPORTS

##################################################################
#指定生成的文件存放位置
##################################################################
MOC_DIR         = $$PWD/temp/moc
RCC_DIR         = $$PWD/temp/rcc
UI_DIR          = $$PWD/temp/ui
OBJECTS_DIR     = $$PWD/temp/obj
DESTDIR         = $$PWD/temp/bin

INCLUDEPATH +=  . \
                ./include \
                ./src

HEADERS += \
    include/AutoSegmentationTools.h \
    include/BoundingBox.h \
    include/CCConst.h \
    include/CCCoreLib.h \
    include/CCCoreLibExport.h \
    include/CCGeom.h \
    include/CCMiscTools.h \
    include/CCPlatform.h \
    include/CCShareable.h \
    include/CCToolbox.h \
    include/CCTypes.h \
    include/ChamferDistanceTransform.h \
    include/CloudSamplingTools.h \
    include/ConjugateGradient.h \
    include/Delaunay2dMesh.h \
    include/DgmOctree.h \
    include/DgmOctreeReferenceCloud.h \
    include/DistanceComputationTools.h \
    include/ErrorFunction.h \
    include/FastMarching.h \
    include/FastMarchingForPropagation.h \
    include/Garbage.h \
    include/GenericCloud.h \
    include/GenericDistribution.h \
    include/GenericIndexedCloud.h \
    include/GenericIndexedCloudPersist.h \
    include/GenericIndexedMesh.h \
    include/GenericMesh.h \
    include/GenericOctree.h \
    include/GenericProgressCallback.h \
    include/GenericTriangle.h \
    include/GeometricalAnalysisTools.h \
    include/Grid3D.h \
    include/Jacobi.h \
    include/KdTree.h \
    include/LocalModel.h \
    include/ManualSegmentationTools.h \
    include/MathTools.h \
    include/MeshSamplingTools.h \
    include/Neighbourhood.h \
    include/NormalDistribution.h \
    include/ParallelSort.h \
    include/PointCloud.h \
    include/PointCloudTpl.h \
    include/PointProjectionTools.h \
    include/Polyline.h \
    include/RayAndBox.h \
    include/ReferenceCloud.h \
    include/RegistrationTools.h \
    include/SaitoSquaredDistanceTransform.h \
    include/ScalarField.h \
    include/ScalarFieldTools.h \
    include/SimpleMesh.h \
    include/SimpleTriangle.h \
    include/SquareMatrix.h \
    include/StatisticalTestingTools.h \
    include/TrueKdTree.h \
    include/WeibullDistribution.h \
    src/Chi2Helper.h

SOURCES += \
    src/AutoSegmentationTools.cpp \
    src/BoundingBox.cpp \
    src/CCMiscTools.cpp \
    src/CCShareable.cpp \
    src/ChamferDistanceTransform.cpp \
    src/CloudSamplingTools.cpp \
    src/Delaunay2dMesh.cpp \
    src/DgmOctree.cpp \
    src/DgmOctreeReferenceCloud.cpp \
    src/DistanceComputationTools.cpp \
    src/ErrorFunction.cpp \
    src/FastMarching.cpp \
    src/FastMarchingForPropagation.cpp \
    src/GeometricalAnalysisTools.cpp \
    src/KdTree.cpp \
    src/LocalModel.cpp \
    src/ManualSegmentationTools.cpp \
    src/MeshSamplingTools.cpp \
    src/Neighbourhood.cpp \
    src/NormalDistribution.cpp \
    src/NormalizedProgress.cpp \
    src/PointProjectionTools.cpp \
    src/Polyline.cpp \
    src/ReferenceCloud.cpp \
    src/RegistrationTools.cpp \
    src/SaitoSquaredDistanceTransform.cpp \
    src/ScalarField.cpp \
    src/ScalarFieldTools.cpp \
    src/SimpleMesh.cpp \
    src/StatisticalTestingTools.cpp \
    src/TrueKdTree.cpp \
    src/WeibullDistribution.cpp

    然后将CloudCompare源码中对应的源文件,拷贝到自己对应的工程目录下。

    最后构建完后的工程如下图所示:

QT6+CloudCompare显示3D点云

3 修改源码

    由于CloudCompare源码是基于Qt5的,换成Qt6后要修改部分源码。下面是我记录的要修改的内容:


//修改内容1:
inline ccQOpenGLFunctions* functions() const { return context() ? context()->versionFunctions<ccQOpenGLFunctions>() : nullptr; }//源码
inline ccQOpenGLFunctions* functions() const { return context() ? (ccQOpenGLFunctions*)context()->functions () : nullptr; }//修改后

//修改内容2:
<<endl;//源码
<<Qt::endl;//修改后
//修改内容3:
      stream.readNextStartElement();
            QString itemName = stream.name().toString();
      QString itemValue = stream.readElementText();
            ccLog::Print(QString("[XML] Item '%1': '%2'").arg(itemName,itemValue));
//            QStringRef itemName = stream.name();
//      QString itemValue = stream.readElementText();
//      ccLog::Print(QString("[XML] Item '%1': '%2'").arg(itemName.toString(),itemValue));
//修改内容4:
    QOpenGLFunctions_2_1* glFunc = (QOpenGLFunctions_2_1*)context->functions();//修改后
//    QOpenGLFunctions_2_1* glFunc = context->versionFunctions<QOpenGLFunctions_2_1>();

//修改内容5:
//    QStringList tokens = currentLine.simplified().split(QChar(' '), QString::SkipEmptyParts);
        QStringList tokens = currentLine.simplified().split(QChar(' '), Qt::SkipEmptyParts);
//修改内容6:
//#include <QGLBuffer>
#include <QOpenGLBuffer>

//修改内容7:
//            xShift = tab.colWidth[c] - QFontMetrics(bodyFont).width(str);
                        xShift = tab.colWidth[c] - QFontMetrics(bodyFont).horizontalAdvance(str);

//修改内容8:
//        float sizeModifier = (event->delta() < 0 ? -1.0f : 1.0f);
        float sizeModifier = (event->angleDelta().y() < 0 ? -1.0f : 1.0f);

//修改内容9:
//  return QStringLiteral( "Created %1" ).arg( QDateTime::currentDateTime().toString( Qt::SystemLocaleShortDate ) );
    return QStringLiteral( "Created %1" ).arg( QDateTime::currentDateTime().toString("yyyy/MM/dd hh:mm") );

//修改内容10:
//  QSize screenSize = QApplication::desktop()->screenGeometry().size();
    QSize screenSize = QGuiApplication::primaryScreen()->availableSize();
//修改内容11:
//    if (sep == 4) //comma 
    if (sep == QChar(44)) //comma

//                if (lsfDlg.listWidget->isItemSelected(lsfDlg.listWidget->item(i)))
                                if (lsfDlg.listWidget->item(i)->isSelected())
//修改内容12:
//  foreach (QCPItemPosition *child, mChildrenX.toList()) 
    foreach (QCPItemPosition *child, mChildrenX.values())

//修改内容13:
//    painter.setRenderHint(QPainter::HighQualityAntialiasing);
      painter.setRenderHint(QPainter::Antialiasing); // to make Antialiasing look good if using the OpenGL graphicssystem
    
//修改内容14:
//  if (QCPLayoutElement *el = layoutElementAt(event->pos()))
    if (QCPLayoutElement *el = layoutElementAt(event->position()))
    
//修改内容15:
//        mColorBuffer[i] = (it-1).value().rgb();
          --it;
        mColorBuffer[i] = it.value().rgb();



//修改内容16:
//    mAxisRect.data()->setRangeDrag(0);
    mAxisRect.data()->setRangeDrag(QCPAxis::orientation(QCPAxis::AxisType(0)));
  
  
  
//修改内容17:
//      QCPDataMap::const_iterator upperEnd = upper+1;
      QCPDataMap::const_iterator upperEnd = ++upper;--upper;
  
//修改内容18:
//    newData.t = (mData->constEnd()-1).key()+1;
  QCPCurveDataMap::const_iterator upperEnd = mData->constEnd();--upperEnd;
  if (!mData->isEmpty())
    newData.t = upperEnd.key()+1;
  
//修改内容19:
    if (command == PDMS_LAST)
  {
    if (s_elementsStack.size() < 2)
            return false;
//        ElementsStack::iterator it = s_elementsStack.end(); --it;
        ElementsStack::iterator i = s_elementsStack.begin();
        ElementsStack::iterator j = s_elementsStack.begin();
        for (; i != s_elementsStack.end(); j=i,++i) {}
        ElementsStack::iterator it = j;
    if (isSet() == 1)
    {
//      while (true)
//      {
//        if (isNameReference() && strcmp(refname, (*it)->name) == 0)
//          break;
//        if (isTokenReference() && (*it)->getType() == token)
//          break;
//        if (it == s_elementsStack.begin())
//          return false;
//        --it;
//      }
            for (ElementsStack::iterator tmp = s_elementsStack.begin(); tmp != j; ++tmp) {
                it = tmp;
                if (isNameReference() && strcmp(refname, (*it)->name) == 0)
                    break;
                if (isTokenReference() && (*it)->getType() == token)
                    break;
                if (it == s_elementsStack.begin())
                    return false;
            }
    }
    item = *it;
    return true;
  }
  
//修改内容20:
//  ccViewer(QWidget *parent = 0, Qt::WindowFlags flags = 0);
    ccViewer(QWidget *parent = 0, Qt::WindowFlags flags = Qt::Widget);

4 编译源码

    编译成功后,拷贝对应的库到程序目录,运行程序后效果如下:

QT6+CloudCompare显示3D点云

  我以将测试源码放到CSDN上面,有需要可以下载。文章来源地址https://www.toymoban.com/news/detail-401585.html

https://download.csdn.net/download/qq_40732350/85230547

到了这里,关于QT6+CloudCompare显示3D点云的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 三维点云拟合圆形(附open3d python 代码)

    圆拟合方法可分为以下步骤: 使用  SVD(奇异值分解) 找到平均中心点集的最佳拟合平面。 将均值中心点投影到新的 2D 坐标中的拟合平面上。 使用 最小二乘法 拟合 2D 坐标中的圆并得到圆心和半径。 将圆中心变换回 3D 坐标。现在,拟合圆由其中心、半径和法线向量指定。

    2024年02月06日
    浏览(30)
  • CloudCompare——CANUPO点云分类

      CANUPO插件是一种自动分类点云的简单而有效的方法。它允许用户创建自己的分类器(通过在小样本上训练它们)和/或在点云上一次应用一个分类器,以便将其分成两个子集。它还为每个点输出分类置信度值,以便用户可以快速识别有问题的案例(问题一般出现在边界上)

    2024年02月12日
    浏览(22)
  • Open3D点云数据处理(二十):最小二乘直线拟合(三维)

    专栏目录:Open3D点云数据处理(Python) 最小二乘三维直线拟合的原理是通过最小化数据点到直线距离的平方和,找到最优的直线模型来拟合给定数据集。这个距离是指数据点到直线的垂线距离。 三维直线通常表示为两个平面的交线,形如 { A

    2024年02月12日
    浏览(31)
  • open3d教程(二):可视化三维模型,并转换成点云(Python版本)

    可以自己用建模软件建立一个模型 从free3d免费下载 open3d.visualization. draw_geometries 参数: geometry_list ( List[open3d.geometry.Geometry]) : 要可视化的几何体列表. window_name( str ,  optional ,  default=\\\'Open3D\\\'): 展示模型的可视化窗口名称,默认是Open3d. width: 

    2024年02月11日
    浏览(37)
  • 【GlobalMapper精品教程】059:基于las点云创建数字高程地形并二三维着色显示

    本文讲述在globalmapper免费中文版中基于地形点云las数据创建数字高程地形、数字高程二三维联动可视化并进行数字高程着色显示。 相关阅读 :ArcGIS实验教程——实验二十:ArcGIS数字高程模型DEM建立 加载配套实验数据包中的 point.las 点云数据,如下图所示,默认是灰度显示。

    2024年02月08日
    浏览(30)
  • CloudCompare 二次开发(13)——点云投影到圆柱

      不依赖任何第三方点云相关库,使用CloudCompare编程实现点云投影到指定圆柱,具体计算原理见:PCL 点云投影到圆柱 1、 mainwindow.h 文件 public 中添加: 2、 mainwindow.cpp 文件 void MainWindow::connectActions() 函数中添加:

    2024年02月09日
    浏览(21)
  • python读取并显示3d点云数据

    首先给出代码,很简单,如下所示: 在运行之前需要安装open3d库,安装过程如下: 点击图中的cmd,这个安装anaconda就会有。直接在cmd中输入pip install open3d -i https://pypi.tuna.tsinghua.edu.cn/simple 这是通过镜像下载,速度很快。 下载成功后,就可以运行了。运行之前,请将路径更改

    2024年02月12日
    浏览(28)
  • open3d,读取stl/ply/obj/off/gltf/glb三维模型,并转换成点云,保存

    可以自己用建模软件建立一个模型 本案例使用模型的下载地址 可以从free3d免费下载,无需注册 效果: 效果: 均匀采样会在表面出现采样点聚集的现象,open3d实现了一种基于poisson_disk方法的采样,能实现表面的均匀采样 原理 :参数umber_of_points是最终采样的点数量,实际会先

    2024年02月11日
    浏览(40)
  • CloudCompare二次开发之如何通过PCL进行点云分割?

      因笔者课题涉及点云处理,需要通过PCL进行点云数据一系列处理分析,查阅现有网络资料,对常用PCL点云分割进行代码实现,本文记录分割实现过程。    (1)设计.ui文件    ①设计按钮       ②编译.ui       (2)修改mainwindow.h文件       (3)修改ma

    2024年02月05日
    浏览(29)
  • CloudCompare二次开发之如何通过PCL进行点云滤波?

      因笔者课题涉及点云处理,需要通过PCL进行点云数据一系列处理分析,查阅现有网络资料,对常用PCL点云滤波器进行代码实现,本文记录滤波器实现过程。    (1)设计.ui文件    ①设计按钮       ②编译.ui       (2)修改mainwindow.h文件       (3)修改

    2024年02月05日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包