[学习SLAM]Quaternion 插值/ 用四元数插值来对齐IMU和图像帧

2023-05-16

小白:师兄,好久没见到你了啊,我最近在看IMU(Inertial Measurement Unit,惯性导航单元)相关的东西,正好有问题求助啊

师兄:又遇到啥问题啦?

小白:是这样的,现在VIO(Visual-Inertial Odometry,视觉惯性里程计)很火,我就想试试把IMU测量的信息和图像进行简单的融合,这样利用IMU测量的先验信息,可以给图像一个比较好的初值。。。

师兄:嗯嗯,这个思路没问题的啊,图像信息和 IMU 确实存在一定互补性,两者各有所长,取长补短。

小白:是滴,我也是这样想的,不过我采集了图像和IMU的数据后,发现IMU输出频率好高啊,远远大于图像帧率!

师兄:没错,IMU本身就是惯性传感器,用来测量角速度和加速度,对短时快速运动很敏感,因此帧率很高才能测量到,所以一般是100Hz以上。而我们图像传感器输出帧率一般比较低,15 - 60Hz 居多~

小白:那就有问题了啊,我想要把IMU测量的值和图像估计的值进行对齐,这样我就能根据当前IMU输出的旋转量来作为图像预测的初值了,现在帧率差这么多,这个怎么对齐呢?

师兄:你是用什么来表达的旋转?

小白:四元数,我看网上都说用四元数好,不过不知道为啥(/尴尬)

四元数的优势

师兄:四元数确实在对姿态的描述具有独特的优势,非常适合用来表示空间中的旋转。这主要是因为几个原因:

1、四元数解决了其他3维空间旋转算法会遇到的恼人的问题,比如使用欧拉角来表示旋转操作时会遇到的万向节锁问题(Gimbal lock)。见下图

2、计算效率比旋转矩阵方法高,因为表达四元数只需要4个数,旋转矩阵需要9个。

3、其简单的数学表达方式可以被用来规划出高阶连续姿态运动以及在多姿态间插值。这里的插值就可以解决你说的对齐问题啦

小白:原来如此,看来我选择四元数表示是非常正确的!不过我有个疑问,师兄,什么是插值啊?

什么是插值?

师兄:插值对应的英文是interpolation ,是数学上的一个常用术语。下面是维基百科的专业解释

数学的数值分析领域中,插值是一种通过已知的、离散的数据点,在一定范围内推求新数据点的过程或方法。求解科学和工程的问题时,通常有许多数据点借由采样、实验等方法获得,这些数据可能代表了有限个数值函数,其中自变量的值。而根据这些数据,我们往往希望得到一个连续的函数(也就是曲线);或者更密集的离散方程与已知数据互相吻合,这个过程叫做拟合。插值是曲线必须通过已知点的拟合。

小白:师兄,你说的每个字我都认识,但是连在一起完全不知道啥意思啊!

师兄:没关系,为了严谨定义一般都比较晦涩难懂。插值,讲一个通俗但不严谨的例子,比如现在有10只大雁(对应已有的样本)排成一定的阵列在飞,让你在第5、6只大雁中间(原来没有样本的插值点)再插入一只大雁,但是要保证插队后的大雁在整体中不能太突兀,要显得比较“合群”(对应拟合曲线),如果其他大雁飞人字形,插入的大雁尽量要保持整体仍是人字形;如果其他大雁飞一字形,插入的大雁尽量要保持整体仍是一字形。

小白:师兄,你早这么说,我不就明白啦!那一般怎样插值呢?

师兄:嗯,以后多举例子。插值方法有很多种,比如最简单的最邻近插值(nearest interpolation)、线性插值(linear interpolation);常用的双线性插值(Bilinear interpolation),还有保护图像细节效果较好的双三次插值(bicubic interpolation)、三次样条插值(cubic Spline Interpolation)等。

千言万语汇成一个图,如下图是一维和二维插值的比较。黑色表示待计算的插值点,其他颜色的点表示样本点。

小白:看晕了都。那这么多插值方法,我们用哪种呢?

