public void FindMatches(Matrix <float> dbDescriptors, Matrix <float> queryDescriptors, ref IList <IndecesMapping> imap) { var indices = new Matrix <int>(queryDescriptors.Rows, 2); // matrix that will contain indices of the 2-nearest neighbors found var dists = new Matrix <float>(queryDescriptors.Rows, 2); // matrix that will contain distances to the 2-nearest neighbors found Console.WriteLine(2); // create FLANN index with 4 kd-trees and perform KNN search over it look for 2 nearest neighbours //var indexParams = new LshIndexParams(10, 10, 0); KdTreeIndexParams indexParams = new KdTreeIndexParams(4); var flannIndex = new Index(dbDescriptors, indexParams); flannIndex.KnnSearch(queryDescriptors, indices, dists, 2, 24); Console.WriteLine(3); for (int i = 0; i < indices.Rows; i++) { // filter out all inadequate pairs based on distance between pairs if (dists.Data[i, 0] < (0.6 * dists.Data[i, 1])) { // find image from the db to which current descriptor range belongs and increment similarity value. // in the actual implementation this should be done differently as it's not very efficient for large image collections. foreach (var img in imap) { if (img.IndexStart <= i && img.IndexEnd >= i) { img.Similarity++; break; } } } } }
public Matcher() { ip = new Emgu.CV.Flann.KdTreeIndexParams(); sp = new SearchParams(); matcher = new FlannBasedMatcher(ip, sp); _disposables.Add(ip); _disposables.Add(sp); _disposables.Add(matcher); }
//public static long Classify(VectorOfKeyPoint modelKeyPoints, Mat modelDescriptors, Mat observedImage, double uniquenessThreshold, int k, int detectionType) public static long Classify(Mat modelDescriptors, Mat observedImage, double uniquenessThreshold, int k, int detectionType) { var score = 0L; using (var matches = new VectorOfVectorOfDMatch()) { Mat mask = null; //Mat homography = null; var observedKeyPoints = new VectorOfKeyPoint(); var obsImage = new Mat(); CvInvoke.Threshold(observedImage, obsImage, 127.0, 255.0, ThresholdType.BinaryInv); using (UMat uObservedImage = obsImage.GetUMat(AccessType.Read)) { switch (detectionType) { default: using (var featureDetector = new SIFT(0, 3, 0.04, 10.0, 1.6)) { var observedDescriptors = new Mat(); featureDetector.DetectAndCompute(uObservedImage, null, observedKeyPoints, observedDescriptors, false); using (var ip = new KdTreeIndexParams()) using (var sp = new SearchParams()) using (DescriptorMatcher matcher = new FlannBasedMatcher(ip, sp)) { matcher.Add(modelDescriptors); matcher.KnnMatch(observedDescriptors, matches, k, null); mask = new Mat(matches.Size, 1, DepthType.Cv8U, 1); mask.SetTo(new MCvScalar(255)); Features2DToolbox.VoteForUniqueness(matches, uniquenessThreshold, mask); score = 0; for (int i = 0; i < matches.Size; i++) { if (mask.GetData(i)[0] == 0) { continue; } foreach (var e in matches[i].ToArray()) { ++score; } } //var nonZeroCount = CvInvoke.CountNonZero(mask); //if (nonZeroCount >= 4) //{ // nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, matches, mask, 1.5, 20); // if (nonZeroCount >= 4) // homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, matches, mask, 2); //} } } break; case 1: using (var featureDetector = new KAZE()) { var observedDescriptors = new Mat(); featureDetector.DetectAndCompute(uObservedImage, null, observedKeyPoints, observedDescriptors, false); using (var ip = new KdTreeIndexParams()) using (var sp = new SearchParams()) using (DescriptorMatcher matcher = new FlannBasedMatcher(ip, sp)) { matcher.Add(modelDescriptors); matcher.KnnMatch(observedDescriptors, matches, k, null); mask = new Mat(matches.Size, 1, DepthType.Cv8U, 1); mask.SetTo(new MCvScalar(255)); Features2DToolbox.VoteForUniqueness(matches, uniquenessThreshold, mask); score = 0; for (int i = 0; i < matches.Size; i++) { if (mask.GetData(i)[0] == 0) { continue; } foreach (var e in matches[i].ToArray()) { ++score; } } //var nonZeroCount = CvInvoke.CountNonZero(mask); //if (nonZeroCount >= 4) //{ // nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, matches, mask, 1.5, 20); // if (nonZeroCount >= 4) // homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, matches, mask, 2); //} } } break; } } } return(score); }
/// <summary> /// The method used to discover similarities amongst the images, and populating arrays. /// </summary> /// <param name="m_modelImage"> The model image (library basic). </param> /// <param name="m_observedImage"> The observed image (test). </param> /// <param name="d_matchTime"> The output total time for computing the homography matrix. </param> /// <param name="v_modelKeyPoints"></param> /// <param name="v_observedKeyPoints"></param> /// <param name="v_matches"></param> /// <param name="m_mask"></param> /// <param name="m_homography"></param> /// <param name="l_score"> Field contains the score of matching. </param> public static void FindMatch(Mat m_modelImage, Mat m_observedImage, out double d_matchTime, out VectorOfKeyPoint v_modelKeyPoints, out VectorOfKeyPoint v_observedKeyPoints, VectorOfVectorOfDMatch v_matches, out Mat m_mask, out Mat m_homography, out long l_score) { ErrInfLogger.LockInstance.InfoLog("Start of the FindMatch"); TimerAbstraction _tim = new TimerRefinedAbstraction(); _tim._iTimer = new TimerFractional(); m_homography = null; v_modelKeyPoints = new VectorOfKeyPoint(); v_observedKeyPoints = new VectorOfKeyPoint(); KAZE featureDetector = new KAZE(); Mat modelDescriptors = new Mat(); featureDetector.DetectAndCompute(m_modelImage, null, v_modelKeyPoints, modelDescriptors, false); _tim.MeasureStart(); Mat observedDescriptors = new Mat(); featureDetector.DetectAndCompute(m_observedImage, null, v_observedKeyPoints, observedDescriptors, false); // KdTree for faster results / less accuracy using (KdTreeIndexParams ip = new KdTreeIndexParams()) using (SearchParams sp = new SearchParams()) using (DescriptorMatcher matcher = new FlannBasedMatcher(ip, sp)) { matcher.Add(modelDescriptors); matcher.KnnMatch(observedDescriptors, v_matches, SettingsContainer.Instance.i_K, null); m_mask = new Mat(v_matches.Size, 1, DepthType.Cv8U, 1); m_mask.SetTo(new MCvScalar(255)); Features2DToolbox.VoteForUniqueness(v_matches, SettingsContainer.Instance.d_UniquenessThreshold, m_mask); // Calculate score based on matches size // ----------------------------------------------> l_score = 0; for (int i = 0; i < v_matches.Size; i++) { if (m_mask.GetData(i)[0] == 0) { continue; } foreach (var e in v_matches[i].ToArray()) { ++l_score; } } // <---------------------------------------------- int nonZeroCount = CvInvoke.CountNonZero(m_mask); if (nonZeroCount >= 4) { nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(v_modelKeyPoints, v_observedKeyPoints, v_matches, m_mask, 1.5, 20); if (nonZeroCount >= 4) { m_homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(v_modelKeyPoints, v_observedKeyPoints, v_matches, m_mask, 2); } } } _tim.MeasureStop(); d_matchTime = Math.Round(_tim.MeasureResult().TotalMilliseconds, 2); _tim.MeasureRestart(); ErrInfLogger.LockInstance.InfoLog("End of the FindMatch"); }