Publishing 2019 R1 content
[platform/upstream/dldt.git] / tools / accuracy_checker / tests / test_postprocessor.py
1 """
2 Copyright (c) 2019 Intel Corporation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 """
16
17 import numpy as np
18 import pytest
19
20 from accuracy_checker.config import ConfigError
21 from accuracy_checker.postprocessor import PostprocessingExecutor
22
23 from accuracy_checker.representation import (
24     DetectionAnnotation,
25     DetectionPrediction,
26     ContainerAnnotation,
27     ContainerPrediction,
28     ClassificationAnnotation
29 )
30
31 from .common import make_representation, make_segmentation_representation
32
33
34 def postprocess_data(executor, annotations, predictions):
35     return executor.full_process(annotations, predictions)
36
37
38 class TestPostprocessor:
39     def test_without_apply_to_and_sources_filter_raise_config_error_exception(self):
40         config = [{'type': 'filter', 'labels': [1]}]
41
42         with pytest.raises(ConfigError):
43             PostprocessingExecutor(config)
44
45     def test_both_provided_apply_to_and_sources_filter_raise_config_error_exception(self):
46         config = [{
47             'type': 'filter',
48             'apply_to': 'prediction',
49             'annotation_source': 'annotation',
50             'labels': [1]
51         }]
52
53         with pytest.raises(ConfigError):
54             PostprocessingExecutor(config)
55
56     def test_filter_annotations_unsupported_source_type_in_container_raise_type_error_exception(self):
57         config = [{'type': 'filter', 'annotation_source': 'annotation', 'labels': [1]}]
58         annotation = ContainerAnnotation({'annotation': ClassificationAnnotation()})
59         executor = PostprocessingExecutor(config)
60
61         with pytest.raises(TypeError):
62             postprocess_data(executor, [annotation], [None])
63
64     def test_filter_annotations_source_not_found_raise_config_error_exception(self):
65         config = [{'type': 'filter', 'annotation_source': 'ann', 'labels': [1]}]
66         annotation = ContainerAnnotation({
67             'annotation': make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]
68         })
69         executor = PostprocessingExecutor(config)
70
71         with pytest.raises(ConfigError):
72             postprocess_data(executor, [annotation], [None])
73
74     def test_filter_predictions_unsupported_source_type_raise_type_error_exception(self):
75         config = [{
76             'type': 'filter',
77             'prediction_source': 'detection_out',
78             'labels': [1],
79             'remove_filtered': False
80         }]
81         prediction = ContainerPrediction({'detection_out': ClassificationAnnotation()})
82         executor = PostprocessingExecutor(config)
83
84         with pytest.raises(TypeError):
85             postprocess_data(executor, [None], [prediction])
86
87     def test_filter_predictions_source_not_found_raise_config_error_exception(self):
88         config = [{
89             'type': 'filter', 'prediction_source': 'undefined', 'labels': [1]
90         }]
91         prediction = ContainerPrediction({'detection_out': make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0]})
92         executor = PostprocessingExecutor(config)
93
94         with pytest.raises(ConfigError):
95             postprocess_data(executor, [None], [prediction])
96
97     def test_filter_container_annotations_by_labels_with_ignore_using_source(self):
98         config = [{
99             'type': 'filter', 'annotation_source': 'annotation', 'labels': [1], 'remove_filtered': False
100         }]
101         annotation = ContainerAnnotation({
102             'annotation':  make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]
103         })
104         expected = ContainerAnnotation({
105             'annotation': make_representation(
106                 '0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True, meta=[{'difficult_boxes': [1]}]
107             )[0]
108         })
109
110         postprocess_data(PostprocessingExecutor(config), [annotation], [None])
111
112         assert annotation == expected
113
114     def test_filter_container_annotations_by_labels_with_ignore_using_apply_to(self):
115         config = [{
116             'type': 'filter',
117             'apply_to': 'annotation',
118             'labels': [1],
119             'remove_filtered': False
120         }]
121         annotation = ContainerAnnotation({
122             'annotation': make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]
123         })
124         expected = ContainerAnnotation({
125             'annotation': make_representation(
126                 '0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True, meta=[{'difficult_boxes': [1]}]
127             )[0]
128         })
129
130         postprocess_data(PostprocessingExecutor(config), [annotation], [None])
131
132         assert annotation == expected
133
134     def test_filter_regular_annotations_by_labels_with_ignore(self):
135         config = [{'type': 'filter', 'apply_to': 'annotation', 'labels': [1], 'remove_filtered': False}]
136         annotation = make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]
137         expected = make_representation(
138                 '0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True, meta=[{'difficult_boxes': [1]}]
139             )[0]
140
141         postprocess_data(PostprocessingExecutor(config), [annotation], [None])
142
143         assert annotation == expected
144
145     def test_filter_multi_source_annotations_by_labels_with_ignore(self):
146         config = [{
147             'type': 'filter',
148             'annotation_source': ['annotation1', 'annotation2'],
149             'labels': [1],
150             'remove_filtered': False
151         }]
152         annotation = ContainerAnnotation({
153             'annotation1': make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0],
154             'annotation2': make_representation('1 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]
155         })
156         expected = ContainerAnnotation({
157             'annotation1': make_representation(
158                 '0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True, meta=[{'difficult_boxes': [1]}]
159             )[0],
160             'annotation2': make_representation(
161                 '1 0 0 10 10; 1 0 0 11 11', is_ground_truth=True, meta=[{'difficult_boxes': [0, 1]}]
162             )[0]
163         })
164
165         postprocess_data(PostprocessingExecutor(config), [annotation], [None])
166
167         assert annotation == expected
168
169     def test_filter_multi_source_annotations_by_labels_with_ignore_using_apply_to(self):
170         config = [{
171             'type': 'filter',
172             'apply_to': 'annotation',
173             'labels': [1],
174             'remove_filtered': False
175         }]
176         annotation = ContainerAnnotation({
177             'annotation1': make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0],
178             'annotation2': make_representation('1 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]
179         })
180         expected = ContainerAnnotation({
181             'annotation1': make_representation(
182                 '0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True, meta=[{'difficult_boxes': [1]}]
183             )[0],
184             'annotation2': make_representation(
185                 '1 0 0 10 10; 1 0 0 11 11', is_ground_truth=True, meta=[{'difficult_boxes': [0, 1]}]
186             )[0]
187         })
188         postprocess_data(PostprocessingExecutor(config), [annotation], [None])
189
190         assert annotation == expected
191
192     def test_filter_regular_annotations_by_labels_with_remove_using_annotation_source_warm_user_warning(self):
193         config = [{
194             'type': 'filter',
195             'annotation_source': 'annotation',
196             'labels': [1],
197             'remove_filtered': True
198         }]
199         annotation = make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]
200         expected = make_representation('0 0 0 10 10', is_ground_truth=True)[0]
201
202         with pytest.warns(UserWarning):
203             postprocess_data(PostprocessingExecutor(config), [annotation], [None])
204
205         assert annotation == expected
206
207     def test_filter_regular_annotations_by_labels_with_remove_using_apply_to(self):
208         config = [{'type': 'filter', 'apply_to': 'annotation', 'labels': [1], 'remove_filtered': True}]
209         annotation = make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]
210         expected = make_representation('0 0 0 10 10', is_ground_truth=True)[0]
211
212         postprocess_data(PostprocessingExecutor(config), [annotation], [None])
213
214         assert annotation == expected
215
216     def test_filter_annotations_by_labels_with_remove_on_container(self):
217         config = [{
218             'type': 'filter',
219             'annotation_source': 'annotation',
220             'labels': [1],
221             'remove_filtered': True
222         }]
223         annotation = ContainerAnnotation({
224             'annotation': make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]
225         })
226         expected = ContainerAnnotation({
227             'annotation': make_representation('0 0 0 10 10', is_ground_truth=True)[0]
228         })
229
230         postprocess_data(PostprocessingExecutor(config), [annotation], [None])
231
232         assert annotation == expected
233
234     def test_filter_annotations_by_labels_with_remove_on_container_using_apply_to(self):
235         config = [{'type': 'filter', 'apply_to': 'annotation', 'labels': [1], 'remove_filtered': True}]
236         annotation = ContainerAnnotation({
237             'annotation': make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]
238         })
239         expected = ContainerAnnotation({
240             'annotation': make_representation('0 0 0 10 10', is_ground_truth=True)[0]
241         })
242
243         postprocess_data(PostprocessingExecutor(config), [annotation], [None])
244
245         assert annotation == expected
246
247     def test_filter_multi_source_annotations_by_labels_with_remove(self):
248         config = [{
249             'type': 'filter',
250             'annotation_source': ['annotation1', 'annotation2'],
251             'labels': [1], 'remove_filtered': True
252         }]
253         annotation = ContainerAnnotation({
254             'annotation1': make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0],
255             'annotation2': make_representation('0 0 0 10 10', is_ground_truth=True)[0]
256         })
257         expected = ContainerAnnotation({
258             'annotation1': make_representation('0 0 0 10 10', is_ground_truth=True)[0],
259             'annotation2': make_representation('0 0 0 10 10', is_ground_truth=True)[0]
260         })
261
262         postprocess_data(PostprocessingExecutor(config), [annotation], [None])
263
264         assert annotation == expected
265
266     def test_filter_multi_source_by_labels_with_remove_on_container_using_apply_to(self):
267         config = [{'type': 'filter', 'apply_to': 'annotation', 'labels': [1], 'remove_filtered': True}]
268         annotation = ContainerAnnotation({
269             'annotation1': make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0],
270             'annotation2': make_representation('0 0 0 10 10', is_ground_truth=True)[0]
271         })
272         expected = ContainerAnnotation({
273             'annotation1': make_representation('0 0 0 10 10', is_ground_truth=True)[0],
274             'annotation2': make_representation('0 0 0 10 10', is_ground_truth=True)[0]
275         })
276
277         postprocess_data(PostprocessingExecutor(config), [annotation], [None])
278
279         assert annotation == expected
280
281     def test_filter_predictions_by_labels_with_ignore(self):
282         config = [{'type': 'filter', 'apply_to': 'prediction', 'labels': ['to_be_filtered'], 'remove_filtered': False}]
283         prediction = DetectionPrediction(labels=['some_label', 'to_be_filtered'])
284         expected = DetectionPrediction(labels=['some_label', 'to_be_filtered'], metadata={'difficult_boxes': [1]})
285
286         postprocess_data(PostprocessingExecutor(config), [None], [prediction])
287
288         assert prediction == expected
289
290     def test_filter_predictions_by_labels_with_ignore_on_container(self):
291         config = [{
292             'type': 'filter',
293             'prediction_source': 'detection_out',
294             'labels': [1],
295             'remove_filtered': False
296         }]
297         prediction = ContainerPrediction({
298             'detection_out': make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0]
299         })
300         expected = ContainerPrediction({'detection_out': make_representation(
301             '0 0 0 10 10; 1 0 0 11 11', score=1, meta=[{'difficult_boxes': [1]}]
302         )[0]})
303
304         postprocess_data(PostprocessingExecutor(config), [None], [prediction])
305
306         assert prediction == expected
307
308     def test_filter_predictions_by_labels_with_ignore_on_container_using_apply_to(self):
309         config = [{'type': 'filter', 'apply_to': 'prediction', 'labels': [1], 'remove_filtered': False}]
310         prediction = ContainerPrediction({
311             'detection_out': make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0]
312         })
313         expected = ContainerPrediction({'detection_out': make_representation(
314             '0 0 0 10 10; 1 0 0 11 11', score=1, meta=[{'difficult_boxes': [1]}]
315         )[0]})
316
317         postprocess_data(PostprocessingExecutor(config), [None], [prediction])
318
319         assert prediction == expected
320
321     def test_filter_multi_source_predictions_by_labels_with_ignore(self):
322         config = [{
323             'type': 'filter', 'prediction_source': ['detection_out1', 'detection_out2'], 'labels': [1],
324             'remove_filtered': False
325         }]
326         prediction = ContainerPrediction({
327             'detection_out1': make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0],
328             'detection_out2': make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0]
329         })
330         expected = ContainerPrediction({
331             'detection_out1': make_representation(
332                 '0 0 0 10 10; 1 0 0 11 11', score=1, meta=[{'difficult_boxes': [1]}]
333             )[0],
334             'detection_out2': make_representation(
335                 '0 0 0 10 10; 1 0 0 11 11', score=1, meta=[{'difficult_boxes': [1]}]
336             )[0]
337         })
338
339         postprocess_data(PostprocessingExecutor(config), [None], [prediction])
340
341         assert prediction == expected
342
343     def test_filter_multi_source_predictions_by_labels_with_ignore_using_apply_to(self):
344         config = [{
345             'type': 'filter', 'apply_to': 'prediction', 'labels': [1], 'remove_filtered': False
346         }]
347         prediction = ContainerPrediction({
348             'detection_out1': make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0],
349             'detection_out2': make_representation('1 0 0 10 10; 1 0 0 11 11', score=1)[0]
350         })
351         expected = ContainerPrediction({
352             'detection_out1': make_representation(
353                 '0 0 0 10 10; 1 0 0 11 11', score=1, meta=[{'difficult_boxes': [1]}]
354             )[0],
355             'detection_out2': make_representation(
356                 '1 0 0 10 10; 1 0 0 11 11', score=1, meta=[{'difficult_boxes': [0, 1]}]
357             )[0]
358         })
359
360         postprocess_data(PostprocessingExecutor(config), [None], [prediction])
361
362         assert prediction == expected
363
364     def test_filter_predictions_by_labels_with_remove(self):
365         config = [{'type': 'filter', 'apply_to': 'prediction', 'labels': [1], 'remove_filtered': True}]
366         prediction = make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)
367         expected = make_representation('0 0 0 10 10', score=1)
368
369         postprocess_data(PostprocessingExecutor(config), [None], prediction)
370
371         assert prediction == expected
372
373     def test_filter_predictions_by_labels_with_remove_on_container(self):
374         config = [{
375             'type': 'filter', 'prediction_source': 'detection_out', 'labels': [0], 'remove_filtered': True
376         }]
377         prediction = ContainerPrediction({
378             'detection_out': make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0]
379         })
380         expected = ContainerPrediction({'detection_out':  make_representation('1 0 0 11 11', score=1)[0]})
381
382         postprocess_data(PostprocessingExecutor(config), [None], [prediction])
383
384         assert prediction == expected
385
386     def test_filter_predictions_by_labels_with_remove_on_container_using_apply_to(self):
387         config = [{'type': 'filter', 'apply_to': 'prediction', 'labels': [0], 'remove_filtered': True}]
388         prediction = ContainerPrediction({
389             'detection_out': make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0]
390         })
391         expected = ContainerPrediction({'detection_out': make_representation('1 0 0 11 11', score=1)[0]})
392
393         postprocess_data(PostprocessingExecutor(config), [None], [prediction])
394
395         assert prediction == expected
396
397     def test_filter_multi_source_predictions_by_labels_with_remove(self):
398         config = [{
399             'type': 'filter',
400             'prediction_source': ['detection_out1', 'detection_out2'],
401             'labels': [1],
402             'remove_filtered': True
403         }]
404         prediction = ContainerPrediction({
405             'detection_out1': make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0],
406             'detection_out2': make_representation('0 0 0 10 10', score=1)[0]
407         })
408         expected = ContainerPrediction({
409             'detection_out1': make_representation('0 0 0 10 10', score=1)[0],
410             'detection_out2': make_representation('0 0 0 10 10', score=1)[0]
411         })
412
413         postprocess_data(PostprocessingExecutor(config), [None], [prediction])
414
415         assert prediction == expected
416
417     def test_filter_multi_source_predictions_by_labels_with_remove_using_apply_to(self):
418         config = [{'type': 'filter', 'apply_to': 'prediction', 'labels': [1], 'remove_filtered': True}]
419         prediction = ContainerPrediction({
420             'detection_out1': make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0],
421             'detection_out2': make_representation('0 0 0 10 10', score=1)[0]
422         })
423         expected = ContainerPrediction({
424             'detection_out1': make_representation('0 0 0 10 10', score=1)[0],
425             'detection_out2': make_representation('0 0 0 10 10', score=1)[0]
426         })
427
428         postprocess_data(PostprocessingExecutor(config), [None], [prediction])
429
430         assert prediction == expected
431
432     def test_filter_regular_annotations_and_regular_predictions_by_labels_with_ignore_using_apply_to(self):
433         config = [{'type': 'filter', 'apply_to': 'all', 'labels': [1], 'remove_filtered': False}]
434         prediction = make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0]
435         expected_prediction = make_representation(
436             '0 0 0 10 10; 1 0 0 11 11', score=1, meta=[{'difficult_boxes': [1]}]
437         )[0]
438         annotation = make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]
439         expected_annotation = make_representation(
440             '0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True, meta=[{'difficult_boxes': [1]}]
441         )[0]
442
443         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
444
445         assert prediction == expected_prediction and annotation == expected_annotation
446
447     def test_filter_regular_annotations_and_regular_predictions_by_labels_with_remove_using_apply_to(self):
448         config = [{'type': 'filter', 'apply_to': 'all', 'labels': [1], 'remove_filtered': True}]
449         prediction = make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)
450         expected_prediction = make_representation('0 0 0 10 10', score=1)
451         annotation = make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)
452         expected_annotation = make_representation('0 0 0 10 10', is_ground_truth=True)
453
454         postprocess_data(PostprocessingExecutor(config), annotation, prediction)
455
456         assert prediction == expected_prediction and annotation == expected_annotation
457
458     def test_filter_container_annotations_and_regular_predictions_by_labels_with_ignore_using_apply_to(self):
459         config = [{'type': 'filter', 'apply_to': 'all', 'labels': [1], 'remove_filtered': False}]
460         prediction = make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0]
461         expected_prediction = make_representation(
462             '0 0 0 10 10; 1 0 0 11 11', score=1, meta=[{'difficult_boxes': [1]}]
463         )[0]
464         annotation = make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]
465         expected_annotation = make_representation(
466             '0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True, meta=[{'difficult_boxes': [1]}]
467         )[0]
468
469         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
470
471         assert prediction == expected_prediction and annotation == expected_annotation
472
473     def test_filter_container_annotations_and_regular_predictions_by_labels_with_remove_using_apply_to(self):
474         config = [{'type': 'filter', 'apply_to': 'all', 'labels': [1], 'remove_filtered': True}]
475         prediction = make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0]
476         expected_prediction = make_representation('0 0 0 10 10', score=1)[0]
477         annotation = ContainerAnnotation({
478             'annotation': make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]
479         })
480         expected_annotation = ContainerAnnotation({
481             'annotation': make_representation('0 0 0 10 10', is_ground_truth=True)[0]
482         })
483
484         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
485
486         assert prediction == expected_prediction and annotation == expected_annotation
487
488     def test_filter_regular_annotations_and_container_predictions_by_labels_with_ignore_using_apply_to(self):
489         config = [{'type': 'filter', 'apply_to': 'all', 'labels': [1], 'remove_filtered': False}]
490         prediction = ContainerPrediction({
491             'detection_out': make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0]
492         })
493         expected_prediction = ContainerPrediction({
494             'detection_out': make_representation(
495                 '0 0 0 10 10; 1 0 0 11 11', score=1, meta=[{'difficult_boxes': [1]}]
496             )[0]
497         })
498         annotation = make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]
499         expected_annotation = make_representation(
500             '0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True, meta=[{'difficult_boxes': [1]}]
501         )[0]
502
503         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
504
505         assert prediction == expected_prediction and annotation == expected_annotation
506
507     def test_filter_regular_annotations_and_container_predictions_by_labels_with_remove_using_apply_to(self):
508         config = [{'type': 'filter', 'apply_to': 'all', 'labels': [1], 'remove_filtered': True}]
509         prediction = ContainerPrediction({
510             'detection_out': make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0]
511         })
512         expected_prediction = ContainerPrediction({'detection_out': make_representation('0 0 0 10 10', score=1)[0]})
513         annotation = make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]
514         expected_annotation = make_representation('0 0 0 10 10', is_ground_truth=True)[0]
515
516         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
517
518         assert prediction == expected_prediction and annotation == expected_annotation
519
520     def test_filter_container_annotations_and_container_predictions_by_labels_with_ignore_using_apply_to(self):
521         config = [{'type': 'filter', 'apply_to': 'all', 'labels': [1], 'remove_filtered': False}]
522         prediction = ContainerPrediction({
523             'detection_out': make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0]
524         })
525         expected_prediction = ContainerPrediction({
526             'detection_out': make_representation(
527                 '0 0 0 10 10; 1 0 0 11 11', score=1, meta=[{'difficult_boxes': [1]}]
528             )[0]
529         })
530         annotation = make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]
531         expected_annotation = make_representation(
532             '0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True, meta=[{'difficult_boxes': [1]}]
533         )[0]
534
535         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
536
537         assert prediction == expected_prediction and annotation == expected_annotation
538
539     def test_filter_container_annotations_and_container_predictions_by_labels_with_remove_using_apply_to(self):
540         config = [{'type': 'filter', 'apply_to': 'all', 'labels': [1], 'remove_filtered': True}]
541         prediction = ContainerPrediction({
542             'prediction': make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0]
543         })
544         expected_prediction = ContainerPrediction({'prediction': make_representation('0 0 0 10 10', score=1)[0]})
545         annotation = ContainerAnnotation({
546             'annotation': make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]
547         })
548         expected_annotation = ContainerAnnotation({
549             'annotation': make_representation('0 0 0 10 10', is_ground_truth=True)[0]
550         })
551
552         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
553
554         assert prediction == expected_prediction and annotation == expected_annotation
555
556     def test_filter_container_annotations_and_container_predictions_by_labels_with_ignore_using_sources(self):
557         config = [{'type': 'filter', 'apply_to': 'all', 'labels': [1], 'remove_filtered': False}]
558         prediction = ContainerPrediction({'prediction': make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0]})
559         expected_prediction = ContainerPrediction({
560             'prediction': make_representation('0 0 0 10 10; 1 0 0 11 11', score=1, meta=[{'difficult_boxes': [1]}])[0]
561         })
562         annotation = ContainerAnnotation({
563             'annotation': make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]
564         })
565         expected_annotation = ContainerAnnotation({
566             'annotation': make_representation(
567                 '0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True, meta=[{'difficult_boxes': [1]}]
568             )[0]
569         })
570
571         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
572
573         assert prediction == expected_prediction and annotation == expected_annotation
574
575     def test_filter_container_annotations_and_container_predictions_by_labels_with_remove_using_sources(self):
576         config = [{'type': 'filter', 'annotation_source': 'annotation', 'prediction_source': 'prediction',
577                    'labels': [1], 'remove_filtered': True}]
578         prediction = ContainerPrediction({'prediction': make_representation('0 0 0 10 10; 1 0 0 11 11', score=1)[0]})
579         expected_prediction = ContainerPrediction({'prediction': make_representation('0 0 0 10 10', score=1)[0]})
580         annotation = ContainerAnnotation(
581             {'annotation': make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)[0]})
582         expected_annotation = ContainerAnnotation(
583             {'annotation': make_representation('0 0 0 10 10', is_ground_truth=True)[0]})
584
585         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
586
587         assert prediction == expected_prediction and annotation == expected_annotation
588
589     def test_filter_annotations_by_min_confidence_do_nothing(self):
590         config = [{'type': 'filter', 'apply_to': 'annotation', 'min_confidence': 0.5, 'remove_filtered': True}]
591         annotations = make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)
592         expected_annotations = make_representation('0 0 0 10 10; 1 0 0 11 11', is_ground_truth=True)
593
594         postprocess_data(PostprocessingExecutor(config), annotations, [None])
595
596         assert np.array_equal(annotations, expected_annotations)
597
598     def test_filter_predictions_by_min_confidence_with_ignore(self):
599         config = [{'type': 'filter', 'apply_to': 'prediction', 'min_confidence': 0.5, 'remove_filtered': False}]
600         predictions = [
601             make_representation('0 0 0 10 10; 1 0 0 11 11', score=[0.3, 0.8])[0],
602             make_representation('0 0 0 10 10; 1 0 0 11 11', score=[0.5, 0.4])[0]
603         ]
604         expected_predictions = [
605             make_representation('0 0 0 10 10; 1 0 0 11 11', score=[0.3, 0.8], meta=[{'difficult_boxes': [0]}])[0],
606             make_representation('0 0 0 10 10; 1 0 0 11 11', score=[0.5, 0.4], meta=[{'difficult_boxes': [1]}])[0]
607         ]
608
609         executor = PostprocessingExecutor(config)
610         postprocess_data(executor, [None, None], predictions)
611
612         assert np.array_equal(predictions, expected_predictions)
613
614     def test_filter_predictions_by_min_confidence_with_remove(self):
615         config = [{'type': 'filter', 'apply_to': 'prediction', 'min_confidence': 0.5, 'remove_filtered': True}]
616         predictions = [
617             make_representation('0 0 0 10 10; 1 0 0 11 11', score=[0.3, 0.8])[0],
618             make_representation('0 0 0 10 10; 1 0 0 11 11', score=[0.5, 0.4])[0]
619         ]
620         expected_predictions = [
621             make_representation('1 0 0 11 11', score=0.8)[0],
622             make_representation('0 0 0 10 10', score=0.5)[0]
623         ]
624
625         postprocess_data(PostprocessingExecutor(config), [None, None], predictions)
626
627         assert np.array_equal(predictions, expected_predictions)
628
629     def test_filter_annotations_by_height_range_with_ignored(self):
630         config = [{
631             'type': 'filter',
632             'apply_to': 'annotation',
633             'height_range': '(10.0, 20.0)',
634             'remove_filtered': False
635         }]
636         annotations = [
637             make_representation('0 0 5 0 15; 1 0 10 0 15', is_ground_truth=True)[0],
638             make_representation('0 0 5 0 35; 1 0 10 0 40', is_ground_truth=True)[0]
639         ]
640         expected = [
641             make_representation('0 0 5 0 15; 1 0 10 0 15', is_ground_truth=True, meta=[{'difficult_boxes': [1]}])[0],
642             make_representation('0 0 5 0 35; 1 0 10 0 40', is_ground_truth=True, meta=[{'difficult_boxes': [0, 1]}])[0]
643         ]
644
645         postprocess_data(PostprocessingExecutor(config), annotations, [None, None])
646
647         assert np.array_equal(annotations, expected)
648
649     def test_filter_annotations_by_height_range_with_remove(self):
650         config = [{'type': 'filter', 'apply_to': 'annotation', 'height_range': '(10.0, 20.0)', 'remove_filtered': True}]
651         annotations = [
652             make_representation('0 0 5 0 15; 1 0 10 0 15', is_ground_truth=True)[0],
653             make_representation('0 0 5 0 35; 1 0 10 0 40', is_ground_truth=True)[0]
654         ]
655         expected = [
656             make_representation('0 0 5 0 15', is_ground_truth=True)[0],
657             make_representation('', is_ground_truth=True)[0]
658         ]
659
660         postprocess_data(PostprocessingExecutor(config), annotations, [None, None])
661
662         assert np.array_equal(annotations, expected)
663
664     def test_filter_predictions_by_height_range_with_ignored(self):
665         config = [{
666             'type': 'filter',
667             'apply_to': 'prediction',
668             'height_range': '(10.0, 20.0)',
669             'remove_filtered': False
670         }]
671         predictions = [
672             make_representation('0 0 5 0 15; 1 0 10 0 15', score=1)[0],
673             make_representation('0 0 5 0 35; 1 0 10 0 40', score=1)[0]
674         ]
675         expected = [
676             make_representation('0 0 5 0 15; 1 0 10 0 15', score=1, meta=[{'difficult_boxes': [1]}])[0],
677             make_representation('0 0 5 0 35; 1 0 10 0 40', score=1, meta=[{'difficult_boxes': [0, 1]}])[0]
678         ]
679
680         postprocess_data(PostprocessingExecutor(config), [None, None], predictions)
681
682         assert np.array_equal(predictions, expected)
683
684     def test_filter_predictions_by_height_range_with_remove(self):
685         config = [{'type': 'filter', 'apply_to': 'prediction', 'height_range': '(10.0, 20.0)', 'remove_filtered': True}]
686         predictions = [
687             make_representation('0 0 5 0 15; 1 0 10 0 15', score=1)[0],
688             make_representation('0 0 5 0 35; 1 0 10 0 40', score=1)[0]
689         ]
690         expected = [
691             make_representation('0 0 5 0 15', score=1)[0],
692             make_representation('', score=1)[0]
693         ]
694
695         postprocess_data(PostprocessingExecutor(config), [None, None], predictions)
696
697         assert np.array_equal(predictions, expected)
698
699     def test_filter_predictions_by_unknown_min_visibility_raises_value_error_exception(self):
700         config = [{'type': 'filter', 'apply_to': 'prediction', 'min_visibility': 'unknown'}]
701         predictions = [
702            make_representation('0 0 5 0 15; 1 0 10 0 15', score=1)[0],
703            make_representation('0 0 5 0 35; 1 0 10 0 40', score=1)[0]
704         ]
705
706         with pytest.raises(ValueError):
707             postprocess_data(PostprocessingExecutor(config), [None], predictions)
708
709     def test_filter_annotations_by_unknown_min_visibility_raises_value_error_exception(self):
710         config = [{'type': 'filter', 'apply_to': 'annotation', 'min_visibility': 'unknown'}]
711         annotations = [DetectionPrediction(y_mins=[5.0, 10.0], y_maxs=[15.0, 40.0])]
712
713         with pytest.raises(ValueError):
714             postprocess_data(PostprocessingExecutor(config), annotations, [None])
715
716     def test_filter_predictions_by_visibility_raises_value_error_with_unknown_visibility(self):
717         config = [{'type': 'filter', 'apply_to': 'prediction', 'min_visibility': 'heavy occluded'}]
718         predictions = [DetectionPrediction(
719             y_mins=[5.0, 10.0], y_maxs=[15.0, 40.0], metadata={'visibilities': ['unknown']}
720         )]
721
722         with pytest.raises(ValueError):
723             postprocess_data(PostprocessingExecutor(config), [None], predictions)
724
725     def test_filter_annotations_by_visibility_raises_value_error_with_unknown_visibility(self):
726         config = [{'type': 'filter', 'apply_to': 'annotation', 'min_visibility': 'heavy occluded'}]
727         annotations = [DetectionAnnotation(
728             y_mins=[5.0, 10.0], y_maxs=[15.0, 40.0], metadata={'visibilities': ['unknown']}
729         )]
730
731         with pytest.raises(ValueError):
732             postprocess_data(PostprocessingExecutor(config), annotations, [None])
733
734     def test_filter_by_visibility_does_nothing_with_annotations_without_visibility(self):
735         config = [{'type': 'filter', 'apply_to': 'annotation', 'min_visibility': 'heavy occluded'}]
736         annotations = [
737             make_representation('0 0 5 0 15; 1 0 10 0 15', is_ground_truth=True)[0],
738             make_representation('0 0 5 0 35; 1 0 10 0 40', is_ground_truth=True)[0]
739         ]
740         expected = [
741             make_representation('0 0 5 0 15; 1 0 10 0 15', is_ground_truth=True, meta=[{'difficult_boxes': []}])[0],
742             make_representation('0 0 5 0 35; 1 0 10 0 40', is_ground_truth=True, meta=[{'difficult_boxes': []}])[0]
743         ]
744
745         postprocess_data(PostprocessingExecutor(config), annotations, [None, None])
746
747         assert np.array_equal(annotations, expected)
748
749     def test_filter_by_visibility_does_nothing_with_predictions_without_visibility(self):
750         config = [{'type': 'filter', 'apply_to': 'prediction', 'min_visibility': 'heavy occluded'}]
751         predictions = [
752             DetectionPrediction(y_mins=[5.0, 10.0], y_maxs=[15.0, 40.0]),
753             DetectionPrediction(y_mins=[5.0, 10.0], y_maxs=[35.0, 50.0])
754         ]
755         expected = [
756             DetectionPrediction(y_mins=[5.0, 10.0], y_maxs=[15.0, 40.0], metadata={'difficult_boxes': []}),
757             DetectionPrediction(y_mins=[5.0, 10.0], y_maxs=[35.0, 50.0], metadata={'difficult_boxes': []})
758         ]
759
760         postprocess_data(PostprocessingExecutor(config), [None, None], predictions)
761
762         assert np.array_equal(predictions, expected)
763
764     def test_filter_by_visibility_does_nothing_with_default_visibility_level_and_heavy_occluded(self):
765         config = [{'type': 'filter', 'apply_to': 'annotation', 'min_visibility': 'heavy occluded'}]
766         annotation = make_representation('0 0 5 0 15; 1 0 10 0 15', is_ground_truth=True)[0]
767         expected = make_representation(
768             '0 0 5 0 15; 1 0 10 0 15', is_ground_truth=True, meta=[{'difficult_boxes': []}]
769         )[0]
770
771         postprocess_data(PostprocessingExecutor(config), [annotation], [None])
772
773         assert annotation == expected
774
775     def test_filter_by_visibility_does_nothing_with_default_visibility_level_and_partially_occluded(self):
776         config = [{'type': 'filter', 'apply_to': 'annotation', 'min_visibility': 'partially occluded'}]
777         annotation = make_representation('0 0 5 0 15; 1 0 10 0 15', is_ground_truth=True)[0]
778         expected = make_representation(
779             '0 0 5 0 15; 1 0 10 0 15', is_ground_truth=True, meta=[{'difficult_boxes': []}]
780         )[0]
781
782         postprocess_data(PostprocessingExecutor(config), [annotation], [None])
783
784         assert annotation == expected
785
786     def test_filter_by_visibility_filters_partially_occluded_remove_filtered(self):
787         config = [{'type': 'filter', 'apply_to': 'annotation', 'min_visibility': 'partially occluded',
788                    'remove_filtered': True}]
789         annotation = make_representation(
790             '0 0 5 0 15; 1 0 10 0 15', is_ground_truth=True,
791             meta=[{'visibilities': ['heavy occluded', 'partially occluded']}]
792         )[0]
793         expected = make_representation(
794             '1 0 10 0 15', is_ground_truth=True, meta=[{'visibilities': ['heavy occluded', 'partially occluded']}]
795         )[0]
796
797         postprocess_data(PostprocessingExecutor(config), [annotation], [None])
798
799         assert annotation == expected
800
801     def test_nms(self, mocker):
802         mock = mocker.patch('accuracy_checker.postprocessor.nms.NMS.process_all', return_value=([], []))
803         config = [{'type': 'nms', 'overlap': 0.4}]
804         postprocess_data(PostprocessingExecutor(config), [], [])
805         mock.assert_called_once_with([], [])
806
807     def test_resize_prediction_boxes(self):
808         config = [{'type': 'resize_prediction_boxes'}]
809         annotation = DetectionAnnotation(metadata={'image_size': [(100, 100, 3)]})
810         prediction = make_representation('0 0 0 5 5; 1 7 7 8 8', score=1)[0]
811         expected = make_representation('0 0 0 500 500; 1 700 700 800 800', score=1)[0]
812
813         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
814
815         assert prediction == expected
816
817     def test_clip_annotation_denormalized_boxes(self):
818         config = [{'type': 'clip_boxes', 'apply_to': 'annotation', 'boxes_normalized': False}]
819         meta = {'image_size': [(10, 10, 3)]}
820         annotation = make_representation('0 -1 0 5 5; 1 9 11 10 10', is_ground_truth=True, meta=[meta])[0]
821         expected = make_representation('0 0 0 5 5; 1 9 10 10 10', is_ground_truth=True, meta=[meta])[0]
822
823         postprocess_data(PostprocessingExecutor(config), [annotation], [None])
824
825         assert annotation == expected
826
827     def test_clip_annotation_normalized_boxes(self):
828         config = [{'type': 'clip_boxes', 'apply_to': 'annotation', 'boxes_normalized': True}]
829         meta = {'image_size': [(10, 10, 3)]}
830         annotation = make_representation('0 -1 0 5 5; 1 9 11 10 10', is_ground_truth=True, meta=[meta])[0]
831         expected = make_representation('0 0 0 1 1; 1 1 1 1 1', is_ground_truth=True, meta=[meta])[0]
832
833         postprocess_data(PostprocessingExecutor(config), [annotation], [None])
834
835         assert annotation == expected
836
837     def test_clip_annotation_denormalized_boxes_with_size(self):
838         config = [{'type': 'clip_boxes', 'apply_to': 'annotation', 'boxes_normalized': False, 'size': 10}]
839         meta = {'image_size': [(10, 10, 3)]}
840         annotation = make_representation('0 -1 0 5 5; 1 9 11 10 10', is_ground_truth=True, meta=[meta])[0]
841         expected = make_representation('0 0 0 5 5; 1 9 10 10 10', is_ground_truth=True, meta=[meta])[0]
842
843         postprocess_data(PostprocessingExecutor(config), [annotation], [None])
844
845         assert annotation == expected
846
847     def test_clip_annotation_normalized_boxes_with_size_as_normalized(self):
848         config = [{'type': 'clip_boxes', 'apply_to': 'annotation', 'boxes_normalized': True, 'size': 10}]
849         meta = {'image_size': [(10, 10, 3)]}
850         annotation = make_representation('0 -1 0 5 5; 1 9 11 10 10', is_ground_truth=True, meta=[meta])[0]
851         expected = make_representation('0 0 0 1 1; 1 1 1 1 1', is_ground_truth=True, meta=[meta])[0]
852
853         postprocess_data(PostprocessingExecutor(config), [annotation], [None])
854
855         assert annotation == expected
856
857     def test_clip_prediction_denormalized_boxes(self):
858         config = [{'type': 'clip_boxes', 'apply_to': 'prediction', 'boxes_normalized': False}]
859         annotation = DetectionAnnotation(metadata={'image_size': [(10, 10, 3)]})
860         prediction = make_representation('0 -1 0 5 5; 1 9 11 10 10', score=1)[0]
861         expected = make_representation('0 0 0 5 5; 1 9 10 10 10', score=1)[0]
862
863         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
864
865         assert prediction == expected
866
867     def test_clip_prediction_normalized_boxes(self):
868         config = [{'type': 'clip_boxes', 'apply_to': 'prediction', 'boxes_normalized': True}]
869         annotation = DetectionAnnotation(metadata={'image_size': [(10, 10, 3)]})
870         prediction = make_representation('0 -1 0 5 5; 1 9 11 10 10', score=1)[0]
871         expected = make_representation('0 0 0 1 1; 1 1 1 1 1', score=1)[0]
872         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
873
874         assert prediction == expected
875
876     def test_clip_predictions_denormalized_boxes_with_size(self):
877         config = [{'type': 'clip_boxes', 'apply_to': 'prediction', 'boxes_normalized': False, 'size': 10}]
878         annotation = DetectionAnnotation(metadata={'image_size': [(10, 10, 3)]})
879         prediction = make_representation('0 -1 0 5 5; 1 9 11 10 10', score=1)[0]
880         expected = make_representation('0 0 0 5 5; 1 9 10 10 10', score=1)[0]
881
882         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
883
884         assert prediction == expected
885
886     def test_clip_predictions_normalized_boxes_with_size_as_normalized(self):
887         config = [{'type': 'clip_boxes', 'apply_to': 'prediction', 'boxes_normalized': True, 'size': 10}]
888         annotation = DetectionAnnotation(metadata={'image_size': [(10, 10, 3)]})
889         prediction = make_representation('0 -1 0 5 5; 1 9 11 10 10', score=1)[0]
890         expected = make_representation('0 0 0 1 1; 1 1 1 1 1', score=1)[0]
891
892         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
893
894         assert prediction == expected
895
896     def test_cast_to_int_default(self):
897         config = [{'type': 'cast_to_int'}]
898         annotation = make_representation('0 -1 0 5 5; 1 9 11 10 10', is_ground_truth=True)[0]
899         prediction = make_representation('0 -1.1 0.5 5.9 5.1; 1 -9.9 11.5 10.9 10.1', score=1)[0]
900         expected_annotation = make_representation('0 -1 0 5 5; 1 9 11 10 10', is_ground_truth=True)[0]
901         expected_prediction = make_representation('0 -1 0 6 5; 1 -10 12 11 10', score=1)[0]
902
903         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
904
905         assert prediction == expected_prediction and annotation == expected_annotation
906
907     def test_cast_to_int_to_nearest(self):
908         config = [{'type': 'cast_to_int', 'round_policy': 'nearest'}]
909         annotation = make_representation('0 -1 0 5 5; 1 9 11 10 10', is_ground_truth=True)[0]
910         prediction = make_representation('0 -1.1 0.5 5.9 5.1; 1 -9.9 11.5 10.9 10.1', score=1)[0]
911         expected_annotation = make_representation('0 -1 0 5 5; 1 9 11 10 10', is_ground_truth=True)[0]
912         expected_prediction = make_representation('0 -1 0 6 5; 1 -10 12 11 10', score=1)[0]
913
914         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
915
916         assert prediction == expected_prediction and annotation == expected_annotation
917
918     def test_cast_to_int_to_nearest_to_zero(self):
919         config = [{'type': 'cast_to_int', 'round_policy': 'nearest_to_zero'}]
920         annotation = make_representation('0 -1 0 5 5; 1 9 11 10 10', is_ground_truth=True)[0]
921         prediction = make_representation('0 -1.1 0.5 5.9 5.1; 1 -9.9 11.5 10.9 10.1', score=1)[0]
922         expected_annotation = make_representation('0 -1 0 5 5; 1 9 11 10 10', is_ground_truth=True)[0]
923         expected_prediction = make_representation('0 -1 0 5 5; 1 -9 11 10 10', score=1)[0]
924
925         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
926
927         assert prediction == expected_prediction and annotation == expected_annotation
928
929     def test_cast_to_int_to_lower(self):
930         config = [{'type': 'cast_to_int', 'round_policy': 'lower'}]
931         annotation = make_representation('0 -1 0 5 5; 1 9 11 10 10', is_ground_truth=True)[0]
932         prediction = make_representation('0 -1.1 0.5 5.9 5.1; 1 -9.9 11.5 10.9 10.1', score=1)[0]
933         expected_annotation = make_representation('0 -1 0 5 5; 1 9 11 10 10', is_ground_truth=True)[0]
934         expected_prediction = make_representation('0 -2 0 5 5; 1 -10 11 10 10', score=1)[0]
935
936         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
937
938         assert prediction == expected_prediction and annotation == expected_annotation
939
940     def test_cast_to_int_to_greater(self):
941         config = [{'type': 'cast_to_int', 'round_policy': 'greater'}]
942         annotation = make_representation('0 -1 0 5 5; 1 9 11 10 10', is_ground_truth=True)[0]
943         prediction = make_representation('0 -1.1 0.5 5.9 5.1; 1 -9.9 11.5 10.9 10.1', score=1)[0]
944         expected_annotation = make_representation('0 -1 0 5 5; 1 9 11 10 10', is_ground_truth=True)[0]
945         expected_prediction = make_representation('0 -1 1 6 6; 1 -9 12 11 11', score=1)[0]
946
947         postprocess_data(PostprocessingExecutor(config), [annotation], [prediction])
948
949         assert prediction == expected_prediction and annotation == expected_annotation
950
951     def test_cast_to_int_to_unknown_raise_config_error(self):
952         config = [{'type': 'cast_to_int', 'round_policy': 'unknown'}]
953
954         with pytest.raises(ConfigError):
955             postprocess_data(PostprocessingExecutor(config), [None], [None])
956
957     def test_extend_segmentation_mask_with_float_filling_raise_config_error(self):
958         config = [{'type': 'extend_segmentation_mask', 'filling_label':  0.5}]
959
960         with pytest.raises(ConfigError):
961             postprocess_data(PostprocessingExecutor(config), [None], [None])
962
963     def test_extend_segmentation_mask_default(self):
964         config = [{'type': 'extend_segmentation_mask'}]
965         annotation = make_segmentation_representation(np.zeros((5, 5)), ground_truth=True)
966         prediction = make_segmentation_representation(np.zeros((7, 7)), ground_truth=False)
967         expected_annotation_mask = np.zeros((7, 7))
968         expected_annotation_mask[0, :] = 255
969         expected_annotation_mask[:, 0] = 255
970         expected_annotation_mask[-1, :] = 255
971         expected_annotation_mask[:, -1] = 255
972         expected_prediction_mask = np.zeros((7, 7))
973         postprocess_data(PostprocessingExecutor(config), annotation, prediction)
974         assert np.array_equal(prediction[0].mask, expected_prediction_mask)
975         assert np.array_equal(annotation[0].mask, expected_annotation_mask)
976
977     def test_extend_segmentation_mask_do_nothing(self):
978         config = [{'type': 'extend_segmentation_mask'}]
979         annotation = make_segmentation_representation(np.zeros((5, 5)), ground_truth=True)
980         prediction = make_segmentation_representation(np.zeros((5, 5)), ground_truth=False)
981         expected_mask = np.zeros((5, 5))
982         postprocess_data(PostprocessingExecutor(config), annotation, prediction)
983         assert np.array_equal(prediction[0].mask, expected_mask)
984         assert np.array_equal(annotation[0].mask, expected_mask)
985
986     def test_extend_segmentation_mask_asymmetrical(self):
987         config = [{'type': 'extend_segmentation_mask'}]
988         annotation = make_segmentation_representation(np.zeros((5, 5)), ground_truth=True)
989         prediction = make_segmentation_representation(np.zeros((6, 7)), ground_truth=False)
990         expected_annotation_mask = np.zeros((6, 7))
991         expected_annotation_mask[:, 0] = 255
992         expected_annotation_mask[-1, :] = 255
993         expected_annotation_mask[:, -1] = 255
994         expected_prediction_mask = np.zeros((6, 7))
995         postprocess_data(PostprocessingExecutor(config), annotation, prediction)
996         assert np.array_equal(prediction[0].mask, expected_prediction_mask)
997         assert np.array_equal(annotation[0].mask, expected_annotation_mask)
998
999     def test_extend_segmentation_mask_raise_config_error_if_prediction_less_annotation(self):
1000         config = [{'type': 'extend_segmentation_mask'}]
1001         annotation = make_segmentation_representation(np.zeros((5, 5)), ground_truth=True)
1002         prediction = make_segmentation_representation(np.zeros((4, 4)), ground_truth=False)
1003         with pytest.raises(ConfigError):
1004             postprocess_data(PostprocessingExecutor(config), annotation, prediction)
1005
1006     def test_extend_segmentation_mask_with_filling_label(self):
1007         config = [{'type': 'extend_segmentation_mask', 'filling_label': 1}]
1008         annotation = make_segmentation_representation(np.zeros((5, 5)), ground_truth=True)
1009         prediction = make_segmentation_representation(np.zeros((7, 7)), ground_truth=False)
1010         expected_annotation_mask = np.zeros((7, 7))
1011         expected_annotation_mask[0, :] = 1
1012         expected_annotation_mask[:, 0] = 1
1013         expected_annotation_mask[-1, :] = 1
1014         expected_annotation_mask[:, -1] = 1
1015         expected_prediction_mask = np.zeros((7, 7))
1016         postprocess_data(PostprocessingExecutor(config), annotation, prediction)
1017         assert np.array_equal(prediction[0].mask, expected_prediction_mask)
1018         assert np.array_equal(annotation[0].mask, expected_annotation_mask)
1019
1020
1021 class TestPostprocessorExtraArgs:
1022     def test_cast_to_int_raise_config_error_on_extra_args(self):
1023         config = {'type': 'cast_to_int', 'something_extra': 'extra'}
1024         with pytest.raises(ConfigError):
1025             postprocess_data(PostprocessingExecutor(config), [None], [None])
1026
1027     def test_clip_boxes_raise_config_error_on_extra_args(self):
1028         config = {'type': 'clip_boxes', 'size': 1, 'something_extra': 'extra'}
1029         with pytest.raises(ConfigError):
1030             postprocess_data(PostprocessingExecutor(config), [None], [None])
1031
1032     def test_correct_yolo_v2_boxes_raise_config_error_on_extra_args(self):
1033         config = {'type': 'correct_yolo_v2_boxes', 'something_extra': 'extra'}
1034         with pytest.raises(ConfigError):
1035             postprocess_data(PostprocessingExecutor(config), [None], [None])
1036
1037     def test_encode_segmentation_mask_raise_config_error_on_extra_args(self):
1038         config = {'type': 'encode_segmentation_mask', 'something_extra': 'extra'}
1039         with pytest.raises(ConfigError):
1040             postprocess_data(PostprocessingExecutor(config), [None], [None])
1041
1042     def test_filter_raise_config_error_on_extra_args(self):
1043         config = {'type': 'filter', 'something_extra': 'extra'}
1044         with pytest.raises(ConfigError):
1045             postprocess_data(PostprocessingExecutor(config), [None], [None])
1046
1047     def test_nms_raise_config_error_on_extra_args(self):
1048         config = {'type': 'nms', 'something_extra': 'extra'}
1049         with pytest.raises(ConfigError):
1050             postprocess_data(PostprocessingExecutor(config), [None], [None])
1051
1052     def test_normalize_landmarks_points_raise_config_error_on_extra_args(self):
1053         config = {'type': 'normalize_landmarks_points', 'something_extra': 'extra'}
1054         with pytest.raises(ConfigError):
1055             postprocess_data(PostprocessingExecutor(config), [None], [None])
1056
1057     def test_resize_prediction_boxes_raise_config_error_on_extra_args(self):
1058         config = {'type': 'resize_prediction_boxes', 'something_extra': 'extra'}
1059         with pytest.raises(ConfigError):
1060             postprocess_data(PostprocessingExecutor(config), [None], [None])
1061
1062     def test_resize_segmentation_mask_raise_config_error_on_extra_args(self):
1063         config = {'type': 'resize_segmentation_mask', 'something_extra': 'extra'}
1064         with pytest.raises(ConfigError):
1065             postprocess_data(PostprocessingExecutor(config), [None], [None])
1066
1067     def test_extend_segmentation_mask_raise_config_error_on_extra_args(self):
1068         config = {'type': 'resize_segmentation_mask', 'something_extra': 'extra'}
1069         with pytest.raises(ConfigError):
1070             postprocess_data(PostprocessingExecutor(config), [None], [None])