Как реализовать Optical Flow tracker?

Я использую оболочку OpenCV - Emgu CV и пытаюсь реализовать трекер движения с помощью Optical Flow, но я не могу найти способ объединить горизонтальную и вертикальную информацию, полученную из алгоритма OF:

flowx = new Image<Gray, float>(size);
flowy = new Image<Gray, float>(size);

OpticalFlow.LK(currImg, prevImg, new Size(15, 15), flowx, flowy);

Моя проблема не в том, чтобы знать, как объединить информацию о вертикальном и горизонтальном движении, чтобы построить трекер движущихся объектов? Новый образ?

Кстати, есть простой способ отобразить информацию о потоке на текущем кадре?

Заранее спасибо.

3 ответа

Решение

Вот функция, которую я определил в видео-уроке по отслеживанию движений головы на YouTube. Вы можете найти полный исходный код, прикрепленный к видео

void ComputeDenseOpticalFlow()
    {
        // Compute dense optical flow using Horn and Schunk algo
        velx = new Image<Gray, float>(faceGrayImage.Size);
        vely = new Image<Gray, float>(faceNextGrayImage.Size);

        OpticalFlow.HS(faceGrayImage, faceNextGrayImage, true, velx, vely, 0.1d, new MCvTermCriteria(100));            

        #region Dense Optical Flow Drawing
        Size winSize = new Size(10, 10);
        vectorFieldX = (int)Math.Round((double)faceGrayImage.Width / winSize.Width);
        vectorFieldY = (int)Math.Round((double)faceGrayImage.Height / winSize.Height);
        sumVectorFieldX = 0f;
        sumVectorFieldY = 0f;
        vectorField = new PointF[vectorFieldX][];
        for (int i = 0; i < vectorFieldX; i++)
        {
            vectorField[i] = new PointF[vectorFieldY];
            for (int j = 0; j < vectorFieldY; j++)
            {
                Gray velx_gray = velx[j * winSize.Width, i * winSize.Width];
                float velx_float = (float)velx_gray.Intensity;
                Gray vely_gray = vely[j * winSize.Height, i * winSize.Height];
                float vely_float = (float)vely_gray.Intensity;
                sumVectorFieldX += velx_float;
                sumVectorFieldY += vely_float;
                vectorField[i][j] = new PointF(velx_float, vely_float);

                Cross2DF cr = new Cross2DF(
                    new PointF((i*winSize.Width) +trackingArea.X,
                               (j*winSize.Height)+trackingArea.Y),
                               1, 1);
                opticalFlowFrame.Draw(cr, new Bgr(Color.Red), 1);

                LineSegment2D ci = new LineSegment2D(
                    new Point((i*winSize.Width)+trackingArea.X,
                              (j * winSize.Height)+trackingArea.Y), 
                    new Point((int)((i * winSize.Width)  + trackingArea.X + velx_float),
                              (int)((j * winSize.Height) + trackingArea.Y + vely_float)));
                opticalFlowFrame.Draw(ci, new Bgr(Color.Yellow), 1);

            }
        }
        #endregion
    }

Визуализация оптического потока. Общий подход заключается в использовании двумерного поля потока с цветовой кодировкой. Это означает, что мы отображаем поток в виде изображения, где интенсивность пикселя соответствует абсолютному значению потока в пикселе, а оттенок отражает направление потока. Посмотрите на Рис.2 в [ Baker et al., 2009]. Другой способ - нарисовать векторы потока в сетке над первым изображением (скажем, каждые 10 пикселей).

Объединяя х и у. Непонятно, что вы здесь имеете в виду. Пиксель (x,y) из первого изображения перемещается в (x+flowx, y+flowy) во втором. Итак, чтобы отследить объект, вы фиксируете положение объекта на первом изображении и добавляете значение потока, чтобы получить его положение на втором.

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

Другие вопросы по тегам