简体   繁体   English

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

[英]Extracting foreground image as mask by thresholding

I'm looking for a robust way to extract the foreground from an image where the background has some noise in it. 我正在寻找一种强大的方法来从背景中有一些噪音的图像中提取前景。

So, the image I want to use it on is: 所以,我想用它的图像是:

图像有一些背景噪音

My attempt was to use the Otsu thresholding . 我的尝试是使用Otsu thresholding I did that in Python as follows: 我在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()

This gives the R, G, B threshold as (62 67 64), which is a bit high. 这使得R,G,B阈值为(62 67 64),这有点高。 The result is: 结果是:

大津的结果

This image is also one of the images where Otsu thresholding worked best. 此图像也是Otsu thresholding处理效果最好的图像之一。 If I use a manual threshold like a value of 30, it works quite well. 如果我使用值为30的手动阈值,它可以很好地工作。 The result is: 结果是:

手册

I was wondering if there are some other approaches that I should try. 我想知道是否还有其他方法我应该尝试。 Segmentation really is not my area of expertise and what I can do out of the box seem limited. 分割确实不是我的专业领域,我开箱即用的东西似乎有限。

Your image looks not very colorful. 你的形象看起来不是很丰富多彩 So you can perform the segmentation on the gray values and not on each color separately and then combining three masks. 因此,您可以对灰度值执行分割,而不是分别对每种颜色执行分割,然后组合三个蒙版。

Looking at the package scikit-image.filter there are several other threshold methods. 查看包scikit-image.filter还有其他几种阈值方法。 I tried them all and found threshold_isodata to perform extremely well giving almost the same image as your desired image. 我尝试了所有这些并发现threshold_isodata执行得非常好,提供与您想要的图像几乎相同的图像。 Therefore I recommend the isodata algorithm. 因此我推荐使用isodata算法。

Example: 例:

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()

gives: 得到:

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM