Ubuntu下基于ROS开发QT人机交互界面和PCL点云处理软件

前言:

        博主也是因为工作和兴趣原因,需要开发一套可以人机交互并且处理点云数据的ROS的操作系统和相关功能包。所以潜心研究一周多的相关资料,现在有一些系统性的心得和经验,以此作为记录也供大家参考(该博客永久开放且开源;其中包含的知识点和模块都可以单独作为教程使用)。

废话不多说,我们直接开始正文......

正文:

模块一:ROS安装

说明:

        有两种方式:

        第一是用我自制的shell脚本(ubuntu20.04 安装ros1-noetic版),一键安装。

       第二是用下面详细的每一步安装教程。

安装:

方法一:

1、直接下载我的脚本 安装ROS 提取码: xs66,如果版本不对需要自己更改(网络不好,中间断了需要自己接着做)。

2、终端 bash ros_install.sh

方法二:
1、打开命令终端框。
2、添加ros下载源
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
或者(据说可以提高下载速度)
sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.ustc.edu.cn/ros/ubuntu/ $DISTRIB_CODENAME main" > /etc/apt/sources.list.d/ros-latest.list'
3、添加密钥
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
4、更新软件源
sudo apt update
5、开始安装(noetic版 不是ubuntu20.04 需要换成对应版本)
sudo apt install ros-noetic-desktop-full
####第6-9这里感谢大佬 鱼香肉丝 提供的技术支持
####https://fishros.org.cn/forum/(鱼香ROS社区)
6、安装pip(如果有就不用下载了)
sudo apt-get install python3-pip 
7、下载rosdepc(国内rosdep) 需要网络好,不行就下面两条重复换着用
sudo pip install rosdepc
或
sudo pip3 install rosdepc
8、rosdepc初始化
sudo rosdepc init
9、rosdepc更新
rosdepc update
10、添加barc文件并刷新
echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
source ~/.bashrc

到此,不出问题你就没有问题,注意ROS版本哦。

模块二:Qt安装

说明:

        同样,你可以下载我提供的内容来进行安装(可能会有版本更新和维护问题),也可以根据教程一步步来。

安装:

方法一:

        1、安装Qt 提取码: xs66里面有两个run文件,一般我们只用qt-unified-linux-x64-online.run 但是如果你对另一个已经集成了ROS开发插件的Qt感兴趣的可以自己试试。

        2、终端 bash install.sh (我会帮你下载Qt必要的依赖文件 并调起安装程序)

方法二:

        1、下载Qt .run可执行程序https://download.qt.io/archive/qt/

        选择版本号:

下载对应.run就行了。

        2、下载完了,进如.run文件所在文件夹。

#1、给该程序赋予权限(这个得看你下载的文件名)
sudo chmod 777 qt-unified-linux-x64-online.run
#2、双击qt-unified-linux-x64-online.run(这个得看你下载的文件名)或者在终端输入
./qt-unified-linux-x64-online.run

        3、登陆(注册)、欢迎等一直无脑点就好了

        4、选择组件(博主后面配置VTK8.2 是在Qt5上编译的 所以我选择最后一个Qt5.15.2),我建议Qt5.15.2下面的组件小白全下(不缺那点内存),但是熟悉可以选择一下。

        5、下载过程很漫长(可能和墙和源有关),也可以用其他办法(这里就自己去研究了)。

问题:

安装好后出现打不开的问题:
1、到
/home/xs/Qt/(这前面是你的安装目录)Tools/QtCreator/bin
2、在终端执行:
./qtcreator
3、报错

qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: linuxfb, vkkhrdisplay, xcb, minimal, minimalegl, wayland, wayland-egl, offscreen, vnc, eglfs.

已放弃 (核心已转储)

4、这是缺少xcb库引起的,所以用这个命令查看具体是那些缺少了


ldd /home/xs/Qt/(你的安装目录)Tools/QtCreator/lib/Qt/plugins/platforms/libqxcb.so


