You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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种颜色的图片:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 02:40:25