public MatcherResult knnMatch(KeyPoints queryDescriptor, BFMatcher matcher, string leafCategory, int distanceCutoff = int.MaxValue, PreProcessedImage trainingData = null)
        {
            MatcherResult result = new MatcherResult();

            result.Category = leafCategory;

            using (VectorOfVectorOfDMatch vectorMatchesForSift = new VectorOfVectorOfDMatch())
            {
                matcher.KnnMatch(queryDescriptor.Descriptor, vectorMatchesForSift, 2, null);

                int numberOfMatches = 0;

                Dictionary <int, int> counts      = new Dictionary <int, int>();
                List <MDMatch>        goodMatches = new List <MDMatch>(vectorMatchesForSift.Size);
                for (int i = 0; i < vectorMatchesForSift.Size; i++)
                {
                    // Do Ratio test: Reject matches where ratio of closest match with second closest if greater than 0.8
                    if (
                        (vectorMatchesForSift[i].Size == 1 ||
                         vectorMatchesForSift[i][0].Distance < 0.75 * vectorMatchesForSift[i][1].Distance) &&
                        vectorMatchesForSift[i][0].Distance < distanceCutoff)
                    {
                        goodMatches.Add(vectorMatchesForSift[i][0]);
                        numberOfMatches++;
                    }
                }

                //goodMatches = clusterBasedOnPoseEstimation(goodMatches, queryDescriptor, trainingData);

                int maxResults = int.MaxValue;
                result.MatchingPoints = goodMatches.Count;
                if (!goodMatches.Any())
                {
                    result.MatchDistance        = float.MaxValue;
                    result.AverageDistance      = 0;
                    result.MatchDistanceWeight  = 0;
                    result.MatchingPointsWeight = 0;
                }
                else
                {
                    result.MatchDistance        = goodMatches.OrderBy(item => item.Distance).Take(maxResults).Sum(item => item.Distance);
                    result.AverageDistance      = result.MatchDistance / result.MatchingPoints;
                    result.MatchDistanceWeight  = 1 / Math.Pow(result.AverageDistance, 2);
                    result.MatchingPointsWeight = result.MatchingPoints * result.MatchingPoints;
                }
            }
            return(result);
        }
        public void startComparingImages(Dictionary <String, BFMatcher> categoryBfmatcherMapping)
        {
            using (PreProcess preProcessAlgorithm = new PreProcess(queryImage))
            {
                using (Image <Gray, Byte> grayScaleImage = preProcessAlgorithm._ImageToGrayScaleUsingConvert())
                {
                    using (FeatureExtractAlgorithm featureSet = new FeatureExtractAlgorithm(grayScaleImage))
                    {
                        using (KeyPoints leafDescriptor = featureSet.SIFTDescriptor())
                        {
                            foreach (var pair in categoryBfmatcherMapping)
                            {
                                if (pair.Key == "abies_concolor")
                                {
                                    continue;
                                }

                                try
                                {
                                    DescriptorMatcher learningAlgo = new DescriptorMatcher();
                                    BFMatcher         bfmatch      = pair.Value;
                                    string            leafCategory = pair.Key;
                                    MatcherResult     result       = learningAlgo.knnMatch(leafDescriptor, bfmatch, leafCategory);
                                    finalResultSet.Add(result);
                                }
                                catch (Exception exception)
                                {
                                    //TODO
                                    //Console.WriteLine(exception.ToString());
                                }
                            }
                            finalResultSet = finalResultSet.OrderByDescending(item => item, new MatcherResultComparer()).Take(3).ToList();
                        }
                    }
                }
            }
        }
