将布尔型的numpy数组转换为pillow图像。

11

我目前正在使用scikit-image库中的python进行图像处理。我正试图使用以下代码使用sauvola阈值将图像制作成二进制图像:

from PIL import Image
import numpy
from skimage.color import rgb2gray
from skimage.filters import threshold_sauvola

im = Image.open("test.jpg")
pix = numpy.array(im)
img = rgb2gray(pix)

window_size = 25
thresh_sauvola = threshold_sauvola(img, window_size=window_size)
binary_sauvola = img > thresh_sauvola

以下是结果:

enter image description here

输出结果是一个numpy数组,数据类型为布尔型。

[[ True  True  True ...  True  True  True]
 [ True  True  True ...  True  True  True]
 [ True  True  True ...  True  True  True]
 ...
 [ True  True  True ...  True  True  True]
 [ True  True  True ...  True  True  True]
 [ True  True  True ...  True  True  True]]

问题在于,我需要使用以下代码将该数组转换回 PIL 图像:
image = Image.fromarray(binary_sauvola)

这将使图像看起来像这样:

enter image description here

我还尝试将数据类型从布尔型更改为uint8,但是我会收到以下异常:

AttributeError: 'numpy.ndarray' object has no attribute 'mask'

到目前为止,我还没有找到一种方法来获取类似于阈值处理结果的PIL图像。


1
我也尝试将数据类型从bool更改为uint8,这是我的尝试。显然没有使用viewastype,所以我不确定你做了什么。 - Mad Physicist
我尝试了以下代码将数据类型更改为uint8: image = Image.fromarray(binary_sauvola.astype('uint8')) - R.hagens
然后显示堆栈跟踪。那个错误看起来很奇怪。请编辑问题。如果可以避免,不要在评论中放置牛和错误。 - Mad Physicist
2个回答

13

更新

这个错误现在已经在Pillow==6.2.0中被解决了。GitHub上与此问题相关的链接在这里

如果您无法更新到新版本的Pillow,请参见以下内容。


PIL的Image.fromarray函数在模式为“1”的图像上存在一个bug。 这个代码片段演示了该错误,并展示了几种解决方法。以下是最好的两种解决方法:

import numpy as np
from PIL import Image

# The standard work-around: first convert to greyscale 
def img_grey(data):
    return Image.fromarray(data * 255, mode='L').convert('1')

# Use .frombytes instead of .fromarray. 
# This is >2x faster than img_grey
def img_frombytes(data):
    size = data.shape[::-1]
    databytes = np.packbits(data, axis=1)
    return Image.frombytes(mode='1', size=size, data=databytes)

还可以参考将PIL黑白图像转换为Numpy数组时出错


img_grey没有给我正确的结果,但是img_frombytes有。非常感谢您的答案。 - R.hagens
1
@R.hagens 非常愉快!有趣的是,img_grey 对你来说表现不佳。我不确定为什么会这样,我大约一年前就对这个主题进行了研究,但我忘记了细节。但我更喜欢 img_frombytes,因为我自己写的。 :) - PM 2Ring
如果你感兴趣的话,img_grey 给了我以下结果 https://imgur.com/a/VC3yqs4。 - R.hagens
@R.hagens 谢谢。本质上是同一个 bug,但我得思考一下为什么它仍然会发生,尽管 img_grey 进行了灰度转换。 - PM 2Ring
1
这个问题已经在最新的pillow==6.2.0中得到解决。该问题在github上的链接为:https://github.com/python-pillow/Pillow/issues/3109 - Taro Kiritani

2

这个选项在2018年可能不可用,但目前已经可以使用。

from skimage.io._plugins.pil_plugin import ndarray_to_pil, pil_to_ndarray
ndarray_to_pil(some_binary_image).convert("1")

似乎可以解决问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接