OpenCV相机标定
OpenCV相机标定
相机内参矩阵cameraMatrix
\[cameraMatrix = \begin{bmatrix}
f_x & 0 & c_x \\
0 & f_y & c_y \\
0 & 0 & 1
\end{bmatrix}
\]
相机畸变系数distCoeffs
畸变系数:径向畸变\((k_1,k_2,k_3)\), 切向畸变\((p_1,p_2)\)
\[distCoeffs = \begin{pmatrix}
k_1 & k_2 & p_1 & p_2 & k_3
\end{pmatrix}
\]
findChessboardCorners
棋盘格角点检测
#include <opencv2/calib3d.hpp>
bool cv::findChessboardCorners(
InputArray image,
Size patternSize,
OutputArray corners,
int flags = CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE
)
Python:
retval, corners = cv.findChessboardCorners(image, patternSize[, corners[, flags]])
image:输入 棋盘格图像,必须是8位灰度或彩色图像(cv::Mat)
patternSize:输入 棋盘图内角点的行列数(注意:不是棋盘格的行列数,如棋盘格的行列数分别为4、8,而内部角点的行列数分别是3、7,因此这里应该指定为cv::Size(3, 7))(cv::Size)corners:输出 检测到的棋盘格角点(std::vector<cv::Point2f>)flags:输入 用于指定在检测棋盘格角点的过程中所应用的一种或多种过滤方法(int):cv::CALIB_CB_ADAPTIVE_THRESH:使用自适应阈值将图像转化成二值图像cv::CALIB_CB_NORMALIZE_IMAGE:归一化图像灰度系数(用直方图均衡化或者自适应阈值)cv::CALIB_CB_FILTER_QUADS:在轮廓提取阶段,使用附加条件排除错误的假设cv::CALIB_CV_FAST_CHECK:快速检测
drawChessboardCorners
棋盘格角点的绘制
#include <opencv2/calib3d.hpp>
void cv::drawChessboardCorners(
InputOutputArray image,
Size patternSize,
InputArray corners,
bool patternWasFound
)
Python:
image = cv.drawChessboardCorners(image, patternSize, corners, patternWasFound)
image:输入 棋盘格图像,必须是8位灰度或彩色图像(cv::Mat)patternSize:输入 棋盘图内角点的行列数(cv::Size)corners:输入findChessboardCorners检测到的角点(std::vector<cv::Point2f>)patternWasFound:输入 标志位,用来指示定义的棋盘内角点是否被完整的探测到,true表示别完整的探测到,函数会用直线依次连接所有的内角点,作为一个整体,false表示有未被探测到的内角点,这时候函数会以(红色)圆圈标记处检测到的内角点;(bool)
cornerSubPix
亚像素检测
#include <opencv2/imgproc.hpp>
void cv::cornerSubPix(
InputArray image,
InputOutputArray corners,
Size winSize,
Size zeroZone,
TermCriteria criteria
)
Python:
corners = cv.cornerSubPix(image, corners, winSize, zeroZone, criteria)
image:输入 8位或浮点型单通道图像(cv::Mat)corners:输入输出 输入角点的初始坐标,输出更加精确的点(std::vector<cv::Point2f>)winSize:输入 大小为搜索窗口的一半,如果winSize=cv::Size(5,5),则搜索窗口为11*11(cv::Size)zeroZone:输入 死区的一半尺寸,死区为不对搜索区的中央位置做求和运算的区域。它是用来避免自相关矩阵出现某些可能的奇异性。当值为(-1,-1)时表示没有死区(cv::Size)criteria:输入 求角点的迭代过程的终止条件,可以为迭代次数和角点精度两者的组合(cv::TermCriteria(cv::TermCriteria::COUNT + cv::TermCriteria::EPS, 30, 0.1))
经过重投影
projectPoints,cornerSubPix与find4QuadCornerSubpix效果对比,find4QuadCornerSubpix进行亚像素精确化的重投影结果不如cornerSubPix
参考文章
calibrateCamera
求解相机内参和外参
#include <opencv2/calib3d.hpp>
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)
)
Python:
retval, cameraMatrix, distCoeffs, rvecs, tvecs = cv.calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs[, rvecs[, tvecs[, flags[, criteria]]]])
objectPoints:输入 世界坐标系中的三维点集。在使用时,应该是有多张图片同时进行标定,即应该输入一个三维坐标点的向量的向量(std::vector<std::vector<cv::Point3f>>)。测量棋盘上单个黑白矩阵的实际大小,以初始化每一个内角点的世界坐标imagePoints:输入 每一个3D内角点对应的图像坐标2D点(std::vector<std::vector<cv::Point2f>>)imageSize:输入 图像的像素尺寸大小,在计算相机的内参和畸变矩阵时需要使用到该参数(cv::Size)cameraMatrix:输出 相机内参矩阵(cv::Mat)distCoeffs:输出 相机畸变系数矩阵(cv::Mat)rvecs:输出 旋转向量(std::vector<cv::Vec3d>)tvecs:输出 平移向量(std::vector<cv::Vec3d>)flags:输入 标定时所采用的算法(int),有如下几个参数:CV_CALIB_USE_INTRINSIC_GUESS:使用该参数时,在cameraMatrix矩阵中应该有fx,fy,u0,v0的估计值。否则的话,将初始化(u0,v0)图像的中心点,使用最小二乘估算出fx,fy。CV_CALIB_FIX_PRINCIPAL_POINT:在进行优化时会固定光轴点。当CV_CALIB_USE_INTRINSIC_GUESS参数被设置,光轴点将保持在中心或者某个输入的值。CV_CALIB_FIX_ASPECT_RATIO:固定fx/fy的比值,只将fy作为可变量,进行优化计算。当CV_CALIB_USE_INTRINSIC_GUESS没有被设置,fx和fy将会被忽略。只有fx/fy的比值在计算中会被用到。CV_CALIB_ZERO_TANGENT_DIST:设定切向畸变参数(p1,p2)为零。CV_CALIB_FIX_K1,…,CV_CALIB_FIX_K6:对应的径向畸变在优化中保持不变。如果设置了CV_CALIB_USE_INTRINSIC_GUESS参数,就从提供的畸变系数矩阵中得到。否则,设置为0。CV_CALIB_RATIONAL_MODEL:计算k4,k5,k6三个畸变参数。使标定函数使用有理模型,返回8个系数。如果没有设置,则只计算其它5个畸变参数。CALIB_THIN_PRISM_MODEL(薄棱镜畸变模型):启用畸变系数S1、S2、S3和S4。使标定函数使用薄棱柱模型并返回12个系数。如果不设置标志,则函数计算并返回只有5个失真系数。CALIB_FIX_S1_S2_S3_S4:优化过程中不改变薄棱镜畸变系数S1、S2、S3、S4。如果cv_calib_use_intrinsic_guess设置,使用提供的畸变系数矩阵中的值。否则,设置为0。CALIB_TILTED_MODEL(倾斜模型):启用畸变系数tauX and tauY。标定函数使用倾斜传感器模型并返回14个系数。如果不设置标志,则函数计算并返回只有5个失真系数。CALIB_FIX_TAUX_TAUY:在优化过程中,倾斜传感器模型的系数不被改变。如果cv_calib_use_intrinsic_guess设置,从提供的畸变系数矩阵中得到。否则,设置为0。
criteria:输入 可选,最优迭代终止条件设定。
在使用该函数进行标定运算之前,需要对棋盘上每一个内角点的空间坐标系的位置坐标进行初始化,标定的结果是生成相机的内参矩阵cameraMatrix、相机的5个畸变系数distCoeffs,另外每张图像都会生成属于自己的平移向量和旋转向量。
projectPoints
将世界坐标系中的3D坐标投影到像素坐标系中的2D坐标
可用于计算标定的误差
#include <opencv2/calib3d.hpp>
void cv::projectPoints(
InputArray objectPoints,
InputArray rvec,
InputArray tvec,
InputArray cameraMatrix,
InputArray distCoeffs,
OutputArray imagePoints,
OutputArray jacobian = noArray(),
double aspectRatio = 0
)
Python:
imagePoints, jacobian = cv.projectPoints(objectPoints, rvec, tvec, cameraMatrix, distCoeffs[, imagePoints[, jacobian[, aspectRatio]]])
objectPoints:世界坐标系中的3D坐标(std::vector<cv::Point3f>)rvec:世界坐标系到相机坐标系的旋转向量(cv::Vec3d)tvec:世界坐标系到相机坐标系的平移向量(cv::Vec3d)cameraMatrix:相机内参矩阵(cv::Mat)distCoeffs:相机畸变系数矩阵(cv::Mat)imagePoints:3D坐标点在像素坐标系中估计的2D坐标(std::vectorcv::Point2f)jacobian:可选输出的雅可比矩阵aspectRatio:是否固定“宽高比”参数标志
initUndistortRectifyMap
计算畸变参数
#include <opencv2/calib3d.hpp>
void cv::initUndistortRectifyMap(
InputArray cameraMatrix,
InputArray distCoeffs,
InputArray R,
InputArray newCameraMatrix,
Size size,
int m1type,
OutputArray map1,
OutputArray map2
)
Python:
map1, map2 = cv.initUndistortRectifyMap(cameraMatrix, distCoeffs, R, newCameraMatrix, size, m1type[, map1[, map2]])
cameraMatrix:输入 相机内参矩阵(cv::Mat)distCoeffs:输入 相机畸变系数矩阵(cv::Mat)R:输入 畸变矫正矩阵,在客观空间中的转换对象(cv::Mat::eye(cv::Size(3, 3), CV_32FC1))newCameraMatrix:输入 新的3*3的浮点型矩矩阵(cv::Mat)size:输入 失真图像的大小(cv::Size)m1type:输入 第一个输出的map(CV_32FC1/CV_16SC2)map1:输出 x映射函数(cv::Mat)map2:输出 y映射函数(cv::Mat)

浙公网安备 33010602011771号