OpenCV на python: получение кадров, смена цветовой модели и размытие

OpenCV — это мощная библиотека машинного зрения, которую часто применяют в роботах для распознавания объектов окружающего мира. В одной из статей мы подробно описали установку OpenCV на одноплатный компьютер Raspberry Pi 3.

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

Все программы мы будем писать на языке python и запускать на Raspberry Pi 3.

1. Подготовка к написанию первой программы

Шаг 1. Если в ходе установки OpenCV вы использовали виртуальное окружение, то перед запуском python-скриптов необходимо перейти в это окружение с помощью команд:

$ source ~/.profile
$ workon cv

Шаг 2. Для дальнейшей работы нам потребуются три дополнительных python-модуля:

  • video.py
  • common.py
  • tst_scene_render.py

Найти эти модули можно в папке с примерами: /home/pi/Downloads/opencv-master/samples/python

Создадим в домашней папке, папку opencv и скопируем в неё эти модули:

$ cd ~
$ mkdir opencv
$ cp /home/pi/Downloads/opencv-master/samples/python/video.py .
$ cp /home/pi/Downloads/opencv-master/samples/python/common.py .
$ cp /home/pi/Downloads/opencv-master/samples/python/tst_scene_render.py .

Шаг 3. Теперь создадим в этой же папке файл с нашей программой.

$ touch eye.py

Шаг 3. Редактировать программу можно в любом приложении. Если нет предпочтений, то рекомендуем использовать редактор Nano. Откроем в нём недавно созданный файл:

$ nano eye.py

Шаг 4. После того как программа будет написана, сохраним изменения с помощью комбинации клавиш Ctrl+o, нажмем Y для подтверждения. Затем нажмем Ctrl+x для выхода из редактора.

2. Получение кадров с камеры и вывод в окно

Наша программа будет в бесконечном цикле получать кадры с камеры и отображать их в специальном окне. Алгоритм программы:

OpenCV. Работа с веб-камерой

Код на языке python:

import cv2
import video

if __name__ == '__main__':
    # создаем окно с именем result
    cv2.namedWindow( "result" )

    # создаем объект cap для захвата кадров с камеры
    cap = video.create_capture(0)

    while True:
        # захватываем текущий кадр и кладем его в переменную img 
        flag, img = cap.read()
        try:
            # отображаем кадр в окне с именем result
            cv2.imshow('result', img)
        except:
            cap.release()
            raise
 
        ch = cv2.waitKey(5)
        if ch == 27:
            break

    cap.release()
    cv2.destroyAllWindows()

Примечание. Функция create_capture имеет всего один аргумент, который отвечает за индекс камеры в нашей системе. В случае, если камера всего одна, её индекс будет равен 0.

Запускаем python-скрипт:

$ python eye.py

Если в программе нет ошибок, откроется окно с видео.

OpenCV. Работа с веб-камерой

3. Отражение картинки по вертикали и горизонтали

В предыдущей программе мы брали каждый кадр, полученный с камеры и отображали его в неизменном виде. Теперь в разрыв между этими двумя операциями добавим третью — отражение кадра:

OpenCV на python. Отражение картинки

За отражение кадра отвечает функция:

flip( кадр, направление )

Здесь кадр — кадр видеопотока, который нужно отразить;
направление — флаг, определяющий направление отражения: 0 — по-горизонтали, 1 — по-вертикали, -1 — по горизонтали и вертикали одновременно.

В действительности, разные веб-камеры могут по-разному реагировать на вертикальное и горизонтальное отражение. Например, в используемой в этом уроке Logitech С110 вертикаль и горизонталь поменяны местами.

import cv2
import video

if __name__ == '__main__':
    # создаем окно с именем result
    cv2.namedWindow( "result" )

    # создаем объект cap для захвата кадров с камеры
    cap = video.create_capture(0)

    while True:
        # захватываем текущий кадр и кладем его в переменную img 
        flag, img = cap.read()
        try:
            # отражаем кадр
            img = cv2.flip(img,0)
            # отображаем кадр в окне с именем result
            cv2.imshow('result', img)
        except:
            cap.release()
            raise
 
        ch = cv2.waitKey(5)
        if ch == 27:
            break

    cap.release()
    cv2.destroyAllWindows()

