对大小相同的图像进行像素级比较,找出每个像素最常见的颜色

2024-09-29 02:16:55 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我把一张图片转换成一个数组

data1= numpy.asarray(source1.png) 
data2= numpy.asarray(source2.png)
data3= numpy.asarray(source3.png)
data4= numpy.asarray(source4.png)
data5= numpy.asarray(source5.png)

据我所知,如果我要print(data1),我会得到一个数组,显示每个给定位置每个像素的RGB值

现在,我想比较所有数组data1, data2, data3, data 4, data5,找出每个像素最常出现的RGB值,并将其作为新数组/图片输出

例如: 对于位置X1Y1和X2Y1,阵列将如下所示

data1= [[0 0 255], [0 1 0]]
data2= [[0 0 255], [0 1 0]]
data3= [[0 0 255], [0 1 0]]
data4= [[0 0 254], [0 1 0]]
data5= [[0 0 254], [0 1 0]]

由于[(0,0,255)]是位置X1Y1和X2Y1的最常见值,因此新数组将保存为avg= [(0, 0, 255), (0, 1, 0)]

有没有一个功能可以做到这一点?我对数组的理解正确吗


Tags: numpypng图片rgb像素数组asarraydata1
1条回答
网友
1楼 · 发布于 2024-09-29 02:16:55

您可以将rgb值转换为单个基数为16的整数,并使用np.unique查找重复项,如下所示:

def rgb_to_base16(rgb):
    return int('0x{0:02X}{1:02X}{2:02X}'.format(*rgb), 16)

def base16_to_rgb(base16):
    return np.array([base16 >> 16, base16 >> 8 & 0xFF, base16 & 0xFF])

def find_most_common(values):
    unique_values, counts = np.unique(values, return_counts=True)
    if len(unique_values) == len(values):
        return [255, 255, 255]
    else:
        return base16_to_rgb(unique_values[np.argmax(counts)])

stacked = np.stack((img_1, img_2, img_3, img_4), axis=2)

hexified = np.apply_along_axis(rgb_to_base16, 
                               axis=-1, 
                               arr=stacked).astype(np.int)

most_common = np.apply_along_axis(lambda values: find_most_common(values), 
                                  axis=-1, 
                                  arr=hexified).astype(np.uint8)

假设您想单独比较r、g和b值,原始答案:

您可以使用np.bincountnp.argmax获得最常出现的值,您可以使用np.apply_along_axis将其应用于堆叠图像阵列的最后一个轴:

stacked = np.stack((img_1, img_2, img_3), axis=3)
most_common = np.apply_along_axis(lambda x: np.argmax(np.bincount(x)), axis=-1, arr=stacked).astype(np.uint8)

请注意,如果r、g和b中的任何一个都不出现一次以上,并且np.bincount仅适用于非负整数,则此方法将返回每个r、g和b的最低值

如果要为r、g和b中的每一个返回自定义值,如果它们都不重复,则可以将此行为定义为函数而不是lambda表达式:

def find_most_common(values):
    most_common = np.argmax(np.insert(np.bincount(values), 0, 1))
    if most_common == 0:
        return 125
    else:
        return most_common - 1

most_common = np.apply_along_axis(lambda values: find_most_common(values), axis=-1, arr=stacked).astype(np.uint8)

在这里,我们在bin计数前加上一个1,这样argmax如果其他值都不出现一次以上,则返回0

相关问题 更多 >