Поговорим про отрисовку разметки:
Эти примитивы помогут показать, что там нашёл/сделал скрипт, пригодятся на презентации, незаменимы в дебаге да и вообще — в процессе разработки.
Как обычно, начинаем с библиотек.
import cv2
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
plt.rcParams['figure.figsize'] = (9.0, 9.0)
# читаем картинку как цветную
image = cv2.imread("Apollo_11_Launch.jpg", cv2.IMREAD_COLOR)
# посмотрим на оригинальную картинку
plt.imshow(image[:,:,::-1])
plt.show()
Нарисуем линию
cv2.line()
сделает это для нас.
img = cv2.line(img, pt1, pt2, color[, thickness[, lineType[, shift]]])
Обязательные аргументы:
img
— понятно, картинка.
pt1
— первая точка по xy.
pt2
— вторая точка по xy.
color
— цвет линии.
Аргументы необязательные:
thickness
— толщина.
linetype
— тип линии (чуть ниже расскажу, что это за зверь).
shift
— количество дробных битов в координатах точки.
Подробнее про line(): ссылка на офф. документацию
К примерам!
# начнём линию с позиции (200,100) и закончим на (400,100)
# цветом жёлтым (Recall that OpenCV uses BGR format)
# толщиной в 5 пикселей
# тип линии — cv2.LINE_AA (AA — AntiAliased)
cv2.line(imageLine, (200, 100), (400, 100), (0, 255, 255),
thickness=5,
lineType=cv2.LINE_AA);
# отобразим результат:
plt.imshow(imageLine[:,:,::-1])
plt.show()
Тип линии
Этот блок текста отсутствует в туториале. Не думаю, что он имеет какую-то практическую пользу в повседневном использовании OpenCV, но — интересно же!
По умолчанию установлен на AA, и его можно переключить на FILLED, LINE_4, и LINE_8.
В сущности — это всё разные алгоритмы растеризации.
Пожалуй, самый читабельный материал я нашёл здесь.
Что до FILLED — c ним я так и не разобрался. Складывается ощущение, что это допустимый параметр, работающий как LINE_4-8; но нужный для иных объектов.
Нарисуем круг
Примерно то же самое.
img = cv2.circle(img, center, radius, color[, thickness[, lineType[, shift]]])
Обязательные аргументы:
img
— всё та же картинка.
center
— координата центра круга.
radius
— радиус егойный.
color
— цвет.
Необязательные (но часто используемые!) аргументы:
thickness
— толщина обводки при положительном значении. При любом негативном — запоняет круг.
lineType
— то же, что и в cv2.line()
Подробнее про circle(): ссылка на офф. документацию
# рисуем круг:
imageCircle = image.copy()
cv2.circle(imageCircle, (900,500), 100, (0, 0, 255),
thickness=5,
lineType=cv2.LINE_AA);
# отобразим результат:
plt.imshow(imageCircle[:,:,::-1])
plt.show()
Нарисуем прямоугольник
img = cv2.rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]])
Обязательные аргументы:
img
— картинка, требующая аннотации.
pt1
— позиция верхнего левого угла прямоугольника.
pt2
— позиция нижнего правого угла прямоугольника.
color
— цвет.
Необязательные (но часто используемые!) аргументы:
thickness
— то же, что в cv.circle()
lineType
— то же, что в cv2.line()
Подробнее про rectangle(): ссылка на офф. документацию
# рисуем прямоугольник:
imageRectangle = image.copy()
cv2.rectangle(imageRectangle, (500, 100), (700,600), (255, 0, 255), thickness=5, lineType=cv2.LINE_8);
# отобразим результат:
plt.imshow(imageRectangle[:,:,::-1])
plt.show()
Добавим текст
img = cv2.putText(img, text, org, fontFace, fontScale, color[, thickness[, lineType[, bottomLeftOrigin]]])
6 обязательных аргументов:
img
— картинка для обработки.
text
— собственно, надпись.
org
— позиция нижнего левого угла текстового блока.
fontFace
— тип шрифта.
fontScale
— масштаб надписи.
color
— цвет.
Пара необязательных:
thickness
— толщина линии; по умолчанию единица.
lineType
— по умолчанию стоит 8 — 8-связная линия. Часто используется cv2.LINE_AA, сглаженная, то есть.
Подробнее про putText(): ссылка на офф. документацию
Со шрифтами — отдельная история. Первый попавшися не засунешь, поддерживаются сугубо шрифты доктора Херши.
# добавим текст:
imageText = image.copy()
text = "Apollo 11 Saturn V Launch, July 16, 1969"
fontScale = 2.3
fontFace = cv2.FONT_HERSHEY_PLAIN
fontColor = (0, 255, 0)
fontThickness = 2
cv2.putText(imageText, text, (200, 700),
fontFace, fontScale, fontColor,
fontThickness, cv2.LINE_AA);
# отобразим результат:
plt.imshow(imageText[:,:,::-1])
plt.show()
Дальше — веселее!
Следующая часть плотно затронет обработку изображений, оставайтесь на связи.