【问题标题】:Efficient way to count every pixels of an image of a particular value in Python?在Python中计算特定值图像的每个像素的有效方法?
【发布时间】:2019-03-09 16:56:23
【问题描述】:

我有一个由 7 种不同颜色组成的 RGB 图像。 我想以一种有效的方式计算图像中每种像素类型的数量。因此,如果可能的话,不要在每个像素上循环,至少不要手动(numpy 操作是可以的,因为它更快)

我尝试将它加载到一个 numpy 数组中,这给了我一个 N*M*3 数组,但我想不出一种方法来计算特定值的像素... 有什么想法吗?

谢谢!

【问题讨论】:

  • 您是否正在考虑使用直方图?
  • 能否提供一张图片和一段代码?
  • 七种颜色是固定的吗?您是否需要知道所有颜色通道才能决定哪种颜色?因为例如,如果红色(或其他两个)通道足以区分所有七种颜色,那会让事情变得更容易。
  • @Brenlla 我认为这不是一个直接的欺骗,因为使用的少量颜色可能允许一些优化。

标签: python numpy opencv python-imaging-library


【解决方案1】:

只是部分展平并将np.uniquereturn_counts = Trueaxis = 0一起使用

flat_image = image.reshape(-1, 3)  # makes one long line of pixels
colors, counts = np.unique(flat_image, return_counts = True, axis = 0)

或者一行:

colors, counts = np.unique(image.reshape(-1, 3), 
                           return_counts = True, 
                           axis = 0)

【讨论】:

  • 谢谢!我想出了一个有点相似但更复杂的解决方案......这太完美了!
【解决方案2】:

由于只有七种颜色,因此在合理的假设下,简单的掩蔽将很有竞争力。以下时序适用于 100x100x3 @ 8bit 随机图像:

timings
np.unique 6.510251379047986
masking   0.2401340039796196

请注意,大部分但并非全部的加速都是由于将通道合并为一个通道。

代码:

import numpy as np

def create(M, N, k=7):
    while True:
        colors = np.random.randint(0, 256**3, (k,), dtype=np.int32)
        if np.unique(colors).size == k:
            break
    picture = colors[np.random.randint(0, k, (M, N))]
    RGB = np.s_[..., :-1] if picture.dtype.str.startswith('<') else np.s_[..., 1:]
    return picture.view(np.uint8).reshape(*picture.shape, 4)[RGB]

def f_df(image):
    return np.unique(image.reshape(-1, 3), 
                     return_counts = True, 
                     axis = 0)

def f_pp(image, nmax=50):
    iai32 = np.pad(image, ((0, 0), (0, 0), (0, 1)), mode='constant')
    iai32 = iai32.view(np.uint32).ravel()

    colors = np.empty((nmax+1,), np.uint32)
    counts = np.empty((nmax+1,), int)
    colors[0] = iai32[0]
    counts[0] = 0
    match = iai32 == colors[0]
    for i in range(1, nmax+1):
        counts[i] = np.count_nonzero(match)
        if counts[i] == iai32.size:
            return colors.view(np.uint8).reshape(-1, 4)[:i, :-1], np.diff(counts[:i+1])
        colors[i] = iai32[match.argmin()]
        match |= iai32 == colors[i]
    raise ValueError('Too many colors')



image = create(100, 100, 7)

col_df, cnt_df = f_df(image)
col_pp, cnt_pp = f_pp(image)
#print(col_df)
#print(cnt_df)
#print(col_pp)
#print(cnt_pp)
idx_df = np.lexsort(col_df.T)
idx_pp = np.lexsort(col_pp.T)

assert np.all(cnt_df[idx_df] == cnt_pp[idx_pp])

from timeit import timeit
print('timings')
print('np.unique', timeit(lambda: f_df(image), number=1000))
print('masking  ', timeit(lambda: f_pp(image), number=1000))

【讨论】:

    猜你喜欢
    • 2015-05-09
    • 2020-03-31
    • 2022-12-21
    • 1970-01-01
    • 2015-03-29
    • 2017-11-01
    • 1970-01-01
    • 2020-11-21
    • 1970-01-01
    相关资源
    最近更新 更多