双目相机标定、校正及匹配过程

0、两条路线

  1. 先单目标定再双目标定:
    1. findChessboardCorners:寻找棋盘图中棋盘角点
    2. find4QuadCornerSubpix:对粗提取的角点进行精确化
    3. cornerSubPix:在角点检测中精确化角点位置
    4. drawChessboardCorners:将发现到的所有角点绘制到所提供的图像上
    5. calibrateCamera:利用定标来计算摄像机的内参数和外参数
    6. projectPoints:通过得到的摄像机内外参数,对空间的三维点进行重新投影计算,得到新的投影点
    7. 利用标定结果对棋盘图进行矫正
      (1). initUndistortRectifyMap用来计算畸变映射,remap把求得的映射应用到图像上
      (2). 或者undistort一个函数搞定
    8. stereoCalibrate:双目摄像机标定,计算了两个摄像头进行立体像对之间的转换关系,根据左右相机的参数矩阵,生成两个相机之间的关系矩阵,以及基本和本质矩阵
    9. stereoRectify:作用是为每个摄像头计算立体校正的映射矩阵。所以其运行结果并不是直接将图片进行立体矫正,而是得出进行立体矫正所需要的映射矩阵
  2. 直接进行双目标定
    1. findChessboardCorners找到角点
    2. drawChessboardCorners画出角点
    3. stereoCalibrate直接计算左右相机内参矩阵、畸变量、R、T、E、F
      1. undistortPoints去畸变
      2. computeCorrespondEpilines
    4. stereoRectify
    5. initUndistortRectifyMap
    6. remap

路线2的精度会下降
在这里插入图片描述

一、单目标定

1.提取角点(findChessboardCorners)

从文件中读入图像,通过findChessboardCorners找到角点的图像坐标系坐标,这个函数采用Harris算法获得角点。

CV_EXPORTS_W bool findChessboardCorners(InputArray image, 
										Size patternSize, 
										OutputArray corners,
                                        int flags = CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE );

参数说明:

  1. Image:输入的棋盘图,必须是8位的灰度或者彩色图像,类型为cv::Mat
  2. patternSize:棋盘图中每行和每列角点的个数,类型为cv::Size()
  3. corners:检测到的角点,类型为std::vector< cv::Point2f >。
  4. flags :不同的操作标记
    1. CALIB_CB_ADAPTIVE_THRESH:1,使用自适应阈值法把图像转换为黑白图,而不是使用一个固定的阈值。
    2. CALIB_CB_NORMALIZE_IMAGE:2,在利用固定阈值或自适应阈值法二值化图像之前,利用直方图均衡化图像。
    3. CALIB_CB_FILTER_QUADS:4,使用额外的标准(如轮廓面积,周长,正方形形状)来过滤掉在轮廓检索阶段提取的假四边形。
    4. CALIB_CB_FAST_CHECK:8,对图像运行一个快速检查机制以查找棋盘板的角点,如果没有找到角点则返回一个快捷提醒。当没有观察到棋盘时,可以极大地加快在退化条件下的调用。
bool ok = findChessboardCorners(imageInput, board_size, image_points, CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE);

2.对提取到的角点进行亚像素精确化(find4QuadCornerSubpix或cornerSubPix)

两种方法,可取其一

2.1 find4QuadCornerSubpix

bool cv::find4QuadCornerSubpix  ( 	InputArray  img,  
  									InputOutputArray  corners,  
  									Size  region_size  
 ) 

参数说明:
img:输入的Mat矩阵,最好是8位灰度图像,检测效率更高;
corners:初始的角点坐标向量,同时作为亚像素坐标位置的输出,所以需要是浮点型数据,一般用元素是Pointf2f/Point2d的向量来表示。
region_size:角点搜索窗口的尺寸,优化坐标时考虑的邻域范围。

find4QuadCornerSubpix(view_gray, image_points, Size(5, 5));

2.2 cornerSubPix

在角点检测中精确化角点位置,其函数原型如下:

void cornerSubPix(	InputArray image, 
					InputOutputArray corners, 
					Size winSize, 
					Size zeroZone, 
					TermCriteria criteria);

函数参数说明如下:

image:输入图像

corners:输入角点的初始坐标以及精准化后的坐标用于输出。

winSize:搜索窗口边长的一半,例如如果winSize=Size(5,5),则一个大小为的搜索窗口将被使用。

zeroZone:搜索区域中间的dead region边长的一半,有时用于避免自相关矩阵的奇异性。如果值设为(-1,-1)则表示没有这个区域。

criteria:角点精准化迭代过程的终止条件。也就是当迭代次数超过criteria.maxCount,或者角点位置变化小于criteria.epsilon时,停止迭代过程。

cv::TermCriteria criteria = cv::TermCriteria(cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS, 100, 1e-5);
cv::cornerSubPix(view_gray, image_points, cv::Size(5, 5), cv::Size(-1, -1), criteria);

3.显示角点(drawChessboardCorners)

使用**drawChessboardCorners()**函数进行棋盘格绘制显示

