Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Tc.小浩
dpcas
提交
668d6c74
dpcas
项目概览
Tc.小浩
/
dpcas
与 Fork 源项目一致
Fork自
DataBall / dpcas
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
dpcas
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
668d6c74
编写于
4月 27, 2021
作者:
DataBall
🚴🏻
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add face au
上级
d551c7bb
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
706 addition
and
6 deletion
+706
-6
applications/face_bioassay_local_app.py
applications/face_bioassay_local_app.py
+5
-1
components/face_au/face_au_c.py
components/face_au/face_au_c.py
+68
-0
components/face_au/models/mobilenetv2.py
components/face_au/models/mobilenetv2.py
+143
-0
components/face_au/models/resnet.py
components/face_au/models/resnet.py
+262
-0
components/face_au/utils/common_utils.py
components/face_au/utils/common_utils.py
+132
-0
components/face_au/utils/model_utils.py
components/face_au/utils/model_utils.py
+61
-0
lib/face_bioassay_lib/cores/face_fuction.py
lib/face_bioassay_lib/cores/face_fuction.py
+35
-5
未找到文件。
applications/face_bioassay_local_app.py
浏览文件 @
668d6c74
...
...
@@ -28,6 +28,7 @@ import shutil
from
face_detect.yolo_v3_face
import
yolo_v3_face_model
from
face_multi_task.face_multi_task_component
import
FaceMuitiTask_Model
from
face_euler_angle.face_euler_angle_component
import
FaceAngle_Model
from
face_au.face_au_c
import
FaceAu_Model
# 加载工具库
import
sys
sys
.
path
.
append
(
"./lib/face_bioassay_lib/"
)
...
...
@@ -47,6 +48,8 @@ def main_face_bioassay(video_path,cfg_file):
face_euler_model
=
FaceAngle_Model
(
model_path
=
config
[
"face_euler_model_path"
])
face_au_model
=
FaceAu_Model
(
model_path
=
config
[
"face_au_model_path"
])
cap
=
cv2
.
VideoCapture
(
video_path
)
frame_idx
=
0
while
cap
.
isOpened
():
...
...
@@ -58,9 +61,10 @@ def main_face_bioassay(video_path,cfg_file):
faces_bboxes
=
face_detect_model
.
predict
(
img
,
vis
=
False
)
# 检测手,获取手的边界框
faces_message
=
get_faces_batch_attribute
(
face_multitask_model
,
face_euler_model
,
faces_bboxes
,
img
,
use_cuda
=
True
,
vis
=
True
)
face_multitask_model
,
face_euler_model
,
face
_au_model
,
face
s_bboxes
,
img
,
use_cuda
=
True
,
vis
=
True
)
if
faces_message
is
not
None
:
print
(
"faces_message : {}
\n
"
.
format
(
faces_message
))
pass
cv2
.
namedWindow
(
"DriverFatigueMonitor"
,
0
)
cv2
.
imshow
(
"DriverFatigueMonitor"
,
img
)
...
...
components/face_au/face_au_c.py
0 → 100644
浏览文件 @
668d6c74
#-*-coding:utf-8-*-
# date:2021-03-09
# Author: Eric.Lee
# function: handpose_x 21 keypoints 2D
import
os
import
torch
import
cv2
import
numpy
as
np
import
json
import
torch
import
torch.nn
as
nn
import
time
import
math
from
datetime
import
datetime
from
face_au.models.resnet
import
resnet18
,
resnet34
,
resnet50
,
resnet101
from
face_au.models.mobilenetv2
import
MobileNetV2
#
class
FaceAu_Model
(
object
):
def
__init__
(
self
,
model_path
=
'./components/face_au/weights/face_au-resnet50-size256-20210427.pth'
,
img_size
=
256
,
num_classes
=
24
,
model_arch
=
"resnet_50"
,
):
# print("face au loading : ",model_path)
self
.
use_cuda
=
torch
.
cuda
.
is_available
()
self
.
device
=
torch
.
device
(
"cuda:0"
if
self
.
use_cuda
else
"cpu"
)
# 可选的设备类型及序号
self
.
img_size
=
img_size
#-----------------------------------------------------------------------
if
model_arch
==
'resnet_50'
:
model_
=
resnet50
(
num_classes
=
num_classes
,
img_size
=
self
.
img_size
)
elif
model_arch
==
'resnet_18'
:
model_
=
resnet18
(
num_classes
=
num_classes
,
img_size
=
self
.
img_size
)
elif
model_arch
==
'resnet_34'
:
model_
=
resnet34
(
num_classes
=
num_classes
,
img_size
=
self
.
img_size
)
elif
model_arch
==
'resnet_101'
:
model_
=
resnet101
(
num_classes
=
num_classes
,
img_size
=
self
.
img_size
)
#-----------------------------------------------------------------------
model_
=
model_
.
to
(
self
.
device
)
# 加载测试模型
if
os
.
access
(
model_path
,
os
.
F_OK
):
# checkpoint
chkpt
=
torch
.
load
(
model_path
,
map_location
=
self
.
device
)
model_
.
load_state_dict
(
chkpt
)
print
(
'face au model loading : {}'
.
format
(
model_path
))
model_
.
eval
()
# 设置为前向推断模式
self
.
model_au
=
model_
def
predict
(
self
,
img
,
vis
=
False
):
with
torch
.
no_grad
():
# img_ = img_ - [123.67, 116.28, 103.53]
img_
=
torch
.
from_numpy
(
img
)
# img_ = img_.unsqueeze_(0)
if
self
.
use_cuda
:
img_
=
img_
.
cuda
()
# (bs, 3, h, w)
output_
=
self
.
model_au
(
img_
.
float
())
# print(pre_.size())
output_
=
output_
.
cpu
().
detach
().
numpy
()
return
output_
components/face_au/models/mobilenetv2.py
0 → 100644
浏览文件 @
668d6c74
import
torch
import
torch.nn
as
nn
import
math
# A PyTorch implementation of MobileNet V2 architecture and pretrained model.
# from https://github.com/tonylins/pytorch-mobilenet-v2
def
conv_bn
(
inp
,
oup
,
stride
):
return
nn
.
Sequential
(
nn
.
Conv2d
(
inp
,
oup
,
3
,
stride
,
1
,
bias
=
False
),
nn
.
BatchNorm2d
(
oup
),
nn
.
ReLU6
(
inplace
=
True
)
)
def
conv_1x1_bn
(
inp
,
oup
):
return
nn
.
Sequential
(
nn
.
Conv2d
(
inp
,
oup
,
1
,
1
,
0
,
bias
=
False
),
nn
.
BatchNorm2d
(
oup
),
nn
.
ReLU6
(
inplace
=
True
)
)
class
InvertedResidual
(
nn
.
Module
):
def
__init__
(
self
,
inp
,
oup
,
stride
,
expand_ratio
):
super
(
InvertedResidual
,
self
).
__init__
()
self
.
stride
=
stride
assert
stride
in
[
1
,
2
]
hidden_dim
=
round
(
inp
*
expand_ratio
)
self
.
use_res_connect
=
self
.
stride
==
1
and
inp
==
oup
if
expand_ratio
==
1
:
self
.
conv
=
nn
.
Sequential
(
# dw
nn
.
Conv2d
(
hidden_dim
,
hidden_dim
,
3
,
stride
,
1
,
groups
=
hidden_dim
,
bias
=
False
),
nn
.
BatchNorm2d
(
hidden_dim
),
nn
.
ReLU6
(
inplace
=
True
),
# pw-linear
nn
.
Conv2d
(
hidden_dim
,
oup
,
1
,
1
,
0
,
bias
=
False
),
nn
.
BatchNorm2d
(
oup
),
)
else
:
self
.
conv
=
nn
.
Sequential
(
# pw
nn
.
Conv2d
(
inp
,
hidden_dim
,
1
,
1
,
0
,
bias
=
False
),
nn
.
BatchNorm2d
(
hidden_dim
),
nn
.
ReLU6
(
inplace
=
True
),
# dw
nn
.
Conv2d
(
hidden_dim
,
hidden_dim
,
3
,
stride
,
1
,
groups
=
hidden_dim
,
bias
=
False
),
nn
.
BatchNorm2d
(
hidden_dim
),
nn
.
ReLU6
(
inplace
=
True
),
# pw-linear
nn
.
Conv2d
(
hidden_dim
,
oup
,
1
,
1
,
0
,
bias
=
False
),
nn
.
BatchNorm2d
(
oup
),
)
def
forward
(
self
,
x
):
if
self
.
use_res_connect
:
return
x
+
self
.
conv
(
x
)
else
:
return
self
.
conv
(
x
)
class
MobileNetV2
(
nn
.
Module
):
def
__init__
(
self
,
n_class
=
1000
,
input_size
=
224
,
dropout_factor
=
0.5
,
width_mult
=
1.
):
super
(
MobileNetV2
,
self
).
__init__
()
block
=
InvertedResidual
input_channel
=
32
last_channel
=
1280
self
.
dropout_factor
=
dropout_factor
self
.
dropout
=
nn
.
Dropout
(
self
.
dropout_factor
)
interverted_residual_setting
=
[
# t, c, n, s
[
1
,
16
,
1
,
1
],
[
6
,
24
,
2
,
2
],
[
6
,
32
,
3
,
2
],
[
6
,
64
,
4
,
2
],
[
6
,
96
,
3
,
1
],
[
6
,
160
,
3
,
2
],
[
6
,
320
,
1
,
1
],
]
# building first layer
assert
input_size
%
32
==
0
input_channel
=
int
(
input_channel
*
width_mult
)
self
.
last_channel
=
int
(
last_channel
*
width_mult
)
if
width_mult
>
1.0
else
last_channel
self
.
features
=
[
conv_bn
(
3
,
input_channel
,
2
)]
# building inverted residual blocks
for
t
,
c
,
n
,
s
in
interverted_residual_setting
:
output_channel
=
int
(
c
*
width_mult
)
for
i
in
range
(
n
):
if
i
==
0
:
self
.
features
.
append
(
block
(
input_channel
,
output_channel
,
s
,
expand_ratio
=
t
))
else
:
self
.
features
.
append
(
block
(
input_channel
,
output_channel
,
1
,
expand_ratio
=
t
))
input_channel
=
output_channel
# building last several layers
self
.
features
.
append
(
conv_1x1_bn
(
input_channel
,
self
.
last_channel
))
# make it nn.Sequential
self
.
features
=
nn
.
Sequential
(
*
self
.
features
)
# building classifier
self
.
classifier
=
nn
.
Sequential
(
# nn.Dropout(0.2),
nn
.
Linear
(
self
.
last_channel
,
n_class
),
)
self
.
_initialize_weights
()
def
forward
(
self
,
x
):
x
=
self
.
features
(
x
)
# print("1 x.size()", x.size()) # bs,1280,7,7
x
=
x
.
mean
(
3
).
mean
(
2
)
# print("2 x.size()", x.size()) # bs,1280
x
=
self
.
dropout
(
x
)
x
=
self
.
classifier
(
x
)
# print("3 x.size()", x.size()) # bs,num_classes
return
x
def
_initialize_weights
(
self
):
for
m
in
self
.
modules
():
if
isinstance
(
m
,
nn
.
Conv2d
):
n
=
m
.
kernel_size
[
0
]
*
m
.
kernel_size
[
1
]
*
m
.
out_channels
m
.
weight
.
data
.
normal_
(
0
,
math
.
sqrt
(
2.
/
n
))
if
m
.
bias
is
not
None
:
m
.
bias
.
data
.
zero_
()
elif
isinstance
(
m
,
nn
.
BatchNorm2d
):
m
.
weight
.
data
.
fill_
(
1
)
m
.
bias
.
data
.
zero_
()
elif
isinstance
(
m
,
nn
.
Linear
):
n
=
m
.
weight
.
size
(
1
)
m
.
weight
.
data
.
normal_
(
0
,
0.01
)
m
.
bias
.
data
.
zero_
()
if
__name__
==
"__main__"
:
img
=
torch
.
rand
((
9
,
3
,
160
,
160
))
net
=
MobileNetV2
(
n_class
=
120
)
print
(
net
)
print
(
"***"
*
50
)
pred
=
net
(
img
)
print
(
pred
.
size
())
components/face_au/models/resnet.py
0 → 100644
浏览文件 @
668d6c74
import
torch
import
torch.nn
as
nn
import
math
import
torch.utils.model_zoo
as
model_zoo
__all__
=
[
'ResNet'
,
'resnet18'
,
'resnet34'
,
'resnet50'
,
'resnet101'
,
'resnet152'
]
model_urls
=
{
'resnet18'
:
'https://download.pytorch.org/models/resnet18-5c106cde.pth'
,
'resnet34'
:
'https://download.pytorch.org/models/resnet34-333f7ec4.pth'
,
'resnet50'
:
'https://download.pytorch.org/models/resnet50-19c8e357.pth'
,
'resnet101'
:
'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth'
,
'resnet152'
:
'https://download.pytorch.org/models/resnet152-b121ed2d.pth'
,
}
def
conv3x3
(
in_planes
,
out_planes
,
stride
=
1
):
"""3x3 convolution with padding"""
return
nn
.
Conv2d
(
in_planes
,
out_planes
,
kernel_size
=
3
,
stride
=
stride
,
padding
=
1
,
bias
=
False
)
class
BasicBlock
(
nn
.
Module
):
expansion
=
1
def
__init__
(
self
,
inplanes
,
planes
,
stride
=
1
,
downsample
=
None
):
super
(
BasicBlock
,
self
).
__init__
()
self
.
conv1
=
conv3x3
(
inplanes
,
planes
,
stride
)
self
.
bn1
=
nn
.
BatchNorm2d
(
planes
)
self
.
relu
=
nn
.
ReLU
(
inplace
=
True
)
self
.
conv2
=
conv3x3
(
planes
,
planes
)
self
.
bn2
=
nn
.
BatchNorm2d
(
planes
)
self
.
downsample
=
downsample
self
.
stride
=
stride
def
forward
(
self
,
x
):
residual
=
x
out
=
self
.
conv1
(
x
)
out
=
self
.
bn1
(
out
)
out
=
self
.
relu
(
out
)
out
=
self
.
conv2
(
out
)
out
=
self
.
bn2
(
out
)
if
self
.
downsample
is
not
None
:
residual
=
self
.
downsample
(
x
)
out
+=
residual
out
=
self
.
relu
(
out
)
return
out
class
Bottleneck
(
nn
.
Module
):
expansion
=
4
def
__init__
(
self
,
inplanes
,
planes
,
stride
=
1
,
downsample
=
None
):
super
(
Bottleneck
,
self
).
__init__
()
self
.
conv1
=
nn
.
Conv2d
(
inplanes
,
planes
,
kernel_size
=
1
,
bias
=
False
)
self
.
bn1
=
nn
.
BatchNorm2d
(
planes
)
self
.
conv2
=
nn
.
Conv2d
(
planes
,
planes
,
kernel_size
=
3
,
stride
=
stride
,
padding
=
1
,
bias
=
False
)
self
.
bn2
=
nn
.
BatchNorm2d
(
planes
)
self
.
conv3
=
nn
.
Conv2d
(
planes
,
planes
*
4
,
kernel_size
=
1
,
bias
=
False
)
self
.
bn3
=
nn
.
BatchNorm2d
(
planes
*
4
)
self
.
relu
=
nn
.
ReLU
(
inplace
=
True
)
self
.
downsample
=
downsample
self
.
stride
=
stride
def
forward
(
self
,
x
):
residual
=
x
out
=
self
.
conv1
(
x
)
out
=
self
.
bn1
(
out
)
out
=
self
.
relu
(
out
)
out
=
self
.
conv2
(
out
)
out
=
self
.
bn2
(
out
)
out
=
self
.
relu
(
out
)
out
=
self
.
conv3
(
out
)
out
=
self
.
bn3
(
out
)
if
self
.
downsample
is
not
None
:
residual
=
self
.
downsample
(
x
)
out
+=
residual
out
=
self
.
relu
(
out
)
return
out
class
ResNet
(
nn
.
Module
):
def
__init__
(
self
,
block
,
layers
,
num_classes
=
1000
,
img_size
=
224
,
dropout_factor
=
1.
):
self
.
inplanes
=
64
self
.
dropout_factor
=
dropout_factor
super
(
ResNet
,
self
).
__init__
()
self
.
conv1
=
nn
.
Conv2d
(
3
,
64
,
kernel_size
=
7
,
stride
=
2
,
padding
=
3
,
bias
=
False
)
self
.
bn1
=
nn
.
BatchNorm2d
(
64
)
self
.
relu
=
nn
.
ReLU
(
inplace
=
True
)
# see this issue: https://github.com/xxradon/PytorchToCaffe/issues/16
# self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
self
.
maxpool
=
nn
.
MaxPool2d
(
kernel_size
=
3
,
stride
=
2
,
ceil_mode
=
True
)
self
.
layer1
=
self
.
_make_layer
(
block
,
64
,
layers
[
0
])
self
.
layer2
=
self
.
_make_layer
(
block
,
128
,
layers
[
1
],
stride
=
2
)
self
.
layer3
=
self
.
_make_layer
(
block
,
256
,
layers
[
2
],
stride
=
2
)
self
.
layer4
=
self
.
_make_layer
(
block
,
512
,
layers
[
3
],
stride
=
2
)
assert
img_size
%
32
==
0
pool_kernel
=
int
(
img_size
/
32
)
self
.
avgpool
=
nn
.
AvgPool2d
(
pool_kernel
,
stride
=
1
,
ceil_mode
=
True
)
self
.
dropout
=
nn
.
Dropout
(
self
.
dropout_factor
)
self
.
fc
=
nn
.
Linear
(
512
*
block
.
expansion
,
num_classes
)
for
m
in
self
.
modules
():
if
isinstance
(
m
,
nn
.
Conv2d
):
n
=
m
.
kernel_size
[
0
]
*
m
.
kernel_size
[
1
]
*
m
.
out_channels
m
.
weight
.
data
.
normal_
(
0
,
math
.
sqrt
(
2.
/
n
))
elif
isinstance
(
m
,
nn
.
BatchNorm2d
):
m
.
weight
.
data
.
fill_
(
1
)
m
.
bias
.
data
.
zero_
()
def
_make_layer
(
self
,
block
,
planes
,
blocks
,
stride
=
1
):
downsample
=
None
if
stride
!=
1
or
self
.
inplanes
!=
planes
*
block
.
expansion
:
downsample
=
nn
.
Sequential
(
nn
.
Conv2d
(
self
.
inplanes
,
planes
*
block
.
expansion
,
kernel_size
=
1
,
stride
=
stride
,
bias
=
False
),
nn
.
BatchNorm2d
(
planes
*
block
.
expansion
),
)
layers
=
[]
layers
.
append
(
block
(
self
.
inplanes
,
planes
,
stride
,
downsample
))
self
.
inplanes
=
planes
*
block
.
expansion
for
i
in
range
(
1
,
blocks
):
layers
.
append
(
block
(
self
.
inplanes
,
planes
))
return
nn
.
Sequential
(
*
layers
)
def
forward
(
self
,
x
):
x
=
self
.
conv1
(
x
)
x
=
self
.
bn1
(
x
)
x
=
self
.
relu
(
x
)
x
=
self
.
maxpool
(
x
)
x
=
self
.
layer1
(
x
)
x
=
self
.
layer2
(
x
)
x
=
self
.
layer3
(
x
)
x
=
self
.
layer4
(
x
)
x
=
self
.
avgpool
(
x
)
x
=
x
.
view
(
x
.
size
(
0
),
-
1
)
x
=
self
.
dropout
(
x
)
x
=
self
.
fc
(
x
)
return
x
def
load_model
(
model
,
pretrained_state_dict
):
model_dict
=
model
.
state_dict
()
pretrained_dict
=
{
k
:
v
for
k
,
v
in
pretrained_state_dict
.
items
()
if
k
in
model_dict
and
model_dict
[
k
].
size
()
==
pretrained_state_dict
[
k
].
size
()}
model
.
load_state_dict
(
pretrained_dict
,
strict
=
False
)
if
len
(
pretrained_dict
)
==
0
:
print
(
"[INFO] No params were loaded ..."
)
else
:
for
k
,
v
in
pretrained_state_dict
.
items
():
if
k
in
pretrained_dict
:
print
(
"==>> Load {} {}"
.
format
(
k
,
v
.
size
()))
else
:
print
(
"[INFO] Skip {} {}"
.
format
(
k
,
v
.
size
()))
return
model
def
resnet18
(
pretrained
=
False
,
**
kwargs
):
"""Constructs a ResNet-18 model.
Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
"""
model
=
ResNet
(
BasicBlock
,
[
2
,
2
,
2
,
2
],
**
kwargs
)
if
pretrained
:
# model.load_state_dict(model_zoo.load_url(model_urls['resnet18']))
print
(
"Load pretrained model from {}"
.
format
(
model_urls
[
'resnet18'
]))
pretrained_state_dict
=
model_zoo
.
load_url
(
model_urls
[
'resnet18'
])
model
=
load_model
(
model
,
pretrained_state_dict
)
return
model
def
resnet34
(
pretrained
=
False
,
**
kwargs
):
"""Constructs a ResNet-34 model.
Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
"""
model
=
ResNet
(
BasicBlock
,
[
3
,
4
,
6
,
3
],
**
kwargs
)
if
pretrained
:
# model.load_state_dict(model_zoo.load_url(model_urls['resnet34']))
print
(
"Load pretrained model from {}"
.
format
(
model_urls
[
'resnet34'
]))
pretrained_state_dict
=
model_zoo
.
load_url
(
model_urls
[
'resnet34'
])
model
=
load_model
(
model
,
pretrained_state_dict
)
return
model
def
resnet50
(
pretrained
=
False
,
**
kwargs
):
"""Constructs a ResNet-50 model.
Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
"""
model
=
ResNet
(
Bottleneck
,
[
3
,
4
,
6
,
3
],
**
kwargs
)
if
pretrained
:
# model.load_state_dict(model_zoo.load_url(model_urls['resnet50']))
print
(
"Load pretrained model from {}"
.
format
(
model_urls
[
'resnet50'
]))
pretrained_state_dict
=
model_zoo
.
load_url
(
model_urls
[
'resnet50'
])
model
=
load_model
(
model
,
pretrained_state_dict
)
return
model
def
resnet101
(
pretrained
=
False
,
**
kwargs
):
"""Constructs a ResNet-101 model.
Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
"""
model
=
ResNet
(
Bottleneck
,
[
3
,
4
,
23
,
3
],
**
kwargs
)
if
pretrained
:
# model.load_state_dict(model_zoo.load_url(model_urls['resnet101']))
print
(
"Load pretrained model from {}"
.
format
(
model_urls
[
'resnet101'
]))
pretrained_state_dict
=
model_zoo
.
load_url
(
model_urls
[
'resnet101'
])
model
=
load_model
(
model
,
pretrained_state_dict
)
return
model
def
resnet152
(
pretrained
=
False
,
**
kwargs
):
"""Constructs a ResNet-152 model.
Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
"""
model
=
ResNet
(
Bottleneck
,
[
3
,
8
,
36
,
3
],
**
kwargs
)
if
pretrained
:
# model.load_state_dict(model_zoo.load_url(model_urls['resnet152']))
print
(
"Load pretrained model from {}"
.
format
(
model_urls
[
'resnet152'
]))
pretrained_state_dict
=
model_zoo
.
load_url
(
model_urls
[
'resnet152'
])
model
=
load_model
(
model
,
pretrained_state_dict
)
return
model
if
__name__
==
"__main__"
:
input
=
torch
.
randn
([
32
,
3
,
256
,
256
])
model
=
resnet34
(
False
,
num_classes
=
2
,
img_size
=
256
)
output
=
model
(
input
)
print
(
output
.
size
())
components/face_au/utils/common_utils.py
0 → 100644
浏览文件 @
668d6c74
#-*-coding:utf-8-*-
# date:2020-04-11
# Author: Eric.Lee
# function: common utils
import
os
import
shutil
import
cv2
import
numpy
as
np
import
json
def
mkdir_
(
path
,
flag_rm
=
False
):
if
os
.
path
.
exists
(
path
):
if
flag_rm
==
True
:
shutil
.
rmtree
(
path
)
os
.
mkdir
(
path
)
print
(
'remove {} done ~ '
.
format
(
path
))
else
:
os
.
mkdir
(
path
)
def
plot_box
(
bbox
,
img
,
color
=
None
,
label
=
None
,
line_thickness
=
None
):
tl
=
line_thickness
or
round
(
0.002
*
max
(
img
.
shape
[
0
:
2
]))
+
1
color
=
color
or
[
random
.
randint
(
0
,
255
)
for
_
in
range
(
3
)]
c1
,
c2
=
(
int
(
bbox
[
0
]),
int
(
bbox
[
1
])),
(
int
(
bbox
[
2
]),
int
(
bbox
[
3
]))
cv2
.
rectangle
(
img
,
c1
,
c2
,
color
,
thickness
=
tl
)
# 目标的bbox
if
label
:
tf
=
max
(
tl
-
2
,
1
)
t_size
=
cv2
.
getTextSize
(
label
,
0
,
fontScale
=
tl
/
3
,
thickness
=
tf
)[
0
]
# label size
c2
=
c1
[
0
]
+
t_size
[
0
],
c1
[
1
]
-
t_size
[
1
]
-
3
# 字体的bbox
cv2
.
rectangle
(
img
,
c1
,
c2
,
color
,
-
1
)
# label 矩形填充
# 文本绘制
cv2
.
putText
(
img
,
label
,
(
c1
[
0
],
c1
[
1
]
-
2
),
0
,
tl
/
4
,
[
225
,
255
,
255
],
thickness
=
tf
,
lineType
=
cv2
.
LINE_AA
)
class
JSON_Encoder
(
json
.
JSONEncoder
):
def
default
(
self
,
obj
):
if
isinstance
(
obj
,
np
.
integer
):
return
int
(
obj
)
elif
isinstance
(
obj
,
np
.
floating
):
return
float
(
obj
)
elif
isinstance
(
obj
,
np
.
ndarray
):
return
obj
.
tolist
()
else
:
return
super
(
JSON_Encoder
,
self
).
default
(
obj
)
def
draw_landmarks
(
img
,
output
,
draw_circle
):
img_width
=
img
.
shape
[
1
]
img_height
=
img
.
shape
[
0
]
dict_landmarks
=
{}
for
i
in
range
(
int
(
output
.
shape
[
0
]
/
2
)):
x
=
output
[
i
*
2
+
0
]
*
float
(
img_width
)
y
=
output
[
i
*
2
+
1
]
*
float
(
img_height
)
if
41
>=
i
>=
33
:
if
'left_eyebrow'
not
in
dict_landmarks
.
keys
():
dict_landmarks
[
'left_eyebrow'
]
=
[]
dict_landmarks
[
'left_eyebrow'
].
append
([
int
(
x
),
int
(
y
),(
0
,
255
,
0
)])
if
draw_circle
:
cv2
.
circle
(
img
,
(
int
(
x
),
int
(
y
)),
2
,
(
0
,
255
,
0
),
-
1
)
elif
50
>=
i
>=
42
:
if
'right_eyebrow'
not
in
dict_landmarks
.
keys
():
dict_landmarks
[
'right_eyebrow'
]
=
[]
dict_landmarks
[
'right_eyebrow'
].
append
([
int
(
x
),
int
(
y
),(
0
,
255
,
0
)])
if
draw_circle
:
cv2
.
circle
(
img
,
(
int
(
x
),
int
(
y
)),
2
,
(
0
,
255
,
0
),
-
1
)
elif
67
>=
i
>=
60
:
if
'left_eye'
not
in
dict_landmarks
.
keys
():
dict_landmarks
[
'left_eye'
]
=
[]
dict_landmarks
[
'left_eye'
].
append
([
int
(
x
),
int
(
y
),(
255
,
0
,
255
)])
if
draw_circle
:
cv2
.
circle
(
img
,
(
int
(
x
),
int
(
y
)),
2
,
(
255
,
0
,
255
),
-
1
)
elif
75
>=
i
>=
68
:
if
'right_eye'
not
in
dict_landmarks
.
keys
():
dict_landmarks
[
'right_eye'
]
=
[]
dict_landmarks
[
'right_eye'
].
append
([
int
(
x
),
int
(
y
),(
255
,
0
,
255
)])
if
draw_circle
:
cv2
.
circle
(
img
,
(
int
(
x
),
int
(
y
)),
2
,
(
255
,
0
,
255
),
-
1
)
elif
97
>=
i
>=
96
:
cv2
.
circle
(
img
,
(
int
(
x
),
int
(
y
)),
2
,
(
0
,
0
,
255
),
-
1
)
elif
54
>=
i
>=
51
:
if
'bridge_nose'
not
in
dict_landmarks
.
keys
():
dict_landmarks
[
'bridge_nose'
]
=
[]
dict_landmarks
[
'bridge_nose'
].
append
([
int
(
x
),
int
(
y
),(
0
,
170
,
255
)])
if
draw_circle
:
cv2
.
circle
(
img
,
(
int
(
x
),
int
(
y
)),
2
,
(
0
,
170
,
255
),
-
1
)
elif
32
>=
i
>=
0
:
if
'basin'
not
in
dict_landmarks
.
keys
():
dict_landmarks
[
'basin'
]
=
[]
dict_landmarks
[
'basin'
].
append
([
int
(
x
),
int
(
y
),(
255
,
30
,
30
)])
if
draw_circle
:
cv2
.
circle
(
img
,
(
int
(
x
),
int
(
y
)),
2
,
(
255
,
30
,
30
),
-
1
)
elif
59
>=
i
>=
55
:
if
'wing_nose'
not
in
dict_landmarks
.
keys
():
dict_landmarks
[
'wing_nose'
]
=
[]
dict_landmarks
[
'wing_nose'
].
append
([
int
(
x
),
int
(
y
),(
0
,
255
,
255
)])
if
draw_circle
:
cv2
.
circle
(
img
,
(
int
(
x
),
int
(
y
)),
2
,
(
0
,
255
,
255
),
-
1
)
elif
87
>=
i
>=
76
:
if
'out_lip'
not
in
dict_landmarks
.
keys
():
dict_landmarks
[
'out_lip'
]
=
[]
dict_landmarks
[
'out_lip'
].
append
([
int
(
x
),
int
(
y
),(
255
,
255
,
0
)])
if
draw_circle
:
cv2
.
circle
(
img
,
(
int
(
x
),
int
(
y
)),
2
,
(
255
,
255
,
0
),
-
1
)
elif
95
>=
i
>=
88
:
if
'in_lip'
not
in
dict_landmarks
.
keys
():
dict_landmarks
[
'in_lip'
]
=
[]
dict_landmarks
[
'in_lip'
].
append
([
int
(
x
),
int
(
y
),(
50
,
220
,
255
)])
if
draw_circle
:
cv2
.
circle
(
img
,
(
int
(
x
),
int
(
y
)),
2
,
(
50
,
220
,
255
),
-
1
)
else
:
if
draw_circle
:
cv2
.
circle
(
img
,
(
int
(
x
),
int
(
y
)),
2
,
(
255
,
0
,
255
),
-
1
)
return
dict_landmarks
def
draw_contour
(
image
,
dict
):
for
key
in
dict
.
keys
():
# print(key)
_
,
_
,
color
=
dict
[
key
][
0
]
if
'basin'
==
key
or
'wing_nose'
==
key
:
pts
=
np
.
array
([[
dict
[
key
][
i
][
0
],
dict
[
key
][
i
][
1
]]
for
i
in
range
(
len
(
dict
[
key
]))],
np
.
int32
)
# print(pts)
cv2
.
polylines
(
image
,[
pts
],
False
,
color
)
else
:
points_array
=
np
.
zeros
((
1
,
len
(
dict
[
key
]),
2
),
dtype
=
np
.
int32
)
for
i
in
range
(
len
(
dict
[
key
])):
x
,
y
,
_
=
dict
[
key
][
i
]
points_array
[
0
,
i
,
0
]
=
x
points_array
[
0
,
i
,
1
]
=
y
# cv2.fillPoly(image, points_array, color)
cv2
.
drawContours
(
image
,
points_array
,
-
1
,
color
,
thickness
=
1
)
components/face_au/utils/model_utils.py
0 → 100644
浏览文件 @
668d6c74
#-*-coding:utf-8-*-
# date:2020-04-11
# Author: Eric.Lee
# function: model utils
import
os
import
numpy
as
np
import
torch
import
torch.backends.cudnn
as
cudnn
import
random
def
get_acc
(
output
,
label
):
total
=
output
.
shape
[
0
]
_
,
pred_label
=
output
.
max
(
1
)
num_correct
=
(
pred_label
==
label
).
sum
().
item
()
return
num_correct
/
float
(
total
)
def
set_learning_rate
(
optimizer
,
lr
):
for
param_group
in
optimizer
.
param_groups
:
param_group
[
'lr'
]
=
lr
def
set_seed
(
seed
=
666
):
np
.
random
.
seed
(
seed
)
random
.
seed
(
seed
)
torch
.
manual_seed
(
seed
)
if
torch
.
cuda
.
is_available
():
torch
.
cuda
.
manual_seed
(
seed
)
torch
.
cuda
.
manual_seed_all
(
seed
)
cudnn
.
deterministic
=
True
def
split_trainval_datasets
(
ops
):
print
(
' --------------->>> split_trainval_datasets '
)
train_split_datasets
=
[]
train_split_datasets_label
=
[]
val_split_datasets
=
[]
val_split_datasets_label
=
[]
for
idx
,
doc
in
enumerate
(
sorted
(
os
.
listdir
(
ops
.
train_path
),
key
=
lambda
x
:
int
(
x
.
split
(
'.'
)[
0
]),
reverse
=
False
)):
# print(' %s label is %s \n'%(doc,idx))
data_list
=
os
.
listdir
(
ops
.
train_path
+
doc
)
random
.
shuffle
(
data_list
)
cal_split_num
=
int
(
len
(
data_list
)
*
ops
.
val_factor
)
for
i
,
file
in
enumerate
(
data_list
):
if
'.jpg'
in
file
:
if
i
<
cal_split_num
:
val_split_datasets
.
append
(
ops
.
train_path
+
doc
+
'/'
+
file
)
val_split_datasets_label
.
append
(
idx
)
else
:
train_split_datasets
.
append
(
ops
.
train_path
+
doc
+
'/'
+
file
)
train_split_datasets_label
.
append
(
idx
)
print
(
ops
.
train_path
+
doc
+
'/'
+
file
,
idx
)
print
(
'
\n
'
)
print
(
'train_split_datasets len {}'
.
format
(
len
(
train_split_datasets
)))
print
(
'val_split_datasets len {}'
.
format
(
len
(
val_split_datasets
)))
return
train_split_datasets
,
train_split_datasets_label
,
val_split_datasets
,
val_split_datasets_label
lib/face_bioassay_lib/cores/face_fuction.py
浏览文件 @
668d6c74
...
...
@@ -163,7 +163,6 @@ def draw_contour(image,dict,vis = False):
if
vis
:
cv2
.
drawContours
(
image
,
points_array
,
-
1
,
color
,
thickness
=
2
)
def
plot_box
(
x
,
img
,
color
=
None
,
label
=
None
,
line_thickness
=
None
):
# Plots one bounding box on image img
tl
=
line_thickness
or
round
(
0.002
*
max
(
img
.
shape
[
0
:
2
]))
+
1
# line thickness
...
...
@@ -259,7 +258,7 @@ def refine_face_bbox(bbox,img_shape):
return
(
x1
,
y1
,
x2
,
y2
)
def
get_faces_batch_attribute
(
face_multitask_model
,
face_euler_model
,
dets
,
img_raw
,
use_cuda
,
face_size
=
256
,
vis
=
False
):
def
get_faces_batch_attribute
(
face_multitask_model
,
face_euler_model
,
face_au_model
,
dets
,
img_raw
,
use_cuda
,
face_size
=
256
,
vis
=
False
):
if
len
(
dets
)
==
0
:
return
None
img_align
=
img_raw
.
copy
()
...
...
@@ -291,6 +290,7 @@ def get_faces_batch_attribute(face_multitask_model,face_euler_model,dets,img_raw
euler_angles
=
face_euler_model
.
predict
(
image_batch
)
faces_message
=
None
faces_align_batch
=
None
for
i
in
range
(
len
(
dets
)):
x0
,
y0
=
r_bboxes
[
i
][
0
],
r_bboxes
[
i
][
1
]
face_w
=
r_bboxes
[
i
][
2
]
-
r_bboxes
[
i
][
0
]
...
...
@@ -318,10 +318,22 @@ def get_faces_batch_attribute(face_multitask_model,face_euler_model,dets,img_raw
if
abs
(
yaw
)
<
45.
:
face_align_output
=
face_alignment
(
img_align
,
eyes_center
[
0
],
eyes_center
[
1
],
desiredLeftEye
=
(
0.365
,
0.38
),
desiredFaceWidth
=
112
,
desiredFaceHeight
=
None
)
desiredLeftEye
=
(
0.365
,
0.38
),
desiredFaceWidth
=
256
,
desiredFaceHeight
=
None
)
else
:
face_align_output
=
face_alignment
(
img_align
,
eyes_center
[
0
],
eyes_center
[
1
],
desiredLeftEye
=
(
0.38
,
0.40
),
desiredFaceWidth
=
112
,
desiredFaceHeight
=
None
)
desiredLeftEye
=
(
0.38
,
0.40
),
desiredFaceWidth
=
256
,
desiredFaceHeight
=
None
)
# au 输入 预处理
face_align_output_
=
cv2
.
cvtColor
(
face_align_output
,
cv2
.
COLOR_BGR2RGB
).
astype
(
np
.
float32
)
face_align_output_
=
face_align_output_
-
[
123.67
,
116.28
,
103.53
]
face_align_output_
=
face_align_output_
.
transpose
(
2
,
0
,
1
)
face_align_output_
=
np
.
expand_dims
(
face_align_output_
,
0
)
if
faces_align_batch
is
None
:
faces_align_batch
=
face_align_output_
else
:
faces_align_batch
=
np
.
concatenate
((
faces_align_batch
,
face_align_output_
),
axis
=
0
)
#
if
faces_message
is
None
:
faces_message
=
[]
faces_message
.
append
(
...
...
@@ -329,12 +341,30 @@ def get_faces_batch_attribute(face_multitask_model,face_euler_model,dets,img_raw
"xyxy"
:
r_bboxes
[
i
],
"age"
:
age_pre
[
i
][
0
],
"gender"
:
gender_str
,
"head_3d_angle"
:{
"yaw"
:
yaw
,
"pitch"
:
pitch
,
"roll"
:
roll
}
"head_3d_angle"
:{
"yaw"
:
yaw
,
"pitch"
:
pitch
,
"roll"
:
roll
},
"open_mouth"
:
None
,
"eye_close"
:
None
}
)
# plot_box(r_bboxes[i][0:4], img_raw,label="{}, age: {:.1f}, unblur:{}".format(gender_str,age_pre[i][0],int(blur_)), color=(255,90,90), line_thickness=2)
if
vis
:
plot_box
(
r_bboxes
[
i
][
0
:
4
],
img_raw
,
label
=
"{}, age: {:.1f}"
.
format
(
gender_str
,
age_pre
[
i
][
0
]),
color
=
(
255
,
90
,
90
),
line_thickness
=
2
)
# print("faces_align_batch shape : ",faces_align_batch.shape)
au_features
=
face_au_model
.
predict
(
faces_align_batch
)
for
i
in
range
(
len
(
dets
)):
# print("au_features : ",au_features[i])
open_mouth
=
np
.
clip
(
au_features
[
i
][
8
],
0.
,
1.
)
close_eye_r
=
np
.
clip
(
au_features
[
i
][
0
],
0.
,
1.
)
close_eye_l
=
np
.
clip
(
au_features
[
i
][
1
],
0.
,
1.
)
print
(
"open_mouth : {:.2f},eye_close: {:.3f} , {:.3f}"
.
format
(
open_mouth
,
close_eye_r
,
close_eye_l
))
faces_message
[
i
][
"open_mouth"
]
=
open_mouth
faces_message
[
i
][
"eye_close"
]
=
(
close_eye_r
,
close_eye_l
)
cv2
.
putText
(
img_raw
,
"{:.2f}"
.
format
(
open_mouth
),(
int
(
r_bboxes
[
i
][
0
]
-
1
),
int
(
r_bboxes
[
i
][
3
]
+
15
)),
cv2
.
FONT_HERSHEY_DUPLEX
,
0.65
,
(
20
,
185
,
25
),
3
)
cv2
.
putText
(
img_raw
,
"{:.2f}"
.
format
(
open_mouth
),(
int
(
r_bboxes
[
i
][
0
]
-
1
),
int
(
r_bboxes
[
i
][
3
]
+
15
)),
cv2
.
FONT_HERSHEY_DUPLEX
,
0.65
,
(
20
,
185
,
255
),
1
)
cv2
.
putText
(
img_raw
,
"{:.2f},{:.2f}"
.
format
(
close_eye_r
,
close_eye_l
),(
int
(
r_bboxes
[
i
][
0
]
-
1
),
int
(
r_bboxes
[
i
][
3
]
+
35
)),
cv2
.
FONT_HERSHEY_DUPLEX
,
0.65
,
(
20
,
33
,
255
),
3
)
cv2
.
putText
(
img_raw
,
"{:.2f},{:.2f}"
.
format
(
close_eye_r
,
close_eye_l
),(
int
(
r_bboxes
[
i
][
0
]
-
1
),
int
(
r_bboxes
[
i
][
3
]
+
35
)),
cv2
.
FONT_HERSHEY_DUPLEX
,
0.65
,
(
20
,
185
,
255
),
1
)
return
faces_message
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录