python - 在显示转换为 float 的图像时出现奇怪的 matplotlib 行为

标签 python matplotlib

当范围 (0,255) 中的常规 RGB 图像被转换为​​ float ,然后由 matplotlib 显示时,图像显示为负片。如果它被转换为 uint8,它会正确显示(当然)。这让我很难弄清楚发生了什么,因为我不小心将其中一张图像转换为 float 。

我很清楚,当转换为 float 时,图像预计在范围 (0,1) 内,果然,当除以 255 时,显示的图像是正确的。但是,为什么在范围 (0,255) 中转换为 float 的图像会显示为负数?我会期望饱和度(全白)或自动从输入推断范围(并因此正确显示)?如果这些预期的事情中的任何一个发生了,我就能够更快地调试我的代码。我已经包含了重现该行为所需的代码。有谁知道为什么会发生这种情况?

    import numpy as np
    import matplotlib.pyplot as plt
    a = np.random.randint(0,127,(200,400,3))
    b = np.random.randint(128,255,(200,400,3))
    img=np.concatenate((a,b)) # Top should be dark ; Bottom should be light
    plt.imshow(img) # Inverted
    plt.figure()
    plt.imshow(np.float64(img)) # Still Bad. Added to address sascha's comment
    plt.figure()
    plt.imshow(255-img) # Displayed Correctly
    plt.figure()
    plt.imshow(np.uint8(img)) # Displayed Correctly
    plt.figure()
    plt.imshow(img/255.0) # Displays correctly

最佳答案

在源代码中,在 image.py 中,在 AxesImage 类(imshow 返回的)方法 _get_unsampled_image 在绘图过程中的某个时刻被调用。相关代码对我来说是从第 226 行开始的(matplotlib-1.5.3):

if A.dtype == np.uint8 and A.ndim == 3:
    im = _image.frombyte(A[yslice, xslice, :], 0)
    im.is_grayscale = False
else:
    if self._rgbacache is None:
    x = self.to_rgba(A, bytes=False)
    # Avoid side effects: to_rgba can return its argument                        
    # unchanged.                                                                 
    if np.may_share_memory(x, A):
       x = x.copy()
    # premultiply the colors                                                     
    x[..., 0:3] *= x[..., 3:4]
    x = (x * 255).astype(np.uint8)
    self._rgbacache = x

因此检查输入 A 的类型和大小:

if A.dtype == np.uint8 and A.ndim == 3:

在这种情况下没有预处理。否则,如果不检查输入范围,您最终会乘以 255 并转换为 uint8:

x = (x * 255).astype(np.uint8)

而且我们知道如果 x 是从 0 到 255 而不是 0 到 1 会发生什么:

In [1]: np.uint8(np.array([1,2,128,254,255])*255)
Out[1]: array([255, 254, 128,   2,   1], dtype=uint8)

所以光变暗了。这反转图像可能不是我认为你假设的计划行为。

您可以比较每个输入案例从 imshow 返回的对象中 _rgbacache 的值,以观察结果,例如im._rbacache 其中 im = plt.imshow(np.float64(img))

关于python - 在显示转换为 float 的图像时出现奇怪的 matplotlib 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39925420/

相关文章:

python - 如何使用 os windows 在 python 3 中安装 matplotlib

python - 尝试 MNIST 数据集时,tensorflow 和 matplotlib 包出现问题

python - Pydantic V2 `model_validator(mode="包装“)` - How to use ` ModelWrapValidatorHandler`

python - 如何为 GitPython 设置默认分支

python - 使用丢失的文件名引发异常

python - Pandas Dataframe 匹配行之间的日期

python - 如何平滑箭袋图的噪声矢量场

python - matplotlib 图表背景取决于数据

python 中的 Matplotlib.colors.ListedColormap

python - 3D 曲线切线动画