Отслеживание в видео последовательности с определенной пользователем целью для отслеживания
У меня есть проект по созданию приложения, в котором пользователь может нарисовать интересующую область (в этом примере - прямоугольник вокруг транспортного средства для отслеживания), и оно будет автоматически отслеживать транспортное средство в последующих кадрах записанного видео.
Метод, который я реализовал до сих пор с использованием OpenCV, выглядит следующим образом:
(1) Получить пользовательский прямоугольник (область интереса) из
initial_frame
(2) Использование
goodFeaturesToTrack
в области интересов и хранитьinitial_features
(3) Переходите к следующим кадрам в видео
3.1: Получить
next_frame
3.2: Позвонить
calcOpticalFlowPyrLK(prevImg, nextImg, prevPts, nextPts,...)
*где
prevImg
всегдаinitial_frame
а такжеprevPts
всегдаinitial_featues
и каждый раз я только обновляю
nextImg
со следующим кадром видео3.3: Получить ограничивающий прямоугольник для недавно найденных функций из
nextPts
3.4: Показать рамку с ограничительным прямоугольником
Этот метод работает в большинстве из 50 последовательных кадров, за исключением нескольких раз, когда отслеживание приводит к чему-то вроде этого:
но после 50 кадров результаты становятся все менее и менее точными:
Имеет смысл, что функции, обнаруженные в исходном изображении, становятся все менее и менее распространенными в последующих кадрах, поэтому я ищу идеи о том, как улучшить этот метод отслеживания или, возможно, найти лучший метод в целом.
Один из них - использование фильтра Калмана, однако у меня нет представления о том, какие параметры использовать для измерения и динамические параметры, и как обновить измерения с помощью функций, обнаруженных в оптическом потоке. Я открыт для любых предложений или даже совершенно других методов для отслеживания объектов в такого рода приложениях.
* Примечание: эта функция используется для получения ограничительного прямоугольника массива объектов, возвращаемых из оптического потока (здесь я использую EMGUCV):
public Rectangle RectFromPoints(List<PointF> points)
{
using (MemStorage stor = new MemStorage())
{
Contour<PointF> contour = new Contour<PointF>(stor);
// Remove points far outside the major grouping of all the other points
var newPoints = RemoveOutlierPoints(points);
foreach(PointF pnt in newPoints)
{
contour.Push(pnt);
}
var contPoly = contour.ApproxPoly(3, stor);
var rect = contPoly.BoundingRectangle;
return rect;
}
}
3 ответа
В OpenCV 3.0 contrib есть несколько трекеров (TLD, MEDIANFLOW, BOOSTING и MIL). Вы также можете найти пример CPP. Сравнение производительности современных трекеров доступно на странице VOTchallenge.
Попробуйте использовать корреляционный трекер. Современные из них довольно хороши, например: https://www.youtube.com/watch?v=-8-KCoOFfqs. Вы также можете получить код для этого в dlib.
Добрый день. То, что у вас есть, это проблема дрейфа. Функции, которые вы использовали впервые, предназначены только для объекта. но по мере того как новый кадр обновляет старый шаблон, некоторая часть фонового беспорядка включена в изображение в качестве нового шаблона. вам нужно обновить ваш шаблон аналогичным шаблоном, и есть алгоритмы, такие как BMR-настройка.