У меня есть проект по созданию приложения, в котором пользователь может рисовать интересующую область (в этом примере прямоугольник вокруг транспортного средства для отслеживания), и оно будет автоматически отслеживать транспортное средство в последующих кадрах записанного видео.
Метод, который я реализовал до сих пор с использованием 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;
}
}