0,背景
浏览LoFTR代码主页:LoFTR,看到其中提到,LoFTR从0.5.11版本开始集成到kornias库中,所以决定尝试。
硬件:联想拯救者Y7000P 2020,i7-10750H,RTX2060
1,Kornia
Kornia 是一个基于 PyTorch 的开源计算机视觉库,提供了一系列的图像处理操作和算法。它的设计目标是将经典的计算机视觉算法与现代深度学习框架结合起来,方便研究人员和开发者在深度学习模型中使用传统的图像处理技术。以下是 Kornia 的一些主要功能和特点:
-
图像处理:Kornia 提供了各种图像处理功能,如滤波、变换、形态学操作等。这些操作可以在 GPU 上高效地执行,适合处理大规模数据。
-
几何变换:支持仿射变换、透视变换、旋转、缩放、平移等几何变换,可以方便地在深度学习模型中进行数据增强和预处理。
-
特征检测与匹配:Kornia 包含了一些经典的特征检测算法,如 SIFT、ORB 等,可以在深度学习框架中直接使用。
-
图像复原:提供了图像去噪、去模糊、超分辨率等图像复原技术,可以用于提高图像质量。
-
深度学习集成:Kornia 完全基于 PyTorch 构建,可以无缝地与深度学习模型结合使用,支持梯度计算和自动微分。
-
可扩展性:Kornia 的模块化设计使得用户可以根据需要扩展和自定义自己的图像处理算法。
2,安装kornias
运行指令
pip install kornia
需要注意,安装的版本应该大于0.5.11,我在Python 3.8环境下装出来就是0.4.X的,没有LoFTR,就需要下面的指令更新
pip install --upgrade kornia
3,编程使用
LoFTR
(Local Feature TRansformer) 是 Kornia 中用于特征匹配的一个模块。LoFTR 是一种深度学习方法,用于在图像对之间找到对应的特征点。与传统的特征匹配算法(如 SIFT 和 ORB)不同,LoFTR 依靠深度学习模型来提取和匹配特征点,具有更高的鲁棒性和精度。
以下是 LoFTR
的一些主要用途和特点:
-
特征提取与匹配:LoFTR 可以在两幅图像中找到对应的特征点,这对于图像配准、立体视觉、SLAM 等应用非常重要。
-
深度学习驱动:与传统方法不同,LoFTR 使用深度神经网络来学习特征描述和匹配策略,能够在复杂的场景中表现出色。
-
鲁棒性:LoFTR 在存在遮挡、视角变化、光照变化等情况下仍然能够可靠地匹配特征点。
-
高精度:由于使用了深度学习技术,LoFTR 在特征匹配的精度上通常优于传统算法。
-
可扩展性:作为 Kornia 的一部分,LoFTR 可以方便地与其他计算机视觉模块和深度学习模型结合使用。
4,测试程序
选择测试的文件为手机拍摄的远近两张水杯照片
为了减轻显卡压力,将图片转为800*600分辨率(直接处理原图,2060遭不住)
在窗口显示原图、Feature Matches和Matched Keypoints
-
Feature Matches:这个图显示的是两张图像拼接在一起后,绘制出每对匹配的特征点之间的连线。通过这些连线,可以直观地看到LoFTR模型在两张图像中找到了哪些对应的特征点,以及这些特征点的位置关系。
-
Matched Keypoints:这个图展示的是每对匹配的特征点在各自的原始图像中的具体位置。通过
cv2.drawMatches
函数,这些匹配点在两张图像中用连线连接起来,从而可以更清晰地看到哪些特征点在两张图像中被匹配上了。这个图像使得每对匹配点的位置和关系更加明显。
注意:第一次运行下面的程序,会自动下载outdoor权重文件到C盘中:
Downloading: "http://cmp.felk.cvut.cz/~mishkdmy/models/loftr_outdoor.ckpt" to C:\Users\HRSI/.cache\torch\hub\checkpoints\loftr_outdoor.ckpt
100%|██████████████████████████████████████████████| 44.2M/44.2M [01:11<00:00, 650kB/s]
import torch
import kornia as K
from kornia.feature import LoFTR
import cv2
import matplotlib.pyplot as plt# 初始化 LoFTR 模型
loftr = LoFTR(pretrained="outdoor")# 加载并预处理图像
img1 = cv2.imread('demo/images/cup_1.jpg')
img2 = cv2.imread('demo/images/cup_2.jpg')# 调整图像大小为 800x600
img1_resized = cv2.resize(img1, (800, 600))
img2_resized = cv2.resize(img2, (800, 600))# 转换颜色格式从 BGR 到 RGB
img1_resized = cv2.cvtColor(img1_resized, cv2.COLOR_BGR2RGB)
img2_resized = cv2.cvtColor(img2_resized, cv2.COLOR_BGR2RGB)# 转换为张量并添加批次维度
img1_tensor = K.image_to_tensor(img1_resized, False).float() / 255.
img2_tensor = K.image_to_tensor(img2_resized, False).float() / 255.# 将图像转换为灰度图像
img1_gray = K.color.rgb_to_grayscale(img1_tensor)
img2_gray = K.color.rgb_to_grayscale(img2_tensor)# 特征匹配
input_dict = {"image0": img1_gray, "image1": img2_gray}
with torch.no_grad():correspondences = loftr(input_dict)# 提取匹配的特征点
keypoints0 = correspondences['keypoints0']
keypoints1 = correspondences['keypoints1']# 可视化匹配结果
fig, axs = plt.subplots(2, 2, figsize=(20, 15))# 显示原图
axs[0, 0].imshow(img1_resized)
axs[0, 0].set_title('Original Image 1')
axs[0, 0].axis('off')axs[0, 1].imshow(img2_resized)
axs[0, 1].set_title('Original Image 2')
axs[0, 1].axis('off')# 拼接两张图像以便在同一张图上绘制匹配点
img_concat = torch.cat([img1_tensor, img2_tensor], dim=-1)
axs[1, 0].imshow(K.utils.tensor_to_image(img_concat))for kp0, kp1 in zip(keypoints0, keypoints1):axs[1, 0].plot([kp0[0], kp1[0] + img1_tensor.shape[-1]], [kp0[1], kp1[1]], 'ro-')axs[1, 0].set_title('Feature Matches')
axs[1, 0].axis('off')# 绘制匹配点的特写
img_matches = cv2.drawMatches(cv2.cvtColor(img1_resized, cv2.COLOR_RGB2BGR), [cv2.KeyPoint(pt[0].item(), pt[1].item(), 1) for pt in keypoints0],cv2.cvtColor(img2_resized, cv2.COLOR_RGB2BGR), [cv2.KeyPoint(pt[0].item(), pt[1].item(), 1) for pt in keypoints1],[cv2.DMatch(i, i, 0) for i in range(len(keypoints0))], None)axs[1, 1].imshow(cv2.cvtColor(img_matches, cv2.COLOR_BGR2RGB))
axs[1, 1].set_title('Matched Keypoints')
axs[1, 1].axis('off')plt.show()