特征匹配+单应性查找
![](https://img-blog.csdnimg.cn/3113593692f84d2e847eafbcca6c7f1b.png)
![](https://img-blog.csdnimg.cn/dadd8820d60b41e39c397e8a444db6fc.png)
public static void forexample2()
{
Mat Src_Images1 = Cv2.ImRead("D:\\Desktop\\CSsharpOpenCVTest\\bin\\Debug\\_data\\image\\match1.png", ImreadModes.AnyColor);
Mat Src_Images2 = Cv2.ImRead("D:\\Desktop\\CSsharpOpenCVTest\\bin\\Debug\\_data\\image\\match2.png", ImreadModes.AnyColor);
var sift = SIFT.Create();
var descriptors1 = new Mat<float>();
var descriptors2 = new Mat<float>();
sift.DetectAndCompute(Src_Images1, null, out var keypoints1, descriptors1);
sift.DetectAndCompute(Src_Images2, null, out var keypoints2, descriptors2);
var knnmatcher = FlannBasedMatcher.Create("FlannBased");
var Matchs = knnmatcher.KnnMatch(descriptors1, descriptors2, 2);
if (Matchs.ToList().Count > 10)
{
List<DMatch> good = new List<DMatch>();
for (int i = 0; i < Matchs.Length; i++)
{
if (Matchs[i][0].Distance < Matchs[i][1].Distance * 0.7)
{
good.Add(Matchs[i][0]);
}
}
List<List<DMatch>> good1 = new List<List<DMatch>>() { good.ToList() };
//3特征点匹配
List<Point2d> imagepoint1 = new List<Point2d> { };
List<Point2d> imagepoint2 = new List<Point2d> { };
for (int j = 0; j < good.Count; j++)
{
//查找特征点可连接处 变形
Point2d point2D = new Point2d(0, 0);
if (good[j].TrainIdx > Matchs.Length)
{
continue;
}
point2D.X = Convert.ToDouble(keypoints1[good[j].QueryIdx].Pt.X);
point2D.Y = Convert.ToDouble(keypoints1[good[j].QueryIdx].Pt.Y);
imagepoint1.Add(point2D);
//查找特征点可连接处 查找基准线
point2D.X = Convert.ToDouble(keypoints2[good[j].TrainIdx].Pt.X);
point2D.Y = Convert.ToDouble(keypoints2[good[j].TrainIdx].Pt.Y);
imagepoint2.Add(point2D);
}
//4 透视变换图形融合
Mat homo = Cv2.FindHomography(imagepoint1, imagepoint2, HomographyMethods.Ransac);
Point2f[] AffinePointsSrc = new Point2f[4] { new Point2f(0, 0), new Point2f(0, Src_Images1.Height - 1), new Point2f(Src_Images1.Width - 1, Src_Images1.Height - 1), new Point2f(Src_Images1.Width - 1, 0) };
Point2f[] TransImage = Cv2.PerspectiveTransform(AffinePointsSrc, homo);
Point[] pp = new Point[TransImage.Length];
for (int k = 0; k < TransImage.Length; k++)
{
pp[k] = TransImage[k].ToPoint();
}
List<List<Point>> pplist = new List<List<Point>>() { pp.ToList() };
Cv2.CvtColor(Src_Images2, Src_Images2, ColorConversionCodes.GRAY2BGR);
Cv2.Polylines(Src_Images2, pplist, true, Scalar.Blue);
Mat Dsr_Images = new Mat();
Cv2.DrawMatches(Src_Images1, keypoints1, Src_Images2, keypoints2, good, Dsr_Images, Scalar.Red, Scalar.Green, null, DrawMatchesFlags.NotDrawSinglePoints);
Cv2.ImShow("123", Dsr_Images);
}
else
{
Console.WriteLine("没有足够多的关键点");
}
}
结果图
![](https://img-blog.csdnimg.cn/a554b4be67274bb4b7994ec79fbcc066.png)