Поворот изображения в Python

Как повернуть изображение в Python?

При работе с изображениями довольно часто возникает необходимость повернуть картинку. Рассмотрим варианты поворота изображений на произвольный угол при помощи библиотек Pillow и OpenCV. Предложенный в Pillow метод очень прост, он позволяет осуществить поворот изображения на заданный угол вокруг центральной точки. В OpenCV повернуть изображение «без заморочек» можно только на 90, 180 или 270 градусов. Поворот на любой другой угол в OpеnCV реализован немного сложнее, однако он позволяет самостоятельно выбрать центр поворота, а также поиграться с масштабом картинки и другими настройками. Рассмотрим на примерах, как можно повернуть изображение в Python в обозначенных питоновских библиотеках:

ПОВОРАЧИВАЕМ ИЗОБРАЖЕНИЕ С ПОМОЩЬЮ БИБЛИОТЕКИ PILLOW!

Немного теории

Метод поворота в библиотеке Pillow имеет следующий формат:

rotate ( angle [, expand=False] )

Параметры:

1. angle — числовое значение угла поворота изображения. При указании параметра angle нужно учитывать, что поворот реализуется против часовой стрелки.

2. expand(в переводе с англ. значит «расширение») — это необязательный параметр, по умолчанию принимающий значение False. Зачем нужен этот параметр? Как вы увидите на примере ниже, размеры повернутого изображения могут превышать размеры исходной картинки. В случае, когда параметр expand=False, «лишние» края повернутого изображения обрезаются так, чтобы размеры исходного и повернутого изображения были равны. В противном случае, когда expand=True, размер повернутого изображения увеличивается до размеров, необходимых для отображения полученной картинки целиком.

Примеры поворота изображения с помощью метода rotate() библиотеки Pillow

Пример №1

Дано изображение города размером 550X330px. Нужно повернуть изображение на 30 градусов против часовой стрелки, сохранив исходный размер 550X330px.

повернуть изображение в Python
Исходное изображение
# Импортируем модуль Image 
# для работы с изображениями
from PIL import Image

# открываем изображение
with Image.open('city.jpg') as im:
    # поворачиваем на 30 градусов
    im2 = im.rotate(30)

# выводим результат на экран
im2.show()

#сохраняем повернутое изображение
im2.save('city_new.jpg')

Важно: для корректной работы кода, исходное изображение ‘city.jpg’ должно лежать в той же директории, в которой расположен файл с кодом!

повернуть изображение в Python
Полученный результат

В результате мы видим на экране изображение размером 550x330px, полученное путём поворота исходного изображения на 30 градусов против часовой стрелки. При этом области полученного после поворота изображения, которые «вышли» за границы 550x330px, были подрезаны. Чтобы получить изображение целиком, без обрезанных краев, нужно расширить размер повернутого изображения. Как это сделать, смотрите в примере №2.

Пример№2

Дано изображение города размером 550x330px. Нужно повернуть изображение на 30 градусов против часовой стрелки так, чтобы повернутое изображение было сохранено целиком, без подгонки до исходного размера.

повернуть изображение в Python
Исходное изображение
# Импортируем модуль Image 
# для работы с изображениями
from PIL import Image

# открываем изображение
with Image.open('city.jpg') as im:
    # поворачиваем изображение
    im2 = im.rotate(30, expand=True)

# выводим результат на экран
im2.show()

#сохраняем повернутое изображение
im2.save('city_new2.jpg')

Важно: для корректной работы кода, исходное изображение ‘city.jpg’ должно лежать в той же директории, в которой расположен файл с кодом!

Так как мы передали методу rotate параметр expand=True, то полученное после поворота изображение выводится на экран в полном размере. Если размер исходного изображения был 550x330px, то размер повернутого изображения увеличился до 642×562рх:

повернуть изображение в Python
Фото, повернутое на 30 градусов против часовой стрелки

У нас появился Telegram-канал для изучающих Python! Канал совсем свежий, подпишись одним из первых, ведь вместе «питонить» веселее! 😉 Ссылка на канал: «Кодим на Python!»


ПОВОРАЧИВАЕМ ИЗОБРАЖЕНИЕ С ПОМОЩЬЮ БИБЛИОТЕКИ OPENCV

Поворот изображения на угол, кратный 90 градусам

Начиная с версии 3.2, в OpenCV мы можем повернуть изображение на 90, 180 или 270 градусов посредством одной лишь функции под названием rotate():

cv2.rotate (img, rotateCode [, dst] )

Параметры:

  • img — изображение, которое нужно повернуть
  • rotateCode — содержит «код поворота», который может принимать значения:
    • cv2.ROTATE_90_CLOCKWISE — для поворота на 90 градусов по часовой стрелке
    • cv2.ROTATE_180 — для поворота на 180 градусов
    • cv2.ROTATE_90_COUNTERCLOCKWISE — для поворота на 90 градусов против часовой стрелки, что равно повороту на 270 градусов по часовой стрелке
  • dst(необязательный параметр) — выходное изображение

Пример поворота изображения на 90 градусов с помощью метода rotate() библиотеки OpenCV

Повернем изображение с Эверестом на 90 градусов по часовой стрелке и сохраним полученный файл.

повернуть изображение в Python
Исходное изображение
mport cv2
# открываем изображение
img = cv2.imread('Everest.jpg')

# поворачиваем на 90 градусов
rotated_img = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)

#сохраняем повернутое изображение
cv2.imwrite('Everest_90.jpg', rotated_img)

Важно: для корректной работы кода, исходное изображение ‘Everest.jpg’ должно лежать в той же директории, в которой расположен файл с кодом!

В результате работы кода получим новый файл ‘Everest_90.jpg’ следующего вида:

