Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Tc.小浩
yolov7-obb
提交
a6b827ed
Y
yolov7-obb
项目概览
Tc.小浩
/
yolov7-obb
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Y
yolov7-obb
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a6b827ed
编写于
2月 06, 2023
作者:
_白鹭先生_
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
对极小框过滤
上级
dbdd8877
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
45 addition
and
117 deletion
+45
-117
train.py
train.py
+2
-2
utils/dataloader.py
utils/dataloader.py
+37
-25
utils/utils_rbox.py
utils/utils_rbox.py
+6
-90
未找到文件。
train.py
浏览文件 @
a6b827ed
...
@@ -180,7 +180,7 @@ if __name__ == "__main__":
...
@@ -180,7 +180,7 @@ if __name__ == "__main__":
# Adam可以使用相对较小的UnFreeze_Epoch
# Adam可以使用相对较小的UnFreeze_Epoch
# Unfreeze_batch_size 模型在解冻后的batch_size
# Unfreeze_batch_size 模型在解冻后的batch_size
#------------------------------------------------------------------#
#------------------------------------------------------------------#
UnFreeze_Epoch
=
3
00
UnFreeze_Epoch
=
1
00
Unfreeze_batch_size
=
4
Unfreeze_batch_size
=
4
#------------------------------------------------------------------#
#------------------------------------------------------------------#
# Freeze_Train 是否进行冻结训练
# Freeze_Train 是否进行冻结训练
...
@@ -211,7 +211,7 @@ if __name__ == "__main__":
...
@@ -211,7 +211,7 @@ if __name__ == "__main__":
#------------------------------------------------------------------#
#------------------------------------------------------------------#
# lr_decay_type 使用到的学习率下降方式,可选的有step、cos
# lr_decay_type 使用到的学习率下降方式,可选的有step、cos
#------------------------------------------------------------------#
#------------------------------------------------------------------#
lr_decay_type
=
"
cos
"
lr_decay_type
=
"
step
"
#------------------------------------------------------------------#
#------------------------------------------------------------------#
# save_period 多少个epoch保存一次权值
# save_period 多少个epoch保存一次权值
#------------------------------------------------------------------#
#------------------------------------------------------------------#
...
...
utils/dataloader.py
浏览文件 @
a6b827ed
...
@@ -7,7 +7,7 @@ from PIL import Image, ImageDraw
...
@@ -7,7 +7,7 @@ from PIL import Image, ImageDraw
from
torch.utils.data.dataset
import
Dataset
from
torch.utils.data.dataset
import
Dataset
from
utils.utils
import
cvtColor
,
preprocess_input
from
utils.utils
import
cvtColor
,
preprocess_input
from
utils.utils_rbox
import
poly
_filter
,
poly
2rbox
,
rbox2poly
from
utils.utils_rbox
import
poly2rbox
,
rbox2poly
class
YoloDataset
(
Dataset
):
class
YoloDataset
(
Dataset
):
def
__init__
(
self
,
annotation_lines
,
input_shape
,
num_classes
,
anchors
,
anchors_mask
,
epoch_length
,
\
def
__init__
(
self
,
annotation_lines
,
input_shape
,
num_classes
,
anchors
,
anchors_mask
,
epoch_length
,
\
...
@@ -63,6 +63,12 @@ class YoloDataset(Dataset):
...
@@ -63,6 +63,12 @@ class YoloDataset(Dataset):
nL
=
len
(
rbox
)
nL
=
len
(
rbox
)
labels_out
=
np
.
zeros
((
nL
,
7
))
labels_out
=
np
.
zeros
((
nL
,
7
))
if
nL
:
if
nL
:
#---------------------------------------------------#
# 对真实框进行归一化,调整到0-1之间
#---------------------------------------------------#
rbox
[:,
[
0
,
2
]]
=
rbox
[:,
[
0
,
2
]]
/
self
.
input_shape
[
1
]
rbox
[:,
[
1
,
3
]]
=
rbox
[:,
[
1
,
3
]]
/
self
.
input_shape
[
0
]
#---------------------------------------------------#
#---------------------------------------------------#
#---------------------------------------------------#
# 调整顺序,符合训练的格式
# 调整顺序,符合训练的格式
# labels_out中序号为0的部分在collect时处理
# labels_out中序号为0的部分在collect时处理
...
@@ -95,7 +101,7 @@ class YoloDataset(Dataset):
...
@@ -95,7 +101,7 @@ class YoloDataset(Dataset):
# 将polygon转换为rbox
# 将polygon转换为rbox
#------------------------------#
#------------------------------#
rbox
=
np
.
zeros
((
box
.
shape
[
0
],
6
))
rbox
=
np
.
zeros
((
box
.
shape
[
0
],
6
))
rbox
[...,
:
5
]
=
poly2rbox
(
box
[...,
:
8
],
(
ih
,
iw
),
use_pi
=
True
)
rbox
[...,
:
5
]
=
poly2rbox
(
box
[...,
:
8
],
use_pi
=
True
)
rbox
[...,
5
]
=
box
[...,
8
]
rbox
[...,
5
]
=
box
[...,
8
]
if
not
random
:
if
not
random
:
...
@@ -118,10 +124,14 @@ class YoloDataset(Dataset):
...
@@ -118,10 +124,14 @@ class YoloDataset(Dataset):
#---------------------------------#
#---------------------------------#
if
len
(
rbox
)
>
0
:
if
len
(
rbox
)
>
0
:
np
.
random
.
shuffle
(
rbox
)
np
.
random
.
shuffle
(
rbox
)
rbox
[:,
0
]
=
rbox
[:,
0
]
*
nw
/
w
+
dx
/
w
rbox
[:,
0
]
=
rbox
[:,
0
]
*
nw
/
iw
+
dx
rbox
[:,
1
]
=
rbox
[:,
1
]
*
nh
/
h
+
dy
/
h
rbox
[:,
1
]
=
rbox
[:,
1
]
*
nh
/
ih
+
dy
rbox
[:,
2
]
=
rbox
[:,
2
]
*
nw
/
w
rbox
[:,
2
]
=
rbox
[:,
2
]
*
nw
/
iw
rbox
[:,
3
]
=
rbox
[:,
3
]
*
nh
/
h
rbox
[:,
3
]
=
rbox
[:,
3
]
*
nh
/
ih
keep
=
(
rbox
[:,
0
]
>=
0
)
&
(
rbox
[:,
0
]
<
w
)
\
&
(
rbox
[:,
1
]
>=
0
)
&
(
rbox
[:,
0
]
<
h
)
\
&
(
rbox
[:,
2
]
>
5
)
|
(
rbox
[:,
3
]
>
5
)
rbox
=
rbox
[
keep
]
return
image_data
,
rbox
return
image_data
,
rbox
...
@@ -178,16 +188,20 @@ class YoloDataset(Dataset):
...
@@ -178,16 +188,20 @@ class YoloDataset(Dataset):
#---------------------------------#
#---------------------------------#
if
len
(
rbox
)
>
0
:
if
len
(
rbox
)
>
0
:
np
.
random
.
shuffle
(
rbox
)
np
.
random
.
shuffle
(
rbox
)
rbox
[:,
0
]
=
rbox
[:,
0
]
*
nw
/
w
+
dx
/
w
rbox
[:,
0
]
=
rbox
[:,
0
]
*
nw
/
iw
+
dx
rbox
[:,
1
]
=
rbox
[:,
1
]
*
nh
/
h
+
dy
/
h
rbox
[:,
1
]
=
rbox
[:,
1
]
*
nh
/
ih
+
dy
rbox
[:,
2
]
=
rbox
[:,
2
]
*
nw
/
w
rbox
[:,
2
]
=
rbox
[:,
2
]
*
nw
/
i
w
rbox
[:,
3
]
=
rbox
[:,
3
]
*
nh
/
h
rbox
[:,
3
]
=
rbox
[:,
3
]
*
nh
/
i
h
if
flip
:
if
flip
:
rbox
[:,
0
]
=
1
-
rbox
[:,
0
]
rbox
[:,
0
]
=
w
-
rbox
[:,
0
]
rbox
[:,
4
]
*=
-
1
rbox
[:,
4
]
*=
-
1
keep
=
(
rbox
[:,
0
]
>=
0
)
&
(
rbox
[:,
0
]
<
w
)
\
&
(
rbox
[:,
1
]
>=
0
)
&
(
rbox
[:,
0
]
<
h
)
\
&
(
rbox
[:,
2
]
>
5
)
|
(
rbox
[:,
3
]
>
5
)
rbox
=
rbox
[
keep
]
# 查看旋转框是否正确
# 查看旋转框是否正确
# draw = ImageDraw.Draw(image)
# draw = ImageDraw.Draw(image)
# polys = rbox2poly(rbox[..., :5])
*w
# polys = rbox2poly(rbox[..., :5])
# for poly in polys:
# for poly in polys:
# draw.polygon(xy=list(poly))
# draw.polygon(xy=list(poly))
# image.show()
# image.show()
...
@@ -239,7 +253,7 @@ class YoloDataset(Dataset):
...
@@ -239,7 +253,7 @@ class YoloDataset(Dataset):
# 将polygon转换为rbox
# 将polygon转换为rbox
#------------------------------#
#------------------------------#
rbox
=
np
.
zeros
((
box
.
shape
[
0
],
6
))
rbox
=
np
.
zeros
((
box
.
shape
[
0
],
6
))
rbox
[...,
:
5
]
=
poly2rbox
(
box
[...,
:
8
],
(
ih
,
iw
),
use_pi
=
True
)
rbox
[...,
:
5
]
=
poly2rbox
(
box
[...,
:
8
],
use_pi
=
True
)
rbox
[...,
5
]
=
box
[...,
8
]
rbox
[...,
5
]
=
box
[...,
8
]
#---------------------------------#
#---------------------------------#
# 是否翻转图片
# 是否翻转图片
...
@@ -247,7 +261,7 @@ class YoloDataset(Dataset):
...
@@ -247,7 +261,7 @@ class YoloDataset(Dataset):
flip
=
self
.
rand
()
<
.
5
flip
=
self
.
rand
()
<
.
5
if
flip
and
len
(
rbox
)
>
0
:
if
flip
and
len
(
rbox
)
>
0
:
image
=
image
.
transpose
(
Image
.
FLIP_LEFT_RIGHT
)
image
=
image
.
transpose
(
Image
.
FLIP_LEFT_RIGHT
)
rbox
[:,
0
]
=
1
-
rbox
[:,
0
]
rbox
[:,
0
]
=
iw
-
rbox
[:,
0
]
rbox
[:,
4
]
*=
-
1
rbox
[:,
4
]
*=
-
1
#------------------------------------------#
#------------------------------------------#
# 对图像进行缩放并且进行长和宽的扭曲
# 对图像进行缩放并且进行长和宽的扭曲
...
@@ -289,10 +303,14 @@ class YoloDataset(Dataset):
...
@@ -289,10 +303,14 @@ class YoloDataset(Dataset):
#---------------------------------#
#---------------------------------#
if
len
(
rbox
)
>
0
:
if
len
(
rbox
)
>
0
:
np
.
random
.
shuffle
(
rbox
)
np
.
random
.
shuffle
(
rbox
)
rbox
[:,
0
]
=
rbox
[:,
0
]
*
nw
/
w
+
dx
/
w
rbox
[:,
0
]
=
rbox
[:,
0
]
*
nw
/
iw
+
dx
rbox
[:,
1
]
=
rbox
[:,
1
]
*
nh
/
h
+
dy
/
h
rbox
[:,
1
]
=
rbox
[:,
1
]
*
nh
/
ih
+
dy
rbox
[:,
2
]
=
rbox
[:,
2
]
*
nw
/
w
rbox
[:,
2
]
=
rbox
[:,
2
]
*
nw
/
iw
rbox
[:,
3
]
=
rbox
[:,
3
]
*
nh
/
h
rbox
[:,
3
]
=
rbox
[:,
3
]
*
nh
/
ih
keep
=
(
rbox
[:,
0
]
>=
0
)
&
(
rbox
[:,
0
]
<
w
)
\
&
(
rbox
[:,
1
]
>=
0
)
&
(
rbox
[:,
0
]
<
h
)
\
&
(
rbox
[:,
2
]
>
5
)
|
(
rbox
[:,
3
]
>
5
)
rbox
=
rbox
[
keep
]
rbox_data
=
np
.
zeros
((
len
(
rbox
),
6
))
rbox_data
=
np
.
zeros
((
len
(
rbox
),
6
))
rbox_data
[:
len
(
rbox
)]
=
rbox
rbox_data
[:
len
(
rbox
)]
=
rbox
...
@@ -340,7 +358,7 @@ class YoloDataset(Dataset):
...
@@ -340,7 +358,7 @@ class YoloDataset(Dataset):
# 查看旋转框是否正确
# 查看旋转框是否正确
# newImage = Image.fromarray(new_image)
# newImage = Image.fromarray(new_image)
# draw = ImageDraw.Draw(newImage)
# draw = ImageDraw.Draw(newImage)
# polys = rbox2poly(new_rboxes[..., :5])
*w
# polys = rbox2poly(new_rboxes[..., :5])
# for poly in polys:
# for poly in polys:
# draw.polygon(xy=list(poly))
# draw.polygon(xy=list(poly))
# newImage.show()
# newImage.show()
...
@@ -354,12 +372,6 @@ class YoloDataset(Dataset):
...
@@ -354,12 +372,6 @@ class YoloDataset(Dataset):
new_rboxes
=
rbox_1
new_rboxes
=
rbox_1
else
:
else
:
new_rboxes
=
np
.
concatenate
([
rbox_1
,
rbox_2
],
axis
=
0
)
new_rboxes
=
np
.
concatenate
([
rbox_1
,
rbox_2
],
axis
=
0
)
# 查看旋转框是否正确
draw
=
ImageDraw
.
Draw
(
new_image
)
polys
=
rbox2poly
(
new_rboxes
[...,
:
5
])
*
640
for
poly
in
polys
:
draw
.
polygon
(
xy
=
list
(
poly
))
new_image
.
show
()
return
new_image
,
new_rboxes
return
new_image
,
new_rboxes
...
...
utils/utils_rbox.py
浏览文件 @
a6b827ed
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
Author: [egrt]
Author: [egrt]
Date: 2023-01-30 19:00:28
Date: 2023-01-30 19:00:28
LastEditors: [egrt]
LastEditors: [egrt]
LastEditTime: 2023-0
1-30 19:34:3
5
LastEditTime: 2023-0
2-06 20:34:0
5
Description: Oriented Bounding Boxes utils
Description: Oriented Bounding Boxes utils
'''
'''
...
@@ -41,7 +41,7 @@ def regular_theta(theta, mode='180', start=-pi/2):
...
@@ -41,7 +41,7 @@ def regular_theta(theta, mode='180', start=-pi/2):
theta
=
theta
%
cycle
theta
=
theta
%
cycle
return
theta
+
start
return
theta
+
start
def
poly2rbox
(
polys
,
img_size
=
(),
num_cls_thata
=
180
,
radius
=
6.0
,
use_pi
=
False
,
use_gaussian
=
False
):
def
poly2rbox
(
polys
,
num_cls_thata
=
180
,
radius
=
6.0
,
use_pi
=
False
,
use_gaussian
=
False
):
"""
"""
Trans poly format to rbox format.
Trans poly format to rbox format.
Args:
Args:
...
@@ -49,7 +49,6 @@ def poly2rbox(polys, img_size=(), num_cls_thata=180, radius=6.0, use_pi=False, u
...
@@ -49,7 +49,6 @@ def poly2rbox(polys, img_size=(), num_cls_thata=180, radius=6.0, use_pi=False, u
num_cls_thata (int): [1], theta class num
num_cls_thata (int): [1], theta class num
radius (float32): [1], window radius for Circular Smooth Label
radius (float32): [1], window radius for Circular Smooth Label
use_pi (bool): True θ∈[-pi/2, pi/2) , False θ∈[0, 180)
use_pi (bool): True θ∈[-pi/2, pi/2) , False θ∈[0, 180)
Returns:
Returns:
use_gaussian True:
use_gaussian True:
rboxes (array):
rboxes (array):
...
@@ -58,39 +57,19 @@ def poly2rbox(polys, img_size=(), num_cls_thata=180, radius=6.0, use_pi=False, u
...
@@ -58,39 +57,19 @@ def poly2rbox(polys, img_size=(), num_cls_thata=180, radius=6.0, use_pi=False, u
rboxes (array): (num_gts, [cx cy l s θ])
rboxes (array): (num_gts, [cx cy l s θ])
"""
"""
assert
polys
.
shape
[
-
1
]
==
8
assert
polys
.
shape
[
-
1
]
==
8
img_h
,
img_w
=
img_size
[
0
],
img_size
[
1
]
if
use_gaussian
:
if
use_gaussian
:
csl_labels
=
[]
csl_labels
=
[]
rboxes
=
[]
rboxes
=
[]
for
poly
in
polys
:
for
poly
in
polys
:
poly
=
np
.
float32
(
poly
.
reshape
(
4
,
2
))
poly
=
np
.
float32
(
poly
.
reshape
(
4
,
2
))
(
x
,
y
),
(
w
,
h
),
angle
=
cv2
.
minAreaRect
(
poly
)
# θ ∈ [0, 90] # opencv>=4.5.1 若是< -90到0
(
x
,
y
),
(
w
,
h
),
angle
=
cv2
.
minAreaRect
(
poly
)
# θ ∈ [0, 90]
angle
=
-
angle
# θ ∈ [-90, 0] # 故 rbbox2poly 中 角度再 负 了一次 定义是 ccw 逆时针
angle
=
-
angle
# θ ∈ [-90, 0]
# # 两者的闭集位置进行了调换,所以在边界角度处的转换和非边界角度处的转换越有所不同。
# if angle >= 90:
# angle = angle - 180
# else:
# w, h = h, w
# angle = angle -90
theta
=
angle
/
180
*
pi
# 转为pi制
theta
=
angle
/
180
*
pi
# 转为pi制
# trans opencv format to longedge format θ ∈ [-pi/2, pi/2]
# trans opencv format to longedge format θ ∈ [-pi/2, pi/2]
if
w
!=
max
(
w
,
h
):
if
w
!=
max
(
w
,
h
):
x
=
x
/
img_w
y
=
y
/
img_h
w
,
h
=
h
,
w
w
,
h
=
h
,
w
w
=
w
/
img_h
h
=
h
/
img_w
theta
+=
pi
/
2
theta
+=
pi
/
2
else
:
w
=
w
/
img_w
h
=
h
/
img_h
x
=
x
/
img_w
y
=
y
/
img_h
theta
=
regular_theta
(
theta
)
# limit theta ∈ [-pi/2, pi/2)
theta
=
regular_theta
(
theta
)
# limit theta ∈ [-pi/2, pi/2)
angle
=
(
theta
*
180
/
pi
)
+
90
# θ ∈ [0, 180)
angle
=
(
theta
*
180
/
pi
)
+
90
# θ ∈ [0, 180)
...
@@ -105,64 +84,6 @@ def poly2rbox(polys, img_size=(), num_cls_thata=180, radius=6.0, use_pi=False, u
...
@@ -105,64 +84,6 @@ def poly2rbox(polys, img_size=(), num_cls_thata=180, radius=6.0, use_pi=False, u
return
np
.
array
(
rboxes
),
np
.
array
(
csl_labels
)
return
np
.
array
(
rboxes
),
np
.
array
(
csl_labels
)
return
np
.
array
(
rboxes
)
return
np
.
array
(
rboxes
)
def
poly2rbox_new
(
polys
,
num_cls_thata
=
5
,
angle_w
=
36
,
radius
=
6.0
,
use_pi
=
False
,
use_gaussian
=
False
):
"""
Trans poly format to rbox format.
Args:
polys (array): (num_gts, [x1 y1 x2 y2 x3 y3 x4 y4])
num_cls_thata (int): [1], theta class num
radius (float32): [1], window radius for Circular Smooth Label
use_pi (bool): True θ∈[-pi/2, pi/2) , False θ∈[0, 180)
Returns:
use_gaussian True:
rboxes (array):
csl_labels (array): (num_gts, num_cls_thata)
elif
rboxes (array): (num_gts, [cx cy l s θ])
"""
assert
polys
.
shape
[
-
1
]
==
8
if
use_gaussian
:
csl_labels
=
[]
rboxes
=
[]
for
poly
in
polys
:
poly
=
np
.
float32
(
poly
.
reshape
(
4
,
2
))
(
x
,
y
),
(
w
,
h
),
angle
=
cv2
.
minAreaRect
(
poly
)
# θ ∈ [0, 90] # opencv>=4.5.1 若是< -90到0
angle
=
-
angle
# θ ∈ [-90, 0] # 故 rbbox2poly 中 角度再 负 了一次
# # 两者的闭集位置进行了调换,所以在边界角度处的转换和非边界角度处的转换越有所不同。
# if angle >= 90:
# angle = angle - 180
# else:
# w, h = h, w
# angle = angle -90
theta
=
angle
/
180
*
pi
# 转为pi制
# trans opencv format to longedge format θ ∈ [-pi/2, pi/2]
if
w
!=
max
(
w
,
h
):
w
,
h
=
h
,
w
theta
+=
pi
/
2
theta
=
regular_theta
(
theta
)
# limit theta ∈ [-pi/2, pi/2)
# while not pi / 2 > theta >= -pi / 2:
# if theta >= pi / 2:
# theta -= pi
# else:
# theta += pi
angle
=
(
theta
*
180
/
pi
)
+
90
# θ ∈ [0, 180)
if
not
use_pi
:
# 采用angle弧度制 θ ∈ [0, 180)
rboxes
.
append
([
x
,
y
,
w
,
h
,
angle
])
else
:
# 采用pi制
rboxes
.
append
([
x
,
y
,
w
,
h
,
theta
])
if
use_gaussian
:
csl_label
=
gaussian_label_cpu
(
label
=
angle
,
num_class
=
num_cls_thata
,
u
=
0
,
sig
=
radius
)
csl_labels
.
append
(
csl_label
)
if
use_gaussian
:
return
np
.
array
(
rboxes
),
np
.
array
(
csl_labels
)
return
np
.
array
(
rboxes
)
def
rbox2poly
(
obboxes
):
def
rbox2poly
(
obboxes
):
"""
"""
Trans rbox format to poly format.
Trans rbox format to poly format.
...
@@ -259,8 +180,3 @@ def poly_filter(polys, h, w):
...
@@ -259,8 +180,3 @@ def poly_filter(polys, h, w):
x_ctr
,
y_ctr
=
(
x_max
+
x_min
)
/
2.0
,
(
y_max
+
y_min
)
/
2.0
# (num)
x_ctr
,
y_ctr
=
(
x_max
+
x_min
)
/
2.0
,
(
y_max
+
y_min
)
/
2.0
# (num)
keep_masks
=
(
x_ctr
>
0
)
&
(
x_ctr
<
w
)
&
(
y_ctr
>
0
)
&
(
y_ctr
<
h
)
keep_masks
=
(
x_ctr
>
0
)
&
(
x_ctr
<
w
)
&
(
y_ctr
>
0
)
&
(
y_ctr
<
h
)
return
keep_masks
return
keep_masks
\ No newline at end of file
if
__name__
==
"__main__"
:
#print(np.pi)
poly
=
np
.
array
([[
204.
,
197.
,
273.
,
154.
,
290.
,
170.
,
217.
,
218.
]])
print
(
poly2rbox_new
(
poly
,
use_pi
=
True
))
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录