特征检测与匹配(三维重建task1-3)

#include <math/matrix_svd.h>
#include "math/matrix.h"
#include "math/vector.h"typedef math::Matrix<double, 3, 3>  FundamentalMatrix;FundamentalMatrix fundamental_8_point (math::Matrix<double, 3, 8> const& points1, math::Matrix<double, 3, 8> const& points2){FundamentalMatrix F;return F;
#if 0/* direct linear transform */math::Matrix<double, 8, 9> A;for(int i=0; i<8; i++){math::Vec3d p1  = points1.col(i);math::Vec3d p2 = points2.col(i);A(i, 0) = p1[0]*p2[0];A(i, 1) = p1[1]*p2[0];A(i, 2) = p2[0];A(i, 3) = p1[0]*p2[1];A(i, 4) = p1[1]*p2[1];A(i, 5) = p2[1];A(i, 6) = p1[0];A(i, 7) = p1[1];A(i, 8) = 1.0;}math::Matrix<double, 9, 9> vv;math::matrix_svd<double, 8, 9>(A, nullptr, nullptr, &vv);math::Vector<double, 9> f = vv.col(8);FundamentalMatrix F;F(0,0) = f[0]; F(0,1) = f[1]; F(0,2) = f[2];F(1,0) = f[3]; F(1,1) = f[4]; F(1,2) = f[5];F(2,0) = f[6]; F(2,1) = f[7]; F(2,2) = f[8];/* singularity constraint */math::Matrix<double, 3, 3> U, S, V;math::matrix_svd(F, &U, &S, &V);S(2,2)=0;F = U*S*V.transpose();return F;
#endif}int main(int argc, char*argv[])
{// 第一幅图像中的对应点math::Matrix<double, 3, 8> pset1;pset1(0, 0) = 0.180123 ; pset1(1, 0)= -0.156584; pset1(2, 0)=1.0;pset1(0, 1) = 0.291429 ; pset1(1, 1)= 0.137662 ; pset1(2, 1)=1.0;pset1(0, 2) = -0.170373; pset1(1, 2)= 0.0779329; pset1(2, 2)=1.0;pset1(0, 3) = 0.235952 ; pset1(1, 3)= -0.164956; pset1(2, 3)=1.0;pset1(0, 4) = 0.142122 ; pset1(1, 4)= -0.216048; pset1(2, 4)=1.0;pset1(0, 5) = -0.463158; pset1(1, 5)= -0.132632; pset1(2, 5)=1.0;pset1(0, 6) = 0.0801864; pset1(1, 6)= 0.0236417; pset1(2, 6)=1.0;pset1(0, 7) = -0.179068; pset1(1, 7)= 0.0837119; pset1(2, 7)=1.0;//第二幅图像中的对应math::Matrix<double, 3, 8> pset2;pset2(0, 0) = 0.208264 ; pset2(1, 0)= -0.035405 ; pset2(2, 0) = 1.0;pset2(0, 1) = 0.314848 ; pset2(1, 1)=  0.267849 ; pset2(2, 1) = 1.0;pset2(0, 2) = -0.144499; pset2(1, 2)= 0.190208  ; pset2(2, 2) = 1.0;pset2(0, 3) = 0.264461 ; pset2(1, 3)= -0.0404422; pset2(2, 3) = 1.0;pset2(0, 4) = 0.171033 ; pset2(1, 4)= -0.0961747; pset2(2, 4) = 1.0;pset2(0, 5) = -0.427861; pset2(1, 5)= 0.00896567; pset2(2, 5) = 1.0;pset2(0, 6) = 0.105406 ; pset2(1, 6)= 0.140966  ; pset2(2, 6) = 1.0;pset2(0, 7) =  -0.15257; pset2(1, 7)= 0.19645   ; pset2(2, 7) = 1.0;FundamentalMatrix F = fundamental_8_point(pset1, pset2);std::cout<<"Fundamental matrix after singularity constraint is:\n "<<F<<std::endl;std::cout<<"Result should be: \n"<<"-0.0315082 -0.63238 0.16121\n"<<"0.653176 -0.0405703 0.21148\n"<<"-0.248026 -0.194965 -0.0234573\n" <<std::endl;return 0;
}

解析

