Maskrcnn实现笔记—锚框及建议框生成篇

目录

前言

Mask-rcnn为两阶段目标检测网络,第一阶段为特征提取生成建议框;第二阶段为根据建议框截取特征,处理截取特征得到分类、标签及掩码。

一、MaskRcnn特征提取网络及RPN网络

MaskRcnn特征提取网络一般采用resnet101+FPN网络,将生成五个不同大小的特征图P2,P3,P4,P5,P6。

Maskrcnn实现笔记---锚框及建议框生成篇

这五个特征图的大小不同,特征图上的每个像素点的感受野也都不同,对应到原图,相当于可以把原图分割成不同大小的网格。比如最小的(16,16)大小的特征图,上面一个像素点对应到原图上的格子的长宽为(1024/16,1024/16),相当于把原图分为16*16个网格。
锚框生成需要做的就是通过画框把原图分成许多个网格,再经由区域建议网络rpn给这些框进行校正和打分,得分高的也就是感兴趣区域,送到后续分类回归处理。

; 二、锚框生成

1.锚框参数设置

在每个特征图上,锚框的大小都是一样的。但在config文件中人工指定的RPN_ANCHOR_SCALES是对应到原图上的锚框边长。
如当输入为(1024,1024)时,一般锚框的长宽会设置为8个像素点,即以每个特征图上像素点为中心,截取长宽均为8个像素点的锚框,由于每个特征图上像素点感受野是不同的,相对于原图为[4,8,16,32,64]。这样对应的锚框scales即为[32,64,128,256,512]。一般会设置长宽比为[0.5 1 2],这样每个特征图上每个像素点的具有5*3种大小的锚框。

RPN_ANCHOR_SCALES = (32, 64, 128, 256,512)
RPN_ANCHOR_RATIOS = [0.5, 1, 2]

2.锚框生成流程

1.cofig.py文件编写

anchor的长度(像素)
RPN_ANCHOR_SCALES = (32, 64, 128, 256, 512)
anchor的变化比率
RPN_ANCHOR_RATIOS = [0.5, 1, 2]

anchor步长
RPN_ANCHOR_STRIDE = 1

特征金字塔步长(特征图压缩率)
FEATURE_STRIDES = [4, 8, 16, 32, 64]

2.根据传入图片大小和特征金字塔步长计算得到每个特征图的大小
feature_shapes=img_shape/feature_stride.

3.分别为每个特征图生成锚框
传入:特征图shape,锚框scale(与特征图大小对应),锚框变化率,输出锚框中心点坐标及长宽。
4.对锚框进一步处理,将锚框左上角与右下角进行标准化后存入数组
左上角=center-0.5[W,H];右下角=center+0.5[W,H]
左上角/(img_shapes-1),(右下角-1)/(img_shapes-1)

三.RPN网络

RPN网络:

Maskrcnn实现笔记---锚框及建议框生成篇

传入的是不同大小的特征层,首先经过一个3×3的卷积,输出通道变为512,再并行经过两个1×1卷积,一个输出为2k(anchor中包含和不包含物体的得分,k为每个像素点锚框数量,一般为9),另一个输出为4k(anchor应该调整的偏差,编码形式)。
注意由于第一个3×3卷积padding形式为same,后续的又是1×1卷积,所以特征图长宽经过rpn之后是不变的。
比如rpn网络输入特征图大小为[16,16,256],经过3×3变为[16,16,512],最后输出[16,16,2×9]与[16,16,4×9]。锚框生成也是对应特征图大小生成的[16,16,9],所以输出结果也就是特征图上每一个像素点上每一个锚框是否包含物体的得分与应该调整的偏差。

; 四.经过rpn网络后的框后续处理

