Вы находитесь на странице: 1из 22

с/к Анализ изображений, OpenCV

7. Работа с камерой,
анализ фона и движения

http://people.rit.edu/andpph/photofile-misc/strobe-motion-ta-08.jpg

лекции и объявления: вопросы отправляйте на адрес УрГУ / ИММ осень 2010


www.uralvision.blogspot.com perevalovds@gmail.com
Работа с камерой
Получение кадров с камеры
VideoCapture capture; //Класс для работы с камерами и видеофайлами
capture.open( 0 ); //открыть первую камеру (нумерация с 0)
//а если задать строку VideoCapture capture.open( "myfile.avi" ); - будет читать avi-файл

if ( !capture.isOpened() ) { //если камеры нет, завершаем работу


cout << "Нет камеры" << endl;
return -1;
}

Mat image, smoothed, edges;


for(;;) {
capture >> image; // получение кадра

cvtColor(image, smoothed, CV_BGR2GRAY);


GaussianBlur(smoothed, smoothed, Size(7,7), 1.5, 1.5 );
Canny(smoothed, edges, 0, 30, 3 );
imshow( "image", image );
imshow("edges", edges);
if(waitKey(30) >= 0) break; //ждем нажатия клавиши 30 мсек, если нажали - выход
}

//Деструктор capture сам выключит камеру


return 0;
Получение кадров с камеры
Калибровка камеры
Рассмотрим простейшую калибровку, когда камера смотрит сбоку на плоскость. (Есть
более сложные методы калибровки, которые позволяют устранять искажения на
краях изображения с камеры, связанные с неточностью оптики).

Исходное изображение Изображение с выделенными Результат калибровки:


калибровочными точками изображение выровнено
(углы красного 4-угольника)
Калибровка камеры
1. Для проведения калибровки требуется указать координаты нескольких точек на
изображения и указать, в какие точки они должны перейти.

Требуется не менее 4 точек для поиска перспективной проекции. При этом любые
точки не должны лежать на одной прямой.

Примечание: координаты могут быть вещественными числами, что позволяет


повысить точность результата.
Для этого можно использовать субпиксельные методы, вычисляющие положение
объектов с точностью выше, чем пиесел.

2. Затем с помощью функции getPerspectiveTransform вычисляется оптимальная


матрица перспективное преобразование (методом типа МНК, что позволяет успешно
использовать много точек, снятых с погрешностью).

3. Наконец, данная матрица подставляется в функцию warpPerspective для


получения калиброванного изображения.
Калибровка камеры
const int K = 4; //будем использовать 4 точки.
cv::Point2f src[K]; //координаты точек на изображении
cv::Point2f dst[K]; //координаты результирующих точек

src[ 0 ] = cv::Point2f( ..., ... ); //координаты углов на изображении


src[ 1 ] = cv::Point2f( ..., ... ); //должны идти по часовой стрелке с левого верхнего
угла
src[ 2 ] = cv::Point2f( ..., ... ); //- в соответствии с dst, см. ниже
src[ 3 ] = cv::Point2f( ..., ... );

dst[ 0 ] = cv::Point2f( 0, 0 ); //результирующие точки; w и h - размеры результата


dst[ 1 ] = cv::Point2f( w, 0 );
dst[ 2 ] = cv::Point2f( w, h );
dst[ 3 ] = cv::Point2f( 0, h );

Mat transform = getPerspectiveTransform( src, dst ); //вычисляем матрицу преобраз.

warpPerspective( image, imageResult, transform, cv::Size( w, h ), INTER_LINEAR );


//получаем по входному изображению image результат - imageResult
Методы анализа фона
Методы анализа фона

Задача - вычислить пикселы, являющиеся фоном и не


фоном.
1. Запоминание фона

Запоминаем картинку фона,


а затем смотрим отличие кадра с камеры от запомненной картинки.

Более продвинутый метод - "code book", он запоминает яркости фона в каждом


пикселе некоторое время, что позволяет справляться с объектами типа
открывающихся дверей.

Есть и более сложные алгоритмы.

Проблемы:
- быстрое изменение освещения - надо специально
учитывать,
- тени от объектов часто воспринимаются как
не фон, что обычно нежелательно, поэтому
также надо специально учитывать (путем анализа цвета).
2. Адаптивное обучение

Простой метод, в котором мы считаем фон путем усреднения последних N кадров

const float k = 0.01;


back = (1-k) * back + k * image;
это фильтр низких частот

Через несколько секунд объект, пришедший в кадр, становится фоном. Для


некоторых задач это хорошо.

Плюс - не надо специально строить ситуацию когда в кадре никого нет для
запоминания фона.

Есть более сложные алгоритмы автоматического вычисления фона с помощью учета


нескольких кадров.
3.Использование данных о глубине