//Created by sway on 2018/8/29./* 测试8点法求取基础矩阵F** [直接线性变换法]* 双目视觉中相机之间存在对极约束**                       p2'Fp1=0,** 其中p1, p2 为来自两个视角的匹配对的归一化坐标,并表示成齐次坐标形式,* 即p1=[x1, y1, z1]', p2=[x2, y2, z2],将p1, p2的表达形式带入到* 上式中,可以得到如下表达形式**          [x2] [f11, f12, f13] [x1, y1, z1]*          [y2] [f21, f22, f23]                = 0*          [z2] [f31, f32, f33]** 进一步可以得到* x1*x2*f11 + x2*y1*f12 + x2*f13 + x1*y2*f21 + y1*y2*f22 + y2*f23 + x1*f31 + y1*f32 + f33=0** 写成向量形式*               [x1*x2, x2*y1,x2, x1*y2, y1*y2, y2, x1, y1, 1]*f = 0,* 其中f=[f11, f12, f13, f21, f22, f23, f31, f32, f33]'** 由于F无法确定尺度(up to scale, 回想一下三维重建是无法确定场景真实尺度的),因此F秩为8,* 这意味着至少需要8对匹配对才能求的f的解。当刚好有8对点时,称为8点法。当匹配对大于8时需要用最小二乘法进行求解**   [x11*x12, x12*y11,x12, x11*y12, y11*y12, y12, x11, y11, 1]*   [x21*x22, x22*y21,x22, x21*y22, y21*y22, y22, x21, y21, 1]*   [x31*x32, x32*y31,x32, x31*y32, y31*y32, y32, x31, y31, 1]* A=[x41*x42, x42*y41,x42, x41*y42, y41*y42, y42, x41, y41, 1]*   [x51*x52, x52*y51,x52, x51*y52, y51*y52, y52, x51, y51, 1]*   [x61*x62, x62*y61,x62, x61*y62, y61*y62, y62, x61, y61, 1]*   [x71*x72, x72*y71,x72, x71*y72, y71*y72, y72, x71, y71, 1]*   [x81*x82, x82*y81,x82, x81*y22, y81*y82, y82, x81, y81, 1]**现在任务变成了求解线性方程*               Af = 0*(该方程与min||Af||, subject to ||f||=1 等价)*通常的解法是对A进行SVD分解,取最小奇异值对应的奇异向量作为f分解**本项目中对矩阵A的svd分解并获取其最小奇异值对应的奇异向量的代码为*   math::Matrix<double, 9, 9> V;*   math::matrix_svd<double, 8, 9>(A, nullptr, nullptr, &V);*   math::Vector<double, 9> f = V.col(8);***[奇异性约束]*  基础矩阵F的一个重要的性质是F是奇异的,秩为2,因此有一个奇异值为0。通过上述直接线性法求得*  矩阵不具有奇异性约束。常用的方法是将求得得矩阵投影到满足奇异约束得空间中。*  具体地,对F进行奇异值分解*               F = USV'*  其中S是对角矩阵,S=diag[sigma1, sigma2, sigma3]*  将sigma3设置为0,并重构F*                       [sigma1, 0,     ,0]*                 F = U [  0   , sigma2 ,0] V'*                       [  0   , 0      ,0]*/

## 效果
图片1

图片2

效果图1(默认的最近邻+最近邻距离比的结果)

效果图2(去掉最近邻距离比的结果)
特别说明:要得到效果图2直接编译单个文件事行不通的,因为代码缺少这两张图片的路径,需要cmake编译整个目录,然后在bulid文件夹内找到对应编译好的可执行文件。讲太多没意思,还是直接送上操作比较好!
1.先把源码中./ImageBasedModellingEdu/features/matching.h的第169行及下面几行的代码注释掉

2.请在终端下执行以下操作:

cd ~/ImageBasedModellingEdu
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j8

