OpenCvSharp特征点提取与匹配
public static Bitmap MatchPicBySurf(Bitmap imgSrc, Bitmap imgSub, double threshold = 400)
{
Mat matSrc = BitmapConverter.ToMat(imgSrc);
Mat matTo = BitmapConverter.ToMat(imgSub);
Mat matSrcRet = new Mat();
Mat matToRet = new Mat();
KeyPoint[] keyPointsSrc, keyPointsTo;
var Surf = OpenCvSharp.XFeatures2D.SURF.Create(threshold, 4, 3, true, true);
Surf.DetectAndCompute(matSrc, null, out keyPointsSrc, matSrcRet);
Surf.DetectAndCompute(matTo, null, out keyPointsTo, matToRet);
using (var flnMatcher = new OpenCvSharp.FlannBasedMatcher())
{
var matches = flnMatcher.Match(matSrcRet, matToRet);
double minDistance = 1000;
double maxDistance = 0;
for (int i = 0; i < matSrcRet.Rows; i++)
{
double distance = matches[i].Distance;
if (distance > maxDistance)
{
maxDistance = distance;
}
if (distance < minDistance)
{
minDistance = distance;
}
}
var pointsSrc = new List<Point2f>();
var pointsDst = new List<Point2f>();
var goodMatches = new List<DMatch>();
for (int i = 0; i < matSrcRet.Rows; i++)
{
double distance = matches[i].Distance;
if (distance < Math.Max(minDistance * 2, 0.02))
{
pointsSrc.Add(keyPointsSrc[matches[i].QueryIdx].Pt);
pointsDst.Add(keyPointsTo[matches[i].TrainIdx].Pt);
goodMatches.Add(matches[i]);
}
}
var outMat = new Mat();
var pSrc = new List<Point2d>();
var pDst = new List<Point2d>();
foreach (Point2f point in pointsSrc) { pSrc.Add(new Point2d(point.X, point.Y)); }
foreach (Point2f point in pointsDst) { pDst.Add(new Point2d(point.X, point.Y)); }
var outMask = new Mat();
if (pSrc.Count > 0 && pDst.Count > 0)
Cv2.FindHomography(pSrc, pDst, HomographyMethods.Ransac, mask: outMask);
if (outMask.Rows > 10)
{
byte[] maskBytes = new byte[outMask.Rows * outMask.Cols];
outMask.GetArray(out maskBytes);
Cv2.DrawMatches(matSrc, keyPointsSrc, matTo, keyPointsTo, goodMatches, outMat, matchesMask: maskBytes, flags: DrawMatchesFlags.NotDrawSinglePoints);
}
else
Cv2.DrawMatches(matSrc, keyPointsSrc, matTo, keyPointsTo, goodMatches, outMat, flags: DrawMatchesFlags.NotDrawSinglePoints);
return OpenCvSharp.Extensions.BitmapConverter.ToBitmap(outMat);
}
}