上位机图像处理和嵌入式模块部署(树莓派4b与视觉slam十四讲)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        实际使用中,树莓派4b是非常好的一个基础平台。本身板子价格也不是很贵,建议大家多多使用。之前关于vslam,也就是视觉slam,有一本书很火,叫《视觉slam十四讲》。它里面就谈到了很多第三方库的安装,这些库其实都是可以在树莓派4b上面运行的。这样有了4b这样的开发板,大家就不需要反复打开和关闭虚拟机来运行linux了。

1、安装cmake

        cmake本身树莓派4b是不带的,但是slam的一些第三方库编译需要它,所以直接sudo安装,

sudo apt-get install cmake

2、《视觉slam十四讲》github代码

        很多同学只看书不实操,这是不对的。针对书中代码部分,是要反复研习的。好在作者提供了相应的github地址,

https://github.com/gaoxiang12/slambook

3、安装eigen库

        eigen是很基础的矩阵库,里面的加、减、乘、除、求逆、转置,我们都会用到。这里也是同样的直接用sudo安装的,

sudo apt-get install libeigen3-dev

        安装好之后,就可以用一个十四讲里面的demo代码验证一下,

g++ eigenMatrix.cpp -I/usr/include/eigen3 -g -o eigenMatrix

4、安装sophus库

        十四讲里面的sophus库是非模板类,我们使用的sophus库是基于模板类的,就是这一点小小的区别。代码下载的地址如下所示,选择默认分支即可,

https://github.com/strasdat/Sophus

        有了代码,下面就可以准备编译了,

(a) 删除CMakeLists.txt中的-Werror
(b) sudo apt-get install libfmt-dev
(b) make build, cd build, cmake ..
(c) make
(d) sudo make install

        编译过程不算复杂,就是在4b上面编译的时间比较长一点。最后,因为我们安装的sophus库是基于模板类的,所以只能从其他地方找demo代码编译,比如这里,

https://www.cnblogs.com/xkbl-blogs/p/14458669.html

        编译的话,可以直接用g++编译,

g++ demo.cpp -I/usr/include/eigen3 -I/usr/local/include -g -o demo -lfmt

        本身sophus库是用来解决李群、李代数的问题。而李群、李代数又是为了解决矩阵求导的问题,大家把它当成一个数学工具,记住结论并且会解决问题就好。至于推导的过程,暂时看不懂,也没有关系。

        当然,如果大家还是想使用之前十四讲sophus的demo测试代码,其实修改下就好了,

#include <iostream>
#include <cmath>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include "sophus/se3.hpp"

using namespace std;
using namespace Eigen;

/// 本程序演示sophus的基本用法

