python - 通过阈值提取前景图像作为掩模

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

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

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

Image with some background noise

我尝试使用Otsu 阈值。我在 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 阈值处理 效果最好的图像之一。如果我使用手动阈值(例如 30),效果会非常好。结果是:

Manual

我想知道我是否应该尝试其他一些方法。分割确实不是我的专业领域,而且我能做的开箱即用的事情似乎很有限。

最佳答案

您的图像看起来色彩不太丰富。因此,您可以对灰度值进行分割,而不是单独对每种颜色进行分割,然后组合三个蒙版。

查看包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

关于python - 通过阈值提取前景图像作为掩模,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28289374/

相关文章:

python - Django/Python 中的 SQL LIKE

python - 如何提示程序员在python中使用try except子句?

algorithm - 我怎样才能证明这个边遍历算法有效呢?

matlab - mat2gray对multithresh的影响

python - 如何将 2 元组列表拆分为两个列表?

python - "System error: new style getargs format but argument is not a tuple"使用 cv2.blur 时

python - 如何使用Python去除金相图像上的划痕

python - 如何在Python中仅打开10%放大的jpeg图像?

python - 基于像素密度的图像分割

python - 查找列的最大值,并在另一列中返回值