【问题标题】:Python - How to sort a list of colors based on a color's "distance" from a source color in 3D (r, g, b) space?Python - 如何根据颜色与 3D(r、g、b)空间中源颜色的“距离”对颜色列表进行排序?
【发布时间】:2012-12-19 13:25:33
【问题描述】:

以下是我用 Python 编写的应用程序的基本步骤:

  1. 生成随机颜色列表
  2. 创建每种颜色的映射,以该颜色到 3D(r、g、b)空间中“源颜色”的距离为索引。 (例如,橙色 (255, 150, 0) 比深蓝色 (0, 0, 100) 更接近红色 (255, 0, 0)。到目前为止,我有一个格式为 (distance, color )。
  3. 根据我计算的距离(从最低到最高)对该元组列表进行排序。
  4. 检索已排序颜色的列表

这是我的函数,我收到以下错误:TypeError: 'int' object has no attribute '_getitem_' on line sorted_by_dist = sorted(colorMap, key=lambda tup: tup[0])

# Sorts a list of colors according to distance from the source color
def sort_colors(colors, source):
    colorMap = ()
    sortedColors = list()
    for i in range(len(colors)):
        dist = dist_3d(colors[i], source)
        colorMap = colorMap + (dist, colors[i])

    sorted_by_dist = sorted(colorMap, key=lambda tup: tup[0])

    for (d, c) in sorted_by_dist:
        sortedColors.append(c)

    return sortedColors

假设我的 dist_3d() 函数是正确的并返回一个整数值(它是,并且确实),我做错了什么?我不明白。

【问题讨论】:

  • RGB 三元组之间的颜色距离根本上是错误的,与代码是否正确无关。
  • 是的,我明白这一点。它也与整个应用程序无关......现在它只是一个占位符函数,而我的其他代码片段正在工作。它发生在我脑海中作为占位符的第一个“与颜色有关的事情”中。
  • @mmgp,你为什么这么说?实验室色彩空间可能会更好,但 RGB 并不算太破旧。
  • @MarkRansom 真的吗? RGB 的距离函数是多少?
  • @mmgp: sqrt((r1-r2)**2+(g1-g2)**2+(b1-b2)**2)sqrt 是可选的。

标签: python list sorting tuples


【解决方案1】:

您将colorMap 构建为一个大的单维元组,第一个索引是int。所以你的lambda 被传递了一个int 然后你尝试索引它。

你可能想要一个元组列表:

colorMap = []
...
    dist = dist_3d(colors[i], source)
    colorMap.append((dist, colors[i]))

就颜色排序方法而言,我实际上为此使用了kdtree module,加载了我所有的 RGB 元组。然后我可以向它询问与给定颜色元组最接近的 N 种颜色:

from kdtree import KDTree

colors = [(10,10,10),(250,50,5),(100,50,20)]
query_color = (175, 25, 50)

tree = KDTree.construct_from_data(data)
# query the 2 closest colors
nearest = tree.query(query_point=query_color, t=2)

【讨论】:

  • 非常感谢!我以前从未听说过 k-d 树……令人震惊!随着我越来越多地使用颜色,我很可能最终会使用它。我的应用程序现在按设计工作,但需要注意的是我的 dist_3d 并没有真正做正确的事情,但它作为占位符完美地工作。
【解决方案2】:

错误是因为tupint__getitem__[] 运算符的名称。

但是,您的所有函数似乎都在根据与某个参考颜色的距离对颜色列表进行排序。而且,您已经实现了dist_3d。鉴于它有效,那么对颜色进行排序就简单多了。对它们进行适当的排序:

colors.sort(key=lambda color: dist_3d(color, reference_color))

或作为新列表:

sorted_colors = sorted(unsorted_colors, key=lambda color: dist_3d(color, reference_color))

据我所知,您的函数中不需要所有的元组构建和循环以及其他东西。

【讨论】:

    猜你喜欢
    • 2014-11-07
    • 2014-07-04
    • 2016-11-06
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多