首页 > 根据相机外参实现单应矩阵计算的理论与实践

根据相机外参实现单应矩阵计算的理论与实践

论文阅读模块将分享点云处理,SLAM,三维视觉,高精地图相关的文章。公众号致力于理解三维视觉领域相关内容的干货分享,欢迎各位加入我,我们一起每天一篇文章阅读,开启分享之旅,有兴趣的可联系微信[email protected]

单应矩阵介绍

单应性在计算机视觉领域是一个非常重要的概念,它在图像校正、图像拼接、俯视图生成,相机位姿估计、视觉SLAM等领域有非常重要的作用。

单应性(Homography)变换是将一幅图像中的点映射到另一幅图像中相应点的变换关系:

单应矩阵是一个3x3矩阵,具有8个自由度,通常为归一化后表达式,其尺度为1。

下面展示了不同类型的变换,但都与两个平面之间的变换有关。

(1)真实平面和图像平面

(2)由两个相机位置拍摄的平面

(3)围绕其投影轴旋转的相机采集的图像进行拼接

所以单应性矩阵主要用来解决两个问题:

一是表述真实世界中一个平面与对应它图像的透视变换

二是从通过透视变换实现图像从一种视图变换到另外一种视图

外参求解单应矩阵理论

这里将主要讲解以下已知两个相机的位姿如何实现图像的拼接,主要公式就是根据外参计算H矩阵。

单应性将两个平面之间的变换联系起来,这样就可以计算出从第二个平面视图转到第一个平面视图下相应相机位移,在已知内外参的情况下有

使用齐次坐标系表达式将三维世界点转转到相机坐标系下:

使用矩阵乘法可以轻松地将一图像帧中表示的点转换为另一帧图像中:c1Mo是第一帧的位姿,c2Mo是第二帧的位姿。要将相机1中表示的三维点变换为相机2帧的坐标下,其变换公式为:

以上公式对应的是:同一平面两个不同相机坐标系的单应矩阵。如果要同一平面计算出两个图像间的单应矩阵H,则需要内参,此时左边乘以K,右边乘以K的逆矩阵。

为了更好的理解,这里写了一个demo,并与上述的理论对应(注意这里是将第二帧转到第一帧的坐标系下)。

Mat cameraMatrix = (Mat_(3, 3) << 700.0, 0.0, 320.0,0.0, 700.0, 240.0,0, 0, 1);
Mat R1 = c1Mo(Range(0, 3), Range(0, 3));
Mat R2 = c2Mo(Range(0, 3), Range(0, 3));//c1Mo * oMc2
Mat R_2to1 = R1*R2.t();//同一平面两个不同相机坐标系的单应矩阵
// [compute-homography]
Mat H = cameraMatrix * R_2to1 * cameraMatrix.inv();//同一平面计算出两个图像间的单应矩阵H
H /= H.at(2, 2);//归一化
cout << "H:
" << H << endl;

根据求解的单应矩阵实现两个视图的拼接实例显示如下

拼接的结果如下:

warpPerspective(img2, img_stitch, H, Size(img2.cols * 2, img2.rows));Mat half = img_stitch(Rect(0, 0, img1.cols, img1.rows));

完整代码如下:

void basicPanoramaStitching(const string &img1Path, const string &img2Path)
{Mat img1 = imread("Blender_Suzanne1.jpg");Mat img2 = imread("Blender_Suzanne2.jpg");//! [camera-pose-from-Blender-at-location-1]Mat c1Mo = (Mat_(4, 4) << 0.9659258723258972, 0.2588190734386444, 0.0, 1.5529145002365112,0.08852133899927139, -0.3303661346435547, -0.9396926164627075, -0.10281121730804443,-0.24321036040782928, 0.9076734185218811, -0.342020183801651, 6.130080699920654,0, 0, 0, 1);//! [camera-pose-from-Blender-at-location-1]//! [camera-pose-from-Blender-at-location-2]Mat c2Mo = (Mat_(4, 4) << 0.9659258723258972, -0.2588190734386444, 0.0, -1.5529145002365112,-0.08852133899927139, -0.3303661346435547, -0.9396926164627075, -0.10281121730804443,0.24321036040782928, 0.9076734185218811, -0.342020183801651, 6.130080699920654,0, 0, 0, 1);//! [camera-pose-from-Blender-at-location-2]Mat cameraMatrix = (Mat_(3, 3) << 700.0, 0.0, 320.0,0.0, 700.0, 240.0,0, 0, 1);Mat R1 = c1Mo(Range(0, 3), Range(0, 3));Mat R2 = c2Mo(Range(0, 3), Range(0, 3));//c1Mo * oMc2Mat R_2to1 = R1*R2.t();//! [compute-homography]Mat H = cameraMatrix * R_2to1 * cameraMatrix.inv();H /= H.at(2, 2);cout << "H:
" << H << endl;//! [compute-homography]//! [stitch]Mat img_stitch;warpPerspective(img2, img_stitch, H, Size(img2.cols * 2, img2.rows));Mat half = img_stitch(Rect(0, 0, img1.cols, img1.rows));img1.copyTo(half);//! [stitch]Mat img_compare;Mat img_space = Mat::zeros(Size(50, img1.rows), CV_8UC3);hconcat(img1, img_space, img_compare);hconcat(img_compare, img2, img_compare);imshow("Compare images", img_compare);imshow("Panorama stitching", img_stitch);waitKey();}

以上是根据外参实现了同一相机不同位姿采集的图像的拼接,其主要原理主要是根据外参计算出单应性矩阵,将第二帧采集的图像变换到第一帧视角下的结果,最终实现拼接。这里我想到了前视图转换俯视图的方法,同样也是变换视角的问题,只是这里的俯视图的虚拟相机的参数需要自己设置,有时间再更新。

资源

三维点云论文及相关应用分享

【点云论文速读】基于激光雷达的里程计及3D点云地图中的定位方法

3D目标检测:MV3D-Net

三维点云分割综述(上)

3D-MiniNet: 从点云中学习2D表示以实现快速有效的3D LIDAR语义分割(2020)

win下使用QT添加VTK插件实现点云可视化GUI

JSNet:3D点云的联合实例和语义分割

大场景三维点云的语义分割综述

PCL中outofcore模块---基于核外八叉树的大规模点云的显示

基于局部凹凸性进行目标分割

基于三维卷积神经网络的点云标记

点云的超体素(SuperVoxel)

基于超点图的大规模点云分割

更多文章可查看:点云学习历史文章大汇总

SLAM及AR相关分享

【开源方案共享】ORB-SLAM3开源啦!

【论文速读】AVP-SLAM:自动泊车系统中的语义SLAM

【点云论文速读】StructSLAM:结构化线特征SLAM

SLAM和AR综述

常用的3D深度相机

AR设备单目视觉惯导SLAM算法综述与评价

SLAM综述(4)激光与视觉融合SLAM

Kimera实时重建的语义SLAM系统

SLAM综述(3)-视觉与惯导,视觉与深度学习SLAM

易扩展的SLAM框架-OpenVSLAM

高翔:非结构化道路激光SLAM中的挑战

SLAM综述之Lidar SLAM

基于鱼眼相机的SLAM方法介绍

如果你对本文感兴趣,请点击“原文阅读”获取知识星球二维码,务必按照“姓名+学校/公司+研究方向”备注加入免费知识星球,免费下载pdf文档,和更多热爱分享的小伙伴一起交流吧!

以上内容如有错误请留言评论,欢迎指正交流。如有侵权,请联系删除

扫描二维码

                   关注我们

让我们一起分享一起学习吧!期待有想法,乐于分享的小伙伴加入免费星球注入爱分享的新鲜活力。分享的主题包含但不限于三维视觉,点云,高精地图,自动驾驶,以及机器人等相关的领域。

分享及合作:群主微信“920177957”(需要按要求备注) 联系邮箱:[email protected],欢迎企业来联系公众号展开合作。

点一下“在看”你会更好看耶

更多相关:

  • 教程简介 OpenCV 是计算机视觉中经典的专用库,然而其中文版官方教程久久不来。近日,一款最新 OpenCV4.1 版本的完整中文版官方教程出炉,读者朋友可以更好的学习了解 OpenCV 相关细节。教程来自 objectdetection.cn 。 教程目录 OpenCV 简介 0_OpenCV-Python Tutorials O...

  • 公众号致力于分享点云处理,SLAM,三维视觉,高精地图相关的文章与技术,欢迎各位加入我们,一起每交流一起进步,有兴趣的可联系微信:920177957。本文来自点云PCL博主的分享,未经作者允许请勿转载,欢迎各位同学积极分享和交流。IPM模型在解释自适应的IPM模型之前,首先需要了解使用相机的物理参数来描述IPM的基本模型[1](这篇...

  • 公众号致力于分享点云处理,SLAM,三维视觉,高精地图相关的文章与技术,欢迎各位加入我们,一起每交流一起进步,有兴趣的可联系微信:920177957。本文来自点云PCL博主的分享,未经作者允许请勿转载,欢迎各位同学积极分享和交流。前言前段时间刚分享的AVP-SLAM文章中有一个知识点叫做IPM(逆透视变换)AVP-SLAM:自动泊车...

  • 标题:The algorithm to generate color point-cloud with the registration between panoramic imageand laser point-cloud作者:Fanyang ZENG, Ruofei ZHONG 编译:点云PCL来源: https://iops...

  • 目前深度图像的获取方法有激光雷达深度成像法,计算机立体视觉成像,坐标测量机法,莫尔条纹法,结构光法等等,针对深度图像的研究重点主要集中在以下几个方面,深度图像的分割技术 ,深度图像的边缘检测技术 ,基于不同视点的多幅深度图像的配准技术,基于深度数据的三维重建技术,基于三维深度图像的三维目标识别技术,深度图像的多分辨率建模和几何压缩技术...

  • 看龙书的时候发现一个矩阵在传入Shader之前都要转置一下,很好奇为什么要有一步这样的操作。行主序和列主序行主序指矩阵在内存中逐行存储,列主序指矩阵在内存中逐列存储。行主序矩阵内存布局:列主序矩阵内存布局:行向量和列向量行向量指的是把向量当成一个一行n列的矩阵,列向量指的是把向量当成一个n行一列的矩阵。左乘和右乘矩阵“左乘”:矩阵和向...

  • ORB-SLAM点云地图中相机的位姿初始化,无论算法工作在平面场景,还是非平面场景下,都能够完成初始化的工作。其中主要是使用了适用于平面场景的单应性矩阵H和适用于非平面场景的基础矩阵F,程序中通过一个评分规则来选择适合的模型,恢复相机的旋转矩阵R和平移矩阵t那么下面主要讲解关于对极几何中的基础矩阵,本质矩阵,和单应矩阵之间的区别与联...

  • 矩阵可分为稠密矩阵和稀疏矩阵,对于稀疏矩阵而言,使用同样的内存来存储这个矩阵显然是对内存的浪费,那么我们就可以想办法将矩阵中所有的o元素挥着不相关元素剔除,怎么剔除,第一种方法是通过三个一维矩阵来存储原二维矩阵中的所有非0元素,三个矩阵分别为value、column、row, value 数组存储所有的非零元素, column 数...

  • void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const; m – 目标矩阵。如果m在运算前没有合适的尺寸或类型,将被重新分配。rtype – 目标矩阵的类型。因为目标矩阵的通道数与源矩阵一样,所以rtype也可以看做是目标...

  • https://blog.csdn.net/jiangdf/article/details/8460012 glMatrixMode()函数的参数,这个函数其实就是对接下来要做什么进行一下声明,也就是在要做下一步之前告诉计算机我要对“什么”进行操作了,这个“什么”在glMatrixMode的“()”里的选项(参数)有3种模式: GL...