Example #1
0
        /// <summary>
        /// Estimates LK optical flow.
        /// </summary>
        /// <param name="storage">Used storage. Number of pyramid levels is specified within storage. Use storage to gain performance in video* by 2x! </param>
        /// <param name="prevFeatures">Previous features.</param>
        /// <param name="currFeatures">Current features.</param>
        /// <param name="status">Feature status.</param>
        /// <param name="windowSize">Aperture size.</param>
        /// <param name="iterations">Maximal number of iterations. If <paramref name="minFeatureShift"/> is reached then number of iterations will be lower.</param>
        /// <param name="minFeatureShift">Minimal feature shift in horizontal or vertical direction.</param>
        /// <param name="minEigenValue">Minimal eigen value.
        /// Eigen values could be interpreted as lengths of ellipse's axes.
        /// If zero ellipse turn into line therefore there is no corner.</param>
        public static void EstimateFlow(PyrLKStorage <TColor> storage,
                                        PointF[] prevFeatures, out PointF[] currFeatures,
                                        out KLTFeatureStatus[] status,
                                        int windowSize = 15, int iterations = 30, float minFeatureShift = 0.1f, float minEigenValue = 0.001f)
        {
            var initialEstimate = new PointF[prevFeatures.Length];

            currFeatures = new PointF[prevFeatures.Length];
            status       = new KLTFeatureStatus[prevFeatures.Length];

            var scaledPrevFeatures = prevFeatures.Apply(x => x.DownScale(storage.PyrLevels));
            var usedIndicies       = Enumerable.Range(0, prevFeatures.Length).ToArray();

            for (int pyrLevel = storage.PyrLevels; pyrLevel >= 0; pyrLevel--)
            {
                PointF[]           levelCurrFeatures;
                KLTFeatureStatus[] levelStatus;
                LKOpticalFlow <TColor> .EstimateFlow(storage,
                                                     scaledPrevFeatures.GetAt(usedIndicies), out levelCurrFeatures, out levelStatus,
                                                     windowSize, iterations, minFeatureShift, minEigenValue, initialEstimate, pyrLevel);

                //update data
                currFeatures.SetAt(usedIndicies, levelCurrFeatures);
                status.SetAt(usedIndicies, levelStatus);

                if (pyrLevel != 0)
                {
                    scaledPrevFeatures.ApplyInPlace(usedIndicies, x => x.UpScale());
                    currFeatures.ApplyInPlace(usedIndicies, x => x.UpScale());

                    initialEstimate = Sub(currFeatures, scaledPrevFeatures);
                    usedIndicies    = getValidFeatureIndicies(status);
                }
            }
        }