SeqSlam论文阅读和实验( 二 )


继续沿用上面提到的例子 , n个待匹配图像 , 必然得到n个local best match , 这n个得分如上图的红点 。现在假设一个窗口 , 如上宽度为3 。寻找这n个得分的最小值s 0 s_0 s0?(偏差最小) , 已其为中点放置窗口 , 如图窗口内有3个点 。再计算窗口外的点的最小值 s 1 s_1 s1? , 再假定一个阈值 μ \mu μ:如果满足:
s 0 s 1 < μ \frac{s_0}{s_1} < \mu s1?s0??  , 这是一个源码的实现 , 但代码中存在诸多问题 , 我已经改进了很多地方 , 下面放出闭环检测部分主要代码:
def getLoopClosure(self, DD):# DD: 偏差矩阵 , 此处是方阵 , 但不是必选项n, n = DD.shape# 最大和最小移动速度move_min = int(self.params.matching.vmin * self.params.matching.ds)move_max = int(self.params.matching.vmax * self.params.matching.ds)move = np.arange(move_min, move_max + 1)v = move.astype(float) / self.params.matching.ds# 这里检查y轴存的图片数量 , 小于下面的条件是不可能存在闭环的 , 不用检测if n < move_min + 2*self.params.matching.Rwindow + self.params.matching.no_seq + self.params.matching.ds or n < self.params.matching.ds:return None# 遍历所有y轴图片 , 强制计算最佳局部匹配序列 , 保存索引和得分matches = np.nan * np.ones((n, 2))for N in range(move_min + 2*self.params.matching.Rwindow + self.params.matching.no_seq + self.params.matching.ds -1, n):# 这里计算不同速度下匹配得分# 0 ~ ds-1 --> ds itemsidx_add = np.tile(np.arange(0, self.params.matching.ds), (len(v), 1))idx_add = np.floor(idx_add * np.tile(v, (idx_add.shape[1], 1)).T)# 这里是本人改进点 , 逆向匹配也需要考虑idx_add1 = np.tile(idx_add[:,-1], (self.params.matching.ds, 1)).T - idx_add# this is where our trajectory startsn_start = N + 1 - self.params.matching.dsif n_start < self.params.matching.no_seq:continuex = np.tile(np.arange(n_start, n_start + self.params.matching.ds), (len(v), 1))# I think y_max should be min(N + self.param, DD.shape[0])y_max = n_start - self.params.matching.no_seqxx = x * nscore = []final_idx = []flatDD = DD.flatten('F')# 遍历不同速度下 , 计算最佳匹配序列for s in range(y_max+1 - move_min + 1):# 0 ~ N+1-move_miny = np.copy(idx_add + s)y1 = np.copy(idx_add1 + s)y[y > y_max] = y_maxy1[y1 > y_max] = y_maxidx = (xx + y).astype(int)idx1 = (xx + y1).astype(int)ds = np.sum(flatDD[idx], 1)ds1 = np.sum(flatDD[idx1], 1)tmp = np.argmin(ds)tmp1 = np.argmin(ds1)# 如果顺向序列好于逆向if tmp <= tmp1:score.append(ds[tmp])final_idx.append(min(n-1, s + int(idx_add[tmp, -1])))else:score.append(ds1[tmp1])final_idx.append(s)score = np.array(score)min_idx = np.argmin(np.array(score))min_value = http://www.kingceram.com/post/score[min_idx]# 假阳性排除window = np.arange(np.max((0, min_idx - self.params.matching.Rwindow // 2)),np.min((len(score), min_idx + self.params.matching.Rwindow // 2)))not_window = list(set(range(len(score))).symmetric_difference(set(window)))# xorif len(not_window) < self.params.matching.Rwindow:continuemin_value_2nd = np.min(score[not_window])match = [final_idx[min_idx], min_value / min_value_2nd]matches[N, :] = matchreturn matches
实验结果
我使用了New 数据集 , 本来想同时对比FAB-MAP的效果的 , 然而水平有限 , 后面有空再补上 。
再看一下论文中使用的参数:
本人修改了上面部分参数 , 在下面会列出 。
闭环检测
首先试一下闭环检测的效果 , 和数据集的对比一下 , 使用的参数如下:
R x , R y R_x, R_y Rx?,Ry?
128, 96
R w i n d o w R_{} ?
10

SeqSlam论文阅读和实验