Skip to main content

openvino/
prepostprocess.rs

1//! See
2//! [`ov_prepostprocess_c_api`](https://docs.openvino.ai/2024/api/c_cpp_api/group__ov__prepostprocess__c__api.html#).
3//!
4//! For more information, read through the [`PrePostProcess
5//! Walkthrough`](https://docs.openvino.ai/2022.3/openvino_docs_OV_UG_Preprocessing_Overview.html).
6//!
7//! ```
8//! # use openvino::{prepostprocess, Core, ElementType, Layout, Shape, Tensor, ResizeAlgorithm};
9//! # use std::fs;
10//! # let mut core = Core::new().expect("to instantiate the OpenVINO library");
11//! # let mut model = core.read_model_from_file(
12//! #     &"tests/fixtures/inception/inception.xml",
13//! #     &"tests/fixtures/inception/inception.bin",
14//! # ).expect("to read the model from file");
15//! # let data = fs::read("tests/fixtures/inception/tensor-1x3x299x299-f32.bgr").expect("to read the tensor from file");
16//! # let input_shape = Shape::new(&vec![1, 299, 299, 3]).expect("to create a new shape");
17//! # let mut tensor = Tensor::new(ElementType::F32, &input_shape).expect("to create a new tensor");
18//! # let buffer = tensor.get_raw_data_mut().unwrap();
19//! # buffer.copy_from_slice(&data);
20//! // Instantiate a new core, read in a model, and set up a tensor with input data before performing pre/post processing
21//! // Pre-process the input by:
22//! // - converting NHWC to NCHW
23//! // - resizing the input image
24//! let mut pipeline = prepostprocess::Pipeline::new(&model).expect("to create a new pipeline");
25//! let input_info = pipeline.get_input_info_by_name("input").expect("to get input info by name");
26//! let mut input_tensor_info = input_info.get_tensor_info().expect("to get tensor info");
27//! input_tensor_info.set_from(&tensor).expect("to set tensor from");
28//! input_tensor_info.set_layout(Layout::new("NHWC").expect("to create a new layout")).expect("to set layout");
29//! let mut preprocess_steps = input_info.get_steps().expect("to get preprocess steps");
30//! preprocess_steps.resize(ResizeAlgorithm::Linear).expect("to resize");
31//! let mut model_info = input_info.get_model_info().expect("to get model info");
32//! model_info.set_layout(Layout::new("NCHW").expect("to create a new layout")).expect("to set layout");
33//! let new_model = pipeline.build_new_model().expect("to build new model with above prepostprocess steps");
34//! ```
35use crate::{
36    cstr, drop_using_function, layout::Layout, try_unsafe, util::Result, ElementType, Model,
37    ResizeAlgorithm, Tensor,
38};
39use openvino_sys::{
40    ov_preprocess_input_info_free, ov_preprocess_input_info_get_model_info,
41    ov_preprocess_input_info_get_preprocess_steps, ov_preprocess_input_info_get_tensor_info,
42    ov_preprocess_input_info_t, ov_preprocess_input_model_info_free,
43    ov_preprocess_input_model_info_set_layout, ov_preprocess_input_model_info_t,
44    ov_preprocess_input_tensor_info_free, ov_preprocess_input_tensor_info_set_from,
45    ov_preprocess_input_tensor_info_set_layout, ov_preprocess_input_tensor_info_t,
46    ov_preprocess_output_info_free, ov_preprocess_output_info_get_tensor_info,
47    ov_preprocess_output_info_t, ov_preprocess_output_set_element_type,
48    ov_preprocess_output_tensor_info_free, ov_preprocess_output_tensor_info_t,
49    ov_preprocess_prepostprocessor_build, ov_preprocess_prepostprocessor_create,
50    ov_preprocess_prepostprocessor_free, ov_preprocess_prepostprocessor_get_input_info,
51    ov_preprocess_prepostprocessor_get_input_info_by_index,
52    ov_preprocess_prepostprocessor_get_input_info_by_name,
53    ov_preprocess_prepostprocessor_get_output_info_by_index,
54    ov_preprocess_prepostprocessor_get_output_info_by_name, ov_preprocess_prepostprocessor_t,
55    ov_preprocess_preprocess_steps_convert_element_type,
56    ov_preprocess_preprocess_steps_convert_layout, ov_preprocess_preprocess_steps_free,
57    ov_preprocess_preprocess_steps_resize, ov_preprocess_preprocess_steps_t,
58};
59
60/// See
61/// [`ov_preprocess_prepostprocessor_t`](https://docs.openvino.ai/2024/api/c_cpp_api/structov__preprocess__prepostprocessor__t.html).
62#[derive(Debug)]
63pub struct Pipeline {
64    ptr: *mut ov_preprocess_prepostprocessor_t,
65}
66drop_using_function!(Pipeline, ov_preprocess_prepostprocessor_free);
67impl Pipeline {
68    /// Creates a new [`Pipeline`] for the given [`Model`].
69    pub fn new(model: &Model) -> Result<Self> {
70        let mut ptr = std::ptr::null_mut();
71        try_unsafe!(ov_preprocess_prepostprocessor_create(
72            model.as_ptr(),
73            std::ptr::addr_of_mut!(ptr)
74        ))?;
75        Ok(Self { ptr })
76    }
77
78    /// Retrieves the input information by index.
79    pub fn get_input_info_by_index(&self, index: usize) -> Result<InputInfo> {
80        let mut ptr = std::ptr::null_mut();
81        try_unsafe!(ov_preprocess_prepostprocessor_get_input_info_by_index(
82            self.ptr,
83            index,
84            std::ptr::addr_of_mut!(ptr)
85        ))?;
86
87        Ok(InputInfo { ptr })
88    }
89
90    /// Retrieves the input information by name.
91    pub fn get_input_info_by_name(&self, name: &str) -> Result<InputInfo> {
92        let name = cstr!(name);
93        let mut ptr = std::ptr::null_mut();
94        try_unsafe!(ov_preprocess_prepostprocessor_get_input_info_by_name(
95            self.ptr,
96            name.as_ptr(),
97            std::ptr::addr_of_mut!(ptr)
98        ))?;
99
100        Ok(InputInfo { ptr })
101    }
102
103    /// Retrieves the output information by name.
104    pub fn get_output_info_by_name(&self, name: &str) -> Result<OutputInfo> {
105        let name = cstr!(name);
106        let mut ptr = std::ptr::null_mut();
107        try_unsafe!(ov_preprocess_prepostprocessor_get_output_info_by_name(
108            self.ptr,
109            name.as_ptr(),
110            std::ptr::addr_of_mut!(ptr)
111        ))?;
112        Ok(OutputInfo { ptr })
113    }
114
115    /// Retrieves the output information by index.
116    pub fn get_output_info_by_index(&self, index: usize) -> Result<OutputInfo> {
117        let mut ptr = std::ptr::null_mut();
118        try_unsafe!(ov_preprocess_prepostprocessor_get_output_info_by_index(
119            self.ptr,
120            index,
121            std::ptr::addr_of_mut!(ptr)
122        ))?;
123
124        Ok(OutputInfo { ptr })
125    }
126
127    /// Retrieves the input information.
128    ///
129    /// # Panics
130    ///
131    /// Panics if the returned input info is null.
132    pub fn get_input_info(&self) -> Result<InputInfo> {
133        let mut ptr = std::ptr::null_mut();
134        try_unsafe!(ov_preprocess_prepostprocessor_get_input_info(
135            self.ptr,
136            std::ptr::addr_of_mut!(ptr)
137        ))?;
138        assert!(!ptr.is_null());
139        Ok(InputInfo { ptr })
140    }
141
142    /// Builds a new model with all steps from pre/postprocessing.
143    pub fn build_new_model(&self) -> Result<Model> {
144        let mut ptr = std::ptr::null_mut();
145        try_unsafe!(ov_preprocess_prepostprocessor_build(
146            self.ptr,
147            std::ptr::addr_of_mut!(ptr)
148        ))?;
149        Ok(Model::from_ptr(ptr))
150    }
151}
152
153/// See
154/// [`ov_preprocess_input_info_t`](https://docs.openvino.ai/2024/api/c_cpp_api/structov__preprocess__input__info__t.html).
155pub struct InputInfo {
156    ptr: *mut ov_preprocess_input_info_t,
157}
158drop_using_function!(InputInfo, ov_preprocess_input_info_free);
159
160impl InputInfo {
161    /// Retrieves the preprocessing model input information.
162    pub fn get_model_info(&self) -> Result<InputModelInfo> {
163        let mut ptr = std::ptr::null_mut();
164        try_unsafe!(ov_preprocess_input_info_get_model_info(
165            self.ptr,
166            std::ptr::addr_of_mut!(ptr)
167        ))?;
168        Ok(InputModelInfo { ptr })
169    }
170
171    /// Retrieves the input tensor information.
172    pub fn get_tensor_info(&self) -> Result<InputTensorInfo> {
173        let mut ptr: *mut ov_preprocess_input_tensor_info_t = std::ptr::null_mut();
174        try_unsafe!(ov_preprocess_input_info_get_tensor_info(
175            self.ptr,
176            std::ptr::addr_of_mut!(ptr)
177        ))?;
178        Ok(InputTensorInfo { ptr })
179    }
180
181    /// Retrieves the preprocessing steps.
182    pub fn get_steps(&self) -> Result<Steps> {
183        let mut ptr = std::ptr::null_mut();
184        try_unsafe!(ov_preprocess_input_info_get_preprocess_steps(
185            self.ptr,
186            std::ptr::addr_of_mut!(ptr)
187        ))?;
188        Ok(Steps { ptr })
189    }
190}
191
192/// See
193/// [`ov_preprocess_output_info_t`](https://docs.openvino.ai/2024/api/c_cpp_api/structov__preprocess__output__info__t.html).
194pub struct OutputInfo {
195    ptr: *mut ov_preprocess_output_info_t,
196}
197drop_using_function!(OutputInfo, ov_preprocess_output_info_free);
198impl OutputInfo {
199    /// Retrieves preprocess output tensor information.
200    pub fn get_tensor_info(&self) -> Result<OutputTensorInfo> {
201        let mut ptr: *mut ov_preprocess_output_tensor_info_t = std::ptr::null_mut();
202        try_unsafe!(ov_preprocess_output_info_get_tensor_info(
203            self.ptr,
204            std::ptr::addr_of_mut!(ptr)
205        ))?;
206        Ok(OutputTensorInfo { ptr })
207    }
208}
209
210/// See
211/// [`ov_preprocess_input_model_info_t`](https://docs.openvino.ai/2024/api/c_cpp_api/structov__preprocess__input__model__info__t.html).
212pub struct InputModelInfo {
213    ptr: *mut ov_preprocess_input_model_info_t,
214}
215drop_using_function!(InputModelInfo, ov_preprocess_input_model_info_free);
216impl InputModelInfo {
217    /// Sets the layout for the model information obj.
218    pub fn set_layout(&mut self, mut layout: Layout) -> Result<()> {
219        try_unsafe!(ov_preprocess_input_model_info_set_layout(
220            self.ptr,
221            layout.as_mut_ptr()
222        ))
223    }
224}
225
226/// See
227/// [`ov_preprocess_input_tensor_info_t`](https://docs.openvino.ai/2024/api/c_cpp_api/structov__preprocess__input__tensor__info__t.html).
228pub struct InputTensorInfo {
229    ptr: *mut ov_preprocess_input_tensor_info_t,
230}
231drop_using_function!(InputTensorInfo, ov_preprocess_input_tensor_info_free);
232impl InputTensorInfo {
233    /// Sets the [`Layout`] for the input tensor.
234    pub fn set_layout(&mut self, mut layout: Layout) -> Result<()> {
235        try_unsafe!(ov_preprocess_input_tensor_info_set_layout(
236            self.ptr,
237            layout.as_mut_ptr()
238        ))
239    }
240
241    /// Sets the input tensor info from an existing tensor.
242    pub fn set_from(&mut self, tensor: &Tensor) -> Result<()> {
243        try_unsafe!(ov_preprocess_input_tensor_info_set_from(
244            self.ptr,
245            tensor.as_ptr()
246        ))
247    }
248}
249
250/// See
251/// [`ov_preprocess_output_tensor_info_t`](https://docs.openvino.ai/2024/api/c_cpp_api/structov__preprocess__output__tensor__info__t.html).
252pub struct OutputTensorInfo {
253    ptr: *mut ov_preprocess_output_tensor_info_t,
254}
255drop_using_function!(OutputTensorInfo, ov_preprocess_output_tensor_info_free);
256impl OutputTensorInfo {
257    /// Sets the element type for output tensor info.
258    pub fn set_element_type(&mut self, element_type: ElementType) -> Result<()> {
259        try_unsafe!(ov_preprocess_output_set_element_type(
260            self.ptr,
261            element_type.into()
262        ))
263    }
264}
265
266/// See
267/// [`ov_preprocess_preprocess_steps_t`](https://docs.openvino.ai/2024/api/c_cpp_api/structov__preprocess__preprocess__steps__t.html).
268pub struct Steps {
269    ptr: *mut ov_preprocess_preprocess_steps_t,
270}
271drop_using_function!(Steps, ov_preprocess_preprocess_steps_free);
272impl Steps {
273    /// Resizes the data in a [`Tensor`].
274    pub fn resize(&mut self, resize_algo: ResizeAlgorithm) -> Result<()> {
275        try_unsafe!(ov_preprocess_preprocess_steps_resize(
276            self.ptr,
277            resize_algo.into()
278        ))
279    }
280
281    /// Converts the [`Layout`] of the data in a [`Tensor`].
282    pub fn convert_layout(&mut self, mut new_layout: Layout) -> Result<()> {
283        try_unsafe!(ov_preprocess_preprocess_steps_convert_layout(
284            self.ptr,
285            new_layout.as_mut_ptr(),
286        ))
287    }
288
289    /// Converts the element type of data in tensor.
290    pub fn convert_element_type(&mut self, new_element_type: ElementType) -> Result<()> {
291        try_unsafe!(ov_preprocess_preprocess_steps_convert_element_type(
292            self.ptr,
293            new_element_type.into()
294        ))
295    }
296}