SIFT(Scale Invariant Feature Transform)算法是一种尺度不变的特征提取方法,它能够在不同的尺度空间中检测出稳定的关键点,并生成具有唯一性和不变性的描述符。
SIFT 算法的主要优点是:
1.尺度不变性:SIFT 算法使用了高斯金字塔来构建不同尺度的图像,并在每个尺度上进行极值点检测,从而实现了对尺度变化的不敏感。// 加载图片 Mat image1 = Cv2.ImRead("image1.jpg", ImreadModes.Grayscale); Mat image2 = Cv2.ImRead("image2.jpg", ImreadModes.Grayscale); // 堆代码 duidaima.com // 创建SIFT对象 SIFT sift = SIFT.Create(); // 提取特征点和描述符 Mat descriptors1 = new Mat(); Mat descriptors2 = new Mat(); sift.DetectAndCompute(image1, null, out _, descriptors1); sift.DetectAndCompute(image2, null, out _, descriptors2);
// 加载图片 Mat image1 = Cv2.ImRead("image1.jpg", ImreadModes.Grayscale); Mat image2 = Cv2.ImRead("image2.jpg", ImreadModes.Grayscale); // 创建SURF对象 SURF surf = SURF.Create(500); // 500是阈值参数,表示特征点的最小响应值 // 提取特征点和描述符 Mat descriptors1 = new Mat(); Mat descriptors2 = new Mat(); surf.DetectAndCompute(image1, null, out _, descriptors1); surf.DetectAndCompute(image2, null, out _, descriptors2);
// 创建BFMatcher对象 BFMatcher bfMatcher = new BFMatcher(NormTypes.L2, false); // NormTypes.L2表示使用欧式距离作为相似度度量,false表示不交叉匹配 // 进行匹配 DMatch[] bfMatches = bfMatcher.Match(descriptors1, descriptors2); // bfMatches是一个数组,每个元素是一个DMatch对象,表示一对匹配结果
// 创建FlannBasedMatcher对象 FlannBasedMatcher flannMatcher = new FlannBasedMatcher(); // 进行匹配 DMatch[] flannMatches = flannMatcher.Match(descriptors1, descriptors2); // flannMatches是一个数组,每个元素是一个DMatch对象,表示一对匹配结果
// 计算并显示BFMatcher和FlannBasedMatcher的相似度得分,得分越低越相似 Console.WriteLine("The score using BFMatcher is {0}", bfMatches.Average(m => m.Distance)); Console.WriteLine("The score using FlannBasedMatcher is {0}", flannMatches.Average(m => m.Distance));这样,图片特征向量提取和相似度计算就实现了。下面是完整的代码:
class Program { static void Main(string[] args) { // 加载图片 Mat image1 = Cv2.ImRead("image1.jpg", ImreadModes.Grayscale); Mat image2 = Cv2.ImRead("image2.jpg", ImreadModes.Grayscale); // 创建四种特征检测器和描述符生成器 SURF surf = SURF.Create(500); // SURF算法 SIFT sift = SIFT.Create(); // SIFT算法 // 从两张图片中提取特征和描述符 Mat descriptors1 = new Mat(); Mat descriptors2 = new Mat(); // 使用SURF算法 surf.DetectAndCompute(image1, null, out _, descriptors1); surf.DetectAndCompute(image2, null, out _, descriptors2); ComputeSimilarity(descriptors1, descriptors2); // 使用SIFT算法 sift.DetectAndCompute(image1, null, out _, descriptors1); sift.DetectAndCompute(image2, null, out _, descriptors2); ComputeSimilarity(descriptors1, descriptors2); } static void ComputeSimilarity(Mat descriptors1, Mat descriptors2) { // 创建BFMatcher BFMatcher bfMatcher = BFMatcher.Create(NormTypes.L2, false); FlannBasedMatcher flannMatcher = FlannBasedMatcher.Create(); // 使用BFMatcher和FlannBasedMatcher进行匹配 DMatch[] bfMatches = bfMatcher.Match(descriptors1, descriptors2); DMatch[] flannMatches = flannMatcher.Match(descriptors1, descriptors2); // 计算并显示BFMatcher和FlannBasedMatcher的相似度得分,得分越低越相似 Console.WriteLine("The score using BFMatcher is {0}", bfMatches.Average(m => m.Distance)); Console.WriteLine("The score using FlannBasedMatcher is {0}", flannMatches.Average(m => m.Distance)); } }接下来我们运行程序,从四种情况去查看结果。
The score using BFMatcher is 0.77414566 The score using FlannBasedMatcher is 0.77414566SIFT算法
The score using BFMatcher is 366.84616 The score using FlannBasedMatcher is 372.25107
The score using BFMatcher is 0 The score using FlannBasedMatcher is 0SIFT算法
The score using BFMatcher is 0 The score using FlannBasedMatcher is 03、某一张图片和它的部分截图进行对比
The score using BFMatcher is 0.22462595 The score using FlannBasedMatcher is 0.23025486SIFT算法
The score using BFMatcher is 105.93032 The score using FlannBasedMatcher is 108.33074、两张相似的图片进行对比
The score using BFMatcher is 0.37855583 The score using FlannBasedMatcher is 0.38878053SIFT算法
The score using BFMatcher is 239.1525 The score using FlannBasedMatcher is 248.43388从上面的结果可以看出,SURF 和 SIFT 算法都可以提取图片特征向量,同时,BFMatcher 和 FlannBasedMatcher 也有区别。因此,在选算法时,需要根据具体的应用场景和需求进行权衡。