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(); } } } } }
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); } }