public bool MatchDescriptorsWithRatioTest(BFMatcher descriptorMatcher, ref Mat descriptorsEvalImage, Mat trainDescriptors, ref VectorOfDMatch matchesFilteredOut, float maxDistanceRatio)
        {
            if (trainDescriptors.Rows < 4)
            {
                return(false);
            }

            matchesFilteredOut.Clear();
            descriptorMatcher.Add(trainDescriptors);

            VectorOfVectorOfDMatch matchesKNN = new VectorOfVectorOfDMatch();

            descriptorMatcher.KnnMatch(descriptorsEvalImage, matchesKNN, 2, null);
            for (int matchPos = 0; matchPos < matchesKNN.Size; ++matchPos)
            {
                if (matchesKNN[matchPos].Size >= 2)
                {
                    if (matchesKNN[matchPos][0].Distance <= maxDistanceRatio * matchesKNN[matchPos][1].Distance)
                    {
                        matchesFilteredOut.Push(new MDMatch[] { matchesKNN[matchPos][0] });
                    }
                }
            }

            return(!(matchesFilteredOut.Size == 0));
        }
        public bool RefineMatchesWithHomography(VectorOfKeyPoint evalKeypoints, VectorOfKeyPoint trainKeypoints, VectorOfDMatch matches,
                                                ref Mat homographyOut, VectorOfDMatch inliersOut, VectorOfInt inliersMaskOut,
                                                float reprojectionThreshold, int minNumberMatchesAllowed)
        {
            if (matches.Size < minNumberMatchesAllowed)
            {
                return(false);
            }

            PointF[] srcPoints = new PointF[matches.Size];
            PointF[] dstPoints = new PointF[matches.Size];

            for (int i = 0; i < matches.Size; ++i)
            {
                srcPoints[i] = trainKeypoints[matches[i].TrainIdx].Point;
                dstPoints[i] = evalKeypoints[matches[i].QueryIdx].Point;
            }

            inliersMaskOut.Clear();
            inliersMaskOut = new VectorOfInt(srcPoints.Count());

            //for(int i = 0; i < srcPoints.Count(); ++i)
            //{
            //    inliersMaskOut = 0;
            //}

            CvInvoke.FindHomography(srcPoints, dstPoints, homographyOut, Emgu.CV.CvEnum.HomographyMethod.Ransac, reprojectionThreshold, inliersMaskOut);

            for (int i = 0; i < inliersMaskOut.Size; ++i)
            {
                if (inliersMaskOut[i] > 0)
                {
                    inliersOut.Push(new MDMatch[] { matches[i] });
                }
            }
            return(inliersOut.Size >= minNumberMatchesAllowed);
        }