Работаем с OpenCV на Python | OTUS
⚡ Открываем подписку на курсы!
Проходите параллельно 3 онлайн-курса в месяц по цене одного.
Подробнее

Курсы

Программирование
Flutter Mobile Developer Подготовка к сертификации Oracle Java Programmer (OCAJP)
-8%
Алгоритмы и структуры данных
-12%
Web-разработчик на Python
-11%
Архитектура и шаблоны проектирования
-14%
JavaScript Developer. Basic Супер-интенсив «СУБД в высоконагруженных системах»
-18%
iOS-разработчик. Базовый курс
-23%
Разработчик на Spring Framework
-23%
Python Developer. Basic
-16%
C# ASP.NET Core разработчик
-18%
Разработчик программных роботов (RPA) на базе UiPath и PIX
-6%
JavaScript Developer. Professional
-9%
Android Developer. Basic
-10%
Java Developer. Professional Разработчик C# AWS для разработчиков Highload Architect Reverse-Engineering. Professional CI/CD Vue.js разработчик Agile Project Manager Нереляционные базы данных Супер - интенсив по паттернам проектирования Супер - интенсив по Kubernetes Advanced Fullstack JavaScript developer
Инфраструктура
PostgreSQL
-10%
IoT-разработчик
-12%
Administrator Linux. Professional
-11%
Базы данных
-19%
Administrator Linux.Basic
-18%
Супер-интенсив «СУБД в высоконагруженных системах»
-18%
Супер-интенсив "SQL для анализа данных"
-16%
Software Architect
-12%
Сетевой инженер AWS для разработчиков Highload Architect Разработчик голосовых ассистентов и чат-ботов Внедрение и работа в DevSecOps Администратор Linux. Виртуализация и кластеризация Нереляционные базы данных Супер-практикум по использованию и настройке GIT
Специализации Курсы в разработке Подготовительные курсы
+7 499 938-92-02

Работаем с OpenCV на Python

CV_Deep_20.3-5020-851e75.png

OpenCV — известная библиотека машинного обучения и компьютерного зрения, имеющая открытый исходный код. Она включает в себя более 2500 алгоритмов, среди которых есть и классические, и современные. В принципе, OpenCV имеет интерфейсы на разных языках программирования (Java, C++ и Matlab), но сегодня мы поработаем с Python.

На установке долго останавливаться не будем, т. к. подробные инструкции есть здесь (для Windows) и здесь (для Linux).

Импорт и просмотр изображений

Импорт и просмотр изображений осуществляется следующим образом:

import cv2
image = cv2.imread("./путь/к/изображению.расширение")
cv2.imshow("Image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Замечание 1: во время чтения способом, который представлен выше, изображение находится не в RGB, а в BGR. Поначалу это, может, и неважно, но знать стоит. Тут есть несколько путей решения вопроса: 1. Поменяйте местами первый канал (R — красный) с третьим каналом (B — синий). В результате красный цвет будет не (255,0,0), а (0,0,255). 2. Поменяйте непосредственно цветовое пространство на RGB с помощью следующего кода:

rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

Замечание 2: если вы захотите закрыть окно, в котором изображение отображается, нажмите любую клавишу. Дело в том, что используя кнопку закрытия окна, можно столкнуться с подвисанием.

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

import cv2
def viewImage(image, name_of_window):
    cv2.namedWindow(name_of_window, cv2.WINDOW_NORMAL)
    cv2.imshow(name_of_window, image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

Кадрирование

Посмотрите на эту картинку:

1_JOqAtM92uNHBxJ9uRAyKtg_1-20219-00ef21.jpeg

А теперь на то, как она будет выглядеть после кадрирования:

1_UuTiqdGQFfvA78djIPwVYA_1-20219-024ff7.jpeg

Для кадрирования:

import cv2
cropped = image[10:500, 500:2000]
viewImage(cropped, "Пёсик после кадрирования")

Здесь image[10:500, 500:2000] — это image[y:y + высота, x:x + ширина].

Меняем размер

Вот эта фотография довольно большая:

1_AJjT80DpN93YUWTUkOBOJQ_1-20219-df68c1.jpeg

Давайте уменьшим её размер на 20 %:

1_YJzoBwWOtJhkksl3Mpv61w_1-20219-85ec58.jpeg

import cv2
scale_percent = 20 # Это % от изначального размера
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent / 100)
dim = (width, height)
resized = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)
viewImage(resized, "После изменения размера изображения на 20 %")

