numpy数组中特定轴上的模式

时间:2017-09-07 07:14:38

标签: python arrays numpy frequency

目标

给定一个图像列表,我想创建一个新图像,其中每个像素包含在该位置的输入列表中最常出现的值(R,G,B)。

详情

输入:长度> = 2的列表L.列表中的每个图像/对象都是一个float32 numpy数组,其大小为(288,512,3),其中3表示R / G / B颜色通道。

输出:具有相同形状(288,512,3)的numpy数组。如果没有最频繁出现的像素,则可以返回该位置的任何像素。

尝试

image = stats.mode(L)[0][0]

这种方法的问题在于它单独查看像素的每个R / G / B值。但是如果所有颜色通道都匹配(即R1 = R2,G1 = G2,B1 = B2),我希望像素被认为与另一个像素相同。

1 个答案:

答案 0 :(得分:2)

试试这个:

def packRGB(RGB):
    return np.left_shift(RGB, [0, 8, 16]).sum(-1)

def unpackRGB(i24):
    B = np.right_shift(i24, 16)
    G = np.right_shift(i24, 8) - np.left_shift(B, 8)
    R = i24 - np.left_shift(G, 8) - np.left_shift(B, 16)
    return np.stack([R, G, B]).T

def img_mode(imgs_list, average_singles = True):
    imgs = np.array(imgs_list) #(10, 100, 100, 3)
    imgs24 = packRGB(imgs) # (10, 100, 100)
    mode, count = scipy.stats.mode(imgs24, axis = 0) # (1, 100,100)
    mode, count = mode.squeeze(), count.squeeze()  #(100, 100)
    if average_singles:
        out = np.empty(imgs.shape[1:])
        out[count == 1] = np.rint(np.average(imgs[:, count == 1], axis = 0))
        out[count > 1] = unpackRGB(mode[count > 1])
    else:
        out = unpackRGB(mode)
    return out

编辑:修正了错误,并在其他问题中添加了选项:如果没有模式,则设置为Aany值,由于没有分割或舍入而应该更快。 scipy.stats.mode返回最低值,在这种情况下,它将是具有最低蓝色值的像素。您也可以尝试median,因为mode对输入中的非常小的差异会不稳定(特别是如果只有十个)

这也会比Photoshop的统计函数慢很多(我假设你正在尝试做this之类的事情),因为你想并行化函数以及让它节省时间。