【问题标题】:Python 3 PIL: Converting a Numpy array of 3-tuples to an image in HSVPython 3 PIL:将 3 元组的 Numpy 数组转换为 HSV 中的图像
【发布时间】:2019-03-11 17:22:53
【问题描述】:

我正在尝试编写在 Python 3 中制作 Mandelbrot 分形图像的代码。该代码在不使用 numpy 数组的情况下工作,但速度很慢。为了加快速度,我尝试使用 numpy 和 numba。

在 PIL 中对 3 元组的 numpy 数组使用 Image.fromarray() 时,生成的图像是一系列垂直线,而不是预期的 Mandelbrot 图像。 经过一些研究,我认为问题出在数据类型上,并且可能与有符号整数和无符号整数有关。如果我为 numpy 数组中的 HSV 值存储整数而不是 3 个元组,我可以让事情正常工作。不幸的是,这给出了一个黑白图像,我想要一个彩色图像。 另一个奇怪的事情是,每次运行代码时,代码生成的图像都会略有变化。我不确定这是一个相关的还是单独的问题。 这是代码,经过调整以删除 mandelbrot 生成器并简单地创建一个渐变图像,显示了问题:

from PIL import Image, ImageDraw
from numba import jit
import numpy as np 

@jit
def simple_image(width,height):
    n3 = np.empty((width, height), dtype=object)
    for i in range(width):
        for j in range(height):
            n3[i, j] = (min(j, 255), 255, 255)
    return n3 

arr = simple_image(800, 600) 

im = Image.new('HSV', (800, 600), (0, 0, 0))
im = Image.fromarray(arr.astype(object), mode='HSV')
im.convert('RGB').save('output.png', 'PNG')

这是生成的图像。 Vertical Lines

当我对代码进行一些更改以便它存储整数并创建黑白图像时,它可以工作:

from PIL import Image, ImageDraw
from numba import jit
import numpy as np 

@jit
def simple_image(width,height):
    n3 = np.empty((width, height))
    for i in range(width):
        for j in range(height):
            n3[i, j] = min(j, 255)
    return n3 

arr = simple_image(800, 600) 

im = Image.new('HSV', (800, 600), (0, 0, 0))
im = Image.fromarray(arr)
im.convert('RGB').save('output.png', 'PNG')

【问题讨论】:

  • 彩色图像应该是 3d,例如(width, height, 3) 形状。
  • 您是否建议将行 im = Image.new('HSV', (800, 600), (0, 0, 0)) 更改为 im = Image.new('HSV ', (800, 600, 3), (0, 0, 0)) ?这样做会给出“ValueError:Size must be a tuple of length 2”,但我不知道您的评论还有什么意思。
  • 啊,我知道了,谢谢!它是需要 3d 的 numpy 数组,而不是 2d 元组数组。

标签: python numpy python-imaging-library


【解决方案1】:

感谢hpaulj 的建议,这是回答问题的代码。 numpy 数组从 3 元组的 2d 数组更改为具有长度为 3 的第三维的 3d 数组。dtype 在两个地方设置为 'uint8'。

from PIL import Image, ImageDraw
from numba import jit
import numpy as np 

@jit
def white_image(width,height):
    n3 = np.empty((width, height, 3), dtype='uint8')
    for i in range(width):
        for j in range(height):
            n3[i, j, 0] = min(j, 255)
            n3[i, j, 1] = 255
            n3[i, j, 2] = 255
    return n3 

arr = white_image(800, 600) 

im = Image.new('HSV', (800, 600), (0, 0, 0))
im = Image.fromarray(arr.astype('uint8'), mode='HSV')
im.convert('RGB').save('output.png', 'PNG')

【讨论】:

  • 我相信第一个im = Image.new是多余的
  • @SanjayManohar 我在没有 Image.new 的情况下尝试过,但它不起作用。由于某种原因,数组的解释不同,给了我一个无意义的图像。
猜你喜欢
  • 2020-02-17
  • 2017-06-25
  • 2018-09-28
  • 2010-09-27
  • 2019-11-29
  • 2021-12-09
  • 2015-04-15
  • 1970-01-01
  • 2019-02-26
相关资源
最近更新 更多