我们有两个图像,一个作为参考,另一个图像,我们希望像使用Matlab的参考一样对齐。为了做到这一点,我们需要在两个图像中找到相似的点,然后使用最小二乘法计算内核矩阵进行转换,如下代码:
clear all; close all; clc; imtool close all;
I1 = rgb2gray(im);
I2 = rgb2gray(ref);
points1 = detectSURFFeatures(I1);
points2 = detectSURFFeatures(I2);
[features1,valid_points1] = extractFeatures(I1,points1,'SURFSize',64);
[features2,valid_points2] = extractFeatures(I2,points2,'SURFSize',64);
indexPairs = matchFeatures(features1,features2);
matchedPoints1 = valid_points1(indexPairs(:,1),:);
matchedPoints2 = valid_points2(indexPairs(:,2),:);
[tform, correct1,correct2] = estimateGeometricTransform(matchedPoints1,matchedPoints2,'projective','MaxNumTrials',100000,'Confidence',99.9999,'MaxDistance',4);
sourcepoints = correct1.Location;
targetpoints = correct2.Location;
sizenum = size(sourcepoints,1);
x_source = sourcepoints(:,1);
y_source = sourcepoints(:,2);
x_target = targetpoints(:,1);
y_target = targetpoints(:,2);
zero_vec = zeros([sizenum,1]);
one_vec = ones([sizenum,1]);
H = [x_source,y_source,one_vec,zero_vec,zero_vec,zero_vec,-x_source.*x_target,-y_source.*x_target;...
zero_vec,zero_vec,zero_vec,x_source,y_source,one_vec,-x_source.*y_target,-y_source.*y_target];
Y = [x_target;y_target];
variables = (inv(H'*H))*H'*Y;
variables(9) = 1;
kernel = reshape(variables,3,3)';
在这段代码中,我们并不关心速度,对我们来说最重要的是准确性。
1)在这里我们使用Surf方法,我们试着了解这是否是这项任务的最佳方法,或者我们应该使用其他功能检测,如HOG或FAST等?
2)我们试着了解每个特征检测器之间的差异以及何时使用它们?
提前致谢。
答案 0 :(得分:0)
您的观点的简短摘要:
1)SIFT和SURF基于梯度直方图(HoG),即计算像素块中的每个梯度,这些计算会花费时间。 SIFT和SURF受专利保护。即使花费时间,但当设备架构上的时间,功耗和计算成本对您来说都不重要时,它仍可以为您带来最佳效果。
2)这取决于要在哪里使用该应用程序。它是基于系统的应用程序,还是手持设备(移动设备)还是智能眼镜?
SIFT和SURF在手机和智能眼镜上的效果不佳。 FAST不是旋转不变的。 BRISK需要高计算GPU。如果在任何情况下都不会使用它,那么很难建议哪种方法最好。
您可以从以下帖子中找到更详细的答案
答案 1 :(得分:0)
没有“最佳”特征检测器之类的东西,绝对来说,匹配的质量在很大程度上取决于特定图像,此外还取决于您用于配置检测器的参数,尽管有些特征检测器客观上具有它们在其中运作良好的各种条件
SURF 和 SIFT 通常被认为是最好的特征检测器,这有充分的理由,它们在大多数情况下都非常强大且非常快,到目前为止,我发现它们唯一显示其缺点的唯一情况是目标非常详细(例如,电路板),但请记住,SURF和SIFT均受专利保护,因此如果您的目标涉及到,您将必须付出很多钱商业用途
AKAZE (https://github.com/pablofdezalc/akaze)是SURF / SIFT的有效免费使用替代品:其鲁棒性在大多数情况下与SIFT / SURF相似情况及其性能,这里唯一的限制是您需要64位体系结构才能以良好的性能运行AKAZE,我发现在32位体系结构上,性能会急剧下降
FAST 非常快速且非常“贪婪”,与其他检测器相比,它提取了许多关键点,但不是旋转不变式(意味着如果目标相对于参考图像旋转,则它将不起作用)。而且它只是一个检测器,因此您将不得不使用其他描述符来描述提取的关键点,并且匹配的鲁棒性将取决于此,我的建议是尝试使用FREAK或ORB作为描述符,这两个都给我带来了很好的效果快速
BRIEF 具有良好的性能,并且提取的关键点数量少于FAST,就像FAST一样,不是旋转不变的,并且没有相应的描述符
ORB 基本上是前2个检测器(ORB代表定向快速和旋转简报)的演变,是旋转不变,并且还实现了自己的描述符,这可能是一般用途的最佳选择,它是免费使用的,其鲁棒性可与SIFT / SURF / AKAZE媲美,而性能(使用默认参数)则略微克服了它们,实际上,在大多数情况下要逊色一些,在某些特定情况下,它可以克服SURF / SIFT / AKAZE(例如再一次使用电气板)
BRISK 的行为与ORB非常相似,但CPU负载却要多一些,因为在大多数情况下,ORB的鲁棒性和性能都更好,人们通常最终使用ORB代替< / p>
HOG (您提到的)实际上并不是要与特征匹配一起使用,它更可能适用于深度学习分类
如果您打算快速测试这些检测器/描述符的鲁棒性和性能,我建议您下载并安装Find-Object(http://introlab.github.io/find-object/),该对象可通过目标图像匹配对这些算法进行基准测试,以提供舒适的环境界面可以轻松做到这一点,如果您对它感兴趣,则可以在github上找到源代码(https://github.com/introlab/find-object)