Как вывести несколько изображений в Python в одном ряду?

Предлагаю решить нехитрую задачку и вывести несколько изображений в Python так, чтобы изображения располагались по 5 штук в ряду. Однако сначала сформулируем ТЗ:
Техническое задание:
Дано: несколько изображений, расположенных в одной папке под названием pic. Некоторые изображения могут быть одинаковыми, но у каждого из них — уникальное имя.
- Получить список с именами изображений, расположенных в папке pic
- Сформировать блок для вывода изображений
- Организовать поочередное чтение изображений из папки pic и их вывод на экран по 5 штук в ряд
Решение:
Для начала убедимся, что в папке «pic» находятся изображения, предназначенные для вывода на экран. Затем, в одной директории с папкой «pic», создадим новый файл для записи скрипта. После этого можно переходить к написанию кода по описанным в ТЗ шагам!
1. Получим список с именами изображений, расположенных в папке pic
В Python есть замечательный библиотека под названием os, обладающая широким функционалом для работы с файлами и папками. Одной из полезных функций библиотеки os является функция listdir(«путь к папке»), позволяющая получить список файлов, расположенных по относительному адресу «путь к папке». Предлагаю применить эту функцию на практике:
# для начала подключим модуль os
import os
# затем получим список с именами всех картинок, находящихся в папке pic
pictures = os.listdir('pic')
Проверим, что на этом этапе хранится в переменной pictures:

Отлично! Список с файлами сформирован! Однако, было бы неплохо упорядочить эти файлы по именам. С этой задачей отлично справляется питоновская функция sorted(). Передадим ей в качестве аргумента наш не упорядоченный список, а на выходе получим список с расположенными по возрастанию именами файлов:
# для начала подключим модуль os
import os
# затем получим список с именами всех картинок, находящихся в папке pic
pictures = os.listdir('pic')
# Упорядочим список
pictures = sorted(pictures)
Выведем содержимое pictures на экран:

2. Создадим блок(фигуру) для вывода изображений
1) Подключим matplotlib.pyplot. Так как мы планируем выводить изображения экран, то нам понадобится библиотека для визуализации графики под названием matplotlib с коллекцией функций pyplot. Импортируем их в верхнем блоке нашей программы под псевдонимом «plt»:
# подключим модуль os
import os
# импортируем matplotlib.pyplot
import matplotlib.pyplot as plt
# затем получим список с именами всех картинок, находящихся в папке pic
pictures = os.listdir('pic')
# отсортируем список
pictures = sorted(pictures)
2) Создадим фигуру для вывода изображений. Теперь нам нужно подготовить блок для вывода изображений. Для этого мы при помощи функции figure из matplotlib.pyplot создадим фигуру размером 16 дюймов на 4 дюйма:
# подключим модуль os
import os
# импортируем matplotlib.pyplot
import matplotlib.pyplot as plt
# получим список с именами всех картинок, находящихся в папке pic
pictures = os.listdir('pic')
# Упорядочим список
pictures = sorted(pictures)
# Создадим фигуру размером 16 на 4 дюйма
pic_box = plt.figure(figsize=(16,4))
3. Напишем цикл для считывания и вывода изображений
Пришла пора перейти к самому интересному — к цикличному считыванию изображений из списка pictures, переводу их в RGB-формат и поочередному выводу каждого изображения в нужной ячейке фигуры pic_box.
Сначала предлагаю взглянуть на сам цикл. А после мы разберем основные моменты кода:
# импортируем библиотеки
import os
import matplotlib.pyplot as plt
import cv2
# получим список с именами всех картинок, находящихся в папке pic
pictures = os.listdir('pic')
# Упорядочим список
pictures = sorted(pictures)
# Создадим фигуру размером 16 на 4 дюйма
pic_box = plt.figure(figsize=(16,4))
# Поочередно считываем в переменную picture имя изображения из списка pictures. В переменную i записываем номер итерации
for i, picture in enumerate(pictures):
# считываем изображение в picture
picture = cv2.imread('pic/' + picture)
# конвертируем BGR изображение в RGB
picture = cv2.cvtColor(picture, cv2.COLOR_BGR2RGB)
# добавляем ячейку в pix_box для вывода текущего изображения
pic_box.add_subplot(2,5,i+1)
plt.imshow(picture)
# отключаем отображение осей
plt.axis('off')
# выводим все созданные фигуры на экран
plt.show()
Предлагаю взглянуть на результат работы цикла:
В результате работы цикла на экран выведены все 9 фото из папки pic в уменьшенном формате, по 5 штук в ряду. Таким образом, задача о том, как вывести несколько изображений в Python решена успешно!

