多目相机贴图
目前有一个左中右三目相机,想要实现中间相机图像贴到左右标定的点云数据中,经过探索,可参照一下步骤实现:
- 左中右三个相机进行标定,得到各自内参和畸变系数
- 使用固定内参的方法,对左右相机就行双目标定得到左右相机的外参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) )
- 对左右目相机进行立体矫正,得到参数P1。
P1 为第一个摄像机输出新的(经校正的)坐标系统中的3x4投影矩阵,即它将经校正的第一个摄像机坐标系统中给定的点投影到被校正的第一个摄像机的图像中
CV_EXPORTS_W 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(),CV_OUT Rect* validPixROI1 = 0, CV_OUT Rect* validPixROI2 = 0 );
参数说明:
cameraMatrix1 第一个相机内参矩阵
distCoeffs1 第一个相机畸变参数
cameraMatrix1 第二个相机内参矩阵
distCoeffs1 第二个相机畸变参数
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覆盖整个图像。否则,它们可能会更小
- 获取左目相机矫正后的图像,remap后保存图像,以便后续进行左和中间相机标定
CV_EXPORTS_W void initUndistortRectifyMap( InputArray cameraMatrix, InputArray distCoeffs,InputArray R, InputArray newCameraMatrix,Size size, int m1type, OutputArray map1, OutputArray map2 );
参数说明:
cameraMatrix——输入的摄像头内参数矩阵(3X3矩阵)
distCoeffs——输入的摄像头畸变系数矩阵(5X1矩阵)
R——输入的第一和第二摄像头坐标系之间的旋转矩阵,通过stereoRectify计算得来的R1或R2可以放在这里。
newCameraMatrix——输入的校正后的3X3摄像机矩阵
size——摄像头采集的无失真图像尺寸,去畸变后图像的尺寸
m1type——map1的数据类型,可以是CV_32FC1或CV_16SC2
map1——输出的X坐标重映射参数
map2——输出的Y坐标重映射参数
这个函数用于计算无畸变和修正转换关系,为了重映射,将结果以映射的形式表达。无畸变的图像看起来就想原始的图像,就像这个图像是用内参为newCameraMatrix的且无畸变的相机采集得到的。
void remap(InputArray src, //输入图像OutputArray dst, //输出图像InputArray map1, //第一个映射InputArray map2, //第二个映射int interpolation, //插值int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
参数说明:
src——输入图像,即原图像,需要单通道8位或者浮点类型的图像
dst——输出图像,即目标图像,需和原图形一样的尺寸和类型
map1——它有两种可能表示的对象:(1)表示点(x,y)的第一个映射;(2)表示CV_16SC2,CV_32FC1等
map2——有两种可能表示的对象:(1)若map1表示点(x,y)时,这个参数不代表任何值;(2)表示 CV_16UC1,CV_32FC1类型的Y值
intermap2polation——插值方式,有四种插值方式:
INTER_NEAREST——最近邻插值、
INTER_LINEAR——双线性插值(默认)、
INTER_CUBIC——双三样条插值(默认)、
INTER_LANCZOS4——lanczos插值(默认)
intborderMode——边界模式,默认BORDER_CONSTANT,表示目标图像中“离群点(outliers)”的像素值不会被此函数修改。
borderValue——边界颜色,默认Scalar()黑色,当有常数边界时使用的值
- 根据步骤3获取P1,使用
cv::decomposeProjectionMatrix
获取左目相机矫正后的内参矩阵
void decomposeProjectionMatrix(InputArray projMatrix,
OutputArray cameraMatrix,
OutputArray rotMatrix,
OutputArray transVect,
OutputArray rotMatrixX=noArray(),
OutputArray rotMatrixY=noArray(),
OutputArray rotMatrixZ=noArray(),
OutputArray eulerAngles=noArray() )
该函数计算投影矩阵分解为校准矩阵、旋转矩阵和相机位置。
参数说明:
projMatrix 输入参数,3x4 投影矩阵
cameraMatrix 输出参数,3x3 相机内参
rotMatrix 输出参数,3x3 旋转矩阵,从相机1到相机2的旋转矩阵
transVect 输出参数,4x1平移向量,从相机1到相机2的平移矩阵
rotMatrX 输出参数,3x3 绕X轴选择矩阵
rotMatrY 输出参数,3x3 绕Y轴选择矩阵
rotMatrZ 输出参数,3x3 绕Z轴选择矩阵
eulerAngles 输出参数,度数表示的欧拉角
- 根据步骤4得到的左相机矫正后图像和步骤5得到的左相机新的内参,使用固定参数与中间相机进行双目标定,到中间相机R、T
- 左中相机进行立体标定,cv::stereoRectify,得到左边相机的 R1(Rec_L),其中R1表示左目相机世界坐标到矫正后的左目相机世界坐标。
- 使用decomposeProjectionMatrix,得到中间相机相对于左边相机的Kc、R、T
- 使用步骤8中的R、T,计算左边相机坐标转到中间相机:
Wc = RRec_LPw + T
Wc表示中间相机世界坐标,R、T表示矫正后中间相机相对于左边相机的旋转和平移 - 中间相机坐标投影到像素坐标
Ppix = Kc*Wc
Ppix表示像素坐标,Kc表示中间相机矫正后内参