【问题标题】:Python - Find the closest color to a color, from giving list of colorsPython - 从给出颜色列表中找到最接近颜色的颜色
【发布时间】:2019-06-12 00:33:17
【问题描述】:

我有 20 种颜色的列表,每种颜色都像 (0,0,0)(rgb) 但具有不同的值,我需要找到最接近我给出的颜色的颜色,例如 (200, 191 , 231)。问题是我不确定我应该如何检查关闭的颜色,以及我应该如何在列表中设置所有这些颜色值?在数组中?

我一直在考虑是否可以为示例 (1,2,3) = 4 添加所有颜色,然后找到最接近的颜色,但我不确定这是否是个好主意..

这是颜色列表:

#(0, 0, 0) - Black
#(127, 127, 127) - Gray
#(136, 0, 21) - Bordeaux
#(237, 28, 36) - red
#(255, 127, 39) - orange
#(255, 242, 0) - yellow
#(34, 177, 76) - green
#(203, 228, 253) - blue
#(0, 162, 232) - dark blue
#(63, 72, 204) - purple
#(255, 255, 255) - white
#(195, 195, 195) - light gray
#(185, 122, 87) - light brown
#(255, 174, 201) - light pink
#(255, 201, 14) - dark yellow
#(239, 228, 176) - light yellow
#(181, 230, 29) - light green
#(153, 217, 234) - light blue
#(112, 146, 190) - dark blue
#(200, 191, 231) - light purple

这里是函数:

def paint(pixel):
  r,g,b,a = pix[x,y]
  print(str(r) + ' '+  str(g) + ' ' + str(b))
  sleep(0.20)

如果您想出了一个好的解决方案或有任何问题,请重播,谢谢您的帮助!

【问题讨论】:

标签: python rgb


【解决方案1】:

你想求红色、绿色和蓝色数字之间的绝对差之和,然后选择最小的那个。

from math import sqrt

COLORS = (
    (181, 230, 99),
    (23, 186, 241),
    (99, 23, 153),
    (231, 99, 29),
)

def closest_color(rgb):
    r, g, b = rgb
    color_diffs = []
    for color in COLORS:
        cr, cg, cb = color
        color_diff = sqrt((r - cr)**2 + (g - cg)**2 + (b - cb)**2)
        color_diffs.append((color_diff, color))
    return min(color_diffs)[1]

closest_color((12, 34, 156))
# => (99, 23, 153)

closest_color((23, 145, 234))
# => (23, 186, 241)

编辑:改进代码并使用上面提到的欧几里得距离计算 Sven 而不是基本的差异总和。

【讨论】:

  • 您的解决方案不考虑相同距离的更多颜色。这是错误的解决方案
  • 不错,但不是很快...
【解决方案2】:

快速、高效、清洁的解决方案

假设我们有:

list_of_colors = [[255,0,0],[150,33,77],[75,99,23],[45,88,250],[250,0,255]]

为了快速处理,使用 numpy 并转换为 numpy 数组

import numpy as np

想要的颜色

color = [155,155,155]

完整代码

import numpy as np

list_of_colors = [[255,0,0],[150,33,77],[75,99,23],[45,88,250],[250,0,255]]
color = [155,155,155]

def closest(colors,color):
    colors = np.array(colors)
    color = np.array(color)
    distances = np.sqrt(np.sum((colors-color)**2,axis=1))
    index_of_smallest = np.where(distances==np.amin(distances))
    smallest_distance = colors[index_of_smallest]
    return smallest_distance 

closest_color = closest(list_of_colors,color)
print(closest_color )

该算法没有循环,并且由于使用了 numpy,所以速度非常快

【讨论】:

  • @stackmodern 这是您不用循环遍历的解决方案。您也可以将其应用于图像,但您必须围绕轴值进行操作
  • @stackmodern 你能更详细地描述你的问题吗?你想传递整个图像?
  • @stackmodern 你应该检查 numpy api。这也适用于图像。 a) 您需要将 list_of_colors 作为具有此形状 (x,y,3) [即 numpy 形式的标准图像形状] 的 numpy 数组传递,并且在函数中更改轴 = 2。自己试试。 list_of_colors = np.ones(shape=[100,100,3]) 其中 3 是 rgb 通道。 axis=2 表示您在第三维进行操作,即 rgb 通道。如果您有灰度图像,请不要使用 3 作为 rgb 通道,而是使用 1,例如 (100,100,1)。如果使用 (100,100) 则需要再次更改 axis=...
  • 最接近的函数接受此维度的列表或 numpy 数组: (n,3) 其中 n(0.index) 是列表/数组中的项目数,3 (1.index) 是颜色通道。因此axis = 1(1.index),因为它通过rgb通道计算东西。如果要为图像 (n,m,3) 计算此值,其中 3(2.index) 是 rgb chanell,则需要将这一行 distances = np.sqrt(np.sum((colors-color)**2,axis=1)) 更改为访问 rgb 通道,即 2. 数组索引,因此轴=2。就是这样
  • @stackmodern 要么你了解 numpy 的工作原理(这是关于我几分钟前用维度写的),要么你把你的图像作为 numpy 数组并使用这个命令:image.reshape(-1,3)你会没事的,不用改变任何东西。如果你仍然不明白,你需要学习 numpy 是如何工作的。我建议你学习numpy,然后你会很容易地修改这个函数
猜你喜欢
  • 2014-07-22
  • 2019-07-02
  • 1970-01-01
  • 1970-01-01
  • 2016-11-13
  • 1970-01-01
  • 2012-04-06
  • 2014-01-28
  • 2016-03-25
相关资源
最近更新 更多