Пояснения по коду:
Обратите внимание, что для работы с изображением мы дополнительно используем библиотеку cv2. Поэтому ее нужно импортировать в верхней части файла с кодом:
import os
import matplotlib.pyplot as plt
# импортируем библиотеку cv2
import cv2
…
После подключения библиотеки cv2 мы при помощи функции cv2.imread( ) можем прочитать изображение, расположенное по адресу «pic/имя_изображения»:
picture = cv2.imread('pic/' + picture)
Так как мы считываем изображение при помощи библиотеки cv2 в цветовом формате BGR, а выводим его на экран с помощью библиотеки matplotlib, использующей RGB формат, возникает необходимость в конвертации изображения из BGR формата в RGB. Для конвертирования формата изображения мы использовали функцию cv2.cvtColor():
cv2.cvtColor(picture, cv2.COLOR_BGR2RGB)
После того, как изображение прочитано и конвертировано в RGB, можно приступить к добавлению изображений в pic_box. Для этого нужно спланировать, сколько рядов и столбцов с изображениями мы желаем сформировать. Я хочу расположить по 5 изображений в 2 ряда, поэтому использую функцию add_subplot() с соответствующими параметрами:
pic_box.add_subplot(2, 5, i+1)
Функция add_subplot() разбивает созданный ранее контейнер pic_box (с размерами 16 на 4 дюйма) на 10 ячеек (2×5) и возвращает оси следующей для заполнения ячейки. В качестве последнего параметра в функции add_subplot() мы используем не i, а i+1, так как нумерация блоков стартует с единицы, а функция enumerate() ведет отсчет с нуля. Таким образом, нулевое изображение мы будем размещать в позиции первой ячейки, 1-е изображение — в позиции 2-ой, .. i-е изображение — в позиции (i+1)-й ячейки.
После этого мы вызываем функцию вывода текущего изображения и отключаем отображение осей:
plt.imshow(picture) plt.axis('off')
В качестве последнего штриха добавим функцию вывода всех созданных фигур на экран:
plt.show()

Итоговый листинг с кодом:
В финальном этапе код будет выглядеть следующим образом:
# импортируем библиотеки
import os
import matplotlib.pyplot as plt
import cv2
# получим список с именами всех картинок, находящихся в папке pic
pictures = os.listdir('pic')
# Упорядочим список
pictures = sorted(pictures)
# Создадим фигуру размером 16 на 4 дюйма
pic_box = plt.figure(figsize=(16,4))
# Поочередно считываем в переменную picture имя изображения из списка pictures. В переменную i записываем номер итерации
for i, picture in enumerate(pictures):
# считываем изображение в picture
picture = cv2.imread('pic/' + picture)
# конвертируем BGR изображение в RGB
picture = cv2.cvtColor(picture, cv2.COLOR_BGR2RGB)
# добавляем ячейку в pix_box для вывода текущего изображения
pic_box.add_subplot(2,5,i+1)
plt.imshow(picture)
# отключаем отображение осей
plt.axis('off')
# выводим все созданные фигуры на экран
plt.show()
Обратите внимание, что для успешной работы приведенного выше кода важно, чтобы предназначенные для вывода изображения находились в папке «pic», а папка «pic» находилась в той же директории, что и файл с кодом. В противном случае нужно поменять на актуальные пути в строках:
pictures = os.listdir('pic') и picture = cv2.imread('pic/' + picture)
Как сделать так, чтобы картинки выводились в одну строку, а не переносились?
Для того, чтобы все картинки вывелись в одной строке, нужно поменять параметры в функции add_subplot(), а точнее строку из итогового кода:
pic_box.add_subplot(2,5,i+1)
заменить на:pic_box.add_subplot(1,N,i+1)
,где N — количество изображений, 1-это число рядов. Например, если нужно вывести 9 изображений, то заменяем на строку:
pic_box.add_subplot(1,9,i+1)