ファイルストレージ
typedef struct CvFileStorage { ... // 隠しフィールド } CvFileStorage;
構造体 CvFileStorage は,ディスク上のファイルと関連付けられたファイルストレージの,「ブラックボックス」的な表現です.後述されるいくつかの関数は,引数として CvFileStorage をとり,スカラー値や標準的なCXCoreオブジェクト(行列やシーケンス,グラフ),ユーザ定義オブジェクトなどから構成される階層的コレクションに対して,読み書きを可能にします.
CXCoreの関数では,XML( http://www.w3c.org/XML )や YAML( http://www.yaml.org )形式のデータの読み書きが可能です.以下は,浮動小数点型の 単位行列 A を,CxCore 関数を用いて XML および YAML 形式のファイルに保存したものです:
XML:
\begin{verbatim}
<?xml version="1.0">
<opencv_storage>
<A type_id="opencv-matrix">
<rows>3</rows>
<cols>3</cols>
<dt>f</dt>
<data>1. 0. 0. 0. 1. 0. 0. 0. 1.</data>
</A>
</opencv_storage>
\end{verbatim}
YAML:
\begin{verbatim}
%YAML:1.0
A: !!opencv-matrix
rows: 3
cols: 3
dt: f
data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1.]
\end{verbatim}
この例から分かるように,階層構造を表現するために,XMLではネスト(入れ子)されたタグを利用し,YAMLでは(Pythonと似た)インデントを利用します.
同じCXCore関数で,どちらのデータ形式の読み書きが可能で,オープンされたファイルの拡張子(XMLでは .xml,YAMLでは .yaml)によって形式を判別します.
ファイルストレージノード.
/* ファイルノードの種類 */ #define CV_NODE_NONE 0 #define CV_NODE_INT 1 #define CV_NODE_INTEGER CV_NODE_INT #define CV_NODE_REAL 2 #define CV_NODE_FLOAT CV_NODE_REAL #define CV_NODE_STR 3 #define CV_NODE_STRING CV_NODE_STR #define CV_NODE_REF 4 /* not used */ #define CV_NODE_SEQ 5 #define CV_NODE_MAP 6 #define CV_NODE_TYPE_MASK 7 /* オプションフラグ */ #define CV_NODE_USER 16 #define CV_NODE_EMPTY 32 #define CV_NODE_NAMED 64 #define CV_NODE_TYPE(tag) ((tag) & CV_NODE_TYPE_MASK) #define CV_NODE_IS_INT(tag) (CV_NODE_TYPE(tag) == CV_NODE_INT) #define CV_NODE_IS_REAL(tag) (CV_NODE_TYPE(tag) == CV_NODE_REAL) #define CV_NODE_IS_STRING(tag) (CV_NODE_TYPE(tag) == CV_NODE_STRING) #define CV_NODE_IS_SEQ(tag) (CV_NODE_TYPE(tag) == CV_NODE_SEQ) #define CV_NODE_IS_MAP(tag) (CV_NODE_TYPE(tag) == CV_NODE_MAP) #define CV_NODE_IS_COLLECTION(tag) (CV_NODE_TYPE(tag) >= CV_NODE_SEQ) #define CV_NODE_IS_FLOW(tag) (((tag) & CV_NODE_FLOW) != 0) #define CV_NODE_IS_EMPTY(tag) (((tag) & CV_NODE_EMPTY) != 0) #define CV_NODE_IS_USER(tag) (((tag) & CV_NODE_USER) != 0) #define CV_NODE_HAS_NAME(tag) (((tag) & CV_NODE_NAMED) != 0) #define CV_NODE_SEQ_SIMPLE 256 #define CV_NODE_SEQ_IS_SIMPLE(seq) (((seq)->flags & CV_NODE_SEQ_SIMPLE) != 0) typedef struct CvString { int len; char* ptr; } CvString; /* 読み込んだファイルストレージに含まれる要素の全てのキー(names)は, ルックアップ処理の高速化のためハッシュに記憶されます. */ typedef struct CvStringHashNode { unsigned hashval; CvString str; struct CvStringHashNode* next; } CvStringHashNode; /* ファイルストレージの基本要素 - スカラー,またはコレクション */ typedef struct CvFileNode { int tag; struct CvTypeInfo* info; /* 型情報 (ユーザ定義オブジェクトでのみ利用する,そうでない場合は0) */ union { double f; /* 浮動小数点型のスカラー値 */ int i; /* 整数型のスカラー値 */ CvString str; /* 文字列 */ CvSeq* seq; /* シーケンス(順序付きファイルノードのコレクション) */ struct CvMap* map; /* マップ(名前付きファイルノードのコレクション) */ } data; } CvFileNode;
この構造体は,ファイルストレージからデータを取り出す(例えば,ファイルからのデータ読み込み)ためだけに用いられます.ファイルへのデータ書き込みは,最小限のバッファを使い逐次的に実行されます.ファイルストレージには,データは保存されません.
逆にファイルからデータを読み出す場合,ファイル全体がパースされ,メモリ内に木構造として表現されます.また,木構造の各ノードは, CvFileNode によって表現されます.ファイルノード N の種類は, CV_NODE_TYPE(N->tag) として取得できます.いくつかのファイルノード(葉)は,文字列や,整数,浮動小数点数などのスカラーです.そして,それ以外のファイルノードには,ファイルノードのコレクション,スカラーのコレクション,あるいはコレクションのコレクション,などがあります.コレクションには,シーケンスとマップの2種類があります(ここでは YAML表記を用いるが,XTLでも同様である).シーケンス( CvSeq と混同しないように!)は,名前なしファイルノードの順序付きコレクションであり,マップは,名前付きファイルノードの順序なしコレクションです.したがって,シーケンスの要素にはインデックスでアクセスできますし( GetSeqElem )し,マップの要素には名前でアクセスできます( GetFileNodeByName ).次の表は,ファイルノードの種類について説明したものです:
Type | CV_NODE_TYPE(node->tag) | Value |
Integer | CV_NODE_INT | node->data.i |
Floating-point | CV_NODE_REAL | node->data.f |
Text string | CV_NODE_STR | node->data.str.ptr |
Sequence | CV_NODE_SEQ | node->data.seq |
Map | CV_NODE_MAP | node->data.map (see below) |
この map フィールドに直接アクセスする必要はありません(ちなみに CvMap は隠しフィールドです).このマップの要素は,この「マップ」ファイルノードへのポインタを引数にとる関数 GetFileNodeByName で取得できます.
ユーザ(独自の)オブジェクトは, CvMat や CvSeq などの CxCore の標準的な型のインスタンス,あるいは,関数 RegisterTypeInfo で登録された任意の型のインスタンスです.このようなオブジェクトは,オープンされたファイルストレージがパースされた後,初期状態では(前述のXMLやYAMLの例のように)ファイル内のマップとして表現されます.そして,ユーザが関数 Read や ReadByName を呼び出すと,その要求に従いオブジェクトがデコード(ネイティブな表現に変換)されます.
属性のリスト.
typedef struct CvAttrList { const char** attr; /* (attribute\_name,attribute\_value) ペアの配列.終端は NULL */ struct CvAttrList* next; /* 属性リストの次のチャンクへのポインタ */ } CvAttrList; /* 構造体 CvAttrList を初期化します */ inline CvAttrList cvAttrList( const char** attr=NULL, CvAttrList* next=NULL ); /* 存在すれば属性値を,なければ 0 (NULL) を返します */ const char* cvAttrValue( const CvAttrList* attr, const char* attr\_name );
現在の実装では,属性値は,ユーザオブジェクトを書き込む際の追加パラメータを渡すために利用されます( Write を参照してください).オブジェクト型指定( type_id 属性 )を除けば,タグ内部のXML属性はサポートされません.
型情報.
typedef int (CV_CDECL *CvIsInstanceFunc)( const void* structPtr ); typedef void (CV_CDECL *CvReleaseFunc)( void** structDblPtr ); typedef void* (CV_CDECL *CvReadFunc)( CvFileStorage* storage, CvFileNode* node ); typedef void (CV_CDECL *CvWriteFunc)( CvFileStorage* storage, const char* name, const void* structPtr, CvAttrList attributes ); typedef void* (CV_CDECL *CvCloneFunc)( const void* structPtr ); typedef struct CvTypeInfo { int flags; /* 使用されません */ int header_size; /* sizeof(CvTypeInfo) */ struct CvTypeInfo* prev; /* リスト内で一つ前に登録された型 */ struct CvTypeInfo* next; /* リスト内で一つ後に登録された型 */ const char* type_name; /* ファイルストレージに書き込まれる型の名前 */ /* メソッド */ CvIsInstanceFunc is_instance; /* 渡されたオブジェクトが,この型のインスタンスであるかをチェックします */ CvReleaseFunc release; /* オブジェクトを解放します(メモリなど) */ CvReadFunc read; /* ファイルストレージからオブジェクトを読み込みます */ CvWriteFunc write; /* ファイルストレージにオブジェクトを書き込みます */ CvCloneFunc clone; /* オブジェクトのコピーを作成します */ } CvTypeInfo;
構造体 CvTypeInfo は,標準型またはユーザ定義型に属する,ある1つの型の型情報を保持します.その型のインスタンスは,対応する構造体 CvTypeInfo へのポインタを持つこともあれば,持たないこともあります.どちらの場合でも,関数 TypeOf を用いて,与えられたオブジェクトの型情報構造体を取得できます.別の手段として, FindType を利用して,型の名前から型情報を得ることも可能で,これは,ファイルストレージからオブジェクトを読み込む際に利用されます.また,型情報構造体を型リストの先頭に追加する関数 RegisterType を用いて,新しい型を登録することができます.つまり,一般的な標準型から特別な型を作成し,基本メソッドをオーバーライドすることが可能です.
オブジェクトを複製します.
Parameter: | structPtr – 複製されるオブジェクト |
---|
この関数は,与えられたオブジェクトの型を求め, オブジェクトへのポインタを引数に clone を呼び出します.
構造体の書き込みを終了します.
Parameter: | fs – ファイルストレージ |
---|
この関数は,現在の構造体の書き込みを終了します.
名前から型を求めます.
Parameter: | typeName – 形の名前 |
---|
この関数は,登録された型の中から,指定された名前を持つものを見つけます.その名前をもつ型が存在しない場合,NULLが返されます.
型リストの先頭要素へのポインタを返します.
この関数は,登録型リストの先頭の型を返します.あとは,構造体 CvTypeInfo のフィールド prev と next を介して,このリスト全体を走査できます.
マップあるいはファイルストレージから,ノードを見つけます.
パラメタ: |
|
---|
この関数は,ファイルノードを見つけます.これは,関数 GetFileNodeByName の高速バージョンです( GetHashedKey の説明を参照してください).また,存在しないノードを指定すれば,マップに新しいノードを追加することもできます.
マップあるいはファイルストレージから,ノードを見つけます.
パラメタ: |
|
---|
この関数は,名前 name を元にファイルノードを見つけます.ノードの探索は, map 内で行われますが,そのポインタがNULLの場合はファイルストレージのトップレベルノード全体が探索されます.マップに対してはこの関数を,シーケンスに対しては GetSeqElem (あるいは,シーケンスリーダ)を用いることで,ファイルストレージ内を走査することができます.ある1つのキーに対する複数のクエリ(例えば,構造体の配列を探索する場合)をより高速に処理するためには, GetHashedKey と GetFileNode を組み合わせて使用することもできます.
ファイルノードの名前を返します.
Parameter: | node – ファイルノード |
---|
この関数は,ファイルノードの名前を返します.ファイルノードが名前を持たない場合や, node が NULL の場合は,NULLを返します.
与えられた名前に対する固有のポインタを返します.
パラメタ: |
|
---|
この関数は,各ファイルノードの名前に固有なポインタを返します.このポインタは,関数 GetFileNode に渡すことができます.関数 GetFileNode は,文字列の内容ではなくポインタを利用して文字列同士を比較するので,関数 GetFileNodeByName よりも高速に動作します.
次の例では,点座標の配列が,2エントリのマップのシーケンスとしてエンコードされています:
%YAML:1.0 points: - { x: 10, y: 10 } - { x: 20, y: 20 } - { x: 30, y: 30 } # ...
また,ハッシュ化された”x”と”y”のポインタを取得することで,点座標のデコードを高速化することが可能です.
#include "cxcore.h" int main( int argc, char** argv ) { CvFileStorage* fs = cvOpenFileStorage( "points.yml", 0, CV\_STORAGE\_READ ); CvStringHashNode* x\_key = cvGetHashedNode( fs, "x", -1, 1 ); CvStringHashNode* y\_key = cvGetHashedNode( fs, "y", -1, 1 ); CvFileNode* points = cvGetFileNodeByName( fs, 0, "points" ); if( CV\_NODE\_IS\_SEQ(points->tag) ) { CvSeq* seq = points->data.seq; int i, total = seq->total; CvSeqReader reader; cvStartReadSeq( seq, &reader, 0 ); for( i = 0; i < total; i++ ) { CvFileNode* pt = (CvFileNode*)reader.ptr; #if 1 /* 高速バージョン */ CvFileNode* xnode = cvGetFileNode( fs, pt, x\_key, 0 ); CvFileNode* ynode = cvGetFileNode( fs, pt, y\_key, 0 ); assert( xnode && CV\_NODE\_IS\_INT(xnode->tag) && ynode && CV\_NODE\_IS\_INT(ynode->tag)); int x = xnode->data.i; // or x = cvReadInt( xnode, 0 ); int y = ynode->data.i; // or y = cvReadInt( ynode, 0 ); #elif 1 /* 低速バージョン.x_key と y_keyを利用しません */ CvFileNode* xnode = cvGetFileNodeByName( fs, pt, "x" ); CvFileNode* ynode = cvGetFileNodeByName( fs, pt, "y" ); assert( xnode && CV\_NODE\_IS\_INT(xnode->tag) && ynode && CV\_NODE\_IS\_INT(ynode->tag)); int x = xnode->data.i; // or x = cvReadInt( xnode, 0 ); int y = ynode->data.i; // or y = cvReadInt( ynode, 0 ); #else /* 超低速ですが使いやすいバージョン */ int x = cvReadIntByName( fs, pt, "x", 0 /* デフォルト値 */ ); int y = cvReadIntByName( fs, pt, "y", 0 /* デフォルト値 */ ); #endif CV\_NEXT\_SEQ\_ELEM( seq->elem\_size, reader ); printf("%d: (%d, %d)\n", i, x, y ); } } cvReleaseFileStorage( &fs ); return 0; }
マップヘのアクセス方法に関わらず,単純なシーケンスを使うものに比べて,これはまだかなり遅いことに注意してください.例えば,上述の例で言えば,点座標を(マップのシーケンスではなく)複数の整数値のペアから成る1つのシーケンスとしてエンコードする方が,より効率的です.
ファイルストレージのトップレベルノードの1つを取得します.
パラメタ: |
|
---|
この関数は,ファイルストレージのトップレベルノードの1つを取得します.トップレベルノードは名前を持たず,これはファイルストレージに1つずつ順番に保存されているストリームに相当します.インデックスが範囲外だった場合,この関数は NULL ポインタを返します.つまり, stream_index=0,1,... を順に指定しながら,NULLポインタが返されるまで関数を繰り返し呼び出すことで,すべてのトップレベルノードを取得することができます.この関数は,ファイルストレージの再帰的な走査のために利用されます.
ファイルからオブジェクトを読み出します.
パラメタ: |
---|
この関数は,ファイルからオブジェクトを読み出します.これは, Read の簡単なインタフェースです.オブジェクトが読み出された後,ファイルストレージはクローズされ,テンポラリバッファは全て削除されます.よって,シーケンスや輪郭,グラフなどの動的構造体を読み出すためには,有効な出力先となるメモリストレージを関数に渡す必要があります.
データを読み書きするために,ファイルストレージをオープンします.
パラメタ: |
---|
この関数は,データを読み書きするためにファイルストレージをオープンします.書き込みの場合,新しいファイルが作成されるか,既に存在するファイルに再び書き込まれます.ファイルの読み書きの種類は,ファイル名の拡張子によって決まります: .xml は XML , .yml や .yaml は YAML となります.また,この関数は, CvFileStorage へのポインタを返します.
オブジェクトをデコードし,そのポインタを返します.
パラメタ: |
|
---|
この関数は,ユーザオブジェクト(オブジェクトは,ファイルストレージの部分木の固有表現から作成される)をデコードし,それを返します.デコードされるオブジェクトは,``read`` メソッド( CvTypeInfo を参照してください)をサポートする,登録済みの型のインスタンスでなければいけません.オブジェクトの型は,ファイルからエンコードされて得られる型名によって決まります.オブジェクトが動的構造体である場合,そのオブジェクトはメモリストレージ内に作成され,関数 OpenFileStorage に渡されます.NULLポインタが渡された場合は,一時的なメモリストレージ内に作成され,これは,関数 ReleaseFileStorage が呼ばれたときに解放されます.また,オブジェクトが動的構造体ではない場合は,オブジェクトはヒープ内に作成されます.これは,それ専用の関数か,あるいは一般的な関数 Release を用いて解放されます.
指定された名前のオブジェクトを見つけ,それをデコードします.
パラメタ: |
|
---|
この関数は, GetFileNodeByName と Read の単純な合成です.
ファイルノードから整数型の値を読み込みます.
パラメタ: |
|
---|
この関数は,ファイルノードによって表される整数値を返します.ファイルノードがNULLの場合, defaultValue が返されます(つまり,関数 GetFileNode の直後にこの関数を呼ぶ場合,NULLポインタのチェックを行わずに良いので便利です).ファイルノードの型が CV_NODE_INT である場合は, node->data.i が返されます.また,ファイルノードの型が CV_NODE_REAL である場合は, node->data.f が整数に変換されて返されます.その他の場合は,戻り値は不定です.
指定された名前のファイルノードを見つけ,そこから整数値を読み込みます.
パラメタ: |
|
---|
この関数は, GetFileNodeByName と ReadInt の単純な合成です.
複数の数値を読み込みます.
パラメタ: |
|
---|
この関数は,スカラー値のシーケンスを表すファイルノードから値を読み込みます.
シーケンスリーダからデータを読み込みます.
パラメタ: |
|
---|
この関数は,シーケンスを表すファイルノードから1つあるいは複数の要素を読み込み,ユーザが指定した配列に書き出します.読み込まれるシーケンス要素の総数は, count と各配列要素に含まれる値の個数の積となります.例えば,dt= 2if の場合だと,この関数は, 個のシーケンス要素を読み出します.また, SetSeqReaderPos によってリーダが移動されると,シーケンスの種類に関わらず,ファイルノードの一部が読み飛ばされたり,繰り返し読まれたりする場合があります.
ファイルノードから浮動小数点型の値を読み込みます.
パラメタ: |
|
---|
この関数は,ファイルノードによって表される浮動小数点数を返します.ファイルノードがNULLの場合, defaultValue が返されます(つまり,関数 GetFileNode の直後にこの関数を呼ぶ場合,NULLポインタのチェックを行わずに良いので便利です).ファイルノードの型が CV_NODE_REAL である場合は, node->data.f が返されます.また,ファイルノードの型が CV_NODE_INT である場合は, node->data.i が浮動小数点数に変換されて返されます.その他の場合は,戻り値は不定です.
指定された名前のファイルノードを見つけ,そこから浮動小数点値を読み込みます.
パラメタ: |
|
---|
この関数は, GetFileNodeByName と ReadReal の単純な合成です.
ファイルノードから文字列を読み込みます.
パラメタ: |
|
---|
この関数は,ファイルノードによって表される文字列を返します.ファイルノードがNULLの場合, defaultValue が返されます(つまり,関数 GetFileNode の直後にこの関数を呼ぶ場合,NULLポインタのチェックを行わずに良いので便利です).ファイルノードの型が CV_NODE_STR である場合は, node->data.str.ptr が返されます.その他の場合の戻り値は,不定です.
指定された名前のファイルノードを見つけ,そこから文字列を読み込みます.
パラメタ: |
|
---|
この関数は, GetFileNodeByName と ReadString の単純な合成です.
新しい型を登録します.
Parameter: | info – 型情報構造体 |
---|
この関数は,構造体 info によって記述される新しい型を登録します.この関数は,その構造体のコピーを作成するので,ユーザは関数呼び出し後に元の構造体を削除するべきです.
オブジェクトを解放します.
Parameter: | structPtr – オブジェクトへのダブルポインタ |
---|
この関数は,与えられたオブジェクトの型を見つけ,ダブルポインタを引数に release を呼び出します.
フィルストレージを解放します.
Parameter: | fs – 解放されるファイルストレージへのダブルポインタ |
---|
この関数は,そのストレージに関連付けられているファイルをクローズし,すべての一時的な構造体を解放します.この関数を呼び出す場合は,必ずそのストレージに関する全ての入出力処理が終了していなければいけません.
オブジェクトをファイルに保存します.
パラメタ: |
|
---|
この関数は,オブジェクトをファイルに保存します.これは,関数 Write の簡単なインタフェースです.
次のストリームを開始します.
Parameter: | fs – ファイルストレージ |
---|
この関数は,ファイルストレージの次のストリームを開始します.YAMLとXMLは両方とも,複数の「ストリーム」をサポートしています.これは,ファイルの連結や書き込み処理の再開の際に役立ちます.
ファイルノードシーケンスリーダを初期化します.
パラメタ: |
|
---|
関数 cvStartReadRawData() は,ファイルノードからデータを読み込むためにシーケンスリーダを初期化します.そして,初期化されたリーダは,関数 ReadRawDataSlice に渡すことができます.
新しい構造体の書き込みを開始します.
パラメタ: |
|
---|
この関数は,マップやシーケンスの複合構造体(コレクション)の書き込みを開始します.構造体の,スカラーや構造体からなる全フィールドが書き込まれた後で, EndWriteStruct が実行されるべきです.この関数は,オブジェクトをグループ化する場合や,ユーザオブジェクトに対して write を実装する場合などに用いられます( CvTypeInfo を参照してください).
ユーザオブジェクトを書き込みます.
パラメタ: |
|
---|
この関数は,ファイルストレージにオブジェクトを書き込みます.まず, TypeOf を用いて適切な型情報を求め,それから,その型に関連する write メソッドが呼び出されます.
属性は,書き込み手続きをカスタマイズするために利用されます.標準の型では,以下の属性をサポートしています(すべての *dt 属性は, WriteRawData の引数 dt と同じフォーマットです):
以下は, CvFileStorage の説明にある YAML ファイルを作成するコードです:
#include "cxcore.h" int main( int argc, char** argv ) { CvMat* mat = cvCreateMat( 3, 3, CV_32F ); %修正 CvFileStorage* fs = cvOpenFileStorage( "example.yml", 0, CV_STORAGE_WRITE );%修正 cvSetIdentity( mat ); cvWrite( fs, "A", mat, cvAttrList(0,0) ); cvReleaseFileStorage( &fs ); cvReleaseMat( &mat ); return 0; }
コメントを書き込みます.
パラメタ: |
|
---|
この関数は,ファイルストレージにコメントを書き込みます.ストレージを読み込む際にはコメントは読み飛ばされるので,これはデバッグや説明を記述する目的でのみ利用します.
ファイルノードを,他のファイルストレージに書き込みます.
パラメタ: |
|
---|
この関数は,ファイルノードのコピーをファイルストレージに書き込みます.これは,複数のファイルストレージを1つにマージしたり,XMLとYAML形式を変換したりする場合に利用できます.
整数型の値を書き込みます.
パラメタ: |
|
---|
この関数は,1つの整数値(名前あり,または名前なし)をファイルストレージに書き込みます.
複数の数値を書き込みます.
パラメタ: |
|
---|
この関数は,1つあるいは複数の数値で構成される要素をもつ配列を書き込みます.この関数は, WriteInt と WriteReal を繰り返し呼び出すことで代用可能ですが,1度だけこの関数を呼び出す方が効率的です.また,これらの要素は名前を持たないため,マップではなくシーケンスに書き込まれるべきものであることに注意してください.
浮動小数点型の値を書き込みます.
パラメタ: |
|
---|
この関数は,単精度浮動小数点型の値(名前あり,または名前なし)をファイルに書き込みます.また,特殊な値は次のようにエンコードされます:NaN (Not A Number) は .NaN, は +.Inf(-.Inf) .
以下の例では,新たな型を登録することなく,停止基準構造体などの独自の構造体に値を格納するための,低レベル書き込み関数の使い方を示します.
void write_termcriteria( CvFileStorage* fs, const char* struct_name, CvTermCriteria* termcrit ) { cvStartWriteStruct( fs, struct_name, CV_NODE_MAP, NULL, cvAttrList(0,0)); cvWriteComment( fs, "termination criteria", 1 ); // 単なる説明コメント if( termcrit->type & CV_TERMCRIT_ITER ) cvWriteInteger( fs, "max_iterations", termcrit->max_iter ); if( termcrit->type & CV_TERMCRIT_EPS ) cvWriteReal( fs, "accuracy", termcrit->epsilon ); cvEndWriteStruct( fs ); }
文字列を書き込みます.
パラメタ: |
|
---|
この関数は,ファイルストレージに文字列を書き込みます.