单目标定
过程
- 读取每幅图像(可以只有1张),从中提取角点,然后对角点进行亚像素精确化。
- 摄像机单目标定
- 矫正图片
用到的数据
Size boardSize
: 棋盘格的大小,为内角点在列和行的数量vector<vector<Point2f>> cornersOfAllImgs
:
所有图片的角点, 每张图片的角点是棋盘格内角点在图片上的对应像素点Size squareSize = Size(60,60)
: 每个棋盘格的实际大小,单位为mmvector<vector<Point3f>> objRealPoint
: 棋盘角点的实际坐标(世界坐标系下的坐标,以左上方的角点为(0,0)点)
要计算的数据
Mat cameraMat = Mat(3,3,CV_32FC1.Scalar::all(0))
: 内参数矩阵Mat distcoeffs = Mat(1, 5, CV_32FC1, Scalar::all(0))
: 畸变系数vector<Mat> tvecsMat
: 所有图片的旋转向量vector<Mat> rvecsMat
: 所有图片的平移向量
其中,cameraMat 和 distcoeffs用于矫正图片
代码
if (findChessboardCorners(img,
boardSize,
corners)
== 0)
{
cout << filename << "找不到角点" << endl;
exit(1);
}
else {
Mat imgGray;
cvtColor(img, imgGray, CV_RGB2GRAY);
cornerSubPix(
imgGray,
corners, Size(5, 5),
Size(-1, -1),
TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
cornersOfAllImgs.push_back(corners);
drawChessboardCorners(imgGray,
boardSize,
corners,
false);
imshow("Camera Calibration", imgGray);
waitKey(1);
}
calibrateCamera(
cornerPoints,
cornersOfAllImgs,
imgSize,
cameraMat,
distcoeffs,
rvecsMat,
tvecsMat,
0);
for (int i = 0; i < imgCount; ++i) {
initUndistortRectifyMap(cameraMat, distcoeffs, R, cameraMat, imgSize, CV_32FC1, mapx, mapy);
Mat imgSrc = imread(filenames[i]);
Mat imgDst = imgSrc.clone();
remap(imgSrc, imgDst, mapx, mapy, INTER_LINEAR);
strStm.clear();
undistortImgFilename.clear();
strStm << "img\\";
strStm << i + 1;
strStm >> undistortImgFilename;
undistortImgFilename += "_d.jpg";
imwrite(undistortImgFilename, imgDst);
}
双目标定
过程
- 先用单目标定得到左右相机的内参数矩阵和畸变系数
- 双目标定摄像头
- 矫正图片
用到的数据
Size mgSize
: 摄象头分辨率Size boardSize
: 内角点在列和行上的数量squareSize
: 棋盘格大小vector<vector<Point2f>> cornersOfAllImagesL
vector<vector<Point2f>> cornersOfAllImagesR
左右相机的所有图片的角点vector<Point2f> objRealSize
: 内角点的实际坐标(世界坐标系)- 左右相机的内参数矩阵和畸变系数
要计算的数据
Mat R, T, E, F
: 分别为R旋转矢量 T平移矢量 E本征矩阵 F基础矩阵Mat Rl, Rr, Pl, Pr, Q
: 校正旋转矩阵R,投影矩阵P,重投影矩阵Q
代码
double rms = stereoCalibrate(objRealPoint, imagePointL, imagePointR,
cameraMatL, distcoeffL,
cameraMatR, distcoeffR,
Size(imageWidth, imageHeight), R, T, E, F, CALIB_USE_INTRINSIC_GUESS,
TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, 1e-5));
cout << "Stereo Calibration done with RMS error = " << rms << endl;
stereoRectify(cameraMatL, distcoeffL, cameraMatR, distcoeffR, imageSize, R, T, Rl,
Rr, Pl, Pr, Q, CALIB_ZERO_DISPARITY, -1, imageSize, &validROIL,&validROIR);
initUndistortRectifyMap(cameraMatL, distcoeffL, Rl, Pl, imgSize, CV_32FC1, mapLx, mapLy);
initUndistortRectifyMap(cameraMatR, distcoeffR, Rr, Pr, imgSize, CV_32FC1, mapRx, mapRy);
Mat rectifyImageL, rectifyImageR;
cvtColor(grayImageL, rectifyImageL, CV_GRAY2BGR);
cvtColor(grayImageR, rectifyImageR, CV_GRAY2BGR);
Mat rectifyImageL2, rectifyImageR2;
remap(rectifyImageL, rectifyImageL2, mapLx, mapLy, INTER_LINEAR);
remap(rectifyImageR, rectifyImageR2, mapRx, mapRy, INTER_LINEAR);