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

为何plt.imshow在图像数值已修改时仍显示原始图像?

问题原因及修复方案

核心问题点

  • plt.imshow自动缩放导致视觉误判
    你生成的img_shrunk像素值被限制在0-30区间,但plt.imshow处理uint8类型灰度图时,默认会将当前图像的像素极值映射为黑白,相当于把0-30的范围拉伸到了0-255的显示区间,视觉上和原图差异极小,让你误以为显示的是原始图像。

  • 灰度映射计算存在uint8溢出隐患
    你用np.arange(256, dtype=np.uint8)创建查找表后直接做减法运算,若img_min大于某个灰度值,uint8的无符号特性会导致减法溢出(比如5-10会得到251),直接导致映射结果错误。

修复后的代码

# Load the image
img = cv2.imread(current_dir + "/img.jpg", cv2.IMREAD_GRAYSCALE)

plt.figure("Original Image", figsize=(6, 6))
plt.subplot(211)
plt.title("Original Image")
plt.imshow(img, "gray")
plt.subplot(212)
hist_full = cv2.calcHist([img], [0], None, [256], [0, 256])
plt.plot(hist_full)

img_min = np.amin(img)
img_max = np.amax(img)
# 转换为float32类型,避免uint8减法溢出
gray_levels = np.arange(256, dtype=np.float32)
gray_levels = np.uint8(
    ((gray_levels - img_min) / (img_max - img_min)) * 30
)
img_shrunk = cv2.LUT(img, gray_levels)

plt.figure("Shrunk Original Image", figsize=(6, 6))
plt.subplot(211)
plt.title("Shrunk Original Image")
# 指定vmin和vmax,强制按0-30的范围显示,还原真实效果
plt.imshow(img_shrunk, "gray", vmin=0, vmax=30)
plt.subplot(212)
hist_full = cv2.calcHist([img_shrunk], [0], None, [256], [0, 256])
plt.plot(hist_full)
plt.show()  # 必须调用该方法才能显示图像

关键说明

  1. 指定vmin=0, vmax=30后,plt.imshow会严格按照0对应黑色、30对应白色渲染,你能直观看到灰度范围压缩后的效果。
  2. 将查找表转换为float32类型计算,彻底避免了uint8无符号减法的溢出问题,保证直方图变化和显示效果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 00:17:46