首页 > 其他分享 >雷达坐标变换及其相关运算

雷达坐标变换及其相关运算

时间:2024-05-14 23:52:38浏览次数:17  
标签:begin end 运算 变换 ipBox depth 坐标 bmatrix Matrix

坐标系变换

坐标系变换包括:平移,旋转。

旋转矩阵

例如,绕X轴旋转有:

\[ Y_L` = Y_Lcosa - Z_Lsina \\ Z_L' = Y_Lsina + Z_Lcosa \\ \]

转换为矩阵形式

\[ \begin{bmatrix} X_L` \\ Y_L` \\ Z_L` \end{bmatrix} = \begin{bmatrix} 1 & 0 & 0 \\ 0 & cosa & -sina \\ 0 & sina & cosa \end{bmatrix} \begin{bmatrix} X_L \\ Y_L \\ Z_L \end{bmatrix} \]

同理,绕Y轴、X轴旋转有:

\[\begin{bmatrix} X_L` \\ Y_L` \\ Z_L` \end{bmatrix} = \begin{bmatrix} cosb & 0 & sinb \\ 0 & 1 & 0 \\ -sinb & 0 & cosb \end{bmatrix} \begin{bmatrix} X_L \\ Y_L \\ Z_L \end{bmatrix} \]

\[\begin{bmatrix} X_L` \\ Y_L` \\ Z_L` \end{bmatrix} = \begin{bmatrix} cosy & -siny & 0 \\ siny & cosy & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} X_L \\ Y_L \\ Z_L \end{bmatrix} \]

将上面三个矩阵相乘得到旋转矩阵:

\[ R= \begin{bmatrix} cosbcosa & -sinacosb & sinb \\ sinasinbcosy + cosasiny & cosacosy-sinasinbsiny & -sinacosb \\ sinasiny+cosacosbcosy & cosasinbsiny + sinacosy & cosacosb \end{bmatrix} \]

平移矩阵

\[T = \begin{bmatrix} \Delta x \\ \Delta y \\ \Delta z \end{bmatrix} \]

最后,可以得到激光雷达坐标与相机坐标(世界坐标系下)关系

\[ \begin{bmatrix} X_c` \\ Y_c` \\ Z_c` \\ 1 \end{bmatrix} = \begin{bmatrix} R & T \\ 0 & 1 \end{bmatrix} \begin{bmatrix} X_L` \\ Y_L` \\ Z_L` \\ 1 \end{bmatrix} \\ \]

例如下面是一个变换矩阵

0.029548,-0.999563,-0.00120571,-0.0189618
-0.00609057,0.00102618,-0.999981,0.181019
0.999545,0.0295548,-0.00605758,-0.0807626
0,0,0,1

将点云投影至图像

以下是一段示例代码,可将激光雷达获得点云投影至图像每个像素。

vector<vector<float>> DepthQueue::pushback(pcl::PointCloud<pcl::PointXYZ> &pc)
{
    if (this->processQueue.empty())
    {
        this->_initflag = true;
    }
    Matrix4Xf pc_Matrix = pc.getMatrixXfMap();
    int cols = pc_Matrix.cols();
    Matrix3Xf transformed_points = (this->E_0 * pc_Matrix).topRows(3);
    Matrix<float, 3, MaxPointsNum> pointsBox;       // 点云矩阵
    Matrix<float, 1, MaxPointsNum> dptBox;          // 深度矩阵
    Matrix<int, 2, MaxPointsNum> ipBox;             // 投影至图像的点阵
    pointsBox.leftCols(cols) << transformed_points;
    dptBox.leftCols(cols) << transformed_points.row(2);
    ipBox << ((this->K_0 * pointsBox).array().rowwise() * (pointsBox.row(2).array().inverse())).topRows(2).matrix().cast<int>();
    auto inside_x = (ipBox.row(0).array() >= 0 && ipBox.row(0).array() < ImageW);
    auto inside_y = (ipBox.row(1).array() >= 0 && ipBox.row(1).array() < ImageH);
    ipBox.row(0) << (inside_x).select(ipBox.row(0), MatrixXf::Constant(1, MaxPointsNum, 0));    // x轴
    ipBox.row(1) << (inside_y).select(ipBox.row(1), MatrixXf::Constant(1, MaxPointsNum, 0));    // y轴
    this->processQueue.push(ipBox);
    // 将超出队列大小的点云全置零
    if (this->processQueue.size() > maxQueueSize)
    {
        Matrix<int, 2, MaxPointsNum> outpoints = this->processQueue.front();
        for (int i = 0; i < MaxPointsNum; ++i)
        {
            if (this->depth[outpoints(1, i)][outpoints(0, i)] == 0.)
                continue;
            this->depth[outpoints(1, i)][outpoints(0, i)] = 0.;
        }
        this->processQueue.pop();
    }
    for (int i = 0; i < MaxPointsNum; ++i)
    {
        if (dptBox(0, i) > 0)
        {
            if ((fabs(this->depth[ipBox(1, i)][ipBox(0, i)]) > Epsilon && dptBox(0, i) < this->depth[ipBox(1, i)][ipBox(0, i)]) || fabs(this->depth[ipBox(1, i)][ipBox(0, i)]) < Epsilon)
                this->depth[ipBox(1, i)][ipBox(0, i)] = dptBox(0, i);
                // depth[y][x] -> 图像中x,y点的深度。
        }
        else
            break;
    }
    return this->depth;
}

