18
18
import numpy as np
19
19
20
20
from .image_model import ImageModel
21
- from .utils import RESIZE_TYPES , load_labels , nms , pad_image
21
+ from .model import WrapperError
22
+ from .types import ListValue , NumericalValue
23
+ from .utils import load_labels , nms
22
24
23
25
24
26
class MaskRCNNModel (ImageModel ):
25
- def __init__ (self , model_adapter , prob_threshold = 0.5 , labels = None , keep_aspect_ratio = False ):
26
- super ().__init__ (model_adapter )
27
- self .resize_type = 'fit_to_window' if keep_aspect_ratio else 'standard'
28
- self .resize = RESIZE_TYPES [self .resize_type ]
29
- self .prob_threshold = prob_threshold
27
+ __model__ = 'MaskRCNN'
28
+
29
+ def __init__ (self , model_adapter , configuration ):
30
+ super ().__init__ (model_adapter , configuration )
30
31
self ._check_io_number ((1 , 2 ), (3 , 4 , 5 , 8 ))
31
- self .type = 'segmentoly' if len (self .inputs ) == 2 else 'mask_rcnn'
32
- if isinstance (labels , (list , tuple )):
33
- self .labels = labels
32
+ self .is_segmentoly = len (self .inputs ) == 2
33
+ if isinstance (self . labels , (list , tuple )):
34
+ self .labels = self . labels
34
35
else :
35
- self .labels = load_labels (labels ) if labels else None
36
+ self .labels = load_labels (self . labels ) if self . labels else None
36
37
37
38
self .output_blob_name = self ._get_outputs ()
38
39
40
+ @classmethod
41
+ def parameters (cls ):
42
+ parameters = super ().parameters ()
43
+ parameters .update ({
44
+ 'prob_threshold' : NumericalValue (
45
+ default_value = None ,
46
+ description = 'Probability threshold for detections filtering'
47
+ ),
48
+ 'labels' : ListValue (
49
+ default_value = None ,
50
+ description = 'List of labels'
51
+ ),
52
+ })
53
+ return parameters
54
+
39
55
def _get_outputs (self ):
40
- if self .type == 'segmentoly' :
56
+ if self .is_segmentoly :
41
57
return self ._get_segmentoly_outputs ()
42
58
outputs = {}
43
59
for layer_name in self .outputs :
@@ -52,7 +68,7 @@ def _get_outputs(self):
52
68
elif len (layer_shape ) == 3 :
53
69
outputs ['masks' ] = layer_name
54
70
else :
55
- raise Exception ( "Unexpected output layer shape {} with name {}" .format (layer_shape , layer_name ))
71
+ raise WrapperError ( self . __model__ , "Unexpected output layer shape {} with name {}" .format (layer_shape , layer_name ))
56
72
57
73
return outputs
58
74
@@ -69,34 +85,34 @@ def _get_segmentoly_outputs(self):
69
85
elif layer_name == 'raw_masks' and len (layer_shape ) == 4 :
70
86
outputs ['masks' ] = layer_name
71
87
else :
72
- raise Exception ( "Unexpected output layer shape {} with name {}" .format (layer_shape , layer_name ))
88
+ raise WrapperError ( self . __model__ , "Unexpected output layer shape {} with name {}" .format (layer_shape , layer_name ))
73
89
return outputs
74
90
75
91
def preprocess (self , inputs ):
76
92
dict_inputs , meta = super ().preprocess (inputs )
77
- input_image_size = meta ['resized_shape' ]. shape [:2 ]
78
- if self .type == 'segmentoly' :
93
+ input_image_size = meta ['resized_shape' ][:2 ]
94
+ if self .is_segmentoly :
79
95
assert len (self .image_info_blob_names ) == 1
80
96
input_image_info = np .asarray ([[input_image_size [0 ], input_image_size [1 ], 1 ]], dtype = np .float32 )
81
97
dict_inputs [self .image_info_blob_names [0 ]] = input_image_info
82
98
return dict_inputs , meta
83
99
84
100
def postprocess (self , outputs , meta ):
85
- boxes = outputs [self .output_blob_name ['boxes' ]] if self .type == 'segmentoly' else \
101
+ boxes = outputs [self .output_blob_name ['boxes' ]] if self .is_segmentoly else \
86
102
outputs [self .output_blob_name ['boxes' ]][:, :4 ]
87
- scores = outputs [self .output_blob_name ['scores' ]] if self .type == 'segmentoly' else \
103
+ scores = outputs [self .output_blob_name ['scores' ]] if self .is_segmentoly else \
88
104
outputs [self .output_blob_name ['boxes' ]][:, 4 ]
89
105
scale_x = meta ['resized_shape' ][1 ] / meta ['original_shape' ][1 ]
90
106
scale_y = meta ['resized_shape' ][0 ] / meta ['original_shape' ][0 ]
91
107
boxes [:, 0 ::2 ] /= scale_x
92
108
boxes [:, 1 ::2 ] /= scale_y
93
- if self .type == 'segmentoly' :
109
+ if self .is_segmentoly :
94
110
classes = outputs [self .output_blob_name ['labels' ]].astype (np .uint32 )
95
111
else :
96
112
classes = outputs [self .output_blob_name ['labels' ]].astype (np .uint32 ) + 1
97
113
masks = []
98
114
for box , cls , raw_mask in zip (boxes , classes , outputs [self .output_blob_name ['masks' ]]):
99
- raw_cls_mask = raw_mask [cls , ...] if self .type == 'segmentoly' else raw_mask
115
+ raw_cls_mask = raw_mask [cls , ...] if self .is_segmentoly else raw_mask
100
116
masks .append (self ._segm_postprocess (box , raw_cls_mask , * meta ['original_shape' ][:- 1 ]))
101
117
# Filter out detections with low confidence.
102
118
detections_filter = scores > self .prob_threshold
@@ -139,19 +155,33 @@ def _segm_postprocess(self, box, raw_cls_mask, im_h, im_w):
139
155
140
156
141
157
class YolactModel (ImageModel ):
142
- def __init__ (self , model_adapter , prob_threshold = 0.5 , labels = None , keep_aspect_ratio = False ):
143
- super ().__init__ (model_adapter )
144
- self .resize_type = 'fit_to_window' if keep_aspect_ratio else 'standard'
145
- self .resize = RESIZE_TYPES [self .resize_type ]
146
- self .prob_threshold = prob_threshold
158
+ __model__ = 'Yolact'
159
+
160
+ def __init__ (self , model_adapter , configuration ):
161
+ super ().__init__ (model_adapter , configuration )
147
162
self ._check_io_number (1 , 4 )
148
- if isinstance (labels , (list , tuple )):
149
- self .labels = labels
163
+ if isinstance (self . labels , (list , tuple )):
164
+ self .labels = self . labels
150
165
else :
151
- self .labels = load_labels (labels ) if labels else None
166
+ self .labels = load_labels (self . labels ) if self . labels else None
152
167
153
168
self .output_blob_name = self ._get_outputs ()
154
169
170
+ @classmethod
171
+ def parameters (cls ):
172
+ parameters = super ().parameters ()
173
+ parameters .update ({
174
+ 'prob_threshold' : NumericalValue (
175
+ default_value = None ,
176
+ description = 'Probability threshold for detections filtering'
177
+ ),
178
+ 'labels' : ListValue (
179
+ default_value = None ,
180
+ description = 'List of labels'
181
+ ),
182
+ })
183
+ return parameters
184
+
155
185
def _get_outputs (self ):
156
186
outputs = {}
157
187
for layer_name in self .outputs :
@@ -165,7 +195,7 @@ def _get_outputs(self):
165
195
elif layer_name == 'mask' and len (layer_shape ) == 3 :
166
196
outputs ['masks' ] = layer_name
167
197
else :
168
- raise Exception ( "Unexpected output layer shape {} with name {}" .format (layer_shape , layer_name ))
198
+ raise WrapperError ( self . __model__ , "Unexpected output layer shape {} with name {}" .format (layer_shape , layer_name ))
169
199
return outputs
170
200
171
201
def postprocess (self , outputs , meta ):
@@ -276,10 +306,10 @@ def _sanitize_coordinates(_x1, _x2, img_size, shift=0, padding=0):
276
306
return x1 , x2
277
307
278
308
279
- def get_instance_segmentation_model (model_adapter , prob_threshold = 0.5 , labels = None , keep_aspect_ratio = False ):
309
+ def get_instance_segmentation_model (model_adapter , configuration ):
280
310
inputs = model_adapter .get_input_layers ()
281
311
outputs = model_adapter .get_output_layers ()
282
312
if len (inputs ) == 1 and len (outputs ) == 4 and 'proto' in outputs .keys ():
283
- return YolactModel (model_adapter , prob_threshold , labels , keep_aspect_ratio )
313
+ return YolactModel (model_adapter , configuration )
284
314
else :
285
- return MaskRCNNModel (model_adapter , prob_threshold , labels , keep_aspect_ratio )
315
+ return MaskRCNNModel (model_adapter , configuration )
0 commit comments