1 介绍
我们准备建立一个无人见区域定位系统SRL,Simultaneous Region Localization;
系统的主要算法选择是根据开源的ORB-SLAM3算法框架来实现的;
2 定位算法介绍
2.1 模板匹配
2.1.1 基于相关性的模板匹配算法
请参考《【图像处理】模板匹配的学习笔记》
2.2 特征点算法
常用的特征子算法(按照提取效果排序):
- SIFT
- ORB
关于使用Opencv实现基于特征子的目标匹配,请参考官方教程《OpenCV – Features2D + Homography to find a known object》
2.2.1 SIFT算法(Offcial Choice)
我感觉SIFT还是一项很好的算法,能够提取的特征点很多,并且SIFT还是OpenCV官方Demo中使用的特征子算法,
请参考 OpenCV: Feature Matching + Homography to find Objects
2.2.2 特征点算法的torch实现
请参考博文《实践教程 | 使用Pytorch从头实现Canny边缘检测》;
2.3 Match算法(模板匹配)
现在我在网上看到的特征点匹配算法有:
- 暴力匹配(BF匹配)
- KNN匹配
- FLANN匹配
BF匹配OpenCV参数说明可以参考《Opencv for python(2)–图像匹配》;
这里我们尽量使用OpenCV已经实现好的匹配算法
2.4 查询算法(词袋模型)
查询算法我们参考ORB-SLAM3系统,使用词袋模型(BoW)来进行查询;
关于视觉词袋模型的算法步骤,这里我们参考了博文——《计算机视觉(八)——基于BOW的图像检索 by Did_I_Miss_It?》;
VBoW的效果:
- 固定大小的图像表示: 通过使用视觉词袋模型,可以将各种特征子算法提取的描述子信息转化为维度固定的向量,从而使用相同大小的特征向量来表示一张图像;
下面来说说视觉词袋模型算法的具体过程,其步骤如下:
- 特征提取,获得特征集合;
- 聚类获得视觉词典;
- 根据视觉词典,对特征集进行量化;
2.5 回环检测算法
请参考博文《综述 | SLAM回环检测方法·任旭倩》;
3 初始定位 & 重定位
3.1 任务描述
我们准备开始进行区域定位的学习和研究;
区域定位任务与图像匹配任务十分相关;
观测视图大小:(1024, 576)
请参考博文《自动驾驶——传感器的配置参数》
3.2 数据准备——BIGEMAP
Note
水经注地图下载器的分辨率更高。
我们将使用BIGEMAP地图下载器来获取大幅面的卫星地图,来作为匹配的基准数据;
2.2.1 基准图制作
我们选择华中科技大学及其附近区域作为需要观测区;
区域范围为:
坐标 | 起点坐标 | 终点坐标 |
精度 | 114 .3903350830 | 114 .4521331787 |
纬度 | 30 .5380439758 | 30 .5056858063 |
2.4 区域定位(Region Localization)
区域定位算法我们采用Coarse-to-Fine的两阶段方式来进行:
- Coarse: 全局定位
- Fine: 局部匹配
2.4.1 全局定位——“快速找出大致范围”
2.4.3 基线模型
因为算法的选择比较多,各种模型设计也较为复杂,
这里我们首先基于OpenCV的实现建立基线,这里我们的基线模型来自于OpenCV的官方demo:
OpenCV: Feature Matching + Homography to find Objects 描述子:SIFT算子
示例代码:
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
MIN_MATCH_COUNT = 10
img1 = cv.imread('box.png',0) # queryImage
img2 = cv.imread('box_in_scene.png',0) # trainImage
# Initiate SIFT detector
sift = cv.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1,None)
kp2, des2 = sift.detectAndCompute(img2,None)
# 输出关键点的数量
print(f'Image 1: {len(kp1)} keypoints found.')
print(f'Image 2: {len(kp2)} keypoints found.')
2.4.3 编程实现
显示大幅面图像
使用matplotlib
来显示图像,可以对图像进行缩放,代码示例如下:
# 使用matplotlib显示基准图
# img = Image.open(im_path)
plt.imread(im_path)
plt.figure("Image") # 图像窗口名称
plt.imshow(ref_map)
plt.axis('off') # 关掉坐标轴为 off
plt.title('image') # 图像题目
plt.show() # 显示图像
Note:
- 这里没有使用OpenCV来显示图像,因为OpenCV显示大图像需要对窗口进行设置,而且无法进行缩放浏览,所以为了能够进行缩放浏览,这里我们使用
matplotlib
显示图像; - OpenCV显示大图像的代码如下:
img = cv.imread("./data/Rectangle_Hust/Rectangle_Hust_Level_18.tif")
print(img.shape)
cv.namedWindow('Image', cv.WINDOW_NORMAL)
cv.imshow("Image", img)
cv.waitKey(0)
cv.destroyAllWindows()