特征点检测与匹配
特征点检测的基本概念
- 什么是特征
- 图像特征就是指有意义的图像区域
- 具有独特性、易于识别性,比如角点、斑点以及高密度区
- 角点
- 在特征中最重要的是角点
- 灰度梯度的最大值对应的像素
- 两条线的交点
- 极值点(一阶导数最大值,但二阶导数为0)
- OpenCV特征的场景
- 图像搜索,如以图搜图
- 拼图游戏
- 图像拼接,将两张有关联的图拼接到一起
- 拼图方法
- 寻找特征
- 特征是唯一的
- 可追踪的
- 能比较的
Harris角点检测
- 光滑地区,无论向哪里移动,衡量系数不变
- 边缘地址,垂直边缘移动时,衡量系统变化剧烈
- 在交点处,往哪个方向移动,衡量系统都变化剧烈
-
Harris角点检测API:
cornerHarris(img, dst, blockSize, ksize, k)
img
: 源dst
: 输出结果blockSize
: 窗口的大小ksize
: kernel size Sobel的卷积核k
: 权重系数,经验值,一般取0.02 ~ 0.04之间
Shi-Tomasi角点检测
- Shi-Tomasi是Harris角点检测的改进
- Harris角点检测算的稳定性和k有关,而k是个经验值,不好设定最佳值
-
Shi-Tomasi的API:
goodFeaturesToTrack(img, maxCorners, qualityLevel, minDistance, mask, blockSize, useHarrisDetector, k)
img
: 图像源maxCorners
: 角点的最大数,值为0表示无限制qualityLevel
: 角点的质量(小于1.0的正数,一般在0.01-0.1之间)minDistance
: 角之间最小欧式距离,忽略小于此距离的点mask
: 指定检测的区域,不设定则会检测整幅图blockSize
: 检测窗口大小useHarrisDetector
: 是否使用Harris算法(既可以使用Harris检测也可以用于Tomasi检测,如果写true就会使用原始的Harris算法,写false才会使用Shi-Tomasi的交点检测方法)k
: 默认是0.04
SIFT关键点检测
- Scale-Invariant Feature Transform:与缩放无关的特征转换(有版权问题)
- SIFT出现的原因
- Harris角点具有旋转不变的特性,但缩放后,原来的角点有可能就不是角点了
- SIFT就是要解决Harris的这个痛点,原本检测是角,放大之后检测依旧是角。
- 使用SIFT的步骤
- 创建SIFT对象
- 进行检测,
kp=sift.detect(img, ...)
获取特征点 - 绘制关键点,
drawKeypoints(gray, kp, img)
SIFT计算描述子
- 关键点和描述子
- 关键点:位置、大小和方向
- 关键点描述子:记录了关键点周围对其有贡献的像素点的一组向量值,其不受仿射变换、光照变换等影响
- 优点:特征检测的点特别准确,描述子也描述的非常详细
- 缺点:速度慢,有版权问题
- 计算描述子API:
kp, des = sift.compute(img, kp)
- 入参
img
: 图像源kp
: 关键点
- 返回值
kp
: 关键点des
: 描述子:作用就是进行特征匹配
- 入参
-
同时计算关键点和描述子API:
kp, des = sift.detectAndCompute(img, mask)
- 入参
img
: 图像源mask
: 指明对img中哪个区域进行计算
- 返回值
kp
: 关键点des
: 描述子
- 入参
SURF特征检测
- Speeded-Up Robust Features:加速的鲁棒性特征检测(有版权问题)
- 优点:速度快,保留了SIFT的优点(特征检测的点特别准确,描述子也描述的非常详细)
- 缺点:有版权问题
-
使用SURF的步骤
- 创建SURF对象,
surf = cv2.xfeatures2d.SURF_create()
- 进行检测,
kp, des = surf.detectAndCompute(gray, mask)
获取特征点与描述子 - 绘制关键点,
drawKeypoints(gray, kp, img)
- 创建SURF对象,
OBR特征检测
- Oriented FAST and Rotated BRIEF:特征点检测和描述子计算
- 优点:ORB可以做到实时检测,无版权问题
FAST
可以做到特征点的实时检测,但是没有方向,所以增加了方向这个属性Oriented
。BRIEF
是对已检测到的特征点进行描述,它加快了特征描述符建立的速度,同时也极大的降低了特征匹配的时间,BRIEF
对图像的旋转处理的不太好,所以又增加了Rotated
属性。-
使用OBR的步骤
- 创建OBR对象,
orb = cv2.ORB_create()
- 进行检测,
kp, des = surf.detectAndCompute(gray, mask)
获取特征点与描述子 - 绘制关键点,
drawKeypoints(gray, kp, img)
- 创建OBR对象,
暴力特征匹配
- BF(Brute-Force),暴力特征匹配方法(使用枚举的方式进行匹配)
- 暴力特征匹配原理:它使用第一组中每个特征的描述子,它与第二组中的所有特征描述子进行匹配(第一幅图与第二幅图),计算它们之间的差距,然后将最接近一个区配返回。
-
OpenCV特征匹配步骤
- 创建匹配器:
BFMatcher(normType, crossCheck)
normType
: 匹配类型,默认使用NORM_L2
NORM_L1
: 使用SIFT描述子计算的,取描述子的绝对值,然后进行加法运算NORM_L2
: 使用SURF的描述子计算的,取描述子的平方和求开方,也就是欧氏距离HAMMING1
: 使用OBR描述子计算的,查看二进制位在第几位发生了变化...
crossCheck
: 交叉检查(第一幅图与第二幅匹配,第二幅与第一幅匹配,提升准确度),默认为false
- 进行特征匹配:
bf.match(des1, des2)
参数为SIFT、SURF、OBR等计算的描述子,对两幅图的描述子进行计算des1
: 描述子des2
: 描述子
- 绘制匹配点:
cv2.drawMatches(img1, kp1, img2, kp2 ...)
img1, kp1
: 搜索的图和特征点img2, kp2
: 匹配的图和特征点match()
方法返回的匹配结果
- 创建匹配器:
FLANN特征匹配与图像查找
- FLANN
- FLANN 最快邻近区特征匹配方法
- 优点:在进行批量特征匹配时,FLANN速度更快
- 缺点:由于它使用的是临近近似值,所以精度较差,如果我们要做的是图像的精确匹配,就需要使用暴力特征匹配
- 使用FLANN特征匹配的步骤
- 创建FLANN匹配器:
FlannBasedMatcher(...)
index_params
字典:匹配算法KDTREE、LSH
,一般KDTREE
设置成5,search_params
设置成50KDTREE
的设置方式index_params = dict(algorithm=FLANN_INDEX_KDTREE, tree=5)
- 如果上面参数匹配的是
KDTREE
则需要第二个字段->search_params
字典:指定KDTREE算法中遍历树的次数search_params
设置方式search_params = dict(checks=50)
- 进行特征匹配:
flann.match/knnMatch(...)
knnMatch
方法- 参数为
SIFT
、SURF
、ORB
等计算的描述子,k
,表示取欧氏距离最近的前k个关键点 - 返回的是匹配的结果
DMatch
对象DMatch
的内容distance
: 描述子之间的距离,值越低越好queryIdx
: 第一个图像的描述子索引值trainIdx
: 第二个图的描述子索引值imgIdx
: 第二个图的索引值
- 参数为
- 绘制匹配点:
cv2.drawMatches/drawMatchesKnn(...)
drawMatchesKnn
只能与knnMatch
搭配才能绘制- 搜索
img
,kp
- 匹配图
img
,kp
match()
方法返回的匹配结果(knn结果)
- 搜索
- 创建FLANN匹配器:
-
图像查找
- 图像查找:特征匹配 + 单应性矩阵
- 什么是单应性矩阵
- 单应性的作用(一)图像转正
- 单应性的作用(二)换图像中的广告
图像拼接
-
图像拼接合并的步骤
- 读文件并重置尺寸
- 根据特征点和计算描述子,得到单应性矩阵
- 图像变换
- 图像拼接并输出图像
-
图像拼接前
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
|