not found就是关于xcb所缺失的动态库 一个个下载好就好啦

    linux-vdso.so.1 (0x00007ffff4939000)
    libQt6XcbQpa.so.6 => /home/xs/Qt/Tools/QtCreator/lib/Qt/plugins/platforms/../../lib/libQt6XcbQpa.so.6 (0x00007ffbe3073000)
    libxkbcommon-x11.so.0 => /lib/x86_64-linux-gnu/libxkbcommon-x11.so.0 (0x00007ffbe3029000)
    libxkbcommon.so.0 => /lib/x86_64-linux-gnu/libxkbcommon.so.0 (0x00007ffbe2fe7000)
    libxcb-cursor.so.0 => not found
    libxcb-icccm.so.4 => /lib/x86_64-linux-gnu/libxcb-icccm.so.4 (0x00007ffbe2fe0000)

我这里是
libxcb-cursor.so.0 => not found

5、下载缺少的库

sudo apt install libxcb-cursor0

OK! Qt安装完毕

模块三:ros_qtc_plugin安装

说明:

        前面Qt的链接文件中是包含有一个qtcreator-ros-bionic-latest-offline-installer.run的运行文件,这个是自带ROS开发插件的Qt,不过美中不足的是版本太低只有4.9.2,所以我们必须安装一个针对高版本可以开发ROS的Qt插件(ros_qtc_plugin)。

安装:

方法一:

        1、直接点击下载获得我的网盘资料,不过我这个是针对Qt creator12的版本的(下载完毕后不用解压,直接看方法二的第三点)。

方法二:

        1、由于版本迭代或其他原因导致版本不能对应,那么就需要自己去下载一个对应的插件。首先,先进入Qt creator,点击菜单栏上面帮助-》About Qt creator就可以看到版本号了(我这里就是12.0.0)。

2、进入https://github.com/ros-industrial/ros_qtc_plugin/tags下载插件,选择对应版本(我这里就是12.0),然后点击Downloads,进入后点击ROSProjectManager-12.0-Linux-x86_64.zip开始下载,下载慢的话,那就需要科学上网了。

3、下载完毕后,进入Qt Creator点击菜单栏上面帮助-》关于插件,就可以开始安装插件了。

4、跟着我的图示一步步来:

找到你下载的ZIP包,完了后点下一步,选择在Qt Creator下安装。然后就无脑下一步、完成、重启Qt Creator 就好了。

这个时候,你再进入关于插件可以看到ROSProjectManager了,如果没载入就点一下勾再重启Qt就好了。

这里进去就可以创建和编辑自己的ROS工作空间了。

使用:

1、博主建议是现在终端创建ROS工作空间,再选择:

mkdir Qt_ros
cd Qt_ros
mkdir src
catkin_make
#创建一个Qt_ros/src的目录,然后编译

先看图片,特别是黄色那个框要正确。

选择结束后,就可以开始你的代码之旅了。

改善:

        经博主研究发现,这个插件只能说打开ROS的工作空间,可以识别ROS的文件结构,但是在我这边不能利用Qt创建包、msg、srv等等,所以有两种方式解决。

一、利用传统终端手动创建。

二、安装我上面提到的Qt资源链接里的qtcreator-ros-bionic-latest-offline-installer.run

然后,打开新安装的Qt4.9.2,利用它来创建包或者其他ROS的资源。

就可以开始创建了(其他创包等详细知识就自行了解或联系博主(1874020422@qq.com),这里就不再赘述了)。

模块四:Qt制作ROS人机交互界面

说明:

        本模块将详细介绍,利用Cmakelist将Qt和ROS联合交叉编译来达到Qt制作UI界面以和ROS通讯的目的,博主以UI界面控制小乌龟为例,利用Qt多线程重写run函数和ROS话题通讯机制。其中功能包源码文件点击下载 提取码: xs66。

开发:

步骤:

        1、首先,要像上文所讲建立自己的工作空间;然后建一个ROS包,必须依赖roscpp,这样才功能包会创建src(源码)目录。项目树如下:

        2、这个时候,点击Qt欢迎利用Qt再创建一个项目(Qt Widgets Application),项目名字随便取都可以。

              

OK,这就是这两个项目的项目树:

3、那么这个时候,我们可以双击widget.ui文件,开始设计你的界面布局,当然也可以先拷贝(第4步)到ROS空间的功能包下再编辑。

4、保存后就可以进入你的UI项目文件夹复制到你的ROS空间功能包的src下。

5、重新开关下项目,就得到下图的文件框架。

6、重写CMakeLists.txt文件。

#设置cmake版本号
cmake_minimum_required(VERSION 3.0.2)
#设置项目名称
project(ui)

