Опубликован: 20.08.2013 | Уровень: для всех | Доступ: платный | ВУЗ: Новосибирский Государственный Университет
Лекция 4:

Начало работы с библиотекой OpenCV

< Лекция 3 || Лекция 4: 1234 || Лекция 5 >

1.2. Где взять OpenCV и достать информацию по библиотеке?

Сайт библиотеки – http://opencv.org. На нем можно загрузить библиотеку для разных платформ, найти документацию по библиотеке, краткие инструкции по установке (Quick Start), уроки по ее использованию (Tutorials), справочную карту (Cheat Sheet), которую полезно сразу распечатать, ссылки на полезные сайты и т. п. Ссылка WIKI ведет на сайт для разработчиков http://code.opencv.org.

На сайте http://docs.opencv.org собрана вся документация. В частности, имеются подробные описания всех функций с полнотекстовым поиском.

На сайте http://answers.opencv.org можно задать свой вопрос, касающийся библиотеки, и получить на него ответ от разработчиков или других пользователей. Прежде чем сформулировать свой вопрос, имеет смысл попытаться найти похожий, среди тех, которые уже задавали. Наиболее популярные вопросы попадают на верх списка. На них нужно обратить внимание в первую очередь.

1.3. OpenCV на Python'е

Для первых экспериментов с библиотекой авторы рекомендуют использовать Python (http://python.org). Программу на этом языке можно писать в любом текстовом редакторе. Далее без предварительной компиляции она выполняется интерпретатором Python. Python с библиотекой NumPy превращается в бесплатный аналог системы MATLAB, при этом сам язык более продвинутый, чем язык MATLAB.

Мы предлагаем следующую последовательность шагов для быстрого сайта (на примере Windows):

  1. Загружаем самораспаковывающийся архив с SourceForge: http://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.4.3/ и распаковываем его в какой-нибудь домашний каталог.
  2. Загружаем и устанавливаем Python 2.7.x c http://python.org, загружаем и устанавливаем NumPy: http://numpy.scipy.org (выбираем версию, соответствующую версии Python).
  3. Копируем cv2.pyd из распакованного каталога OpenCV в <каталог Python>\Lib\site-packages.

    Можно начинать эксперименты!

  4. Опционально устанавливаем редактор с поддержкой Python, например, Sublime Text 2.
1.3.1. Первая программа

Набираем следующую программу в текстовом редакторе (first.py):

import sys, cv2 as cv # Импортируем системный модуль 
 # Импортируем модуль OpenCV (cv2) под именем cv 
img = cv.imread(sys.argv[1], 1) # Загружаем изображение 
cv.imshow("original", img) # Отрисовываем изображение 
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) 
 # Конвертируем цветное изображение в монохромное 
gray = cv.GaussianBlur(gray, (7, 7), 1.5) 
 # Добавляем размытие 
edges = cv.Canny(gray, 0, 50) # Запускаем детектор ребер 
cv.imshow("edges", edges) # Отображаем результат 
cv.waitKey() # Ожидаем нажатия любой клавиши для 
завершения работы   
   

Программа загружает изображение, имя которого указывается в параметрах запуска программы, применяет к нему серию преобразований и отображает результат.

Копируем файл lena.jpg из <opencv>/samples/c в каталог, где находится first.py, и запускаем программу (из Far, cmd и т. п.) командой:

python first.py lena.jpg 
   

Исходное изображение и результат показаны на рисунке.


Рис. 4.3.

Обратим внимание на вызов функции cv.GaussianBlur в коде программы, которая осуществляет размытие. Если бы его не было, на выходе получили бы слишком много ребер.

Функция cv.waitKey() не только ждет нажатие произвольной клавиши на клавиатуре, но и выполняет обработку сообщений от операционной системы, в частности запросы на отрисовку окна. Без этой команды окно бы не "слушалось" действий пользователя.

1.3.2. Вторая программа: добавляем видео

Настоящее компьютерное зрение начинается, когда появляется работа с "живыми" камерами. В следующей программе (second.py) добавим обработку видео. Для каждого кадра будем выполнять те же операции, что и в предыдущей программе для одного изображения.

import sys, cv2 as cv 
cap = cv.VideoCapture(0) 
 # Инициализация для захвата с веб-камеры 
while True: 
 ok, img = cap.read() % Загружаем очередной кадр 
 if not ok: 
  break 
 gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) 
  # Конвертируем цветное изображение в монохромное 
 gray = cv.GaussianBlur(gray, (7, 7), 1.5)  
  # Добравляем размытие 
 edges = cv.Canny(gray, 1, 50) # Детектируем ребра 
 cv.imshow("edges", edges) # Отображаем результат 
 if cv.waitKey(30) > 0: # Ожидаем 30 мс 
  break # Если клавиша нажата, то выход из цикла  
   

Здесь функция cv.waitKey() вызывается с одним входным аргументом. Это количество миллисекунд (в нашем случае 30), в течение которого система ожидает нажатия на клавишу. По-умолчанию (как в программе first.py) используется значение 0, что означает бесконечное время ожидания. Функция возвращает код нажатой клавиши. Если клавиша не нажата, то возвращается -1.

Обратите внимание на небольшой размер программы, которая, тем не менее, дает довольно эффектный результат.

1.3.3. Третья программа: добавляем детектирование лиц

Добавим процедуру детектирования лиц. Получим следующий код (face.py):

