Matplotlib:使用 imread 缺少通道

Matplotlib: Missing channel using imread

当我尝试使用 matplotlib 加载具有三个通道的图像时,当我发出 numpy shape 命令时它只有一个通道。这显示了下图:

这是我使用的代码:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

img = mpimg.imread('dolphin.png')
plt.imshow(img)
plt.show()

img.shape
(320, 500)

我也遵循了matplotlib image tutorial,它使用与上面相同的命令。

使用 opencv 加载图像结果是具有三个通道的图像,正如预期的那样。

import cv2
imgcv = cv2.imread('dolphin.png')
plt.imshow(imgcv)
plt.show()

imgcv.shape
(320, 500, 3)

我正在使用 Python 3.5.6 和 anaconda。

这是 conda list 命令的简短输出:

...
matplotlib                3.0.0
...
opencv3                   3.1.0
...
pillow                    5.2.0
...

我用的原图:

我是不是遗漏了一个包,或者是否有另一个命令来加载 *.png 文件?一切似乎都适用于 *.jpg 图像

据我所知,matplotlib 的 imread 正确读取了图像。如果图像仅包含一个通道,则生成的 numpy 数组将为 2D。如果图像包含 3 或 4 个通道,则 numpy 数组将为 3D。

从你得到的问题中提取海豚图像

plt.imread("https://i.stack.imgur.com/cInHj.png").shape
> (320, 500)

关于matplotlib文档中的stinkbug图像,确实存在一个小问题。您看到的图像也是灰度图像,

plt.imread("https://matplotlib.org/_images/stinkbug.png").shape
> (375, 500)

但是教程声称它是 3 通道图像。从教程的角度来看,这是正确的,因为它从 github 存储库文件夹中的 doc 获取图像。

plt.imread("https://raw.githubusercontent.com/matplotlib/matplotlib/master/doc/_static/stinkbug.png").shape
> (375, 500, 3)

问题是文档是通过 sphinx 和 sphinx-gallery 构建的,此外可能还使用了一些其他库。在此过程中,图像不会以原始格式复制到输出文件夹。此问题已被报告 here,原因尚未完全查明。

无论如何,剩下的悬而未决的问题是,为什么 cv2.imread 给你一个灰度图像的 3D 数组?

来自OpenCV imread documentation

Second argument is a flag which specifies the way image should be read.

  • cv2.IMREAD_COLOR : Loads a color image. Any transparency of image will be neglected. It is the default flag.
  • cv2.IMREAD_GRAYSCALE : Loads image in grayscale mode
  • cv2.IMREAD_UNCHANGED : Loads image as such including alpha channel

Note Instead of these three flags, you can simply pass integers 1, 0 or -1 respectively.

所以在这里你需要自己指定,你想使用哪种模式。

让我们验证一下:

import cv2
import urllib.request as req

dolphinurl ="https://i.stack.imgur.com/cInHj.png"
stinkbugweburl = "https://matplotlib.org/_images/stinkbug.png"
stinkbuggiturl = "https://raw.githubusercontent.com/matplotlib/matplotlib/master/doc/_static/stinkbug.png"

def printshape(url, **kw):
    req.urlretrieve(url, "image_name.png")
    im = cv2.imread("image_name.png", **kw)
    print(im.shape)

printshape(dolphinurl)
printshape(stinkbugweburl)
printshape(stinkbugweburl)

这会打印

(320, 500, 3)
(375, 500, 3)
(375, 500, 3)

而如果您指定灰度,

printshape(dolphinurl,0)
printshape(stinkbugweburl,0)
printshape(stinkbugweburl,0)

它会打印

(320, 500)
(375, 500)
(375, 500)

从这个意义上说,由用户决定他们想如何阅读图像。