Python - 计算独特元素的频率

Python - Compute frequency of unique elements

我在字典中有一堆独特的 RGB 颜色 key: 'Color' 和目标图像中每种 RGB 颜色的 list

我想:

最后我希望实现更新frequency['Frequency']所以在过程结束时dict: Frequency会包含一堆对(Color,Frequency)。然后我想从低到高的频率排序并打印每对 RGB 颜色 + 出现次数。

到目前为止,这是我的代码:

from PIL import Image

im = Image.open('test.png').convert('RGB')
im2 = Image.open('test2.png').convert('RGB')

unique_colors = set()

def get_unique_colors(img):
    for i in range(0,img.size[0]):
        for j in range(0,img.size[1]):
            r,g,b = img.getpixel((i,j))
            unique_colors.add((r,g,b))
    return(unique_colors)

unique_colors = get_unique_colors(im)

all_colors = []

def get_all_colors(img):
    for i in range(0,img.size[0]):
        for j in range(0,img.size[1]):
            r,g,b = rgb_im.getpixel((i,j))
            all_colors.append((r,g,b))
    return(all_colors)

all_colors = get_all_colors(im2)

frequency = {'Color': list(unique_colors), 'Frequency': [0 for x in range(0,len(unique_colors))]}

我面临很多问题,因为我缺乏操作字典的能力,在这种情况下使用字典来存储这样的数据真的合适吗?

我认为您的字典创建不正确。如果你像下面这样创建你的 dict,你可以有一个 dict(color, frequency) 结构:

frequency = dict(zip(list(unique_colors), [0 for x in range(0,len(unique_colors))]))

zip函数将两个列表放在一起作为键值对。如果 unique_colors={'red','green','blue'},这将创建一个像这样的字典:

frequency = {'red': 0, 'green': 0, 'blue': 0}

之后您可以将字典更新为:

frequency['red']+=1

然后字典变为 {'red': 1, 'green': 0, 'blue': 0}

使用字典是个好主意,事实证明标准库已经用 collections.Counter 为您完成了一些工作,它计算了您放入其中的内容。通过所有像素位置将 itertools.product 添加到 运行,然后将其放入自定义像素迭代器中,您将得到

from PIL import Image
import collections
import itertools

def iter_colors(img):
    coordinates = itertools.product(range(img.size[0]), range(img.size[1]))
    return map(img.getpixel, coordinates)

im = Image.open('test.png').convert('RGB')
im2 = Image.open('test2.png').convert('RGB')

unique_colors = set(iter_colors(im))
print("unique", unique_colors)

frequencies = collections.Counter((rgb for rgb in iter_colors(im2)
    if rgb in unique_colors))
print("frequencies", frequencies)

# counter keys are rgb tuples and velue is number of times seen
rgbs_sorted = list(sorted(frequencies))
print("im2 rgb values sorted by value:", ", ".join(
    str(rgb) for rgb in rgbs_sorted))
print("im2 rgb values sorted by most common:", ", ".join(
    str(rgb) for rgb in frequencies.most_common()))
print("one rgb value", frequencies[rgbs_sorted[0]])

在测试图像上,这返回了

unique {(0, 0, 255), (191, 191, 191), (0, 255, 0)}
frequencies Counter({(191, 191, 191): 45, (0, 0, 255): 44, (0, 255, 0): 32})
im2 rgb values sorted by value: (0, 0, 255), (0, 255, 0), (191, 191, 191)
im2 rgb values sorted by most common: ((191, 191, 191), 45), ((0, 0, 255), 44), ((0, 255, 0), 32)
one rgb value 44