int main(int argc, char **argv) {

  // 沿Z轴转90度的旋转矩阵
  Matrix3d R = AngleAxisd(M_PI / 2, Vector3d(0, 0, 1)).toRotationMatrix();
  // 或者四元数
  Quaterniond q(R);
  Sophus::SO3d SO3_R(R);              // Sophus::SO3d可以直接从旋转矩阵构造
  Sophus::SO3d SO3_q(q);              // 也可以通过四元数构造
  // 二者是等价的
  cout << "SO(3) from matrix:\n" << SO3_R.matrix() << endl;
  cout << "SO(3) from quaternion:\n" << SO3_q.matrix() << endl;
  cout << "they are equal" << endl;

  // 使用对数映射获得它的李代数
  Vector3d so3 = SO3_R.log();
  cout << "so3 = " << so3.transpose() << endl;
  // hat 为向量到反对称矩阵
  cout << "so3 hat=\n" << Sophus::SO3d::hat(so3) << endl;
  // 相对的,vee为反对称到向量
  cout << "so3 hat vee= " << Sophus::SO3d::vee(Sophus::SO3d::hat(so3)).transpose() << endl;

  // 增量扰动模型的更新
  Vector3d update_so3(1e-4, 0, 0); //假设更新量为这么多
  Sophus::SO3d SO3_updated = Sophus::SO3d::exp(update_so3) * SO3_R;
  cout << "SO3 updated = \n" << SO3_updated.matrix() << endl;

  cout << "*******************************" << endl;
  // 对SE(3)操作大同小异
  Vector3d t(1, 0, 0);           // 沿X轴平移1
  Sophus::SE3d SE3_Rt(R, t);           // 从R,t构造SE(3)
  Sophus::SE3d SE3_qt(q, t);            // 从q,t构造SE(3)
  cout << "SE3 from R,t= \n" << SE3_Rt.matrix() << endl;
  cout << "SE3 from q,t= \n" << SE3_qt.matrix() << endl;
  // 李代数se(3) 是一个六维向量,方便起见先typedef一下
  typedef Eigen::Matrix<double, 6, 1> Vector6d;
  Vector6d se3 = SE3_Rt.log();
  cout << "se3 = " << se3.transpose() << endl;
  // 观察输出,会发现在Sophus中,se(3)的平移在前,旋转在后.
  // 同样的,有hat和vee两个算符
  cout << "se3 hat = \n" << Sophus::SE3d::hat(se3) << endl;
  cout << "se3 hat vee = " << Sophus::SE3d::vee(Sophus::SE3d::hat(se3)).transpose() << endl;

  // 最后,演示一下更新
  Vector6d update_se3; //更新量
  update_se3.setZero();
  update_se3(0, 0) = 1e-4;
  Sophus::SE3d SE3_updated = Sophus::SE3d::exp(update_se3) * SE3_Rt;
  cout << "SE3 updated = " << endl << SE3_updated.matrix() << endl;

  return 0;
}

5、安装opencv

        这部分虽然前面的文章提供了相应的步骤,这里不妨重新温习一下。安装方法就是直接sudo安装,

sudo apt-get install libopencv-dev

        编译方法就是用g++编译,不过要添加上头文件和lib文件,

g++ imageBasics.cpp -o imagesBasics -I /usr/include/opencv4/ -L /usr/lib/ -lopencv_core -lopencv_imgcodecs -lopencv_highgui -lopencv_imgproc

6、ceres库

        ceres和下面要讲的g2o都是一种数据优化方法。一般来说,我们构建好一个损失函数之后,都不是通过数学方法直接计算的,大部分情况都是通过优化方法步步逼近解决的。如果不使用优化方法,指望穷举来找到最优值,花费的时间就太多了,无法满足实时处理的要求。

        好在ceres可以直接用sudo安装,这样方便一点,

sudo apt-get install libceres-dev

        安装后,就可以在/usr/include和/lib/aarch64-linux-gnu下面看到相应的头文件、lib文件了。这个时候就可以用g++直接编译了,

g++ main.cpp -o main -I/usr/include/opencv4/ -I/usr/include/eigen3  -I/usr/local/include -L/usr/lib/ -lopencv_core -lopencv_imgcodecs -lopencv_highgui -lopencv_imgproc -lceres -lglog

7、g2o库的编译和使用

        g2o,也就是图优化,是目前用的比较多的一种优化方法。因为没有通过sudo apt-cache search找到对应的安装库,所以就自己下载代码来处理了。代码可以从这个地方下载,

https://github.com/RainerKuemmerle/g2o

        编译也没有什么复杂的,整个过程除了时间长一点,没有遇到什么困难,

(a) 解压文件
(b) mkdir build
(c) cd build 
(d) cmake ..
(e) make
(f) make install

        安装好了库之后,接下来就可以编译、运行示例程序了。编译时,就是选项多了一点,其他都还好,

g++ main.cpp -o main -I/usr/include/opencv4/ -I/usr/include/eigen3  -I/usr/local/include -L/usr/lib/ -lopencv_core -lopencv_imgcodecs -lopencv_highgui -lopencv_imgproc -lg2o_core -lg2o_stuff

        最后运行的时候,我们发现找不到动态库,这个时候就要重新配置一下LD_LIBRARY_PATH,

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

        至此,g2o也算是用起来了。

8、总结

        当然,不光上面这些内容,树莓派4b还有可能安装一些其他的内容,比如说qt、ros、pcd点云库等等。不管是什么需求,我们努力去安装就好了,逢山开路、遇水搭桥,只有用树莓派4b解决越来越多的专业问题,才能体现我们软件的价值所在,而不是在低端的领域反复做一些造轮子的事情。

        十四讲的1-6章非常重要,在作者的另外一本书《自动驾驶与机器人的slam技术》中也大量使用,有兴趣的同学可以去看看,会有不少的收获。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode刷题-(36~40)-Java

算法是码农的基本功&#xff0c;也是各个大厂必考察的重点&#xff0c;让我们一起坚持刷算法题吧。 遇事不决&#xff0c;可问春风&#xff0c;春风不语&#xff0c;即是本心。 我们在我们能力范围内&#xff0c;做好我们该做的事&#xff0c;然后相信一切都事最好的安排就可…

深入理解Python协程:从基础到实战

title: 深入理解Python协程&#xff1a;从基础到实战 date: 2024/4/27 16:48:43 updated: 2024/4/27 16:48:43 categories: 后端开发 tags: 协程异步IO并发编程Pythonaiohttpasyncio网络爬虫 第1章&#xff1a;协程基础 1.1 协程概念介绍 协程&#xff08;Coroutines&…

【科学研究】读博:一场精神赌博❓

::: block-1 “时问桫椤”是一个致力于为本科生到研究生教育阶段提供帮助的不太正式的公众号。我们旨在在大家感到困惑、痛苦或面临困难时伸出援手。通过总结广大研究生的经验&#xff0c;帮助大家尽早适应研究生生活&#xff0c;尽快了解科研的本质。祝一切顺利&#xff01;—…

C++必修:类与对象(一)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C学习 贝蒂的主页&#xff1a;Betty’s blog 1. 面向过程与面向对象 1.1. 面向过程 我们之前学习的C语言就是一种面向过程的语…

java中http调用组件深入详解

目录 一、前言 二、http调用概述 2.1 什么是http调用 2.1.1 http调用步骤 2.2 HTTP调用特点 2.3 HTTP调用应用场景 三、微服务场景下http调用概述 3.1 微服务开发中http调用场景 3.2 微服务组件中http的应用 四、常用的http调用组件 4.1 java中常用的http组件介绍 4…

用 Python 创建 Voronoi 图

概述 最常见的空间问题之一是找到距离我们当前位置最近的兴趣点 (POI)。假设有人很快就会耗尽汽油&#xff0c;他/她需要在为时已晚之前找到最近的加油站&#xff0c;解决这个问题的最佳解决方案是什么&#xff1f;当然&#xff0c;驾驶员可以检查地图来找到最近的加油站&…

力扣每日一题-总行驶距离-2024.4.25

力扣题目&#xff1a;总行驶距离 题目链接: 2739.总行驶距离 题目描述 代码思路 直接用数学模拟计算即可 代码纯享版 class Solution {public int distanceTraveled(int mainTank, int additionalTank) {int sum 0;while(additionalTank > 0){if(mainTank > 5){mai…

CATO原理中的数学与魔术(六)——Baby Hummer的拓展一

在上一篇中&#xff0c;我们从CATO原理的数学讲解进入了魔术部分&#xff0c;介绍了其经典作品《Baby Hummer》&#xff0c;相关内容请戳&#xff1a; CATO原理中的数学与魔术&#xff08;五&#xff09;——Baby Hummer CATO原理中的数学与魔术&#xff08;四&#xff09;——…

leetcode 221 最大正方形面积

示例 3&#xff1a; 输入&#xff1a;matrix [["0"]] 输出&#xff1a;0 # 最大正方形面积 def max_square(matrix):m len(matrix)n len(matrix[0])if m 0 or n 0::return Nonemax_side 1dp [[0] * (n 1) for _ in range(m 1)]for i in range(1, m 1):fo…

2024全新瀚海跑道:矢量图片迅速养号游戏玩法,每天一小时,日转现200

