233 lines
7.9 KiB
Python
233 lines
7.9 KiB
Python
# Copyright (C) 2018-2022 Intel Corporation
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
|
|
from openvino.preprocess import ResizeAlgorithm, ColorFormat
|
|
from openvino.runtime import Layout, Type, serialize
|
|
|
|
|
|
xml_path = ''
|
|
input_name = ''
|
|
# ! [ov:preprocess:create]
|
|
from openvino.preprocess import PrePostProcessor
|
|
from openvino.runtime import Core
|
|
|
|
core = Core()
|
|
model = core.read_model(model=xml_path)
|
|
ppp = PrePostProcessor(model)
|
|
# ! [ov:preprocess:create]
|
|
|
|
# ! [ov:preprocess:tensor]
|
|
from openvino.preprocess import ColorFormat
|
|
from openvino.runtime import Layout, Type
|
|
ppp.input(input_name).tensor() \
|
|
.set_element_type(Type.u8) \
|
|
.set_shape([1, 480, 640, 3]) \
|
|
.set_layout(Layout('NHWC')) \
|
|
.set_color_format(ColorFormat.BGR)
|
|
# ! [ov:preprocess:tensor]
|
|
# ! [ov:preprocess:model]
|
|
# `model's input` already `knows` it's shape and data type, no need to specify them here
|
|
ppp.input(input_name).model().set_layout(Layout('NCHW'))
|
|
# ! [ov:preprocess:model]
|
|
# ! [ov:preprocess:steps]
|
|
from openvino.preprocess import ResizeAlgorithm
|
|
ppp.input(input_name).preprocess() \
|
|
.convert_element_type(Type.f32) \
|
|
.convert_color(ColorFormat.RGB) \
|
|
.resize(ResizeAlgorithm.RESIZE_LINEAR) \
|
|
.mean([100.5, 101, 101.5]) \
|
|
.scale([50., 51., 52.])
|
|
# .convert_layout(Layout('NCHW')); # Not needed, such conversion will be added implicitly
|
|
# ! [ov:preprocess:steps]
|
|
# ! [ov:preprocess:build]
|
|
print(f'Dump preprocessor: {ppp}')
|
|
model = ppp.build()
|
|
# ! [ov:preprocess:build]
|
|
|
|
# ! [ov:preprocess:input_index]
|
|
ppp.input(1) # Gets 2nd input in a model
|
|
ppp.output(2) # Gets output with index=2 (3rd one) in a model
|
|
# ! [ov:preprocess:input_index]
|
|
|
|
|
|
# ! [ov:preprocess:input_name]
|
|
ppp.input('image')
|
|
ppp.output('result')
|
|
# ! [ov:preprocess:input_name]
|
|
|
|
# ! [ov:preprocess:input_1]
|
|
# no index/name is needed if model has one input
|
|
ppp.input().preprocess().scale(50.)
|
|
|
|
# same for output
|
|
ppp.output() \
|
|
.postprocess().convert_element_type(Type.u8)
|
|
# ! [ov:preprocess:input_1]
|
|
# ! [ov:preprocess:mean_scale]
|
|
ppp.input('input').preprocess().mean(128).scale(127)
|
|
# ! [ov:preprocess:mean_scale]
|
|
# ! [ov:preprocess:mean_scale_array]
|
|
# Suppose model's shape is {1, 3, 224, 224}
|
|
# N=1, C=3, H=224, W=224
|
|
ppp.input('input').model().set_layout(Layout('NCHW'))
|
|
# Mean/Scale has 3 values which matches with C=3
|
|
ppp.input('input').preprocess() \
|
|
.mean([103.94, 116.78, 123.68]).scale([57.21, 57.45, 57.73])
|
|
# ! [ov:preprocess:mean_scale_array]
|
|
# ! [ov:preprocess:convert_element_type]
|
|
# First define data type for your tensor
|
|
ppp.input('input').tensor().set_element_type(Type.u8)
|
|
|
|
# Then define preprocessing step
|
|
ppp.input('input').preprocess().convert_element_type(Type.f32)
|
|
|
|
# If conversion is needed to `model's` element type, 'f32' can be omitted
|
|
ppp.input('input').preprocess().convert_element_type()
|
|
# ! [ov:preprocess:convert_element_type]
|
|
# ! [ov:preprocess:convert_layout]
|
|
# First define layout for your tensor
|
|
ppp.input('input').tensor().set_layout(Layout('NHWC'))
|
|
|
|
# Then define layout of model
|
|
ppp.input('input').model().set_layout(Layout('NCHW'))
|
|
|
|
print(ppp) # Will print 'implicit layout conversion step'
|
|
# ! [ov:preprocess:convert_layout]
|
|
# ! [ov:preprocess:convert_layout_2]
|
|
ppp.input('input').tensor().set_shape([1, 480, 640, 3])
|
|
|
|
# Model expects shape {1, 3, 480, 640}
|
|
ppp.input('input').preprocess()\
|
|
.convert_layout([0, 3, 1, 2])
|
|
# 0 -> 0; 3 -> 1; 1 -> 2; 2 -> 3
|
|
# ! [ov:preprocess:convert_layout_2]
|
|
|
|
# ! [ov:preprocess:resize_1]
|
|
ppp.input('input').tensor().set_shape([1, 3, 960, 1280])
|
|
ppp.input('input').model().set_layout(Layout('??HW'))
|
|
ppp.input('input').preprocess()\
|
|
.resize(ResizeAlgorithm.RESIZE_LINEAR, 480, 640)
|
|
# ! [ov:preprocess:resize_1]
|
|
# ! [ov:preprocess:resize_2]
|
|
ppp.input('input').tensor().set_shape([1, 3, 960, 1280])
|
|
# Model accepts {1, 3, 480, 640} shape, thus last dimensions are 'H' and 'W'
|
|
ppp.input('input').model().set_layout(Layout('??HW'))
|
|
# Resize to model's dimension
|
|
ppp.input('input').preprocess().resize(ResizeAlgorithm.RESIZE_LINEAR)
|
|
# ! [ov:preprocess:resize_2]
|
|
# ! [ov:preprocess:convert_color_1]
|
|
ppp.input('input').tensor().set_color_format(ColorFormat.BGR)
|
|
|
|
ppp.input('input').preprocess().convert_color(ColorFormat.RGB)
|
|
# ! [ov:preprocess:convert_color_1]
|
|
# ! [ov:preprocess:convert_color_2]
|
|
# This will split original `input` to 2 separate inputs: `input/y' and 'input/uv'
|
|
ppp.input('input').tensor()\
|
|
.set_color_format(ColorFormat.NV12_TWO_PLANES)
|
|
|
|
ppp.input('input').preprocess()\
|
|
.convert_color(ColorFormat.RGB)
|
|
print(ppp) # Dump preprocessing steps to see what will happen
|
|
# ! [ov:preprocess:convert_color_2]
|
|
|
|
# ! [ov:preprocess:custom]
|
|
# It is possible to insert some custom operations
|
|
import openvino.runtime.opset8 as ops
|
|
from openvino.runtime import Output
|
|
from openvino.runtime.utils.decorators import custom_preprocess_function
|
|
|
|
@custom_preprocess_function
|
|
def custom_abs(output: Output):
|
|
# Custom nodes can be inserted as Preprocessing steps
|
|
return ops.abs(output)
|
|
|
|
ppp.input("input_image").preprocess() \
|
|
.custom(custom_abs)
|
|
# ! [ov:preprocess:custom]
|
|
|
|
# ! [ov:preprocess:postprocess]
|
|
# Model's output has 'NCHW' layout
|
|
ppp.output('result_image').model().set_layout(Layout('NCHW'))
|
|
|
|
# Set target user's tensor to U8 type + 'NHWC' layout
|
|
# Precision & layout conversions will be done implicitly
|
|
ppp.output('result_image').tensor()\
|
|
.set_layout(Layout("NHWC"))\
|
|
.set_element_type(Type.u8)
|
|
|
|
# Also it is possible to insert some custom operations
|
|
import openvino.runtime.opset8 as ops
|
|
from openvino.runtime import Output
|
|
from openvino.runtime.utils.decorators import custom_preprocess_function
|
|
|
|
@custom_preprocess_function
|
|
def custom_abs(output: Output):
|
|
# Custom nodes can be inserted as Post-processing steps
|
|
return ops.abs(output)
|
|
|
|
ppp.output("result_image").postprocess()\
|
|
.custom(custom_abs)
|
|
# ! [ov:preprocess:postprocess]
|
|
|
|
# ! [ov:preprocess:save_headers]
|
|
from openvino.preprocess import PrePostProcessor, ColorFormat, ResizeAlgorithm
|
|
from openvino.runtime import Core, Layout, Type, set_batch
|
|
# First method - imports
|
|
from openvino.runtime import serialize
|
|
# Second method - imports
|
|
from openvino.runtime.passes import Manager, Serialize
|
|
# ! [ov:preprocess:save_headers]
|
|
|
|
# ! [ov:preprocess:save]
|
|
# ======== Step 0: read original model =========
|
|
core = Core()
|
|
model = core.read_model(model='/path/to/some_model.onnx')
|
|
|
|
# ======== Step 1: Preprocessing ================
|
|
ppp = PrePostProcessor(model)
|
|
# Declare section of desired application's input format
|
|
ppp.input().tensor() \
|
|
.set_element_type(Type.u8) \
|
|
.set_spatial_dynamic_shape() \
|
|
.set_layout(Layout('NHWC')) \
|
|
.set_color_format(ColorFormat.BGR)
|
|
|
|
# Specify actual model layout
|
|
ppp.input().model().set_layout(Layout('NCHW'))
|
|
|
|
# Explicit preprocessing steps. Layout conversion will be done automatically as last step
|
|
ppp.input().preprocess() \
|
|
.convert_element_type() \
|
|
.convert_color(ColorFormat.RGB) \
|
|
.resize(ResizeAlgorithm.RESIZE_LINEAR) \
|
|
.mean([123.675, 116.28, 103.53]) \
|
|
.scale([58.624, 57.12, 57.375])
|
|
|
|
# Dump preprocessor
|
|
print(f'Dump preprocessor: {ppp}')
|
|
model = ppp.build()
|
|
|
|
# ======== Step 2: Change batch size ================
|
|
# In this example we also want to change batch size to increase throughput
|
|
set_batch(model, 2)
|
|
|
|
# ======== Step 3: Save the model ================
|
|
# First method - using serialize runtime wrapper
|
|
serialize(model, '/path/to/some_model_saved.xml', '/path/to/some_model_saved.bin')
|
|
|
|
# Second method - using Manager and Serialize pass
|
|
manager = Manager()
|
|
manager.register_pass(Serialize('/path/to/some_model_saved.xml', '/path/to/some_model_saved.bin'))
|
|
manager.run_passes(model)
|
|
# ! [ov:preprocess:save]
|
|
|
|
# ! [ov:preprocess:save_load]
|
|
core = Core()
|
|
core.set_property({'CACHE_DIR': '/path/to/cache/dir'})
|
|
|
|
# In case that no preprocessing is needed anymore, we can load model on target device directly
|
|
# With cached model available, it will also save some time on reading original model
|
|
compiled_model = core.compile_model('/path/to/some_model_saved.xml', 'CPU')
|
|
# ! [ov:preprocess:save_load]
|