为何scikit-image加载的图像乘0.5后在matplotlib中显示更亮?
图像调暗操作后反而变亮的问题解决
问题现象
使用scikit-image的io.imread加载图像后,执行以下代码将图像RGB值缩小一半(例如原255变为127.5),但matplotlib显示时,处理后的图像反而比原图更亮(左侧为原图,右侧为处理后图像):
test_image = io.imread("TestProvs2.bmp") test_image = test_image * 0.5 show_map(test_image)
原因分析
io.imread加载的8位位图(如bmp)默认是uint8类型(数值范围0-255),乘以0.5后会自动转换为浮点数类型。而matplotlib在显示浮点数图像时,默认把0.0-1.0作为有效亮度范围,所有大于1.0的数值都会被截断为1.0(纯白)。原本0-255的数值缩小一半后是0-127.5,远超出matplotlib的默认范围,导致所有像素都被映射为高亮,所以图像显示更亮。
解决方案
方案1:先转成0-1范围的浮点数再调整
使用skimage.img_as_float将uint8图像转换为0-1范围的浮点数,再进行亮度调整,匹配matplotlib的显示规则:
from skimage import io, img_as_float import matplotlib.pyplot as plt test_image = io.imread("TestProvs2.bmp") # 转换为0-1范围的浮点数格式 test_image_float = img_as_float(test_image) # 调暗50% test_image_dark = test_image_float * 0.5 plt.imshow(test_image_dark) plt.show()
方案2:调整后转回uint8类型
将调整后的浮点数数值四舍五入后转回uint8类型,保持0-255的数值范围:
import numpy as np from skimage import io import matplotlib.pyplot as plt test_image = io.imread("TestProvs2.bmp") # 调暗后转回uint8,确保数值正确 test_image_dark = np.uint8(np.round(test_image * 0.5)) plt.imshow(test_image_dark) plt.show()
方案3:显示时指定数值范围
在plt.imshow中通过vmin和vmax指定图像的数值范围为0-255,让matplotlib正确映射亮度:
from skimage import io import matplotlib.pyplot as plt test_image = io.imread("TestProvs2.bmp") test_image_dark = test_image * 0.5 # 指定显示的数值范围与原图像一致 plt.imshow(test_image_dark, vmin=0, vmax=255) plt.show()
内容的提问来源于stack exchange,提问作者Thomas Slade
相关产品推荐
相关产品推荐