特征检测与匹配,测试8点法求取基础矩阵F(三维重建task1-3)相关推荐

  1. 2D - 2D 点对 求解基础矩阵 F 本质矩阵E 单应矩阵 H 进而求 旋转矩阵 R 和 t

    *对极几何 求解 两组单目相机 2D图像 间的 旋转平移 矩阵 * 2D 点对 求 两相机的 旋转和平移矩阵 * 空间点 P 两相机 像素点对 p1 p2 两相机 归一化平面上的点对 x1 x2 与P ...

  2. svo: semi-direct visual odometry 半直接视觉里程计 fast角点匹配 光流匹配 单应变换求位姿 直接法求解位姿 高斯均匀分布混合深度滤波

    svo: semi-direct visual odometry 半直接视觉里程计 本博文github地址 svo代码注释 SVO代码分析 较细致 svo: semi-direct visual od ...

  3. sift特征检测与匹配

    文章目录 一 实验背景 1.sift算法介绍 1.1sift算法特点 1.2sift算法可以解决的问题 1.3 sift算法实现具体步骤 2.关键点相关概念 2.1关键点(特征点) 2.2尺度空间 3 ...

  4. OpenCV基础(23)特征检测与匹配

    图像的8x8像素部分被考虑,并将这个 8x8 框进一步划分为 4 个块,每个块为 4x4 维度.在每个 4x4 块内,图像梯度以向量的形式表示.通过搜索最独特或不同的特征在图像中找到关键点.这里,Ke ...

  5. C语言设计函数求最大公约数,C语言程序设计课程设计--编写函数求取两个整数m,n的最大公约数和最小公倍数.doc_在线文库www.lddoc.cn...

    C语言程序设计课程设计--编写函数,求取两个整数m,n的最大公约数和最小公倍数.doc C语言程序设计课程设计C语言程序设计课程设计评语考勤(10)纪律(10)过程(40)设计报告(30)答辩(10) ...

  6. 利用边缘灰度变化建模,来提高圆环直径求取精度

    简 介: 利用对所获得的圆环边缘亮度平均变化曲线,利用Sigmoid函数进行建模逼近,可以对原来经由HoughCircle所获得的半径进行补偿.对于利用扫描仪所获得的图片进行实际处理,可以看到它可以获 ...

  7. 使用SVD求取矩阵的伪逆

    ➤01 矩阵的SVD分解 对于矩阵A∈Rn×mA \in R_{n \times m}A∈Rn×m​,可以通过奇异值分解(Singular Vector Decomposite)分解成如下形式:A=U ...

  8. 数字图像处理学习笔记(一):特征检测和匹配概述

    数字图像处理学习笔记(一):特征检测和匹配概述 参考博客: 特征点的匹配 SIFT特征详解 数字图像处理学习笔记(二):SIFT(尺度不变特征变换)算法 1.特征点概述 如何高效且准确的匹配出两个不同 ...

  9. 11.9 至 11.17 四道典型题记录: Counter 弹出 | map函数 | 子集求取 | 有序字符桶分装

    11.9 至 11.17 四道典型题记录: Counter 弹出 | map函数 | 子集求取 | 有序字符桶分装    昨天休息的时候一直在想应该学习哪种语言,我想这也是好多人发愁无法下手的原因之一 ...

最新文章

  1. 公司运作 - 利润率、周转率
  2. python 抛出异常raise
  3. 深度学习在单图像超分辨率上的应用:SRCNN、Perceptual loss、SRResNet
  4. 修改CentOS7网卡名称为传统名称eth0格式(20170711更新)
  5. python数据挖掘是什么_python数据挖掘是什么
  6. oracle linux内存推荐分配,浅析Oracle 的体系架构及内存分配机制
  7. Dell Caps Lock 切换大小写被窃取焦点问题解决办法
  8. 907计算机专业基础与408相比,2018年北京大学信息科学技术学院907计算机专业基础之计算机操作系统考研强化五套模拟题...
  9. java numberformat 方法_java.text.NumberFormat用法
  10. CodeForces - 798B Mike and strings
  11. php为什么要创建类,php – 是否有理由为单一功能创建类?
  12. 成功的人不是最聪明的那个人,但绝对是一个交流很棒的人
  13. 多台电脑同步VSCode的配置和插件
  14. 正确安装Senta的姿势
  15. Java九阳神功-抽象方法与抽象类
  16. 【雕爷学编程】Arduino动手做(43)---单路继电器模块
  17. 小程序文章怎么导出来_微店小程序—小程序怎么搜索微信店铺
  18. fast lio测试
  19. 郑州轻工业大学OJ python 1060: 逆序数字
  20. 干货分享——shutdown命令

热门文章

  1. Totoro 在自动化测试领域的深耕与收获
  2. highecharts 3d饼图,引线文字
  3. oracle 18c 18.3 学习之五 unplug drop plug pdb
  4. 2021年低压电工答案解析及低压电工试题及答案
  5. vim 粘贴时取消自动换行
  6. c# datetime与 timeStamp(unix时间戳) 互相转换
  7. 学会使用微信公众平台
  8. 解决Mysqlf服务启动后停止。某些服务器在未由其他服务或程序使用时将自动停止的问题
  9. 考研英语二语法知识点 1.2简单句的核心变化
  10. Android框架源码分析-浅析OkHttp3