ヒープメモリ管理¶
ここでは PyFIE におけるヒープメモリの管理について説明します。
FIE(C 言語) では
fnOAL_malloc()
や fnOAL_free()
などのメモリ確保/解放関数が用意されており、
これらを使用してヒープメモリの管理を行います。
PyFIE においてもこれらのヒープメモリ管理関数を使用することは可能ですが、
単純にヒープメモリを扱いたい場合(メモリブロックにアライメント等の条件が必要のない場合)には、
PyFIE のユーティリティ関数 malloc()
を代わりに使用することができます。
malloc()
では指定サイズのヒープメモリ領域確保が行われ、
その PyFIE ポインタ型インスタンスを返します。
このメモリ領域は fnOAL_malloc()
で確保されたようなメモリ領域を使用する場所で、
同じように使用することができます。
注釈
ただし malloc()
で確保されたメモリ領域に対して、
fnOAL_free()
による解放や
fnOAL_realloc()
によるサイズ変更を行うことは出来ません。
また、 malloc()
で確保されたヒープメモリ領域は、
Python によるガベージコレクションの対象となるためメモリ解放を行う必要がありません。
これによりヒープメモリの管理が容易となります。
下記は
fnFIE_make_histogram()
関数に渡すためのメモリ領域を
malloc()
により確保する例です。
- C 言語
UINT * hist; INT bins = 256; // ヒストグラム用のメモリを確保 hist = (UINT *)fnOAL_malloc(sizeof(UINT) * bins); // ヒストグラムの作成 fnFIE_make_histogram(img, 0, &hist, &bins); // ここでヒストグラムを使用する // (省略 ...) // ヒストグラムの使用が終わったらメモリを解放 fnOAL_free(hist);
- Python
bins = pyfie.INT(256) # ヒストグラム用のメモリを確保 hist = pyfie.malloc(pyfie.UINT, bins) # ヒストグラムの作成 pyfie.fnFIE_make_histogram(img, 0, hist, bins) # ここでヒストグラムを使用する (Matplotlib を使用してヒストグラムのプロットを行う例) from matplotlib import pyplot pyplot.plot(hist.ndarray(bins)) # ヒストグラム用に確保したメモリ(hist)はガベージコレクションの対象となるので解放不要
変数 img は確保済の F_IMG_UC8 型画像オブジェクト(FHANDLE) であるものとします
注釈
上記の例では、 作成したヒストグラムを使用するために
PyFIE ポインタのインスタンスメソッド ndarray()
を使用し、
ポインタ (hist) から numpy.ndarray
(NumPy) へのアタッチを行っています。
これは NumPy が使用可能な環境でのみ利用できる拡張機能となります。 詳細は PyFIE 算術型ポインタから ndarray へのアタッチ を参照ください。
このように malloc()
を使用して確保されたメモリ領域は解放する必要がありません。
これに対し、 PyFIE 関数内部で確保され 返されるメモリ領域(FHANDLE
を除く)は Python のガベージコレクション対象となりませんので、
ユーザーが解放処理を行う必要があります。
このようなメモリ領域に対して FIE ライブラリでは大抵の場合 fnOAL_free()
にて解放処理を行うことが要求されますので、
PyFIE においても同様にこれに従うこととなります。
下記例では fnFIE_edge_corr_subpix()
関数内部で確保されるメモリ領域 edges の解放処理が必要となります。
- C 言語
F_EDGE_CORR_PARAMS params; DPNT_T offset; F_DEDGE * edges = NULL; INT edge_num = 0; params.width = 11; params.height = 5; params.var_threshold = 30; params.sigmoid_k = 1.0; params.mag_threshold = 160; params.nms_length = 6; offset.x = 0; offset.y = 0; // エッジ検出を行い結果をポインタ edges に受け取る. fnFIE_edge_corr_subpix( src, NULL, ¶ms, F_EDGE_FEAT_DIRECT | F_EDGE_FEAT_MAG_SQRT, F_BORDER_NONE, offset, &edges, &edge_num ); // 検出されたエッジを使用する. // (省略 ...) // fnFIE_edge_corr_subpix() 内部で確保されたメモリ領域の解放. fnOAL_free(edges);
- Python
params = pyfie.F_EDGE_CORR_PARAMS( width = 11, height = 5, var_threshold = 30, sigmoid_k = 1.0, mag_threshold = 160, nms_length = 6 ) edges = pyfie.F_DEDGE.PTR() edge_num = pyfie.INT() # エッジ検出を行い結果をポインタ edges に受け取る. pyfie.fnFIE_edge_corr_subpix( src, None, params, pyfie.F_EDGE_FEAT_DIRECT | pyfie.F_EDGE_FEAT_MAG_SQRT, pyfie.F_BORDER_NONE, (0, 0), edges, edge_num ) # 検出されたエッジを使用する. (入力画像上にエッジをプロットする例) src.imshow() edges.plot(edge_num) # fnFIE_edge_corr_subpix() 内部で確保されたメモリ領域の解放. edges.fnOAL_free()
変数 src は確保済の画像オブジェクト(FHANDLE) であるものとします
注釈
上記の例では、 メモリ領域の解放をポインタオブジェクト(edges)のインスタンスメソッド fnOAL_free()
を使用して行っています。
詳細は ポインタオブジェクト拡張機能 を参照ください。
また検出されたエッジの使用例では、 Matplotlib による拡張機能を利用しています。 詳細は Matplotlib によるプロット機能 を参照ください。
以上をまとめると、 PyFIE で記述を簡素化するための ヒープメモリ管理に関するガイドラインは次のようになります。
ヒープメモリの確保が必要な場合は
malloc()
を使用するfnOAL_free()
等による解放処理は、 PyFIE 関数内部で確保されたメモリ領域に対してのみ行う