Chan-Vese 分割#

Chan-Vese分割アルゴリズムは、境界が明確に定義されていないオブジェクトをセグメント化するために設計されています。このアルゴリズムは、セグメント化された領域の外側の平均値からの強度差の合計、セグメント化された領域の内側の平均値からの強度差の合計、およびセグメント化された領域の境界の長さに依存する項によって定義されるエネルギーを反復的に最小化するために進化するレベルセットに基づいています。

このアルゴリズムは、Tony ChanとLuminita Veseによって、「An Active Contour Model Without Edges」と題された論文[1]で最初に提案されました。[2][3]も参照してください。

このアルゴリズムの実装は、元の論文で記述されている面積係数「nu」が実装されておらず、グレースケール画像にのみ適しているという意味で、いくぶん簡略化されています。

lambda1lambda2の典型的な値は1です。「背景」が分布の点でセグメント化されたオブジェクトと非常に異なる場合(たとえば、様々な強度の図形を持つ均一な黒の画像)、これらの値はお互いに異なる必要があります。

muの典型的な値は0から1の間ですが、輪郭が非常に不明瞭な形状を扱う場合、より高い値を使用できます。

このアルゴリズムは、各反復におけるエネルギーに対応する値のリストも返します。これは、上記で説明した様々なパラメータを調整するために使用できます。

参考文献#

Original Image, Chan-Vese segmentation - 200 iterations, Final Level Set, Evolution of energy over iterations
import matplotlib.pyplot as plt
from skimage import data, img_as_float
from skimage.segmentation import chan_vese

image = img_as_float(data.camera())
# Feel free to play around with the parameters to see how they impact the result
cv = chan_vese(
    image,
    mu=0.25,
    lambda1=1,
    lambda2=1,
    tol=1e-3,
    max_num_iter=200,
    dt=0.5,
    init_level_set="checkerboard",
    extended_output=True,
)

fig, axes = plt.subplots(2, 2, figsize=(8, 8))
ax = axes.flatten()

ax[0].imshow(image, cmap="gray")
ax[0].set_axis_off()
ax[0].set_title("Original Image", fontsize=12)

ax[1].imshow(cv[0], cmap="gray")
ax[1].set_axis_off()
title = f'Chan-Vese segmentation - {len(cv[2])} iterations'
ax[1].set_title(title, fontsize=12)

ax[2].imshow(cv[1], cmap="gray")
ax[2].set_axis_off()
ax[2].set_title("Final Level Set", fontsize=12)

ax[3].plot(cv[2])
ax[3].set_title("Evolution of energy over iterations", fontsize=12)

fig.tight_layout()
plt.show()

スクリプトの総実行時間:(0分4.440秒)

Sphinx-Galleryによって生成されたギャラリー