Matplotlib によるプロット機能

ここでは MatplotlibPyplot を利用したプロット機能について紹介します。 この機能は Matplotlib を使用することが可能な環境でのみ有効となります。


ここで示される例は Jupyter notebook により実行されたものとなります。 プロット結果の確認のために、 Matplotlib のインラインバックエンドは下記のように設定されているものとします。

[1]:
%matplotlib inline

画像オブジェクトのプロット

画像オブジェクトのプロットは、画像オブジェクトのインスタンスメソッド imshow() により行います。

[2]:
# PyFIE のインポート
import pyfie

# ファイル画像の読み込み
src = pyfie.imread("file_name.png")


# 画像オブジェクトのプロット
src.imshow()
[2]:
<matplotlib.axes._subplots.AxesSubplot at 0x24e3a328430>
../_images/tutorial_sample_matplotlib_4_1.png

プロットの表示倍率を指定する場合は、 imshow() のパラメータ scale を使用します。 下記はデフォルトの 1.5 倍の表示倍率にてプロットを行う例です。

[3]:
# 表示倍率を指定してのプロット
src.imshow(scale=1.5)
[3]:
<matplotlib.axes._subplots.AxesSubplot at 0x24e3b1a4340>
../_images/tutorial_sample_matplotlib_6_1.png

また imshow() のパラメータには、 matplotlib.pyplot.imshow() に指定可能なパラメータを そのまま渡すことができます。 下記は matplotlib.pyplot.imshow() のパラメータ cmap にて カラーマップの指定を行う例です。

[4]:
src.imshow(cmap="hot")
[4]:
<matplotlib.axes._subplots.AxesSubplot at 0x24e3a2c7dc0>
../_images/tutorial_sample_matplotlib_8_1.png

画像内の指定領域のみをプロットする場合は、 imshow() の代わりに imshow_roi() を使用してプロットを行います。

[5]:
src.imshow_roi(170, 265, 70, 60)
[5]:
<matplotlib.axes._subplots.AxesSubplot at 0x24e3a25b8e0>
../_images/tutorial_sample_matplotlib_10_1.png

この他の画像オブジェクトのプロットに関する詳細は、 「詳細 >> 拡張機能 >> Matplotlib によるプロット機能」 を参照してください。


構造体のプロット

一部の PyFIE 構造体 は, インスタンスメソッド plot() をもっており その形状をプロットすることができます。 例えば構造体 BOX_T は 「矩形」 を表現する構造体であり、 下記例のようにプロットをおこなうことができます。

[6]:
# 構造体 BOX_T に矩形領域を設定
roi = pyfie.BOX_T()
roi.st.x = src.width / 4
roi.st.y = src.height / 4
roi.ed.x = roi.st.x + src.width / 2
roi.ed.y = roi.st.y + src.height / 2


# 画像上に BOX_T による矩形領域をプロット
src.imshow()
roi.plot()
[6]:
<matplotlib.axes._subplots.AxesSubplot at 0x24e3a27a820>
../_images/tutorial_sample_matplotlib_13_1.png

また plot() をもつ PyFIE 構造体は、 そのポインタや配列からもプロットを行うことができます。 これにより複数要素のプロットを一度に行うことができます。

以降は画像から検出したエッジ点群をプロットする例です。 まず準備としてエッジ点群の検出を下記のように行います。

[7]:
# エッジ点群検出パラメータの設定
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()


# エッジ点群検出の実行
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
)
[7]:
F_ERR_NONE

検出されたエッジ点群は、 構造体 F_DEDGE のポインタ(edges)として得られました。 この構造体ポインタのインスタンスメソッド plot() を使用して プロットを行います。 構造体ポインタのプロットではプロットする要素個数を指定する必要があり、 下記の例では検出されたエッジ点個数(edge_num)を指定しています。

注釈

下記の例では Jupyter notebook の 1 つのセルで、 「画像全体に対するプロット」 と 「指定領域に対するプロット」 という 2 つのプロットを行っています。 このような場合、インラインバックエンド環境では Pyplotmatplotlib.pyplot.show() を呼び出す必要があります。 下記の例ではこれを PyFIE の pyfie.plot_show() 経由で行っています。

[8]:
# 画像の上に検出されたエッジ点群をプロット
src.imshow(scale=2.0)
edges.plot(edge_num, linewidth=0.3)

pyfie.plot_show()

# 指定領域のみのプロット
src.imshow_roi(170, 265, 70, 60)
edges.plot(edge_num)
../_images/tutorial_sample_matplotlib_17_0.png
[8]:
<matplotlib.axes._subplots.AxesSubplot at 0x24e3b4df9d0>
../_images/tutorial_sample_matplotlib_17_2.png

つぎに、 構造体の配列を使用したプロットの例を示します。

下記は、先ほど検出したエッジ点群(edges)を連結処理し、 その連結結果をプロットする例となっています。 連結結果は複数のクラスタ(edge_clust)として得られるので、 各クラスタに対して構造体 F_DEDGE の配列(_edges)を用意しプロットをおこなっています。 先ほどの構造体ポインタの場合とは異なり、 構造体配列のプロットの際には要素個数の指定が不要となります。

[9]:
# エッジ連結結果(エッジクラスタ)を受け取るための構造体ポインタを用意
edge_clust = pyfie.F_EDGE_CLUST.PTR()
clust_num = pyfie.INT()


# エッジ連結の実行
pyfie.fnFIE_edge_connecting2(
    edges, edge_num, pyfie.PI/2, 5, 20, -1,
    edge_clust, clust_num
)

# エッジ連結結果のプロット
for i in range(clust_num):
    _clust = edge_clust[i]

    # クラスタに含まれるエッジ点をまとめる構造体配列を用意
    _edges = pyfie.F_DEDGE.ARRAY(_clust.num)

    # 構造体配列にクラスタのインデックスに従いエッジ点群を設定
    for j in range(_clust.num):
        _edges[j] = edges[_clust.pindex[j]]

    # まとめたエッジ点をプロット
    _edges.plot()


# 入力画像をプロット
src.imshow_roi(120, 110, 220, 220, scale=1.5)

[9]:
<matplotlib.axes._subplots.AxesSubplot at 0x24e3b351df0>
../_images/tutorial_sample_matplotlib_19_1.png

最後に、PyFIE 関数により確保されたリソースの解放を行います。

[10]:
# fnFIE_edge_corr_subpix() により確保されたエッジ点群を解放
edges.fnOAL_free()


# fnFIE_edge_connecting2() により確保されたエッジクラスタを解放
pyfie.fnFIE_free_edge_clust(edge_clust, clust_num)
[10]:
F_ERR_NONE

この他の PyFIE 構造体のプロットに関する詳細は、 「詳細 >> 拡張機能 >> Matplotlib によるプロット機能」 を参照してください。