在Python中计算图像中不同颜色对象的数量

在Python中计算图像中不同颜色对象的数量,python,opencv,scipy,python-imaging-library,scikit-image,Python,Opencv,Scipy,Python Imaging Library,Scikit Image,下面是一个示例,我想从中计算每种颜色的对象数。不使用opencv的简单方法是什么 [编辑2]: 我尝试的方法如下: (1) 彩色物体计数 from PIL import Image im = Image.open('./colored-polka-dots.png').getcolors() im.sort(key=lambda k: (k[0]), reverse=True) print('Top 5 colors: {}'.format((im[:5]))) # View non-back

下面是一个示例,我想从中计算每种颜色的对象数。不使用opencv的简单方法是什么

[编辑2]: 我尝试的方法如下: (1) 彩色物体计数

from PIL import Image
im = Image.open('./colored-polka-dots.png').getcolors()
im.sort(key=lambda k: (k[0]), reverse=True)
print('Top 5 colors: {}'.format((im[:5])))

# View non-background colors
color_values = []
for color in im[1:5]:
    color_values.append(color[1])
    arr = np.asarray(color[1]).reshape(1,1,4).astype(np.uint8)
    plt.imshow(arr)
    plt.show() # get top 4 frequent colors as green,blue,pink,ornage

# Create a dict of color names and their corressponding rgba values
color_dict = {}
for color_name,color_val in zip(['green','blue','pink','orange'],color_values):
    color_dict[color_name] = color_val

# Make use of ndimage.measurement.labels from scipy 
# to get the number of distinct connected features that satisfy a given threshold
for color_name,color_val in color_dict.items():
    b = ((img[:,:,0] ==color_val[0]) * (img[:,:,1] ==color_val[1]) * (img[:,:,2] ==color_val[2]))*1
    labeled_array, num_features = scipy.ndimage.measurements.label(b.astype('Int8'))
    print('Color:{} Count:{}'.format(color_name,num_features))
> 输出:

虽然这达到了目的,但我想知道是否有更有效、更优雅的方法来解决这个问题。

下面是一个基于scikit图像的简单解决方案:

代码

将numpy导入为np
从撇渣进口io、形态、测量
从sklearn.cluster导入KMeans
img=io.imread('https://i.stack.imgur.com/du0XZ.png')
行、列、带=img.shape
X=图像重塑(行*列、带)
kmeans=kmeans(n_集群=5,随机状态=0)。拟合(X)
labels=kmeans.labels\重塑(行、列)
对于np.unique中的i(标签):
blobs=np.int(词法.二进制\u打开(标签==i))
color=np.around(kmeans.cluster\u centers\ui])
count=len(np.unique(measure.label(blobs))-1
打印('颜色:{}>>对象:{}'。格式(颜色,计数))
输出

Color:[254.253.253.255.]>>对象:1
颜色:[255.144.36.255.]>>对象:288
颜色:[39.215.239.255.]>>对象:288
颜色:[255.38.135.255.]>>对象:288
颜色:[192.231.80.255.]>>对象:288
备注

  • 我对颜色进行了聚类,使程序对像素颜色的细微变化具有鲁棒性

  • 群集中心的RGB坐标已四舍五入,仅用于可视化目的

  • 为了去除孤立的像素,我还通过执行了一个打开操作

  • 有必要从生成的标签数量中减去
    1
    ,以仅考虑具有所考虑颜色标签的那些连接区域

  • 输出的第一行显然对应于白色背景

下面是一个基于scikit图像的简单解决方案:

代码

将numpy导入为np
从撇渣进口io、形态、测量
从sklearn.cluster导入KMeans
img=io.imread('https://i.stack.imgur.com/du0XZ.png')
行、列、带=img.shape
X=图像重塑(行*列、带)
kmeans=kmeans(n_集群=5,随机状态=0)。拟合(X)
labels=kmeans.labels\重塑(行、列)
对于np.unique中的i(标签):
blobs=np.int(词法.二进制\u打开(标签==i))
color=np.around(kmeans.cluster\u centers\ui])
count=len(np.unique(measure.label(blobs))-1
打印('颜色:{}>>对象:{}'。格式(颜色,计数))
输出

Color:[254.253.253.255.]>>对象:1
颜色:[255.144.36.255.]>>对象:288
颜色:[39.215.239.255.]>>对象:288
颜色:[255.38.135.255.]>>对象:288
颜色:[192.231.80.255.]>>对象:288
备注

  • 我对颜色进行了聚类,使程序对像素颜色的细微变化具有鲁棒性

  • 群集中心的RGB坐标已四舍五入,仅用于可视化目的

  • 为了去除孤立的像素,我还通过执行了一个打开操作

  • 有必要从生成的标签数量中减去
    1
    ,以仅考虑具有所考虑颜色标签的那些连接区域

  • 输出的第一行明显对应于白色背景


您能向我们展示一下您迄今为止所做的尝试吗?post讲述如何仅使用numpy/scipy查找彩色对象的计数。您可以出于自己的目的修改此项,以避免可能的重复。解决办法可能是help@Professor_Joykill,我已添加我的解决方案。你能提出改进意见吗?你能告诉我们你迄今为止所做的尝试吗?post讲述如何仅使用numpy/scipy查找彩色对象的计数。您可以出于自己的目的修改此项,以避免可能的重复。解决办法可能是help@Professor_Joykill,我已添加我的解决方案。你能提出改进建议吗?
orange: 288

green: 288

pink: 288

blue: 288