人臉檢測 Retinaface - GT框(ground truth box)與 先驗框(prior box)之間是如何匹配的

人臉檢測 Retinaface - GT框(ground truth box)與 先驗框(prior box)之間是如何匹配的

flyfish

原函數是def match(threshold, truths, priors, variances, labels, landms, loc_t, conf_t, landm_t, idx):
內容較多所以將函數簡化重新解釋

開始部分是計算IoU
計算IoU 是計算先驗框和GT框
先驗框的座標是center-size,這裏要轉換成統一的 xmin, ymin, xmax, ymax形式
truths是GT框的座標,priors是先驗框的座標,計算前要用point_form轉換座標,所以看到的代碼是
overlaps = jaccard(truths,point_form(priors) )

後面的操作模擬寫一個程序
先把數量邊小,手工標註一張圖片,裏面有2個目標,程序自動生成了5個先驗框,然後分析

import torch
print( torch.__version__)#1.4.0

truths=torch.randn(2,4)#[目標,每個邊框座標4個值]
labels=torch.Tensor([[99], [100]])#兩個類別,類別數據比較大,容易一眼就看出來
overlaps = torch.rand(2, 5)#[目標的個數,先驗框的個數] 生成0到1之間的隨機數作爲IoU的計算結果
print("overlaps:",overlaps)
# overlaps: \
# tensor([[0.8388, 0.9715, 0.4808, 0.4071, 0.2703],
#         [0.1282, 0.7579, 0.6970, 0.3630, 0.5478]])

#爲每個GT框匹配一個IoU最大的先驗框,獲取 與目標GT框(GTBox) IoU最大的 先驗框(PriorBox) 的值和索引
#GTBox 1:PriorBox n
best_prior_overlap, best_prior_idx = overlaps.max(1, keepdim=True)
print(overlaps.max(1, keepdim=True))
# torch.return_types.max(
# values=tensor([[0.9715],
#         [0.7579]]),
# indices=tensor([[1],
#         [1]]))

#與上面相反,獲取 與先驗框(PriorBox) IoU最大的 GT框(GTBox) 的值和索引
#PriorBox 1:GTBox n
best_truth_overlap, best_truth_idx = overlaps.max(0, keepdim=True)
print(overlaps.max(0, keepdim=True))
# torch.return_types.max(
# values=tensor([[0.8388, 0.9715, 0.6970, 0.4071, 0.5478]]),
# indices=tensor([[0, 0, 1, 0, 1]]))


best_prior_idx.squeeze_(1)  # best_prior_idx的shape是[num_objects,1],去掉1維,shape變爲[num_objects]
best_prior_overlap.squeeze_(1) # best_prior_idx的shape是[num_objects,1],去掉1維,shape變爲[num_objects]


best_truth_idx.squeeze_(0)  # best_truth_idx的shape是[1,num_priors],去掉0維,shape變爲[num_priors]
best_truth_overlap.squeeze_(0)  # best_truth_overlap的shape是[1,num_priors],去掉0維,shape變爲[num_priors]



#GTBox與PriorBox的IoU最大的,確保最好的PriorBox保留下來,設置爲2,只要大於閾值就行,設置88也沒問題.

best_truth_overlap.index_fill_(0, best_prior_idx, 88)
print("best_truth_overlap:",best_truth_overlap)
# best_truth_overlap: \
# tensor([ 0.8388, 88.0000,  0.6970,  0.4071,  0.5478])

# 保證每一個GTBox匹配它的都是具有最大IoU的PriorBox
for j in range(best_prior_idx.size(0)):
    best_truth_idx[best_prior_idx[j]] = j
# 循環過程
# best_prior_idx.size(0): 2
# j 0
# best_prior_idx[j]: tensor(1)
# j 1
# best_prior_idx[j]: tensor(1)
# best_truth_idx: tensor([0, 1, 1, 0, 1])

print("best_truth_idx:",best_truth_idx)
#best_truth_idx: tensor([0, 1, 1, 0, 1])

matches = truths[best_truth_idx]#每一個PriorBox對應的bbox取出來
print("matches:",matches)
# matches: tensor([[ 0.8280,  0.5840,  0.5258,  1.1107],
#         [-1.4758,  0.3446,  0.3785,  1.8465],
#         [-1.4758,  0.3446,  0.3785,  1.8465],
#         [ 0.8280,  0.5840,  0.5258,  1.1107],
#         [-1.4758,  0.3446,  0.3785,  1.8465]])

print("best_truth_overlap:",best_truth_overlap)#每一個anchor對應的label取出來
#best_truth_overlap: tensor([ 0.8388, 88.0000,  0.6970,  0.4071,  0.5478])

conf = labels[best_truth_idx] #PriorBox對應的gt box的類別
print(conf.shape)#torch.Size([5, 1])
print("conf:",conf)
# conf: tensor([[ 99.],
#         [100.],
#         [100.],
#         [ 99.],
#         [100.]])
threshold=0.1
conf[best_truth_overlap < threshold] = 0  #過濾掉iou太低的,標記爲background
print("conf:",conf)
# conf: tensor([[ 99.],
#         [100.],
#         [100.],
#         [ 99.],
#         [100.]])

相當於遍歷conf中每一個元素都與threshold比較,成立則該元素爲0

假設threshold=0.5
假設best_truth_overlap的值是

tensor([ 0.2567,  0.8579,  0.3156, 88.0000, 88.0000])

結果是

# conf: tensor([[100.],
#         [ 99.],
#         [100.],
#         [100.],
#         [ 99.]])
# 則過濾掉其中的0.2567和  0.3156
# conf: tensor([[  0.],
#         [ 99.],
#         [  0.],
#         [100.],
#         [ 99.]])
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章