Matplotlib: отсутствует канал с использованием 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, в котором используются те же команды, что и выше.
Загрузка изображения с помощью 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 изображениями
1 ответ
На мой взгляд, Matplotlib's imread
правильно читает на картинке. Если изображение содержит только один канал, результирующий массив будет двумерным. Если изображение содержит 3 или 4 канала, массив Numpy будет 3D.
Принимая изображение дельфина из вопроса, который вы получаете
plt.imread("https://stackru.com/images/58df611d8526bf6fb61ec96629ec55e28a1dadf0.png").shape
> (320, 500)
Что касается образа stinkbug из документации matplotlib, то здесь действительно есть небольшая проблема. Изображение, которое вы видите, также является серым,
plt.imread("https://matplotlib.org/_images/stinkbug.png").shape
> (375, 500)
Однако в учебнике утверждается, что это 3-канальное изображение. Это правильно с точки зрения учебника, потому что оно берет изображение с doc
в папке хранилища github.
plt.imread("https://raw.githubusercontent.com/matplotlib/matplotlib/master/doc/_static/stinkbug.png").shape
> (375, 500, 3)
Проблема в том, что документация строится через sphinx и sphinx-gallery и, кроме того, может использовать некоторые другие библиотеки. При этом изображение не копируется в исходном формате в выходную папку. Об этой проблеме уже сообщалось, причина еще не полностью устранена.
В любом случае остаётся открытым вопрос: почемуcv2.imread
дать вам массив 3D для изображения в оттенках серого?
От OpenCVimread
документация:
Второй аргумент - это флаг, который определяет способ чтения изображения.
- cv2.IMREAD_COLOR: загружает цветное изображение. Любая прозрачность изображения будет игнорироваться. Это флаг по умолчанию.
- cv2.IMREAD_GRAYSCALE: загружает изображение в режиме градаций серого
- cv2.IMREAD_UNCHANGED: загружает изображение как таковое, включая альфа-канал
Примечание. Вместо этих трех флагов вы можете просто передать целые числа 1, 0 или -1 соответственно.
Поэтому здесь вам нужно указать, какой режим вы хотите использовать.
Давайте проверим:
import cv2
import urllib.request as req
dolphinurl ="https://stackru.com/images/58df611d8526bf6fb61ec96629ec55e28a1dadf0.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)
В этом смысле, пользователь должен решить, как он хочет читать изображение.