#寻找ros包 赋予catkin
find_package(catkin REQUIRED COMPONENTS
  roscpp
  turtlesim
  sensor_msgs
  )

#声明联合编译为ros包 不然roslaunch和rosrun调不起
catkin_package()

#打开QT moc(自定义信号和槽函数生成功能生成信号的moc_xxx.cpp文件) RCC(qrc资源文件) UIC(负责处理ui文件,生成对应的ui_xxxx.h文件)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)


#寻找QT包 有QT6就是6 没有就是QT5
find_package(Qt5 COMPONENTS Widgets Core Gui REQUIRED)



#########################################  源码、ui文件和头文件  ################################################
set(SOURCES
    src/widget.ui
    src/widget.cpp
    src/main.cpp
    src/rosnode.cpp
)
#这里可以不设置这个 直接把这两个放在src下编译 也行
set(HEADERS
   include/widget.h
   include/rosnode.h
)

###############################################################################################################

#加载头文件到环境中
include_directories(
    include #当前目录的include
    ${catkin_INCLUDE_DIRS} #ros头文件
)

#源码编译为
add_executable(ui ${SOURCES} ${HEADERS}
)

#链接所有动态链接库
target_link_libraries(ui Qt5::Widgets Qt5::Core Qt5::Gui ${catkin_LIBRARIES})


7、创建一个rosnode类和方法以便开启线程操作后段数据。

8、由于我上面CMakelists.txt文件中是在include文件夹下找头文件,所以:

这两个头文件移动放到include下就好了。

文件结构如下

ok,到这里你就可以简单编译一下,不过你的rosnode.h和rosnode.cpp没有内容,所以自己随便写点吧,便于编译通过。

注意:

        如果有些ROS相关头文件找不到,那么只需要删除工作空间下的bulid和devel文件夹重新编译即可。

项目编写:
源码文件:

1、main.cpp

#include "widget.h"
#include "rosnode.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    ros::init(argc,argv,"ui");
    Widget w; //实例化widget

    Rosnode n; //实例化一个rosnode对象(该类和方法在rosnode.h和rosnode.cpp中实现)
    QObject::connect(&w,&Widget::puba,&n,&Rosnode::geta); //绑定对象信号和槽函数
    QObject::connect(&n,&Rosnode::pubb,&w,&Widget::getb); //绑定对象信号和槽函数
    n.start(); //开启子线程,开始跑rosnode类的run函数

    w.show(); //展示widget页面
    return a.exec(); //阻塞,防止一闪而过
}

2、widget.cpp

#include "widget.h"
#include "ui_widget.h"

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

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

/*
 * 下面五个函数全是对按钮槽函数的实现
 * 在ui设计界面点击你的按钮,鼠标右键转到槽生成
*/
void Widget::on_pb_forword_clicked()
{
    emit puba(1.0,0.0); //抛出 信号 线速度,角速度
}

void Widget::on_pb_back_clicked()
{
    emit puba(-1.0,0.0);
}


void Widget::on_pb_left_clicked()
{
    emit puba(0.0,1.0);
}


void Widget::on_pb_right_clicked()
{
    emit puba(0.0,-1.0);
}


void Widget::on_pb_stop_clicked()
{
    emit puba(0.0,0.0);
}

/***************************************/

/*处理抛出来的ROS位置值*/
void Widget::getb(double x, double y)
{
    ui->label->setText(QString("x:%1 , y:%2").arg(x).arg(y));
}

3、rosnode.cpp

#include "rosnode.h"

void Rosnode::run()
{
    pub=nh.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel",1); //发布话题
    ros::Rate loop(10);  //发布频率10次一秒
    while (ros::ok())
    {
        pub.publish(msg);
        loop.sleep();
        ros::spinOnce();
    }

}

Rosnode::Rosnode()
{
    sub=nh.subscribe("/turtle1/pose",1,&Rosnode::sub_callback,this); //绑定消息回调函数
}

/*有位置消息过来就以信号抛出给主线程了*/
void Rosnode::sub_callback(const turtlesim::Pose::ConstPtr &msg_)
{
    emit this->pubb(msg_->x,msg_->y);
}

/*得到信号传过来的a_和b_的值传给msg的线速度和角速度*/
void Rosnode::geta(double a_ ,double b_)
{
    msg.linear.x=a_;
    msg.angular.z=b_;
}

