Наш первый шаг к проектам компьютерного зрения. Введение в возможности библиотеки обработки изображений и видео OpenCV.

Краткое введение
Моя цель при написании этой статьи:
- поощрять всех использовать библиотеку OpenCV;
- продемонстрировать некоторые основные возможности OpenCV;
Мотивация
Чуть больше года назад наш мир изменился. Пандемия COVID-19 вынудила большинство из нас пойти на социальную изоляцию.
Как Data Scientist я смотрю на это следующим образом.
Даже находясь в помещении, мы можем собирать и анализировать некоторые данные (например, прямо с веб-камеры), верно?
Обработка и анализ требуют от нас либо написания собственных библиотек обработки изображений, либо использования уже разработанных.
Ранее я писал об анализе научных статей о COVID-19 с помощью регулярных выражений. В этой статье я хочу поделиться некоторыми своими знаниями об OpenCV, библиотеке обработки изображений и видео. В частности, чтобы подготовиться к реальным проектам, о которых я сейчас думаю.
В конечном счете, моя идея состоит в том, чтобы объединить эти знания с машинным обучением, чтобы создать несколько проектов компьютерного зрения, которые каждый может выполнять дома.
Итак, давайте начнем.
Краткий обзор возможностей OpenCV, о которых я расскажу в этой статье:
- Обработка изображения
- Письмо и рисование
- Обработка видео
- Порог
- Маскировка и наложение
- Удаление шума
- Цветовая фильтрация
- Обнаружение краев/контуров
- Обнаружение глаз
Введение в OpenCV
Что такое OpenCV?
Короче говоря, OpenCV — это большая библиотека с открытым исходным кодом для компьютерного зрения, обработки изображений и машинного обучения.
Библиотека является кроссплатформенной и бесплатной для использования по лицензии Apache 2 с открытым исходным кодом. OpenCV написан на C++ и связан с Python, Java и Matlab/Octave.
OpenCV используется для множества видов анализа изображений и видео, таких как редактирование фотографий, оптическое распознавание символов, обнаружение объектов, распознавание лиц, расширенное роботизированное зрение и т. д.
Довольно широкий спектр приложений. Чтобы узнать больше об OpenCV и его приложениях, см., например, официальную страницу или Википедию.
Здесь мы сосредоточимся на основных, но важных методах библиотеки OpenCV.
Мы будем использовать следующие библиотеки:
Инструменты
NumPy. Эта библиотека имеет решающее значение для работы с массивами, словарями, функциями, типами данных и изображениями. ("официальная страница")Matplotlib. (необязательно) Эта библиотека содержит методы для создания статических, анимированных и интерактивных визуализаций в Python. ("официальная страница")python-OpenCV. Как описано выше, это кроссплатформенная библиотека для анализа изображений и всевозможных других приложений. ("официальная страница")
В случае, если вы не знаете, как установить эти пакеты, вот краткое описание:
Установка
Вероятно, самый простой способ установить эти пакеты — использовать pip (pip3).
— Пользователи Linux/Mac
pip3 install numpy (or apt-get install python3-numpy )
pip3 install matplotlib (or apt-get install python3-matplotlib )
pip3 install opencv-python (or apt-get install python3-OpenCV )
— Пользователи Windows
Запустите следующие команды в командной строке
pip install numpy
pip install matplotlib
pip install opencv-python
— Проверка установленных библиотек
В среде Python (например, скрипт или блокнот Jupiter):
Если вы видите слова «Импорт выполнен!», значит, все библиотеки были успешно установлены и импортированы.
Мы готовы начать наше путешествие по основам OpenCV!
Основы OpenCV
Давайте начнем с примера того, как читать, отображать и записывать изображение в файл.
Затем мы применим эти методы и приемы и к обработке видео, ведь любое видео представляет собой последовательность кадров (статичных изображений), отображаемых друг за другом.
Все коды и изображения можно найти в этой директории GitHub.
1. Обработка изображений
Начнем с того, что покажем красивую фотографию, которую я сделал давным-давно (до пандемии) на цветочном рынке Амстердама.
Одна из распространенных практик работы с изображениями в OpenCV — максимально упростить их. Например, чтобы изменить размер или преобразовать их в оттенки серого.
Конечно, мы можем прочитать наше изображение в цвете. Однако я хочу показать самый простой способ отображения изображения.
Итак, давайте прочитаем мою красивую яркую картинку в оттенках серого.
В результате мы можем увидеть сообщение с указанием размеров нашего измененного изображения.
Resized image has hight = 512, width = 384
и всплывающее окно под названием «изображение».

