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的效果:

  • 固定大小的图像表示: 通过使用视觉词袋模型,可以将各种特征子算法提取的描述子信息转化为维度固定的向量,从而使用相同大小的特征向量来表示一张图像;

下面来说说视觉词袋模型算法的具体过程,其步骤如下:

  1. 特征提取,获得特征集合;
  2. 聚类获得视觉词典
  3. 根据视觉词典,对特征集进行量化;

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:

  1. 这里没有使用OpenCV来显示图像,因为OpenCV显示大图像需要对窗口进行设置,而且无法进行缩放浏览,所以为了能够进行缩放浏览,这里我们使用matplotlib显示图像;
  2. 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()