Help us understand the problem. What is going on with this article?

C++のcv::FileStorageで出力したXMLファイルをPythonのOpenCVで読み込む

はじめに

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

以上です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away