import sys, cv2 as cv 
cap = cv.VideoCapture(0) 
cascade = cv.CascadeClassifier( 
 "lbpcascade_frontalface.xml") 
  # Загрузка обученного каскадного классификатора 
while True: 
 ok, img = cap.read() 
 if not ok: 
  break 
 gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) 
 sf = min(640./img.shape[1], 480./img.shape[0]) 
 gray = cv.resize(gray, (0,0), None, sf, sf) 
  # Масштабирование 
 rects = cascade.detectMultiScale(gray, scaleFactor=1.3, 
  minNeighbors=4, minSize=(40, 40), 
  flags=cv.cv.CV_HAAR_SCALE_IMAGE) % Детектирование 
 gray = cv.GaussianBlur(gray, (3, 3), 1.1) 
  # Размываем  
 edges = cv.Canny(gray, 5, 50) # Детектируем ребра 
 
 out = cv.cvtColor(edges, cv.COLOR_GRAY2BGR) 
 for x, y, w, h in rects: 
  cv.rectangle(out, (x, y), (x+w, y+h), (0,0,255), 2) 
   # Вокруг найденного лица 
   # рисуем красный прямоугольник 
 cv.imshow("edges+face", out) 
 if cv.waitKey(30) > 0: 
  break  
   

Сначала с помощью функции cv.CascadeClassifier() загружаем обученную модель (каскадный классификатор) для детектирования лиц.

Если применять алгоритм детектирования к ребрам, то лиц, скорее всего, не найдем, поэтому алгоритм применяем к исходному изображению после его преобразования в монохромное изображение и масштабирования. Использование большого разрешения в задаче детектирования лиц особого смысла не имеет, поэтому изображение масштабируем (функцией cv.resize()). В результате с помощью изотропного (одинакового по обоим осям) масштабирования помещаем изображение в прямоугольник размера 630 \times 480.

Алгоритм детектирования (детектор) вызываем функцией cascade.detectMultiScale(). Выделяем ребра и совмещаем изображения. Вокруг найденного лица рисуем красный прямоугольник.

Обратим внимание, что нигде не требуется явно выделять и освобождать память для хранения изображений: все происходит автоматически. Это сокращает время разработки программ и создания прототипов

Перед запуском программы копируем lpbcascade_frontalface.xml из <OpenCV>/data/lbpcascades в тот же каталог, что и face.py. Запускаем:

python face.py 
   

Результат показан на рисунке.


Рис. 4.4.
1.3.4. Несколько замечаний об использовании связки Python + OpenCV

Использование OpenCV в связке с Python удобно для создания простых приложений, проведения первых экспериментов, создания прототипов. Заметим, что на языке Python доступна практически вся функциональность библиотеки. Слабым местом могла бы быть производительность, но если использовать "векторно-матричную" идеологию (как в MATLAB'е), то можно получать и достаточно быстрый код. Для этого следует избегать обработки изображений попиксельно и других массивов поэлементно в циклах. Вместо этого использовать векторные функции, которые работают сразу со всем изображением или массивом.

Другое хорошее свойство Python – его самодокументированность. В интерактивной сессии Python (в командном окне) можно быстро получить список доступных функций, список методов конкретного класса, быструю справку по каждой функции и т. д.:

>>> import cv2 as cv 
>>> dir(cv) # Получаем список функций и классов в cv 
>>> cv.resize.__doc__ # Описание функции resize 
>>> cap = cv.VideoCapture(0) 
>>> dir(cap) # Список методов VideoCapture 
>>> cap.read.__doc__ # Описание метода read 
   

Обертки для Python генерируются автоматически на этапе сборки библиотеки.

Настоятельно рекомендуем ознакомиться с набором примеров на Python, которые можно найти в папке <OpenCV>/samples/python2: устранение размытия в результате движения камеры, распознавание рукописных цифр, видеоэффекты и т. д.

< Лекция 3 || Лекция 4: 1234 || Лекция 5 >
Александра Максимова
Александра Максимова

При прохождении теста 1 в нем оказались вопросы, который во-первых в 1 лекции не рассматривались, во-вторых, оказалось, что вопрос был рассмаотрен в самостоятельно работе №2. Это значит, что их нужно выполнить перед прохождением теста? или это ошибка?
 

Алена Борисова
Алена Борисова

В лекции по обработке полутоновых изображений (http://www.intuit.ru/studies/courses/10621/1105/lecture/17979?page=2) увидела следующий фильтр:


    \begin{array}{|c|c|c|}
    \hline \\
    0 & 0 & 0 \\
    \hline \\
    0 & 2 & 0 \\
    \hline \\
    0 & 0 & 0 \\
    \hline 
    \end{array} - \frac{1}{9} \begin{array}{|c|c|c|}
    \hline \\
    0 & 0 & 0 \\
    \hline \\
    0 & 1 & 0 \\
    \hline \\
    0 & 0 & 0 \\
    \hline 
    \end{array}

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

Что вижу я в конструкции фильтра (скорее всего ошибочно): F(x, y) = 2 * I(x, y) - 1/9 I(x, y) = 17/9 * I(x, y), где F(x, y) - яркость отфильтрованного пикселя, а I(x, y) - яркость исходного пикселя с координатами (x, y). Что означает обычное повышение яркости изображения, при этом без учета соседних пикселей (так как их множители равны 0).

Объясните, пожалуйста, как данный фильтр может повышать четкость изображения?

Сергей Кротов
Сергей Кротов
Россия
Дмитрий Донсков
Дмитрий Донсков
Россия, Москва, Московский Авиационный Институт