最初我注意到这种玩法&#xff0c;是因为最近在浏览各大平台的视频时&#xff0c;我发现了一种特殊类型的账号&#xff0c;其养号成功率高达90%。这些账号发布的视频内容和数据非常夸张&#xff0c;而且制作起来非常简单&#xff0c;任何人都可以轻松上手。这些账号主要发布矢量…

Spring Web MVC入门(2)——请求

目录 一、传递单个参数 基础类型和包装类型的区别 1、基础类型 &#xff08;1&#xff09;不传参 &#xff08;2&#xff09;传字符串 2、包装类型 &#xff08;1&#xff09;不传参 &#xff08;2&#xff09;传字符串 3、小结 二、传递多个参数 三、传递对象 四、…

Leetcode_相交链表

✨✨所属专栏&#xff1a;LeetCode刷题专栏✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ 题目&#xff1a; 题解&#xff1a; 看到这个题目首先我们要排除链表逆置的想法&#xff0c;如图、因为c1节点只有一个next指针&#xff0c;逆置后不可能同时指向a2和b3节点。 其次有的的同学…

阿里前端常考vue面试题汇总_阿里高级vue面试题

改变 ![](https://img-blog.csdnimg.cn/img_convert/b736620bcd29f08f3685022ab5583d8b.webp?x-oss-processimage/format,png)你会发现&#xff0c; **只有改变的栏目才闪烁&#xff0c;也就是进行重绘** &#xff0c;数据没有改变的栏目还是保持原样&#xff0c;这样就大大节…

WebSocket 深入浅出

WebSocket 深入浅出 1. WebSocket 是什么2. WebSocket 建立连接通信的过程3. WebSocket 和http的联系与区别4. WebSocket 的使用场景及限制 1. WebSocket 是什么 定义&#xff1a;WebSocket 是一种网络通信协议&#xff0c;它允许在单个TCP连接上进行全双工通信。是HTML5规范提…

网络安全实训Day15

写在前面 电子垃圾&#xff0c;堂堂恢复连载。本来不想分天数梳理了&#xff0c;但是最后要写实训报告&#xff0c;报告里还要有实训日记记录每日学的东西&#xff0c;干脆发这里留个档&#xff0c;到时候写报告提供一个思路。 网络空间安全实训-渗透测试 渗透测试概述 定义 一…

关于conda占C盘内存的问题

文章目录 前言一、C盘中.conda文件中的envs二、C盘中.conda文件中的pkgs 前言 最近发现C盘空间越来越少&#xff0c;于是就去清理了一下conda在C盘的存储&#xff0c;不看不知道&#xff0c;一看吓一跳&#xff0c;足足十几G&#xff01;于是去网上搜索了相关的包能不能删除&a…

(3)C程序可执行文件的生成过程

原文链接&#xff1a;https://www.jianshu.com/p/b7e44f749211 一、可执行文件的生成 我们先通过一个简单C程序&#xff0c;回顾一下可执行文件的生成过程。 ​​​​​​​ ​​​​​​​ 可执行文件的生成过程如下图&#xff1a; 如图&#xff0c;可执行文…

------分割线之 WebSecurityConfigrerAdapter弃用问题------

WebSecurityConfigurerAdapter 被弃用的原因是 Spring Security 项目的维护者希望将项目的主要开发工作集中在新的配置方式上&#xff0c;即基于 Java 的配置&#xff08;Java Configuration&#xff09;和基于 Lambda 的表达式。这主要是因为 Spring 5.0 引入了重量级的 Java …

Windows系统下使用MySQL8.0.22创建第二套数据库

配置新的 MySQL 实例&#xff1a; 为了创建一个新的数据库实例&#xff0c;你需要复制 MySQL 的安装目录并创建一个新的数据目录和配置文件。假设你已经安装了 MySQL 在 C:\Program Files\MySQL\ 下&#xff0c;按照以下步骤操作&#xff1a; 复制整个 MySQL 文件夹&#xff0c…

【探索Java编程:从入门到入狱】Day2

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…