在Python中,将图像中的颜色映射到颜色列表中最接近的成员

2022-04-19 00:00:00 python numpy indexing colors rgb

问题描述

我有一个19种颜色的列表,它是一个大小为(19,3)的数字数组:

colors = np.array([[0, 0, 0], 
[0, 0, 255], 
[255, 0, 0], 
[150, 30, 150], 
[255, 65, 255], 
[150, 80, 0], 
[170, 120, 65], 
[125, 125, 125], 
[255, 255, 0], 
[0, 255, 255], 
[255, 150, 0], 
[255, 225, 120], 
[255, 125, 125], 
[200, 100, 100], 
[0, 255, 0], 
[0, 150, 80], 
[215, 175, 125], 
[220, 180, 210], 
[125, 125, 255]
])
现在我有了一个图像(大小为(1024,1024,3)的NumPy数组),其颜色与上面定义的所有颜色都有些接近或相等。然而,我的程序要求图像只能包含上面的颜色,而不能包含接近的颜色,因此我需要将数组中每个像素的颜色转换为19种颜色中最接近的颜色。

我在Python - Find the closest color to a color, from giving list of colors:

看到了一个函数,可以从只使用Numpy的一组颜色中查找最接近的颜色(它工作得很好):

def closest_color(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

使用此函数,我可以从预定义列表中找到最接近单一颜色的颜色,但在我的问题中,我没有想要更改的单一颜色,而是整个图像(1024x1024像素的颜色)。使用NumPy来解决我的问题的这个函数(或使用任何更好的函数),最有效的方式是什么?我希望尽可能减少for循环的数量,因为我总共需要处理30,000个大小为1024 x 1024的图像。

谢谢!


解决方案

我们可以使用Cython-powered kd-tree for quick nearest-neighbor lookup,从而实现我们的分类/分类-

from scipy.spatial import cKDTree

# Input image : img
out_img = colors[cKDTree(colors).query(img,k=1)[1]]

相关文章