使用光流Lucas-Kanade和EmguCV计算实际速度

时间:2017-12-01 07:25:18

标签: c# image-processing emgucv opticalflow

如何使用Lucals-kanade algorithm计算视频中所有移动物体的实际速度来计算光流量? 我需要在这个视频上做这个。相机固定在一个地方(图1) enter image description here

我找到关键点并使用Lucas-Kanade algorithm跟踪它们(图2)enter image description here

如何使用此算法更新每辆车的实际速度?

感谢您的回答!

我的代码:

public class OpticalFlowLK : BaseFilter
{
    private Mat prevFrame;
    private Mat nextFrame;
    private bool prevFrameEmpty = true;
    private GFTTDetector gFTTDetector;
    private Stopwatch sWatch;
    private double time = 0.04;
    public OpticalFlowLK()
    {
        TAG = "[Optical Flow Lucas Kanade]";
        gFTTDetector = new GFTTDetector(500);
        sWatch = new Stopwatch();
    }   
    protected override Mat ProcessFrame(ref Mat frame)
    {
        Mat rez = new Mat();
        frame.CopyTo(rez);
        nextFrame = new Mat();
        Mat gray = new Mat();
        var tmpImg = gray.ToImage<Gray, Byte>();
        CvInvoke.CvtColor(frame, nextFrame, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);
        if (!prevFrameEmpty)
        {
            VectorOfKeyPoint prevFeatures = new VectorOfKeyPoint(gFTTDetector.Detect(prevFrame));
            //Features2DToolbox.DrawKeypoints(rez, prevFeatures, rez, new Bgr(0, 0, 255));
            PointF[] prevPts = new PointF[prevFeatures.Size];
            for (int i = 0; i < prevFeatures.Size; i++)
            {
                prevPts[i] = prevFeatures[i].Point;
            }

            PointF[] nextPts;
            byte[] status;
            float[] errors;
            sWatch.Start();
            CvInvoke.CalcOpticalFlowPyrLK(prevFrame, nextFrame, prevPts, new Size(20, 20), 1, new MCvTermCriteria(20, 0.03), out nextPts, out status, out errors);
            sWatch.Stop();  
            sWatch.Reset();
            prevFrame = nextFrame.Clone();
            for (int i = 0; i < status.Length; i++)
            {
                Point prevPt = new Point((int)prevPts[i].X,(int)nextPts[i].Y);
                Point nextPt = new Point((int)nextPts[i].X,(int)nextPts[i].Y);
                double lenght = Math.Sqrt(Math.Pow(prevPt.X - nextPt.X, 2) + Math.Pow(prevPt.Y - nextPt.Y, 2));
                if (lenght > 3)
                {
                    CvInvoke.Circle(rez, nextPt, 1, new MCvScalar(0, 255, 0), 2);
                }
            }

            sWatch.Stop();
            prevFrameEmpty = false;
        }
        else if (prevFrameEmpty)
        {
            prevFrame = nextFrame.Clone();
            prevFrameEmpty = false;
        }
        return rez;
    }
    protected override bool InitFilter(ref Mat frame)
    {
        throw new NotImplementedException();
    }
}

0 个答案:

没有答案