使用光流的点跟踪

时间:2014-05-15 04:11:49

标签: c# opencv image-processing emgucv opticalflow

您好我正在尝试将点跟踪应用于场景。

现在我想让这些点只能水平移动。有没有人对此有任何想法? 数组“Actual”和“nextfeature”包含相关的x,y坐标。我试图从两个阵列中获得差异,但它没有用。我尝试使用Farneback获得光流,但它没有给我一个令人满意的结果。我真的很感激,如果有人能给我任何想法,如何让积分只在水平线上移动。

感谢。

这是代码。

    private void ProcessFrame(object sender, EventArgs arg)
    {


        PointF[][] Actual = new PointF[0][];

        if (Frame == null) 
        {

            Frame = _capture.RetrieveBgrFrame();

            Previous_Frame = Frame.Copy();

        }

        else
        {

            Image<Gray, byte> grayf = Frame.Convert<Gray, Byte>();

            Actual = grayf.GoodFeaturesToTrack(300, 0.01d, 0.01d, 5);


            Image<Gray, byte> frame1 = Frame.Convert<Gray, Byte>();
            Image<Gray, byte> prev = Previous_Frame.Convert<Gray, Byte>();
            Image<Gray, float> velx = new Image<Gray, float>(Frame.Size);
            Image<Gray, float> vely = new Image<Gray, float>(Previous_Frame.Size);



            Frame = _capture.RetrieveBgrFrame().Resize(300,300,Emgu.CV.CvEnum.INTER.CV_INTER_AREA);

            Byte []status;
            Single[] trer;
            PointF[][] feature = Actual;
            PointF[] nextFeature = new PointF[300];



            Image<Gray, Byte> buf1 = new Image<Gray, Byte>(Frame.Size);
            Image<Gray, Byte> buf2 = new Image<Gray, Byte>(Frame.Size);
            opticalFlowFrame = new Image<Bgr, Byte>(prev.Size);

            Image<Bgr, Byte>  FlowFrame = new Image<Bgr, Byte>(prev.Size);


            OpticalFlow.PyrLK(prev, frame1, Actual[0], new System.Drawing.Size(10, 10), 0, new MCvTermCriteria(20, 0.03d),
                     out nextFeature, out status, out trer);




            for (int x = 0; x < Actual[0].Length ; x++)
            {
                opticalFlowFrame.Draw(new CircleF(new PointF(nextFeature[x].X, nextFeature[x].Y), 1f), new Bgr(Color.Blue), 2);

            }

            new1 = old;
            old = nextFeature;

            Actual[0] = nextFeature;



            Previous_Frame = Frame.Copy();
            captureImageBox.Image = Frame;
            grayscaleImageBox.Image = opticalFlowFrame;


            //cannyImageBox.Image = velx;

            //smoothedGrayscaleImageBox.Image = vely;
        }
    }

1 个答案:

答案 0 :(得分:0)

首先......我只能给你一个关于此的一般概念,而不是代码片段......

以下是您可以这样做的方法: (解决此问题的众多可行方法之一)

  1. 取第零帧并通过 goodFeaturesToTrack 传递。收集数组中的点...比如, initialPoints

  2. 抓住第(0 + 1)帧。关于从步骤1中获取的点,通过 calcOpticalFlowPyrLK 运行它。将下一个点存储在另一个数组中......例如, nextPoints 。还要跟踪状态错误向量。

  3. 现在,随着 initialPoints nextPoints ,我们将放弃openCV的舒适度并以我们的方式做事。对于 initialPoints nextPoints 中的每个功能(状态设置为1且错误低于可接受的阈值),我们计算点之间的梯度。

  4. 仅接受水平运动的那些点,其斜率角度约为0度或180度。现在......矢量方向不会完美地位于0或180 ......所以要考虑一点+/-阈值。

  5. 对所有帧重复步骤1到4。

    浏览您发布的代码......似乎您几乎已经执行了第1步和第2步。

    然而,一旦你得到了矢量 nextFeature ,你好像在画它周围的圆圈。有趣......但不是我们需要的。

    检查您是否可以实施渐变计算和过滤。