IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> SOLD2算法之3: 特征点与heatmap结合检测有效线段(CVPR 2021) -> 正文阅读

[人工智能]SOLD2算法之3: 特征点与heatmap结合检测有效线段(CVPR 2021)

在这里插入图片描述

input image:[1, 1, H, W],经过backbone net后为[1, 256, H/4, W/4]

heatmap_decoder用于检测出线段的heatmap

先看heatmap_decoder,它的结构如下
conv 3x3, s=1, p=1
pixelShuffel(2)
这个block出现2次,然后接一个conv 1x1
PixelShuffel起了重要的上采样及改变channel的作用。

backbone net出来的channel=256被两个pixelShuffel(2)变换后channel=16,再经过conv1x1,最终heatmap的channel为2,即黑白两通道,[1, 2, H, W]。
这个heatmap对dim=1求softmax, 只取channel=1通道,shape变换为[H, W]

现在已经得到了topk=300个的特征点[300, 2],线段的heatmap [H, W],现在要把它们结合起来检测图像中的线段。

1)heatmap refine
首先,要把heatmap给refine一下,为什么呢,因为有的地方值很小,会显得很弱;
要把整体的值给调整到[0, 1],当然这不是简单的归一化,直接归一化还是面临值小的地方很弱的问题。
源码中是以block为单位处理的,把H,W分成20个block这样的思想,
每次走block_size/2, 所以block_H = H / (1 + (20-1)/2), 同理block_W

block每走一步,把block区域里面>thres=0.001的元素给挑出来,逆序排列,取前N个的heatmap value的平均值,用区域里面所有heatmap的值除这个平均值,限制到[0,1]。
block窗口扫完整个heatmap,则处理完毕。
可能会说,block窗口扫描时是有重叠的,有的位置点很多,有的点很少,这一除岂不是点多的位置叠加更多?源码中还统计了每个位置点的个数,用结果?每个位置点的个数来解决这一问题。
这样做可避免直接除最大值导致有些值太弱,又避免了整个heatmap的平均值太小;同时,用block为单位,避免受某块区域值太大或太小所影响。

有兴趣可以阅读以下源码

#这个refine操作可以使prob分布到[0,1]取值区间,如果prob都偏小会更明显
def refine_heatmap(self, heatmap, ratio=0.2, valid_thresh=1e-2):

2)candidate selection
直观理解,这部分是候选的线段有点多,要去掉一些candidate。
对应paper的如下部分,简言之,就是线段的NMS:
在这里插入图片描述
先说总共有多少条candidate线段,假设有300个特征点,它们中的每个都可以作为线段的起点和终点(当然排除自己到自己的),再去掉重复的(1->2, 2->1),所以有300x300-自己到自己-一半重复的,相当于一个矩阵的上三角,共44850条线段,为下图的蓝线。

至于怎么去掉不需要的candidate,见下图,
现要去掉旁边有一堆杂乱线段的蓝线,怎么判断蓝线周围有没有很近的杂乱线段呢?
用每条蓝线的起点,连接所有可以作为重300个特征点,为下图的红线(省略了一部分)。
paper中把这些线都投影到蓝线上,投影线段的长度在蓝线内,且到投影点距离<=3个像素的,算作杂乱的线,如果存在这些杂乱的线,那么这个蓝线就不再考虑了。
蓝线有44850条,每条线都要这样处理,这计算量也是够大的(用了矩阵计算优化)。
跑了一下44850条直线瞬间只剩下11868条,还是太多有木有。
在这里插入图片描述
有兴趣可以看以下代码

#把投影在同一直线,同时投影距离较近的直线从candidate_map中去掉
def candidate_suppression(self, junctions, candidate_map):
    #节选一部分
    junc_mask = junc_dist_mask * proj_mask  #投影在直线内,且到投影点距离<=3的mask

    # Minus starting points
    num_segs = start_point_idxs.shape[0]
    junc_counts = torch.sum(junc_mask, dim=[1, 2]) #有多少个投影在直线内,又<=3个像素的投影线
    junc_counts -= junc_mask[..., 0][torch.arange(0, num_segs),
                                     start_point_idxs].to(torch.int) #去掉起点到它自己的线段个数
    junc_counts -= junc_mask[..., 0][torch.arange(0, num_segs),
                                     end_point_idxs].to(torch.int) #去掉蓝线线段个数,那么剩下的就是一些距离很近的线段的个数,方便后面去掉
    
    # Get the invalid candidate mask
    final_mask = junc_counts > 0
    candidate_map[start_point_idxs[final_mask],
                  end_point_idxs[final_mask]] = 0

3)检测有效线段
在这里插入图片描述

这一步的作用是把上面一步剩下的线段 和 网络输出的线段heatmap匹配,再滤掉一波多余的candidate线段。
可能会说直接在线段上采点,看点在不在heatmap的线段上不就行了,为什么要local maximum search。
那遇到下面这种情况呢,采样点算不算在heatmap的线段上?
其实这几个采样点已经算是检测到线段了,但是真要从heatmap中取对应值,仍然取不到1,只会取到很小的值。
在这里插入图片描述
这个local maximum search就是以每个采样点为中心,半径为3pixel的圆内找到局部最大值,如下图,这样就能找到heatmap线段上的值1了。
在这里插入图片描述
这个半径是随线段长短变化的,
在这里插入图片描述

#每条线上采样64个点,每个点半径dist_thresh内的区域取heatmap的local max值,返回所有采样点区域的heatmap local max值
def detect_local_max(self, heatmap, cand_h, cand_w, H, W,
                     normalized_seg_length, device):

仅仅这样就能检测出有效线段了么?No, 比如如下场景
在这里插入图片描述
这个乍一看已经和heatmap的线段不一致了,
paper中用了如下方法来解决
在这里插入图片描述
算采样点的平均score,平均score低了那就是偏离了,认为是无效线段。

那如果是如下情形呢?采样点的线段非常之短,而heatmap中的线段很长,这明显就不是一条直线啊。
在这里插入图片描述
这种情况用长度比例来解决,
在这里插入图片描述
这个比例是这样算的,取出的heatmap值大于一个阈值的采样点数,除以采样点总数(一个线段采64个点)得到的比例,比例要>90%才行。不然就算无效线段。

经过average score和inlier ratio这一波操作,第2)步过滤后的11868条线段,转眼就只剩下了457条。

def detect(self, junctions, heatmap, device=torch.device("cpu")):

这就是最终检测到的line segments,shape为[457, 2, 2], 两个2分别是线段起点和终点的(h,w)坐标。

其他步骤
1.SOLD2算法之backbone
2.SOLD2算法之特征点检测,点NMS

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:22:35  更:2022-04-09 18:24:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:48:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码