Выполняя дополнительные действия, мы изменяем размер нашего изображения, сохраняя соотношение осей на основе желаемого размера высоты.
В этом случае я хочу, чтобы окончательная высота была 512 пикселей, чтобы сэкономить память обработки, даже если это означает потерю части информации с высоким разрешением. Ширина регулируется автоматически.
Кроме того, можно обнаружить, что мы можем нажать любую кнопку, чтобы остановить отображение этого окна (это закодировано в строках cv2.waitKey(0) и cv2.destroyAllWindows()).
Без функции
cv2.waitKey(0)мы бы даже не увидели это окно, потому что оно сразу открывалось и закрывалось.
В конце мы сохраняем изображение в градациях серого в формате .png.
Итак, теперь мы открыли, изменили размер, отобразили и сохранили наше первое изображение с помощью OpenCV!
Помимо выполнения операций над изображением, мы можем захотеть нарисовать что-нибудь поверх него. Давайте посмотрим, как мы можем сделать это с помощью OpenCV!
2. Письмо и рисование
Можно спросить: Ну, Руслан, до сих пор этот урок казался полезным. Но с какой стати нам нужно что-то рисовать на нашем изображении?
Рад, что спросил.
Непосредственным применением рисования и письма поверх нашего изображения/видео может быть обнаружение объектов. Когда мы обнаруживаем объект, мы, естественно, хотим его кадрировать, верно? Другими словами, мы хотим нарисовать прямоугольник, круг или любую другую фигуру вокруг этого объекта.
Это одна из причин, по которой я показываю этот пример на втором месте. Мы будем постепенно наращивать сложность наших программ.
Давайте нарисуем несколько геометрических фигур поверх нашего измененного изображения цветов с амстердамского рынка в градациях серого, чтобы увидеть это в действии:
В результате можно увидеть следующую картину:

Этот код говорит сам за себя. Однако, чтобы помочь увидеть структуру, я объясню следующее:
Для создания геометрических фигур/фигур мы указываем изображение, поверх которого мы хотим их нарисовать. Затем координаты, цвета и стиль линии, например ширина линии.
Например, координаты для конкретной формы:
- линия, прямоугольник: вверху слева, затем внизу справа;
- круг: центр, затем размер радиуса.
Прямо сейчас этот пример может показаться просто забавным, но в конечном итоге мы будем использовать его для создания чего-то классного.
Мы можем перейти к обработке видео с нашей веб-камеры!
3. Обработка видео
Как указано выше,
если мы не хотим отслеживать что-то или кого-то на видео (т.е. соединять кадры), мы можем просто обрабатывать видео аналогично статичному изображению, т.е. покадрово.
Давайте посмотрим, как любой может использовать веб-камеру для создания и обработки видео таким образом.
В результате мы можем захватить видео с нашей веб-камеры в оттенках серого (мы также можем легко изменить его для цветовой шкалы) с нашей веб-камеры и сохранить видео в интересующем формате. При желании мы можем сохранить видео.
Я стараюсь делать обширные комментарии непосредственно в коде, чтобы сократить описание слова. Тем не менее, я хотел бы упомянуть несколько ключевых моментов для обработки видео с помощью OpenCV:
- вернуть переменную
cv2.VideoCapture()capt - инициировать бесконечный (
while) цикл, пока мы не прервем его с помощью ключа 'q' (для выхода) - прочитать видеокадр методом
capt.read() - Не забудьте! Выпустите видеозахват и запись (если вы это делаете)
Примечание. Воспроизведение видео из файла аналогично его захвату с камеры, просто измените индекс камеры на имя видеофайла, например
capt = cv.VideoCapture(‘out.avi’).
А пока мы можем записать видео, написать и нарисовать какие-нибудь геометрические фигуры поверх его кадров.
Но как насчет реальных модификаций или операций с этими кадрами/изображениями? Мы приближаемся к серии полезных приложений OpenCV.
Давайте теперь перейдем к обработке изображений — пороговой обработке, маскированию и наложению и многому другому!
4. Порог
Позвольте мне ответить на два вопроса здесь.
Во-первых, зачем нам пороговое значение?
Пороговое значение используется для упрощения изображения. По сути, он преобразует все в черно-белое (ниже и выше определенного значения).
Во-вторых, как мы можем использовать это во благо?
Предположим, у нас есть очень плохо сделанная фотография страницы из книги или документа — с разным уровнем света и тени.
Вот пример такой картинки страницы из книги 21 урок для 21 века Ювала Ноя Харари

