Qt调用PCL库,在QWidget中显示点云

最终效果展示

在Qt界面中显示点云

本人环境:Ubuntu18.04 / Qt 5.14.2 / PCL 1.8

下面介绍具体原理和实现步骤。


原理

其实核心就是这一行代码
在这里插入图片描述
将数据从pclviewer 传输到 QVTKWidget。

具体实现

1、.ui 设计

插入一个QWidget,然后右键QWidget => 提升为 => QVTKWidget (注意QVTKWidget.h区分大小写!!)
在这里插入图片描述
在这里插入图片描述再新建四个horizontalSlider,分别命名为horizontalSlider_Red,horizontalSlider_Green,horizontalSlider_Blue,horizontalSlider_Size。用于控制点云的颜色和大小。

2、代码

.pro

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# 主要需要修改的部分在下方,注意库的地址!
# -------------------------------------------------------
INCLUDEPATH += /usr/include/eigen3								#注意路径可能不一样

INCLUDEPATH += /usr/include/vtk-6.3
LIBS += /usr/lib/x86_64-linux-gnu/libvtk*.so					#注意路径可能不一样

INCLUDEPATH += /usr/include/boost								#注意路径可能不一样
LIBS += /usr/lib/x86_64-linux-gnu/libboost_*.so		

INCLUDEPATH += /usr/include/pcl-1.8								#注意路径可能不一样
LIBS += /usr/lib/x86_64-linux-gnu/libpcl_*.so
# -------------------------------------------------------

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += \
    main.cpp \
    qtpclviewer.cpp

HEADERS += \
    qtpclviewer.h

FORMS += \
    qtpclviewer.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

qtpclviewer.h

#ifndef QTPCLVIEWER_H
#define QTPCLVIEWER_H

#include <QMainWindow>
#include "ui_qtpclviewer.h"

#ifndef INITIAL_OPENGL
#define INITIAL_OPENGL
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL)
VTK_MODULE_INIT(vtkInteractionStyle)
#endif

#include <QFileDialog>
#include <vtkRenderWindow.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>

//QT_BEGIN_NAMESPACE
//namespace Ui { class QtPclViewer; }
//QT_END_NAMESPACE

class QtPclViewer : public QMainWindow
{
    Q_OBJECT

public:
    QtPclViewer(QWidget *parent = nullptr);
    ~QtPclViewer();

private:
    Ui::QtPclViewer *ui;
    // Ui::QtPclViewerClass ui;

    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud;
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;
    void initialVtkWidget();

protected:
    unsigned red;
    unsigned green;
    unsigned blue;
    double size;

    private slots :

       void onOpen();
       void rgbSliderReleased( );
       void pSliderValueChangeed(int value);
       void redSliderValueChangeed(int value);
       void greenSliderValueChangeed(int value);
       void blueSliderValueChangeed(int value);
};
#endif // QTPCLVIEWER_H

main.cpp

#include "qtpclviewer.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QtPclViewer w;
    w.show();
    return a.exec();
}

qtpclviewer.cpp

#include "qtpclviewer.h"
#include "ui_qtpclviewer.h"

QtPclViewer::QtPclViewer(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::QtPclViewer)
{
    ui->setupUi(this);

    initialVtkWidget();
    onOpen();

//    connect(ui.actionOpen, SIGNAL(triggered()), this, SLOT(onOpen()));
    connect(ui->horizontalSlider_Size, SIGNAL(valueChanged(int)), this, SLOT(pSliderValueChangeed(int)));//改变大小
    connect(ui->horizontalSlider_Red, SIGNAL(valueChanged(int)), this, SLOT(redSliderValueChangeed(int)));//颜色改变
    connect(ui->horizontalSlider_Green, SIGNAL(valueChanged(int)), this, SLOT(greenSliderValueChangeed(int)));
    connect(ui->horizontalSlider_Blue, SIGNAL(valueChanged(int)), this, SLOT(blueSliderValueChangeed(int)));
    connect(ui->horizontalSlider_Red, SIGNAL(sliderReleased( )), this, SLOT(rgbSliderReleased( )));//slider滑动
    connect(ui->horizontalSlider_Green, SIGNAL(sliderReleased( )), this, SLOT(rgbSliderReleased( )));
    connect(ui->horizontalSlider_Blue, SIGNAL(sliderReleased( )), this, SLOT(rgbSliderReleased( )));
}

QtPclViewer::~QtPclViewer()
{
    delete ui;
}

