Python 查找Numpy中排名前10(n)的RGB颜色
我有一个吃几秒钟的函数。函数应该返回给定图像中的前(n)种颜色。必须对返回进行排序,以便我可以使用第一、第二、第三个最上面颜色的rgb值 在第一方面,我有一个PIL.Image对象,我在x,y坐标上循环,并在defaultdict中计算它。我已经用一个Numpy数组替换了我项目中的PIL对象,这给了我很大的提升,但我不知道在这种情况下如何替换defaultdict 我当前的解决方案:Python 查找Numpy中排名前10(n)的RGB颜色,python,numpy,image-processing,colors,numpy-slicing,Python,Numpy,Image Processing,Colors,Numpy Slicing,我有一个吃几秒钟的函数。函数应该返回给定图像中的前(n)种颜色。必须对返回进行排序,以便我可以使用第一、第二、第三个最上面颜色的rgb值 在第一方面,我有一个PIL.Image对象,我在x,y坐标上循环,并在defaultdict中计算它。我已经用一个Numpy数组替换了我项目中的PIL对象,这给了我很大的提升,但我不知道在这种情况下如何替换defaultdict 我当前的解决方案: import numpy as np from scipy import misc # for example
import numpy as np
from scipy import misc # for example Image
from collections import defaultdict
def count_colors(img, n):
img = img.reshape(-1, img.shape[-1])
color = defaultdict(int)
for pixel in img:
rgb = (pixel[0], pixel[1], pixel[2])
color[rgb] += 1
sorted_color = sorted(color.items(), key=lambda k_v: k_v[1], reverse=True)
sorted_color = sorted_color[:n]
return sorted_color
img = misc.face() # example Numpy Image array
top_colors = count_colors(img, n=5)
display(top_colors)
[((9, 9, 9), 1062),
((10, 10, 10), 700),
((8, 8, 8), 668),
((9, 7, 8), 586),
((9, 7, 10), 579)]
电流输出:
import numpy as np
from scipy import misc # for example Image
from collections import defaultdict
def count_colors(img, n):
img = img.reshape(-1, img.shape[-1])
color = defaultdict(int)
for pixel in img:
rgb = (pixel[0], pixel[1], pixel[2])
color[rgb] += 1
sorted_color = sorted(color.items(), key=lambda k_v: k_v[1], reverse=True)
sorted_color = sorted_color[:n]
return sorted_color
img = misc.face() # example Numpy Image array
top_colors = count_colors(img, n=5)
display(top_colors)
[((9, 9, 9), 1062),
((10, 10, 10), 700),
((8, 8, 8), 668),
((9, 7, 8), 586),
((9, 7, 10), 579)]
有没有真正的简单方法来解决这个问题?方法#1
我们可以使用来获得每种唯一颜色的计数,然后为紧凑的矢量化解决方案获取其中的前N种颜色的计数-
def topN_colors(img, N):
unqc,C = np.unique(img.reshape(-1,img.shape[-1]), axis=0, return_counts=True)
topNidx = np.argpartition(C,-N)[-N:]
return unqc[topNidx], C[topNidx]
# https://stackoverflow.com/a/57236217/ @tstanisl
def scalarize(x):
# compute x[...,2]*65536+x[...,1]*256+x[...,0] in efficient way
y = x[...,2].astype('u4')
y <<= 8
y +=x[...,1]
y <<= 8
y += x[...,0]
return y
def topN_colors_v2(img, N):
img2D = scalarize(img)
unq,idx,C = np.unique(img2D, return_index=True, return_counts=True)
topNidx = np.argpartition(C,-N)[-N:]
return img.reshape(-1,img.shape[-1])[idx[topNidx]], C[topNidx]
方法#2
另一个主要基于24位整数2D缩减,以获得更高效的解决方案-
def topN_colors(img, N):
unqc,C = np.unique(img.reshape(-1,img.shape[-1]), axis=0, return_counts=True)
topNidx = np.argpartition(C,-N)[-N:]
return unqc[topNidx], C[topNidx]
# https://stackoverflow.com/a/57236217/ @tstanisl
def scalarize(x):
# compute x[...,2]*65536+x[...,1]*256+x[...,0] in efficient way
y = x[...,2].astype('u4')
y <<= 8
y +=x[...,1]
y <<= 8
y += x[...,0]
return y
def topN_colors_v2(img, N):
img2D = scalarize(img)
unq,idx,C = np.unique(img2D, return_index=True, return_counts=True)
topNidx = np.argpartition(C,-N)[-N:]
return img.reshape(-1,img.shape[-1])[idx[topNidx]], C[topNidx]
是的,它是有效的,你的第二种方法非常快。我真的需要按降序排列。您的范围(-N,0)是关键。我修改了返回到:return img.reformate(-1,img.shape[-1])[idx[topNidx][::-1],C[topNidx][::-1]tbh,我没有得到scalarize函数。你永远不会停止学习:)