基于opencv的鱼眼矫正法-棋盘标定
2016-12-04 15:34
393 查看
<网页blog已经上线,一大波干货即将来袭:https://faiculty.com/>
这篇文章主要谈论了基于opencv的棋盘标定法的鱼眼矫正步骤。
这篇文章主要参考博客:棋盘标定。感谢博主。
主要矫正函数:opencv:fisheye
具体的有关理论可以移步到:
注意:
多张带棋盘(棋盘是一样的)鱼眼图像,只是简单的重复取样。
需要知道棋盘的每行每列角点数 ,比如 Size board_size = Size(9,6)
需要知道棋盘格小的大小Size square_size = Size(20,20)
这个步骤利用cvtColor函数:
2. 提取角点:
这个步骤可以直接用findChessboardCorners函数:
2. 把每张图像得到的coroners保存下来
每个vector元素是一行角点的坐标。计算可以根据以下两个条件:
每行每列的角点数
棋盘格的大小
函数定义如下:
注意这几个函数的输入:
K:这个是相机的内参矩阵3x3
D: 这个是畸变系数
R: 这个是旋转矩阵(摄像头与水平面的夹角)
P:新的camera maxtrix,新的参数矩阵。我们可以通过调节它来控制我们的视野,具体怎么做下文有参考,理论来源于哪里(请移步摄像机成像原理)
size:就是你要求输出的图像size
m1type:输出映射矩阵的类型 (也就是后面map的类型)
map1:映射矩阵1
map2: 映射矩阵2,有了这两个映射矩阵我们就可以在后面用remap来映射出图像
得到参数后的矫正公式如下:
内参模型:
矫正:
新的new camera matrix矩阵的作用:
fx、fy:fx,fy变大(小),视场变小(大),裁剪较多(少),但细节清晰(模糊);
cx、cy这个是圆心坐标
通过控制new camera matrix可以控制畸变矫正图像的范围。
这篇文章主要谈论了基于opencv的棋盘标定法的鱼眼矫正步骤。
这篇文章主要参考博客:棋盘标定。感谢博主。
主要矫正函数:opencv:fisheye
序言
棋盘标定法需要预先求得内参矩阵和畸变矩阵,之后同一摄像头拍摄的鱼眼图像就可以直接根据他们之间的变换关系确定。具体的有关理论可以移步到:
一、程序环境
openCV3.1 + VS2013 + win10二、角点检测
2.1 输入图像
为了提高我们的标定参数精度,我们输入多张带棋盘的鱼眼图像。注意:
多张带棋盘(棋盘是一样的)鱼眼图像,只是简单的重复取样。
需要知道棋盘的每行每列角点数 ,比如 Size board_size = Size(9,6)
需要知道棋盘格小的大小Size square_size = Size(20,20)
2.2 提取角点坐标
1.先把彩色图像变成灰度图:这个步骤利用cvtColor函数:
void cvCvtColor(const CvArr* src, CvArr* dst, int code) Parameters: src – Source image: 8-bit unsigned, 16-bit unsigned ( CV_16UC... ), or single-precision floating-point. dst – Destination image of the same size and depth as src . code – Color space conversion code. See the description below. dstCn – Number of channels in the destination image. If the parameter is 0, the number of the channels is derived automatically from src and code . /* 例如 */ cvtColor(image, imageGray , CV_RGB2GRAY);
2. 提取角点:
这个步骤可以直接用findChessboardCorners函数:
findChessboardCorners(image, board_size, corners,CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE+ CALIB_CB_FAST_CHECK ); /* 函数的具体参数可以参考openCV手册 */
2.3. 亚像素精确化
这个步骤可以直接用CornerSubPix函数:cornerSubPix(imageGray, corners, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1)); /* 函数的具体参数可以参考openCV手册 */ /* 然后标记角点,可以在角点周围画一个圆: */ for (int j = 0; j < corners.size(); j++) { circle( imageTemp, corners[j], 10, Scalar(0,0,255), 2, 8, 0); }
2.4. 保存好找到角点
1. 把标定好的图像另存为。。。2. 把每张图像得到的coroners保存下来
三、摄像机标定
摄像机的标定主要是利用fisheye::calibrate()函数,所以后面的工作将围绕函数所需要的参数展开,函数定义如下:double cv::fisheye::calibrate ( InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, const Size & image_size, InputOutputArray K, InputOutputArray D, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, int flags = 0, TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 100, DBL_EPSILON) ) /* 参数定义如下: */
3.1 objectPoints参数
这个参数是角点在棋盘中的三维坐标(令Z = 0),是一个元素为Vector的Vector类型,定义如下:vector<vector<Point3f>> object_Points; /** 保存定标板上角点的三维坐标 **/
每个vector元素是一行角点的坐标。计算可以根据以下两个条件:
每行每列的角点数
棋盘格的大小
3.2 imagePoints参数
这个参数是角点在图像中的坐标,在之前我们已经保存好的。这个也是一个元素为Vector的Vector类型类型,定义如下:vector<vector<Point2f>> corners_Seq; /** 保存检测到的所有角点 **/
3.3 image_size参数
可以用每张图像的size大小,一般都设定为原图的大小。3.4 K参数
摄像机内参数矩阵。这个是个输出的结果,所以初始化一个矩阵就可以了。cv::Matx33d intrinsic_matrix;
3.5 D参数
畸变参数。也是输出参数。cv::Vec4d distortion_coeffs;
3.6 rvecs参数
图像输出的旋转参数。这也是输出结果。std::vector<cv::Vec3d> rotation_vectors;
3.7 tvecs参数
这个是图像的平移参数,这也是输出结果。std::vector<cv::Vec3d> translation_vectors;
3.8 flag
int flags = 0; flags |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC; flags |= cv::fisheye::CALIB_CHECK_COND; flags |= cv::fisheye::CALIB_FIX_SKEW; fisheye::calibrate(object_Points, corners_Seq, image_size, intrinsic_matrix, distortion_coeffs, rotation_vectors, translation_vectors, flags, cv::TermCriteria(3, 20, 1e-6));
四、矫正图像
得到参数后,我们把原图做映射,得到矫正后的图像。4.1 initUndistortRectifyMap
这个函数大概的思路就是从目标图像触发找到对应的原始图像的坐标,然后将其值复制到目标图像。函数定义如下:
注意这几个函数的输入:
K:这个是相机的内参矩阵3x3
D: 这个是畸变系数
R: 这个是旋转矩阵(摄像头与水平面的夹角)
P:新的camera maxtrix,新的参数矩阵。我们可以通过调节它来控制我们的视野,具体怎么做下文有参考,理论来源于哪里(请移步摄像机成像原理)
size:就是你要求输出的图像size
m1type:输出映射矩阵的类型 (也就是后面map的类型)
map1:映射矩阵1
map2: 映射矩阵2,有了这两个映射矩阵我们就可以在后面用remap来映射出图像
得到参数后的矫正公式如下:
内参模型:
矫正:
新的new camera matrix矩阵的作用:
fx、fy:fx,fy变大(小),视场变小(大),裁剪较多(少),但细节清晰(模糊);
cx、cy这个是圆心坐标
通过控制new camera matrix可以控制畸变矫正图像的范围。
4.2 remap
这个函数做的工作就是映射。根据前面得到的map1 map2做图像的映射。然后做插值操作。相关文章推荐
- 张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)
- 张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)
- 张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)
- 张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)
- 张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)
- 张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)
- 基于OpenCv的摄像机立体标定和立体矫正的源代码
- 张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)
- 张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)
- 张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)(单目)
- 张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)
- Opencv学习笔记 ---opencv生成摄像头标定棋盘
- 【opencv】openCV生成标定相机用的黑白棋盘
- MATLAB双目标定与OpenCV计算矫正参数矩阵
- 使用OpenCV进行相机标定(基于OpenCV2.4.3)
- 基于EmguCV的摄像机标定及矫正
- 机器视觉学习笔记(7)——基于OpenCV的双目摄像机标定
- 基于matlab标定数据,使用opencv实现双目立体摄像头的标定(源代码)
- 基于OpenCV的立体相机标定StereoCalibration与目标三维坐标定位
- [opencv] 生成标定棋盘格