void cv::drawChessboardCorners(
								cv::InputOutputArray image, // 棋盘格图像(8UC3)即是输入也是输出
								cv::Size patternSize, // 棋盘格内部角点的行、列数
								cv::InputArray corners, // findChessboardCorners()输出的角点
								bool patternWasFound // findChessboardCorners()的返回值
									);

参数说明:

  1. image:棋盘格图像(8UC3),既是输入也是输出
  2. patternSize:棋盘格内部角点的行、列,和cv::findChessboardCorners()指定的相同
  3. corners:检测到的棋盘格角点
  4. patternWasFound :cv::findChessboardCorners()的返回值
drawChessboardCorners(imageInput, this->board_size, image_points, ok);

4.单目相机标定(calibrateCamera)

【OpenCV3学习笔记 】相机标定函数 calibrateCamera( ) 使用详解(附相机标定程序和数据)
求解出该相机的内参数和每一个视角的外参数。

double cv::calibrateCamera  (   
								InputArrayOfArrays objectPoints,
								InputArrayOfArrays imagePoints,
								Size imageSize,
								InputOutputArray cameraMatrix,
								InputOutputArray distCoeffs,
								OutputArrayOfArrays rvecs,
								OutputArrayOfArrays tvecs,
								int flags = 0,
								TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON) 
)  

参数说明:

  1. objectPoints :世界坐标系中的点。在使用时,应该输入vector< vector< Point3f > >。
  2. imagePoints :其对应的图像点。和objectPoints一样,应该输入vector< vector< Point2f > >型的变量
  3. imageSize :图像的大小,在计算相机的内参数和畸变矩阵需要用到
  4. cameraMatrix :内参数矩阵。输入一个Mat cameraMatrix即可。
  5. distCoeffs :畸变矩阵。输入一个Mat distCoeffs即可。
  6. rvecs :旋转向量;应该输入一个Mat的vector,即vector< Mat > rvecs。因为每个vector< Point3f >会得到一个rvecs。
  7. tvecs :位移向量;和rvecs一样,也应该为vector< Mat >。
  8. flags :标定函数是所采用的模型(重点)
    1. CV_CALIB_USE_INTRINSIC_GUESS:使用该参数时,将包含有效的fx,fy,cx,cy的估计值的内参矩阵cameraMatrix作为初始值输入,然后函数对其做进一步优化。如果不使用这个参数,用图像的中心点初始化光轴点坐标(cx, cy),使用最小二乘估算出fx,fy(这种求法好像和张正友的论文不一样,不知道为何要这样处理)。注意,如果已知内部参数(内参矩阵和畸变系数),就不需要使用这个函数来估计外参,可以使用solvepnp()函数计算外参数矩阵
    2. CV_CALIB_FIX_PRINCIPAL_POINT:在进行优化时会固定光轴点,光轴点将保持为图像的中心点。当CV_CALIB_USE_INTRINSIC_GUESS参数被设置,保持为输入的值。
    3. CV_CALIB_FIX_ASPECT_RATIO:固定fx/fy的比值,只将fy作为可变量,进行优化计算。当CV_CALIB_USE_INTRINSIC_GUESS没有被设置,fx和fy的实际输入值将会被忽略,只有fx/fy的比值被计算和使用。
    4. CV_CALIB_ZERO_TANGENT_DIST:切向畸变系数(P1,P2)被设置为零并保持为零。
    5. CV_CALIB_FIX_K1,…,CV_CALIB_FIX_K6:对应的径向畸变系数在优化中保持不变。如果设置了CV_CALIB_USE_INTRINSIC_GUESS参数,就从提供的畸变系数矩阵中得到。否则,设置为0。
    6. CV_CALIB_RATIONAL_MODEL(理想模型):启用畸变k4,k5,k6三个畸变参数。使标定函数使用有理模型,返回8个系数。如果没有设置,则只计算其它5个畸变参数。
    7. CALIB_THIN_PRISM_MODEL (薄棱镜畸变模型):启用畸变系数S1、S2、S3和S4。使标定函数使用薄棱柱模型并返回12个系数。如果不设置标志,则函数计算并返回只有5个失真系数。
    8. CALIB_FIX_S1_S2_S3_S4 :优化过程中不改变薄棱镜畸变系数S1、S2、S3、S4。如果cv_calib_use_intrinsic_guess设置,使用提供的畸变系数矩阵中的值。否则,设置为0。
    9. CALIB_TILTED_MODEL (倾斜模型):启用畸变系数tauX and tauY。标定函数使用倾斜传感器模型并返回14个系数。如果不设置标志,则函数计算并返回只有5个失真系数。
    10. CALIB_FIX_TAUX_TAUY :在优化过程中,倾斜传感器模型的系数不被改变。如果cv_calib_use_intrinsic_guess设置,从提供的畸变系数矩阵中得到。否则,设置为0。
  9. criteria: 迭代优化算法的终止准则

函数返回:重投影的总的均方根误差。

在相机标定之后,可以得到相机内参数矩阵与畸变系数cameraMatrix,distCoeffs

5.重投影计算(projectPoints)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值