目标
给定一个图像列表,我想创建一个新图像,其中每个像素包含在该位置的输入列表中最常出现的值(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),我希望像素被认为与另一个像素相同。
答案 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之类的事情),因为你想并行化函数以及让它节省时间。