forked from PaddlePaddle/PaddleHub
-
Notifications
You must be signed in to change notification settings - Fork 0
/
module.py
130 lines (101 loc) · 4.03 KB
/
module.py
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import os
import cv2
import paddle
import numpy as np
from paddle.nn import Layer
from paddlehub.module.module import moduleinfo
@moduleinfo(
name="SINet_Portrait_Segmentation", # 模型名称
type="CV/semantic_segmentation", # 模型类型
author="jm12138", # 作者名称
author_email="[email protected]", # 作者邮箱
summary="SINet_Portrait_Segmentation", # 模型介绍
version="1.0.0" # 版本号
)
class SINet_Portrait_Segmentation(Layer):
# 初始化函数
def __init__(self, name=None, directory=None):
super(SINet_Portrait_Segmentation, self).__init__()
# 设置模型路径
self.model_path = os.path.join(self.directory, "SINet")
# 加载模型
self.model = paddle.jit.load(self.model_path)
self.model.eval()
# 均值方差
self.mean = [107.304565, 115.69884, 132.35703]
self.std = [63.97182, 65.1337, 68.29726]
# 读取数据函数
@staticmethod
def load_datas(paths, images):
datas = []
# 读取数据列表
if paths is not None:
for im_path in paths:
assert os.path.isfile(im_path), "The {} isn't a valid file path.".format(im_path)
im = cv2.imread(im_path)
datas.append(im)
if images is not None:
datas = images
# 返回数据列表
return datas
# 预处理函数
def preprocess(self, datas, batch_size):
input_datas = []
for img in datas:
# 缩放
h, w = img.shape[:2]
img = cv2.resize(img, (224, 224))
# 格式转换
img = img.astype(np.float32)
# 归一化
for j in range(3):
img[:, :, j] -= self.mean[j]
for j in range(3):
img[:, :, j] /= self.std[j]
img /= 255.
# 格式转换
img = img.transpose((2, 0, 1))
img = img[np.newaxis, ...]
input_datas.append(img)
# 数据切分
input_datas = np.concatenate(input_datas, 0)
split_num = len(datas) // batch_size + 1 if len(datas) % batch_size != 0 else len(datas) // batch_size
input_datas = np.array_split(input_datas, split_num)
return input_datas
# 后处理函数
def postprocess(self, outputs, datas, output_dir, visualization):
# 检查输出目录
if visualization:
if not os.path.exists(output_dir):
os.mkdir(output_dir)
# 拼接输出
outputs = paddle.concat(outputs)
results = []
for output, img, i in zip(outputs, datas, range(len(datas))):
# 计算MASK
mask = 1 - (output[0] > 0).numpy().astype('float32')
# 缩放
h, w = img.shape[:2]
mask = cv2.resize(mask, (w, h))
# 计算输出图像
result = (img * mask[..., np.newaxis] + (1 - mask[..., np.newaxis]) * 255).astype(np.uint8)
# 格式还原
mask = (mask * 255).astype(np.uint8)
# 可视化
if visualization:
cv2.imwrite(os.path.join(output_dir, 'result_mask_%d.png' % i), mask)
cv2.imwrite(os.path.join(output_dir, 'result_%d.png' % i), result)
results.append({'mask': mask, 'result': result})
return results
# 关键点检测函数
def Segmentation(self, images=None, paths=None, batch_size=1, output_dir='output', visualization=False):
# 加载数据处理器
datas = self.load_datas(paths, images)
# 获取输入数据
input_datas = self.preprocess(datas, batch_size)
# 模型预测
outputs = [self.model(paddle.to_tensor(input_data)) for input_data in input_datas]
# 结果后处理
results = self.postprocess(outputs, datas, output_dir, visualization)
# 返回结果
return results