Как видите, прочитать здесь что-либо непросто.
Если бы это был важный документ, который мы обязательно должны были прочитать, что бы мы сделали в таком случае? Мы не могли просто игнорировать это низкое качество.
Давайте посмотрим, как мы можем использовать пороговое значение, чтобы спасти эту ситуацию.
В результате получаем улучшенное изображение

Теперь давайте кратко рассмотрим этот код
После чтения изображения мы применяем различные пороговые значения, например, простой двоичный порог (для цвета и оттенков серого), адаптивный порог Гаусса и пороги Оцу.
Каждый из них имеет некоторые плюсы и минусы. В этом случае наш адаптивный порог показал наилучшие результаты.
Дайте мне знать, если вас интересуют различия между порогами и основное использование каждого из них.
Теперь мы переходим к маскированию и наложению изображений, еще одной полезной операции.
5. Маскировка и наложение
Я хочу показать, как мы можем разместить логотип (или любое другое изображение) поверх исходного изображения.
Мы можем использовать эту технику не только для создания красивых изображений с заданным логотипом, но также для вычитания и замены некоторых областей изображений или так называемых областей изображений (ROI).
Наложение изображений позволяет нам размещать одно изображение поверх другого, а маскирование позволяет нам удалять ненужные части изображения, обеспечивая наилучший результат.
Поскольку это пример OpenCV, давайте воспользуемся их логотипом, чтобы разместить его поверх нашего известного изображения цветочного рынка Амстердама :-)

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

Ключевыми моментами этого процесса являются следующие:
- создать маску изображения логотипа, а также инверсную;
- выберите область изображения (
ROI) для наложения логотипа; - примените к этому
ROIмаску, а к логотипу обратную маску; - сложите эти два результата;
- строить по базовому изображению;
Та-Да! Наше изображение содержит логотип без каких-либо бесполезных фоновых пикселей.
Еще одним важным аспектом плохо снятого или некачественного изображения является шум.
Давайте посмотрим, как мы можем аккуратно обработать зашумленное изображение.
6. Удаление шума
Работа с данными в реальной жизни обычно включает предварительную обработку или очистку от шума. Это также включает в себя данные изображения/видео.
Естественно, может возникнуть вопрос, как уменьшить шум от данных изображения.
Самый простой способ удалить этот шум — применить сглаживание с помощью некоторого ядра свертки. Это приведет к размытию изображения для усреднения случайных значений пикселей. Это может показаться нелогичным, но на самом деле это помогает нам легче находить интересующий объект.
Мы можем использовать несколько разных ядер: например, гауссовское, квадратное, медианное.
Каждый из них имеет различный эффект и может быть лучше для определенных ситуаций.
Это общий обзор возможностей OpenCV, поэтому не будем отвлекаться на детали того, какое ядро лучше. Я посвящу этому еще одну статью.
А пока давайте посмотрим, как использовать все вышеупомянутые ядра в предоставленной библиотеке.
В итоге имеем исходное изображение

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

Далее переходим к цветовой фильтрации.
7. Цветовая фильтрация
Цветовая фильтрация очень полезна для определения определенного цвета или диапазона цветов на изображении/видео.
Это включает в себя какой-то указатель или даже зеленый экран для создания виртуального фона, например. Есть много возможностей.
Вероятно, самый простой способ создать фильтр — это использовать Hue Saturation Value (или HSV). С цветами HSV мы лучше контролируем наш фильтр, чем, например, с цветами BGR или RGB. Думайте об оттенке как о цвете, о насыщенности как о силе этого цвета и о значении как о количестве света.
Итак, вот мой код для фильтрации синего цвета
в результате получаем исходное изображение и отфильтрованное.

