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⚠️ 直方图

OpenCV ⚠️高手勿入! 半小时学会基本操作 23⚠️ 角点检测

OpenCV ⚠️高手勿入! 半小时学会基本操作 23⚠️ 角点检测