Added support for attribute 'pad_to_max_dimension' for TF OD API models (#4720)

* Added support for attribute 'pad_to_max_dimension' for TF OD API models

* Restored line removed by mistake
This commit is contained in:
Evgeny Lazarev authored and GitHub committed 2021-03-11 13:21:20 +03:00
1 parent 61389b5e51
commit 56a179c6a3
4 files changed
+47 -51

No files matched your search

@@ -363,7 +363,8 @@ def skip_nodes_by_condition(current_node: Node, condition: callable):
return current_node
def calculate_shape_keeping_aspect_ratio(height: int, width: int, min_size: int, max_size: int):
def calculate_shape_keeping_aspect_ratio(height: int, width: int, min_size: int, max_size: int,
pad_to_max_dimension: bool = False):
"""
The function scales spatial sizes of the image keeping aspect ratio to satisfy provided requirements.
The behavior of this function is equivalent to the output shape calculation of the Preprocessor block of TensorFlow
@@ -372,8 +373,11 @@ def calculate_shape_keeping_aspect_ratio(height: int, width: int, min_size: int,
:param width: input width.
:param min_size: size limit.
:param max_size: size limit.
:param pad_to_max_dimension: scale the input image size to the maximum value specified
:return: the tuple with scaled image height, width.
"""
if pad_to_max_dimension:
return max_size, max_size
ratio_min = min_size / min(height, width)
ratio_max = max_size / max(height, width)
ratio = min(ratio_min, ratio_max)
@@ -441,6 +445,7 @@ def calculate_placeholder_spatial_shape(graph: Graph, match: SubgraphMatch, pipe
# if the model is created with an input image resizer keeping aspect ratio
if resizer_min_dimension and resizer_max_dimension:
pad_to_max_dimension = pipeline_config.get_param('pad_to_max_dimension')
print('[ WARNING ] Model Optimizer removes pre-processing block of the model which resizes image keeping '
'aspect ratio. The Inference Engine does not support dynamic image size so the Intermediate '
'Representation file is generated with the input image size of a fixed size.')
@@ -448,7 +453,8 @@ def calculate_placeholder_spatial_shape(graph: Graph, match: SubgraphMatch, pipe
scaled_height, scaled_width = calculate_shape_keeping_aspect_ratio(user_defined_height,
user_defined_width,
resizer_min_dimension,
resizer_max_dimension)
resizer_max_dimension,
pad_to_max_dimension)
if scaled_height != user_defined_height or scaled_width != user_defined_width:
log.error('The model resizes the input image keeping aspect ratio with min dimension {}, max '
'dimension {}. The provided input height {}, width {} is transformed to height {}, width '
@@ -457,7 +463,10 @@ def calculate_placeholder_spatial_shape(graph: Graph, match: SubgraphMatch, pipe
height = scaled_height
width = scaled_width
else:
height = width = resizer_min_dimension
if pad_to_max_dimension:
height = width = resizer_max_dimension
else:
height = width = resizer_min_dimension
print('Specify the "--input_shape" command line parameter to override the default shape which is equal to '
'({}, {}).'.format(height, width))
@@ -16,6 +16,8 @@
import unittest
from generator import generator, generate
from extensions.front.tf.ObjectDetectionAPI import calculate_shape_keeping_aspect_ratio, \
calculate_placeholder_spatial_shape
from mo.front.subgraph_matcher import SubgraphMatch
@@ -34,58 +36,33 @@ class FakePipelineConfig:
return self._model_params[param]
@generator
class TestCalculateShape(unittest.TestCase):
min_size = 600
max_size = 1024
def test_calculate_shape_1(self):
self.assertTupleEqual(calculate_shape_keeping_aspect_ratio(100, 300, self.min_size, self.max_size), (341, 1024))
def test_calculate_shape_2(self):
self.assertTupleEqual(calculate_shape_keeping_aspect_ratio(100, 600, self.min_size, self.max_size), (171, 1024))
def test_calculate_shape_3(self):
self.assertTupleEqual(calculate_shape_keeping_aspect_ratio(100, 3000, self.min_size, self.max_size), (34, 1024))
def test_calculate_shape_4(self):
self.assertTupleEqual(calculate_shape_keeping_aspect_ratio(300, 300, self.min_size, self.max_size), (600, 600))
def test_calculate_shape_5(self):
self.assertTupleEqual(calculate_shape_keeping_aspect_ratio(300, 400, self.min_size, self.max_size), (600, 800))
def test_calculate_shape_6(self):
self.assertTupleEqual(calculate_shape_keeping_aspect_ratio(300, 600, self.min_size, self.max_size), (512, 1024))
def test_calculate_shape_7(self):
self.assertTupleEqual(calculate_shape_keeping_aspect_ratio(1000, 2500, self.min_size, self.max_size),
(410, 1024))
def test_calculate_shape_8(self):
self.assertTupleEqual(calculate_shape_keeping_aspect_ratio(1800, 2000, self.min_size, self.max_size),
(600, 667))
def test_calculate_shape_11(self):
self.assertTupleEqual(calculate_shape_keeping_aspect_ratio(300, 100, self.min_size, self.max_size), (1024, 341))
def test_calculate_shape_12(self):
self.assertTupleEqual(calculate_shape_keeping_aspect_ratio(600, 100, self.min_size, self.max_size), (1024, 171))
def test_calculate_shape_13(self):
self.assertTupleEqual(calculate_shape_keeping_aspect_ratio(3000, 100, self.min_size, self.max_size), (1024, 34))
def test_calculate_shape_15(self):
self.assertTupleEqual(calculate_shape_keeping_aspect_ratio(400, 300, self.min_size, self.max_size), (800, 600))
def test_calculate_shape_16(self):
self.assertTupleEqual(calculate_shape_keeping_aspect_ratio(600, 300, self.min_size, self.max_size), (1024, 512))
def test_calculate_shape_17(self):
self.assertTupleEqual(calculate_shape_keeping_aspect_ratio(2500, 1000, self.min_size, self.max_size),
(1024, 410))
def test_calculate_shape_18(self):
self.assertTupleEqual(calculate_shape_keeping_aspect_ratio(2000, 1800, self.min_size, self.max_size),
(667, 600))
@generate(*[(100, 300, 341, 1024, False),
(100, 600, 171, 1024, False),
(100, 3000, 34, 1024, False),
(300, 300, 600, 600, False),
(300, 400, 600, 800, False),
(300, 600, 512, 1024, False),
(1000, 2500, 410, 1024, False),
(1800, 2000, 600, 667, False),
(300, 100, 1024, 341, False),
(600, 100, 1024, 171, False),
(3000, 100, 1024, 34, False),
(400, 300, 800, 600, False),
(600, 300, 1024, 512, False),
(2500, 1000, 1024, 410, False),
(2000, 1800, 667, 600, False),
(300, 300, 1024, 1024, True),
(900, 300, 1024, 1024, True),
(1300, 900, 1024, 1024, True),
(1025, 1025, 1024, 1024, True),
])
def test_calculate_shape(self, h, w, th, tw, pad):
self.assertTupleEqual(calculate_shape_keeping_aspect_ratio(h, w, self.min_size, self.max_size, pad), (th, tw))
class TestCalculatePlaceholderSpatialShape(unittest.TestCase):
@@ -122,5 +99,13 @@ class TestCalculatePlaceholderSpatialShape(unittest.TestCase):
self.assertTupleEqual((800, 600),
calculate_placeholder_spatial_shape(self.graph, self.match, self.pipeline_config))
def test_keep_aspect_ratio_resizer_overrided_by_user_pad(self):
self.pipeline_config._model_params['resizer_min_dimension'] = 600
self.pipeline_config._model_params['resizer_max_dimension'] = 1024
self.pipeline_config._model_params['pad_to_max_dimension'] = True
self.graph.graph['user_shapes'] = {'image_tensor': [{'shape': [1, 400, 300, 3]}]}
self.assertTupleEqual((1024, 1024),
calculate_placeholder_spatial_shape(self.graph, self.match, self.pipeline_config))
def test_missing_input_shape_information(self):
self.assertRaises(Error, calculate_placeholder_spatial_shape, self.graph, self.match, self.pipeline_config)
@@ -32,6 +32,7 @@ mapping_rules = [
('resizer_image_width', 'image_resizer/fixed_shape_resizer/width'),
('resizer_min_dimension', 'image_resizer/keep_aspect_ratio_resizer/min_dimension'),
('resizer_max_dimension', 'image_resizer/keep_aspect_ratio_resizer/max_dimension'),
('pad_to_max_dimension', 'image_resizer/keep_aspect_ratio_resizer/pad_to_max_dimension', False),
# anchor generator attributes
('anchor_generator_height', 'first_stage_anchor_generator/grid_anchor_generator/height$', 256),
('anchor_generator_width', 'first_stage_anchor_generator/grid_anchor_generator/width$', 256),
@@ -151,6 +151,7 @@ class TestingSimpleProtoParser(unittest.TestCase):
'use_matmul_crop_and_resize': False,
'add_background_class': True,
'share_box_across_classes': False,
'pad_to_max_dimension': False,
}
os.unlink(file_name)
self.assertDictEqual(pipeline_config._model_params, expected_result)