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

如何确保绘制NumPy图像数组时相同像素值始终显示同一颜色

问题描述

我正在对图像序列进行像素处理,遇到一个问题:当绘制包含不同像素值范围的图像时,相同像素值会显示不同颜色。

例如,我有一张包含6种不同像素值(0、2、3、4、5、6)的图像:

代码示例1

import numpy as np
import matplotlib.pyplot as plt
import cv2

image = np.zeros(shape=[256, 256], dtype=np.uint8)

cv2.circle(image, center=(50, 50), radius=10, color=(2, 2), thickness= -1)
cv2.circle(image, center=(100, 100), radius=10, color=(3, 3), thickness= -1)
cv2.circle(image, center=(150, 150), radius=10, color=(4, 4), thickness= -1)
cv2.circle(image, center=(75, 200), radius=10, color=(5, 5), thickness= -1)
cv2.circle(image, center=(200, 89), radius=10, color=(6, 6), thickness= -1)


plt.imshow(image)
plt.show()

输出1

仅含0、2-6像素值的图像

当我向图像中添加两个像素值为7和12的图形后,原有所有像素的颜色都发生了改变:

代码示例2

image = np.zeros(shape=[256, 256], dtype=np.uint8)

cv2.circle(image, center=(50, 50), radius=10, color=(2, 2), thickness= -1)
cv2.circle(image, center=(100, 100), radius=10, color=(3, 3), thickness= -1)
cv2.circle(image, center=(150, 150), radius=10, color=(4, 4), thickness= -1)
cv2.circle(image, center=(75, 200), radius=10, color=(5, 5), thickness= -1)
cv2.circle(image, center=(200, 89), radius=10, color=(6, 6), thickness= -1)
cv2.circle(image, center=(21, 230), radius=5, color=(7, 7), thickness= -1)
cv2.circle(image, center=(149, 250), radius=5, color=(12, 12), thickness= -1)


plt.imshow(image)
plt.show()

输出2

添加7和12像素值后的图像

请问如何确保相同像素值无论图像中存在其他何种像素,都能显示同一颜色?


解决方案

问题出在matplotlib.pyplot.imshow()的默认行为上:它会自动将当前图像的像素值归一化到0-1区间——把图像里的最小像素值对应到颜色映射的起点,最大值对应到终点。当图像的像素值范围变化时,这个归一化的基准也跟着变,导致相同像素值的显示颜色发生偏移。

下面是两种可靠的解决方法:

方法1:固定颜色映射的数值范围

调用imshow()时,通过vmin和vmax参数指定全局的像素值范围,比如你所有图像中可能出现的最小像素是0,最大是12,就固定这个范围:

plt.imshow(image, vmin=0, vmax=12)
plt.show()

这样无论单张图像里有没有包含0或12,所有像素都会按照0-12的区间映射颜色,相同像素值的显示效果完全一致。

方法2:使用离散颜色映射(适合分类场景)

如果你的像素值是类别标签(比如0代表背景,2-12是不同的目标类别),推荐用离散颜色映射,直接给每个像素值绑定固定颜色:

import matplotlib.colors as mcolors

# 列出所有可能出现的像素值
all_pixels = [0, 2, 3, 4, 5, 6, 7, 12]
# 给每个像素值分配对应颜色(可根据需求自定义)
color_list = ['#000000', '#0000FF', '#008000', '#FF0000', '#00FFFF', '#FF00FF', '#FFFF00', '#FFA500']
# 创建离散颜色映射
custom_cmap = mcolors.ListedColormap(color_list)
# 创建边界归一化,确保每个像素值对应唯一颜色区间
custom_norm = mcolors.BoundaryNorm([val - 0.5 for val in all_pixels] + [all_pixels[-1] + 0.5], custom_cmap.N)

plt.imshow(image, cmap=custom_cmap, norm=custom_norm)
plt.show()

这种方式彻底脱离了像素值的数值大小影响,每个指定的像素值都会显示你设定的固定颜色,完全不受其他像素的干扰。


内容的提问来源于stack exchange,提问作者Deep

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 04:52:50