Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
曾经的那一瞬间
Models
提交
a1df6e20
M
Models
项目概览
曾经的那一瞬间
/
Models
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
Models
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a1df6e20
编写于
9月 09, 2021
作者:
V
Vishnu Banna
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
box_ops update
上级
f5830dbe
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
83 addition
and
100 deletion
+83
-100
official/vision/beta/projects/yolo/ops/box_ops.py
official/vision/beta/projects/yolo/ops/box_ops.py
+83
-100
未找到文件。
official/vision/beta/projects/yolo/ops/box_ops.py
浏览文件 @
a1df6e20
...
...
@@ -38,32 +38,7 @@ def yxyx_to_xcycwh(box: tf.Tensor):
return
box
@
tf
.
custom_gradient
def
_xcycwh_to_yxyx
(
box
:
tf
.
Tensor
,
scale
):
"""Private function to allow custom gradients with defaults."""
with
tf
.
name_scope
(
'xcycwh_to_yxyx'
):
xy
,
wh
=
tf
.
split
(
box
,
2
,
axis
=-
1
)
xy_min
=
xy
-
wh
/
2
xy_max
=
xy
+
wh
/
2
x_min
,
y_min
=
tf
.
split
(
xy_min
,
2
,
axis
=-
1
)
x_max
,
y_max
=
tf
.
split
(
xy_max
,
2
,
axis
=-
1
)
box
=
tf
.
concat
([
y_min
,
x_min
,
y_max
,
x_max
],
axis
=-
1
)
def
delta
(
dbox
):
# y_min = top, x_min = left, y_max = bottom, x_max = right
dt
,
dl
,
db
,
dr
=
tf
.
split
(
dbox
,
4
,
axis
=-
1
)
dx
=
dl
+
dr
dy
=
dt
+
db
dw
=
(
dr
-
dl
)
/
scale
dh
=
(
db
-
dt
)
/
scale
dbox
=
tf
.
concat
([
dx
,
dy
,
dw
,
dh
],
axis
=-
1
)
return
dbox
,
0.0
return
box
,
delta
def
xcycwh_to_yxyx
(
box
:
tf
.
Tensor
,
darknet
=
False
):
def
xcycwh_to_yxyx
(
box
:
tf
.
Tensor
):
"""Converts boxes from x_center, y_center, width, height to yxyx format.
Args:
...
...
@@ -74,11 +49,13 @@ def xcycwh_to_yxyx(box: tf.Tensor, darknet=False):
Returns:
box: a `Tensor` whose shape is the same as `box` in new format.
"""
if
darknet
:
scale
=
1.0
else
:
scale
=
2.0
box
=
_xcycwh_to_yxyx
(
box
,
scale
)
with
tf
.
name_scope
(
'xcycwh_to_yxyx'
):
xy
,
wh
=
tf
.
split
(
box
,
2
,
axis
=-
1
)
xy_min
=
xy
-
wh
/
2
xy_max
=
xy
+
wh
/
2
x_min
,
y_min
=
tf
.
split
(
xy_min
,
2
,
axis
=-
1
)
x_max
,
y_max
=
tf
.
split
(
xy_max
,
2
,
axis
=-
1
)
box
=
tf
.
concat
([
y_min
,
x_min
,
y_max
,
x_max
],
axis
=-
1
)
return
box
...
...
@@ -98,8 +75,9 @@ def intersect_and_union(box1, box2, yxyx=False):
intersection: a `Tensor` who represents the intersection.
union: a `Tensor` who represents the union.
"""
if
not
yxyx
:
box1_area
=
tf
.
reduce_prod
(
tf
.
split
(
box1
,
2
,
axis
=-
1
)[
-
1
],
axis
=-
1
)
box2_area
=
tf
.
reduce_prod
(
tf
.
split
(
box2
,
2
,
axis
=-
1
)[
-
1
],
axis
=-
1
)
box1
=
xcycwh_to_yxyx
(
box1
)
box2
=
xcycwh_to_yxyx
(
box2
)
...
...
@@ -110,13 +88,14 @@ def intersect_and_union(box1, box2, yxyx=False):
intersect_wh
=
tf
.
math
.
maximum
(
intersect_maxes
-
intersect_mins
,
0.0
)
intersection
=
tf
.
reduce_prod
(
intersect_wh
,
axis
=-
1
)
box1_area
=
tf
.
reduce_prod
(
b1ma
-
b1mi
,
axis
=-
1
)
box2_area
=
tf
.
reduce_prod
(
b2ma
-
b2mi
,
axis
=-
1
)
if
yxyx
:
box1_area
=
tf
.
reduce_prod
(
b1ma
-
b1mi
,
axis
=-
1
)
box2_area
=
tf
.
reduce_prod
(
b2ma
-
b2mi
,
axis
=-
1
)
union
=
box1_area
+
box2_area
-
intersection
return
intersection
,
union
def
smallest_encompassing_box
(
box1
,
box2
,
yxyx
=
False
):
def
smallest_encompassing_box
(
box1
,
box2
,
yxyx
=
False
,
clip
=
False
):
"""Calculates the smallest box that encompasses box1 and box2.
Args:
...
...
@@ -141,15 +120,15 @@ def smallest_encompassing_box(box1, box2, yxyx=False):
bcmi
=
tf
.
math
.
minimum
(
b1mi
,
b2mi
)
bcma
=
tf
.
math
.
maximum
(
b1ma
,
b2ma
)
bca
=
tf
.
reduce_prod
(
bcma
-
bcmi
,
keepdims
=
True
,
axis
=-
1
)
box_c
=
tf
.
concat
([
bcmi
,
bcma
],
axis
=-
1
)
if
not
yxyx
:
box_c
=
yxyx_to_xcycwh
(
box_c
)
box_c
=
tf
.
where
(
bca
==
0.0
,
tf
.
zeros_like
(
box_c
),
box_c
)
return
box_c
if
clip
:
bca
=
tf
.
reduce_prod
(
bcma
-
bcmi
,
keepdims
=
True
,
axis
=-
1
)
box_c
=
tf
.
where
(
bca
<=
0.0
,
tf
.
zeros_like
(
box_c
),
box_c
)
return
bcmi
,
bcma
,
box_c
def
compute_iou
(
box1
,
box2
,
yxyx
=
False
):
...
...
@@ -166,15 +145,13 @@ def compute_iou(box1, box2, yxyx=False):
Returns:
iou: a `Tensor` who represents the intersection over union.
"""
# get box corners
with
tf
.
name_scope
(
'iou'
):
intersection
,
union
=
intersect_and_union
(
box1
,
box2
,
yxyx
=
yxyx
)
iou
=
math_ops
.
divide_no_nan
(
intersection
,
union
)
iou
=
math_ops
.
rm_nan_inf
(
iou
,
val
=
0.0
)
return
iou
def
compute_giou
(
box1
,
box2
,
yxyx
=
False
,
darknet
=
False
):
def
compute_giou
(
box1
,
box2
,
yxyx
=
False
):
"""Calculates the General intersection over union between box1 and box2.
Args:
...
...
@@ -191,27 +168,21 @@ def compute_giou(box1, box2, yxyx=False, darknet=False):
giou: a `Tensor` who represents the General intersection over union.
"""
with
tf
.
name_scope
(
'giou'
):
# get IOU
if
not
yxyx
:
box1
=
xcycwh_to_yxyx
(
box1
,
darknet
=
darknet
)
box2
=
xcycwh_to_yxyx
(
box2
,
darknet
=
darknet
)
yxyx
=
True
yxyx1
=
xcycwh_to_yxyx
(
box1
)
yxyx2
=
xcycwh_to_yxyx
(
box2
)
else
:
yxyx1
,
yxyx2
=
box1
,
box2
intersection
,
union
=
intersect_and_union
(
box1
,
box2
,
yxyx
=
yxyx
)
cmi
,
cma
,
_
=
smallest_encompassing_box
(
yxyx1
,
yxyx2
,
yxyx
=
True
)
intersection
,
union
=
intersect_and_union
(
yxyx1
,
yxyx2
,
yxyx
=
True
)
iou
=
math_ops
.
divide_no_nan
(
intersection
,
union
)
iou
=
math_ops
.
rm_nan_inf
(
iou
,
val
=
0.0
)
# find the smallest box to encompase both box1 and box2
boxc
=
smallest_encompassing_box
(
box1
,
box2
,
yxyx
=
yxyx
)
if
yxyx
:
boxc
=
yxyx_to_xcycwh
(
boxc
)
_
,
cwch
=
tf
.
split
(
boxc
,
2
,
axis
=-
1
)
c
=
tf
.
math
.
reduce_prod
(
cwch
,
axis
=-
1
)
bcwh
=
cma
-
cmi
c
=
tf
.
math
.
reduce_prod
(
bcwh
,
axis
=-
1
)
# compute giou
regularization
=
math_ops
.
divide_no_nan
((
c
-
union
),
c
)
giou
=
iou
-
regularization
giou
=
tf
.
clip_by_value
(
giou
,
clip_value_min
=-
1.0
,
clip_value_max
=
1.0
)
return
iou
,
giou
...
...
@@ -236,30 +207,27 @@ def compute_diou(box1, box2, beta=1.0, yxyx=False, darknet=False):
with
tf
.
name_scope
(
'diou'
):
# compute center distance
if
not
yxyx
:
box1
=
xcycwh_to_yxyx
(
box1
,
darknet
=
darknet
)
box2
=
xcycwh_to_yxyx
(
box2
,
darknet
=
darknet
)
yxyx
=
True
intersection
,
union
=
intersect_and_union
(
box1
,
box2
,
yxyx
=
yxyx
)
boxc
=
smallest_encompassing_box
(
box1
,
box2
,
yxyx
=
yxyx
)
xycc1
,
xycc2
=
box1
,
box2
yxyx1
=
xcycwh_to_yxyx
(
box1
)
yxyx2
=
xcycwh_to_yxyx
(
box2
)
else
:
yxyx1
,
yxyx2
=
box1
,
box2
xycc1
=
yxyx_to_xcycwh
(
box1
)
xycc2
=
yxyx_to_xcycwh
(
box2
)
cmi
,
cma
,
_
=
smallest_encompassing_box
(
yxyx1
,
yxyx2
,
yxyx
=
True
)
intersection
,
union
=
intersect_and_union
(
yxyx1
,
yxyx2
,
yxyx
=
True
)
iou
=
math_ops
.
divide_no_nan
(
intersection
,
union
)
iou
=
math_ops
.
rm_nan_inf
(
iou
,
val
=
0.0
)
if
yxyx
:
boxc
=
yxyx_to_xcycwh
(
boxc
)
box1
=
yxyx_to_xcycwh
(
box1
)
box2
=
yxyx_to_xcycwh
(
box2
)
b1xy
,
_
=
tf
.
split
(
box
1
,
2
,
axis
=-
1
)
b2xy
,
_
=
tf
.
split
(
box
2
,
2
,
axis
=-
1
)
_
,
bcwh
=
tf
.
split
(
boxc
,
2
,
axis
=-
1
)
b1xy
,
_
=
tf
.
split
(
xycc
1
,
2
,
axis
=-
1
)
b2xy
,
_
=
tf
.
split
(
xycc
2
,
2
,
axis
=-
1
)
bcwh
=
cma
-
cmi
center_dist
=
tf
.
reduce_sum
((
b1xy
-
b2xy
)
**
2
,
axis
=-
1
)
c_diag
=
tf
.
reduce_sum
(
bcwh
**
2
,
axis
=-
1
)
regularization
=
math_ops
.
divide_no_nan
(
center_dist
,
c_diag
)
diou
=
iou
-
regularization
**
beta
diou
=
tf
.
clip_by_value
(
diou
,
clip_value_min
=-
1.0
,
clip_value_max
=
1.0
)
return
iou
,
diou
...
...
@@ -280,33 +248,48 @@ def compute_ciou(box1, box2, yxyx=False, darknet=False):
ciou: a `Tensor` who represents the complete intersection over union.
"""
with
tf
.
name_scope
(
'ciou'
):
# compute DIOU and IOU
iou
,
diou
=
compute_diou
(
box1
,
box2
,
yxyx
=
yxyx
,
darknet
=
darknet
)
if
yxyx
:
box1
=
yxyx_to_xcycwh
(
box1
)
box2
=
yxyx_to_xcycwh
(
box2
)
_
,
_
,
b1w
,
b1h
=
tf
.
split
(
box1
,
4
,
axis
=-
1
)
_
,
_
,
b2w
,
b2h
=
tf
.
split
(
box1
,
4
,
axis
=-
1
)
# computer aspect ratio consistency
terma
=
tf
.
cast
(
math_ops
.
divide_no_nan
(
b1w
,
b1h
),
tf
.
float32
)
termb
=
tf
.
cast
(
math_ops
.
divide_no_nan
(
b2w
,
b2h
),
tf
.
float32
)
arcterm
=
tf
.
square
(
tf
.
math
.
atan
(
terma
)
-
tf
.
math
.
atan
(
termb
))
v
=
tf
.
squeeze
(
4
*
arcterm
/
(
math
.
pi
**
2
),
axis
=-
1
)
v
=
tf
.
cast
(
v
,
b1w
.
dtype
)
a
=
tf
.
stop_gradient
(
math_ops
.
divide_no_nan
(
v
,
((
1
-
iou
)
+
v
)))
ciou
=
diou
-
(
v
*
a
)
ciou
=
tf
.
clip_by_value
(
ciou
,
clip_value_min
=-
1.0
,
clip_value_max
=
1.0
)
if
not
yxyx
:
xycc1
,
xycc2
=
box1
,
box2
yxyx1
=
xcycwh_to_yxyx
(
box1
)
yxyx2
=
xcycwh_to_yxyx
(
box2
)
else
:
yxyx1
,
yxyx2
=
box1
,
box2
xycc1
=
yxyx_to_xcycwh
(
box1
)
xycc2
=
yxyx_to_xcycwh
(
box2
)
# Build the smallest encomapssing box.
cmi
,
cma
,
_
=
smallest_encompassing_box
(
yxyx1
,
yxyx2
,
yxyx
=
True
)
intersection
,
union
=
intersect_and_union
(
yxyx1
,
yxyx2
,
yxyx
=
True
)
iou
=
math_ops
.
divide_no_nan
(
intersection
,
union
)
b1xy
,
b1w
,
b1h
=
tf
.
split
(
xycc1
,
[
2
,
1
,
1
],
axis
=-
1
)
b2xy
,
b2w
,
b2h
=
tf
.
split
(
xycc2
,
[
2
,
1
,
1
],
axis
=-
1
)
bchw
=
cma
-
cmi
# Center regularization
center_dist
=
tf
.
reduce_sum
((
b1xy
-
b2xy
)
**
2
,
axis
=-
1
)
c_diag
=
tf
.
reduce_sum
(
bchw
**
2
,
axis
=-
1
)
regularization
=
math_ops
.
divide_no_nan
(
center_dist
,
c_diag
)
# Computer aspect ratio consistency
terma
=
math_ops
.
divide_no_nan
(
b1w
,
b1h
)
# gt
termb
=
math_ops
.
divide_no_nan
(
b2w
,
b2h
)
# pred
arcterm
=
tf
.
squeeze
(
tf
.
math
.
pow
(
tf
.
math
.
atan
(
termb
)
-
tf
.
math
.
atan
(
terma
),
2
),
axis
=-
1
)
v
=
(
4
/
math
.
pi
**
2
)
*
arcterm
# Compute the aspect ratio weight, should be treated as a constant
a
=
tf
.
stop_gradient
(
math_ops
.
divide_no_nan
(
v
,
1
-
iou
+
v
))
if
darknet
:
grad_scale
=
tf
.
stop_gradient
(
tf
.
square
(
b2w
)
+
tf
.
square
(
b2h
))
v
*=
tf
.
squeeze
(
grad_scale
,
axis
=-
1
)
ciou
=
iou
-
regularization
-
(
v
*
a
)
return
iou
,
ciou
def
aggregated_comparitive_iou
(
boxes1
,
boxes2
=
None
,
iou_type
=
0
,
beta
=
0.6
):
def
aggregated_comparitive_iou
(
boxes1
,
boxes2
=
None
,
iou_type
=
0
,
beta
=
0.6
):
"""Calculates the IOU between two set of boxes.
Similar to bbox_overlap but far more versitile.
...
...
@@ -333,12 +316,12 @@ def aggregated_comparitive_iou(boxes1,
else
:
boxes2
=
tf
.
transpose
(
boxes1
,
perm
=
(
0
,
2
,
1
,
3
))
if
iou_type
==
0
:
#
diou
if
iou_type
==
0
or
iou_type
==
"diou"
:
#
diou
_
,
iou
=
compute_diou
(
boxes1
,
boxes2
,
beta
=
beta
,
yxyx
=
True
)
elif
iou_type
==
1
:
#
giou
elif
iou_type
==
1
or
iou_type
==
"giou"
:
#
giou
_
,
iou
=
compute_giou
(
boxes1
,
boxes2
,
yxyx
=
True
)
elif
iou_type
==
2
:
#
ciou
elif
iou_type
==
2
or
iou_type
==
"ciou"
:
#
ciou
_
,
iou
=
compute_ciou
(
boxes1
,
boxes2
,
yxyx
=
True
)
else
:
iou
=
compute_iou
(
boxes1
,
boxes2
,
yxyx
=
True
)
return
iou
return
iou
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录