相机校准与方形棋盘
本教程的目标是学习如何校准一个已经给定一套棋盘图像的相机。
测试数据:使用数据/象棋文件夹中的图像。
- 通过在cmake配置中将BUILD_EXAMPLES设置为ON,用OpenCV编译样本。
- 转到bin文件夹,并使用imagelist_creator创建图像的XML / YAML列表。
- 然后,运行校准样品以获取相机参数。使用方形尺寸等于3cm。
Pose 预估
现在,让我们编写检测图像中棋盘的代码,并找到与相机的距离。您可以将此方法应用于具有已知3D几何的任何对象; 您在图像中检测到。
测试数据:使用您的数据文件夹中的chess_test * .jpg图像。
- 创建一个空的控制台项目。加载测试图像:
Mat img = imread(argv [1],IMREAD_GRAYSCALE);
- 使用findChessboard功能检测此图像中的棋盘:
bool found = findChessboardCorners(img,boardSize,ptvec,CALIB_CB_ADAPTIVE_THRESH);
- 现在,在任何坐标系中编写一个生成棋盘的3d坐标矢量<Point3f>数组的函数。为了简单起见,我们选择一个系统,使得棋盘角中的一个位于原点,而棋盘在平面z = 0
- 从XML / YAML文件读取相机参数:
FileStorage fs( filename, FileStorage::READ );
Mat intrinsics, distortion;
fs["camera_matrix"] >> intrinsics;
fs["distortion_coefficients"] >> distortion;
- 现在我们准备通过运行`solvePnP`来找到棋盘姿势了
vector<Point3f> boardPoints;
// fill the array
...
solvePnP(Mat(boardPoints), Mat(foundBoardCorners), cameraMatrix,
distCoeffs, rvec, tvec, false);
- 计算重新投影错误,就像在校准样品中一样(参见opencv / samples / cpp / calibration.cpp,函数computeReprojectionErrors)。
问题:你如何计算从相机原点到任何一个角落的距离?答:由于我们的形象在于3D空间,首先我们将计算出相对摄像机的姿势。这将给我们3D到2D通信。接下来,我们可以应用一个简单的L2范数来计算任何点(拐点的终点)之间的距离。