Python OpenCV图像处理与深度学习: Python OpenCV图像配准入门
图像配准:从特征匹配到单应性矩阵
学习目标
通过本课程,学员们将了解图像配准的基本原理,掌握使用OpenCV进行特征匹配和单应性矩阵计算的方法,最终实现图像的精确对齐。同时,学员将能够独立完成图像配准项目,为图像处理和计算机视觉领域的进一步学习打下坚实的基础。
相关知识点
- Python OpenCV图像配准
学习内容
1 Python OpenCV图像配准
1.1 特征检测与描述
在图像处理和计算机视觉领域,特征检测与描述是图像配准过程中的关键步骤。特征检测是指从图像中提取出具有代表性的点、线或区域,这些特征点通常具有良好的可重复性和鲁棒性,即使在图像发生旋转、缩放或光照变化的情况下也能被准确地检测出来。特征描述则是为每个检测到的特征点生成一个描述符,这个描述符能够唯一地标识该特征点,以便在不同的图像中找到相同的特征点。
1.1.1 特征检测
执行以下指令获取测试图片。
odel-community-picture.obs.cn-north-4.myhuaweicloud.com/ascend-zone/notebook_datasets/d5af67b02faa11f0a794fa163edcddae/data.zip
unzip data.zip
OpenCV提供了多种特征检测算法,如SIFT(尺度不变特征变换)、SURF(加速稳健特征)、ORB(Oriented FAST and Rotated BRIEF)等。这些算法各有特点,适用于不同的应用场景。例如,SIFT算法对图像的尺度和旋转变化具有很好的不变性,但计算复杂度较高;ORB算法则计算速度快,适用于实时应用。
import cv2
import numpy as np
from matplotlib import pyplot as plt# 读取图像
img = cv2.imread('example1.jpg', 0)# 初始化ORB特征检测器
orb = cv2.ORB_create()# 检测特征点
keypoints, descriptors = orb.detectAndCompute(img, None)
# 绘制特征点
img_with_keypoints = cv2.drawKeypoints(img, keypoints, None, color=(0,255,0), flags=0)
plt.imshow(cv2.cvtColor(img_with_keypoints, cv2.COLOR_BGR2RGB))
plt.title('img_with_keypoints'), plt.xticks([]), plt.yticks([])
plt.show()
1.1.2 特征描述
特征描述符是特征检测的下一步,它为每个特征点生成一个向量,这个向量能够唯一地标识该特征点。不同的特征检测算法生成的描述符也不同。例如,SIFT算法生成的描述符是一个128维的向量,而ORB算法生成的描述符是一个256维的二进制向量。
# 使用SIFT算法进行特征检测和描述
sift = cv2.SIFT_create()
keypoints, descriptors = sift.detectAndCompute(img, None)# 打印描述符的形状
print("SIFT Descriptors Shape:", descriptors.shape)
1.2 特征匹配
特征匹配是图像配准过程中的另一个重要步骤,它通过比较两幅图像中特征点的描述符,找到匹配的特征点对。OpenCV提供了多种特征匹配算法,如BFMatcher(暴力匹配)和FLANN(快速最近邻搜索)等。
1.2.1 暴力匹配
BFMatcher是一种简单的特征匹配算法,它通过计算两个描述符之间的距离来确定它们是否匹配。常用的匹配距离度量方法有L2范数(欧氏距离)和L1范数(曼哈顿距离)。
# 读取两幅图像
img1 = cv2.imread('example1.jpg', 0)
img2 = cv2.imread('example2.jpg', 0)# 使用ORB算法检测特征点和描述符
orb = cv2.ORB_create()
keypoints1, descriptors1 = orb.detectAndCompute(img1, None)
keypoints2, descriptors2 = orb.detectAndCompute(img2, None)# 初始化BFMatcher
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)# 进行特征匹配
matches = bf.match(descriptors1, descriptors2)# 按距离排序
matches = sorted(matches, key=lambda x: x.distance)
# 绘制匹配结果
img_matches = cv2.drawMatches(img1, keypoints1, img2, keypoints2, matches[:10], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
plt.imshow(cv2.cvtColor(img_matches, cv2.COLOR_BGR2RGB))
plt.title('Feature Matches'), plt.xticks([]), plt.yticks([])
plt.show()
1.2.2 FLANN匹配
FLANN是一种更高效的特征匹配算法,它通过构建索引来加速匹配过程。FLANN特别适用于大规模数据集的特征匹配。
# 使用SIFT算法检测特征点和描述符
sift = cv2.SIFT_create()
keypoints1, descriptors1 = sift.detectAndCompute(img1, None)
keypoints2, descriptors2 = sift.detectAndCompute(img2, None)# 初始化FLANN匹配器
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)flann = cv2.FlannBasedMatcher(index_params, search_params)# 进行特征匹配
matches = flann.knnMatch(descriptors1, descriptors2, k=2)# 筛选匹配点
good_matches = []
for m, n in matches:if m.distance < 0.7 * n.distance:good_matches.append(m)
# 绘制匹配结果
img_matches = cv2.drawMatches(img1, keypoints1, img2, keypoints2, good_matches, None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
plt.imshow(cv2.cvtColor(img_matches, cv2.COLOR_BGR2RGB))
plt.title('Feature Matches'), plt.xticks([]), plt.yticks([])
plt.show()
1.3 单应性矩阵计算
单应性矩阵(Homography Matrix)是描述两幅图像之间几何变换关系的3x3矩阵。通过计算单应性矩阵,可以将一幅图像中的点映射到另一幅图像中的对应点,从而实现图像的对齐。
1.3.1 计算单应性矩阵
OpenCV提供了findHomography
函数来计算单应性矩阵。该函数需要输入匹配的特征点对,并返回单应性矩阵和掩码。
# 读取两幅图像
img1 = cv2.imread('example1.jpg', 0)
img2 = cv2.imread('example2.jpg', 0)# 使用SIFT算法检测特征点和描述符
sift = cv2.SIFT_create()
keypoints1, descriptors1 = sift.detectAndCompute(img1, None)
keypoints2, descriptors2 = sift.detectAndCompute(img2, None)# 初始化FLANN匹配器
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)flann = cv2.FlannBasedMatcher(index_params, search_params)# 进行特征匹配
matches = flann.knnMatch(descriptors1, descriptors2, k=2)# 筛选匹配点
good_matches = []
pts1 = []
pts2 = []
for m, n in matches:if m.distance < 0.7 * n.distance:good_matches.append(m)pts2.append(keypoints2[m.trainIdx].pt)pts1.append(keypoints1[m.queryIdx].pt)pts1 = np.float32(pts1)
pts2 = np.float32(pts2)# 计算单应性矩阵
H, mask = cv2.findHomography(pts1, pts2, cv2.RANSAC, 5.0)
# 绘制匹配结果
img_matches = cv2.drawMatches(img1, keypoints1, img2, keypoints2, good_matches, None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
plt.imshow(cv2.cvtColor(img_matches, cv2.COLOR_BGR2RGB))
plt.title('Feature Matches'), plt.xticks([]), plt.yticks([])
plt.show()