备注
单击 here 下载完整的示例代码或通过活页夹在浏览器中运行此示例
基于局部特征和随机森林的可训练分割¶
基于像素的分割是使用基于不同尺度的局部强度、边缘和纹理的局部特征来计算的。使用用户提供的掩码来标识不同的区域。掩码的像素用于训练随机森林分类器 1 来自SCRICKIT-学习。然后,根据分类器的预测来标记未标记的像素。
这种分割算法在其他软件中称为可训练分割,例如ilastik 2 或ImageJ 3 (在这里它也被称为“WEKA分段”)。
- 1
https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html
- 2
https://www.ilastik.org/documentation/pixelclassification/pixelclassification
- 3
Https://imagej.net/Trainable_Weka_Segmentation#Training_features_.282D.29
import numpy as np
import matplotlib.pyplot as plt
from skimage import data, segmentation, feature, future
from sklearn.ensemble import RandomForestClassifier
from functools import partial
full_img = data.skin()
img = full_img[:900, :900]
# Build an array of labels for training the segmentation.
# Here we use rectangles but visualization libraries such as plotly
# (and napari?) can be used to draw a mask on the image.
training_labels = np.zeros(img.shape[:2], dtype=np.uint8)
training_labels[:130] = 1
training_labels[:170, :400] = 1
training_labels[600:900, 200:650] = 2
training_labels[330:430, 210:320] = 3
training_labels[260:340, 60:170] = 4
training_labels[150:200, 720:860] = 4
sigma_min = 1
sigma_max = 16
features_func = partial(feature.multiscale_basic_features,
intensity=True, edges=False, texture=True,
sigma_min=sigma_min, sigma_max=sigma_max,
multichannel=True)
features = features_func(img)
clf = RandomForestClassifier(n_estimators=50, n_jobs=-1,
max_depth=10, max_samples=0.05)
clf = future.fit_segmenter(training_labels, features, clf)
result = future.predict_segmenter(features, clf)
fig, ax = plt.subplots(1, 2, sharex=True, sharey=True, figsize=(9, 4))
ax[0].imshow(segmentation.mark_boundaries(img, result, mode='thick'))
ax[0].contour(training_labels)
ax[0].set_title('Image, mask and segmentation boundaries')
ax[1].imshow(result)
ax[1].set_title('Segmentation')
fig.tight_layout()

输出:
/scikit-image/doc/examples/segmentation/plot_trainable_segmentation.py:46: FutureWarning:
`multichannel` is a deprecated argument name for `multiscale_basic_features`. It will be removed in version 1.0. Please use `channel_axis` instead.
功能重要性¶
我们在下面检查不同功能的重要性,这是由SCRICIT-LEARN计算得出的。强度特征比纹理特征具有更高的重要性。为了减少计算时间,使用这些信息来减少提供给分类器的特征的数量是很有诱惑力的。但是,这可能会导致区域间边界处的过度拟合和降级结果。
fig, ax = plt.subplots(1, 2, figsize=(9, 4))
l = len(clf.feature_importances_)
feature_importance = (
clf.feature_importances_[:l//3],
clf.feature_importances_[l//3:2*l//3],
clf.feature_importances_[2*l//3:])
sigmas = np.logspace(
np.log2(sigma_min), np.log2(sigma_max),
num=int(np.log2(sigma_max) - np.log2(sigma_min) + 1),
base=2, endpoint=True)
for ch, color in zip(range(3), ['r', 'g', 'b']):
ax[0].plot(sigmas, feature_importance[ch][::3], 'o', color=color)
ax[0].set_title("Intensity features")
ax[0].set_xlabel("$\\sigma$")
for ch, color in zip(range(3), ['r', 'g', 'b']):
ax[1].plot(sigmas, feature_importance[ch][1::3], 'o', color=color)
ax[1].plot(sigmas, feature_importance[ch][2::3], 's', color=color)
ax[1].set_title("Texture features")
ax[1].set_xlabel("$\\sigma$")
fig.tight_layout()

拟合新图像¶
如果您有多个在相似条件下获取的相似对象的图像,则可以使用 fit_segmenter 分割其他图像。在下面的例子中,我们只是使用了图像的不同部分。
img_new = full_img[:700, 900:]
features_new = features_func(img_new)
result_new = future.predict_segmenter(features_new, clf)
fig, ax = plt.subplots(1, 2, sharex=True, sharey=True, figsize=(6, 4))
ax[0].imshow(segmentation.mark_boundaries(img_new, result_new, mode='thick'))
ax[0].set_title('Image')
ax[1].imshow(result_new)
ax[1].set_title('Segmentation')
fig.tight_layout()
plt.show()

输出:
/scikit-image/doc/examples/segmentation/plot_trainable_segmentation.py:103: FutureWarning:
`multichannel` is a deprecated argument name for `multiscale_basic_features`. It will be removed in version 1.0. Please use `channel_axis` instead.
脚本的总运行时间: (0分3.339秒)