- 前提是读者要对YOLO的预测框机制比较熟悉,本节主要是给出具体的计算方法.
-
问题描述
(1) bbox->feature map
我们要做的,是把bbox的全局坐标系转换成相对于他所在的局部坐标系.比如通过归一化的bbox坐标,他是相对于原图坐标左上角的,而我们现在把它转换到每一个小格子左上角上去.通过这个坐标进行损失函数的计算.(2)feature map->bbox
上面过程的逆向计算. -
解析
(1)就是坐标映射问题,当全局尺寸归一化为1时,可以观察出映射公式:
o u t = i n p u t − l e f t G r i d P o s e g r i d S i z e out = \frac{input-leftGridPose}{gridSize} out=gridSizeinput−leftGridPose
其中 l e f t G r i d P o s e leftGridPose leftGridPose是bbox所在格子的左边界坐标, g r i d S i z e gridSize gridSize是格子的尺寸,代码里自动计算.
(2)反过来
迭代每一个feature map 上的格子,每个格子都包含
[
b
b
o
x
_
x
y
w
h
,
c
o
n
f
i
d
e
n
c
e
,
c
l
a
s
s
e
s
]
[bbox\_{xywh}, confidence, classes]
[bbox_xywh,confidence,classes]
假设输出特征层的通道定义为相对坐标,置信度,类别: [ r x , r y , r w , r h , c o n f i d e n c e , c l a s s e s ] [r_x, r_y,r_w,r_h,confidence,classes] [rx,ry,rw,rh,confidence,classes]
-
首先计算每个 g r i d grid grid的左上角坐标,假设我们当前要计算 i , j i,j i,j处的各种参数:
g r i d x , g r i d y = i ∗ g r i d _ s i z e _ x , j ∗ g r i d _ s i z e _ j grid_x, grid_y=i*grid\_size\_x, j*grid\_size\_j gridx,gridy=i∗grid_size_x,j∗grid_size_j -
然后切出相对于左上角的边框预测值以及宽高预测值(这里就要根据各位特征的各个通道具体是怎么定义的来做): r x , r y = p r e d [ 0 : 2 , i , j ] r_x, r_y=pred[0:2, i , j] rx,ry=pred[0:2,i,j] r w , r h = p r e d [ 2 : 4 , i , j , ] r_w, r_h=pred[2:4, i, j,] rw,rh=pred[2:4,i,j,]
-
因为目的是为了可视化预测出的 b b o x bbox bbox, 所以最后把相对坐标转换成相对于整个图像的坐标:
a x = g r i d x + r x ∗ g r i d _ s i z e _ x a_x=grid_x+r_x*grid\_size\_x ax=gridx+rx∗grid_size_x a y = g r i d y + r y ∗ g r i d _ s i z e _ y a_y=grid_y+r_y*grid\_size\_y ay=gridy+ry∗grid_size_y通过上式,从网络输出转换到相对于图像的坐标.
3.给出(1)部分的计算原理代码
import numpy as np
import math
# import matplotlib.pyplot as plt
"""
向上取整 ceil
向下取整 floor
"""
def real_pos(input):
grid_num = 5
grid_size = 1 / 5
# 所在的格子
pos_x = math.ceil(input / grid_size)
left = (pos_x - 1) * grid_size
# right = pos_x * grid_size # 用不到
delta = input - left
output = delta / grid_size
return output
if __name__ == "__main__":
a = real_pos(0.399)
print(a)
# ANTenna 2020.07.16
- 在图像场景下,只需要调用两次就可以了-_-