Matplotlib: отсутствует канал с использованием imread - PullRequest
0 голосов
/ 15 ноября 2018

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

One channel image with 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)

Three channel image with cv2

Я использую Python 3.5.6 с anaconda.

Вот краткий вывод команды conda list:

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

ОригиналЯ использовал изображение:

Original dolphin image

Я пропустил пакет или есть другая команда для загрузки файла * .png?Кажется, что все работает с * .jpg images

1 Ответ

0 голосов
/ 15 ноября 2018

На мой взгляд, imread в matplotlib правильно читает на изображении. Если изображение содержит только один канал, результирующий массив будет двумерным. Если изображение содержит 3 или 4 канала, массив Numpy будет 3D.

Взяв изображение дельфина из вопроса, который вы получаете

plt.imread("https://i.stack.imgur.com/cInHj.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 дает вам трехмерный массив для изображения в оттенках серого?

Из OpenCV imread документации :

Второй аргумент - это флаг, который определяет способ чтения изображения.

  • cv2.IMREAD_COLOR: загрузка цветного изображения. Любая прозрачность изображения будет игнорироваться. Это флаг по умолчанию.
  • cv2.IMREAD_GRAYSCALE: загрузка изображения в режиме оттенков серого
  • cv2.IMREAD_UNCHANGED: загружает изображение как таковое, включая альфа-канал

Примечание. Вместо этих трех флагов вы можете просто передать целые числа 1, 0 или -1 соответственно.

Так что здесь вам необходимо указать, какой режим вы хотите использовать.

Давайте проверим:

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)

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

...