师兄:在图像处理和计算机视觉领域,应用比较多的双线性插值。双线性插值的效果不是最好的,但相较最邻近插值和线性插值的简单粗暴,其获得图像的效果还是更令人满意的,而且双线性插值的计算量和易于理解程度会优于双三次插值和三次样条插值等高阶插值方法。因此双线性插值还是最受广大图像研究者喜爱的。

小白:师兄,可以举个具体的例子吗?还是不太明白插值的具体应用呢!

师兄:嗯,那就再举个栗子吧,比如我们常见的针孔相机成像就是一种射影变换,下图中一个矩形src经过相机拍摄后成像变为了dst,此时我们拿到了dst图像中的像素点,如果想要用得到的dst图像来恢复原始的src图像,就需要用到射影变换和插值。

当我们要对图像进行插值操作的时候,通常需要遍历dst中的每一个像素点,假设dst中某像素点为p(x0,y0),对像素点p进行相应变换,使其对应到原图src中的p’(x0’,y0’)点。在我们遍历dst像素的时候, p点的像素值(x0,y0)都是整数,然而变换后对应到原图src中的p’点的像素值(x0’,y0’)就不一定是整数了。

小白:图中的p'点就是插值点吧?

师兄:对!将src中p’附近的内容放大,我们可以发现p’ (x0’,y0’)点落在了(x1,y1), (x1+1,y1), (x1+1,y1+1), (x1,y1+1)四个相邻点中间。我们要做的,就是要利用(x1,y1), (x1+1,y1), (x1+1,y1+1), (x1,y1+1)这几个整数点的像素值来计算p’ (x0’,y0’)这个非整数点的像素值,再用src中p’ (x0’,y0’)的像素值表示dst中p(x0,y0)的像素值。这个就是插值啦!关于这部分内容网上很多资料,也不是今天的重点,这里就不详细介绍了,今天重点是介绍四元数插值~

小白:嗯嗯,我回头去查查看双线性插值。有点跑偏了,我们还是回到四元数插值的讨论吧~

四元数有哪些插值方法?

师兄:好,其实四元数插值的思路也和上面类似,常见的有线性插值、球面线性插值等。我们从简单的说起。

先说说最简单的线性插值(Linear Interpolation,简称Lerp)

假设有两个四元数 q0,q1,想要在位置 t 处求插值 qt,用线性插值可以这样计算,是不是很熟悉?

小白:是啊,感觉这个非常简单啊,那我就用这个插值好了!

师兄:四元数的线性插值是非常简单,但是是有代价的。如下图所示,四元数表示旋转时是单位四元数,这种插值方式,相当于我们是沿着一条直线(也就是圆上的一个弦)进行插值的,这样插值出来的四元数不是单位四元数,而且还有其他问题(后面会说)。

小白:那我归一化一下就行了吧?

师兄:你说的就是归一化线性插值(Normalized LinearInterpolation,简称Nlerp),前面说过Lerp这样插值出来的并不是单位四元数,但如你所说,只要将 qt 除以它的模 ||qt||就能够 将其转化为一个单位四元数了:

小白:嗯,那就这样进行四元数插值吧,看起来也不是很复杂哈!

师兄:且慢!还是有其他问题的。如下图所示,在同等时间内, vt 扫过的⻆度是不同的, vt 扫过的速度(或者说⻆速度)首先会不断地增加,到t = 0.50之后会开始减速,所以Nlerp插值不能保证均匀的⻆速度。

小白:那怎么办呢?

师兄:为了解决这个问题,我们可以转而对⻆度进行线性插值。这就要使用更复杂一些的插值方法了,比如常用的球面线性插值(Spherical Linear Interpolation),简称Slerp。Slerp插值可以解决前面的均匀角速度问题,它能够保证 每两个四元数之间的⻆速度是固定的,这就从原理上保证了插值的效果。如下图所示,如果 v1 和 v2 之间的夹⻆为 θ,那么:

小白:那这个四元数怎么计算呢?

师兄:计算也不复杂,主要是利用三角形、三角函数性质。证明过程我们就不推导了,直接给出以下结论。当然如果你对结果有疑问,也可以自己推导一遍~

小白:不,不,我相信这个结论,推导的事情前人已经做过了,我就不重复造轮子了,哈哈,用过的时候直接套公式就行了吧!

师兄:理论上是这样的,不过,在编程实现Slerp插值的时候还是有几个问题需要注意一下。

1、如果单位四元数之间的夹角θ非常小,那么sin(θ)可能会由于浮点数的误差被近似为0.0,从而导致除以0的错误.所以,我们在实施 Slerp 之前,需要检查两个四元数的夹角是否过小(或者完全相同)。一旦发现这种问题,我们就必须改用 Nlerp 对两个四元数进行插值,这时候 Nlerp 的误差非常小,所以基本不会与真正的 Slerp 有什么区别。

2、在对两个单位四元数进行插值之前,我们需要先检测q0与q1之间是否是钝角,即检测它们点积的结果q0⋅q1 是否为负数。如果 q0⋅q1<0,那么我们就反转其中的一个四元数,比如说将q1改为−q1 ,并使用q0与−q1之间新的夹角来进行插值,这样才能保证插值的路径是最短的.

小白:哇塞,太中肯的建议了!可以少踩好多坑,谢谢师兄,我要去编程啦!

师兄:哈哈,别着急,这个方法可行,但是编程稍微复杂点,计算量也大,还有一种实现四元数的球面插值计算方式,要简单很多,留给你当做作业练习啦,搞定作业,你就可以直接用来做Slerp插值啦!

编程练习

作业练习1:前面四元数球面线性插值方法比较复杂,下面是它的简化版求解方法,请证明。

假设v0, v1是两个四元数,其夹角为θ,假设在它们中间进行四元数插值结果为v',v'和v1之间夹角为θ‘ < θ,记v⊥是垂直于v1的四元数向量,证明:

v'=v1cosθ' + v⊥sinθ'

作业练习2:编程实现四元数球面线性插值。

我们用智能手机采集了图像序列和IMU数据,由于IMU帧率远大于图像帧率,需要你用Slerp方法进行四元数插值,使得插值后的IMU和图像帧对齐。

已知某帧图像的时间戳为:t =700901880170406

离该图像帧最近的前后两个时刻IMU时间戳为:t1 = 700901879318945,t2 = 700901884127851

IMU在t1, t2时刻测量得的旋转四元数为:

q1x=0.509339, q1y=0.019188, q1z=0.049596, q1w=0.858921

q2x=0.509443, q2y=0.018806, q2z=0.048944,q2w=0.858905

根据上述信息求IMU对齐到图像帧的插值后的四元数。

参考结果已经给出。

Quaternion 插值
线性插值
最简单的插值算法就是线性插值,公式如:
    q(t)=(1-t)q1 + t q2
但这个结果是需要规格化的,否则q(t)的单位长度会发生变化,所以


    q(t)=(1-t)q1+t q2 / || (1-t)q1+t q2 ||


球形线性插值
尽管线性插值很有效,但不能以恒定的速率描述q1到q2之间的曲线,这也是其弊端,我们需要找到一种插值方法使得q1->q(t)之间的夹角θ是线性的,即θ(t)=(1-t)θ1+t*θ2,这样我们得到了球形线性插值函数q(t),如下:


q(t)=q1 * sinθ(1-t)/sinθ + q2 * sinθt/sineθ


如果使用D3D,可以直接使用 D3DXQuaternionSlerp 函数就可以完成这个插值过程。
用 Quaternion 实现 Camera 旋转
总体来讲,Camera 的操作可分为如下几类:
沿直线移动
围绕某轴自转
围绕某轴公转
下面是一个使用了 Quaternion 的 Camera 类:


    class Camera {

    private:
        Quaternion m_orientation;

    public:
        void rotate (const Quaternion& q);
        void rotate(const Vector3& axis, const Radian& angle);
        void roll (const GLfloat angle);
        void yaw (const GLfloat angle);
        void pitch (const GLfloat angle);
    };

    void Camera::rotate(const Quaternion& q)
    {
        // Note the order of the mult, i.e. q comes after
        m_Orientation = q * m_Orientation;
    }

    void Camera::rotate(const Vector3& axis, const Radian& angle)
    {
        Quaternion q;
        q.FromAngleAxis(angle,axis);
        rotate(q);
    }


    void Camera::roll (const GLfloat angle) //in radian
    {
        Vector3 zAxis = m_Orientation * Vector3::UNIT_Z;
        rotate(zAxis, angleInRadian);
    }

    void Camera::yaw (const GLfloat angle)  //in degree
    {
        Vector3 yAxis;
        {
            // Rotate around local Y axis
            yAxis = m_Orientation * Vector3::UNIT_Y;
        }
        rotate(yAxis, angleInRadian);
    }

    void Camera::pitch (const GLfloat angle)  //in radian
    {
        Vector3 xAxis = m_Orientation * Vector3::UNIT_X;
        rotate(xAxis, angleInRadian);
    }

    void Camera::gluLookAt() {
        GLfloat m[4][4];
        identf(&m[0][0]);
        m_Orientation.createMatrix (&m[0][0]);


        glMultMatrixf(&m[0][0]);
        glTranslatef(-m_eyex, -m_eyey, -m_eyez);
    }


用 Quaternion 实现 trackball


用鼠标拖动物体在三维空间里旋转,一般设计一个 trackball,其内部实现也常用四元数。

class TrackBall
{
public:
    TrackBall();

    void push(const QPointF& p);
    void move(const QPointF& p);
    void release(const QPointF& p);

    QQuaternion rotation() const;

private:
    QQuaternion m_rotation;
    QVector3D m_axis;
    float m_angularVelocity;

    QPointF m_lastPos;
};


void TrackBall::move(const QPointF& p)
{
    if (!m_pressed)
        return;

    QVector3D lastPos3D = QVector3D(m_lastPos.x(), m_lastPos.y(), 0.0f);
    float sqrZ = 1 - QVector3D::dotProduct(lastPos3D, lastPos3D);
    if (sqrZ > 0)
        lastPos3D.setZ(sqrt(sqrZ));
    else
        lastPos3D.normalize();

    QVector3D currentPos3D = QVector3D(p.x(), p.y(), 0.0f);
    sqrZ = 1 - QVector3D::dotProduct(currentPos3D, currentPos3D);
    if (sqrZ > 0)
        currentPos3D.setZ(sqrt(sqrZ));
    else
        currentPos3D.normalize();

    m_axis = QVector3D::crossProduct(lastPos3D, currentPos3D);
    float angle = 180 / PI * asin(sqrt(QVector3D::dotProduct(m_axis, m_axis)));

    m_axis.normalize();
    m_rotation = QQuaternion::fromAxisAndAngle(m_axis, angle) * m_rotation;

    m_lastPos = p;
}

 

---------------------------------------------------------------------------------------------------------

每一个单位四元数都可以对应到一个旋转矩阵

单位四元数q=(s,V)的共轭为q*=(s,-V)

单位四元数的模为||q||=1;

四元数q=(s,V)的逆q^(-1)=q*/(||q||)=q*

一个向量r,沿着向量n旋转a角度之后的向量是哪个(假设为v),这个用四元数可以轻松搞定

构造两个四元数q=(cos(a/2),sin(a/2)*n),p=(0,r)

p`=q * p * q^(-1) 这个可以保证求出来的p`也是(0,r`)形式的,求出的r`就是r旋转后的向量

另外其实对p做q * p * q^(-1)操作就是相当于对p乘了一个旋转矩阵,这里先假设 q=(cos(a/2),sin(a/2)*n)=(s,(x, y, z))

两个四元数相乘也表示一个旋转
Q1 * Q2 表示先以Q2旋转,再以Q1旋转

则这个矩阵为

同理一个旋转矩阵也可以转换为一个四元数,即给你一个旋转矩阵可以求出(s,x,y,z)这个四元数,

方法是:

给定任意单位轴q(q1,q2,q3)(向量),求向量p(x,y,z)(或点p)饶q旋转theta角度的变换后的新向量p'(或点p'):

1.用四元数工具:
-------------------------------------------------------------------------
结论:构造四元数变换p'= q*p*q-1,(p,q是由向量p,q扩展成的四元数)。那么,p'转换至对应的向量(或点)就是变换后的新向量p'(或点p')。