首先anchors经过rpn网络,输出建议框与anchors的中心点偏差及长宽偏差的编码形式以及框内是否有目标的概率数组。
至于为什么是编码形式,因为训练rpn网络的时候,喂给网络的输入就是anchors位置,真实框与anchors的偏差的编码形式。因此训练完成后,输出的偏差就是编码形式的偏差。
因此下面对anchors与编码形式的偏差及概率数组进行处理。
RPN网络输出logits,classes,bbox,代表对锚框的修正。后续利用rpn网络得到的预测和偏差,对锚框进行下一步处理。

1.对偏差进行处理

rpn网络将预测anchor与真实框的偏差。在神经网络上,理想状态下希望rpn网络的输出最好符合正态分布,因此训练的时候会把喂入的”真实框与anchor的偏差”做一个标准化,即(x-均值)/标准差,这样得到的输出也是符合正态分布的。
由于anchor的选择是均匀的,所以可以认为均值为0,标准差是由anchor计算得到的。这里直接用了faster-rcnn的值[0.1 0.1 0.2 0.2]。

偏差乘以标准差,我理解成去标准化
deltas = deltas * np.reshape(self.config.RPN_BBOX_STD_DEV, [1, 1, 4])

2.筛选anchor

经过rpn网络后会输出一个anchor内有物体的得分,得分越高则anchor内存在物体的可能性越大。对得分进行排序,保留前k个anchor,k一般取6000。并且还把锚框的下标保留一下(锚框之前堆叠的顺序是按照特征图大小及一行一行的像素点来堆叠的)。

#筛选出前K个得分高的先验框
pre_nms_limit = tf.minimum(self.config.PRE_NMS_LIMIT, tf.shape(anchors)[1])
        # 获得这些框的索引
        ix = tf.nn.top_k(scores, pre_nms_limit, sorted=True,
                         name="top_anchors").indices

3.根据anchor得到建议框

根据anchor的位置和rpn预测的偏差得到建议框,建议框相对于anchor定位更接近于真实框,但是由于一开始anchor的大小相差较差,所以根据建议框的面积还是可以很容易区分这个建议框是从哪个特征图上截取的。

计算anchor的中心和宽高,boxes[y1,x1,y2,x2]
height = boxes[:, 2] - boxes[:, 0]
width = boxes[:, 3] - boxes[:, 1]
center_y = boxes[:, 0] + 0.5 * height
center_x = boxes[:, 1] + 0.5 * width
计算出调整后的先验框的中心和宽高
center_y += deltas[:, 0] * height
center_x += deltas[:, 1] * width
height *= tf.exp(deltas[:, 2])
width *= tf.exp(deltas[:, 3])
计算左上角和右下角的点的坐标
y1 = center_y - 0.5 * height
x1 = center_x - 0.5 * width
y2 = y1 + height
x2 = x1 + width
输出[y1,x2,y2,x2]

4.建议框处理得到最终ROIS(感兴趣区域)

1.修剪超出图像范围内的建议框
input:建议框:[n,y1,x1,y2,x2],窗口坐标[y11,x11,y12,x12]
output:修正后的anchors位置。把超出windows大小的框修正一下,y1=min(y1,y12)等等。
windows=[0,0,1,1],因为之前anchors已经标准化过,这个窗口代表的就是原图的范围。
2.非极大值抑制
如果几个建议框的IOU>nms_threshold,则保留得分最大的一个,去除其他的建议框。一般nms_threshold=0.7。
这样就得到了建议框。

总结

上面主要讲的就是建议框怎么来的。
首先人工指定anchor(先验框)的框的大小(输入图为1024的时候,一般在特征图上截取的长宽为8个像素点)和比率;
然后把特征输入到rpn网络中,会得到anchor与真实框的偏差及anchor中有物体的得分;
最后根据根据得分筛选前k个anchor,并根据偏差对其进行解码得到建议框,并进行非极大值抑制,得到最终的建议框。

Original: https://blog.csdn.net/Tepmoe/article/details/121142859
Author: Tepmoe
Title: Maskrcnn实现笔记—锚框及建议框生成篇

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/686566/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球