【问题标题】:Generating colour image gradient using numpy使用 numpy 生成彩色图像渐变
【发布时间】:2017-03-28 03:24:50
【问题描述】:

我写了一个生成 2 个彩色图像块的函数:

def generate_block():
    x = np.ones((50, 50, 3))
    x[:,:,0:3] = np.random.uniform(0, 1, (3,))
    show_image(x)

    y = np.ones((50, 50, 3))
    y[:, :, 0:3] = np.random.uniform(0, 1, (3,))
    show_image(y)

然后我想将这两种颜色组合成一个渐变,即一张图像从一种颜色变为另一种颜色。我不确定如何继续,有什么建议吗?使用 np.linspace() 我可以形成一维步骤数组,但是接下来呢?

【问题讨论】:

  • 您能将输出描述为图像吗?
  • “一张图片从一种颜色变为另一种颜色”是什么意思?
  • 还有,show_image() 是什么?
  • 当然,@P.Camilleri 图像应该以纯色开始,例如图像顶部的红色,当您向下看时,颜色会逐渐消失并慢慢变为另一种颜色,例如蓝色。快速谷歌搜索返回this。谢谢。
  • 如果是自定义函数,请将代码包含在您的问题中,以便其他用户能够测试您的代码。更好的是,替换一个内置函数,如 plt.imshow()

标签: python arrays python-2.7 numpy


【解决方案1】:

这就是你要找的吗?

def generate_block():
    x = np.ones((50, 50, 3))
    x[:, :, 0:3] = np.random.uniform(0, 1, (3,))
    plt.imshow(x)
    plt.figure() 

    y = np.ones((50, 50, 3))
    y[:,:,0:3] = np.random.uniform(0, 1, (3,))
    plt.imshow(y)

    plt.figure()
    c = np.linspace(0, 1, 50)[:, None, None]
    gradient = x + (y - x) * c
    plt.imshow(gradient)
    return x, y, gradient

要按照您的建议使用np.linspace,我使用了广播,这是 numpy 中非常强大的工具;阅读更多here。

c = np.linspace(0, 1, 50) 创建一个形状为(50,) 的数组,其中包含从 0 到 1 的 50 个数字,均匀分布。添加[:, None, None] 使该数组为3D,形状为(50, 1, 1)。在(x - y) * c 中使用它时,由于x - y 是(50, 50, 3),因此最后两个维度发生广播。 c 被视为一个形状为 (50, 50, 3) 的数组,我们将其称为 d,因此对于范围 (50) 中的 i,d[i, :, :] 是一个形状为 (50, 3) 的数组,其中填充了 c[i]。

所以渐变的第一行是x[0, :, :] + c[0] * (x[0, :, :] - y[0, :, :]),也就是x[0, :, :] 第二行是x[1, :, :] + c[1] * (x[1, :, :] - y[1, :, :])等。ith 行是x[i]和y[i]的重心,系数为1 - c[i]和c[i]

您可以在 c 的定义中使用 [None, :, None] 进行列变化。

【讨论】:

  • 是的,正是我要找的!如果可以的话,你能解释一下c = np.linspace(0, 1, 50)[:, None, None] 和gradient = x + (y - x) * c 做了什么吗?对于渐变,看起来您正在计算两个数组之间的差异并乘以步骤然后添加到第一个颜色块,为什么这样做?
  • 另外,是否有可能以某种方式使用np.outer(x,y) 来获取外部产品并使用它来显示所需的输出?
  • @Boa 我看不出 x 和 y 的外积在这里会有什么帮助。仍然可以使用外部产品,但可以在不同的数组之间使用。
  • 感谢您的解释,显然np.outer 可以使用gradient = np.outer(np.linspace(0,1,50),np.ones((50,))).reshape(50,50,1)
  • @Boa 很高兴知道。请按照 PEP8 的建议在逗号后添加一个空格 :)
【解决方案2】:

感谢 P. Camilleri 的出色回答。 我添加了一个按列变化的示例,它使用给定的 RGB 值和 .最后,我将其转换为您可以保存的图像。

WIDTH_LIMIT = 3200
HEIGHT_LIMIT = 4800
def generate_grad_image(rgb_color=(100,120,140)): # Example value
    x = np.ones((HEIGHT_LIMIT, WIDTH_LIMIT, 3)) 
    x[:, :, 0:3] = rgb_color
    y = np.ones((HEIGHT_LIMIT, WIDTH_LIMIT, 3))
    y[:,:,0:3] = [min(40 + color, 255) for color in rgb_color]
    c = np.linspace(0, 1, WIDTH_LIMIT)[None,:, None]
    gradient = x + (y - x) * c
    im = Image.fromarray(np.uint8(gradient))
    return im

示例输出:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 2012-11-28
    相关资源
    最近更新 更多