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讀取。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章