将标定方法粗略分为摄影测量标定( photogrammetric calibration)和自标定(selfcalibration)。
机器视觉中的摄像机标定和自标定分析
本文:
只需要相机观察在几个(至少两个)不同方向上显示的平面图案。
相机和平面都可以移动,且不需要知道它们的移动。
介于摄影测量校准和自校准之间,因为我们使用 2D 度量信息而不是 3D 或纯隐式信息。
立体视觉入门指南(3):相机标定之张式标定法【超详细值得收藏】
第六节、双目视觉之相机标定
张正友畸变矫正C++代码
双目视觉标定程序讲解
OPENCV3.0 双目立体标定
双目标定的注意事项 已经遇到了起源点的问题
双目相机OpenCV标定常见问题汇总
双目标定(三)标定流程(含矫正)
OpenCV学习笔记(17)双目测距与三维重建的OpenCV实现问题集锦(二)双目定标与双目校正
ubuntu中获取文件名称并生成txt文件
问题:读取图片时可能会出现图片为空,导致错误。
注意:读取时判断一下是否为空。
int main()
{
//单个相机,图片路径
std::string infile="/home/标定/camera/chessboard.txt";
//标定结果和保存文件
std::string outfile="/home/标定/camera/calib_result.txt";
//读取图片
std::ifstream fin(infile);
std::ofstream fout(outfile);
std::vector<cv::Mat> images;
if(fin.is_open())
{
while(!fin.eof()){
std::string str;
fin>>str;
cv::Mat image=cv::imread("/home/标定/camera"+str);
if(!image.empty())
images.emplace_back(image);
}
cv::Size board=cv::Size(9,13);
SingleCameraCalib scc(images,board);
}
return 0;
}
findChessboardCorners函数学习笔记
openCV函数用法之 findChessboardCorners
该函数尝试确定输入图像是否是棋盘图案的视图并定位内部棋盘角。如果找到所有角并且它们按特定顺序放置(逐行,每行从左到右),则该函数返回一个非零值。 否则,如果函数未能找到所有角点或重新排序它们,则返回 0。例如,一个普通的棋盘有 8 x 8 个方格和 7 x 7个内角,即黑色方格相互接触的点。 检测到的坐标是近似的,为了更准确地确定它们的位置,该函数调用cornerSubPix。如果返回的坐标不够准确,您也可以使用带有不同参数的函数cornerSubPix。
bool cv::findChessboardCorners (
InputArray image,
Size patternSize,
OutputArray corners,
int flags = CALIB_CB_ADAPTIVE_THRESH+CALIB_CB_NORMALIZE_IMAGE
)
image | 源棋盘视图。 它必须是 8 位灰度或彩色图像 |
patternSize | 每个棋盘行和列的内角数( patternSize = cv::Size(points_per_row,points_per_colum) = cv::Size(columns,rows) ) |
corners | 检测到的角的输出数组 |
flags | 可以为零或以下值组合的各种操作标志: |
CALIB_CB_ADAPTIVE_THRESH | 使用自适应阈值将图像转换为黑白,而不是固定阈值级别(根据平均图像亮度计算) |
CALIB_CB_NORMALIZE_IMAGE | 在应用固定或自适应阈值之前,使用 equalizeHist 规范化图像伽玛 |
CALIB_CB_FILTER_QUADS | 使用其他标准(如轮廓面积、周长、类似正方形的形状)过滤掉在轮廓检索阶段提取的错误四边形 |
CALIB_CB_FAST_CHECK | 对图像进行快速检查以查找棋盘角,如果没有找到则快捷调用。 当没有观察到棋盘时,这可以大大加快退化条件下的调用 |
OpenCV cv::TermCriteria 模板类
【OpenCV3】角点检测——cv::goodFeaturesToTrack()与cv::cornerSubPix()详解
优化角点位置
image | 输入单通道、8 位或浮点图像 |
corners | 输入角的初始坐标和为输出提供的细化坐标 |
winSize | 搜索窗口边长的一半。 例如,如果 winSize=Size(5,5) ,则使用 (5∗2+1)×(5∗2+1)=11×11 搜索窗口 |
zeroZone | 搜索区域中间的死区大小的一半,在该区域上未进行以下公式中的求和。 它有时用于避免自相关矩阵可能出现的奇异性。 (-1,-1) 的值表示没有这样的大小。 |
criteria | 角细化迭代过程的终止标准。 也就是说,角位置细化的过程在criteria.maxCount 迭代之后或在某个迭代中角位置移动小于criteria.epsilon 时停止。 |
【OpenCV3】棋盘格角点检测与绘制——cv::findChessboardCorners()与cv::drawChessboardCorners()详解
double cv::calibrateCamera ( InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints,
Size imageSize,
InputOutputArray cameraMatrix,
InputOutputArray distCoeffs,
OutputArrayOfArrays rvecs,
OutputArrayOfArrays tvecs,
OutputArray stdDeviationsIntrinsics,
OutputArray stdDeviationsExtrinsics,
OutputArray perViewErrors,
int flags = 0,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON)
)
C++ OpenCV V4.x中的新版双目标定函数stereoCalibrate() 参数说明【新增perViewErrors】
校准立体相机设置。 此函数查找两个相机中每一个的内在参数和两个相机之间的外在参数。
该函数估计构成立体对的两个相机之间的转换。如果计算对象相对于第一个摄像机和第二个摄像机的位姿,分别为 (R1, T1) 和 (R2, T2),对于两个摄像机之间的相对位置和方向固定的立体摄像机, 那么这些姿势肯定是相互关联的。这意味着,如果两个相机的相对位置和方向 (R, T) 已知,则可以在给定 (R1, T1) 时计算 (R2, T2)。
除了立体相关信息外,该功能还可以对两个摄像头中的每一个进行全面校准。 然而,由于参数空间的高维和输入数据中的噪声,函数可能会偏离正确的解。如果可以单独为每个相机高精度估计内在参数(例如,使用 calibrateCamera ),建议您这样做,然后将 CALIB_FIX_INTRINSIC 标志与计算的内在参数一起传递给函数。 否则,如果一次估计所有参数,则限制某些参数是有意义的,例如,传递 CALIB_SAME_FOCAL_LENGTH 和 CALIB_ZERO_TANGENT_DIST 标志,这通常是一个合理的假设。
与 calibrateCamera 类似,该函数将两个相机的所有可用视图中所有点的总重投影误差最小化。 该函数返回重投影误差的最终值。
flag | |
CALIB_FIX_INTRINSIC | 内参数固定,仅估计 R、T、E 和 F 矩阵。 |
CALIB_USE_INTRINSIC_GUESS | 根据指定的标志优化部分或全部内在参数。 初始值由用户提供。 |
CALIB_USE_EXTRINSIC_GUESS | R 和 T 为有效初始值。 否则 R 和 T 被初始化为模式视图的中值(每个维度)。 |
CALIB_FIX_PRINCIPAL_POINT | 在优化过程中固定主点。 |
CALIB_FIX_FOCAL_LENGTH | 固定焦距 |
CALIB_FIX_ASPECT_RATIO | 优化fy,固定比率 fx/fy |
CALIB_SAME_FOCAL_LENGTH | 强制执行 f(0)x=f(1)x 和 f(0)y=f(1)y 焦距相等 |
CALIB_ZERO_TANGENT_DIST | 将每个相机的切向畸变系数设置为零并固定 |
CALIB_FIX_K1,…, CALIB_FIX_K6 | 在优化过程中不要改变相应的径向畸变系数。 如果设置了 CALIB_USE_INTRINSIC_GUESS,则使用提供的 distCoeffs 矩阵中的系数。 否则,将其设置为 0。 |
CALIB_RATIONAL_MODEL | 启用系数 k4、k5 和 k6。 为了提供向后兼容性,应明确指定此额外标志以使校准函数使用有理模型并返回 8 个系数。 如果未设置该标志,则该函数仅计算并返回 5 个失真系数。 |
CALIB_THIN_PRISM_MODEL | 启用系数 s1、s2、s3 和 s4。 为了提供向后兼容性,应明确指定此额外标志以使校准函数使用薄棱镜模型并返回 12 个系数。 如果未设置该标志,则该函数仅计算并返回 5 个失真系数。 |
CALIB_FIX_S1_S2_S3_S4 | 薄棱镜畸变系数在优化过程中没有改变。 如果设置了 CALIB_USE_INTRINSIC_GUESS,则使用提供的 distCoeffs 矩阵中的系数。 否则,将其设置为 0。 |
CALIB_TILTED_MODEL | 启用系数 tauX 和 tauY。 为了提供向后兼容性,应明确指定此额外标志以使校准函数使用倾斜传感器模型并返回 14 个系数。 如果未设置该标志,则该函数仅计算并返回 5 个失真系数。 |
CALIB_FIX_TAUX_TAUY | 倾斜传感器模型的系数在优化过程中没有改变。 如果设置了 CALIB_USE_INTRINSIC_GUESS,则使用提供的 distCoeffs 矩阵中的系数。 否则,将其设置为 0。 |
OpenCV学习之stereoRectify()函数及initUndistortRectifyMap()函数参数说明
为每一个标定过的双目相机计算校正变换
void cv::stereoRectify (
InputArray cameraMatrix1,
InputArray distCoeffs1,
InputArray cameraMatrix2,
InputArray distCoeffs2,
Size imageSize,
InputArray R,
InputArray T,
OutputArray R1,
OutputArray R2,
OutputArray P1,
OutputArray P2,
OutputArray Q,
int flags = CALIB_ZERO_DISPARITY,
double alpha = -1,
Size newImageSize = Size(),
Rect * validPixROI1 = 0,
Rect * validPixROI2 = 0
)
cameraMatrix1 | 第一个相机内参矩阵 |
distCoeffs1 | 第一个相机畸变参数 |
cameraMatrix2 | 第二个相机内参矩阵 |
distCoeffs2 | 第二个相机畸变参数 |
imageSize | 用于相机标定的图像尺寸 |
R | 从第一个相机到第二个相机坐标系系统的旋转矩阵 |
T | 从第一个相机到第二个相机的坐标系的平移矩阵 |
R1 | 为第一个相机输出3x3的修正矩阵(旋转矩阵)。该矩阵将未经过校正的第一个摄像机坐标系中给出的点引入到经过校正的第一个摄像机坐标系中的点。用更专业的术语来说,它执行了一个基础的改变,从未矫正的第一个摄像机的坐标系到矫正的第一个摄像机的坐标系。 |
R2 | 为第二个相机输出3x3的校正变换(旋转矩阵)。该矩阵将未校正的第二摄像机坐标系中给定的点引入已校正的第二摄像机坐标系中的点。用更专业的术语来说,它执行了一个基础的改变,从未矫正的第二个摄像机的坐标系到矫正的第二个摄像机的坐标系。 |
P1 | 为第一个摄像机输出新的(经校正的)坐标系统中的3x4投影矩阵,即它将经校正的第一个摄像机坐标系统中给定的点投影到被校正的第一个摄像机的图像中。 |
P2 | 为第二个摄像机输出新的(经校正的)坐标系统中的3x4投影矩阵,即将经校正的第一个摄像机坐标系统中给定的点投影到经校正的第二个摄像机的图像中。 |
Q | 输出4x4的视差-深度映射矩阵 |
flags | 操作标志,可以是零或CALIB_ZERO_DISPARITY。如果设置了标志,该函数将使每个摄像机的主点在校正视图中具有相同的像素坐标。如果没有设置标志,函数仍然可以在水平或垂直方向(取决于极线的方向)移动图像,以最大化有用的图像区域。 |
alpha | 自由的尺度参数。如果是-1或缺席,函数将执行默认的缩放。否则,参数应该在0和1之间。alpha=0表示校正后的图像被缩放和移动,只有有效像素可见(校正后没有黑色区域)。alpha=1表示对校正后的图像进行抽取和移位,使所有来自相机的原始图像的像素都保留在校正后的图像中(无源图像像素丢失)。任何中间值都是这两个极端情况的中间结果。 |
newImageSize | 校正后图像分辨率。同样的大小也应该传递给initUndistortRectifyMap (参见OpenCV样本目录中的stereo_calib.cpp样本)。当传递(0,0)时(默认),将其设置为原始imageSize。将其设置为较大的值可以帮助您保存原始图像的细节,特别是当有一个大的径向失真。 |
validPixROI1 | 矫正图像内的可选的输出矩形,其中所有像素是有效的。如果alpha=0, ROI覆盖整个图像。否则,它们可能会更小(见下图)。 |
validPixROI2 | 矫正图像内的可选的输出矩形,其中所有像素是有效的。如果alpha=0, ROI覆盖整个图像。否则,它们可能会更小(见下图)。 |
计算不失真和校正变换图。
void cv::initUndistortRectifyMap (
InputArray cameraMatrix,//输入相机矩阵
InputArray distCoeffs,//失真系数的输入向量
InputArray R,//对象空间中的可选校正变换(3x3 矩阵)。
//可以在此处传递由 stereoRectify 计算的 R1 或 R2 。 如果矩阵为空,则假定恒等变换。 在 cvInitUndistortMap假定R为单位矩阵。
InputArray newCameraMatrix,//新的相机矩阵
Size size,//不失真的图像大小。
int m1type,//第一个输出映射的类型,可以是 CV_32FC1、CV_32FC2 或 CV_16SC2,请参阅 convertMaps
OutputArray map1,//第一个输出映射。
OutputArray map2 //第二个输出图。
)
该函数实际上为 remap 使用的逆映射算法构建映射。 对于目标(不失真和校正过)图像中的每个像素 (u,v),该函数计算源图像(即来自相机的原始图像)中的相应坐标。 应用以下过程:
转换图像以补偿镜头失真。
该函数转换图像以补偿径向和切向镜头失真。
void cv::undistort (
InputArray src,//输入(失真)图像。
OutputArray dst,//输出(校正后的)图像,其大小和类型与 src 相同。
InputArray cameraMatrix,//输入相机矩阵
InputArray distCoeffs,//失真系数的输入向量
InputArray newCameraMatrix = noArray()
//畸变图像的相机矩阵。 默认情况下,它与 cameraMatrix 相同,但您可以使用不同的矩阵额外缩放和移动结果。
)
根据观测点坐标计算理想点坐标。(推公式,相机坐标系到像素坐标系这一块)
该函数类似于 undistort 和 initUndistortRectifyMap,但它对稀疏的点集而不是光栅图像进行操作。 该函数还对 projectPoints 执行反向转换。 在 3D 对象的情况下,它不会重建其 3D 坐标,但对于平面对象,如果指定了适当的 R,它会重建一个平移向量。其中 undistort 是一种近似迭代算法,它从归一化的失真点坐标中估计出归一化的原始点坐标(“归一化”意味着坐标不依赖于相机矩阵)。
该函数可用于立体摄像头或单目摄像头(当 R 为空时)。
src:观测到的点,1xN or Nx1 2-channel (CV_32FC2 or CV_64FC2)
dst:输出不失真(去畸变?)和反向透视变换后的理想点坐标。如果矩阵 P 是恒等矩阵或省略,则 dst 将包含归一化点坐标。
cameraMatrix: 内参矩阵
distCoeffs: 畸变系数
R:对象空间中的校正变换(3x3 矩阵)。通过 stereoRectify 计算的 R1 或 R2 可以在这里传递。如果矩阵为空,则使用恒等变换
P:新相机矩阵 (3x3) 或新投影矩阵 (3x4)。通过stereoRectify 计算的 P1 或 P2 可以在这里传递。如果矩阵为空,则使用标识新相机矩阵。