Matplotlib: отсутствует канал с использованием imread

Когда я пытаюсь загрузить изображение, которое имеет три канала, с помощью matplotlib, у меня будет только один канал, когда я выдаю numpy shape команда. Это показывает следующее изображение:

Одноканальное изображение с matplotlib

Вот код, который я использовал:

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)

Трехканальное изображение с cv2

Я использую 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)

В этом смысле, пользователь должен решить, как он хочет читать изображение.

Другие вопросы по тегам