Обратите внимание, что данная функция учитывает соотношение сторон оригинального фото.

Поворот

Допустим, нам не нравится такой ракурс:

1_SVkI8I5XHs18gfS3jrL4Cw_1-20219-189a9d.jpeg

Давайте его перевернём на 180°:

1_j2pCsTfv_bF1ZAys8IQTLA_1-20219-51e381.jpeg

import cv2
(h, w, d) = image.shape
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, 180, 1.0)
rotated = cv2.warpAffine(image, M, (w, h))
viewImage(rotated, "Фото после поворота на 180°")

Что тут что: — image.shape возвратит высоту, ширину и каналы; — М — матрица поворота, поворачивающая фото на 180° относительно центра; — -ve — угол поворота по часовой стрелке; — +ve — угол поворота против часовой.

Переводим изображение в градации серого и в чёрно-белое отображение по порогу

Вот исходное фото:

1_TRn_JK8tlKBCUSgkooKVpg_670x670_1-20219-0951a5.jpeg

Вот градации серого:

1_lVHmCqfGqT0Fx5DIJnaRzQ_1-20219-812b0e.jpeg

А вот чёрно-белый вариант:

1_4p1SghdBZucSg5R2dZvn1Q_1-20219-0a1e49.jpeg

```python import cv2 gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) ret, threshold_image = cv2.threshold(im, 127, 255, 0) viewImage(gray_image, "Градации серого") viewImage(threshold_image, "Чёрно-белый вариант")

В нашем случае gray_image является одноканальной версией изображения. Что касается функции threshold, то она возвращает изображение, где все пиксели, которые темнее (менее) 127 заменяются на 0, а все, которые больше (ярче) 127, заменяются на 255.

Ещё примерчик для ясности:
```python
ret, threshold = cv2.threshold(im, 150, 200, 10)

Тут всё, что темнее 150, меняется на 10, а всё, что ярче, меняется на 200.

Размытие/сглаживание

Вот отчётливое фото:

1_Rny9ak_Taj58otF4ao9uFA_1-20219-187d7f.jpeg

А вот оно же после размытия:

1_WhEeegXBhcAllIRDN4TTvA_1-20219-758e21.jpeg

import cv2
blurred = cv2.GaussianBlur(image, (51, 51), 0)
viewImage(blurred, "Размытое изображение")

Здесь функция GaussianBlur осуществляет размытие по Гауссу, принимая три параметра: 1. Исходное фото. 2. Кортеж из двух нечётных положительных чисел (чем числа больше, тем, соответственно, больше сила сглаживания). 3. Параметры sigmaX и sigmaY. Если их оставить равными 0, значение параметров рассчитается автоматически.

Рисуем прямоугольники

1_rr0RN5b8cxseYUwABRdlKw_1-20219-fb41c6.jpeg

Поместим лицо пёсика в прямоугольник:

1_uMd8BQyqdDhpH_gR8F3tbg_1-20219-c85dfc.jpeg

import cv2
output = image.copy()
cv2.rectangle(output, (2600, 800), (4100, 2400), (0, 255, 255), 10)
viewImage(output, "Обводим прямоугольником")

Данная функция принимает пять параметров: 1. Непосредственно, изображение. 2. Координату левого верхнего угла (x1, y1). 3. Координату правого нижнего угла (x2, y2). 4. Цвет прямоугольника (GBR/RGB с учётом выбранной цветовой модели). 5. Толщину линии прямоугольника.

