edgefirst-validator 4.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- deepview/modelpack/utils/argmax.py +16 -0
- edgefirst/validator/__init__.py +1 -0
- edgefirst/validator/__main__.py +375 -0
- edgefirst/validator/datasets/__init__.py +118 -0
- edgefirst/validator/datasets/cache.py +296 -0
- edgefirst/validator/datasets/core.py +250 -0
- edgefirst/validator/datasets/darknet.py +446 -0
- edgefirst/validator/datasets/database.py +1067 -0
- edgefirst/validator/datasets/instance/__init__.py +4 -0
- edgefirst/validator/datasets/instance/core.py +222 -0
- edgefirst/validator/datasets/instance/detection.py +145 -0
- edgefirst/validator/datasets/instance/multitask.py +80 -0
- edgefirst/validator/datasets/instance/segmentation.py +120 -0
- edgefirst/validator/datasets/utils/fetch.py +682 -0
- edgefirst/validator/datasets/utils/readers.py +425 -0
- edgefirst/validator/datasets/utils/transformations.py +1695 -0
- edgefirst/validator/evaluators/__init__.py +17 -0
- edgefirst/validator/evaluators/callbacks/__init__.py +3 -0
- edgefirst/validator/evaluators/callbacks/core.py +192 -0
- edgefirst/validator/evaluators/callbacks/plots.py +900 -0
- edgefirst/validator/evaluators/callbacks/studio.py +234 -0
- edgefirst/validator/evaluators/core.py +257 -0
- edgefirst/validator/evaluators/detection.py +749 -0
- edgefirst/validator/evaluators/multitask.py +270 -0
- edgefirst/validator/evaluators/parameters/__init__.py +53 -0
- edgefirst/validator/evaluators/parameters/core.py +554 -0
- edgefirst/validator/evaluators/parameters/dataset.py +239 -0
- edgefirst/validator/evaluators/parameters/model.py +338 -0
- edgefirst/validator/evaluators/parameters/validation.py +528 -0
- edgefirst/validator/evaluators/segmentation.py +729 -0
- edgefirst/validator/evaluators/utils/__init__.py +3 -0
- edgefirst/validator/evaluators/utils/classify.py +292 -0
- edgefirst/validator/evaluators/utils/match.py +262 -0
- edgefirst/validator/evaluators/utils/timer.py +132 -0
- edgefirst/validator/metrics/__init__.py +9 -0
- edgefirst/validator/metrics/data/__init__.py +7 -0
- edgefirst/validator/metrics/data/label.py +668 -0
- edgefirst/validator/metrics/data/metrics.py +759 -0
- edgefirst/validator/metrics/data/plots.py +476 -0
- edgefirst/validator/metrics/data/stats.py +507 -0
- edgefirst/validator/metrics/detection.py +595 -0
- edgefirst/validator/metrics/segmentation.py +173 -0
- edgefirst/validator/metrics/utils/math.py +717 -0
- edgefirst/validator/publishers/__init__.py +3 -0
- edgefirst/validator/publishers/console.py +147 -0
- edgefirst/validator/publishers/studio.py +128 -0
- edgefirst/validator/publishers/tensorboard.py +119 -0
- edgefirst/validator/publishers/utils/logger.py +111 -0
- edgefirst/validator/publishers/utils/table.py +403 -0
- edgefirst/validator/runners/__init__.py +8 -0
- edgefirst/validator/runners/core.py +727 -0
- edgefirst/validator/runners/deepviewrt.py +177 -0
- edgefirst/validator/runners/hailo.py +263 -0
- edgefirst/validator/runners/keras.py +150 -0
- edgefirst/validator/runners/kinara.py +265 -0
- edgefirst/validator/runners/offline.py +228 -0
- edgefirst/validator/runners/onnx.py +241 -0
- edgefirst/validator/runners/processing/decode.py +320 -0
- edgefirst/validator/runners/processing/dvapi.py +4192 -0
- edgefirst/validator/runners/processing/nms.py +637 -0
- edgefirst/validator/runners/processing/outputs.py +507 -0
- edgefirst/validator/runners/tensorrt.py +321 -0
- edgefirst/validator/runners/tflite.py +221 -0
- edgefirst/validator/validate.py +843 -0
- edgefirst/validator/visualize/__init__.py +3 -0
- edgefirst/validator/visualize/detection.py +623 -0
- edgefirst/validator/visualize/segmentation.py +281 -0
- edgefirst/validator/visualize/utils/plots.py +635 -0
- edgefirst_validator-4.2.1.dist-info/METADATA +111 -0
- edgefirst_validator-4.2.1.dist-info/RECORD +73 -0
- edgefirst_validator-4.2.1.dist-info/WHEEL +5 -0
- edgefirst_validator-4.2.1.dist-info/entry_points.txt +2 -0
- edgefirst_validator-4.2.1.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
from edgefirst.validator.datasets.instance.core import Instance
|
|
2
|
+
from edgefirst.validator.datasets.instance.detection import DetectionInstance
|
|
3
|
+
from edgefirst.validator.datasets.instance.segmentation import SegmentationInstance
|
|
4
|
+
from edgefirst.validator.datasets.instance.multitask import MultitaskInstance
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Instance:
|
|
5
|
+
"""
|
|
6
|
+
Base Instance object for containing the ground truth dataset instance.
|
|
7
|
+
|
|
8
|
+
Parameters
|
|
9
|
+
----------
|
|
10
|
+
image_path: str
|
|
11
|
+
The path to the image for Darknet datasets. Otherwise this is the
|
|
12
|
+
image name for TFRecord datasets. This is required either to
|
|
13
|
+
allow reading the image from file or saving the image results
|
|
14
|
+
in disk with the same file name.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(self, image_path: str):
|
|
18
|
+
self.__image_path = image_path
|
|
19
|
+
# This is the NumPy array image.
|
|
20
|
+
self.__image = None
|
|
21
|
+
self.__visual_image = None
|
|
22
|
+
self.__height = 0
|
|
23
|
+
self.__width = 0
|
|
24
|
+
|
|
25
|
+
# Same property used in YOLOv5 and YOLOv7 for the shapes.
|
|
26
|
+
self.__shapes = [
|
|
27
|
+
[
|
|
28
|
+
[0, 0], # imgsz (model input shape) [height, width]
|
|
29
|
+
# ratio_pad [[scale y, scale x], [pad w, pad h]]
|
|
30
|
+
[(1.0, 1.0), (0.0, 0.0)]
|
|
31
|
+
],
|
|
32
|
+
[1.0, 1.0] # label ratio [x, y]
|
|
33
|
+
]
|
|
34
|
+
# The original image dimensions.
|
|
35
|
+
self.__image_shape = None
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def image_path(self) -> str:
|
|
39
|
+
"""
|
|
40
|
+
Attribute to access the image path/name.
|
|
41
|
+
|
|
42
|
+
Returns
|
|
43
|
+
-------
|
|
44
|
+
str
|
|
45
|
+
The image path/name.
|
|
46
|
+
"""
|
|
47
|
+
return self.__image_path
|
|
48
|
+
|
|
49
|
+
@image_path.setter
|
|
50
|
+
def image_path(self, path: str):
|
|
51
|
+
"""
|
|
52
|
+
Sets the image path/name.
|
|
53
|
+
|
|
54
|
+
Parameters
|
|
55
|
+
----------
|
|
56
|
+
path: str
|
|
57
|
+
The image path/name.
|
|
58
|
+
"""
|
|
59
|
+
self.__image_path = path
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def image(self) -> np.ndarray:
|
|
63
|
+
"""
|
|
64
|
+
Attribute to access the image.
|
|
65
|
+
|
|
66
|
+
Returns
|
|
67
|
+
-------
|
|
68
|
+
np.ndarray
|
|
69
|
+
The image as a NumPy array.
|
|
70
|
+
"""
|
|
71
|
+
return self.__image
|
|
72
|
+
|
|
73
|
+
@image.setter
|
|
74
|
+
def image(self, this_image: np.ndarray):
|
|
75
|
+
"""
|
|
76
|
+
Sets the image array.
|
|
77
|
+
|
|
78
|
+
Parameters
|
|
79
|
+
----------
|
|
80
|
+
this_image: np.ndarray
|
|
81
|
+
The image array.
|
|
82
|
+
"""
|
|
83
|
+
self.__image = this_image
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def visual_image(self) -> np.ndarray:
|
|
87
|
+
"""
|
|
88
|
+
Attribute to access the image.
|
|
89
|
+
|
|
90
|
+
Returns
|
|
91
|
+
-------
|
|
92
|
+
np.ndarray
|
|
93
|
+
The image as a NumPy array.
|
|
94
|
+
"""
|
|
95
|
+
return self.__visual_image
|
|
96
|
+
|
|
97
|
+
@visual_image.setter
|
|
98
|
+
def visual_image(self, this_image: np.ndarray):
|
|
99
|
+
"""
|
|
100
|
+
Sets the image array.
|
|
101
|
+
|
|
102
|
+
Parameters
|
|
103
|
+
----------
|
|
104
|
+
this_image: np.ndarray
|
|
105
|
+
The image array.
|
|
106
|
+
"""
|
|
107
|
+
self.__visual_image = this_image
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def height(self) -> int:
|
|
111
|
+
"""
|
|
112
|
+
Attribute to access the image height in pixels.
|
|
113
|
+
|
|
114
|
+
Returns
|
|
115
|
+
-------
|
|
116
|
+
int
|
|
117
|
+
The image height in pixels. 0 means uninitialized.
|
|
118
|
+
"""
|
|
119
|
+
return self.__height
|
|
120
|
+
|
|
121
|
+
@height.setter
|
|
122
|
+
def height(self, image_height: int):
|
|
123
|
+
"""
|
|
124
|
+
Sets the image height dimension to a new value.
|
|
125
|
+
|
|
126
|
+
Parameters
|
|
127
|
+
----------
|
|
128
|
+
image_height: int
|
|
129
|
+
This is the new image height to set.
|
|
130
|
+
"""
|
|
131
|
+
self.__height = image_height
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
def width(self) -> int:
|
|
135
|
+
"""
|
|
136
|
+
Attribute to access the image width in pixels.
|
|
137
|
+
|
|
138
|
+
Returns
|
|
139
|
+
-------
|
|
140
|
+
int:
|
|
141
|
+
The image width in pixels. 0 means uninitialized.
|
|
142
|
+
"""
|
|
143
|
+
return self.__width
|
|
144
|
+
|
|
145
|
+
@width.setter
|
|
146
|
+
def width(self, image_width: int):
|
|
147
|
+
"""
|
|
148
|
+
Sets the image width dimension to a new value.
|
|
149
|
+
|
|
150
|
+
Parameters
|
|
151
|
+
----------
|
|
152
|
+
image_width: int
|
|
153
|
+
This is the new image width to set.
|
|
154
|
+
"""
|
|
155
|
+
self.__width = image_width
|
|
156
|
+
|
|
157
|
+
@property
|
|
158
|
+
def shapes(self) -> list:
|
|
159
|
+
"""
|
|
160
|
+
Attribute to access the inference shapes which includes
|
|
161
|
+
the image shape after letterbox operation and aswell as padding
|
|
162
|
+
and ratio which are variables that mirrors YOLOv5 and YOLOv7
|
|
163
|
+
implementation of the letterbox image processing.
|
|
164
|
+
This attribute is used for bounding box rescaling for both the
|
|
165
|
+
ground truth and detections.
|
|
166
|
+
|
|
167
|
+
Returns
|
|
168
|
+
-------
|
|
169
|
+
list
|
|
170
|
+
.. code-block:: python
|
|
171
|
+
|
|
172
|
+
[
|
|
173
|
+
[image height, image width]],
|
|
174
|
+
[[ratio y, ratio x], [pad x, pad y]],
|
|
175
|
+
label_ratio
|
|
176
|
+
]
|
|
177
|
+
"""
|
|
178
|
+
return self.__shapes
|
|
179
|
+
|
|
180
|
+
@shapes.setter
|
|
181
|
+
def shapes(self, shape: list):
|
|
182
|
+
"""
|
|
183
|
+
Sets the shapes attribute to a new value.
|
|
184
|
+
|
|
185
|
+
Parameters
|
|
186
|
+
----------
|
|
187
|
+
shape: list
|
|
188
|
+
.. code-block:: python
|
|
189
|
+
|
|
190
|
+
[
|
|
191
|
+
[image height, image width]],
|
|
192
|
+
[[ratio y, ratio x], [pad x, pad y]],
|
|
193
|
+
label_ratio
|
|
194
|
+
]
|
|
195
|
+
"""
|
|
196
|
+
self.__shapes = shape
|
|
197
|
+
|
|
198
|
+
@property
|
|
199
|
+
def image_shape(self) -> tuple:
|
|
200
|
+
"""
|
|
201
|
+
Attribute to access the image shape.
|
|
202
|
+
This is the original image dimensions prior
|
|
203
|
+
to image preprocessing.
|
|
204
|
+
|
|
205
|
+
Returns
|
|
206
|
+
-------
|
|
207
|
+
tuple
|
|
208
|
+
This contains the image (height, width) dimensions.
|
|
209
|
+
"""
|
|
210
|
+
return self.__image_shape
|
|
211
|
+
|
|
212
|
+
@image_shape.setter
|
|
213
|
+
def image_shape(self, shape: tuple):
|
|
214
|
+
"""
|
|
215
|
+
Sets the image shape.
|
|
216
|
+
|
|
217
|
+
Parameters
|
|
218
|
+
----------
|
|
219
|
+
shape: tuple
|
|
220
|
+
Sets the original image dimensions.
|
|
221
|
+
"""
|
|
222
|
+
self.__image_shape = shape
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from edgefirst.validator.datasets.instance import Instance
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DetectionInstance(Instance):
|
|
9
|
+
"""
|
|
10
|
+
Instance for storing ground truth and
|
|
11
|
+
model bounding boxes, labels, and scores.
|
|
12
|
+
|
|
13
|
+
Parameters
|
|
14
|
+
----------
|
|
15
|
+
image_path: str
|
|
16
|
+
The path to the image for Darknet datasets. Otherwise this is the
|
|
17
|
+
image name for TFRecord datasets. This is required either to
|
|
18
|
+
allow reading the image from file or saving the image results
|
|
19
|
+
in disk with the same file name.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, image_path: str):
|
|
23
|
+
super(DetectionInstance, self).__init__(image_path)
|
|
24
|
+
|
|
25
|
+
# These are the 2D bounding boxes in either YOLO, COCO, or PascalVoc.
|
|
26
|
+
self.__boxes = np.array([])
|
|
27
|
+
# These contain either string or integer labels per bounding box.
|
|
28
|
+
self.__labels = np.array([])
|
|
29
|
+
# These contain the prediction scores per bounding box. Empty if gt.
|
|
30
|
+
self.__scores = np.array([])
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def boxes(self) -> Union[list, np.ndarray]:
|
|
34
|
+
"""
|
|
35
|
+
Attribute to access the 2D bounding boxes for detection.
|
|
36
|
+
|
|
37
|
+
Returns
|
|
38
|
+
-------
|
|
39
|
+
Union[list, np.ndarray]
|
|
40
|
+
This contains the 2D normalized bounding boxes.
|
|
41
|
+
"""
|
|
42
|
+
return self.__boxes
|
|
43
|
+
|
|
44
|
+
@boxes.setter
|
|
45
|
+
def boxes(self, boxes_2d: Union[list, np.ndarray]):
|
|
46
|
+
"""
|
|
47
|
+
Sets the 2D bounding boxes to a new value.
|
|
48
|
+
|
|
49
|
+
Parameters
|
|
50
|
+
----------
|
|
51
|
+
boxes_2d: Union[list, np.ndarray]
|
|
52
|
+
These are the 2D bounding boxes to set.
|
|
53
|
+
"""
|
|
54
|
+
self.__boxes = boxes_2d
|
|
55
|
+
|
|
56
|
+
def append_boxes(self, box: Union[list, np.ndarray]):
|
|
57
|
+
"""
|
|
58
|
+
Appends list or stacks NumPy array 2D bounding boxes.
|
|
59
|
+
|
|
60
|
+
Parameters
|
|
61
|
+
----------
|
|
62
|
+
box: Union[list, np.ndarray]
|
|
63
|
+
This is the 2D normalized bounding box in either
|
|
64
|
+
YOLO, COCO, or PascalVoc.
|
|
65
|
+
"""
|
|
66
|
+
if isinstance(self.__boxes, np.ndarray):
|
|
67
|
+
self.__boxes = np.vstack([self.__boxes, box])
|
|
68
|
+
else:
|
|
69
|
+
self.__boxes.append(box)
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def labels(self) -> Union[list, np.ndarray]:
|
|
73
|
+
"""
|
|
74
|
+
Attribute to access the labels per bounding box.
|
|
75
|
+
|
|
76
|
+
Returns
|
|
77
|
+
-------
|
|
78
|
+
Union[list, np.ndarray]
|
|
79
|
+
This contains the labels per bounding box.
|
|
80
|
+
"""
|
|
81
|
+
return self.__labels
|
|
82
|
+
|
|
83
|
+
@labels.setter
|
|
84
|
+
def labels(self, new_labels: Union[list, np.ndarray]):
|
|
85
|
+
"""
|
|
86
|
+
Sets the labels to a new value.
|
|
87
|
+
|
|
88
|
+
Parameters
|
|
89
|
+
----------
|
|
90
|
+
new_labels: Union[list, np.ndarray]
|
|
91
|
+
These are the labels to set.
|
|
92
|
+
"""
|
|
93
|
+
self.__labels = new_labels
|
|
94
|
+
|
|
95
|
+
def append_labels(self, label: Union[str, int, np.integer]):
|
|
96
|
+
"""
|
|
97
|
+
Appends list or appends NumPy array label.
|
|
98
|
+
|
|
99
|
+
Parameters
|
|
100
|
+
----------
|
|
101
|
+
label: Union[str, int, np.integer]
|
|
102
|
+
This is the label to append to the list.
|
|
103
|
+
"""
|
|
104
|
+
if isinstance(self.__labels, np.ndarray):
|
|
105
|
+
self.__labels = np.append(self.__labels, label)
|
|
106
|
+
else:
|
|
107
|
+
self.__labels.append(label)
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def scores(self) -> Union[list, np.ndarray]:
|
|
111
|
+
"""
|
|
112
|
+
Attribute to access the scores per bounding box.
|
|
113
|
+
|
|
114
|
+
Returns
|
|
115
|
+
-------
|
|
116
|
+
Union[list, np.ndarray]
|
|
117
|
+
This contains the scores per bounding box.
|
|
118
|
+
"""
|
|
119
|
+
return self.__scores
|
|
120
|
+
|
|
121
|
+
@scores.setter
|
|
122
|
+
def scores(self, new_scores: Union[list, np.ndarray]):
|
|
123
|
+
"""
|
|
124
|
+
Sets the scores to a new value.
|
|
125
|
+
|
|
126
|
+
Parameters
|
|
127
|
+
----------
|
|
128
|
+
new_scores: Union[list, np.ndarray]
|
|
129
|
+
These are the scores to set.
|
|
130
|
+
"""
|
|
131
|
+
self.__scores = new_scores
|
|
132
|
+
|
|
133
|
+
def append_scores(self, score: float):
|
|
134
|
+
"""
|
|
135
|
+
Appends list or appends NumPy array scores.
|
|
136
|
+
|
|
137
|
+
Parameters
|
|
138
|
+
----------
|
|
139
|
+
score: float
|
|
140
|
+
This is the score to append to the list.
|
|
141
|
+
"""
|
|
142
|
+
if isinstance(self.__scores, np.ndarray):
|
|
143
|
+
self.__scores = np.append(self.__scores, score)
|
|
144
|
+
else:
|
|
145
|
+
self.__scores.append(score)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from edgefirst.validator.datasets.instance import DetectionInstance
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class MultitaskInstance(DetectionInstance):
|
|
9
|
+
"""
|
|
10
|
+
Instance for storing Multitask ground truth and model predictions
|
|
11
|
+
for Vision which has bounding boxes, labels, scores, and masks.
|
|
12
|
+
|
|
13
|
+
Parameters
|
|
14
|
+
----------
|
|
15
|
+
image_path: str
|
|
16
|
+
The path to the image for Darknet datasets. Otherwise this is the
|
|
17
|
+
image name for TFRecord datasets. This is required either to
|
|
18
|
+
allow reading the image from file or saving the image results
|
|
19
|
+
in disk with the same file name.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, image_path: str):
|
|
23
|
+
super(MultitaskInstance, self).__init__(image_path)
|
|
24
|
+
|
|
25
|
+
# These contain the segmentation points to form the
|
|
26
|
+
# polygon shape around the object.
|
|
27
|
+
self.__polygons = np.array([])
|
|
28
|
+
# This is the segmentation mask for the image.
|
|
29
|
+
self.__mask = None
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def polygons(self) -> Union[list, np.ndarray]:
|
|
33
|
+
"""
|
|
34
|
+
Attribute to access the 2D points that form the polygon to shape
|
|
35
|
+
around the object to form segmentation masks.
|
|
36
|
+
|
|
37
|
+
Returns
|
|
38
|
+
-------
|
|
39
|
+
Union[list, np.ndarray]
|
|
40
|
+
This contains the polygon points. Ex.
|
|
41
|
+
[[[x1,y1], [x2,y2], ... ,[xn,yn]], [...], ...]
|
|
42
|
+
"""
|
|
43
|
+
return self.__polygons
|
|
44
|
+
|
|
45
|
+
@polygons.setter
|
|
46
|
+
def polygons(self, new_polygons: Union[list, np.ndarray]):
|
|
47
|
+
"""
|
|
48
|
+
Sets the polygons to a new value.
|
|
49
|
+
|
|
50
|
+
Parameters
|
|
51
|
+
----------
|
|
52
|
+
new_polygons: Union[list, np.ndarray]
|
|
53
|
+
This is the polygons to set.
|
|
54
|
+
"""
|
|
55
|
+
self.__polygons = new_polygons
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def mask(self) -> np.ndarray:
|
|
59
|
+
"""
|
|
60
|
+
Attribute to access the segmentation mask of the image.
|
|
61
|
+
|
|
62
|
+
Returns
|
|
63
|
+
-------
|
|
64
|
+
np.ndarray
|
|
65
|
+
This contains the mask with the same dimensions as the image
|
|
66
|
+
providing an integer label per pixel to represent the mask.
|
|
67
|
+
"""
|
|
68
|
+
return self.__mask
|
|
69
|
+
|
|
70
|
+
@mask.setter
|
|
71
|
+
def mask(self, new_mask: np.ndarray):
|
|
72
|
+
"""
|
|
73
|
+
Sets the mask to a new value.
|
|
74
|
+
|
|
75
|
+
Parameters
|
|
76
|
+
----------
|
|
77
|
+
new_mask: np.ndarray
|
|
78
|
+
This is the mask to set.
|
|
79
|
+
"""
|
|
80
|
+
self.__mask = new_mask
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from edgefirst.validator.datasets.instance import Instance
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SegmentationInstance(Instance):
|
|
9
|
+
"""
|
|
10
|
+
Instance for storing segmentation properties from the
|
|
11
|
+
ground truth or model predictions.
|
|
12
|
+
|
|
13
|
+
Parameters
|
|
14
|
+
----------
|
|
15
|
+
image_path: str
|
|
16
|
+
The path to the image for Darknet datasets. Otherwise this is the
|
|
17
|
+
image name for TFRecord datasets. This is required either to
|
|
18
|
+
allow reading the image from file or saving the image results
|
|
19
|
+
in disk with the same file name.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, image_path: str):
|
|
23
|
+
super(SegmentationInstance, self).__init__(image_path)
|
|
24
|
+
|
|
25
|
+
# These are the unique integer labels in the segmentation mask.
|
|
26
|
+
self.__labels = np.array([])
|
|
27
|
+
# These contain the segmentation points to form the
|
|
28
|
+
# polygon shape around the object.
|
|
29
|
+
self.__polygons = np.array([])
|
|
30
|
+
# This is the segmentation mask for the image.
|
|
31
|
+
self.__mask = None
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def labels(self) -> Union[list, np.ndarray]:
|
|
35
|
+
"""
|
|
36
|
+
Attribute to access the labels per bounding box.
|
|
37
|
+
|
|
38
|
+
Returns
|
|
39
|
+
-------
|
|
40
|
+
Union[list, np.ndarray]
|
|
41
|
+
This contains the labels per bounding box.
|
|
42
|
+
"""
|
|
43
|
+
return self.__labels
|
|
44
|
+
|
|
45
|
+
@labels.setter
|
|
46
|
+
def labels(self, new_labels: Union[list, np.ndarray]):
|
|
47
|
+
"""
|
|
48
|
+
Sets the labels to a new value.
|
|
49
|
+
|
|
50
|
+
Parameters
|
|
51
|
+
----------
|
|
52
|
+
new_labels: Union[list, np.ndarray]
|
|
53
|
+
These are the labels to set.
|
|
54
|
+
"""
|
|
55
|
+
self.__labels = new_labels
|
|
56
|
+
|
|
57
|
+
def append_labels(self, label: Union[str, int, np.integer]):
|
|
58
|
+
"""
|
|
59
|
+
Appends list or appends NumPy array label.
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
label: Union[str, int, np.integer]
|
|
64
|
+
This is the label to append to the list.
|
|
65
|
+
"""
|
|
66
|
+
if isinstance(self.__labels, np.ndarray):
|
|
67
|
+
self.__labels = np.append(self.__labels, label)
|
|
68
|
+
else:
|
|
69
|
+
self.__labels.append(label)
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def polygons(self) -> Union[list, np.ndarray]:
|
|
73
|
+
"""
|
|
74
|
+
Attribute to access the 2D points that form the polygon to shape
|
|
75
|
+
around the object to form segmentation masks.
|
|
76
|
+
|
|
77
|
+
Returns
|
|
78
|
+
-------
|
|
79
|
+
Union[list, np.ndarray]
|
|
80
|
+
This contains the polygon points. Ex.
|
|
81
|
+
[[[x1,y1], [x2,y2], ... ,[xn,yn]], [...], ...]
|
|
82
|
+
"""
|
|
83
|
+
return self.__polygons
|
|
84
|
+
|
|
85
|
+
@polygons.setter
|
|
86
|
+
def polygons(self, new_polygons: Union[list, np.ndarray]):
|
|
87
|
+
"""
|
|
88
|
+
Sets the polygons to a new value.
|
|
89
|
+
|
|
90
|
+
Parameters
|
|
91
|
+
----------
|
|
92
|
+
new_polygons: Union[list, np.ndarray]
|
|
93
|
+
This is the polygons to set.
|
|
94
|
+
"""
|
|
95
|
+
self.__polygons = new_polygons
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def mask(self) -> np.ndarray:
|
|
99
|
+
"""
|
|
100
|
+
Attribute to access the segmentation mask of the image.
|
|
101
|
+
|
|
102
|
+
Returns
|
|
103
|
+
-------
|
|
104
|
+
np.ndarray
|
|
105
|
+
This contains the mask with the same dimensions as the image
|
|
106
|
+
providing an integer label per pixel to represent the mask.
|
|
107
|
+
"""
|
|
108
|
+
return self.__mask
|
|
109
|
+
|
|
110
|
+
@mask.setter
|
|
111
|
+
def mask(self, new_mask: np.ndarray):
|
|
112
|
+
"""
|
|
113
|
+
Sets the mask to a new value.
|
|
114
|
+
|
|
115
|
+
Parameters
|
|
116
|
+
----------
|
|
117
|
+
new_mask: np.ndarray
|
|
118
|
+
This is the mask to set.
|
|
119
|
+
"""
|
|
120
|
+
self.__mask = new_mask
|