【问题标题】:How do I efficiently update the color of a pixel in a numpy image array if it is closer to one color in a palette than any other color?如果 numpy 图像数组中像素的颜色比任何其他颜色更接近调色板中的一种颜色,如何有效地更新它的颜色?
【发布时间】:2022-07-30 06:31:50
【问题描述】:

假设我有一个图像的 numpy 数组,img

import numpy as np

img = np.random.rand(100,100,3) * 255

还有一个颜色列表,palette

white = np.array([255,255,255])
red = np.array([255,0,0])
blue = np.array([0,0,255])
palette = np.array([white, red, blue])

如何创建一个新的图像数组 new_img,其中每个像素通过欧几里得距离比调色板中的任何其他颜色更接近白色的每个像素都更改为白色 ([255,255,255]) 和其他所有颜色像素颜色保持原样。 (能够改变距离函数会很好,但不是硬性要求。)

我可以用 for 循环遍历每个像素以天真的方式做到这一点,但它当然比它可能需要的要慢得多。

【问题讨论】:

  • 这取决于你如何定义距离,例如RED=[255,0,0]BLACK[0,0,0]的距离与BLUE=[0,0,255]相同,与此GREY=[85,85,85][42,84,129]相同
  • 人类感知不是线性数学的。看这里en.wikipedia.org/wiki/Color_difference
  • 对图像进行调色是一个常见的问题,并且没有好的捷径解决方案。您需要逐个像素地进行操作。

标签: python numpy


【解决方案1】:

先求每个向量的距离,再求最小距离的索引。

import numpy as np

img = np.random.rand(100,100,3) * 255
white = np.array([255,255,255])
red = np.array([255,0,0])
blue = np.array([0,0,255])
palette = np.array([white, red, blue])

palette_type = np.linalg.norm(img[...,None,:]-palette[:,:], axis=-1).argmin(axis=-1) ## 0 stands for white, 1 for red and 2 for blue.

new_img  = palette[palette_type]

【讨论】:

  • 谢谢!这比我的方法快得多。我还添加了几行来使白色像素透明并保持所有其他像素的原始颜色。我将在单独答案的代码块中分享它。
【解决方案2】:

感谢 Murali 提供的 the solution 提供了极大帮助。我拿了那个:

import numpy as np

img = np.random.rand(100,100,3) * 255
white = np.array([255,255,255])
red = np.array([255,0,0])
blue = np.array([0,0,255])
palette = np.array([white, red, blue])

palette_type = np.linalg.norm(img[...,None,:]-palette[:,:], axis=-1).argmin(axis=-1) ## 0 stands for white, 1 for red and 2 for blue.

new_img  = palette[palette_type]

并添加了几行,通过使白色像素透明并将所有其他像素保持为原始颜色来进一步提高:

mask = np.all(new_img == white, axis=-1)
img_copy = img.copy()
img_copy[mask] = white
h,w, _ = img_copy.shape
transparent_img = np.dstack((img_copy, np.zeros((h,w),dtype=np.uint8)+255))
masked_white = (transparent_img[:, :, 0:3] == white).all(2)
transparent_img[masked_white] = [0,0,0,0]

【讨论】:

    猜你喜欢
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 2019-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多