はじめに
skimage.morphologyのskeletonizeで、ボクセルグラフで表示した3次元オブジェクトを細線化する方法について説明する。
コード
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
import numpy as np
from skimage.morphology import skeletonize,octahedron,ball
import matplotlib.pyplot as plt
#make object
octahedron6=octahedron(3)
ball6=ball(3)
struc1 = np.concatenate([ball6,octahedron6])
struc2 = np.concatenate([octahedron6,ball6])
struc3 = np.concatenate([struc1,struc2],axis=1)
struc4 = np.concatenate([struc2,struc1],axis=1)
struc = np.concatenate([struc3,struc4],axis=2)
#skeletonize
skeleton = skeletonize(struc)
fig = plt.figure(figsize=(8,4))
ax1 = fig.add_subplot(121,projection='3d')
ax1.voxels(struc,ec='w')
ax1.grid()
ax1.set(xlim=(-1,struc.shape[0]+1),
ylim=(-1,struc.shape[0]+1),
zlim=(-1,struc.shape[0]+1))
ax1.set_title('Original', fontsize=15)
ax2 = fig.add_subplot(122,projection='3d')
ax2.voxels(skeleton,ec='k')
ax2.grid()
ax2.set(xlim=(-1,skeleton.shape[0]+1),
ylim=(-1,skeleton.shape[0]+1),
zlim=(-1,skeleton.shape[0]+1))
ax2.set_title('Skeleton', fontsize=15)
fig.tight_layout()
plt.savefig('3d_skelton.png',dpi=100)
plt.show()

解説
モジュールのインポートなど
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
import numpy as np
from skimage.morphology import skeletonize,octahedron,ball
import matplotlib.pyplot as plt
バージョン
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
import skimage
print(skimage.__version__)
0.16.2
import matplotlib
print(matplotlib.__version__)
3.2.0
print(np.__version__)
1.18.1
構造化要素で物体を作成
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
#make object
octahedron6=octahedron(3)
ball6=ball(3)
struc1 = np.concatenate([ball6,octahedron6])
struc2 = np.concatenate([octahedron6,ball6])
struc3 = np.concatenate([struc1,struc2],axis=1)
struc4 = np.concatenate([struc2,struc1],axis=1)
struc = np.concatenate([struc3,struc4],axis=2)
skimage,morphologyのoctahedronとballを使って構造化要素を作成して、それらをnp.concatenateで連結して3次元オブジェクトを作成する。
3次元オブジェクトの細線化
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
skeleton = skeletonize(struc)
skeletonizeで細線化する。2次元画像の細線化については下記記事で解説した。

[scikit-image] 23. 画像の細線化(morphology.skeletonize)
ここでは、skimage.morphology の skeletonizeを用いた画像の細線化について説明する。
結果の表示
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 = plt.figure(figsize=(8,4))
ax1 = fig.add_subplot(121,projection='3d')
ax1.voxels(struc,ec='w')
ax1.grid()
ax1.set(xlim=(-1,struc.shape[0]+1),
ylim=(-1,struc.shape[0]+1),
zlim=(-1,struc.shape[0]+1))
ax1.set_title('Original', fontsize=15)
ax2 = fig.add_subplot(122,projection='3d')
ax2.voxels(skeleton,ec='k')
ax2.grid()
ax2.set(xlim=(-1,skeleton.shape[0]+1),
ylim=(-1,skeleton.shape[0]+1),
zlim=(-1,skeleton.shape[0]+1))
ax2.set_title('Skeleton', fontsize=15)
fig.tight_layout()
plt.savefig('3d_skelton.png',dpi=100)
plt.show()
ボクセルグラフでオリジナル物体とその物体を細線化した結果を表示する。なお、ボクセルグラフについては下記で解説した。

[matplotlib 3D] 28. Pythonで3D voxelグラフ
3D voxelグラフの作成について解説する。

回転アニメーション
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
import matplotlib.animation as animation
from IPython.display import HTML
fig = plt.figure(figsize=(8,4))
ax1 = fig.add_subplot(121,projection='3d')
ax1.voxels(struc,ec='w')
ax1.grid()
ax1.set(xlim=(-1,struc.shape[0]+1),
ylim=(-1,struc.shape[0]+1),
zlim=(-1,struc.shape[0]+1))
ax2 = fig.add_subplot(122,projection='3d')
ax2.voxels(skeleton,ec='k')
ax2.grid()
ax2.set(xlim=(-1,skeleton.shape[0]+1),
ylim=(-1,skeleton.shape[0]+1),
zlim=(-1,skeleton.shape[0]+1))
fig.tight_layout()
def animate(i):
ax1.view_init(elev=30., azim=30 + 3.6*i)
ax2.view_init(elev=30., azim=30 - 3.6*i)
return fig,
# Animate
ani = animation.FuncAnimation(fig, animate,frames=100, interval=100, blit=True)
ani.save('rotate_3d_skeltone.mp4', writer="ffmpeg",dpi=100)
HTML(ani.to_html5_video())
回転アニメーションは以下記事を参考にして作成した。

[matplotlib 3D] 14. 3Dグラフの回転アニメーション
matplotlib mplot3d のグラフの回転アニメーション
参考
Generate footprints (structuring elements) — skimage 0.26.0rc0.dev0 documentation
skimage.morphology — skimage 0.26.0rc0.dev0 documentation
コメント