【问题标题】:Strange PIL.Image.fromarray behaviour with numpy zeros and ones in mode='1'奇怪的 PIL.Image.fromarray 行为与 numpy 零和 mode='1'
【发布时间】:2020-01-10 14:10:25
【问题描述】:

对我来说应该有一些谜题。

根据 PIL 文档,它具有不同的图像模式(如 1、L、8、RGB、RGBA 等),但我对模式“1”感兴趣(1 位像素,黑白,存储每个字节一个像素)。

我创建了 2 个大小为 100 x 100 的矩阵:第一个只有零 (np.zeros),第二个只有一个 (np.ones),期望全黑图像带有 1,而白色图像在模式 '1' 中带有零仅限黑白图像。

结果图片

问题:我做错了什么?

UPD。我试过使用 np.dtype uint8,没有用:

最终可接受的 UPD: 似乎有一个 PIL 错误,有一段时间没有修复,所以你应该使用 workarond 以这种方式创建一个白色矩形。奇怪,但现在我什至不确定“1”模式是什么意思:D

【问题讨论】:

  • 您可能会遇到与here 讨论的错误相同或相关的错误

标签: python arrays numpy python-imaging-library


【解决方案1】:

关于原始问题,这是最短的版本,适合我:

Image.fromarray(255 * np.ones((100, 100), np.uint8), '1')

我得到了正确的全白图像。

As pointed out earlier,当转换为“1”模式时,默认激活dithering。所以,也许模式“1”的意图正是:提供一种创建抖动图像的快速方法。让我们看看这个简短的例子:

from matplotlib import pyplot as plt
import numpy as np
from PIL import Image

plt.figure(1, figsize=(15, 5))

# Open some image
img = Image.open('path/to/your/image.png')
plt.subplot(1, 3, 1), plt.imshow(img)

# Convert to '1'; dithering activated by default
plt.subplot(1, 3, 2), plt.imshow(img.convert('1'))

# Convert to '1'; dithering deactivated
plt.subplot(1, 3, 3), plt.imshow(img.convert('1', dither=Image.NONE))

plt.tight_layout()
plt.show()

这就是输出:

抖动的图像在足够小的情况下看起来很像通常的灰度图像。禁用抖动时(右图),您实际上会得到一个阈值图像,其中所有 >= 128 的值都设置为白色,否则设置为黑色。

希望有帮助!

-----------------------
System information
-----------------------
Python:      3.8.1
Matplotlib:  3.2.0rc1
NumPy:       1.18.1
Pillow:      7.0.0
-----------------------

【讨论】:

    【解决方案2】:

    你需要在创建数组时指定dtype,否则你会得到类似int64的东西:

    im = np.zeros((100,100), dtype=np.uint8)
    

    【讨论】:

    • 我知道您遇到了问题,但现在调查已晚,请尝试Image.fromarray(np.ones((100,100), dtype=np.uint8),'L').convert('1')
    【解决方案3】:

    你的第二个案例Image.fromarray(numpy.ones((100, 100)), '1')有两个问题

    1. numpy.ones(...) 创建一个值 1,它只设置了 8 位中的一位。您需要 255 的值来设置所有八位
    2. 您需要将 numpy dtype 显式设置为uint8
    from PIL import Image
    import numpy
    
    white_image = Image.fromarray(numpy.full(shape=(100, 100), fill_value=255, dtype=numpy.uint8), '1')
    

    这将产生您想要的纯白色图像。

    【讨论】:

    • 这行得通,但它要么与 PIL 文档描述 '1' 模式工作的方式不一致(“1 位像素,黑白,每个字节存储一个像素”),要么我是误解了他们所说的意思。
    • 是的,但我假设 1 位像素,黑白,每个字节存储一个像素,应该使用 0 和 1(更多布尔值),而不是 0、255(更多 int :D )
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    • 1970-01-01
    相关资源
    最近更新 更多