はじめに
C++のOpenCVでキャリブレーションした結果を、XMLファイルとして出力しました。
そのファイルをPythonで使いたかったのですが、C++とPythonではcv::FileStorageの読み込みの勝手が違かったので、備忘録として書いておきます。
読み込むファイル
次のような、C++のOpenCVで出力したファイルがあったとします。
omnidirectionalCalibrate.xml
<?xml version="1.0"?>
<opencv_storage>
<RMS>3.2860994656014744e+00</RMS>
<K type_id="opencv-matrix">
<rows>3</rows>
<cols>3</cols>
<dt>d</dt>
<data>
1.0891482187714628e+03 3.4148746667908486e-01 1.6082218600862714e+03
0. 1.0872430597310340e+03 1.2048174008443893e+03 0. 0. 1.</data></K>
<Xi type_id="opencv-matrix">
<rows>1</rows>
<cols>1</cols>
<dt>d</dt>
<data>
5.9766312514988507e-01</data></Xi>
<D type_id="opencv-matrix">
<rows>1</rows>
<cols>4</cols>
<dt>d</dt>
<data>
-2.1131777151998019e-01 2.6371490472846541e-02
-7.7007784809701241e-04 2.6734126945072976e-03</data></D>
</opencv_storage>
読み込みサンプルコード
sample.py
import cv2
import numpy as np
xmlpath = 'omnidirectionalCalibrate.xml'
fs = cv2.FileStorage(xmlpath, cv2.FileStorage_READ)
K = fs.getNode('K').mat()
D = fs.getNode('D').mat()
Xi = fs.getNode('Xi').mat()
RMS = fs.getNode('RMS').real()
print(K)
print(D)
print(Xi)
print(RMS)
FileStorageで読み込んだあと、getNodeで各タグの要素にアクセスします。
RMSのようにタグに囲まれただけの値はreal()で、他のK、D、Xiのようにtype_id = opencv-matrixがついている行列はmat()で値を取得します。
出力結果
[[1.08914822e+03 3.41487467e-01 1.60822186e+03]
[0.00000000e+00 1.08724306e+03 1.20481740e+03]
[0.00000000e+00 0.00000000e+00 1.00000000e+00]]
[[-0.21131777 0.02637149 -0.00077008 0.00267341]]
[[0.59766313]]
3.2860994656014744
以上です。