public override FeatureMatchResult Match(Mat sourceMat, Mat searchMat, FeatureMatchArgument argument) { //创建SIFT using var sift = SIFT.Create(); //创建特征点描述对象,为下边的特征点匹配做准备 using var sourceDescriptors = new Mat(); using var searchDescriptors = new Mat(); //提取特征点,并进行特征点描述 sift.DetectAndCompute(sourceMat, null, out var sourceKeyPoints, sourceDescriptors); sift.DetectAndCompute(searchMat, null, out var searchKeyPoints, searchDescriptors); //创建Brute-force descriptor matcher using var bfMatcher = new BFMatcher(); //对原图特征点描述加入训练 bfMatcher.Add(new List <Mat>() { sourceDescriptors }); bfMatcher.Train(); //获得匹配特征点,并提取最优配对 var matches = bfMatcher.KnnMatch(sourceDescriptors, searchDescriptors, (int)argument.MatchPoints); argument.OutputDebugMessage($"[FeatureMatch] [SIFT] The number of matching points is ({matches.Length})."); //即使使用SIFT算法,但此时没有经过点筛选的匹配效果同样糟糕,所进一步获取优秀匹配点 var goodMatches = SelectGoodMatches(matches, argument, sourceKeyPoints, searchKeyPoints); //获取匹配结果 var matchResult = GetMatchResult(goodMatches, sourceKeyPoints, searchKeyPoints); argument.OutputDebugMessage($"[FeatureMatch] [SIFT] The result of the match is ({matchResult.Success}) ({matchResult.MatchItems.Count})."); if (matchResult.Success) { var bestMatch = matchResult.MatchItems[0]; argument.OutputDebugMessage($"[FeatureMatch] [SIFT] The center point of the best match is ({bestMatch.Point}), and the rect is {bestMatch.Rectangle}."); } argument.PreviewDebugFeatureMatchResult(matchResult, sourceMat, searchMat, sourceKeyPoints, searchKeyPoints, goodMatches); return(matchResult); }