1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
from keras import backend as K
import tensorflow as tf
def focal_eiou(b1, b2):
"""
输入为:
----------
b1: tensor, shape=(batch, feat_w, feat_h, anchor_num, 4), xywh
b2: tensor, shape=(batch, feat_w, feat_h, anchor_num, 4), xywh
返回为:
-------
ciou: tensor, shape=(batch, feat_w, feat_h, anchor_num, 1)
"""
#-----------------------------------------------------------#
# 求出预测框左上角右下角
# b1_mins (batch, feat_w, feat_h, anchor_num, 2)
# b1_maxes (batch, feat_w, feat_h, anchor_num, 2)
#-----------------------------------------------------------#
b1_xy = b1[..., :2]
b1_wh = b1[..., 2:4]
b1_wh_half = b1_wh/2.
b1_mins = b1_xy - b1_wh_half
b1_maxes = b1_xy + b1_wh_half
#-----------------------------------------------------------#
# 求出真实框左上角右下角
# b2_mins (batch, feat_w, feat_h, anchor_num, 2)
# b2_maxes (batch, feat_w, feat_h, anchor_num, 2)
#-----------------------------------------------------------#
b2_xy = b2[..., :2]
b2_wh = b2[..., 2:4]
b2_wh_half = b2_wh/2.
b2_mins = b2_xy - b2_wh_half
b2_maxes = b2_xy + b2_wh_half
#-----------------------------------------------------------#
# 求真实框和预测框所有的iou
# iou (batch, feat_w, feat_h, anchor_num)
#-----------------------------------------------------------#
intersect_mins = K.maximum(b1_mins, b2_mins)
intersect_maxes = K.minimum(b1_maxes, b2_maxes)
intersect_wh = K.maximum(intersect_maxes - intersect_mins, 0.)
# ∩面积
intersect_area = intersect_wh[..., 0] * intersect_wh[..., 1]
b1_area = b1_wh[..., 0] * b1_wh[..., 1]
b2_area = b2_wh[..., 0] * b2_wh[..., 1]
# ∪面积
union_area = b1_area + b2_area - intersect_area
# ∩/∪
iou = intersect_area / K.maximum(union_area, K.epsilon())
#-----------------------------------------------------------#
# 计算中心的差距 c**2
# center_distance (batch, feat_w, feat_h, anchor_num)
#-----------------------------------------------------------#
# p**2 中心点距离
center_distance = K.sum(K.square(b1_xy - b2_xy), axis=-1)
# 左上和右下的最小外接矩形w、h
enclose_mins = K.minimum(b1_mins, b2_mins)
enclose_maxes = K.maximum(b1_maxes, b2_maxes)
enclose_wh = K.maximum(enclose_maxes - enclose_mins, 0.0)
#-----------------------------------------------------------#
# 计算对角线距离 c**2
# enclose_diagonal (batch, feat_w, feat_h, anchor_num)
#-----------------------------------------------------------#
enclose_diagonal = K.sum(K.square(enclose_wh), axis=-1)
w_h = K.square(b1_wh - b2_wh)
Cw_Ch = K.maximum(K.square(enclose_wh) ,K.epsilon())
squares = w_h / Cw_Ch
Leiou = 1 - iou + 1.0 * (center_distance) / K.maximum(enclose_diagonal ,K.epsilon()) + K.sum( 1.0 * squares)
gamma = 0.5
focal_eiou_loss = Leiou * iou ** gamma
return focal_eiou_loss
if __name__ == "__main__":
# 导入tensorflow库进行变量创建
import tensorflow as tf
# 创建两个变量 predict, truth进行测试
predict = tf.constant(0.6, shape=(1, 13, 13, 1, 4), dtype=tf.float32)
truth = tf.constant(0.5, shape=(1, 13, 13, 1, 4), dtype=tf.float32)
# 调用定义的函数
result = focal_eiou(predict,truth)
with tf.Session() as sess:
print(sess.run(result))
|