标签:begin,end,运算,变换,ipBox,depth,坐标,bmatrix,Matrix
From: https://www.cnblogs.com/AlanLeeee/p/18192369

相关文章

  • shell运算符
    算术运算符点击查看详情运算符说明举例+加法expr$a+$b结果为30。-减法expr$a-$b结果为-10。*乘法expr$a\*$b结果为200。/除法expr$b/$a结果为2。%取余expr$b%$a结果为0。=赋值a=$b把变量b的值赋给a。==......
  • 将bmp图片画到开发板的指定坐标上
    #include<stdio.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>#include<sys/mman.h>/***********************************************************************************......
  • 位运算符
    &:按位与1&1=11&0=00&0=00&1=05&7=521&7=55&1=15&10=0-5&10=10 |:按位或1|0=10|1=11|1=10|0=03|5=7 ~:按位取反~1100=0011^:按位异或相同为0不同为11^0=10^1=11^1=00^0=0 <<:按位左移i<<n左移n位相当于乘以2的n次方,右边补0......
  • C#运算符的优先级
    C#运算符的优先级C#运算符的优先级请参考下面的顺序:1、括号。学数学的时候我们就知道,要先计算括号里面的内容。C#语言也是一样,如果有多层括号,要从里向外计算。括号优先级最高。2、一元运算符。有些运算符两边有2个操作数,比如2+3、6%5等等,这些叫做二元运算符。只有一个操作数......
  • 运算符与表达式
    运算符与表达式Created:November29,202310:38PM运算符运算符释义+、-、*、/略**、//、%乘方、整除(向下取整至最接近的整数、余数<<、>>指的是二进制左右移&按位与按位与是针对二进制数的操作,指将两个二进制数的每一位都进行比较,如果两个相应的二进......
  • 运算符:operator
    运算符:operator注意:1.多个操作数中,操作数最高为Long,那么运算结果类型也为Long,如果是byte,int,short,那么结果都为Int。如果最高有float,结果是float类型;如果最高有double,结果是double类型;2.关系运算符返回的结果:正确,错误布尔值3.a++,先等于,a再自增,++a,先a自增,再等于4.+=......
  • 离散数学_集合运算_容器实现
    define_CRT_SECURE_NO_WARNINGS1/*1.求任意两个集合的交集、并集、差集2.求任意一个集合的幂集3.求任意一个集合的m元子集*/includeincludeincludeincludeusingnamespacestd;//检验一个元素是否已经存在于集合中boolexisted(vectors,chara){boolexist=fa......
  • C#.Net筑基-运算符Family
    C#运算符内置了丰富的运算符操作类型,使用方便,极大的简化了编码,同时还支持多种运算符重载机制,让自定义的类型也能支持运算符行为。01、运算符概览运算符分类描述数学运算基础的加减乘除,及++、--赋值运算=,及各种复合赋值op=,x+=20;等效于x=x+20;比较运算比较......
  • 第 1 节 向量及其线性运算
    第一节向量及其线性运算一、向量的概念向量:既有大小,又有方向的量自由向量:与起点无关的向量向量的大小叫做向量的模.向量\(\vec{AB}\),a和\(\vec{a}\)的模依次记作\(|\vec{AB}|\),|a|和\(|\vec{a}|\).模等于1的向量叫做单位向量.模等于零的向量叫做零向量,记作0......
  • 【C语言】---- 三目运算符
    C语言中的三目运算符是一种简化版的条件语句,它允许您在一行代码中编写ifelse语句。三目运算符的语法如下:condition?expression1:expression2;如果condition为真,则表达式expression1被求值并作为整个表达式的结果;如果condition为假,则表达式expression2被求值并作为整个表达......