首页 > 其他分享 >openvslam 三角化

openvslam 三角化

时间:2024-07-25 23:09:06浏览次数:18  
标签:const Eigen pt point openvslam 三角 cv row

https://blog.csdn.net/michaelhan3/article/details/89483148

一 :三角化的提出

三角化最早由高斯提出,并应用于测量学中。简单来讲就是:在不同的位置观测同一个三维点P(x, y, z),已知在不同位置处观察到的三维点的二维投影点X1(x1, y1), X2(x2, y2),利用三角关系,恢复出三维点的深度信息z。

 

一 :三角化的提出

三角化最早由高斯提出,并应用于测量学中。简单来讲就是:在不同的位置观测同一个三维点P(x, y, z),已知在不同位置处观察到的三维点的二维投影点X1(x1, y1), X2(x2, y2),利用三角关系,恢复出三维点的深度信息z。

 

二: 三角化求解

(1) 利用叉乘进行消元进行求解

s1x1 = s2Rx2 + t 公式(1)

左右两边同时乘以x1的反对称矩阵,可得:

s1x1^x1 = 0 = s2x1^Rx2 + x1^t 公式(2)

由上式可解得s2,

将s2代入公式(1),可求得s1

该方法也是视觉slam十四讲那本书里讲解三角化里提到的方法。

二: 三角化求解

(1) 利用叉乘进行消元进行求解

s1x1 = s2Rx2 + t 公式(1)

左右两边同时乘以x1的反对称矩阵,可得:

s1x1^x1 = 0 = s2x1^Rx2 + x1^t 公式(2)

由上式可解得s2,

将s2代入公式(1),可求得s1

该方法也是视觉slam十四讲那本书里讲解三角化里提到的方法。

 

(2) 线性三角化法

 

 

 

 

 

 

 openvslam代码

Vec3_t triangulator::triangulate(const cv::Point2d& pt_1, const cv::Point2d& pt_2, const Mat34_t& P_1, const Mat34_t& P_2) 
{
    //H矩阵
    Mat44_t A;
    //H矩阵每一行赋值
    A.row(0) = pt_1.x * P_1.row(2) - P_1.row(0);//u1p1(3)-p1(1)
    A.row(1) = pt_1.y * P_1.row(2) - P_1.row(1);//v1p1(3)-p1(2)
    A.row(2) = pt_2.x * P_2.row(2) - P_2.row(0);//u2p2(3)-p2(1)
    A.row(3) = pt_2.y * P_2.row(2) - P_2.row(1);//v2p2(3)-p2(2)
	//SVD求解,齐次坐标X为H的最小奇异值的奇异向量
    const Eigen::JacobiSVD<Mat44_t> svd(A, Eigen::ComputeFullU | Eigen::ComputeFullV);
	//因为SVD解可能不满足齐次坐标形式(第四个元素为0),所以需要进行归一化处理
    const Vec4_t v = svd.matrixV().col(3);
    return v.block<3, 1>(0, 0) / v(3);//归一化  block:从下标(0,0)开始,取3*1区域
}

  

VINS-Mono中相关代码

void FeatureManager::triangulatePoint(Eigen::Matrix<double, 3, 4> &Pose0, Eigen::Matrix<double, 3, 4> &Pose1,
                        Eigen::Vector2d &point0, Eigen::Vector2d &point1, Eigen::Vector3d &point_3d)
{
    Eigen::Matrix4d design_matrix = Eigen::Matrix4d::Zero();
    design_matrix.row(0) = point0[0] * Pose0.row(2) - Pose0.row(0);
    design_matrix.row(1) = point0[1] * Pose0.row(2) - Pose0.row(1);
    design_matrix.row(2) = point1[0] * Pose1.row(2) - Pose1.row(0);
    design_matrix.row(3) = point1[1] * Pose1.row(2) - Pose1.row(1);
    Eigen::Vector4d triangulated_point;
    triangulated_point =
              design_matrix.jacobiSvd(Eigen::ComputeFullV).matrixV().rightCols<1>();
    point_3d(0) = triangulated_point(0) / triangulated_point(3);
    point_3d(1) = triangulated_point(1) / triangulated_point(3);
    point_3d(2) = triangulated_point(2) / triangulated_point(3);
}

  

ORB-SLAM21中的三角形法的代码如下:

void Initializer::Triangulate(const cv::KeyPoint &kp1, const cv::KeyPoint &kp2, const cv::Mat &P1, const cv::Mat &P2, cv::Mat &x3D)
{
    cv::Mat A(4,4,CV_32F);
 
    A.row(0) = kp1.pt.x*P1.row(2)-P1.row(0);
    A.row(1) = kp1.pt.y*P1.row(2)-P1.row(1);
    A.row(2) = kp2.pt.x*P2.row(2)-P2.row(0);
    A.row(3) = kp2.pt.y*P2.row(2)-P2.row(1);
 
    cv::Mat u,w,vt;
    cv::SVD::compute(A,w,u,vt,cv::SVD::MODIFY_A| cv::SVD::FULL_UV);
    x3D = vt.row(3).t();
    x3D = x3D.rowRange(0,3)/x3D.at<float>(3);
}

(3) 解二元一次方程

视觉slam十四讲单目重建深度滤波部分代码。利用Cramer's法则,
按照对极几何中的定义,设x1, x2为两个特征点的归一化坐标,则它们满足:

