OpenCVでXML/YAML/JSONのデータ構造を扱う
OpenCVでcvパラメータを扱う場合、cv::FileStorageクラスが用意されている。XML, YAML, JSONの各フォーマットのファイルからパラメータの読み書きができる。
利点は、
- C++で簡単にパラメータのファイルを扱うことができる
- cv::Mat, cv::Size等のOpenCVの形式でパラメータを読み書きできること
カメラキャリブレーションのopencv_interactive-calibrationもXML形式のファイルを出力するので、パラメータを読む際は、cv::FileStorageクラスが利用できる。
自作中のPaspberry Piの3Dスキャナーでもcv::FileStorageクラスを利用してパラメータの読み込みを行う予定。
cv::FileStorageをPythonで使う
手書きでパラメータのファイルを作成するより、ファイルを自動生成できたほうが良いと考え、Pythonでツールを作成したのだが、思ったように使えないことが判明した。
(Pythonでサクッと作ってしまえば良いと思っていた)
Pythonで扱う場合の問題(デメリット)
配列(シーケンス)のデータを出力できない
例えば、C++で解像度などcv::Sizeで保持されるデータを出力した場合、シーケンスとして出力される。
<cameraResolution> 640 480</cameraResolution>
しかし、Pythonにはcv::Sizeはなく、タプルで扱うことになるが、タプルはcv::Matに変換されてしまうため、シーケンスとして出力されず、以下のように出力されてしまう。
<cameraResolution type_id="opencv-matrix"> <rows>2</rows> <cols>1</cols> <dt>d</dt> <data> 640. 480.</data></cameraResolution>
これは、Pythonの場合、タプル、リストはすべてcv::Matにバインディングされるためである。読み込み時もPythonであれば、問題はないのだが、C++の場合、cv::Matにしか使えなくなってしまう。
マッピングのデータを出力できない
C++では<< operatorで"{", "}"を出力することで、マッピングされたデータを出力できる。
(同じように"[", "]"でシーケンスのデータを出力できる)
詳細は、OpenCVのドキュメントを参照。
しかし、Pythonには<< operatorはバインディングされていないため出力できない。
代替え方法
もともと、cv::FileStorageはC++でパラメータを扱いやすくするためであり、Pythonで扱うこと自体があまり良い考えでないと思う。
Pythonで扱うのであれば、PyYAMLを使ったほうが良く、Pythonで出力したデータをC++のcv::FileStorageで読み込むこともできるはず。
ただし、PyYAMLではcv::Matの形式では出力できなくなるが、その場合は自作してしまえば良いとなる。
0 件のコメント:
コメントを投稿