Показ изображений и цветовых сеток

На этом занятии мы увидим, как с помощью matplotlib можно выводить изображения и цветовые сетки. Начнем с показа изображений. Для этого в пакете имеется специальная функция:

imshow()

которая на входе ожидает либо двумерный numpy массив, либо PIL-изображение.

Давайте представим, что у нас есть изображение в одном из известных форматов (JPEG, PNG, GIF, BMP и т.д.), хранящийся в файле:

panda.jpg

Чтобы его загрузить, а потом отобразить функцией imshow(), необходимо воспользоваться модулем для загрузки изображений PIL:

from PIL import Image

И, затем, из модуля Image вызвать функцию open():

img = Image.open('panda.jpg')

Все, у нас в программе сформировался объект PIL-изображения из файла panda.jpg. Далее, нам достаточно вызвать функцию imshow() и передать первым параметром это изображение:

import matplotlib.pyplot as plt
fig = plt.figure(figsize=(6, 4))
ax = fig.add_subplot()
ax.imshow(img)
 
plt.show()

Увидим следующий результат:

Также можно загрузить изображение из формата PNG в градациях серого:

img = Image.open('panda_gray.png')

Соответственно, увидим изображение уже в градациях серого:

И здесь возникает вопрос. Откуда функция imshow() «знает» как раскрашивать точки загруженного изображения? Может быть этот вопрос покажется странным? Давайте я его конкретизирую и сделаю следующее. Сформирую произвольный двумерный массив из случайных целых чисел:

data = np.random.randint(0, 255, (100, 100))
ax.imshow(data)

и отобразим его с помощью функции imshow(). Увидим следующее:

Здесь массив data содержит тот же диапазон чисел [0; 255], что и массив img. Но для панды мы видим раскраску в градациях серого, а для data совсем другие цвета. Так как же функция imshow() определяет цвет для конкретного числового значения?

Все просто. Во всех случаях используется специальная таблица (диапазон) соответствия чисел и цветов. Например, в matplotlib имеются заранее определенные наборы таких таблиц. Они называются цветовыми картами.

Для произвольных двумерных данных мы можем указывать желаемую цветовую карту через параметр cmap:

ax.imshow(data, cmap='plasma')

В результате, раскраска чисел будет уже другой:

Но изображения, загружаемые из графических файлов с помощью модуля PIL, уже содержат в себе цветовую палитру, где каждому числу поставлен в соответствие определенный цвет. И изменить эту палитру через параметр cmap уже не получится. Например, строчки:

img = Image.open('panda_gray.png')
ax.imshow(img, cmap='plasma')

Все равно выведут изображение в градациях серого. Но, если преобразовать объект PIL в двумерный массив numpy:

img = np.array(Image.open('panda_gray.png'))

то при отображении уже будет применяться текущая цветовая карта:

ax.imshow(img)  # цветное изображение
ax.imshow(img, cmap='gray')  # изображение в градациях серого

Функция imshow() имеет следующие параметры:

Параметр

Описание

x (первый аргумент)

Двумерный массив numpy или PIL-изображения в формате (M, N), RGB: (M, N, 3), RGBA: (M, N, 4). Каждое число формата RGB или RGBA может быть целым [0; 255] или вещественным [0; 1].

cmap

Цветовая карта

aspect

Соотношение сторон. Или вещественное число или одно из значений: {'equal', 'auto'}

interpolation

Алгоритм интерполяции пикселей (данных) при масштабировании изображения. Поддерживаются значения: 'none',  'nearest',  'bilinear',  'bicubic', 'spline16', 'spline36', 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric', 'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc', 'lanczos'

alpha

Степень прозрачности при отображении данных (параметр игнорируется для RGBA изображений).

origin

Расположение начала координат при отображении данных: {'upper', 'lower'}. Где 'upper' – верхний левый угол, а 'lower' – нижний левый угол.

Например, можно реализовать следующее отображение пикселей изображения панды:

b1 = ax.imshow(img, origin='lower', cmap='gray', aspect='equal', alpha=0.7)
fig.colorbar(b1, ax=ax)

Здесь с помощью функции colorbar() дополнительно сделан вывод цветовой карты для данных системы координат ax.

Функция pcolormesh()

Если требуется отобразить двумерный массив из числовых значений в виде цветовой сетки, то для этого можно воспользоваться еще одной функцией pcolormesh(), которая работает несколько быстрее imshow(), но отображает данные без учета соотношения сторон и может работать только с двумерными массивами, то есть, изображения в форматах RGB или RGBA будут приводить к ошибке.

В самом простом варианте ее можно вызвать, следующим образом:

data = np.random.randint(0, 255, (10, 10))
ax.pcolormesh(data)

Получим обычное отображение данных в виде плоского изображения с цветовой картой по умолчанию:

При необходимости можно настроить способ отображения цветовой сетки, используя следующие параметры функции pcolormesh():

Параметр

Описание

x (первый аргумент)

Двумерный массив numpy в формате (M, N).

cmap

Используемая цветовая карта

edgecolors

Цвет границы вокруг каждой клетки цветовой сетки.

alpha

Степень прозрачности изображения.

shading

Схема заливки: {'flat', 'gouraud'}

snap

Привязка сетки к границам клеток (по умолчанию False)

Например, можно сделать такое отображение данных в виде цветовой стеки:

b = ax.pcolormesh(data, edgecolors='black', cmap='plasma')
fig.colorbar(b, ax=ax)

Мы здесь дополнительно еще вывели полосу выбранной цветовой схемы.

Вот так в пакете matplotlib можно делать отображение изображений и произвольных двумерных данных в виде цветовой сетки.