4、widget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Widget</string>
  </property>
  <widget class="QPushButton" name="pb_forword">
   <property name="geometry">
    <rect>
     <x>360</x>
     <y>180</y>
     <width>89</width>
     <height>25</height>
    </rect>
   </property>
   <property name="text">
    <string>前进</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pb_back">
   <property name="geometry">
    <rect>
     <x>360</x>
     <y>310</y>
     <width>89</width>
     <height>25</height>
    </rect>
   </property>
   <property name="text">
    <string>后退</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pb_right">
   <property name="geometry">
    <rect>
     <x>500</x>
     <y>250</y>
     <width>89</width>
     <height>25</height>
    </rect>
   </property>
   <property name="text">
    <string>右转</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pb_left">
   <property name="geometry">
    <rect>
     <x>230</x>
     <y>250</y>
     <width>89</width>
     <height>25</height>
    </rect>
   </property>
   <property name="text">
    <string>左转</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pb_stop">
   <property name="geometry">
    <rect>
     <x>360</x>
     <y>250</y>
     <width>89</width>
     <height>25</height>
    </rect>
   </property>
   <property name="text">
    <string>停止</string>
   </property>
  </widget>
  <widget class="QLabel" name="label">
   <property name="geometry">
    <rect>
     <x>300</x>
     <y>90</y>
     <width>201</width>
     <height>71</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">background-color: rgb(211, 215, 207);</string>
   </property>
   <property name="text">
    <string>小乌龟位置</string>
   </property>
   <property name="alignment">
    <set>Qt::AlignCenter</set>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>
头文件:

1、widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

signals:
    void puba(double,double); //自定义一个信号,用来传递线速度和角速度(也可以用geometry_msgs::Twist类型,不过需要提前声明)

private slots:
    void on_pb_stop_clicked();

private slots:
    void on_pb_right_clicked();

private slots:
    void on_pb_left_clicked();

private slots:
    void on_pb_back_clicked();

private slots:
    void on_pb_forword_clicked();

public slots:
    void getb(double,double); //自定义一个槽函数,用于接受subb信号传递过来的值 显示乌龟的位置

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

2、rosnode.h

#ifndef ROSNODE_H
#define ROSNODE_H

#include <QThread>
#include "geometry_msgs/Twist.h"
#include "turtlesim/Pose.h"
#include <ros/ros.h>

// 子线程类
class Rosnode : public QThread //继承QThread(线程类)
{
    Q_OBJECT

public:
    void run() override; //重写run函数
    Rosnode();
    void sub_callback(const turtlesim::Pose::ConstPtr &msg_);


    geometry_msgs::Twist msg; //自定义geometry_msgs::Twist消息用于接受、转化、发送给小乌龟
    ros::NodeHandle nh; //定义一个ros节点句柄,用于操作ros方法
    ros::Publisher pub; //话题发布器
    ros::Subscriber sub; //话题订阅器

signals:
void pubb(double,double); //自定义一个信号,用来传递乌龟位置信息(也可以用geometry_msgs::Twist类型,不过需要提前声明)

public slots:
    void geta(double,double); //自定义一个槽函数,用于接受puba信号传递过来的值

};

#endif // ROSNODE_H
运行:

1、可以自己编写一个launch文件来启动小乌龟和自己的ui软件,也可以一个个运行。

2、不论那种方式先刷新自己创建的工作空间,终端cd进入你的工作空间目录。

#注意这里是你的工作空间
cd /home/xs/xs_ws
#刷新工作空间
source devel/setup.bash 

3、运行launch文件:

        一、编写launch:

                a、在你的功能包下建立launch文件夹,在launch文件夹下建立ui.launch文件。

                b、编写文件:

                

<launch>
<!--name 在ros下注册的名字 pkg 包名 type 节点(可执行程序)名 output 打印信息输出位置 required 死亡关闭所有其他节点-->
    <node name="ui" pkg="ui" type="ui" output="screen" required="true"/>
    <node name="turtlesim_node" pkg="turtlesim" type="turtlesim_node" output="screen"/>
</launch>

                c、再利用第2步刷新环境后,在终端:

roslaunch ui ui.launch
#ui 包名   ui.launch 文件名

        二、直接运行:

                a、刷新环境后。

                b、建立三个终端,分别输入下面三条指令

