[matplotlib] 112. クリックイベントでラベル画像のregionprops情報を表示

jupyter notebook, lab

はじめに

この記事では、matplotlibのbutton_press_eventを使用して、scikit-imageのlabel関数で生成したラベル画像をクリックした際に、そのラベル領域のregionprops情報を画像の横に表示する方法について解説します。

コード&解説

モジュールのインポート

バージョン

画像データの作成

1024 x 1024の2Dデータ上のランダムな位置に点を配置し、それにガウシアンフィルターを適用した画像を使用します。大津の手法(threshold_otsu)で最適な閾値を求めて2値化を行い、画像の端に接している領域はclear_border関数で除去します。

画像を表示

生成した画像は以下のようになります。

ラベリング

scikit-imageのlabel関数でラベル付けを行います。ラベル画像の背景は0となり、表示すると見にくくなるため、まずfloat型に変換し、その後背景の0をnp.nanに置き換えます。この処理によって、ラベル画像は下図のように表示されます。

regionprops_tableでラベルの各種情報をDataFrameで取得

regionprops_tableを使用してラベルの情報を取得できます。取得した情報はそのままpandasのDataFrameに変換でき、以下のようなテーブルが表示されます。

label centroid-0 centroid-1 area equivalent_diameter bbox-0 bbox-1 bbox-2 bbox-3
0 1 30.208041 725.370772 1567 44.667285 6 704 54 748
1 2 57.241617 441.379383 5219 81.517097 23 378 91 494
2 3 101.108303 928.963899 1385 41.993294 81 908 123 951
3 4 184.762435 851.028360 9168 108.041937 88 797 292 890
4 5 147.500000 597.000000 3436 66.142657 106 556 190 639
5 6 172.625239 284.097691 12560 126.459040 112 216 238 362
6 7 364.404686 418.897797 53345 260.616507 195 192 536 585
7 8 222.029594 791.613214 1453 43.011825 201 770 244 814
8 9 263.214478 218.805863 3343 65.241396 228 189 299 249
9 10 255.175529 714.618834 1561 44.581688 232 693 280 736
10 11 299.492297 74.433473 1428 42.640193 279 54 321 96
11 12 331.690119 721.232520 9139 107.870924 288 619 387 817
12 13 407.649929 895.445545 1414 42.430658 387 875 429 917
13 14 415.006887 47.923554 1452 42.997021 394 27 438 70
14 15 488.127493 716.581827 12887 128.094645 404 615 564 795
15 16 598.818444 456.352726 24648 177.151936 526 255 684 636
16 17 588.215704 203.824593 3375 65.552906 552 174 626 235
17 18 607.021014 112.094928 1380 41.917426 587 91 629 134
18 19 708.909523 773.184410 16203 143.632518 645 680 789 852
19 20 682.094135 54.043447 1381 41.932610 661 34 704 76
20 21 720.035688 146.964312 1373 41.810978 700 126 742 168
21 22 771.388794 436.854518 11101 118.887477 706 381 841 511
22 23 765.758831 286.270097 3284 64.663117 736 252 797 322
23 24 778.234241 600.765759 1396 42.159725 758 580 800 622
24 25 792.167994 963.973208 1381 41.932610 772 944 814 985
25 26 824.944483 772.348184 1459 43.100539 803 751 847 794
26 27 830.837456 229.233922 1415 42.445659 810 208 853 251
27 28 835.731739 547.392372 1547 44.381320 813 526 861 569
28 29 925.492110 925.536506 12231 124.791798 853 843 991 1007
29 30 890.685933 636.711003 1436 42.759467 870 616 913 659
30 31 896.087719 554.881092 1539 44.266417 872 534 920 577

GridSpecによるFigの作成

GridSpecを使用してFigureを作成します。GridSpecの詳細については下記記事で解説しています。なお、ax2、ax3、ax4の軸は非表示にしています。

[matplotlib] 10. Matplotlibで複数のグラフを表示する方法(subplot、add_subplot、subplots、GridSpec)
Matplotlibで複数グラフを効率的に配置・表示する方法を解説。subplot、add_subplot、subplots、GridSpecなどの手法を使って、1つのウィンドウ内に様々な配置でグラフを組み合わせる技術を紹介します。

ラベル像とテキストを表示する準備

情報表示領域には、Label、Centroid、Areaの項目を薄い文字で表示します。ax1にラベル画像を表示し、ax2、ax3、ax4には初期状態で空のテキストを配置しておきます。

クリックした時の処理

最初に、label_image_fのnp.nanの部分をクリックした時の処理として、情報表示テキストを空にするよう設定します。

クリックしたラベルの値はlabel_image_f[int(np.rint(event.ydata)),int(np.rint(event.xdata))]で取得できます。このラベル値を使って、regionprops_tableのDataFrameから重心(centroid)と面積(area)の情報を取得します。取得した値はset_textメソッドを使って図上に表示します。

イベントの有効化

マウスクリックイベントは fig.canvas.mpl_connect(‘button_press_event’, onclick) で有効化できます。なお、コメントアウトされている処理を実行するとイベントが無効になります。

実際の操作結果は以下のようになります。

コードをダウンロード(.pyファイル)

コードをダウンロード(.ipynbファイル)

まとめ

本記事では、matplotlibのイベント処理機能とscikit-imageのラベリング・領域解析機能を組み合わせることで、対話的に画像内の領域情報を表示するアプリケーションを実装する方法を紹介しました。この技術は画像解析ツールの開発や、セグメンテーション結果の視覚的検証に役立ちます。

参考

skimage.measure — skimage 0.26.0rc0.dev0 documentation
https://matplotlib.org/stable/users/event_handling.html

コメント