在不同分辨率手机上校验图标是否存在的方法
Brute-Force匹配器基础 Brute-Force匹配器很简单,它取第一个集合里一个特征的描述子并用第二个集合里所有其他的特征和他通过一些距离计算进行匹配。最近的返回。
对于BF匹配器,首先我们得用cv2.BFMatcher()创建BF匹配器对象.它取两个可选参数,第一个是normType。它指定要使用的距离量度。默认是cv2.NORM_L2。对于SIFT,SURF很好。(还有cv2.NORM_L1)。对于二进制字符串的描述子,比如ORB,BRIEF,BRISK等,应该用cv2.NORM_HAMMING。使用Hamming距离度量,如果ORB使用VTA_K == 3或者4,应该用cv2.NORM_HAMMING2
第二个参数是布尔变量,crossCheck模式是false,如果它是true,匹配器返回那些和(i, j)匹配的,这样集合A里的第i个描述子和集合B里的第j个描述子最匹配。两个集合里的两个特征应该互相匹配,它提供了连续的结果,
当它创建以后,两个重要的方法是BFMatcher.match()和BFMatcher.knnMatch()。第一个返回最匹配的,第二个方法返回k个最匹配的,k由用户指定。当我们需要多个的时候很有用。
想我们用cv2.drawKeypoints()来画关键点一样,cv2.drawMatches()帮我们画匹配的结果,它把两个图像水平堆叠并且从第一个图像画线到第二个图像来显示匹配。还有一个cv2.drawMatchesKnn来画k个最匹配的。如果k=2,它会给每个关键点画两根匹配线。所以我们得传一个掩图,如果我们想选择性的画的话。
SIFT实现 加载图像 找到描述子 def sift(filename): img = cv2.imread(filename) # 读取文件 img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转化为灰度图 sift = cv2.SIFT_create() keyPoint, descriptor = sift.detectAndCompute(img, None) # 特征提取得到关键点以及对应的描述符(特征向量) return img, keyPoint, descriptor bf.match 接着我们用距离度量cv2.NORM_L2创建一个BFMatcher对象,crossCheck设为真。然后我们用Matcher.match()方法来获得两个图像里最匹配的。我们按他们距离升序排列,这样最匹配的(距离最小)在最前面。然后我们画出最开始的50个匹配
import cv2 from matplotlib import pyplot as plt def match(filename1, filename2): img1, kp1, des1 = sift(filename1) img2, kp2, des2 = sift(filename2) bf = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True) # sift的normType应该使用NORM_L2或者NORM_L1 matches = bf.match(des1, des2) matches = sorted(matches, key=lambda x: x.distance) len_before = len(matches) for m in matches: for n in matches: if(m != n and m.distance >= n.distance*0.75): matches.remove(m) break len_after = len(matches) img = cv2.drawMatches(img1, kp1, img2, kp2, matches[:20], img2, flags=2) plt.imshow(img), plt.show() val = round(len_after / len_before, 2) print(val) return val bf.knnMatch BFMatcher.knnMatch()方法会返回最佳匹配。而该方法为每个关键点返回 k 个最佳匹配(降序排列之后取前 k 个),其中 k 是由用户设定的,设置k=2这样我们可以应用比率检测
...