MATLAB相机标定的使用并导出XML文件

MATLAB相机标定的使用并导出XML文件

前言

MATLAB的相机标定工具cameraCalibrator位于Computer Vision toolBox,在命令行输入cameraCalibrator,并回车即可启动GUI界面,可视化做得很友好,而且要比opencv中的相机标定准确度要高,运行速度要快(自己体会),下面介绍一下如何使用,以及如何将标定好的参数导出为XML文件,以供opencv读入。

目录

MATLAB相机标定的使用

准备工作

打印一种黑白棋盘图像,在MATLAB中的帮助文档中已经为我们准备好了一个pdf文件(MATLAB安装目录\MATLAB\R201xa(b)\help\toolbox\vision\examples\checkerboardPattern.pdf),这是一张黑白棋盘图像,我们找到它,打印即可。

下一步就是用相机进行拍照,从不同的角度进行拍照,为了达到较高的精度,图片的数目至少要20张左右。我用自己的手机拍了17张照片。(注意拍照时的分辨率要固定,且图片的尺寸要一致!)

相机标定

步骤:

  • 启动:cameraCalibrator回车

  • add images

  • 设置棋盘格的尺寸(mm),提前量一下。

  • 设置参数。包括径向畸变参数的个数(2/3)、是否计算切向畸变。我的设置分别是3、是。

  • 开始标定

  • 参数导出,保存的参数是一种特殊的数据结构,里面包含了相机内参(IntrinsicMatrix)、径向畸变(RadialDistortion)、切向畸变(TangentialDistortion)、相机的外参(RotationMatrices,TranslationVectors)等。

这里写图片描述
上面是一张截图,右侧还可以将每一张图片对应的相机外参以三维立体图的形式展现。

导出XML文件

通过编写MATLAB函数向相机标定的内参和畸变参数保存为opencv可以读取的XML文件

function writeXML(cameraParams,file)
%writeXML(cameraParams,file)
%功能:将相机校正的参数保存为xml文件
%输入:
%cameraParams:相机校正数据结构
%file:xml文件名
%说明在xml文件是由一层层的节点组成的。
%首先创建父节点 fatherNode,
%然后创建子节点 childNode=docNode.createElement(childNodeName),
%再将子节点添加到父节点 fatherNode.appendChild(childNode)
docNode = com.mathworks.xml.XMLUtils.createDocument('opencv_storage'); %创建xml文件对象
docRootNode = docNode.getDocumentElement; %获取根节点

IntrinsicMatrix = (cameraParams.IntrinsicMatrix)'; %相机内参矩阵
RadialDistortion = cameraParams.RadialDistortion; %相机径向畸变参数向量1*3
TangentialDistortion =cameraParams.TangentialDistortion; %相机切向畸变向量1*2
Distortion = [RadialDistortion(1:2),TangentialDistortion,RadialDistortion(3)]; %构成opencv中的畸变系数向量[k1,k2,p1,p2,k3]

camera_matrix = docNode.createElement('camera-matrix'); %创建mat节点
camera_matrix.setAttribute('type_id','opencv-matrix'); %设置mat节点属性
rows = docNode.createElement('rows'); %创建行节点
rows.appendChild(docNode.createTextNode(sprintf('%d',3))); %创建文本节点,并作为行的子节点
camera_matrix.appendChild(rows); %将行节点作为mat子节点

cols = docNode.createElement('cols');
cols.appendChild(docNode.createTextNode(sprintf('%d',3)));
camera_matrix.appendChild(cols);

dt = docNode.createElement('dt');
dt.appendChild(docNode.createTextNode('d'));
camera_matrix.appendChild(dt);

data = docNode.createElement('data');
for i=1:3
    for j=1:3
        data.appendChild(docNode.createTextNode(sprintf('%.16f ',IntrinsicMatrix(i,j))));
    end
    data.appendChild(docNode.createTextNode(sprintf('\n')));
end
camera_matrix.appendChild(data);
docRootNode.appendChild(camera_matrix);

distortion = docNode.createElement('distortion');
distortion.setAttribute('type_id','opencv-matrix');
rows = docNode.createElement('rows');
rows.appendChild(docNode.createTextNode(sprintf('%d',5)));
distortion.appendChild(rows);

cols = docNode.createElement('cols');
cols.appendChild(docNode.createTextNode(sprintf('%d',1)));
distortion.appendChild(cols);

dt = docNode.createElement('dt');
dt.appendChild(docNode.createTextNode('d'));
distortion.appendChild(dt);
data = docNode.createElement('data');
for i=1:5
      data.appendChild(docNode.createTextNode(sprintf('%.16f ',Distortion(i))));
end
distortion.appendChild(data);

docRootNode.appendChild(distortion);

xmlFileName = file;
xmlwrite(xmlFileName,docNode);
end

在命令行输入:

writeXML(cameraParams,'cameraParams.xml');

就完成了将相机内参和畸变参数保存问XML文件。

以下是导出到XML文件内容:

<?xml version="1.0" encoding="utf-8"?>
<opencv_storage>
   <camera-matrix type_id="opencv-matrix">
      <rows>3</rows>
      <cols>3</cols>
      <dt>d</dt>
      <data>3099.7082447931371000 0.0000000000000000 1077.7535540640906000 
0.0000000000000000 3086.4434775466948000 1826.5450377846478000 
0.0000000000000000 0.0000000000000000 1.0000000000000000 
</data>
   </camera-matrix>
   <distortion type_id="opencv-matrix">
      <rows>5</rows>
      <cols>1</cols>
      <dt>d</dt>
      <data>-0.0890744873306951 5.1317176243308209 -0.0051019418392772 -0.0021081150992697 -39.0645994879151530 </data>
   </distortion>
</opencv_storage>

上面的函数只导出了相机内参和畸变参数,其它参数没有导出。

经过测试,可以从opencv中使用FileStorage读取。

猜你喜欢

转载自blog.csdn.net/healingwounds/article/details/78752046