Как реализовать Optical Flow tracker? - PullRequest
5 голосов
/ 27 сентября 2010

Я использую оболочку 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 ]

9 голосов
/ 27 сентября 2010

Вот функция, которую я определил в моем видеоруководстве по отслеживанию движения головы на 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
    }
4 голосов
/ 28 сентября 2010

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

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

0 голосов
/ 27 сентября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...