はじめに
jupyter notebookの対話的にパラメータを選択できる機能(ipywidgets IntSlider)で、scikit-image measureのprofile_lineを使って、画像の任意の位置の強度プロファイルを取得して表示する方法について説明する。
なお、profile_lineについては下記記事で解説した。

[scikit-image] 71. 画像の強度プロファイルを任意の範囲で表示(skimage.measure profile_line)
skimage.measureのprofile_lineで、任意の範囲の画像の強度プロファイルを表示する方法について説明する。
コード
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%matplotlib notebook | |
import numpy as np | |
import matplotlib.pyplot as plt | |
from ipywidgets import interact,interactive,IntSlider,HBox,VBox | |
from mpl_toolkits.axes_grid1 import make_axes_locatable | |
from scipy import ndimage | |
from skimage.measure import profile_line | |
from IPython.display import display | |
plt.rcParams['font.size']=12 | |
plt.rcParams['font.family'] = 'sans-serif' | |
#make data | |
n = 3 | |
s = 128 | |
im = np.zeros((s, s)) | |
points = (s*np.random.random((2, n**2))).astype(int) | |
im[points[0], points[1]] = 10000 | |
im = ndimage.gaussian_filter(im, sigma=s/(5.*n)) | |
fig, ax = plt.subplots(ncols=2,figsize=(8,4)) | |
img = ax[0].imshow(im, cmap=plt.cm.gist_earth, interpolation='gaussian',origin='upper',alpha=1) | |
ax[0].set_xlabel("x") | |
ax[0].set_ylabel("y") | |
divider = make_axes_locatable(ax[0]) | |
cax = divider.append_axes("top", size="5%", pad=0.02) | |
plt.colorbar(img, cax=cax,orientation='horizontal') | |
cax.xaxis.set_ticks_position('top') | |
start_, = ax[0].plot([],[],'ro',lw=3) | |
end_, = ax[0].plot([],[],'ro',lw=3) | |
line, = ax[0].plot([],[],'r-',lw=3) | |
pro, = ax[1].plot([],[],'.-') | |
ax[1].set_xlabel("position") | |
ax[1].set_ylabel("Intensity") | |
plt.tight_layout() | |
x_s = IntSlider(min=0, max=127,step=1,value=0, description="x_start: ", | |
orientation='horizontal') | |
y_s = IntSlider(min=0, max=127,step=1,value=0, description="y_start: ", | |
orientation='horizontal') | |
x_e = IntSlider(min=0, max=127,step=1,value=127, description="x_end: ", | |
orientation='horizontal') | |
y_e = IntSlider(min=0, max=127,step=1,value=127, description="y_end: ", | |
orientation='horizontal') | |
def f(x_s,y_s,x_e,y_e): | |
start_.set_data([x_e,y_e]) | |
end_.set_data([x_s,y_s]) | |
line.set_data([[x_e,x_s],[y_e,y_s]]) | |
profile = profile_line(im,[y_s,x_s],[y_e,x_e],linewidth=1) | |
pro.set_data([[np.arange(len(profile))],profile]) | |
ax[1].set_xlim(0,len(profile)) | |
ax[1].set_ylim(0,profile.max()+1) | |
ax[1].set_title('data points = '+str(profile.shape[0])+'') | |
out =interactive(f,x_s=x_s,y_s=y_s,x_e=x_e,y_e=y_e) | |
hbox1 = HBox([x_s, x_e]) | |
hbox2 = HBox([y_s, y_e]) | |
ui = VBox([hbox1, hbox2]) | |
display(ui) | |

解説
モジュールのインポートなど
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact,interactive,IntSlider,HBox,VBox
from mpl_toolkits.axes_grid1 import make_axes_locatable
from scipy import ndimage
from skimage.measure import profile_line
from IPython.display import display
plt.rcParams['font.size']=12
plt.rcParams['font.family'] = 'sans-serif'
画像データの作成
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
n = 3
s = 128
im = np.zeros((s, s))
points = (s*np.random.random((2, n**2))).astype(int)
im[points[0], points[1]] = 10000
im = ndimage.gaussian_filter(im, sigma=s/(5.*n))
用いる画像については、下記記事と同様に作成した。

[matplotlib] 57. plt.imshow()で軸を画像から離して表示
matplotlibのplt.imshowで画像を表示する際に、軸を画像から離して表示する方法について説明する。
画像の表示
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fig, ax = plt.subplots(ncols=2,figsize=(8,4))
img = ax[0].imshow(im, cmap=plt.cm.gist_earth, interpolation='gaussian',origin='upper',alpha=1)
ax[0].set_xlabel("x")
ax[0].set_ylabel("y")
divider = make_axes_locatable(ax[0])
cax = divider.append_axes("top", size="5%", pad=0.02)
plt.colorbar(img, cax=cax,orientation='horizontal')
cax.xaxis.set_ticks_position('top')
make_axes_locatableでカラーバーを画像の上に表示した。cax.xaxis.set_ticks_position(‘top’)でカラーバーの目盛りが上側に来るようにした。
ipywidgetsの設定
plotの作成
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
start_, = ax[0].plot([],[],'ro',lw=3)
end_, = ax[0].plot([],[],'ro',lw=3)
line, = ax[0].plot([],[],'r-',lw=3)
pro, = ax[1].plot([],[],'.-')
widgetsで取得した値を用いてプロットを表示するためにデータが空のプロットを作成しておく。
proはskimageのprofile_lineで取得したデータを表示するためにプロットであり、画像の横のax[1]に表示する。
IntSliderの作成
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
x_s = IntSlider(min=0, max=127,step=1,value=0, description="x_start: ",
orientation='horizontal')
y_s = IntSlider(min=0, max=127,step=1,value=0, description="y_start: ",
orientation='horizontal')
x_e = IntSlider(min=0, max=127,step=1,value=127, description="x_end: ",
orientation='horizontal')
y_e = IntSlider(min=0, max=127,step=1,value=127, description="y_end: ",
orientation='horizontal')
プロファイルの開始点の座標と終了点の座標を取得するためにIntSliderを作成する。
Sliderの値を変えたときに行う処理
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def f(x_s,y_s,x_e,y_e):
start_.set_data([x_e,y_e])
end_.set_data([x_s,y_s])
line.set_data([[x_e,x_s],[y_e,y_s]])
profile = profile_line(im,[y_s,x_s],[y_e,x_e],linewidth=1)
pro.set_data([[np.arange(len(profile))],profile])
ax[1].set_xlim(0,len(profile))
ax[1].set_ylim(0,profile.max()+1)
ax[1].set_title('data points = '+str(profile.shape[0])+'')
set_dataで選択した値を用いて、画像上にプロファイルを取得する範囲を点と線で示す。
profile_lineに取得した座標を入れて、プロファイルを得る。得たプロファイルも同様にset_dataでデータをセットすることで表示する。
Widgetsの有効化と表示
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
out =interactive(f,x_s=x_s,y_s=y_s,x_e=x_e,y_e=y_e)
hbox1 = HBox([x_s, x_e])
hbox2 = HBox([y_s, y_e])
ui = VBox([hbox1, hbox2])
display(ui)
interactiveで関数fを有効にし、ipywidgetsが動作するようにする。
widgetsはHBox とVBoxを用いて、整列させたものを作成して、それをdisplay(ui)で表示した。
IntSliderを変化させたときの強度プロファイルの変化

参考
Using Interact — Jupyter Widgets 8.1.5 documentation
https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20List.html
コメント