void QtPclViewer::initialVtkWidget()
{
    //初始化颜色及大小信息
    red = 255;
    green = 255;
    blue = 255;
    size = 1.0;
    //点云加载
    cloud.reset(new pcl::PointCloud<pcl::PointXYZ>);
    viewer.reset(new pcl::visualization::PCLVisualizer("viewer", false));
    //viewer->addPointCloud(cloud, "cloud");
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud, red, green, blue);//自定义点云颜色
    viewer->addPointCloud<pcl::PointXYZ>(cloud, single_color, "cloud");
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, size, "cloud");//设置点云单个点的大小
    ui->qvtkWidget->SetRenderWindow(viewer->getRenderWindow());
    viewer->setupInteractor(ui->qvtkWidget->GetInteractor(), ui->qvtkWidget->GetRenderWindow());
    ui->qvtkWidget->update();
}
void QtPclViewer::onOpen()
{
    QString fileName = QFileDialog::getOpenFileName(this, "Open PointCloud", ".", "Open PCD files(*.pcd)");
    if (!fileName.isEmpty())
    {
        std::string file_name = fileName.toStdString();
        //sensor_msgs::PointCloud2 cloud2;
        pcl::PCLPointCloud2 cloud2;
        //pcl::PointCloud<Eigen::MatrixXf> cloud2;
        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, cloud2, 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);
        }

        // pcl::io::loadPCDFile("1_over.pcd",*cloud);
        qDebug("cloud->points.size: %ld", cloud->points.size());
        //重新加载点云
        //viewer->updatePointCloud(cloud, "cloud");
        pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud, red, green, blue);//自定义点云颜色
        viewer->updatePointCloud<pcl::PointXYZ>(cloud, single_color, "cloud");
        viewer->resetCamera();
        ui->qvtkWidget->update();
    }
}
void QtPclViewer::rgbSliderReleased()
{
    //更新点云颜色
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud, red, green, blue);
    viewer->updatePointCloud<pcl::PointXYZ>(cloud, single_color, "cloud");
    ui->qvtkWidget->update();
}

void QtPclViewer::redSliderValueChangeed(int value)
{
    red= value;
}
void QtPclViewer::greenSliderValueChangeed(int value)
{
    green= value;
}
void QtPclViewer::blueSliderValueChangeed(int value)
{
    blue= value;
}

void QtPclViewer::pSliderValueChangeed(int value)
{
    size=double(10+value)/10;
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, size, "cloud");//设置点云单个点的大小
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>single_color(cloud, red, green, blue);
    viewer->updatePointCloud<pcl::PointXYZ>(cloud,single_color, "cloud");
    ui->qvtkWidget->update();
}
  • 10
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
以下是使用PCL点云实现基于欧几里得聚类的点云分割算法示例代码: ```c++ #include <iostream> #include <pcl/point_types.h> #include <pcl/filters/extract_indices.h> #include <pcl/segmentation/extract_clusters.h> #include <pcl/kdtree/kdtree.h> int main(int argc, char** argv) { // Load point cloud data pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::io::loadPCDFile("input_cloud.pcd", *cloud); // Create KDTree for efficient nearest neighbor search pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>); tree->setInputCloud(cloud); // Create vector for storing cluster indices std::vector<pcl::PointIndices> cluster_indices; // Create EuclideanClusterExtraction object and set parameters pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec; ec.setClusterTolerance(0.02f); // Maximum distance between points in a cluster ec.setMinClusterSize(100); // Minimum number of points in a cluster ec.setMaxClusterSize(25000); // Maximum number of points in a cluster ec.setSearchMethod(tree); ec.setInputCloud(cloud); // Extract clusters ec.extract(cluster_indices); // Print number of clusters found std::cout << "Number of clusters found: " << cluster_indices.size() << std::endl; // Create ExtractIndices object for each cluster and save to file for (int i = 0; i < cluster_indices.size(); ++i) { pcl::ExtractIndices<pcl::PointXYZ> extract; extract.setInputCloud(cloud); extract.setIndices(boost::make_shared<const pcl::PointIndices>(cluster_indices[i])); pcl::PointCloud<pcl::PointXYZ>::Ptr cluster(new pcl::PointCloud<pcl::PointXYZ>); extract.filter(*cluster); pcl::io::savePCDFile("cluster_" + std::to_string(i) + ".pcd", *cluster); } return 0; } ``` 此代码将从名为“input_cloud.pcd”的文件加载点云数据,使用KDTree进行最近邻搜索并执行欧几里得聚类,最后将每个簇的点保存到单独的PCD文件。聚类的参数(聚类容差、最小/最大簇大小等)可以根据应用程序的需要进行调整。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值