其中,p',q,p,q-1均为四元数。q由向量q扩展,为q=(cos(theta/2),sin(theta/2)*q),p由向量p扩展,为p=(0,x,y,z),q-1为q的逆,因为q为单位四元数,所以q-1=q*=(cos(theta/2),-sin(theta/2)*q)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[学习SLAM]Quaternion 插值/ 用四元数插值来对齐IMU和图像帧 的相关文章

  • vxWorks6.9及workBench3.3常见配置

    1 双斜杠注释 在workBench集成开发环境当中 xff0c 默认的注释方式为 xxxxxx 如果想要使用 注释的方法必须修改workBench 的编译选项 xff0c 为编译选项添加c99支持或者gnu89 在编译选项中添加 std
  • 可能是最全的FreeRTOS源码分析及应用开发系列

    可能是最全的FreeRTOS源码分析及应用开发系列 FreeRTOS 是一个可裁剪的小型且免费的 RTOS 系统 xff0c 尺寸非常小 xff0c 可运行于微控制器上 其特点包括 xff1a 内核支持抢占式 xff0c 合作式和时间片调度
  • FreeRTOS系列|FreeRTOS简介

    1 RTOS简介 RTOS全称为 Real Time Operation System xff0c 即实时操作系统 RTOS强调的是实时性 xff0c 又分为硬实时和软实时 硬实时要求在规定的时间内必须完成操作 xff0c 不允许超时 xf
  • FreeRTOS系列|任务创建和删除

    1 任务创建和删除API函数 xTaskCreate 函数 xff1a 动态创建一个新的任务 xff0c 每个任务都需要RAM来保存任务状态 任务控制块 43 任务栈 xff0c 此接口采用动态分配内存资源 BaseType t span
  • FreeRTOS系列|多任务调度

    1 多任务启动流程 多任务启动流程如下表所示 启动后以下各函数由上至下依次执行含义osKernelStart 启动内核vTaskStartScheduler 启动任务调度器xPortStartScheduler 启动调度器prvStartF
  • PTP 报文格式

    HeaderBodySuffix34 字节Variable lengthOptional 所有的 PTP 帧都包含一个公共报头 xff0c 它决定了协议版本和消息类型 xff0c 还定义了消息的剩余内容 所有多字节字段以大端顺序发送 xff
  • makefile:make -C M=参数的使用

    Makefile为 xff0c PWD span class token operator 61 span span class token punctuation span shell pwd span class token punct
  • BW笔记(2011-10-24更新至No.237)

    1 同一个变量名的UID可能有多个 xff0c 记得注意 2 在查找时要注意技术名称还是名称 xff0c 因为查询时会在两个中进行 xff0c 模糊查询时要细心 xff0c FV与V都可以查到 3 复制的时候注意长度 xff0c 过长的会不
  • rpmsg 内核开发 用户层接口

    地址 xff1a https blog csdn net thisway diy article details 129195479 韦东山 Tina Linux E907开发指南 AMP 环境搭建 7 1 rpmsg 内核开发 7 2 r
  • __raw_writel, writel_relaxed 和 writel的区别

    因为对别的平台不了解 xff0c 下面仅谈它们在ARM上的区别 raw writel xff1a 因为有volatile关键字 xff0c 所以编译器不会打乱多个 raw writel的执行顺序 对于ARM而言 xff0c 当多个写以代码的
  • WFE和WFI的区别

    1 概念 xff1a WFI Wait for interrupt 和WFE Wait for event 是两个让ARM核进入low power standby模式的指令 xff0c 由ARM architecture定义 xff0c 由
  • Ubuntu16.04安装中文输入法

    转载地址 xff1a http blog csdn net suxiang198 article details 52040283 Ubuntu16 04安装完后 xff0c 和12 04以及14 04都不一样 xff0c 并没有中文输入功
  • QT linux安装

    转载地址 xff1a http www cnblogs com tangkaixuan p 6504102 html 文章来自https lug ustc edu cn sites qtguide 1 4 Qt在Linux下安装 Qt在Li
  • Linux CAN编程详解

    转载地址 xff1a http velep com archives 1181 html Linux CAN编程详解 是一篇百度文库上的文档 xff0c 主要描述了以下内容 xff1a can总线介绍及其帧类型 xff1b Linux 系统
  • buildroot学习(十)——at91sam9g45软件平台更新

    转载地址 xff1a https blog csdn net srf1986 article details 52474697 xff08 xff11 xff13 xff16 xff09 spice protocol In computin
  • killall 、kill 、pkill 命令详解

    转载地址 xff1a https www cnblogs com rsky p 4886043 html killall 命令 Linux系统中的killall命令用于杀死指定名字的进程 xff08 kill processes by na
  • PCIe扫盲——PCIe简介

    转载地址 xff1a http blog chinaaet com justlxy p 5100053066 PCI Express是继ISA和PCI总线之后的第三代I O总线 xff0c 即3GIO 由Intel在2001年的IDF上提出
  • Adaptive Autosar通讯层:ARA::COM中的Instance Identifiers

    一般概念 实例标识符 在收发两端都是要用的 是很核心的概念 proxy端用来搜索服务 xff0c skeleton端用来创建服务实例 站在API的角度来看 xff0c 这样的识别符是和特定的技术绑定的 所以 xff0c 标识符的结构和内容都
  • BW:数据源抽取机制(这篇是以前的笔记,写得很差,有不少错的地方,留着给自己看)

    题记 xff1a 忽然想到这么个问题 xff0c 后勤数据源和非后勤数据初始化有何区别 xff0c 然后进行周边的拓展 xff0c 所以就形成了下文 大部分知识源于 TBW350 和 SAP SDN 对数据源抽取机制的深入探讨 一 什么数据
  • 【ARA com API】ara::core::Optional

    文章目录 ara core Optional 是什么标准中的代码示例 ara core Optional 是什么 实际上就是std optional 但是当前的AP标准没有支持到那么新版本的C 43 43 标准 xff08 我没有具体研究是