Example #3
0
        private List <MatcherResult> QueryImage(string filePath, string expectedCategory)
        {
            using (PreProcess preProcessAlgorithm = new PreProcess(null))
            {
                PreProcessedImage    preProcessedQueryImage = preProcessAlgorithm.Execute(filePath, expectedCategory);
                List <MatcherResult> finalResultSet         = new List <MatcherResult>(this.trainingDataset.Count);
                DescriptorMatcher    learningAlgo           = new DescriptorMatcher();

                foreach (PreProcessedImage trainingData in this.trainingDataset)
                {
                    try
                    {
                        using (BFMatcher trainingMatcher = new BFMatcher(DistanceType.L1))
                        {
                            double areaRatio    = trainingData.ContourArea / preProcessedQueryImage.ContourArea;
                            int    contourDelta = trainingData.NumberOfContours - preProcessedQueryImage.NumberOfContours;
                            //if (areaRatio < 0.1 || areaRatio > 5)
                            //{
                            //    continue;
                            //}

                            //if(contourDelta > 100 || contourDelta < -100)
                            //{
                            //    continue;
                            //}

                            trainingMatcher.Add(trainingData.KeyPoints.Descriptor);
                            MatcherResult result = learningAlgo.knnMatch(preProcessedQueryImage.KeyPoints, trainingMatcher, trainingData.Category, 300, trainingData);
                            result.ContourRatio  = CvInvoke.MatchShapes(trainingData.Contour, preProcessedQueryImage.Contour, Emgu.CV.CvEnum.ContoursMatchType.I3);
                            result.AreaRatio     = areaRatio;
                            result.ContoursDelta = contourDelta;
                            //Console.WriteLine("QueryCategory: {0}, {1}", preProcessedQueryImage.Category, result.ToString());
                            finalResultSet.Add(result);
                        }
                    }
                    catch (Exception exception)
                    {
                        //Console.WriteLine(exception);
                    }
                }

                //IEnumerable<MatcherResult> highConfidenceResults = finalResultSet.Where(item => item.MatchingPoints >= 3);
                //finalResultSet = highConfidenceResults.ToList();
                //// If there are clusters with size great than or equal to 3 , then they have a very high probability of being correct.
                //if (highConfidenceResults.Any())
                //{
                //    //Console.WriteLine("High confidence:" + highConfidenceResults.Count() + " : " + highConfidenceResults.Max(item => item.MatchingPoints));
                //    finalResultSet = highConfidenceResults.ToList();
                //}
                //else
                //{
                //    finalResultSet = finalResultSet
                //                            .Where(item => item.MatchingPoints > 0)
                //                            .GroupBy(item => item.Category)
                //                            .Select(item =>
                //                                new MatcherResult()
                //                                {
                //                                    Category = item.Key,
                //                                    MatchingPoints = item.Sum(result => result.MatchingPoints),
                //                                    MatchDistance = item.Sum(result => result.MatchDistance)
                //                                })
                //                            .ToList();
                //}

                double totalWeightDistance = finalResultSet.Sum(item => item.MatchDistanceWeight);
                double totalWeightPoints   = finalResultSet.Sum(item => item.MatchingPointsWeight);

                //finalResultSet = finalResultSet
                //                    .Where(item => item.MatchingPoints > 0)
                //                    .GroupBy(item => item.Category)
                //                    .Select(item =>
                //                        new MatcherResult()
                //                        {
                //                            Category = item.Key,
                //                            MatchingPoints = item.Sum(result => result.MatchingPoints * result.MatchingPointsWeight) / totalWeightPoints,
                //                            MatchDistance = item.Sum(result => result.MatchDistance * result.MatchDistanceWeight) / totalWeightDistance
                //                        })
                //                    .ToList();

                finalResultSet = finalResultSet
                                 .Where(item => item.MatchingPoints > 0)
                                 .GroupBy(item => item.Category)
                                 .Select(item =>
                                         new MatcherResult()
                {
                    Category       = item.Key,
                    MatchingPoints = item.Sum(result => result.MatchingPointsWeight) / totalWeightPoints,
                    MatchDistance  = item.Sum(result => result.MatchDistanceWeight) / totalWeightDistance
                })
                                 .ToList();

                finalResultSet = finalResultSet.Where(item => item.MatchingPoints > 0).OrderByDescending(item => item, new MatcherResultWeightedComparer()).Take(3).ToList();
                return(finalResultSet);
            }
        }