From c691dc483db3da2c2ff9646a22e751a889cf3349 Mon Sep 17 00:00:00 2001 From: Przemyslaw Wysocki Date: Fri, 15 Dec 2023 13:43:47 +0100 Subject: [PATCH] [PyOV][torchvision] Fix Resize for non-square images and expose missing interpolation modes (#21673) --- .../torchvision/torchvision_preprocessing.py | 21 +++++++++++++------ .../test_preprocessor.py | 13 ++++++++---- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/bindings/python/src/openvino/preprocess/torchvision/torchvision_preprocessing.py b/src/bindings/python/src/openvino/preprocess/torchvision/torchvision_preprocessing.py index 503984ee67a..43968fb4fa4 100644 --- a/src/bindings/python/src/openvino/preprocess/torchvision/torchvision_preprocessing.py +++ b/src/bindings/python/src/openvino/preprocess/torchvision/torchvision_preprocessing.py @@ -62,7 +62,7 @@ def _setup_size_sequence(size: Sequence, error_msg: str) -> SequenceType[int]: if len(size) == 1: return size[0], size[0] elif len(size) == 2: - return size + return size[0], size[1] raise ValueError(error_msg) @@ -284,13 +284,22 @@ class _(TransformConverterBase): def convert(self, input_idx: int, ppp: PrePostProcessor, transform: Callable, meta: Dict) -> None: resize_mode_map = { InterpolationMode.NEAREST: ResizeAlgorithm.RESIZE_NEAREST, + InterpolationMode.BILINEAR: ResizeAlgorithm.RESIZE_BILINEAR_PILLOW, + InterpolationMode.BICUBIC: ResizeAlgorithm.RESIZE_BICUBIC_PILLOW, } if transform.max_size: raise ValueError("Resize with max_size if not supported") - if transform.interpolation is not InterpolationMode.NEAREST: - raise ValueError("Only InterpolationMode.NEAREST is supported.") + if transform.interpolation not in resize_mode_map.keys(): + raise ValueError(f"Interpolation mode {transform.interpolation} is not supported.") - h, w = _setup_size(transform.size, "Incorrect size type for Resize operation") + target_h, target_w = _setup_size(transform.size, "Incorrect size type for Resize operation") + + # rescale the smaller image edge + current_h, current_w = meta["image_dimensions"] + if current_h > current_w: + target_h = int(transform.size * (current_h / current_w)) + elif current_w > current_h: + target_w = int(transform.size * (current_w / current_h)) ppp.input(input_idx).tensor().set_layout(Layout("NCHW")) @@ -300,9 +309,9 @@ class _(TransformConverterBase): input_shape[meta["layout"].get_index_by_name("W")] = -1 ppp.input(input_idx).tensor().set_shape(input_shape) - ppp.input(input_idx).preprocess().resize(resize_mode_map[transform.interpolation], h, w) + ppp.input(input_idx).preprocess().resize(resize_mode_map[transform.interpolation], target_h, target_w) meta["input_shape"] = input_shape - meta["image_dimensions"] = (h, w) + meta["image_dimensions"] = (target_h, target_w) def _from_torchvision(model: ov.Model, transform: Callable, input_example: Any, input_name: Union[str, None] = None) -> ov.Model: diff --git a/src/bindings/python/tests/test_torchvision_to_ov/test_preprocessor.py b/src/bindings/python/tests/test_torchvision_to_ov/test_preprocessor.py index f76faf924b2..041f2afcf55 100644 --- a/src/bindings/python/tests/test_torchvision_to_ov/test_preprocessor.py +++ b/src/bindings/python/tests/test_torchvision_to_ov/test_preprocessor.py @@ -67,15 +67,20 @@ def test_normalize(): @pytest.mark.parametrize( - ("interpolation", "tolerance"), + ("target_size", "interpolation", "tolerance"), [ - (transforms.InterpolationMode.NEAREST, 4e-05), + ((220, 220, 3), transforms.InterpolationMode.NEAREST, 4e-05), + ((200, 240, 3), transforms.InterpolationMode.NEAREST, 0.3), # Ticket 127670 + ((220, 220, 3), transforms.InterpolationMode.BILINEAR, 4e-03), + ((200, 240, 3), transforms.InterpolationMode.BILINEAR, 4e-03), + ((220, 220, 3), transforms.InterpolationMode.BICUBIC, 4e-03), + ((200, 240, 3), transforms.InterpolationMode.BICUBIC, 4e-03), ], ) -def test_resize(interpolation, tolerance): +def test_resize(target_size, interpolation, tolerance): if platform.machine() in ["arm", "armv7l", "aarch64", "arm64", "ARM64"]: pytest.skip("Ticket: 114816") - test_input = np.random.randint(255, size=(220, 220, 3), dtype=np.uint8) + test_input = np.random.randint(255, size=target_size, dtype=np.uint8) preprocess_pipeline = transforms.Compose( [ transforms.Resize(224, interpolation=interpolation),