如何用NumPy按图像读取顺序提取并保留唯一RGB颜色?
保留图像像素颜色首次出现顺序的NumPy实现方法
用户原本使用以下代码提取图像中的颜色:
import re from PIL import Image import numpy as np docName = "pal.png" img = Image.open(docName).convert("RGB") # 转换为NumPy数组 npArr = np.array(img) # 将所有像素转为RGB列向量,找出唯一颜色 colours, counts = np.unique(npArr.reshape(-1,3), axis=0, return_counts=1) # 转换为字符串格式 npStr = np.array2string(colours, separator = ", ") pal = re.sub(r"\s?\[|\]\,|]]", "", npStr) print(pal)
使用的示例图为一张包含4种颜色的图片:
该图包含的颜色为:
51, 51, 51
179, 198, 15
255, 204, 0
255, 255, 255
问题在于np.unique会按亮度对颜色重新排序,用户需要保留图像从左上角到右下角的颜色首次出现顺序,期望输出顺序:
51, 51, 51 # 近黑色 255, 255, 255 # 白色 255, 204, 0 # 黄色 179, 198, 15 # 绿色
解决方案
可以通过NumPy的原生参数轻松实现需求,以下是两种可行方法:
方法1:利用np.unique的return_index参数
np.unique提供return_index=True参数,能返回唯一元素在原数组中的首次出现索引,通过对索引排序即可得到按首次出现顺序排列的颜色:
import numpy as np from PIL import Image docName = "pal.png" img = Image.open(docName).convert("RGB") # 将图像数组转为一维RGB列向量 npArr = np.array(img).reshape(-1, 3) # 获取唯一颜色及它们在原数组中的首次出现索引 colours, first_indices = np.unique(npArr, axis=0, return_index=True) # 按首次出现索引排序,得到目标顺序的颜色 sorted_colours = colours[np.argsort(first_indices)] # 格式化输出结果 for c, comment in zip(sorted_colours, ["近黑色", "白色", "黄色", "绿色"]): print(f"{c[0]:3d}, {c[1]:3d}, {c[2]:3d} # {comment}")
方法2:利用视图(view)提升大图像处理效率
对于像素量较大的图像,可以将RGB数组转为一维视图,通过处理一维数组的方式获取首次出现顺序,性能更优:
import numpy as np from PIL import Image docName = "pal.png" img = Image.open(docName).convert("RGB") npArr = np.array(img).reshape(-1, 3) # 将RGB数组转为一维视图(仅针对连续内存的数组) rgb_view = npArr.view(np.dtype((np.void, npArr.dtype.itemsize * 3))) # 获取唯一视图及首次出现索引 _, first_indices = np.unique(rgb_view, return_index=True) # 按索引排序得到目标颜色 sorted_colours = npArr[np.sort(first_indices)] # 输出格式化结果 for c in sorted_colours: print(f"{c[0]:3d}, {c[1]:3d}, {c[2]:3d}")
内容的提问来源于stack exchange,提问作者Ghoul Fool
相关产品推荐
相关产品推荐

