protected override void DisposeObject() { if (_modelKeypoints != null) { _modelKeypoints.Dispose(); _modelKeypoints = null; } if (_modelDescriptors != null) { _modelDescriptors.Dispose(); _modelDescriptors = null; } if (_modelDescriptorMatcher != null) { _modelDescriptorMatcher.Dispose(); _modelDescriptorMatcher = null; } if (_octagon != null) { _octagon.Dispose(); _octagon = null; } }
/// <summary> /// Match feature points using symmetry test and RANSAC /// </summary> /// <param name="image1">input image1</param> /// <param name="image2">input image2</param> /// <param name="keypoints1">output keypoint1</param> /// <param name="keypoints2">output keypoint2</param> /// <returns>return fundemental matrix</returns> public Image <Bgr, Byte> Match(Image <Gray, Byte> image1, Image <Gray, Byte> image2, ref VectorOfKeyPoint keypoints1, ref VectorOfKeyPoint keypoints2, bool computeModelFeatures) { //1a. Detection of the SURF features keypoints2 = null; if (computeModelFeatures == true) { keypoints1 = this._Detector.DetectKeyPointsRaw(image1, null); } keypoints2 = this._Detector.DetectKeyPointsRaw(image2, null); //1b. Extraction of the SURF descriptors Matrix <float> descriptors1 = this._Detector.ComputeDescriptorsRaw(image1, null, keypoints1); Matrix <float> descriptors2 = this._Detector.ComputeDescriptorsRaw(image2, null, keypoints2); //2. Match the two image descriptors //Construction of the match BruteForceMatcher <float> matcher = new BruteForceMatcher <float>(DistanceType.L2); //from image 1 to image 2 //based on k nearest neighbours (with k=2) matcher.Add(descriptors1); //Number of nearest neighbors to search for int k = 2; int n = descriptors2.Rows; //The resulting n*k matrix of descriptor index from the training descriptors Matrix <int> trainIdx1 = new Matrix <int>(n, k); //The resulting n*k matrix of distance value from the training descriptors Matrix <float> distance1 = new Matrix <float>(n, k); matcher.KnnMatch(descriptors2, trainIdx1, distance1, k, null); matcher.Dispose(); //from image 1 to image 2 matcher = new BruteForceMatcher <float>(DistanceType.L2); matcher.Add(descriptors2); n = descriptors1.Rows; //The resulting n*k matrix of descriptor index from the training descriptors Matrix <int> trainIdx2 = new Matrix <int>(n, k); //The resulting n*k matrix of distance value from the training descriptors Matrix <float> distance2 = new Matrix <float>(n, k); matcher.KnnMatch(descriptors1, trainIdx2, distance2, k, null); //3. Remove matches for which NN ratio is > than threshold int removed = RatioTest(ref trainIdx1, ref distance1); removed = RatioTest(ref trainIdx2, ref distance2); //4. Create symmetrical matches Matrix <float> symMatches; int symNumber = SymmetryTest(trainIdx1, distance1, trainIdx2, distance2, out symMatches); //--------------modified code for zero matches------------ if (symNumber == 0) // no proper symmetrical matches, should retry in this case { return(null); } //-----------------end modified code---------------------- Matrix <double> fundementalMatrix = ApplyRANSAC(symMatches, keypoints1, keypoints2, symNumber);//, image2); // Image<Bgr, Byte> resultImage = Features2DToolbox.DrawMatches(image1, modelKeyPoints, image2, observedKeyPoints, //indices, new Bgr(255, 0, 0), new Bgr(0, 255, 0), mask, Features2DToolbox.KeypointDrawType.DEFAULT); // return resultImage; return(null); // we do our own drawing of correspondences }