1. Стерео камеры
2. Камеры с вычислением времени полета (на основе лазерного дальномера, time of
filght cameras)
3. Kinect

Дают информацию о расстоянии до каждого пиксела, что позволяет отбросить


дальние объекты, осуществив пороговую обработку глубины.
Анализ движения
Разность двух кадров - алгоритм
"Детектора движения"
1. Пусть image1, image2 - два последовательных кадра с камеры, одноканальных.
2. Строим модуль их разности
Mat diff;
absdiff( image1, image2, diff);
3. Осуществляем пороговую обработку
Mat bin; //тут будут найдены пикселы, соответствующие областям движения
threshold( diff, bin, 100 /* порог */, 255, CV_THRESH_BINARY );
Разность двух кадров - алгоритм
"Детектора движения"

Данный метод позволяет находить области, к которых


произошло движение.

Для анализа направления движения таких объектов -


используется понятие оптического потока.
Что такое оптический поток
Оптический поток (optical flow, optic flow) - это векторное поле явного движения
объектов, поверхностей и ребер в визуальной сцене, вызванное относительным
движением между наблюдателем (глазом, камерой) и сценой.

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

http://www.ultimategraphics.co.jp/jp/images/stories/ultimate/BCC/optical.jpg
Основные применения оптического
потока
1. Для определения направления, в котором движутся
объекты в кадре.

2. При производстве фильмов - для осуществления


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

3. Принципиально можно применять в стереозрении - для


определения расстояния до объекта с помощью анализа
оптического потока кадров, поступающих с двух камер.
Методы вычисления оптического
потока
Вход: два кадра. Выход - векторное поле ( fx(x, y), fy(x,y) )
- вектора геометрического сдвига пикселов с первого кадра на второй.

(I) Блочные ("наивные" методы)


Для каждой точки ищется сдвиг, минимизирующий разность в локальном окне.

(II) Дифференциальные (наиболее используемые)


Оценка производных по x, y, t.
1. Lucas-Kanade - очень быстрый.
2. Farneback - достаточно качественный, но работает медленней
3. CLG - очень качественный, но пока не реализован в OpenCV
4. Пирамидальный Lucas-Kanade, вычисляющийся только на "точках интереса"
5. Horn-Schunk - не очень устойчивый к шумам

(III) На основе дискретной оптимизации (ресурсоемкие)


Решение строится с помощью методов min-cut, max-flow, линейного
программирования или belief propagation.
Методы вычисления оптического
потока
1. Lucas-Kanade
Локальный метод, использующий разложение Тейлора по времени t в окрестности
каждого пиксела независимо.
Достоинства: быстро вычисляется.
Недостатки: "aperture problem" - на областях с однородной текстурой работает плохо
в силу того, что он локальный.
Реализован только в C-версии OpenCV, cvCalcOpticalFlowLK.

Поток, наложенный на изображение.


Обратите внимание, что внутри ладони
поток не найден.

Поток нарисован с шагом в 10 пикселов,


функцией line. (Примечание: значения
потока сглажены по окрестности для
получения более устойчивого результата).
Методы вычисления оптического
потока
2. Farneback
Локальный метод, использующий для расчета аппроксимацию изображения
полиномиальной функцией.

Достоинства: заметно более устойчив к проблемы апертуры.

Недостатки: работает заметно медленней Lucas-Kanade.


Методы вычисления оптического
потока
void calcOpticalFlowFarneback(
const Mat& prevImg, //Первый кадр, 8-битное одноканальное изображение
const Mat& nextImg, //Второй кадр, тип и размер как у prevImg
Mat& flow, //Результирующий поток, будет иметь тип CV_32FC2
double pyrScale, //<1, масштаб построения пирамиды. 0.5
int levels, //Число уровней пирамиды 5
int winsize, //Окно усреднения. Чем больше - тем результат
//более размытый, но и более устойчивы к шумам 5
int iterations, //Число итераций на каждом уровне пирамиды 3
int polyN, //Размер окна для вычисления аппроксимации
//полиномом 7
double polySigma, //параметр гауссиана для сглаживания производных
//при построении аппроксимации 1.5
int flags //флаги
// OPTFLOW_USE_INITIAL_FLOW - не рекомендую использовать!!
//OPTFLOW_FARNEBACK_GAUSSIAN - использовать гауссиан для усреднения
//дает более точный результат в ущерб качеству.
)
Методы вычисления оптического
потока
3. CLG

"Combining Local and Global"


Метод, объединяющий Lucas-Kanade и Horn-Schunk

Сейчас (2010 г.) он и его модификации считаются одними


из лучших по соотношению качество / скорость.

Пока не реализован в OpenCV.

Сложная задача (на получение экзамена):


найти реализацию CLG на C/C++, скомпилировать, и
запустить на какой-то тестовой паре картинок.

Оценить