Вы можете видеть, что я держу хайлайтер уникального цвета. Это принцип работы зеленого экрана в Zoom.
Несколько советов по поиску правильного диапазона HSV:
- начните со всего диапазона от
(0, 0, 0)до(255, 255, 255) - лично я сначала модифицирую Hue (первая цифра)
- когда вы больше не можете фильтровать, используя только оттенок, перейдите к насыщенности (второе число)
- в данном случае мой хайлайтер ярко-оранжевого цвета, поэтому его насыщенность выше
160. - иногда нет необходимости изменять каждое число, например значение здесь
Действительно, цветовая фильтрация — мощная техника. Но мы переходим к другому методу — обнаружению границ!
8. Обнаружение краев/контуров
Здесь мы выполним обнаружение краев.
Обратите внимание, что существуют разные алгоритмы поиска ребер. Для наглядности я использовал только алгоритм Кэнни.
Алгоритм Канни работает следующим образом. С одной стороны, если градиент пикселя выше верхнего порога, пиксель принимается как край. С другой стороны, если значение градиента пикселя ниже нижнего порога, то оно отклоняется.
Код, которым я делюсь, довольно прост.
Здесь мы открыли изображение, применили алгоритм обнаружения границ Канни с вводом нижнего и верхнего порогов, изменили размер этого изображения и сохранили его в файле .png.
В результате получаем обнаруженные ребра

Перейдем к последней существенной возможности OpenCV — обнаружению глаз.
9. Обнаружение глаз
Обнаружение объектов — большая тема.
Здесь я показываю лишь небольшую часть — использование каскадов Хаара для обнаружения объекта. В этом случае мы обнаружим человеческие глаза.
Эти каскады Хаара — что-то вроде шаблонов. Многие из них доступны в Интернете для решения общих задач. Тот каскад, который я здесь использую, можно скачать из этого репозитория.
Итак, нам нужно будет загрузить файл, содержащий некоторые из этих каскадов, а затем использовать его для обнаружения на нашем изображении или видео.
Следующий код включает в себя вышеупомянутые шаги:
В итоге получаем наш каскад в действии

На этом мы завершаем обзор OpenCV.
Резюме и будущие проекты
Все коды и изображения можно найти в этой директории GitHub.
Подведем итоги, в этой статье мы
- узнал о библиотеке OpenCV для обработки изображений/видео;
- прошел через 9 основных возможностей обработки данных OpenCV;
последний пункт охватывает следующие темы:
- Обработка изображения
- Письмо и рисование
- Обработка видео
- Порог
- Маскировка и наложение
- Удаление шума
- Цветовая фильтрация
- Обнаружение краев/контуров
- Обнаружение глаз
Это приемы, которые используются в реальной жизни. Сразу оговорюсь, что это далеко не все приемы и алгоритмы, доступные в OpenCV. Я выбрал эти 9 примеров, чтобы дать вам обзор возможностей.
Также эти темы являются основой для моих будущих статей. В конечном счете, я хочу описать проекты, в которых я комбинирую эти (и другие) методы с алгоритмами машинного обучения.
Мне не терпится поделиться с вами своими проектами, в которых я применяю эти техники.
И последнее, но не менее важное: если у вас есть какие-либо комментарии, предложения или вы нашли какую-либо ошибку, пожалуйста, оставьте комментарий или свяжитесь со мной через LinkedIn. Я буду рад услышать от вас.
Надеюсь, вам понравилась моя статья и вы узнали что-то новое. Спасибо, что дочитали до конца.
использованная литература
Основной ссылкой, которую я бы порекомендовал, является официальный сайт OpenCV. Существует множество документации и руководств.
Хотите узнать больше?
Если вам интересно освежить свои знания Python, вот краткий туториал: от Hello World до функций.
Кроме того, я хотел бы поделиться некоторыми из моих предыдущих проектов. Каждая из них посвящена решению определенной задачи. Это хорошая возможность бросить себе вызов и отточить некоторые навыки Python:
- отслеживание веса с нуля на Python;
- анализ научных статей о COVID-19;
- создание приложения для повышения производительности (Pomodoro) с нуля.
Контакт
Свяжитесь со мной в LinkedIn.
Загляните на мой GitHub.
P.S.: Если вам нравится этот непрерывный опыт чтения на этой прекрасной платформе Medium.com, подумайте о том, чтобы поддержать авторов этого сообщества, подписавшись на членство ЗДЕСЬ. Он стоит всего 5 долларов США в месяц и поддерживает всех авторов.