Результатом будет:

OpenCV на python. Отражение картинки

4. Смена цветовой модели

Цветовая модель — это модель представления цвета каждой точки с помощью группы чисел. Некий цветовой код. Например, в RGB цвет определяется тремя компонентами: красный, зеленый и синий. Любая веб-камера передает кадры именно в такой модели. А в HSV у каждой точки есть цветовой тон — H, насыщение — S и яркость — V.

Некоторые функции машинного зрения проще реализовать в какой-то конкретной модели. Например, в дальнейших уроках мы увидим, что распознавание цветовых пятен на картинке лучше работает в модели HSV.

Для преобразования цветовой модели используем функцию:

cvtColor( кадр, модель )

где модель — код преобразования:

  • COLOR_GRAY — в оттенки серого;
  • COLOR_RGB2HSV — из RGB в HSV;
  • COLOR_BGR2HSV — из BGR в HSV;
  • COLOR_HSV2BGR — обратно, из HSV в BGR;
  • и т.д.

OpenCV поддерживает много моделей, но нам потребуются пока только эти три: RGB, HSV и оттенки серого.

Примечание. По-умолчанию, кадр с камеры приходят в модели BGR, а не RGB, поэтому для преобразования необходимо использовать флаг COLOR_BGR2HSV.

import cv2
import video

if __name__ == '__main__':
    # создаем окно с именем result
    cv2.namedWindow( "result" )

    # создаем объект cap для захвата кадров с камеры
    cap = video.create_capture(0)

    while True:
        # захватываем текущий кадр и кладем его в переменную img 
        flag, img = cap.read()
        try:
            # меняем цветовую модель на HSV
            img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV )
            # отображаем кадр в окне с именем result
            cv2.imshow('result', img)
        except:
            cap.release()
            raise
 
        ch = cv2.waitKey(5)
        if ch == 27:
            break

    cap.release()
    cv2.destroyAllWindows()

Результат работы программы:

OpenCV на python. Преобразование в HSV

Если в программе заменим COLOR_BGR2HSV на COLOR_GRAY, получим такую картинку:

OpenCV на python. Преобразование в оттенки серого

5. Размытие по Гауссу

Часто, изображение с веб-камер страдает наличием большого количества шумов. Особенного это заметно, когда камере не хватает освещения. Для частичного решения этой проблемы применяют фильтр Гаусса, или другими словами размытие по Гауссу (Gaussian blur).

Функция имеет 3 аргумента:

GaussianBlur( кадр, размер ядра, отклонение)

размер ядра — список из двух чисел (x,y), которые задают размер ядра фильтра Гаусса по горизонтали и вертикали. Чем больше ядро, тем более размытым станет кадр;
отклонение — стандартное отклонение по оси X.

import cv2
import video

if __name__ == '__main__':
    # создаем окно с именем result
    cv2.namedWindow( "result" )

    # создаем объект cap для захвата кадров с камеры
    cap = video.create_capture(0)

    while True:
        # захватываем текущий кадр и кладем его в переменную img 
        flag, img = cap.read()
        try:
            # размываем кадр
            img = cv2.GaussianBlur(img, (5, 5), 2)
            # отображаем кадр в окне с именем result
            cv2.imshow('result', img)
        except:
            cap.release()
            raise
 
        ch = cv2.waitKey(5)
        if ch == 27:
            break

Посмотрим на результат:

OpenCV на python. Размытие по Гауссу

Надо отметить, что в OpenCV есть и другие фильтры для удаления шума: медианный фильтр, двухсторонний фильтр и усреднение.

В следующем уроке поговорим о наложении на картинку текста и графики. Это понадобится нам для выделения на кадре интересующих нас областей, а также для вывода прямо в кадр, например, координат точек и величину FPS.


Изменено: