はじめに
この実験では、Matplotlib の RangeSlider ウィジェットを使って画像のしきい値処理を制御する方法を示します。しきい値処理の目的は、グレースケール画像を 2 値画像に変換することで、画素が黒または白のどちらかになるようにすることです。これは、画像から特定の特徴を抽出したい画像分割に役立ちます。
VM のヒント
VM の起動が完了したら、左上隅をクリックしてノートブックタブに切り替え、Jupyter Notebook を使って練習しましょう。
時々、Jupyter Notebook が読み込み終了するまで数秒待つ必要がある場合があります。Jupyter Notebook の制限により、操作の検証を自動化することはできません。
学習中に問題に遭遇した場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。
疑似画像を生成する
まず、NumPy の乱数モジュールを使って疑似グレースケール画像を生成します。結果を再現可能にするために、乱数の種を設定します。
np.random.seed(19680801)
N = 128
img = np.random.randn(N, N)
画像とそのヒストグラムを表示する
次に、Matplotlib のimshow関数を使って画像を表示し、histを使ってそのヒストグラムを表示します。画像用のサブプロットとヒストグラム用のサブプロットを含む図を作成します。
fig, axs = plt.subplots(1, 2, figsize=(10, 5))
fig.subplots_adjust(bottom=0.25)
im = axs[0].imshow(img)
axs[1].hist(img.flatten(), bins='auto')
axs[1].set_title('Histogram of pixel intensities')
RangeSlider を作成する
ここでは、画像のしきい値を調整できる RangeSlider ウィジェットを作成します。スライダー用の新しい軸を作成し、それを図に追加します。
slider_ax = fig.add_axes([0.20, 0.1, 0.60, 0.03])
slider = RangeSlider(slider_ax, "Threshold", img.min(), img.max())
ヒストグラムに垂直線を追加する
しきい値処理の効果をより明確に見るために、ヒストグラムに垂直線を追加して、現在のしきい値を示します。下限と上限のしきい値にそれぞれ 2 本の線を作成します。
lower_limit_line = axs[1].axvline(slider.val[0], color='k')
upper_limit_line = axs[1].axvline(slider.val[1], color='k')
スライダー用のコールバック関数を作成する
ユーザーがスライダーを使ってしきい値を変更するたびに呼び出されるコールバック関数を作成します。この関数は、画像のカラーマップとヒストグラム上の垂直線の位置を更新します。
def update(val):
## RangeSlider によってコールバックに渡される val は
## (min, max) のタプルになります
## 画像のカラーマップを更新する
im.norm.vmin = val[0]
im.norm.vmax = val[1]
## 垂直線の位置を更新する
lower_limit_line.set_xdata([val[0], val[0]])
upper_limit_line.set_xdata([val[1], val[1]])
## 図を再描画して更新を確実にする
fig.canvas.draw_idle()
slider.on_changed(update)
図を表示する
最後に、画像とスライダーが表示された図を表示します。
plt.show()
まとめ
この実験では、Matplotlib の RangeSlider ウィジェットを使って画像のしきい値処理を制御する方法を示しました。疑似グレースケール画像を作成し、それとそのヒストグラムを表示し、しきい値を調整するためのスライダーを作成し、スライダーの値に基づいて画像とヒストグラムを更新する方法を示しました。この技術は、画像分割や画像から特定の特徴を抽出する必要がある他のアプリケーションにも使用できます。