随机推荐

  • ROS学习总结(1)--入门、学习路线

    最近由于项目需要 xff0c 我被分配到机器人驱动模块 xff0c 由此开始研究学习ROS xff0c 在此记录学习ROS的方法 过程 经历与应用 本节记录ROS学习路线 ROS xff08 robot operation system x
  • 使用uart数据起飞

    使用uart得到的位置信息进行起飞 在得到了位置信息的前提下 xff0c 我们开始进行模拟起飞 xff0c 即使用usb供电 xff0c 人工控制其高度 xff0c 在上位机查看油门大小 xff0c 电机的pwm输出 commander c
  • AirSim(五)---理解篇: Airsim世界坐标系、NED坐标系、机体坐标系以及控制相关API接口函数

    目录 1 坐标系 coordinate system 1 AirSim API的坐标系 xff1a NED 坐标系 with SI unit 2 Unreal Engine的坐标系 xff08 3 xff09 AirSim全局坐标系 61
  • 深度学习中常用的优化算法(SGD, Nesterov,Adagrad,RMSProp,Adam)总结

    深度学习中常用的优化算法 SGD Nesterov Adagrad RMSProp Adam 总结 1 引言 在深度学习中我们定义了损失函数以后 xff0c 会采取各种各样的方法来降低损失函数的数值 xff0c 从而使模型参数不断的逼近于真
  • 双系统安装ubuntu 22.04 LTS(一步到位)

    作为一个拥有两次都是一次成功安装好双系统的经验的人 xff0c 我觉得我可以借这个文章仔细讲述一下 xff0c 让大家都可以双系统安装都是一次成功 为什么有着两次安装经验呢 xff0c 第一次安装完成后由于电脑的内存不太够了 xff0c 然
  • UART、RS232、RS485 串行通信详解

    一 UART通信 UART是Universal Asynchronous Receiver Transmitter的缩写 xff0c 意即通用异步串行通信接口 xff0c 是最常用的通信技术之一 xff0c 广泛用于设备与电脑之间 设备与设
  • I2C总线基础知识及操作详解

    I2C总线是一种简单的双向两线式同步串行总线 xff0c 最初由Philips公司开发 xff0c 后又经过几次发展和完善 xff0c 目前已被业界厂商广泛采用 xff0c 成为最常用的板级通信总线之一 xff0c 大量应用于处理器与外围设
  • 对AI的理解及应用的思考

    1 概述 1 1 常用术语 1 2 AI学习方式及地位 序号 学习方法 地位 1 强化学习 Reinforcement Learning 犹如蛋糕上的一颗樱桃 2 监督学习 Supervised Learning 犹如蛋糕外的一层糖霜 3
  • (65)如何根据句柄从二级、三级结构句柄表中找到内核对象

    一 回顾 上一篇博客介绍了如何遍历一级句柄表 一级句柄表非常简单 xff0c 就是一个4KB页 xff0c 最多存储512个句柄表项 如果句柄数量在 512 1024 512 之间 xff0c 句柄表就是二级结构 xff1b 如果句柄数量大
  • BW:BW与第三方BI接口设计与实现:APD、Open Hub、RFM

    最近公司新上了国内某 CRM系统 xff0c SAP的 CRM也光荣下线了 但是紧接着就出现了一些需求 xff0c CRM自带一款小型 BI xff0c 需要一些 SD的数据 xff0c 但是把 R3的数据给他们进行计算的话 xff0c 不
  • Ubuntu下查看CPU、内存和硬盘详细信息的几个命令

    转载自https www cnblogs com shixiangwan p 7066085 html CPU xff1a 型号 xff1a grep 34 model name 34 proc cpuinfo awk F 39 39 39
  • python 小点心---execvp

    execvp会用即将运行的进程的内存替换掉调用进程的内存 xff0c 更进一步讲 xff0c 就是把当前进程的机器指令都清空 xff0c 然后载入被execvp运行起来的进程的机器指令 coding 61 utf 8 import os i
  • jenkins + gitlab + docker + harbor 实现自动触发更新

    当使用微服务方案后 xff0c 面临在大量的项目构建和部署工作 xff0c 借助于jenkins的持续集成 xff0c 可以快速把应用打包成docker镜像 xff0c 实现自动部署 xff0c 加快项目的迭代 一 环境部署 系统IP主机名
  • C++ -- STL文件解析

    1 STL文件格式 STL文件是一种用许多空间小三角形面片逼近三维实体表面的3D模型 STL模型给出了组成三角形法向量的3个分量 用于确定三角面片的正反方向 及三角形的3个顶点坐标 一个完整的STL文件记录了组成实体模型的所有三角形面片的法
  • Ubuntu 查看CPU信息

    Ubuntu 查看cpu个数及核心数 总核数 span class token operator 61 span 物理CPU个数 X 每颗物理CPU的核数 总逻辑CPU数 span class token operator 61 span
  • 韩顺平老师Java基础听课笔记(一)

    Java运行机制 xff1a 1 javac 编译 java文件 生成 class文件 javac Hello java 2 java运行编译后的 class文件 xff08 java Hello xff09 编译后可在Windows Li
  • 韩顺平老师 Java基础听课笔记(二)

    变量 xff1a xff08 先声明后使用 xff09 定义变量 xff1a 1 int a 61 1 2 int b b 61 2 变量在同一个作用域 xff08 同一个方法 xff09 内不能重名 变量三要素 xff1a 变量名 变量值
  • VScode上传到git仓库详细教程

    文章有点啰嗦 坚持看完 xff01 xff01 xff01 首先下载git https git scm com downloads 下载成功之后 xff0c 一直点击next直到安装成功 xff0c 在桌面上点击鼠标右键出现 点击Git B
  • [视觉测距]单目视觉定位测距的两种方式(1)

    单目定位和双目定位的选择 xff0c 我觉得主要还是成本和时间的考虑 之前也尝试过双目定位 xff0c 感觉要更精准些 xff0c 但双目测距需要对两幅图像进行图像变换和极线匹配 xff0c 稍微耗时了一些 这几天尝试了一下单摄像头进行测距
  • [学习SLAM]Quaternion 插值/ 用四元数插值来对齐IMU和图像帧

    小白 xff1a 师兄 xff0c 好久没见到你了啊 xff0c 我最近在看IMU xff08 Inertial Measurement Unit xff0c 惯性导航单元 xff09 相关的东西 xff0c 正好有问题求助啊 师兄 xff