roscore
rosrun ui ui
rosrun turtlesim turtlesim_node
效果:

        

至此,Qt制作ROS人机交互界面的关键功能就打通了。

模块五:Qt配置PCL、VTK显示点云

说明:

        该模块讲述在Qt下配置PCL和VTK显示点云并为点云视觉处理(滤波、平滑、拟合等)留下开发环境,主要是很多文章说直接生成的一个iso文件放到Qt目录下对现在的Qt版本感觉不适用,所以博主采取编译源码结合Qt预留的OPENGL窗口做开发,博主推荐下载我的资料,一键编译安装。链接 提取码: xs66。

安装:

方法一:

操作方式:

        1、将下载的压缩包放到任意位置,解压后进入VTK_PCL_INSTALL。

        2、进入script,打开build_vtk.sh,把下面两行修改为你对应的Qt安装的位置,我这里帮你安装在/usr/loocal下(最好别更改,不然后面你不一定知道在那儿了)。

        3、回到VTK_PCL_INSTALL目录下,鼠标右键-》在终端打开-》输入:

bash install.sh

        4、需要输密码和输y的输入以下,开始等待(过程前半部分需要联网,后面编译看电脑性能了哦)。

5、完成后可以在你的/usr/loocal的include和lib下找到vtk8.2和pcl1.13了。

方法二:

1、先去VTK和PCL官网下载对应版本的包,建议自己查一下版本对应关系(我是Ubuntu20.04+Qt5.15.2+VTK8.2+PCL1.13);VTK下载地址PCL下载地址 

2、对源码包解压后,在vtk和pcl对应源码文件夹中都新建build文件夹,再在build文件夹中建立对应的脚本文件(这步主要是为了配置cmake编程生成的makefile文件的一些配置参数,也可以通过下载cmake_gui来可视化配置(不推荐,博主试了很久都没成功,当然我会简单提一下下载方法))。

A(不推荐):

        cmake_gui 下载和运用(不用这个方式就不用下载,这个方式具体可参考这个文章来配置):

sudo apt-get install cmake-qt-gui
sudo cmake-gui

B(推荐):

        VTK下的build的脚本:build.sh(注意中间QT的安装位置我是/home/xs/Qt/,可以先去对应文件夹下看看有没有qmake和cmake  DCMAKE_INSTALL_PREFIX后面是编译后安装的位置)

cmake ../ -G "Unix Makefiles" \
-DVTK_USE_QVTK:BOOL=ON \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DVTK_USE_GUISUPPORT:BOOL=ON \
-DVTK_QT_VERSION:STRING=5 \
-DQT_QMAKE_EXECUTABLE:PATH=/你QT的安装位置/5.15.2/gcc_64/bin/qmake \
-DVTK_Group_Qt:BOOL=ON \
-DCMAKE_PREFIX_PATH:PATH=/你QT的安装位置/5.15.2/gcc_64/lib/cmake  \
-DCMAKE_BUILD_TYPE=RELEASE \
-DBUILD_SHARED_LIBS:BOOL=ON

        PCL下的build的脚本:build.sh

cmake ../ -G "Unix Makefiles" \
-DCMAKE_BUILD_TYPE=None \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DBUILD_GPU=ON \
-DBUILD_apps=ON \
-DBUILD_examples=ON ..

        在VTK和PCL的build文件夹下分别都运行对应脚本,就会会在build文件夹下生成很多文件

bash build.sh

3、先去VTK的build文件夹下执行

make -j8
# 可以 不加 -j8 j后面的数字是编译时可以调用的内核数 越多编译越快 但是要适量

        编译完后,安装(如果上面安装位置没更改就安装在/usr/local/,不然安装在更改的位置下)

sudo make install
#由于要安装到 /usr/local/下所以需要sudo

4、再去PCL的build下执行

make -j8
# 可以 不加 -j8 j后面的数字是编译时可以调用的内核数 越多编译越快 但是要适量

        编译完后,安装(如果上面安装位置没更改就安装在/usr/local/,不然安装在更改的位置下)

sudo make install
#由于要安装到 /usr/local/下所以需要sudo

5、完成后可以在你的/usr/loocal或者你自定义的目录下的include和lib下找到vtk和pcl了。

注意:

        如果提示编译错误的原因是缺包的话,那就下载依赖文件,我遇到的一般是缺失这几个包。

sudo apt-get update