Рисуем линии

Вот два четвероногих друга:

1_NdAq3JTqU8nLZWjbaGfjPg_1-20219-20d252.jpeg

Давайте разделим их прямой линией:

1_H1r2tUmUN3V15ps5ynwJHQ_1-20219-153d47.jpeg

import cv2
output = image.copy()
cv2.line(output, (60, 20), (400, 200), (0, 0, 255), 5)
viewImage(output, "Два пса, разделённые линией")

Тут функция line тоже принимает пять параметров: 1. Непосредственно, само изображение, где линия рисуется. 2. Координату 1-й точки (x1, y1). 3. Координату 2-й точки (x2, y2). 4. Цвет линии (GBR/RGB с учётом выбранной цветовой модели). 5. Толщину линии.

Текст на изображении

Допустим, на изображение нужно нанести текст:

1_crsVfLMtv1SNBMlqXyFfYg_1-20219-aa00ed.jpeg

Сделаем это:

1_lTizoTFVbhkx2PdDVEi9WQ_1-20219-66781f.jpeg

import cv2
output = image.copy()
cv2.putText(output, "We <3 Dogs", (1500, 3600),cv2.FONT_HERSHEY_SIMPLEX, 15, (30, 105, 210), 40) 
viewImage(output, "Изображение с текстом")

Здесь главную роль играет функция putText, принимающая аж семь параметров: 1. Изображение. 2. Текст для фото. 3. Координату левого нижнего угла начала текста (x, y). 4. Шрифт. 5. Размер шрифта. 6. Цвет текста (GBR/RGB с учётом выбранной цветовой модели). 7. Толщину линий букв.

Распознаём лица

Теперь обойдёмся без собак:

1_nevvkOrzz97jJ3cB8PiQiQ_1-20219-3929e0.jpeg

Итого: обнаружено 2 лица:

1_IUvY3sxQ_j7qErv8Wr1xtg_1-20219-7ef3a0.jpeg

import cv2
image_path = "./путь/к/фото.расширение"
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
image = cv2.imread(image_path)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(
    gray,
    scaleFactor= 1.1,
    minNeighbors= 5,
    minSize=(10, 10)
)
faces_detected = "Лиц обнаружено: " + format(len(faces))
print(faces_detected)
# Рисуем квадраты вокруг лиц
for (x, y, w, h) in faces:
    cv2.rectangle(image, (x, y), (x+w, y+h), (255, 255, 0), 2)
viewImage(image,faces_detected)

Тут используется общая функция распознавания лиц и объектов detectMultiScale. Чтобы она искала именно лица, передаём ей соответствующий каскад.

Функция принимает четыре параметра: 1. Обрабатываемое фото в градации серого. 2. Параметр scaleFactor. Параметр компенсирует перспективу, ведь одни лица бывают больше, т. к. находятся ближе. 3. Параметр minNeighbors, определяющий число объектов вокруг лица. Вообще, во время распознавания объектов соответствующий алгоритм использует скользящее окно. И чем больше значение вышеназванного параметра, тем больше аналогичных объектов нужно алгоритму, чтобы он определил, что текущий объект — это лицо. Если значение будет слишком маленьким, повысится число ложных срабатываний, если слишком большим, алгоритм станет более требовательным. 4. Последний параметр — minSize отвечает за размер этих областей.

Сохранение изображения

Когда нужные манипуляции произведены, можем сохранить изображение:

import cv2
image = cv2.imread("./импорт/путь.расширение")
cv2.imwrite("./экспорт/путь.расширение", image)

Вывод

OpenCV — прекрасная библиотека с простыми алгоритмами. Она пригодится вам при продвинутом редактировании изображений, 3D-рендере, идентификации и отслеживании людей и объектов на видео, поиске идентичных фото из определённого набора и т. д. Пожалуй, правы те, кто говорит, что нельзя переоценить важность OpenCV для людей, разрабатывающих ML-проекты в области изображений и не только.

Источник

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться