ROS+Opencv的双目相机标定和orbslam双目参数匹配
本文承接ROS调用USB双目摄像头模组
目录
- 先完成单目标定
- 双目标定
- 生成可用于ORB-SLAM2的yaml文件
- 生成可用于ORB-SLAM3的yaml文件
- 参考
按照上面链接配置好后,执行
rostopic list
你应该可以找到两个比较关键的节点:/left_cam/image_raw 和 /right_cam/image_raw
先完成单目标定
然后你需要准备黑白棋盘格:
http://www.vision.caltech.edu/bouguetj/calib_doc/htmls/pattern.pdf
接下来启动相机标定程序
rosrun camera_calibration cameracalibrator.py –size 8×6 –square 0.042 image:=/left_cam/image_raw
–size表示要识别的黑白格阵列的大小;
–square指定方格的尺寸,单位m。我是直接用另一个显示屏打开该黑白格文件,设置尺寸为42 mm=0.042 m;
image表示使用的是来哪个Topic的图像数据。左目相机为**/left_cam/image_raw**, 右目为**/right_cam/image_raw**
打开下面的界面后,立即开始标定。你需要左右,上下,前后,对角方向移动摄像头(或标定板)。
类似下面系统会自动探测并保存图像。
当使得标定界面右边X,Y,Size,Skew都变成绿色后
点击早已变成蓝色的CALIBRATE按钮,等待系统计算。
计算完成后,SAVE(保存)和COMMIT(提交)都可以点击
当你点击SAVE之后,命令行显示
这个时候应该是可以点击commit的,但我没成功过……感兴趣的可以去原文看看
我的做法是,找到**/tmp/calibrationdata.tar.gz**,
解压tar -zxvf calibrationdata.tar.gz(也可以右键解压)
打开找到ost.yaml,内容类似下面
然后右目摄像头类似,改成**/right_cam/image_raw**即可
双目标定
由于双目标定需要左右相机同时拍照,所以我们要另行拍照了。
我的双目相机是合并图像的,所以只开一个VideoCapture 即可
这里有分开图像的双目相机拍摄代码
capture.cpp
#include<iostream>
#include<string>
#include<opencv2/opencv.hpp>
#include <boost/format.hpp>using namespace std;
using namespace cv;boost::format left_imgs("./1_left/left%03d.jpg");
boost::format right_imgs("./2_right/right%03d.jpg");int main(int argc, const char** argv) //程序主函数
{string command;if (access("left", 0) == -1){//如果文件夹不存在//则创建command = "mkdir -p left";system(command.c_str());}if (access("right", 0) == -1){//如果文件夹不存在//则创建command = "mkdir -p right";system(command.c_str());}VideoCapture cap(0);//打开相机,电脑自带摄像头一般编号为0,外接摄像头编号为1,主要是在设备管理器中查看自己摄像头的编号。//--------------------------------------------------------------------------------------cap.set(CV_CAP_PROP_FRAME_WIDTH, 2560); //设置捕获视频的宽度cap.set(CV_CAP_PROP_FRAME_HEIGHT, 720); //设置捕获视频的高度if (!cap.isOpened()) //判断是否成功打开相机{cout << "摄像头打开失败!" << endl;return -1;}Mat frame, frame_L,frame_R;cap >> frame; //从相机捕获一帧图像Mat grayImage; //用于存放灰度数据double fScale = 1; //定义缩放系数,对2560*720图像进行缩放显示(2560*720图像过大,液晶屏分辨率较小时,需要缩放才可完整显示在屏幕)Size dsize = Size(frame.cols*fScale, frame.rows*fScale);Mat imagedst = Mat(dsize, CV_32S);resize(frame, imagedst, dsize);char key;int count = 0;while (true){key = waitKey(50);cap >> frame; //从相机捕获一帧图像resize(frame, imagedst, dsize); //对捕捉的图像进行缩放操作imshow("Stereo Video", frame);frame_L = imagedst(Rect(0, 0, int(frame.cols/2), frame.rows)); //获取缩放后左Camera的图像frame_R = imagedst(Rect(int(frame.cols/2), 0, int(frame.cols/2), frame.rows)); //获取缩放后右Camera的图像if (key == 27) //按下ESC退出break;if (key == 32) // 按下空格开始拍照图片保存在工程文件下{imwrite((left_imgs % count).str(), frame_L);imwrite((right_imgs % count).str(), frame_R);count++;
// imshow("图片left", frame_L);
// imshow("图片right", frame_R);}}return 0;
}
运行后按空格拍照,按ESC退出
然后是双目标定的代码:
stereo_calibrator.cpp
//
// Created by daybeha on 2022/2/9.
//
// 双目相机标定#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <boost/format.hpp>#include <opencv2/opencv.hpp>using namespace std;
using namespace cv; //依旧很长的开头boost::format left_imgs("./1_left/left%03d.jpg");
boost::format right_imgs("./2_right/right%03d.jpg");
const int frameNumber = 51; //相机标定时需要采用的图像帧数
const int squareSize = 42; //标定板黑白格子的大小 单位mmconst int imageWidth = 1280; //摄像头的分辨率
const int imageHeight = 720;
const int boardWidth = 8; //横向的角点数目
const int boardHeight = 6; //纵向的角点数据
const int boardCorner = boardWidth * boardHeight; //总的角点数据const Size boardSize = Size(boardWidth, boardHeight); //标定板的总内角点
Size imageSize = Size(imageWidth, imageHeight);Mat R, T, E, F; //R 旋转矢量 T平移矢量 E本征矩阵 F基础矩阵
vector<Mat> rvecs; //旋转向量
vector<Mat> tvecs; //平移向量
vector<vector<Point2f>> imagePointL; //左边摄像机所有照片角点的坐标集合
vector<vector<Point2f>> imagePointR; //右边摄像机所有照片角点的坐标集合
vector<vector<Point3f>> objRealPoint; //各副图像的角点的实际物理坐标集合vector<Point2f> cornerL; //左边摄像机某一照片角点坐标集合vector<Point2f> cornerR; //右边摄像机某一照片角点坐标集合Mat rgbImageL, grayImageL;
Mat rgbImageR, grayImageR;Mat Rl, Rr, Pl, Pr, Q; //校正旋转矩阵R,投影矩阵P 重投影矩阵Q (下面有具体的含义解释)
Mat mapLx, mapLy, mapRx, mapRy; //映射表
Rect validROIL, validROIR; //图像校正之后,会对图像进行裁剪,这里的validROI就是指裁剪之后的区域/*
事先标定好的左相机的内参矩阵
fx 0 cx
0 fy cy
0 0 1
*/
Mat cameraMatrixL = (Mat_<double>(3, 3) << 996.62773, 0. , 723.74872,0. , 991.38498, 307.46763,0. , 0. , 1. ); //这时候就需要你把左右相机单目标定的参数给写上
//获得的畸变参数
Mat distCoeffL = (Mat_<double>(5, 1) << 0.274795, -0.241477, -0.009914, 0.033414, 0.000000);
/*
事先标定好的右相机的内参矩阵
fx 0 cx
0 fy cy
0 0 1
*/
Mat cameraMatrixR = (Mat_<double>(3, 3) << 861.43065, 0. , 647.48681,0. , 853.88712, 282.7715 ,0. , 0. , 1. );
Mat distCoeffR = (Mat_<double>(5, 1) << 0.205708, -0.287710, 0.003034, 0.007459, 0.000000);/*计算标定板上模块的实际物理坐标*/
void calRealPoint(vector<vector<Point3f>>& obj, int boardwidth, int boardheight, int imgNumber, int squaresize)
{vector<Point3f> imgpoint;for (int rowIndex = 0; rowIndex < boardheight; rowIndex++){for (int colIndex = 0; colIndex < boardwidth; colIndex++){imgpoint.emplace_back(Point3f(rowIndex * squaresize, colIndex * squaresize, 0));}}for (int imgIndex = 0; imgIndex < imgNumber; imgIndex++){obj.push_back(imgpoint);}
}void outputCameraParam()
{/*保存数据*//*输出数据*/FileStorage fs("intrinsics.yml", FileStorage::WRITE); //文件存储器的初始化if (fs.isOpened()){fs << "cameraMatrixL" << cameraMatrixL << "cameraDistcoeffL" << distCoeffL << "cameraMatrixR" << cameraMatrixR << "cameraDistcoeffR" << distCoeffR;fs.release();cout << "cameraMatrixL=:" << cameraMatrixL << endl << "cameraDistcoeffL=:" << distCoeffL << endl << "cameraMatrixR=:" << cameraMatrixR << endl << "cameraDistcoeffR=:" << distCoeffR << endl;}else{cout << "Error: can not save the intrinsics!!!!!" << endl;}fs.open("extrinsics.yml", FileStorage::WRITE);if (fs.isOpened()){fs << "R" << R << "T" << T << "Rl" << Rl << "Rr" << Rr << "Pl" << Pl << "Pr" << Pr << "Q" << Q;cout << "R=" << R << endl << "T=" << T << endl << "Rl=" << Rl << endl << "Rr=" << Rr << endl << "Pl=" << Pl << endl << "Pr=" << Pr << endl << "Q=" << Q << endl;fs.release();}elsecout << "Error: can not save the extrinsic parameters\n";
}int main(int argc, char* argv[])
{Mat img;int goodFrameCount = 0;while (goodFrameCount < frameNumber){char filename[100];/*读取左边的图像*/rgbImageL = imread((left_imgs % goodFrameCount).str(), CV_LOAD_IMAGE_COLOR);cvtColor(rgbImageL, grayImageL, CV_BGR2GRAY);/*读取右边的图像*/rgbImageR = imread((left_imgs % goodFrameCount).str(), CV_LOAD_IMAGE_COLOR);cvtColor(rgbImageR, grayImageR, CV_BGR2GRAY);bool isFindL, isFindR;isFindL = findChessboardCorners(rgbImageL, boardSize, cornerL);isFindR = findChessboardCorners(rgbImageR, boardSize, cornerR);if (isFindL && isFindR) //如果两幅图像都找到了所有的角点 则说明这两幅图像是可行的{/*Size(5,5) 搜索窗口的一半大小Size(-1,-1) 死区的一半尺寸TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 20, 0.1)迭代终止条件*/cornerSubPix(grayImageL, cornerL, Size(5, 5), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 20, 0.1));drawChessboardCorners(rgbImageL, boardSize, cornerL, isFindL);imshow("chessboardL", rgbImageL);imagePointL.push_back(cornerL);cornerSubPix(grayImageR, cornerR, Size(5, 5), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 20, 0.1));drawChessboardCorners(rgbImageR, boardSize, cornerR, isFindR);imshow("chessboardR", rgbImageR);imagePointR.push_back(cornerR);//string filename = "res\\image\\calibration";//filename += goodFrameCount + ".jpg";//cvSaveImage(filename.c_str(), &IplImage(rgbImage)); //把合格的图片保存起来goodFrameCount++;cout << "The image" << goodFrameCount << " is good" << endl;}else{cout << "The image is bad please try again" << endl;}if (waitKey(10) == 'q'){break;}}/*计算实际的校正点的三维坐标根据实际标定格子的大小来设置*/calRealPoint(objRealPoint, boardWidth, boardHeight, frameNumber, squareSize);cout << "cal real successful" << endl;/*标定摄像头由于左右摄像机分别都经过了单目标定所以在此处选择flag = CALIB_USE_INTRINSIC_GUESS*/double rms = stereoCalibrate(objRealPoint, imagePointL, imagePointR,cameraMatrixL, distCoeffL,cameraMatrixR, 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;/*立体校正的时候需要两幅图像共面并且行对准 以使得立体匹配更加的可靠使得两幅图像共面的方法就是把两个摄像头的图像投影到一个公共成像面上,这样每幅图像从本图像平面投影到公共图像平面都需要一个旋转矩阵RstereoRectify 这个函数计算的就是从图像平面投影到公共成像平面的旋转矩阵Rl,Rr。 Rl,Rr即为左右相机平面行对准的校正旋转矩阵。左相机经过Rl旋转,右相机经过Rr旋转之后,两幅图像就已经共面并且行对准了。其中Pl,Pr为两个相机的投影矩阵,其作用是将3D点的坐标转换到图像的2D点的坐标:P*[X Y Z 1]' =[x y w]Q矩阵为重投影矩阵,即矩阵Q可以把2维平面(图像平面)上的点投影到3维空间的点:Q*[x y d 1] = [X Y Z W]。其中d为左右两幅图像的时差*///对标定过的图像进行校正stereoRectify(cameraMatrixL, distCoeffL, cameraMatrixR, distCoeffR, imageSize, R, T, Rl, Rr, Pl, Pr, Q,CALIB_ZERO_DISPARITY, -1, imageSize, &validROIL, &validROIR);/*根据stereoRectify 计算出来的R 和 P 来计算图像的映射表 mapx,mapymapx,mapy这两个映射表接下来可以给remap()函数调用,来校正图像,使得两幅图像共面并且行对准ininUndistortRectifyMap()的参数newCameraMatrix就是校正后的摄像机矩阵。在openCV里面,校正后的计算机矩阵Mrect是跟投影矩阵P一起返回的。所以我们在这里传入投影矩阵P,此函数可以从投影矩阵P中读出校正后的摄像机矩阵*///摄像机校正映射initUndistortRectifyMap(cameraMatrixL, distCoeffL, Rl, Pr, imageSize, CV_32FC1, mapLx, mapLy);initUndistortRectifyMap(cameraMatrixR, distCoeffR, Rr, Pr, imageSize, CV_32FC1, mapRx, mapRy);Mat rectifyImageL, rectifyImageR;cvtColor(grayImageL, rectifyImageL, CV_GRAY2BGR);cvtColor(grayImageR, rectifyImageR, CV_GRAY2BGR);imshow("Rectify Before", rectifyImageL);cout << "按Q1退出 ..." << endl;/*经过remap之后,左右相机的图像已经共面并且行对准了*/Mat rectifyImageL2, rectifyImageR2;remap(rectifyImageL, rectifyImageL2, mapLx, mapLy, INTER_LINEAR);remap(rectifyImageR, rectifyImageR2, mapRx, mapRy, INTER_LINEAR);cout << "按Q2退出 ..." << endl;imshow("rectifyImageL", rectifyImageL2);imshow("rectifyImageR", rectifyImageR2);/*保存并输出数据*/outputCameraParam();/*把校正结果显示出来把左右两幅图像显示到同一个画面上这里只显示了最后一副图像的校正结果。并没有把所有的图像都显示出来*/Mat canvas;double sf;int w, h;sf = 600. / MAX(imageSize.width, imageSize.height);w = cvRound(imageSize.width * sf);h = cvRound(imageSize.height * sf);canvas.create(h, w * 2, CV_8UC3);/*左图像画到画布上*/Mat canvasPart = canvas(Rect(w * 0, 0, w, h)); //得到画布的一部分resize(rectifyImageL2, canvasPart, canvasPart.size(), 0, 0, INTER_AREA); //把图像缩放到跟canvasPart一样大小Rect vroiL(cvRound(validROIL.x*sf), cvRound(validROIL.y*sf), //获得被截取的区域cvRound(validROIL.width*sf), cvRound(validROIL.height*sf));rectangle(canvasPart, vroiL, Scalar(0, 0, 255), 3, 8); //画上一个矩形cout << "Painted ImageL" << endl;/*右图像画到画布上*/canvasPart = canvas(Rect(w, 0, w, h)); //获得画布的另一部分resize(rectifyImageR2, canvasPart, canvasPart.size(), 0, 0, INTER_LINEAR);Rect vroiR(cvRound(validROIR.x * sf), cvRound(validROIR.y*sf),cvRound(validROIR.width * sf), cvRound(validROIR.height * sf));rectangle(canvasPart, vroiR, Scalar(0, 255, 0), 3, 8);cout << "Painted ImageR" << endl;/*画上对应的线条*/for (int i = 0; i < canvas.rows; i += 16)line(canvas, Point(0, i), Point(canvas.cols, i), Scalar(0, 255, 0), 1, 8);imshow("rectified", canvas);cout << "wait key" << endl;waitKey(0);//system("pause");return 0;
}
之后你会得到外参文件extrinsics.yml和内参文件intrinsics.yml
标定结果:
生成可用于ORB-SLAM2的yaml文件
首先找到ORB-SLAM2的EuRoC.yaml作为参照
%YAML:1.0#--------------------------------------------------------------------------------------------
# Camera Parameters. Adjust them!
#--------------------------------------------------------------------------------------------# Camera calibration and distortion parameters (OpenCV)
Camera.fx: 435.2046959714599
Camera.fy: 435.2046959714599
Camera.cx: 367.4517211914062
Camera.cy: 252.2008514404297
//
这个是 双目相机的参数不是单个的做相机的相机中心跟焦距。
其对应:extrinsics.yml中的 Pr:
例如我的是
Pr: !!opencv-matrixrows: 3cols: 4dt: ddata: [ 2.8559499458758660e+02, 0., 2.7029193305969238e+02,-3.9636548646706200e+04, 0., 2.8559499458758660e+02,2.8112063348293304e+02, 0., 0., 0., 1., 0. ]
对应的修改焦距和相机中心如下:
Camera.fx: 2.8559499458758660e+02
Camera.fy: 2.8559499458758660e+02
Camera.cx: 2.7029193305969238e+02
Camera.cy: 2.8112063348293304e+02
//Camera.k1: 0.0
Camera.k2: 0.0
Camera.p1: 0.0
Camera.p2: 0.0
//
默认不改,因代码中已做畸变纠正。故均为0.
//
Camera.width: 752
Camera.height: 480
//
相机的图像大小:
我的修改为:Camera.width: 1280
Camera.height: 720//
# Camera frames per second
Camera.fps: 30.0# stereo baseline times fx
Camera.bf: 47.90639384423901
//
这个参数是个大坑,其为相机的基线×相机的焦距。
orbslam的参数文件中单位是m
而opencv标定文件中的单位是mm
其数值同样可以在Pr: 中找出 定位在下面矩阵中的-3.9636548646706200e+04 这个数
Pr: !!opencv-matrixrows: 3cols: 4dt: ddata: [ 2.8559499458758660e+02, 0., 2.7029193305969238e+02,-3.9636548646706200e+04, 0., 2.8559499458758660e+02,2.8112063348293304e+02, 0., 0., 0., 1., 0. ]-3.9636548646706200e+04 就是要填入上面的参数,毫米转为米,求绝对值,填入Camera.bf: 3.9636548646706200e+01//
# Color order of the images (0: BGR, 1: RGB. It is ignored if images are grayscale)
Camera.RGB: 1# Close/Far threshold. Baseline times.
ThDepth: 35
//
深度阈值,不是一个精确的数值,大概预估的,可以不改动,要改的话参考下述公式
自己粗略估计一个相机可以良好显示的最大距离值为s = 10 如果fx = 100 Camera.bf = 20
那么 ThDepth = s*fx/Camera.bf = 10 *100 /20 = 50
将你自己的参数带入上述公式 可以得到大概的阈值。
//
#--------------------------------------------------------------------------------------------
# Stereo Rectification. Only if you need to pre-rectify the images.
# Camera.fx, .fy, etc must be the same as in LEFT.P
#--------------------------------------------------------------------------------------------
LEFT.height: 480
LEFT.width: 752
//
调整为你自己的相机大小
//
LEFT.D: !!opencv-matrixrows: 1cols: 5dt: ddata:[-0.28340811, 0.07395907, 0.00019359, 1.76187114e-05, 0.0]//位于intrinsics.yml中的cameraDistcoeffL: !!opencv-matrixrows: 5cols: 1dt: ddata: [ -2.8632659642339481e-01, 6.6994801733091039e-02,-5.4763802000265397e-04, -1.4767993829858197e-03,-6.1039950504068767e-03 ]填入上面的 LEFT.D: 即可 左图像畸变参数//LEFT.K: !!opencv-matrixrows: 3cols: 3dt: ddata: [458.654, 0.0, 367.215, 0.0, 457.296, 248.375, 0.0, 0.0, 1.0]//左图像相机内参,可在intrinsics.yml 的cameraMatrixL:找到:
cameraMatrixL: !!opencv-matrixrows: 3cols: 3dt: ddata: [ 2.8424872262658977e+02, 0., 3.3099977082276723e+02, 0.,2.8535010886794362e+02, 2.5230877864759117e+02, 0., 0., 1. ]
填入LEFT.K://
LEFT.R: !!opencv-matrixrows: 3cols: 3dt: ddata: [0.999966347530033, -0.001422739138722922, 0.008079580483432283, 0.001365741834644127, 0.9999741760894847, 0.007055629199258132, -0.008089410156878961, -0.007044357138835809, 0.9999424675829176]//左相机旋转矩阵:extrinsics.yml 中的 Rl:
Rl: !!opencv-matrixrows: 3cols: 3dt: ddata: [ 9.9750705548699170e-01, 3.5207065558213610e-02,6.1156657760632900e-02, -3.5691910468923047e-02,9.9933934145707581e-01, 6.8533308118298173e-03,-6.0874968425042433e-02, -9.0190437917577089e-03,9.9810465136093429e-01 ]
填入上面的LEFT.R: //
LEFT.P: !!opencv-matrixrows: 3cols: 4dt: ddata: [435.2046959714599, 0, 367.4517211914062, 0, 0, 435.2046959714599, 252.2008514404297, 0, 0, 0, 1, 0]
//
3x4的投影矩阵 (P' = K(RP + t) = KTP):
extrinsics.yml 中的 Pl:
Pl: !!opencv-matrixrows: 3cols: 4dt: ddata: [ 2.8559499458758660e+02, 0., 2.7029193305969238e+02, 0., 0.,2.8559499458758660e+02, 2.8112063348293304e+02, 0., 0., 0., 1.,0. ]
填入上面的 LEFT.P:
下面的右侧相机参数配置同上述左侧相机参数配置 orb特征点的参数此处不做叙述。
//RIGHT.height: 480
RIGHT.width: 752
RIGHT.D: !!opencv-matrixrows: 1cols: 5dt: ddata:[-0.28368365, 0.07451284, -0.00010473, -3.555907e-05, 0.0]
RIGHT.K: !!opencv-matrixrows: 3cols: 3dt: ddata: [457.587, 0.0, 379.999, 0.0, 456.134, 255.238, 0.0, 0.0, 1]
RIGHT.R: !!opencv-matrixrows: 3cols: 3dt: ddata: [0.9999633526194376, -0.003625811871560086, 0.007755443660172947, 0.003680398547259526, 0.9999684752771629, -0.007035845251224894, -0.007729688520722713, 0.007064130529506649, 0.999945173484644]
RIGHT.P: !!opencv-matrixrows: 3cols: 4dt: ddata: [435.2046959714599, 0, 367.4517211914062, -47.90639384423901, 0, 435.2046959714599, 252.2008514404297, 0, 0, 0, 1, 0]
//
RIGHT相机的设置与LEFT一致,唯一不同的就是RIGHT.P: 参数,
extrinsics.yml 中的 Pr:如下:
Pr: !!opencv-matrixrows: 3cols: 4dt: ddata: [ 2.8559499458758660e+02, 0., 2.7029193305969238e+02,-3.9636548646706200e+04, 0., 2.8559499458758660e+02,2.8112063348293304e+02, 0., 0., 0., 1., 0. ]
对其进行修改,也就是data中的第4个值,需要转化单位从mm转为m。
所以应该填入RIGHT.P: 的数值为:data: [ 2.8559499458758660e+02, 0., 2.7029193305969238e+02,-3.9636548646706200e+01, 0., 2.8559499458758660e+02,2.8112063348293304e+02, 0., 0., 0., 1., 0. ]
ORB Parameter 没什么争议,较为明了,暂不介绍。
//
#--------------------------------------------------------------------------------------------
# ORB Parameters
#--------------------------------------------------------------------------------------------# ORB Extractor: Number of features per image
ORBextractor.nFeatures: 1200# ORB Extractor: Scale factor between levels in the scale pyramid
ORBextractor.scaleFactor: 1.2# ORB Extractor: Number of levels in the scale pyramid
ORBextractor.nLevels: 8# ORB Extractor: Fast threshold
# Image is divided in a grid. At each cell FAST are extracted imposing a minimum response.
# Firstly we impose iniThFAST. If no corners are detected we impose a lower value minThFAST
# You can lower these values if your images have low contrast
ORBextractor.iniThFAST: 20
ORBextractor.minThFAST: 7#--------------------------------------------------------------------------------------------
# Viewer Parameters
#--------------------------------------------------------------------------------------------
Viewer.KeyFrameSize: 0.05
Viewer.KeyFrameLineWidth: 1
Viewer.GraphLineWidth: 0.9
Viewer.PointSize:2
Viewer.CameraSize: 0.08
Viewer.CameraLineWidth: 3
Viewer.ViewpointX: 0
Viewer.ViewpointY: -0.7
Viewer.ViewpointZ: -1.8
Viewer.ViewpointF: 500
下面我们用ORB-SLAM2测试一下
生成可用于ORB-SLAM3的yaml文件
ORB-SLAM3貌似对ORB-SLAM2的yaml做了简化,方便了许多。
也是找到ORB-SLAM3的EuRoC.yaml作为参照
内容差不多,不做重复注释了:
%YAML:1.0#--------------------------------------------------------------------------------------------
# System config
#--------------------------------------------------------------------------------------------# When the variables are commented, the system doesn't load a previous session or not store the current one# If the LoadFile doesn't exist, the system give a message and create a new Atlas from scratch
#System.LoadAtlasFromFile: "Session_MH01_MH02_MH03_Stereo60_Pseudo"# The store file is created from the current session, if a file with the same name exists it is deleted
#System.SaveAtlasToFile: "Session_MH01_MH02_MH03_Stereo60_Pseudo"#--------------------------------------------------------------------------------------------
# Camera Parameters. Adjust them!
#--------------------------------------------------------------------------------------------
File.version: "1.0"# 相机模型:“针孔相机”
Camera.type: "PinHole"# Camera calibration and distortion parameters (OpenCV)
Camera1.fx: 458.654
Camera1.fy: 457.296
Camera1.cx: 367.215
Camera1.cy: 248.375Camera1.k1: -0.28340811
Camera1.k2: 0.07395907
Camera1.p1: 0.00019359
Camera1.p2: 1.76187114e-05Camera2.fx: 457.587
Camera2.fy: 456.134
Camera2.cx: 379.999
Camera2.cy: 255.238Camera2.k1: -0.28368365
Camera2.k2: 0.07451284
Camera2.p1: -0.00010473
Camera2.p2: -3.55590700e-05Camera.width: 752
Camera.height: 480# Camera frames per second
Camera.fps: 20# Color order of the images (0: BGR, 1: RGB. It is ignored if images are grayscale)
Camera.RGB: 1Stereo.ThDepth: 60.0# [R T
# 0 1] 的位姿矩阵
Stereo.T_c1_c2: !!opencv-matrixrows: 4cols: 4dt: fdata: [0.999997256477797,-0.002317135723275,-0.000343393120620,0.110074137800478,0.002312067192432,0.999898048507103,-0.014090668452683,-0.000156612054392,0.000376008102320,0.014089835846691,0.999900662638081,0.000889382785432,0,0,0,1.000000000000000]#--------------------------------------------------------------------------------------------
# ORB Parameters
#--------------------------------------------------------------------------------------------# ORB Extractor: Number of features per image
ORBextractor.nFeatures: 1200# ORB Extractor: Scale factor between levels in the scale pyramid
ORBextractor.scaleFactor: 1.2# ORB Extractor: Number of levels in the scale pyramid
ORBextractor.nLevels: 8# ORB Extractor: Fast threshold
# Image is divided in a grid. At each cell FAST are extracted imposing a minimum response.
# Firstly we impose iniThFAST. If no corners are detected we impose a lower value minThFAST
# You can lower these values if your images have low contrast
ORBextractor.iniThFAST: 20
ORBextractor.minThFAST: 7#--------------------------------------------------------------------------------------------
# Viewer Parameters
#--------------------------------------------------------------------------------------------
Viewer.KeyFrameSize: 0.05
Viewer.KeyFrameLineWidth: 1.0
Viewer.GraphLineWidth: 0.9
Viewer.PointSize: 2.0
Viewer.CameraSize: 0.08
Viewer.CameraLineWidth: 3.0
Viewer.ViewpointX: 0.0
Viewer.ViewpointY: -0.7
Viewer.ViewpointZ: -1.8
Viewer.ViewpointF: 500.0
Viewer.imageViewScale: 1.0
参考
【ROS实践入门(八)ROS使用USB视觉传感器相机】
ROS&OpenCV下单目和双目摄像头的标定与使用
双目相机标定和orbslam2双目参数详解
基于Opencv实现双目摄像头拍照程序
opencv 双目标定操作完整版
ROS+Opencv的双目相机标定和orbslam双目参数匹配相关推荐
- MatLab的双目相机标定和orbslam双目参数匹配
本文承接ROS调用USB双目摄像头模组 目录 相机标定 导出为YAML文件(也可以手动粘贴) 生成可用于ORB-SLAM2的yaml文件 生成可用于ORB-SLAM3的yaml文件 2022.5.6补 ...
- matlab双目相机标定校正_双目相机的标定过程详解!-----MATLAB
基于双目视觉的测距.三维重建等过程中的第一步就是要进行标定.双目相机的标定过程在网上有很多资料,但是基本都没有matlab官方网址讲的好.所以请参考MATLAB官方文档:https://ww2.mat ...
- OpenCV | 双目相机标定之OpenCV获取左右相机图像+MATLAB单目标定+双目标定
博主github:https://github.com/MichaelBeechan 博主CSDN:https://blog.csdn.net/u011344545 原本网上可以搜到很多关于双目相机标 ...
- 双目相机标定以及立体测距原理及OpenCV实现
转载 双目相机标定以及立体测距原理及OpenCV实现 http://blog.csdn.net/dcrmg/article/details/52986522?locationNum=15&fp ...
- opencv双目相机标定-示例代码分析
在这里我使用的是Learning OpenCV3的示例,本节使用的项目代码可以在这里下载到. 一.运行示例 在下载完整个工程以后,按照工程使用说明,下载配置Opencv,运行VS2019项目即 ...
- 【ZED】从零开始使用ZED相机(五):Opencv+Python实现相机标定(双目)
引言 同样Opencv+Python实现双目相机的标定,单目标定详见[ZED]从零开始使用ZED相机(五):Opencv+Python实现相机标定(单目) 1 cv2.stereoCalibrate ...
- 双目相机标定OpenCV源码讲解
双目相机标定OpenCV源码讲解 背景介绍 所述内容 参考资料 摄像机标定部分代码 代码思路 代码中的其他函数 找角点&求内参 求外参 求矫正映射矩阵 后记 背景介绍 暑假接近两个月的时间做了 ...
- 双目相机标定以及立体测距原理及OpenCV实现(下)
前篇:双目相机标定以及立体测距原理及实现(上) 双目相机标定后,可以看到左右相机对应匹配点基本上已经水平对齐. 之后在该程序基础上运行stereo_match.cpp,求左右相机的视差. 注:下边Op ...
- 一文详解双目相机标定理论
01 前言 双目相机标定,从广义上讲,其实它包含两个部分内容: 两台相机各自误差的标定(单目标定) 两台相机之间相互位置的标定(狭义,双目标定) 在这里我们所说的双目标定是狭义的,讲解理论的时候仅指两 ...
最新文章
- 2021年华为与小康-北汽-长安
- php 断点续传,php支持断点续传的文件下载类(附源码)
- 卓晴老师“标杆课教师“采访提纲
- ERROR (ClientException): Unexpected API Error
- php获取页面中的指定内容,php 获取页面中指定内容的实现类
- robot 用AP连PC
- 使用autoit实现自动加域
- [转]SQL中的case when then else end用法
- VMware12部署windows xp虚拟机
- 2017-2018-1 20155327 《信息安全系统设计基础》第十三周学习总结
- 直击平昌!2天40位大咖的平昌区块链论坛精华都在这了!
- raid -- 分区-- 格式化 --挂载
- 微型计算机的现状历史未来,微型计算机的发展历史、现状和未来
- IntelliJ IDEA 2021 for Mac(最好的java开发工具)正式版支持m1芯片
- 智能家居控制系统完整设计方案
- TAP-Win32 Adapter OAS“的网络适配器删除后总是出现(kms激活器及win10激活)
- 百度ueditor粘贴word图片且图片文件自动上传功能
- 中国首届微博开发者大会杨卫华演讲
- javaweb技术及应用QST
- HBuildX 打包说明(网站链接打包apk(app))