Python - How to sort a list of colors based on the color "distance" from the original color in 3D (r, g, b) space?

Here are the basic steps for the application that I am writing in Python:

  • Create a list of random colors
  • Create a mapping of each of these colors indexed by this color distance to the β€œsource color” in 3D space (r, g, b). (For example, orange (255, 150, 0) is closer to red (255, 0, 0) than blue (0, 0, 100). Currently, I have a list of format tuples (distance, color).
  • Sort the list of tuples based on the calculations I calculated (from lowest to highest).
  • Get a list of sorted colors

Here is my function, and I get the following error: TypeError: the object 'int' does not have the attribute '_getitem _' in the string 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 

Assuming my dist_3d () function is correct and returns an integer value (it is and does), what am I doing wrong? I do not understand.

+4
source share
2 answers

You build your colorMap as a large one-dimensional tuple, with the first index being int . This way your lambda is passed int , and then you try to index it.

You probably need a list of tuples:

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

As for the approach to sorting colors, I actually used the kdtree module for this, loaded with all RGB tuples. Then I can set the specified color tuple for the N nearest colors:

 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) 
+3
source

The error is due to the fact that tup is int . __getitem__ is the name of the [] operator.

But it looks like all your function does is sorts the list of colors, depending on the distance from some reference color. And you already have dist_3d . Given that it works, sorting colors is a lot easier. Sort them in place:

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

or as a new list:

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

It is not necessary that all of these tuples and loop, etc. in your function, as I can say.

+2
source

All Articles