повернуть изображение в Python
Повернутое на 90 градусов изображение

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

А теперь не просто сохраним файл, но и выведем его на экран прямо в листинге с кодом!

В этом случае нам понадобится подключить библиотеку matplotlib. Она нужна для вывода изображения на экран. Кроме того, так как OpenCV по умолчанию открывает изображения в BGR-формате, а matlotlib использует RGB, то при выводе изображения на экран, изменим его цветовой режим c помощью функции cv2.cvtColor():

import cv2
# импортируем matplotlib для вывода картинки на экран
import matplotlib.pyplot as plt
%matplotlib inline

# откроем изображение
img = cv2.imread('Everest.jpg')

# Поворачиваем картинку на 90 градусов по часовой стрелке
rotated_img = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)

# так как OpenCV по умолчанию открывает файлы в BGR,а для matplotlib нужен RGB, 
# меняем цветовой режим изображения и выводим его на экран
plt.imshow(cv2.cvtColor(rotated_img, cv2.COLOR_BGR2RGB))
plt.show()

# Сохраняем повернутое изображение 
cv2.imwrite('Everest_90.jpg', rotated_img)

Важно: для корректной работы кода, исходное изображение ‘Everest.jpg’ должно лежать в той же директории, в которой расположен файл с кодом!

Результат работы кода: в результате получим изображение, повернутое на 90 градусов по часовой стрелки. Масштаб изображения при повороте не изменился:

повернуть изображение в Python
Вывод изображения в matplotlib

КАК ПОВЕРНУТЬ ИЗОБРАЖЕНИЕ В OPENCV НА ПРОИЗВОЛЬНЫЙ УГОЛ?

Поворот изображений на угол, не кратный 90, в OpenCV реализуется немного сложнее. Однако, при этом способе поворота вы можете самостоятельно определить центр, вокруг которого будет вращаться картинка, указать масштаб повернутого изображения, а также поиграться с другими настройками.

Как работает поворот изображения в OpenCV?

Сначала создается матрица поворота изображения. Для поворота на градус , вокруг центра изображения, матрица поворота будет иметь вид:

повернуть изображение в Python

Если мы захотим повернуть картинку вокруг нецентральной точки, матрица поворота примет более сложный вид. Но мы не будем подробно на этом останавливаться — к счастью, в OpenCV существует функция getRotationMatrix2D(), которая создаст матрицу поворота за нас. После этого нужно вызвать функцию warpAffine(), которая осуществит афинное преобразование картинки на основе переданной в качестве параметра матрицы поворота. В результате афинного преобразования мы получим повернутое на заданный угол изображение.

Форматы функций getRotationMatrix2D и warpAffine:

cv2.getRotationMatrix2D ( (centre_x, centre_y), angle, scale )

Параметры:

(center_x, center_y) — координаты точки, вокруг которой будет поворачиваться изображение

angle — угол поворота, заданный в градусах. При определении угла следует помнить, что изображение в OpenCV поворачивается против часовой стрелки!

scale — масштаб для изменения повернутого изображения. Если scale = 0.5, то при повороте изображение уменьшится в 2 раза.

cv2.warpAffine ( src, M, dsize [, dst] [, flags] [, borderMode] [, borderValue] )

Параметры:

src — изображение, которое нужно повернуть

M — матрица поворота, которую можно получить с помощью функции getRotationMatrix2D

dsize — размер выходного изображениям

dst — (не обязательный параметр) выходное изображение

flags — (не обязательный параметр) комбинация методов интерполяции

borderMode(не обязательный параметр) метод экстраполяции пикселей

borderValue — (не обязательный параметр) значение, используемое в случае постоянной границы

Пример поворота изображения в OpenCV на 30 градусов по часовой стрелке(330 — против часовой):

import cv2

image = cv2.imread("Everest.jpg")
# определяем высоту и ширину изображения
height, width = image.shape[:2]
# определяем координаты центральной точки
center_x, center_y = (width/2, height/2)

# вращаем изображение на 30 градусов по часовой стрелке
M = cv2.getRotationMatrix2D((center_x, center_y), 330, 1.0)
rotated_image = cv2.warpAffine(image, M, (width, height))

# сохраняем полученное изображение в новом файле
cv2.imwrite("Everest_30.jpg", rotated_image)

В результате в директории с кодом появился новый файл под названием «Everest_30.jpg»:

повернуть изображение в Python

Как видно, размер полученного изображения равен размеру исходного, поэтому «лишние» края повернутого изображения обрезаны. Чтобы этого избежать, нужно изменить координаты точки, вокруг которой будет вращаться изображение (center_x и center_y), а также увеличить размер выходного изображения в функции cv2.warpAffine():

import cv2

image = cv2.imread("Everest.jpg")
# определяем высоту и ширину изображения
height, width = image.shape[:2]
# определяем координаты точки поворота
center_x, center_y = (0, height)

# вращаем изображение на 30 градусов по часовой стрелке
M = cv2.getRotationMatrix2D((center_x, center_y), 330, 1.0)
rotated_image = cv2.warpAffine(image, M, (int(width*1.2), height*2))

# сохраняем полученное изображение в новом файле
cv2.imwrite("Everest_30big.jpg", rotated_image)
повернуть изображение в Python
Повернутое изображение

Мы рассмотрели варианты поворота изображения с помощью двух питоновских библиотек Pillow и OpenCV. В тех случаях, когда требуется «просто повернуть картинку без лишних заморочек» и нет необходимости в использовании OpenCV, я рекомендую воспользоваться функцией rotate() библиотеки Pillow. Если же у вас более серьезный графический проект, предполагающий специфические модификации и работу с OpenCV, то выбор в пользу OpenCV очевиден!

Добавить комментарий