计算 Python 中图像中不同颜色的对象数量
Count the number of objects of different colors in an image in Python
这是一个figure,我想从中计算每种颜色的对象数量。如果不使用 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))
>
Output:
orange: 288
green: 288
pink: 288
blue: 288
虽然达到了目的,但我想知道是否有更高效优雅的方法来解决这个问题。
这是一个基于 scikit-image
:
的更简单的解决方案
代码:
import numpy as np
from skimage import io, morphology, measure
from sklearn.cluster import KMeans
img = io.imread('https://i.stack.imgur.com/du0XZ.png')
rows, cols, bands = img.shape
X = img.reshape(rows*cols, bands)
kmeans = KMeans(n_clusters=5, random_state=0).fit(X)
labels = kmeans.labels_.reshape(rows, cols)
for i in np.unique(labels):
blobs = np.int_(morphology.binary_opening(labels == i))
color = np.around(kmeans.cluster_centers_[i])
count = len(np.unique(measure.label(blobs))) - 1
print('Color: {} >> Objects: {}'.format(color, count))
输出:
Color: [ 254. 253. 253. 255.] >> Objects: 1
Color: [ 255. 144. 36. 255.] >> Objects: 288
Color: [ 39. 215. 239. 255.] >> Objects: 288
Color: [ 255. 38. 135. 255.] >> Objects: 288
Color: [ 192. 231. 80. 255.] >> Objects: 288
备注:
我通过 KMeans
对颜色进行了聚类,以使程序对像素颜色的微小变化具有鲁棒性。
聚类中心的 RGB 坐标经过 around
四舍五入只是为了可视化目的。
我还通过binary_opening
进行了开操作,以去除孤立的像素。
需要从 label
产生的标签数量中减去 1
以仅考虑那些具有所考虑颜色标签的连接区域。
第一行输出明显对应白色背景
这是一个figure,我想从中计算每种颜色的对象数量。如果不使用 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))
> Output:
orange: 288
green: 288
pink: 288
blue: 288
虽然达到了目的,但我想知道是否有更高效优雅的方法来解决这个问题。
这是一个基于 scikit-image
:
代码:
import numpy as np
from skimage import io, morphology, measure
from sklearn.cluster import KMeans
img = io.imread('https://i.stack.imgur.com/du0XZ.png')
rows, cols, bands = img.shape
X = img.reshape(rows*cols, bands)
kmeans = KMeans(n_clusters=5, random_state=0).fit(X)
labels = kmeans.labels_.reshape(rows, cols)
for i in np.unique(labels):
blobs = np.int_(morphology.binary_opening(labels == i))
color = np.around(kmeans.cluster_centers_[i])
count = len(np.unique(measure.label(blobs))) - 1
print('Color: {} >> Objects: {}'.format(color, count))
输出:
Color: [ 254. 253. 253. 255.] >> Objects: 1
Color: [ 255. 144. 36. 255.] >> Objects: 288
Color: [ 39. 215. 239. 255.] >> Objects: 288
Color: [ 255. 38. 135. 255.] >> Objects: 288
Color: [ 192. 231. 80. 255.] >> Objects: 288
备注:
我通过
KMeans
对颜色进行了聚类,以使程序对像素颜色的微小变化具有鲁棒性。聚类中心的 RGB 坐标经过
around
四舍五入只是为了可视化目的。我还通过
binary_opening
进行了开操作,以去除孤立的像素。需要从
label
产生的标签数量中减去1
以仅考虑那些具有所考虑颜色标签的连接区域。第一行输出明显对应白色背景