OpenCV ⚠️高手勿入! 半小时学会基本操作 25⚠️ 图像匹配
Posted 我是小白呀
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV ⚠️高手勿入! 半小时学会基本操作 25⚠️ 图像匹配相关的知识,希望对你有一定的参考价值。
【OpenCV】 ⚠️高手勿入! 半小时学会基本操作 25⚠️ 图像匹配
概述
OpenCV 是一个跨平台的计算机视觉库, 支持多语言, 功能强大. 今天带大家用 OpenCV 来实现一个简单的磨皮. (第 25 课)
图像特征匹配
我们在上一节课中提到了如何通过 SIFT 算法来帮助我们寻找特征点. 下面来简单讲一下特征匹配中的两个匹配器.
match vs knnMatch
match 格式:
match = bf.match(des1, des2)
返回值:
- querlyIdx: 测试图像的特征点的 index
- trainIdx: 测试图像的特征点的 index
- distance: 匹配特征点的欧式距离, 数值越小越接近
knnMatch 格式:
match = bf.knnMatch(des1, des2, k)
返回值:
- m: 最近的匹配特征点
- n: 第二近的匹配点, 如果 m 和 n 的距离足够大, 那么这就是一个正确的匹配
Brute-Force 匹配器
Brute-Force 匹配器 (蛮力匹配器) 通过取第一个集合里一个特征的描述, 并对第二个集合里的所有特征进行匹配.
格式:
cv2.BFMatcher(crossCheck)
参数:
- crossCheck: 是否要求互相匹配, 即 A 中的第 i 个特征和 B 中的第 j 个特征距离最近, 并且 B 中的第 j 个特征和 A 中的第 i 个特征也是距离最近
例子:
import numpy as np
import cv2
# 读取图片
image1 = cv2.imread("dollar1.jpg")
image2 = cv2.imread("dollar4.jpg")
# 实例化SIFT
sift = cv2.SIFT_create()
# 得到特征点
kp1, des1 = sift.detectAndCompute(image1, None)
kp2, des2 = sift.detectAndCompute(image2, None)
# 实例化Brute-Force匹配器
bf1 = cv2.BFMatcher(crossCheck=True)
# 匹配
match1 = bf1.match(des1, des2)
# 按距离从小到大排序
match1 = sorted(match1, key=lambda x: x.distance)
# 绘制特征匹配
image_match1 = cv2.drawMatches(image1, kp1, image2, kp2, match1[:10], None, flags=2)
# 展示特征匹配
cv2.imshow("match1", image_match1)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 实例化Brute-Force匹配器
bf2 = cv2.BFMatcher()
# 匹配
match2 = bf2.knnMatch(des1, des2, k=2)
# 最近点和次近点阈值 (比值小于0.75)
array = np.array([[x] for x, y in match2])[[m.distance < 0.75 * n.distance for m, n in match2]]
# 绘制特征匹配
image_match2 = cv2.drawMatchesKnn(image1, kp1, image2, kp2, array, None, flags=2)
# 展示特征匹配
cv2.imshow("match2", image_match2)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存图片
cv2.imwrite("match1.jpg", image_match1)
cv2.imwrite("match2.jpg", image_match2)
输出结果:
FLANN 匹配器
FLANN (Fast Library for Approximate Nearest Neighbors) 匹配器针对大型数据集中的快速最近邻搜索 & 高维特征进行了优化. 相较于 BF 匹配器更准确快速和方便.
例子:
import numpy as np
import cv2
# 读取图片
image1 = cv2.imread("dollar1.jpg")
image2 = cv2.imread("dollar4.jpg")
# 实例化SIFT
sift = cv2.SIFT_create()
# 得到特征点
kp1, des1 = sift.detectAndCompute(image1, None)
kp2, des2 = sift.detectAndCompute(image2, None)
# Flann参数
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)
# 实例化Flann匹配器
flann = cv2.FlannBasedMatcher(index_params, search_params)
# 匹配
match2 = flann.knnMatch(des1, des2, k=2)
# 最近点和次近点阈值 (比值小于0.5)
array = np.array([[x] for x, y in match2])[[m.distance < 0.5 * n.distance for m, n in match2]]
# 绘制特征匹配
image_flann = cv2.drawMatchesKnn(image1, kp1, image2, kp2, array, None, flags=2)
# 展示特征匹配
cv2.imshow("flann", image_flann)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存图片
cv2.imwrite("flann.jpg", image_flann)
输出结果:
以上是关于OpenCV ⚠️高手勿入! 半小时学会基本操作 25⚠️ 图像匹配的主要内容,如果未能解决你的问题,请参考以下文章
OpenCV⚠️高手勿入! 半小时学会基本操作 16⚠️ 模板匹配
OpenCV ⚠️高手勿入! 半小时学会基本操作 17⚠️ 高斯双边
OpenCV⚠️高手勿入! 半小时学会基本操作 14⚠️ 圆圈检测
OpenCV⚠️高手勿入! 半小时学会基本操作 15⚠️ 直方图