我们在上一篇文章获取了图像的特征,现在我们使用之前的特征进行特征匹配
1 Brute-Force 蛮力匹配
1.1 导入库
1.2 定义展示函数
1.3 读取灰度图像
1.4 获取两张图像的特征 detectAndCompute()
detectAndCompute的第一个参数是要操作的图像,第二个参数是掩膜(mask),我们这个不使用掩膜,所以写None
1.5 特征匹配 BFMatcher(),match(),drawMatches()
1.5.1 一对一匹配
首先创建蛮力匹配器,之后对两张图像的特征点进行匹配,匹配之后我们对匹配上的特征点以欧几里得距离排序
- crossCheck = True
现在我有两张图像,左边的图像中有两个特征点A,B,右边的图像有一个特征点C
crossCheck为True的意思是当我A到C的距离最近时,C到A的距离也最近,那么我们认为这个特征是匹配的,像此时我下面这张图,我的C的是距离B最近的,那么这个时候我们认为A和C是不匹配的
- 上面的距离为欧几里得距离,如果在平面图像中我们可以理解为距离,如果在多维的图像中它表示最近距离,详细可了解 欧几里得度量_百度百科
然后我们将两张图最匹配的10个点画出来
drawMatches的参数
- None是outImg(输入图像),我们不输出图像,所以参数为None
- flags可以选下面的这些值
我们每个都看一下
- flags = 0
这个是默认值,是给所有的点都画出来
- flags = 1
这个是把上面这些内容在输出图片中也画出来,我们没有输出图片时会报错
- flags = 4
这个是画出更多的关键点
- flags = 2
这个是不画出没有匹配的点,我们上面的代码用的就是flags = 2
1.5.2 k对最佳匹配 knnMatch(),drawMatchesKnn()
- m是我图一中的特征点,n是我图二中的特征点
- knnMatch中的k是一共有几组匹配
发现一个中括号内有两个元素
那么如果是三个元素,我们就应该这样遍历才不会报错,我们正好看一下m,n,j过滤前的样子
- m
- n
- j
从这我们可以发现刚刚的 DMatch是两个点加上一个线段
我们的m,n,j都是若干组最佳匹配,我们后面的判定就是判定这两大组相似度的(越小越像)
我们可以把0.75变小
2 扩展
2.1 随机抽样一直算法(Random sample consensus,RANSAC)
这个算法会减少部分误匹配情况
用最小二乘法会导致有很多点误识别的情况,用RANSAC就可以避免这种情况,第一行的两张图是一次函数,第二行的两张图是二次函数
2.2 单应性矩阵
这个在后面图像拼接中会使用