opencv的单应矩阵相机标定
来源:互联网 发布:什么是php技术 编辑:程序博客网 时间:2024/04/30 06:21
给定同一相机在不同角度拍摄的不同照片,如何标定计算机的内参(焦距、主点)、外参(主要是旋转矩阵)?
opencv的图片拼接demo stitching_detailed中有示例
主要过程:
1.surf /orb算法查找两个图片的特征点;
2.匹配两个图片的特征点,匹配过程中使用RANSAC算法计算单应矩阵;
3.根据单应矩阵计算焦距;
4.根据单应矩阵、焦距等参数计算旋转矩阵;
5.计算主点.
1.单应矩阵计算
单应矩阵是在匹配特征点的过程中得到的
BestOf2NearestMatcher::match->cvFindHomography->runRANSAC关键过程:
1)cvConvertPointsHomogeneous
二维坐标转齐次坐标,方便计算H矩阵,这里只是做了简单的行列转换,并增加了一列。
2)estimator.runRANSAC
运行RANSAC算法,目标是找到两福图像特征点之间的映射关系,也就是单应矩阵H,
基本原理:
从两幅图像的特征点中随机找到4对不同的特征点,每对特征点齐次坐标对记为(p1,p2),然后计算矩阵方程的p1=H*p2解,也就是H的估计值,然后把所有特征点代入,记录每次得到的内点(也就是符合解的点)的数量,
迭代若干次(初始2000次,根据RANSAC算法会指数性减少),每次都记录内点数最多的解,最终将内点最多的解作为单应矩阵H的最优解。
关键过程:
<1> CvModelEstimator2::getSubset 从输入的特征点中获取随机4对特征点,这些特征点要满足在各自图像上不能在同一直线(否则方程可能无法求解),为找到这些点需要迭代最多300次,调用checkSubset检查直线;
<2> CvHomographyEstimator::runKernel 求解4对特征点构成的8个方程组,得到一次H矩阵的解,H矩阵是3×3矩阵,归一化后剩余8个未知数,一对特征点产生两个方程,所以需要4个特征点对产生8个方程
<3> CvModelEstimator2::findInliers 根据得到的H估计解,代入所有特征点,计算内点,返回内点数、内点mask等,之后会根据每次返回的最大内点数,确定H的最优解;
<4> cvRANSACUpdateNumIters 通过置信度、当前解的内点数等参数更新需要迭代的次数,会从初始的2000次指数性降低。
之后opencv会对返回的内点mask将原来两幅图的特征点放入返回的MatchesInfo结构中,并且再次对这些内点计算其单应矩阵,作为最终的H矩阵。
BestOf2NearestMatcher::match
2.根据单应矩阵估计内参:焦距
HomographyBasedEstimator::estimate->estimateFocal->focalsFromHomography直接用公式根据H矩阵计算得到焦距。
原理:
参考《Construction of Panoramic Image Mosaics with Global and Local Alignment.pdf》第3.2节以及第5节
基本解释:
同一个空间点P(x,y,z)在两个图像上的点分别为P1(x1,y1),P2(x2,y2),根据相机坐标系和世界坐标系变换公式:P1=K1*R1*P,P2=K2*R2*P,其中Ki,Ri分别为两个图像对应的相机的内参和旋转矩阵,
由于空间P是同一个点,那么P1=K1*R1*R2的逆*K2的逆*P2=K1*R12*K2的逆*P2,已知P1P2的单应矩阵H(通过RANSAC算法求出),那么H=K1*R12*K2的逆,Ki作为内参主要有焦距和主点,主点可以忽略,
R12为图像1到图像2的旋转矩阵,那么H矩阵中只包含旋转矩阵和焦距参数,根据旋转矩阵的正交性,可以求解得到焦距,使焦距成为H矩阵各个元素的表达式,从而求得焦距的估计值。
opencv对每幅图像求一个焦距然后取其中间值作为warp球体的半径。
3.计算外参:旋转矩阵
在HomographyBasedEstimator::estimate中除了估算焦距之外,还估算了旋转矩阵:findMaxSpanningTree(num_images, pairwise_matches, span_tree, span_tree_centers);
span_tree.walkBreadthFirst(span_tree_centers[0], CalcRotation(num_images, pairwise_matches, cameras));
findMaxSpanningTree:
由于可能输入多个图像,产生了多个匹配特征点的MatchesInfo结构,每个MatchesInfo包含两幅图像之间匹配的特征点(内点)以及H矩阵,需要确定这些图像之间的邻接关系,
这里以两幅图像之间的内点数量为权值构建最大生成树,保证这样的一个图片序列两两之间的内点数最多,也就最有可能是邻接的;
span_tree.walkBreadthFirst:
用广度优先遍历这棵最大生成树,分别计算每两个邻接图像(也就是每个相机)的旋转矩阵R。
原理:
根据上面的公式:H=K1*R12*K2的逆,R12=K1的逆*H*K2,R1=R2*R12=R2*K1的逆*H*K2,已知上幅图像的R、两个相机的内参Ki(焦距、主点)、两幅图的单应矩阵H,可以求得下幅图的R。
4.计算内参:主点
简单设置为图像的中心位置 0 0
- opencv的单应矩阵相机标定
- 【OpenCV】单目相机标定 / 双目相机标定
- 基于opencv的相机标定
- 单目相机的标定
- 相机标定——基于张正友标定标定法与MFC的单目相机标定
- OpenCV,计算两幅图像的单应矩阵
- OpenCV,计算两幅图像的单应矩阵
- 利用OpenCV进行相机标定的源代码
- 利用OpenCV进行相机标定的源代码
- OpenCV标定相机的测试程序.
- 极简OpenCV的相机标定代码
- 基于OPENCV的相机标定及代码
- opencv 单目相机标定 自带例子程序的使用
- 基于OpenCV单目相机的快速标定--源码、工程、实现过程
- 双目相机标定之OpenCV获取左右相机图像+MATLAB单目标定+双目标定
- 使用opencv标定单目相机(张正友法)代码实现
- OpenCV相机标定函数
- OPenCV相机标定函数
- 工厂方法
- windows XAMPP环境下安装phpredis扩展
- iOS开发多线程篇
- 求两个整数的最大公约数
- ecshop建站流程
- opencv的单应矩阵相机标定
- nodejs用expressjs框架搭建多人博客(一)
- Ubuntu下vim的小技巧
- js es6 let命令
- K-means 与 KNN
- Hive – Distinct 的实现
- 森林转二叉树(Vijos1180 选课)
- Retrofit网络连接
- Java中的反射机制(1)