通过阈值处理提取前景图像作为掩码

时间:2015-02-03 00:31:10

标签: python image-processing image-segmentation scikit-image

我正在寻找一种强大的方法来从背景中有一些噪音的图像中提取前景。

所以,我想用它的图像是:

Image with some background noise

我的尝试是使用Otsu thresholding。我在Python中做到了如下:

from skimage.filter import threshold_otsu
import os.path as path
import matplotlib.pyplot as plt

img = io.imread(path.expanduser('~/Desktop/62.jpg'))
r_t = threshold_otsu(img[:, :, 0])
g_t = threshold_otsu(img[:, :, 1])
b_t = threshold_otsu(img[:, :, 2])

m = np.zeros((img.shape[0], img.shape[1]), dtype=np.uint8)
mask = (img[:, :, 0] < r_t) & (img[:, :, 1] < g_t) & (img[:, :, 2] < b_t)
m[~mask] = 255

plt.imshow(m)
plt.show()

这使得R,G,B阈值为(62 67 64),这有点高。结果是:

Otsu result

此图片也是Otsu thresholding效果最好的图片之一。如果我使用值为30的手动阈值,它可以很好地工作。结果是:

Manual

我想知道是否还有其他方法我应该尝试。分割确实不是我的专业领域,我开箱即用的东西似乎有限。

1 个答案:

答案 0 :(得分:2)

您的图片看起来不是很丰富多彩。因此,您可以对灰度值执行分割,而不是分别对每种颜色执行分割,然后组合三个蒙版。

查看包scikit-image.filter,还有其他一些阈值方法。我尝试了所有这些并发现threshold_isodata表现得非常好,可以提供与所需图像几乎相同的图像。因此我推荐使用isodata算法。

示例:

import numpy as np
import skimage.io as io
import skimage.filter as filter
import matplotlib.pyplot as plt

img = io.imread('62.jpg')
gray = np.sum(img, axis=2) # summed up over red, green, blue
#threshold = filter.threshold_otsu(gray) # delivers very high threshold
threshold = filter.threshold_isodata(gray) # works extremely well
#threshold = filter.threshold_yen(gray) # delivers even higher threshold
print(threshold)

plt.imshow(gray > threshold)
plt.show()

给出:

enter image description here