Python统计图像唯一颜色:与在线工具结果差异及实现疑问
图像唯一颜色统计结果差异问题
我需要用Python统计图像中的唯一颜色,测试多款在线工具后得到两种不同结果,测试图为JPEG格式。4款工具里3款给出结果83,847,1款给出43,162;我用两种Python方法统计均得到43,162,现疑惑结果差异的原因、哪种结果正确,若83,847为预期值,该如何用Python实现。
工具统计情况
- 给出83,847的工具:Pixspy、PlanetCalc、canvas-pixel-color-counter
- 给出43,162的工具:imgonline
我的Python实现代码
方法1(基于NumPy)
img = Image.open(os.path.join(IMAGE_FOLDER_PATH, image)) x = np.array(img) # 统计唯一颜色 _, counts = np.unique(x.reshape(-1, x.shape[-1]), axis=0, return_counts=True) counts_size = counts.size print(f"Unique Color: {counts_size}")
方法2(基于集合)
img = Image.open(os.path.join(IMAGE_FOLDER_PATH, image)) unique_colors = set() image_width, image_height = img.size for i in range(image_width): for j in range(image_height): pixel = img.getpixel((i, j)) unique_colors.add(pixel) unique_colors_count = len(unique_colors)
差异原因
核心在于JPEG图像的色彩空间解码方式不同:
- PIL/Pillow默认会将JPEG从原始的YCbCr色彩空间转换为RGB格式。JPEG压缩时采用的色度子采样(常见4:2:0)会让相邻像素共享色度信息,转RGB后这些像素会合并为相同的RGB值,导致唯一颜色数量减少。
- 多数给出83,847的在线工具(如基于Canvas渲染的工具)会直接处理JPEG的YCbCr原始采样数据,没有经过RGB转换,因此保留了更多原始采样的颜色值,统计出的唯一颜色数量更多。
结果正确性说明
两种结果都不能直接定义为"正确",取决于你的统计目标:
- 若需要统计图像最终显示的RGB颜色,则43,162是正确结果,你的现有Python代码已经实现。
- 若需要统计JPEG文件原始存储的YCbCr采样颜色,则83,847是对应结果。
实现83,847结果的Python代码
直接以YCbCr模式读取图像并统计即可:
基于NumPy的实现
from PIL import Image import numpy as np import os img = Image.open(os.path.join(IMAGE_FOLDER_PATH, image)).convert('YCbCr') x = np.array(img) _, counts = np.unique(x.reshape(-1, x.shape[-1]), axis=0, return_counts=True) print(f"Unique Color (YCbCr): {counts.size}")
基于集合的实现
from PIL import Image import os img = Image.open(os.path.join(IMAGE_FOLDER_PATH, image)).convert('YCbCr') unique_colors = set() image_width, image_height = img.size for i in range(image_width): for j in range(image_height): pixel = img.getpixel((i, j)) unique_colors.add(pixel) print(f"Unique Color (YCbCr): {len(unique_colors)}")
内容的提问来源于stack exchange,提问作者Ecko
相关产品推荐
相关产品推荐

