Перейти к содержимому
Compvision.ru
Cfr

Трекинг объектов.

Recommended Posts

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

и вообще я не понял за счёт чего у нас карта глубины получится? (камера вроде как неподвижна)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Лучше тем, что можно точнее сегментировать, так как доступна не только информация о яркости, но и направление движения. В самом простом случае можно разделять блобы в местах резкого изменения в поле векторов. В более сложном случае обучить классификатор (например, EM + GMM, которые есть в OpenCV), на вход которому подавать яркость пикселя, цвет, Собеля, Лапласиан и вектор движения.

Карта глубины строится за счёт информации о движении (типа structure from motion). Это будет не абсолютная, а относительная карта глубины, но она будет. Эта область подробнее освещена здесь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Nuzhny, у меня к сожалению нет на рабочем компьютере NVIDIA. Мне хотелось бы как получить это оптический поток Брокса в реальном времени.

Я даже зашел на simple_flow, скачал код и не смог разобраться в нем. Конкретно: там написано чтобы запустить прогу надо два изображения, и какую то дату которая получается из матлаба. а хотелось бы чтобы опт.поток в реальном времени рассчитывался. я бы с удовольствием изменил код, но я не могу понять где он вообще?

Бог с ним, с simple flow, давайте Брокса хотя бы попробуем сделать... в opencv нет такой функции - я не могу найти...

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если судить по этой работе, на основе которой и есть реализация в OpenCV, то карту глубины можно и не строить. Но он реализован только на CUDA, что не есть хорошо. Если не подойдёт никакой другой, то реализуем сами.

Реализация SimpleFlow есть на CPU, не знаю насколько точная. Реализацию от авторов я тоже не смог запустить.

Давай я сегодня-завтра набросаю тестовый проект с выбором алгоритма и выложу сюда. Заодно подробней прочитаю публикации Брокса. Думаю, что сегментацию не обязательно проводить именно по результатам его реализации оптического потока.

P.S. OpenCV я беру не инсталятором, а скачиваю git'ом исходники, поэтому всё, что я упоминаю, там есть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ну и вдогонку.

Как называется оптический поток Брокса в OpenCV я уже говорил - BroxOpticalFlow.

SimpleFlow называется - calcOpticalFlowSF.

Остальные, я думаю, ты знаешь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Не могу не поучаствовать в благородном деле :rolleyes:.

Залил на общий 4shared свежие лекции по опт. потокам от Брокса (прошу сильно не распространять, а то прикроют утечку).

Плюс к этому:

Архив с матлабовским проектом SIFT_Flow:

SIFTflow.zip

Документ к нему:

SIFTflow.pdf

Отсюда: http://people.csail.mit.edu/celiu/SIFTflow/

Библиотека реализаций алгоритмов машинного зрения:

Algorithms

Scale Invariant Feature Transform (SIFT)

Dense Scale Invariant Feature Transform (DSIFT)

Maximally Stable Extremal Regions

K-means clustering

Integer K-means (IKM)

Hierarchical Integer K-means (HIKM)

Agglomerative Information Bottleneck (AIB)

KD-trees and forests

Homogeneous kernel map

PEGASOS SVM solver

Simple Linear Iterative Clustering (SLIC)

Quick shift image segmentation

Histogram of Oriented Gradients (HOG) features

Covariant feature detectors

:

http://www.vlfeat.org/index.html

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Посмотрел на реализацию SimpleFlow из OpenCV - так себе. Качество работы мне не очень понравилось, поэтому даже за оптимизацию смысла нет браться. Хотя можно попробовать подкрутить параметры, но что-то сомневаюсь, что поможет. Если кто-то хочет посмотреть, то исходник примера ниже. Там можно "играть" размерами обрабатываемой картинки (я уменьшил для ускорения), всеми входными параметрами и просматривать результат с разным шагом.

А я попробую реализовать Брокса.

#include <stdio.h>

#include <tchar.h>

#include <iostream>


#include <opencv.hpp>

////////////////////////////////////////////////////////////////////////////


int main(int argc, char* argv[])

