Brute-Force匹配器也就是蛮力匹配器,顾名思义,它的工作原理是:在第一幅图像上选取一个关键点,然后依次与第二幅图像的每个关键点进行(描述符)距离测试,最后返回距离最近的关键点。
对于BF匹配器,我们首先要使用BFMatcher()创建一个BFMatcher对象。它有两个可选参数:
第一个是normType,它用来指定要使用的距离测试类型。
第二个参数是布尔变量corssCheck,默认值为False。如果设置为True,匹配条件就会更加严格,只有到A中的第i个特征点与B中的第j个特征点距离最近,并且B中的第j个特征点到A中的第i个特征点也是最近(A中没有其他的点到j的距离最近)时才会返回最佳匹配(i, j)。也就是这两个特征点要互相匹配才行。这样就能提供统一的结果,这可以用来代替D.Lowe在SIFT文章中提出的比值测试方法。
BFMatcher对象有两个方法,bf.match()和bf.knnMatch()。第一个方法会返回最佳匹配。第二个方法为每个关键点返回k个匹配(降序排列之后取前K个),其中K是由用户设定的。结果出了匹配之外还要做其他事情的话可能会用上(比如进行比值测试)。
下面是一个例子:
代码如下:
//定位关键点,并将要检测的最大关键点数量nfeatures设置为800
var orb = ORB.Create(800);
var descriptors1 = new Mat();
var descriptors2 = new Mat();
//定位给定训练图片中的关键点并计算它们对应的 ORB 描述符
KeyPoint[] keyPoints1=null;
KeyPoint[] keyPoints2=null;
orb.DetectAndCompute(img1, null, out keyPoints1, descriptors1);
orb.DetectAndCompute(img2, null, out keyPoints2, descriptors2);
//创建BFMatcher
var bf = new BFMatcher(NormTypes.Hamming, crossCheck: true);
var matches = bf.Match(descriptors1, descriptors2);
var goodMatches = matches
.OrderBy(x => x.Distance)
.Take(10)
.ToArray();
var srcPts = goodMatches.Select(m => keyPoints1[m.QueryIdx].Pt).Select(p => new Point2d(p.X, p.Y));
var dstPts = goodMatches.Select(m => keyPoints2[m.TrainIdx].Pt).Select(p => new Point2d(p.X, p.Y));
var homography = Cv2.FindHomography(srcPts, dstPts, HomographyMethods.Ransac, 5, null);
int h = img1.Height, w = img1.Width;
var img2Bounds = new[]
{
new Point2d(0, 0),
new Point2d(0, h-1),
new Point2d(w-1, h-1),
new Point2d(w-1, 0),
};
//矩阵变换
var img2BoundsTransformed = Cv2.PerspectiveTransform(img2Bounds, homography);
var view = img2.Clone();
var drawingPoints = img2BoundsTransformed.Select(p => (OpenCvSharp.Point)p).ToArray();
Cv2.Polylines(view, new[] { drawingPoints }, true, Scalar.Red, 3);
Bitmap view_Bitmap = view.ToBitmap();
pictureBox2.Image = view_Bitmap;
感谢您的阅读,喜欢请给个关注和赞,如需完整代码,关注点赞后私信发送“模板匹配”获取。
未经允许请勿转载。