本文主要是对opencv单双目摄像头标定及其校正过程中用到的相关函数进行搜集整理,便于对另一片博客中的代码的理解。建议大家去opencv的官网检索原始函数定义,虽然是英文但是不妨碍使用。
1、TermCriteria()
函数说明:
定义迭代算法终止条件的类。
函数形式:
cv::TermCriteria::TermCriteria ( int type, int maxCount, double epsilon)
#python使用示例
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
参数解释:
- type:The type of termination criteria, 判定迭代终止的条件类型,要么只按count算,要么只按EPS算,要么两个条件达到一个就算结束
COUNT:按最大迭代次数算
EPS:就是epsilon,按达到某个收敛的阈值作为求解结束标志
COUNT + EPS:要么达到了最大迭代次数,要么按达到某个阈值作为收敛结束条件。 - maxCount:The maximum number of iterations or elements to compute. 具体的最大迭代的次数是多少。
- epsilon:The desired accuracy or change in parameters at which the iterative algorithm stops. 具体epsilon值是多少。
2、FindChessboardCorners
函数介绍:
函数cvFindChessboardCorners试图确定输入图像是否是棋盘模式,并确定角点的位置。如果所有角点都被检测到且它们都被以一定顺序排布,函数返回非零值,否则在函数不能发现所有角点或者记录它们地情况下,函数返回0。例如一个正常地棋盘图右8x8个方块和7x7个内角点,内角点是黑色方块相互联通的位置。这个函数检测到的坐标只是一个大约的值,如果要精确地确定它们的位置,可以使用函数cvFindCornerSubPix。
函数形式:
void drawChessboardCorners(InputOutputArray image, Size patternSize, InputArray corners, bool patternWasFound)¶
Python:
retval,corners = cv.findChessboardCorners( image,patternSize[, corners[,flags]] )
##示例如下:
retR, cornersR = cv2.findChessboardCorners(ChessImaR,(7, 6), None)
参数解释:
- image:输入的棋盘图,必须是8位的灰度或者彩色图像。
- pattern_size:棋盘图中每行和每列角点的个数。
- Corners:检测到的角点
- Flags:各种操作标志,可以是0或者下面值的组合:
- CV_CALIB_CB_ADAPTIVE_THRESH -使用自适应阈值(通过平均图像亮度计算得到)将图像转换为黑白图,而不是一个固定的阈值。
- CV_CALIB_CB_NORMALIZE_IMAGE -在利用固定阈值或者自适应的阈值进行二值化之前,先使用cvNormalizeHist来均衡化图像亮度。
- CV_CALIB_CB_FILTER_QUADS -使用其他的准则(如轮廓面积,周长,方形形状)来去除在轮廓检测阶段检测到的错误方块。
3、cornerSubPix( )
函数介绍:
FindChessboardCorners这个API函数能够获取图像中的强角点。但是获取的角点坐标是整数,但是通常情况下,角点的真实位置并不一定在整数像素位置,因此为了获取更为精确的角点位置坐标,需要角点坐标达到亚像素(subPixel)精度。
函数形式:
void cv::cornerSubPix( InputArray _image, InputOutputArray _corners,
Size win, Size zeroZone, TermCriteria criteria )
Python:
corners = cv.cornerSubPix image, corners, winSize, zeroZone, criteria )
##示例如下:
cv2.cornerSubPix(ChessImaR, cornersR, (11, 11), (-1, -1), criteria)
参数解释:
- image:输入单通道,8位或浮点图像。
- corners:输入角的初始坐标
- winSize:搜索窗口边长的一半。比如设置Size(11,11),需要注意的是11为半径,则窗口大小为23x23。
- zeroZone:设置的“零区域”,在搜索窗口内,设置的“零区域”内的值不会被累加,权重值为0。如果设置为Size(-1,-1),则表示没有这样的区域;
- criteria: 终止角点优化迭代过程的条件。
4、FindChessboardCorners( )
函数介绍:
函数cvFindChessboardCorners试图确定输入图像是否是棋盘模式,并确定角点的位置。如果所有角点都被检测到且它们都被以一定顺序排布,函数返回非零值,否则在函数不能发现所有角点或者记录它们地情况下,函数返回0。例如一个正常地棋盘图右8x8个方块和7x7个内角点,内角点是黑色方块相互联通的位置。这个函数检测到的坐标只是一个大约的值,如果要精确地确定它们的位置,可以使用函数cvFindCornerSubPix。
函数形式:
void drawChessboardCorners(InputOutputArray image, Size patternSize, InputArray corners, bool patternWasFound)¶
Python:
retval,corners = cv.findChessboardCorners( image,patternSize[, corners[,flags]] )
##示例如下:
retR, cornersR = cv2.findChessboardCorners(ChessImaR,(7, 6), None)
参数解释:
- image:输入的棋盘图,必须是8位的灰度或者彩色图像。
- pattern_size:棋盘图中每行和每列角点的个数。
- Corners:检测到的角点
- Flags:各种操作标志,可以是0或者下面值的组合:
- CV_CALIB_CB_ADAPTIVE_THRESH -使用自适应阈值(通过平均图像亮度计算得到)将图像转换为黑白图,而不是一个固定的阈值。
- CV_CALIB_CB_NORMALIZE_IMAGE -在利用固定阈值或者自适应的阈值进行二值化之前,先使用cvNormalizeHist来均衡化图像亮度。
- CV_CALIB_CB_FILTER_QUADS -使用其他的准则(如轮廓面积,周长,方形形状)来去除在轮廓检测阶段检测到的错误方块。
5、calibrateCamera( )
函数介绍:
求解摄像机的内外参数。
函数形式:
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)
)
Python:
retval, cameraMatrix, distCoeffs, rvecs, tvecs = cv.calibrateCamera( objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs[, rvecs[, tvecs[, flags[, criteria]]]]
##示例如下:
retL, mtxL, distL, rvecsL, tvecsL = cv2.calibrateCamera(objpoints,
imgpointsL,
ChessImaL.shape[::-1], None, None)
参数解释:
- objectPoints:输入目标点的位置的集合的集合。其每个点位代表着物体的三维坐标。
- imagePoints:图像角点位置的集合,其每个点是objectPoints中的点投影在图片中成像的对应点。
- imageSize:用于标定的图片的尺寸。
- cameraMatrix:输出的相机内参矩阵。
- distCoeffs:输出的畸变矩阵。
- rvecs: 输出的旋转向量。
- tvecs:输出的平移向量。
- stdDeviationsIntrinsics :内参数的输出向量。输出顺序为: (fx,fy,cx,cy,k1,k2,p1,p2,k3,k4,k5,k6,s1,s2,s3,s4,τx,τy) ,如果不估计其中某一个参数,值等于0
- stdDeviationsExtrinsics :外参数的输出向量。输出顺序: (R1,T1,…,RM,TM) ,M是标定图片的个数, Ri,Ti 是1x3的向量 。
- criteria: 迭代优化算法的终止准则。
- flags :标定函数是所采用的模型:
- CV_CALIB_USE_INTRINSIC_GUESS:使用该参数时,将包含有效的fx,fy,cx,cy的估计值的内参矩阵cameraMatrix,作为初始值输入,然后函数对其做进一步优化。如果不使用这个参数,用图像的中心点初始化光轴点坐标(cx, cy),使用最小二乘估算出fx,fy(这种求法好像和张正友的论文不一样,不知道为何要这样处理)。注意,如果已知内部参数(内参矩阵和畸变系数),就不需要使用这个函数来估计外参,可以使用solvepnp()函数计算外参数矩阵。
- 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。
6、getOptimalNewCameraMatrix( )
函数说明:
该函数根据自由缩放参数计算并返回最佳的新的相机矩阵。通过更改此参数,alpha = 0时,只保留有意义的像素,如果alpha=1 所有的像素都保留下来,并且包括一些额外的黑色图像。它还返回一个图像ROI,可以用来裁剪结果。函数出的新相机矩阵和newImageSize应该传递给initUndistortRectifyMap,以用remap生成地图。
函数形式:
Mat cv::getOptimalNewCameraMatrix( InputArray cameraMatrix,
InputArray distCoeffs,
Size imageSize,
double alpha,
Size newImgSize = Size(),
Rect * validPixROI = 0,
bool centerPrincipalPoint = false
)
Python:
retval, validPixROI = cv.getOptimalNewCameraMatrix( cameraMatrix, distCoeffs, imageSize, alpha[, newImgSize[, centerPrincipalPoint]] )
##示例如下:
retR, mtxR, distR, rvecsR, tvecsR = cv2.calibrateCamera(objpoints,
imgpointsR,
ChessImaR.shape[::-1], None, None)
参数解释:
- cameraMatrix:输入相机内参矩阵。
- distCoeffs:输入畸变系数。
- imageSize:原始图像尺寸。
- alpha:自由缩放参数介于0(只保留有意义的像素)和1(保留所源图像像素)之间的自由缩放参数。
- newImgSize:各种操作标志,可以是0或者下面值的组合:
- validPixROI: 可选的输出矩形,用于概述未失真图像中所有良好像素的区域
- centerPrincipalPoint:可选标志,指示在新的相机矩阵中主点是否应位于图像中心。
7、undistort( )
函数说明:
独立的一个畸变矫正函数,一次性可以完成映射矩阵的求解和重新映射。
函数形式:
void cv::undistort( InputArray src,
OutputArray dst,
InputArray cameraMatrix,
InputArray distCoeffs,
InputArray newCameraMatrix = noArray()
)
Python:
dst = cv.undistort( src, cameraMatrix, distCoeffs[, dst[, newCameraMatrix]] )
##示例如下:
dst = cv2.undistort(img, mtx, dist, None, newcameramtx)
参数解释:
- src:输入未经过矫正的图像
- dst:经过矫正后输出的图像
- cameraMatrix:标定而得到的摄像机矩阵
- distCoeffs:标定得到的摄像机畸变矩阵
- newCameraMatrix-输入矫正后的摄像机矩阵
8、stereoCalibrate( )
函数说明:
标定一个立体摄像头的,也就是同时标定两个摄像头。标定的结果除了能够求出两个摄像头的内外参数矩阵,跟能够得出两个摄像头的位置关系R,T。
函数形式:
double cv::stereoCalibrate( InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints1,
InputArrayOfArrays imagePoints2,
InputOutputArray cameraMatrix1,
InputOutputArray distCoeffs1,
InputOutputArray cameraMatrix2,
InputOutputArray distCoeffs2,
Size imageSize,
InputOutputArray R,
InputOutputArray T,
OutputArray E,
OutputArray F,
OutputArray perViewErrors,
int flags = CALIB_FIX_INTRINSIC,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 1e-6)
)
Python:
retval, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F= cv.stereoCalibrate( objectPoints, imagePoints1, imagePoints2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, imageSize[, R[, T[, E[, F[, flags[, criteria]]]]]])
##示例如下:
retS, MLS, dLS, MRS, dRS, R, T, E, F = cv2.stereoCalibrate(objpoints,imgpointsL,imgpointsR,OmtxL,distL,OmtxR,distR,
ChessImaR.shape[::-1], criteria_stereo,flags)
参数解释:
- objectPoints:vector 型的数据结构,存储标定角点在世界坐标系中的位置。
- imagePoints1: vector<vector> 型的数据结构,存储标定角点在第一个摄像机下的投影后的亚像素坐标。
- imagePoints2- vector<vector> 型的数据结构,存储标定角点在第二个摄像机下的投影后的亚像素坐标。
- cameraMatrix1:输入/输出型的第一个摄像机的相机矩阵。如果CV_CALIB_USE_INTRINSIC_GUESS , CV_CALIB_FIX_ASPECT_RATIO ,CV_CALIB_FIX_INTRINSIC , or CV_CALIB_FIX_FOCAL_LENGTH其中的一个或多个标志被设置,该摄像机矩阵的一些或全部参数需要被初始化。
- distCoeffs1:第一个摄像机的输入/输出型畸变向量。根据矫正模型的不同,输出向量长度由标志决定。
- cameraMatrix2:输入/输出型的第二个摄像机的相机矩阵。参数意义同第一个相机矩阵相似。
- distCoeffs2:第一个摄像机的输入/输出型畸变向量。根据矫正模型的不同,输出向量长度由标志决定。
- imageSize:图像的大小。
- R:输出型,第一和第二个摄像机之间的旋转矩阵。
- T:输出型,第一和第二个摄像机之间的平移矩阵。
- E:输出型,基本矩阵。
- F:输出型,基础矩阵。
- term_crit:迭代优化的终止条件。
- flag:标志位
- CV_CALIB_FIX_INTRINSIC 如果该标志被设置,那么就会固定输入的cameraMatrix和distCoeffs不变,只求解𝑅,𝑇,𝐸,𝐹
- CV_CALIB_USE_INTRINSIC_GUESS 根据用户提供的cameraMatrix和distCoeffs为初始值开始迭代
- CV_CALIB_FIX_FOCAL_LENGTH 迭代过程中不会改变焦距
- CV_CALIB_SAME_FOCAL_LENGTH 强制保持两个摄像机的焦距相同
- CV_CALIB_ZERO_TANGENT_DIST 切向畸变保持为零
- CV_CALIB_FIX_K1,…,CV_CALIB_FIX_K6 迭代过程中不改变相应的值。如果设置了 CV_CALIB_USE_INTRINSIC_GUESS 将会使用用户提供的初始值,否则设置为零
- CV_CALIB_RATIONAL_MODEL 畸变模型的选择,如果设置了该参数,将会使用更精确的畸变模型,distCoeffs的长度就会变成8
9、stereoRectify()
函数说明:
为每个摄像头计算立体校正的映射矩阵。所以其运行结果并不是直接将图片进行立体矫正,而是得出进行立体矫正所需要的映射矩阵。
函数形式:
void 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 )
Python:
R1,R2,P1,P2,Q,validPixROI1,validPixROI2 =cv.stereoRectify( cameraMatrix1,distCoeffs1,cameraMatrix2,distCoeffs2,imageSize,R,T [,R1 [,R2 [,P1 [,P2 [,Q [,标志[,alpha [,newImageSize]]]]]]]]]]]]]]]]]])
##示例如下:
RL, RR, PL, PR, Q, roiL, roiR= cv2.stereoRectify(MLS, dLS, MRS, dRS,
ChessImaR.shape[::-1], R, T,
1,(0,0))
参数解释:
- cameraMatrix1:第一个摄像机的摄像机矩阵
- distCoeffs1:第一个摄像机的畸变向量
- cameraMatrix2:第二个摄像机的摄像机矩阵
- distCoeffs1:第二个摄像机的畸变向量
- imageSize:图像大小
- R: stereoCalibrate() 求得的R矩阵
- T:stereoCalibrate() 求得的T矩阵
- R1:输出矩阵,第一个摄像机的校正变换矩阵(旋转变换)
- R2:输出矩阵,第二个摄像机的校正变换矩阵(旋转矩阵)
- P1:输出矩阵,第一个摄像机在新坐标系下的投影矩阵
- P2:输出矩阵,第二个摄像机在想坐标系下的投影矩阵
- Q:4*4的深度差异映射矩阵
- flags:可选的标志有两种零或者 CV_CALIB_ZERO_DISPARITY ,如果设置 CV_CALIB_ZERO_DISPARITY 的话,该函数会让两幅校正后的图像的主点有相同的像素坐标。否则该函数会水平或垂直的移动图像,以使得其有用的范围最大
- alpha:拉伸参数。如果设置为负或忽略,将不进行拉伸。如果设置为0,那么校正后图像只有有效的部分会被显示(没有黑色的部分),如果设置为1,那么就会显示整个图像。设置为0~1之间的某个值,其效果也居于两者之间。
- newImageSize:校正后的图像分辨率,默认为原分辨率大小。
- validPixROI1:可选的输出参数,Rect型数据。其内部的所有像素都有效
- validPixROI2:可选的输出参数,Rect型数据。其内部的所有像素都有效
10、initUndistortRectifyMap( )
函数说明:
该函数功能是计算畸变矫正和立体校正的映射变换,实现极线对齐。
函数形式:
void 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]] )
##示例如下:
Left_Stereo_Map= cv2.initUndistortRectifyMap(MLS, dLS, RL, PL,
ChessImaR.shape[::-1], cv2.CV_16SC2)
参数解释:
- cameraMatrix:摄像机参数矩阵
- distCoeffs:畸变参数矩阵
- R:stereoCalibrate() 求得的R矩阵
- newCameraMatrix:矫正后的摄像机矩阵(可省略)
- Size:没有矫正图像的分辨率
- m1type:第一个输出映射的数据类型,可以为 CV_32FC1 或 CV_16SC2
- map1:输出的第一个映射变换
- map2:输出的第二个映射变换
11、remap( )
函数说明:
该函数功能是计算畸变矫正和立体校正的映射变换,实现极线对齐。
函数形式:
void remap(InputArray src, OutputArray dst, InputArray map1, InputArray
map2, int interpolation,int borderMode=BORDER_CONSTANT, const Scalar&
borderValue=Scalar())
Python:
dst = cv.remap( src, map1, map2, interpolation[, dst[, borderMode[, borderValue]]] )
##示例如下:
Left_nice= cv2.remap(frameL,Left_Stereo_Map[0],Left_Stereo_Map[1], cv2.INTER_LANCZOS4, cv2.BORDER_CONSTANT, 0)
参数解释:
- src:原图像
- dst:几何变换后的图像
- map1:第一个映射,无论是点(x,y)或者单纯x的值都需要是CV_16SC2 ,CV_32FC1 , 或 CV_32FC2类型
- map2:第二个映射,y需要是CV_16UC1 , CV_32FC1类型。或者当map1是点(x,y)时,map2为空。
- interpolation:插值方法,但是不支持最近邻插值
- borderMode:一般默认BORDER_CONSTANT就行
- borderValue:默认情况下为0