{

	const char* in_file_name = "D:\\alles\\тестовые видео\\T_CAMERA_A.avi";


	cv::VideoCapture cap;


	cap.open(in_file_name);

	//cap.set(CV_CAP_PROP_POS_MSEC, 10 * 1000);


	if (!cap.isOpened())

	{

		std::cout << "File read error!" << std::endl;

		return 1;

	}


	double fps = cap.get(CV_CAP_PROP_FPS);

	if (fps < 1)

		fps = 30;

	cv::Size frame_size((int)cap.get(CV_CAP_PROP_FRAME_WIDTH), (int)cap.get(CV_CAP_PROP_FRAME_HEIGHT));


	const int RESIZE_K = 8;


	frame_size.width /= RESIZE_K / 2;

	frame_size.height /= RESIZE_K;

	cv::Mat frameResult(frame_size, CV_8UC3);

	frame_size.width /= 2;


	size_t f_counter = 0;


	cv::Mat cap_frame;

	cv::Mat frame1;

	cv::Mat frame2;

	cv::Mat flow;


	cv::namedWindow("flow", CV_WINDOW_NORMAL);


	for (cap >> cap_frame; !cap_frame.empty(); cap >> cap_frame)

	{

		cv::resize(cap_frame, frame1, cv::Size(frame_size.width, frame_size.height), 0.0, 0.0, cv::INTER_LINEAR);


		int64 start_time = cv::getTickCount();

		if (!frame1.empty() && !frame2.empty())

		{

			cv::calcOpticalFlowSF(frame1, frame2, flow, 3, 2, 4, 4.1, 25.5, 18, 55.0, 25.5, 0.35, 18, 55.0, 25.5, 10);

		}

		int64 end_time = cv::getTickCount();


		if (!flow.empty())

		{

			frame1.copyTo(cv::Mat(frameResult, cv::Rect(0, 0, frame1.cols, frame1.rows)));


			cv::Mat flowImg(cv::Mat(frameResult, cv::Rect(frame1.cols, 0, frame1.cols, frame1.rows)));

			frame1.copyTo(flowImg);


			cv::Scalar color(255, 0, 255);

			const int step = 4;

			for (int y = step / 2; y < flow.rows; y += step)

			{

				for (int x = step / 2; x < flow.cols; x += step)

				{

					cv::Vec2f flow_at_point = flow.at<cv::Vec2f>(y, x);


					cv::line(flowImg, cv::Point(x, y), cv::Point(x + (int)flow_at_point[0], y + (int)flow_at_point[1]), color, 1, 8, 0);

				}

			}


			cv::imshow("flow", frameResult);

		}


		int64 work_time = (double)((double)(end_time - start_time) / cv::getTickFrequency());

		int frame_time = (int)std::max<int64>(int64(1000. / fps) - work_time, 1);

		std::cout << "Frame " << f_counter++ << ": fps = " << fps << "; work time = " << work_time << "; frame time = " << frame_time << std::endl;


		if (cv::waitKey(frame_time) == 27)

			break;


		frame1.copyTo(frame2);

	}

	cv::destroyAllWindows();


	return 0;

}

////////////////////////////////////////////////////////////////////////////

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

для сравнения алгоритмов

http://vision.middlebury.edu/flow/

3, 2, 4, 4.1, 25.5, 18, 55.0, 25.5, 0.35, 18, 55.0, 25.5, 10);

что то уж очень много у него параметров.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Глобальные методы типа Хорна-Шанка хорошо решают эту проблему, но они медленные. Локальные, типа Лукаса-Канаде, методы лажают.

Многие современные гибриды работают нормально.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

С августа текущего года начал программировать.

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

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

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

1.1 Я сам представлял кадр с камеры как матрицу коэффициентов свечения пикселей, потом пробовал пересчитывать смещение отдельных групп элементов. Не углубляясь в дальнейшее объяснение скажу, что это хрень получается, особенно, если делать это в одиночку.

1.2 Метод статичного фона из примеров опенцэвэ. Очень много шумов, нет границ объектов, да и вычленение отдельных объектов - задача практически невыполнимая, овчинка выделки не стоит.

2. Меня весьма спас метод кодовой книги (codebook). Действенная штука, шаблоны движения, всё такое. Но опять же - даже если подбирать определенные параметры среднестатистического человека и ставить ограничение по размерам движущихся областей с учетом масштаба и расстояния от камеры до объекта слежения - всё равно очень сильно косячит. В счетчике посетителей не должно быть деление одного объекта на два. Программа должна четко распознавать одного человека как один объект, и тут только один выход - третий пункт моих экспериментов, каскады

3. Каскады. В моём случае каскады Хаара, а именно распознавание лиц. Программа делает дополнительную фишечку - через область интересов распознанное каскадами лицо сохраняется в базу данных посетителей. Так вот на нем я и остановился.

Теперь особенности разработки: в моем случае используются 6 IP камер от шведов (Axis). Быстродействие, даже с самым современным компьютером, тут играет огромную роль, поэтому сразу отбрасываю вариант использования Лукаса-Канаде, ибо он, по отзывам, жрет очень много ресурсов.

Итак, есть лица или же upperbody\lowerbody. Проблема с подсчетом заключается только в трекинге.

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

В моем случае трекинг осуществляется покадровым методом, т.е. поиск признаков Хаара сам выдает прямоугольную область объекта, следовательно проблема моя только в том, что мне несколько раз при пересечении границы попадается один и тот же человек. Причем люди бывают разные - кто-то проходит данную границу шириной в 8 пикселей за один кадр, кто-то за три кадра ну и так далее.

