publicstaticBitmapMatchPicBySift(Bitmap imgSrc,Bitmap imgSub){using(Mat matSrc = imgSrc.ToMat())using(Mat matTo = imgSub.ToMat())using(Mat matSrcRet =newMat())using(Mat matToRet =newMat()){KeyPoint[] keyPointsSrc, keyPointsTo;using(var sift = OpenCvSharp.XFeatures2D.SIFT.Create()){
sift.DetectAndCompute(matSrc,null,out keyPointsSrc, matSrcRet);
sift.DetectAndCompute(matTo,null,out keyPointsTo, matToRet);}using(var bfMatcher =newOpenCvSharp.BFMatcher()){var matches = bfMatcher.KnnMatch(matSrcRet, matToRet,k:2);var pointsSrc =newList<Point2f>();var pointsDst =newList<Point2f>();var goodMatches =newList<DMatch>();foreach(DMatch[] items in matches.Where(x => x.Length >1)){if(items[0].Distance <0.5* items[1].Distance){
pointsSrc.Add(keyPointsSrc[items[0].QueryIdx].Pt);
pointsDst.Add(keyPointsTo[items[0].TrainIdx].Pt);
goodMatches.Add(items[0]);
Console.WriteLine($"{keyPointsSrc[items[0].QueryIdx].Pt.X}, {keyPointsSrc[items[0].QueryIdx].Pt.Y}");}}var outMat =newMat();// algorithm RANSAC Filter the matched resultsvar pSrc = pointsSrc.ConvertAll(Point2fToPoint2d);var pDst = pointsDst.ConvertAll(Point2fToPoint2d);var outMask =newMat();// If the original matching result is null, Skip the filtering stepif(pSrc.Count >0&& pDst.Count >0)
Cv2.FindHomography(pSrc, pDst, HomographyMethods.Ransac,mask: outMask);// If passed RANSAC After processing, the matching points are more than 10.,Only filters are used. Otherwise, use the original matching point result(When the matching point is too small, it passes through RANSAC After treatment,It is possible to get the result of 0 matching points.).if(outMask.Rows >10){byte[] maskBytes =newbyte[outMask.Rows * outMask.Cols];
outMask.GetArray(0,0, 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);}}}
SURF algorithm
publicstaticBitmapMatchPicBySurf(Bitmap imgSrc,Bitmap imgSub,double threshold =400){using(Mat matSrc = imgSrc.ToMat())using(Mat matTo = imgSub.ToMat())using(Mat matSrcRet =newMat())using(Mat matToRet =newMat()){KeyPoint[] keyPointsSrc, keyPointsTo;using(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 =newOpenCvSharp.FlannBasedMatcher()){var matches = flnMatcher.Match(matSrcRet, matToRet);//Finding the Minimum and Maximum Distancedouble minDistance =1000;//Backward approximationdouble 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;}}
Console.WriteLine($"max distance : {maxDistance}");
Console.WriteLine($"min distance : {minDistance}");var pointsSrc =newList<Point2f>();var pointsDst =newList<Point2f>();//Screening better matching pointsvar goodMatches =newList<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);//Compression of new ones with distances less than ranges DMatch
goodMatches.Add(matches[i]);}}var outMat =newMat();// algorithm RANSAC Filter the matched resultsvar pSrc = pointsSrc.ConvertAll(Point2fToPoint2d);var pDst = pointsDst.ConvertAll(Point2fToPoint2d);var outMask =newMat();// If the original matching result is null, Skip the filtering stepif(pSrc.Count >0&& pDst.Count >0)
Cv2.FindHomography(pSrc, pDst, HomographyMethods.Ransac,mask: outMask);// If passed RANSAC After processing, the matching points are more than 10.,Only filters are used. Otherwise, use the original matching point result(When the matching point is too small, it passes through RANSAC After treatment,It's possible to get the result of 0 matching points.).if(outMask.Rows >10){byte[] maskBytes =newbyte[outMask.Rows * outMask.Cols];
outMask.GetArray(0,0, 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);}}}
SIFT algorithmpublic static Bitmap MatchPicBySift(Bitmap imgSrc, Bitmap imgSub) { using (Mat matSrc = imgSrc.ToMat()) using (Mat matTo = imgSub.ToMat()) using (Mat matSrcRet = new Mat()) using (Mat m