当前位置: 首页 > news >正文

摄像机模型与标定——标定函数

转载:http://blog.csdn.net/gdut2015go/article/details/48251683

摄像机内参数,能够让我们将3D坐标转换为2D图像坐标。

说明:要理解下面的函数中参数的真实用法还需要阅读一下相机标定程序。

摄像机标定函数:

void cvCalibrateCamera2(  
CvMat* object_points,  
CvMat* image_points,  
int* point_counts,  
CvSize image_size,  
CvMat* intrinsic_matrix,  
CvMat* distortion_coeffs,  
CvMat* rotation_vectors = NULL,  
CvMat* translation_vectors = NULL,  
int flags = 0  
); 


1、object_points,是一个N×3的矩阵,如果对于每一个棋盘,我们有k个角点,并且我们通过旋转棋盘,得到棋盘的M的视场图,那么此时N=k×M。
在使用棋盘的场合,我们另点z的坐标值为0,而x,y坐标用里面来度量,选用英寸单位,那么所有参数计算的结果也是用英寸表示。类似地,如果设置所有x坐标为0(而不是z坐标),那么意味着与摄像机相关的棋盘位置将主要在x方向上而不是在z方向上。棋盘上的正方形定义了一个单位,即如果正方形的边长为90mm,那么物体和摄像机坐标单位应该是mm/90。最简单的方式是我们定义棋盘的每一个方块为一个单位。

2、image_points,是一个N×2的矩阵。包含object_points所提供的所有点的坐标。即算法在图像中寻找到的角点的坐标。

3、point_counts,每个图像上角点的个数,以M×1矩阵形式提供,M是视场的数目

4、image_size,图像的大小,以像素为衡量单位。

5、intrinsic_matrix,摄像机内参数矩阵3×3大小。可以作为输入变量(此时会影响计算的结果),可以作为输出变量(本来主要就是为了求解该参数),内参数矩阵完全定义了理想摄像机模型的摄像机行为。

6、distortion_matrix,畸变系数,为5×1大小的矢量,可以作为输入变量,可以作为输出变量(同上),畸变系数的记录顺序是:k1,k2,p1,p2,k3;

7、rotation_vectors,大小为M×3,M为视场的个数。旋转矢量的讲解参考上一篇文章。可以通过cvRodrigues2()将旋转矢量转换为旋转矩阵。

8、translation_vectors,大小为M×3矩阵。


函数中的标志位:

1、CV_CALIB_USE_INTRINSIC_GUESS  cvCalibrateCamera2()计算内参数矩阵的时候,通常不需要额外的信息。具体来说,参数cx和cy(图像中心)的初始值可以直接从变量image_size中得到(即(H-1)/2,(W-1)/2)),如果设置了该变量那么instrinsic_matrix假设包含正确的值,并被用作初始猜测,为cvCalibrateCamera2()做优化时所用。

2、CV_CALIB_USE_PRINCIPAL_POINT 可以和CV_CALIB_USE_INTRINSIC_GUESS 一起使用。如果仅设置了该标志位,那么设置图像的中心作为主点。如果一起使用,则设置主点位置为intrinsic_matrix矩阵提供的初始值。(这也是为什么,instrinsic_matrix不仅可以作为输出,也可以作为输入的原因了)

3、CV_CALIB_FIX_ASPECT_RATIO 如果设置了该标志位,那么在调用标定程序时,优化过程只同时改变fx和fy,而固定intrinsic_matrix的其他值(如果 CV_CALIB_USE_INTRINSIC_GUESS也没有被设置,则intrinsic_matrix中的fx和fy可以为任何值,但比例相关)。

4、CV_CALIB_FIX_FOCAL_LENGTH 该标志位在优化的时候,直接使用intrinsic_matrix传递过来的fx和fy。

5、CV_CALIB_FIX_K1,CV_CALIB_FIX_K2,CV_CALIB_FIX_K3 固定径向畸变k1,k2,k3。径向畸变参数可以通过组合这些标志设置为任意值。一般地最后一个参数应设置为0,初始使用鱼眼透镜。

6、CV_CALIB_ZERO_TANGENT_DIST 该标志在标定高级摄像机的时候比较重要,因为精确制作将导致很小的径向畸变。试图将参数拟合0会导致噪声干扰和数值不稳定。通过设置该标志可以关闭切向畸变参数p1和p2的拟合,即设置两个参数为0。


只计算外参数

函数cvFindExtrinsicCameraParam2()只计算外参数,接口如下:


void cvFindExtrinsicCameraParams2(  
const CvMat* object_points,  
const CvMat* image_points,  
const CvMat* intrinsic_matrix,  
const CvMat* distortion_coeffs,  
CvMat* rotation_vector,  
CvMat* translation_vector  
);  


函数的形参和标定函数是一样的,只是内参数矩阵和畸变系数是直接提供,而非计算得到的。

矫正

