Python 对大小相同的图像进行像素级比较,找出每个像素最常见的颜色
假设我把一张图片转换成一个数组Python 对大小相同的图像进行像素级比较,找出每个像素最常见的颜色,python,numpy,image-processing,rgb,Python,Numpy,Image Processing,Rgb,假设我把一张图片转换成一个数组 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) 据我所知,如果我要打印(数据1),我会得到一个数组,显示每个给定位置每个像素的RGB值 现在,我想比较所有数组data1、d
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)
据我所知,如果我要打印(数据1),我会得到一个数组,显示每个给定位置每个像素的RGB值
现在,我想比较所有数组data1、data2、data3、data4、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]]
由于位置X1Y1和X2Y1的最常见值为[(0,0255)]
,因此新数组将保存为avg=[(0,0,255),(0,1,0)]
有没有一个功能可以做到这一点?我是否正确理解数组?您可以将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.bincount
和np.argmax
获取最常出现的值,您可以使用np将其应用于堆叠图像阵列的最后一个轴。沿轴应用\u
:
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计数前加上一个值,这样如果其他值都不出现一次,则
argmax
将返回0。什么是(0,1,0)?另一个颜色值,在我写X1Y1时忘记了。编辑我的问题是否有任何代码可以让它输出我自己定义的某种颜色?哦,对不起,我实际上误读了值而不是颜色。你想比较单个的r、g和b值还是整个颜色作为rgb三元组?我想比较整个颜色-所以rgb三元组我用一个解决方案再次更新了我的答案。我留下了原始答案,以防有人发现它有用。很抱歉再次打扰你。你的代码很棒。我只是想知道,如果除了RGB还有其他值,比如CMYK值,你会怎么做?我明白了,你可以把这些值转换成RGB,但是你也可以用CMYK值来做hexificaton吗?