为何matplotlib读取的图像部分是0-255整数、部分是0.0-1.0浮点数?
问题描述
我编写了一个处理图像的Python脚本,第一张图像可正常运行,但第二张完全无法运行。
脚本内容如下:
import matplotlib.pyplot as plt import matplotlib.image as mpimg import numpy as np image = mpimg.imread('test.jpg') # Grab the x and y size and make a copy of the image ysize = image.shape[0] xsize = image.shape[1] color_select = np.copy(image) # Define color selection criteria ###### MODIFY THESE VARIABLES TO MAKE YOUR COLOR SELECTION red_threshold = 200 green_threshold = 200 blue_threshold = 200 ###### rgb_threshold = [red_threshold, green_threshold, blue_threshold] # Do a boolean or with the "|" character to identify # pixels below the thresholds thresholds = (image[:,:,0] < rgb_threshold[0]) \ | (image[:,:,1] < rgb_threshold[1]) \ | (image[:,:,2] < rgb_threshold[2]) color_select[thresholds] = [0,0,0] plt.imshow(color_select)
排查后发现第二张图像失效的原因:
我通过以下代码查看图像通道的像素值范围:
print("Red channel - Min:", np.min(image[:,:,0]), "Max:", np.max(image[:,:,0])) print("Green channel - Min:", np.min(image[:,:,1]), "Max:", np.max(image[:,:,1])) print("Blue channel - Min:", np.min(image[:,:,2]), "Max:", np.max(image[:,:,2]))
第一张图像的通道范围:
Red channel - Min: 0 Max: 255 Green channel - Min: 10 Max: 255 Blue channel - Min: 0 Max: 255
第二张失效图像的通道范围:
Red channel - Min: 0.0 Max: 1.0 Green channel - Min: 0.0 Max: 1.0 Blue channel - Min: 0.0 Max: 1.0
疑问:为何部分图像像素值范围是0-255,部分是0.0-1.0?
原因解释
这是mpimg.imread()的读取规则决定的:
- 读取JPG、8位PNG这类常见的8位位图格式时,像素值会以
uint8整数类型加载,范围是0-255——因为8位二进制恰好能表示256个亮度等级(从0到255)。 - 读取16位PNG、浮点格式图像,或是部分经过特殊处理存储的图像时,
mpimg.imread()会自动将像素值归一化到0.0-1.0的浮点数区间,对应float32或float64类型。 - 还有些科研领域的图像本身就采用浮点格式存储,读取后自然呈现0-1的范围。
你的脚本里阈值设为200,对于0-1范围的图像来说,所有像素值都远小于200,导致thresholds全为True,最终整个图像被改成黑色,所以看起来完全失效。
解决方案
读取图像后统一像素值范围,就能兼容两种类型的图像:
- 统一为0-255的整数范围:
if image.dtype in (np.float32, np.float64): image = (image * 255).astype(np.uint8)
- 统一为0-1的浮点范围:
if image.dtype == np.uint8: image = image.astype(np.float32) / 255.0
内容的提问来源于stack exchange,提问作者KansaiRobot
相关产品推荐
相关产品推荐