标定摄像机通常想做两件事情:

1)矫正畸变效应

2)根据获得的图像重构三维场景

“矫正”是数学上去掉透镜畸变

“校正”是数学上将图像排列整齐。

OpenCV提供了直接使用的校正算法,下面两个方法均能完成矫正:

1)直接一次性调用函数cvUndistort2()完成。

2)通过函数cvInitUndistortMap()和cvRemap()来更有效的处理,通常适合处理视频,或从同一个摄像机得到多个图像的应用。(其实很好理解的,我们利用一帧图像计算畸变映射,将后面的图像帧均利用该映射,并且计算畸变映射是一个耗时的操作)。

cvInitUndistortMap()函数计算畸变映射。
cvRemap()表示在任意图像上应用该映射。


// Undistort images  
void cvInitUndistortMap(  
const CvMat* intrinsic_matrix,//内参数矩阵  
const CvMat* distortion_coeffs,//畸变系数  
cvArr* mapx,//32位单通道矩阵  
cvArr* mapy  
);  
void cvRemap(  
const CvArr* src,  
CvArr *dst,  
const CvArr *mapx,  
const CvArr *mapy,  
int flags=CV INTER LINEAR+CV WARP FILL OUTLIERS,  
CvScalar fillval=cvScalarAll(0) );  
void cvUndistort2(  
const CvArr* src,  
CvArr* dst,  
const cvMat* intrinsic_matrix,  
const cvMat* distortion_coeffs  
);  
// Undistort a list of 2D points only  
void cvUndistortPoints( //函数的功能:将一些列来至于原始图像的2维点坐标并且计算相应的矫正点坐标。  
const CvMat* _src,   
CvMat* dst,   
const CvMat* intrinsic_matrix,   
const CvMat* distortion_coeffs,  
const CvMat* R = 0,//R表示两个摄像机之间的旋转矩阵  
const CvMat* Mr = 0; //Mr表示矫正后的摄像机内参数。  
); 


相关文章:

  • 摄像机模型与标定——三个坐标系及其之间关系
  • 推导四对对应点单应矩阵的计算公式?
  • 透视投影中已知两平面的单应矩阵,能否求出这两平面的夹角?
  • 相机标定的网页收纳
  • 机器视觉的相机标定到底是什么?
  • 摄像机标定--矫正畸变
  • 机器学习(Machine Learning)深度学习(Deep Learning)资料汇总
  • 机器学习(Machine Learning)深度学习(Deep Learning)资料(下)
  • 【深度学习Deep Learning】资料大全
  • 【机器学习Machine Learning】资料大全
  • 深度学习
  • 深度学习框架的评估与比较
  • R-CNN,SPP-NET, Fast-R-CNN,Faster-R-CNN, YOLO, SSD系列深度学习检测方法梳理
  • 【深度学习:目标检测】CVPR 2016:目标检测领域的新进展
  • 【深度学习:目标检测】深度学习检测方法梳理:R-CNN,SPP-NET, Fast-R-CNN,Faster-R-CNN, YOLO, SSD系列
  • #Java异常处理
  • Flannel解读
  • httpie使用详解
  • Meteor的表单提交:Form
  • Python socket服务器端、客户端传送信息
  • 订阅Forge Viewer所有的事件
  • 来,膜拜下android roadmap,强大的执行力
  • 如何学习JavaEE,项目又该如何做?
  • 实现菜单下拉伸展折叠效果demo
  • 手写双向链表LinkedList的几个常用功能
  • ​香农与信息论三大定律
  • #Linux(Source Insight安装及工程建立)
  • #QT(一种朴素的计算器实现方法)
  • #在 README.md 中生成项目目录结构
  • ${factoryList }后面有空格不影响
  • (2)Java 简介
  • (ZT)一个美国文科博士的YardLife
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (附源码)ssm高校志愿者服务系统 毕业设计 011648
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (排序详解之 堆排序)
  • (三)uboot源码分析
  • (一一四)第九章编程练习
  • (转)重识new
  • (转载)OpenStack Hacker养成指南
  • .htaccess配置常用技巧
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .NET MVC第五章、模型绑定获取表单数据
  • .NET 中使用 Mutex 进行跨越进程边界的同步
  • @GetMapping和@RequestMapping的区别
  • @Mapper作用
  • [100天算法】-二叉树剪枝(day 48)
  • [20161101]rman备份与数据文件变化7.txt
  • [Apio2012]dispatching 左偏树
  • [C#] 如何调用Python脚本程序
  • [C#]无法获取源 https://api.nuge t.org/v3-index存储签名信息解决方法
  • [C语言]编译和链接
  • [Docker]十一.Docker Swarm集群raft算法,Docker Swarm Web管理工具
  • [emuch.net]MatrixComputations(7-12)
  • [HTML]Web前端开发技术18(HTML5、CSS3、JavaScript )HTML5 基础与CSS3 应用——喵喵画网页