Следовательно, мои соображения сделать временнОй дедлайн для нахождения в кадре посетителя (это считается чисто логически - сколько здравомыслящий человек может простоять на входе в торговый центр, где люди обычно не задерживаются, а так же учитвать среднюю скорость движения человека и расстояние с учетом масштаба от верхнего края плоскости, по которой ходят посетители, до нижнего). Это определит максимальное количество кадров для работы "отсеивателя", который будет работать для уничтожения схожих объектов.

Отсеиватель я сейчас думаю построить на SURF\SIFT, поскольку фактически для трех-пяти кадров проблема эта позволяет использовать область интересов лица и само лицо как плоский объект для вычленения похожих.

Уважаемые знатоки, внимание, вопрос: я правильно думаю или мне надо думать в другую сторону?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Вроде все логично.

Я думаю, что тут еще понадобится именно трекер, можно стащить реализацию например из http://code.google.com/p/cvblob/ там есть модуль траекторий (cvtrack.cpp), может быть это позволит избавиться от ресурсоемкого модуля распознавания. И нужно будет приделать фильтр положения центра (xc,yc) и размера трекаемой области (w,h) (можно использовать Cumulative moving average по 5-10 кадрам, например можно почитать здесь http://en.wikipedia.org/wiki/Moving_average).

ЗЫ: отслеживаемые объекты, в данном случае не блобы, а прямоугольники, найденные детектором Хаара.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Тут еще есть исходники по трекерам: http://www.codeguru.com/cpp/cpp/algorithms/math/article.php/c15171/Implementing-a-Simple-2D-Object-Tracker.htm

Может и не совсем Ваш случай, но почитать думается не помешает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Теперь особенности разработки: в моем случае используются 6 IP камер от шведов (Axis). Быстродействие, даже с самым современным компьютером, тут играет огромную роль, поэтому сразу отбрасываю вариант использования Лукаса-Канаде, ибо он, по отзывам, жрет очень много ресурсов.

...

Отсеиватель я сейчас думаю построить на SURF\SIFT, поскольку фактически для трех-пяти кадров проблема эта позволяет использовать область интересов лица и само лицо как плоский объект для вычленения похожих.

Уважаемые знатоки, внимание, вопрос: я правильно думаю или мне надо думать в другую сторону?

Думаю, что правильно. Я как-то раз пробовал такое делать, простенькие примеры выкладывал здесь, на форуме. Так вот, ты предлагаешь:

1. найти объект каким-нибудь классификатором (каскады Хаара для лица, тела, HOG);

2. на объекте найти особенные точки (SURF, SIFT, GoodFeaturesToTrack, просто сетку точек на объекте, построить гистограмму);

3. отслеживать эти особенные точки (сравнение дескрипторов, оптический поток Лукаса-Канаде, блочный метод, MeanShift по гистограмме и т.д.);

4. после пересечения линии или по таймауту прекращать отслееживание.

Правильно?

Если так, то можно использовать практически любые алгоритмы, не задумываясь о быстродействии. Почему? Потому что точек будет немного, на скорости практически не скажется, это не всё изображение обсчитывать.

Если интересно, то в последней OpenCV, собранной из исходников, я видел пример hybridtrackingsample. Он использует практически вышеописанный метод, совмещая в себе одновременно MeanShift и отслеживание особых точек на выбор (SURF, SIFT и GoodFeaturesToTrack). Я его не запускал, только исходники глянул.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Добрый День! Подскажите пожалуйста, как лучше реализовать систеу слежения за перемещениями человека, если перемещения только в горизонтальной плоскости. Мне еще нужно определять растояние, пройденное человеком за кадр. Это расстояние будет входными данными для контроллера шагового двигателя, который будет поворачивать систему с другой камерой на угол, такой, чтобы человек всегда был в центре кадра этой камеры-на нее идет запись. Следящая камера неподвижна!

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Лекции по мультиобъектному трекингу (Multi Object Tracking Tutorial: part 1-3 by Student Dave):

http://www.youtube.com/results?search_query=Multi+Object+Tracking+Tutorial

Сайт с матлабовскими исходниками:

http://studentdavestutorials.weebly.com/

Видео с тараканами можно скачать здесь (после бесплатной регистрации можно скачать образец бесплатно):

http://footage.shutterstock.com/clip-2608427-stock-footage-cockroach-like-bugs-running-around-on-a-light-gray-background.html

Пояснение и реализация Венгерского алгоритма (решение задачи назначениях) с картинками:

http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=hungarianAlgorithm

Завернул программку (Венгерский алгоритм) в шаблон:

main.cpp

Решатель прямоугольной задачи о назначениях:

main.cpp

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

В новом матлабе добавили пример мультитрекинга:

http://www.mathworks.com/help/vision/examples/motion-based-multiple-object-tracking.html

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Повозился с мультитрекингом, по мотивам лекций student Dave (см. выше).

Хотел трекать тараканов, как у него, но пока ограничился готовыми точками, которые крутятся вокруг курсора, часто пересекаясь, но траектории не перепутываются ( фильтр настроен на довольно медленные перемещения курсора ). Код еще сыроват, но поиграть можно. В аттаче проект под 2010 студию настроенный под x64.

MultitargetTracker4.rar

Патч (немного причесал, убрал пару утечек памяти):

TrackerAndKalman.rar

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

Видео раза в полтора медленнее оригинала:

PS: попробовал на тараканах (для отделения переднего плана, использовал VIBE от BeS), в принципе сносно.

Ограничил длину треков 10 шагами, чтобы не путались.

post-1-0-59554100-1372335427_thumb.png

post-1-0-01857600-1372275978_thumb.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

еще метод с кодом

http://www.gris.informatik.tu-darmstadt.de/~aandriye/dctracking.html

судя по видео как раз работает с перекрывающимися объектами

http://info.ee.surrey.ac.uk/Personal/Z.Kalal/Publications/2009_olcv.pdf

если объект меняется

с перекрытием

http://imp.iis.sinica.edu.tw/ivclab/research/batracker/index.html

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Добрый день, разбираюсь с проектом MultitargetTracker от Smorodov

Повозился с мультитрекингом, по мотивам лекций student Dave (см. выше).

Хотел трекать тараканов, как у него, но пока ограничился готовыми точками, которые крутятся вокруг курсора, часто пересекаясь, но траектории не перепутываются ( фильтр настроен на довольно медленные перемещения курсора ). Код еще сыроват, но поиграть можно. В аттаче проект под 2010 студию настроенный под x64.

появились вопросы

CTracker(float _dt, float _Accel_noise_mag,...

первый параметр это шаг времени опроса фильтра, по умолчанию равно 0,2. В чём оно задано в милисекундах?

второй параметр не могли бы пояснить, что он означает..

венгерский алгоритм тут используется как "сопоставлялка", ну к примеру есть 20 детектов, т.е. как я понимаю 20 объектов, которые выделил детектор и далее мы этот массив передаём в трекер tracker.Update(centers); и каждому треку уже как бы "выделенному" назначается наиболее похожий детект(это решается с помощью венгерского алгоритма) далее если есть не использованные детекты то создаём для них новые треки так.. а если есть не используемые треки, то удаляем их если если трек долго не используется(ну как в алгоритме)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Как я понимаю теорию, первый параметр это время в секундах, второй - задает степень непредсказуемости системы (вероятностная составляющая сигнала управления). По поводу Венгерского алгоритма вроде все так как Вы пишите, если я чего не упустил в вопросе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

а не будет ли лучше если вместо фильтра Калмана использовать фильтр частиц, я сам пока не разбирался хотелось бы узнать какой будет лучше

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Нет, второй параметр - это свойство системы.

То есть мы не наблюдаем сигналы управления (например мухой :) ) и не знаем куда она сейчас захочет бежать (принимаем за шум).

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

Это шум процесса, еще есть шум измерения, ну это думаю понятно.

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

И еще, про dt - можно конечно его менять, но тогда пересчитывайте матрицы с его участием (а там и инверсия есть), это дорого, поэтому берут постоянным.

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

Для того, чтобы использовать фильтр частиц, нужно уметь вычислить вероятность нахождения объекта в заданной точке. В принципе, фильтр частиц более мощная штука, позволяющая работать и с нелинейными системами. По сути дела, процесс фильтрации здесь заключается в измерении вероятности нахождения объекта в каждой точке (множестве из N равномерно распределенных точек), нахождении его положения методом взвешенной суммы измерений (масса с которой берется точка пропорциональна вероятности нахождения в ней объекта). Генерации нового поколения частиц. При этом происходит полная замена предыдущих частиц их потомками (таким же количеством штук). Но плодовитость частицы, опять же, определяется вероятностью, что там находится объект. Потомки обычно имеют параметры близкие к параметрам родителя, но с небольшим рандомом, параметры которого являются параметрами фильтра (например координаты и скорость). Это не единственный вариант фильтра частиц, но по сути они все похожи.

UPD:

По фильтру Кальмана набрел на книжку (последняя редакция третья):

Grewal, Andrews. Kalman Filtering: Theory and Practice using MATLAB.

и решения задачек к ней:

A Solution Manual and Notes for:

Kalman Filtering: Theory and Practice using MATLAB

by Mohinder S. Grewal and Angus P. Andrews.

В сети ищутся "на раз".

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×