OpenCV — это мощная библиотека машинного зрения, которую часто применяют в роботах для распознавания объектов окружающего мира. В одной из статей мы подробно описали установку OpenCV на одноплатный компьютер Raspberry Pi 3.
Переде тем как приступить непосредственно к функциям машинного зрения, нам необходимо познакомиться со вспомогательными функциями, необходимыми для работы с видеопотоком. В этом уроке мы попробуем получить кадры с видеокамеры и применим к ним различные преобразования: отражение, смена цветовой модели, размытие.
Все программы мы будем писать на языке python и запускать на Raspberry Pi 3.
Подготовка к написанию первой программы
Шаг 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 для выхода из редактора.
Получение кадров с камеры и вывод в окно
Наша программа будет в бесконечном цикле получать кадры с камеры и отображать их в специальном окне. Алгоритм программы:
Код на языке 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
Если в программе нет ошибок, откроется окно с видео.
Отражение картинки по вертикали и горизонтали
В предыдущей программе мы брали каждый кадр, полученный с камеры и отображали его в неизменном виде. Теперь в разрыв между этими двумя операциями добавим третью — отражение кадра:
За отражение кадра отвечает функция:
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()
Результатом будет:
Смена цветовой модели
Цветовая модель — это модель представления цвета каждой точки с помощью группы чисел. Некий цветовой код. Например, в 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()
Результат работы программы:
Если в программе заменим COLOR_BGR2HSV на COLOR_GRAY, получим такую картинку:
Размытие по Гауссу
Часто, изображение с веб-камер страдает наличием большого количества шумов. Особенного это заметно, когда камере не хватает освещения. Для частичного решения этой проблемы применяют фильтр Гаусса, или другими словами размытие по Гауссу (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 есть и другие фильтры для удаления шума: медианный фильтр, двухсторонний фильтр и усреднение.
В следующем уроке поговорим о наложении на картинку текста и графики. Это понадобится нам для выделения на кадре интересующих нас областей, а также для вывода прямо в кадр, например, координат точек и величину FPS.
В пункте (2. Получение кадров с камеры и вывод в окно) указан код на питоне, я его копирую и вставляю в чистый файл (opencv-video-rgb-hsv-gray.py).
Но после запуска этого файла, появляется error
Warning: unable to open video source: 0
Warning: unable to open video source: synth
Traceback (most recent call last):
File «opencv-video-rgb-hsv-gray.py», line 13, in
flag, img = cap.read()
AttributeError: ‘NoneType’ object has no attribute ‘read’
У меня версия cv ‘3.4.1’
Вероятно программа не видит веб-камеру. Она точно правильно подключена и настроена?
Как вариант, в строке:
cap = video.create_capture(0)
попробуйте поменять 0 на 1.
такая же проблема, замена на 1 не помогает
Нашёл решение,
cap = video.create_capture(0) (как понял, это для версии python2, для версии Python3 такого делать не нужно)
делаем так:
cap = cv2.VideoCapture(0), cv2 следственно содержит video, import video не нужно делать
чтобы VideoCapture, увидел камеру делаем команду ниже
Чтобы появилось стандартное V4L устройство /dev/video0, нужно всего-лишь выполнить:
sudo modprobe bcm2835-v4l2
такая же история, не разобрались в чём косяк ?
камеру включите
а где бы взять ту папку с примерами
Добрый день. ошибка на import video . вроде скопировал с opencv341 файл video вставил в папку с кодом в (jupyter) scripts
первый пример не собирается выводится ошибка:
python eye.py
Traceback (most recent call last):
File «eye.py», line 1, in
import cv2
File «/home/pi/.virtualenvs/cv/lib/python3.5/site-packages/cv2/__init__.py», line 9, in
from .cv2 import *
ImportError: libQtGui.so.4: cannot open shared object file: No such file or directory
import video — что это? как установить??? знаю, это смешно… помогите!!! не знаю как установить этот модуль
Здравствуйте. Пишет такую ошибку: module ‘video’ has no attribute ‘create_capture’
Подскажите как исправить