![]() |
OpenCV 5.0.0
Open Source Computer Vision
|
前のチュートリアル: 離散フーリエ変換
次のチュートリアル: OpenCV の parallel_for_ 関数でコードを並列化する方法 (マンデルブロ集合の例)
次のチュートリアル: OpenCV の parallel_for_ 関数でコードを並列化する方法 (畳み込みの例)
| 原著者 | Bernát Gábor |
| 互換性 | OpenCV >= 3.0 |
次の疑問に対する答えが見つかる。
ここではXML、YAML、JSONのファイル入力についてのみ説明する。出力(およびそれに対応する入力)ファイルは、これらの拡張子のいずれか1つだけを持ち、それに応じた構造になる。シリアライズできるデータ構造には2種類ある。マッピング(STLのmapやPythonの辞書のようなもの)と要素のシーケンス(STLのvectorのようなもの)である。両者の違いは、mapではすべての要素が一意の名前を持ち、それを通じてアクセスできる点にある。シーケンスの場合は、特定の項目を取得するためにそれらをたどっていく必要がある。
XML/YAML/JSONファイルのオープンとクローズ。 そのようなファイルに内容を書き込む前に、ファイルを開き、最後に閉じる必要がある。OpenCVにおけるXML/YAML/JSONデータ構造はcv::FileStorageである。この構造をハードドライブ上のどのファイルに結び付けるかを指定するには、そのコンストラクタかこのopen()関数のいずれかを使う。
どちらを使う場合でも、2番目の引数はそれらに対して実行できる操作の種類を指定する定数である: WRITE、READ、APPEND。ファイル名に指定された拡張子は、使用される出力フォーマットも決定する。.xml.gzのような拡張子を指定すれば、出力を圧縮することさえできる。
ファイルはcv::FileStorageオブジェクトが破棄されると自動的に閉じられる。ただし、release関数を使って明示的に呼び出すこともできる。
ベクトル(配列)と連想マップの入出力。 前述のとおり、mapやシーケンス(配列、ベクトル)も出力できる。ここでもまず変数の名前を出力し、その後に出力がシーケンスかmapのどちらであるかを指定する必要がある。
シーケンスでは、最初の要素の前に "[" 文字を、最後の要素の後に "]" 文字を出力する。Pythonでは、FileStorage.startWriteStruct(structure_name, struct_type) を呼び出して構造の書き込みを開始する。ここで struct_type は cv2.FileNode_MAP または cv2.FileNode_SEQ である。FileStorage.endWriteStruct() を呼び出して構造を終了する。
mapでも要領は同じだが、今度は "{" と "}" の区切り文字を使う。
これらから読み込むには、cv::FileNodeとcv::FileNodeIteratorのデータ構造を使う。cv::FileStorageクラスの [] 演算子(またはPythonのgetNode()関数)はcv::FileNodeデータ型を返す。ノードがシーケンスである場合は、cv::FileNodeIteratorを使って項目を反復処理できる。Pythonでは、at()関数を使ってシーケンスの要素にアドレス指定でき、size()関数はシーケンスの長さを返す。
マップ(map)に対しては、[] 演算子(PythonではAt() 関数)を再び使って指定した要素にアクセスできる(>> 演算子も使える):
独自のデータ構造を読み書きする。 次のようなデータ構造があるとする:
C++では、(OpenCVのデータ構造の場合と同様に)クラスの内側と外側に read 関数と write 関数を追加することで、OpenCVのI/O XML/YAMLインターフェースを通じてこれをシリアライズできる。Pythonでは、クラス内に read 関数と write 関数を実装することでこれに近いことができる。内側の部分については:
ここでは、read セクションで、ユーザーが存在しないノードを読み込もうとした場合の動作を定義していることが分かる。この場合は単にデフォルトの初期化値を返しているが、より丁寧な解決策としては、たとえばオブジェクトIDに対してマイナス1の値を返すといった方法もある。
これら4つの関数を追加したら、書き込みには >> 演算子を、読み込みには << 演算子を使う(Pythonでは定義した入出力関数を使う):
あるいは、存在しないノードの読み込みを試すには:
ほとんどの場合、定義した数値を出力するだけである。コンソールの画面には次のように表示されるはずだ:
とはいえ、出力されたXMLファイルの中身の方がはるかに興味深い:
あるいはYAMLファイル:
これの実行例は こちらのYouTube で見ることができる。