sudo apt-get install libxt-dev libqt5x11extras5-dev qttools5-dev

sudo apt-get install git build-essential cmake cmake-gui libflann1.9 libflann-dev libeigen3-dev libboost-all-dev

配置:

当你安装完毕PCL和VTK后,你就可以开始做我们的在Qt上显示点云的事啦。

1、打开Qt创建一个桌面项目,并双击UI文件来打开设计器。

然后,项目名、下一步......

项目创建后:

2、创建OPENGL绘制窗口(为PCL中VTK绘图提供接口)

提升的类名称:QVTKOpenGLNativeWidget

头文件:QVTKOpenGLNativeWidget.h

好,到此你就有一个OPENGL窗口了,记得保存一下,我们将会去编辑.pro文件了

3、配置.pro文件引入VTK和PCL包。

具体的.pro文件qmakelist文件的内容我放在下方了,可以根据自己项目更改。

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h

FORMS += \
    widget.ui

#引入VTK和PCL等include和lib文件
INCLUDEPATH += /usr/include/eigen3

INCLUDEPATH += /usr/local/include/vtk-8.2
LIBS += /usr/local/lib/libvtk*.so

INCLUDEPATH += /usr/local/include/pcl-1.13
LIBS += /usr/local/lib/libpcl_*.so
###################################


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

OK!恭喜你,你的环境已经配好啦,可以开始编写代码了。

项目编写:

        项目文件下载,提取码:xs66

源码文件:

main.cpp

#include "widget.h"

#include <QApplication>

/*屏蔽内容为解决报opengl版本过低的问题*/
// #include <QSurfaceFormat>
// #include "QVTKOpenGLNativeWidget.h"


int main(int argc, char *argv[])
{
    // QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat());
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include "QFileDialog"


boost::shared_ptr<pcl::visualization::PCLVisualizer> view;
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);


    //vtkSmartPointer vtk智能指针
    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();//渲染器
    vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();//一般的opengl渲染窗口
    renderWindow->AddRenderer(renderer);
    view.reset(new pcl::visualization::PCLVisualizer(renderer,renderWindow,"viewer",false));

    ui->openGLWidget->SetRenderWindow(view->getRenderWindow());
    view->setupInteractor(ui->openGLWidget->GetInteractor(),ui->openGLWidget->GetRenderWindow());//交互器 渲染器


    ui->openGLWidget->update();
}

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

void Widget::on_pushButton_clicked()
{

    //读取pcd文件并显示
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());//创建点云指针
    QString fileName = QFileDialog::getOpenFileName(this, "选择点云", ".", "打开PCD点云(*.pcd)");
    if(fileName == "") return;
    pcl::io::loadPCDFile(fileName.toStdString(),*cloud);
    pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> fildColor(cloud, "y");
    view->addPointCloud<pcl::PointXYZ>(cloud, fildColor,"cloud");
    //view->addPointCloud(cloud,"cloud");
    view->resetCamera();    //视角
    ui->openGLWidget->update();
    ui->openGLWidget->GetRenderWindow()->Render();//防止鼠标点击点云才出来
}

头文件:
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>


/*具体内容参考pcl官网和其他pcl教程
#include <vtkRenderWindow.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/point_types.h>//各种格式的点的头文件
#include <pcl/io/pcd_io.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <pcl/visualization/keyboard_event.h>
#include <vtkAutoInit.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/features/normal_3d.h>
#include <pcl/surface/gp3.h>      //贪婪投影三角化算法
#include <pcl/filters/passthrough.h>
*/

#include <vtkRenderWindow.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/point_types.h>//各种格式的点的头文件
#include <pcl/io/pcd_io.h>
#include <vtkGenericOpenGLRenderWindow.h>

QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

运行:

        直接Ctrl+s、Ctrl+b、Ctrl+r再来一个运行,或者点击编译(锤子符号)、运行(绿色三角形)。

效果:

OK!!!

到此,就完事啦。

总结:

        博主研究这一个大板块花费了很多心思和时间,同时也阅读了很多书籍和文章,感谢平台和其他相关文章博主的支持,同时我想说:人生路漫漫,唯有学习可以一直长伴你左右;仁兄加油吧,活到老,学到老。

持续关注博主,将会更新PCL的滤波、平滑、拟合(贪婪三角化)等点云操作方法

  • 26
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值