s1x1 = s2Rx2 + t 公式(1)

=> s1x1 - s2Rx2 = t 公式(2)

对公式(2)左右两侧分别乘以x1T,得:

s1x1Tx1 - s2x1TRx2 = x1T t 公式(3)

对公式(2)左右两侧分别乘以(Rx2)T,得:

s1(Rx2)Tx1 - s2(Rx2)TRx2 = (Rx2)T t 公式(4)

由公式(3)和公式(4)可以联立,然后可以利用Cramer's法则(参见线性代数书)进行求解。

 

 


  

  • 在SVO2中的实现如下
  •  

 

bool depthFromTriangulation(
    const SE3& T_search_ref,
    const Vector3d& f_ref,
    const Vector3d& f_cur,
    double& depth)
{
  Matrix<double,3,2> A; A << T_search_ref.rotation_matrix() * f_ref, f_cur;
  const Matrix2d AtA = A.transpose()*A;
  if(AtA.determinant() < 0.000001)
    return false;
  // d = - (ATA)^(-1) * AT * t
  const Vector2d depth2 = - AtA.inverse()*A.transpose()*T_search_ref.translation();
  depth = fabs(depth2[0]);
  return true;
}

  

标签:const,Eigen,pt,point,openvslam,三角,cv,row
From: https://www.cnblogs.com/gooutlook/p/18324332

相关文章

  • 【算法专题】双指针算法之611. 有效三角形的个数(力扣)
    欢迎来到CILMY23的博客......
  • 用C语言打印杨辉三角形:**
    用C语言打印杨辉三角形:1.杨辉三角形规律:1.每行数字左右对称,由1开始逐渐变大,然后变小,回到1。2.第n行的数字个数等于n,第n行的第一个和最后一个数字都是1。3.对于第i行,除首尾两个1之外,任意位置的数等于它肩上的两个数之和。即第i行第j个数等于第i-1行第j-1个数与第i-1行第......
  • PCL使用贪婪三角形算法曲面重构
    内容介绍贪婪投影三角化算法是一种对原始点云进行快速三角化的算法,该算法假设曲面光滑,点云密度变化均匀,不能在三角化的同时对曲面进行平滑和孔洞修复。方法:(1)将三维点通过法线投影到某一平面(2)对投影得到的点云作平面内的三角化(3)根据平面内三位点的拓扑连接关系获得一个......
  • 仅产生 2D 笛卡尔积的上三角形
    我知道如何使用itertools.productIn[19]:fromitertoolsimportproduct...:...:abcd=product('abcd','abcd')...:foriinrange(4):...:print(''.join(repr(t)for_,tinzip(range(4),abcd)))......
  • 蛇形矩阵是由1开始的自然数依次排列成的一个矩阵上三角形
    /蛇形矩阵是由1开始的自然数依次排列成的一个矩阵上三角形。/#include<stdio.h>#include<string.h>#defineMAX100voidfun(intn){intmatrix[MAX][MAX];//创建矩阵intnum=1;for(inti=0;i<n;i++){intx=0,y=i;while(y>=0)......
  • 三角测量原理推导
    三角测量原理推导接着对极几何求解本质矩阵E后,通过E分解出四组R和t,通过三角测量原理求出深度,只有在两个相机下面深度均为正时,才是E分解出的正确R和t。下面是推导过程。设\(p_1\)为世界坐标P点在相机1下面看到的像素坐标,\(p_2\)为相机2下面的像素坐标,以相机1的光心为世界坐标,K为......
  • 三角函数sin
    #三角函数sin教程##1.三角函数简介三角函数是数学中研究角度与长度关系的一组函数,其中最基本的三个函数是正弦(sin)、余弦(cos)和正切(tan)。这些函数在几何学、物理学、工程学等领域有着广泛的应用。##2.正弦函数(sin)定义正弦函数是对一个角度$\theta$的函数,定义为直角三角......
  • 杨辉三角讲解
    一、背景(阅读时可略过)(1)杨辉其人杨辉,字谦光,杭州人,中国南宋时期杰出的数学家和数学教育家。他是世界上第一个排出丰富的纵横图和讨论其构成规律的数学家。著有《详解九章算法》、《日用算法》、《乘除通变本末》、《田亩比类乘除捷法》、《续古摘奇算法》。杨辉的数学研究与教......
  • 1004:字符三角形 题解
    题目链接题目描述给定一个字符,用它构造一个底边长\(5\)个字符,高\(3\)个字符的等腰字符三角形。解题思路由于是字符,我们需要定义一个char类型的字符变量。第一行为两个空格和一个字符第二行为一个空格和三个字符第三行是五个字符输出即可ACCode#include<bits/stdc++.h......
  • 从零开始学Java(超详细韩顺平老师笔记梳理)05——数组(语法,赋值机制,拷贝反转)、排序(冒泡排
    文章目录前言一、数组1.基础语法1)介绍2)使用(动态、静态初始化语法与使用)3)注意事项和细节2.数组赋值机制(ArryAssign)3.数组拷贝4.数组反转(reserve)5.数组的扩容与缩减二、排序三、查找四、二维数组(TwoDimensionalArry)1.快速入门2.使用3.案例:打印一个10行的......