From ab38c9110f0ea44e0d37f2847d3beee07f7be365 Mon Sep 17 00:00:00 2001 From: guxukai <44280887+GodIsBoom@users.noreply.github.com> Date: Tue, 14 Mar 2023 19:16:07 +0800 Subject: [PATCH] [CVCUDA]add op Python API: Cast, HWC2CHW, Normalize, PadToSize, Resize, StridePad (#1589) * add Cast, HWC2CHW, Normalize, PadToSize, StridePad * add comments * fix comments * fix manager.cc --- .../vision/common/processors/cast_pybind.cc | 22 ++++ .../common/processors/hwc2chw_pybind.cc | 22 ++++ .../vision/common/processors/manager.cc | 2 +- .../common/processors/normalize_pybind.cc | 24 +++++ .../common/processors/pad_to_size_pybind.cc | 23 ++++ .../common/processors/processors_pybind.cc | 12 +++ .../vision/common/processors/resize_pybind.cc | 23 ++++ .../common/processors/stride_pad_pybind.cc | 22 ++++ python/fastdeploy/vision/common/processors.py | 100 ++++++++++++++++-- .../vision_processor/python/preprocess.py | 31 +++++- 10 files changed, 268 insertions(+), 13 deletions(-) create mode 100644 fastdeploy/vision/common/processors/cast_pybind.cc create mode 100644 fastdeploy/vision/common/processors/hwc2chw_pybind.cc create mode 100644 fastdeploy/vision/common/processors/normalize_pybind.cc create mode 100644 fastdeploy/vision/common/processors/pad_to_size_pybind.cc create mode 100644 fastdeploy/vision/common/processors/resize_pybind.cc create mode 100644 fastdeploy/vision/common/processors/stride_pad_pybind.cc diff --git a/fastdeploy/vision/common/processors/cast_pybind.cc b/fastdeploy/vision/common/processors/cast_pybind.cc new file mode 100644 index 000000000..ea286185b --- /dev/null +++ b/fastdeploy/vision/common/processors/cast_pybind.cc @@ -0,0 +1,22 @@ +// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "fastdeploy/pybind/main.h" + +namespace fastdeploy { +void BindCast(pybind11::module& m) { + pybind11::class_(m, "Cast").def( + pybind11::init(), "Default constructor"); +} + +} // namespace fastdeploy \ No newline at end of file diff --git a/fastdeploy/vision/common/processors/hwc2chw_pybind.cc b/fastdeploy/vision/common/processors/hwc2chw_pybind.cc new file mode 100644 index 000000000..16558f9ab --- /dev/null +++ b/fastdeploy/vision/common/processors/hwc2chw_pybind.cc @@ -0,0 +1,22 @@ +// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "fastdeploy/pybind/main.h" + +namespace fastdeploy { +void BindHWC2CHW(pybind11::module& m) { + pybind11::class_(m, "HWC2CHW") + .def(pybind11::init<>(), "Default constructor"); +} + +} // namespace fastdeploy \ No newline at end of file diff --git a/fastdeploy/vision/common/processors/manager.cc b/fastdeploy/vision/common/processors/manager.cc index 89ae4bf15..4d76e6be4 100644 --- a/fastdeploy/vision/common/processors/manager.cc +++ b/fastdeploy/vision/common/processors/manager.cc @@ -60,7 +60,7 @@ void ProcessorManager::PreApply(FDMatBatch* image_batch) { } image_batch->input_cache = &batch_input_cache_; image_batch->output_cache = &batch_output_cache_; - + image_batch->proc_lib = proc_lib_; if (CudaUsed()) { SetStream(image_batch); } diff --git a/fastdeploy/vision/common/processors/normalize_pybind.cc b/fastdeploy/vision/common/processors/normalize_pybind.cc new file mode 100644 index 000000000..5e09f8f11 --- /dev/null +++ b/fastdeploy/vision/common/processors/normalize_pybind.cc @@ -0,0 +1,24 @@ +// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "fastdeploy/pybind/main.h" + +namespace fastdeploy { +void BindNormalize(pybind11::module& m) { + pybind11::class_(m, "Normalize") + .def(pybind11::init, std::vector, bool, + std::vector, std::vector, bool>(), + "Default constructor"); +} + +} // namespace fastdeploy \ No newline at end of file diff --git a/fastdeploy/vision/common/processors/pad_to_size_pybind.cc b/fastdeploy/vision/common/processors/pad_to_size_pybind.cc new file mode 100644 index 000000000..d8f1c6c26 --- /dev/null +++ b/fastdeploy/vision/common/processors/pad_to_size_pybind.cc @@ -0,0 +1,23 @@ +// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "fastdeploy/pybind/main.h" + +namespace fastdeploy { +void BindPadToSize(pybind11::module& m) { + pybind11::class_(m, "PadToSize") + .def(pybind11::init>(), + "Default constructor"); +} + +} // namespace fastdeploy \ No newline at end of file diff --git a/fastdeploy/vision/common/processors/processors_pybind.cc b/fastdeploy/vision/common/processors/processors_pybind.cc index 4d9684aa2..0cbec593a 100644 --- a/fastdeploy/vision/common/processors/processors_pybind.cc +++ b/fastdeploy/vision/common/processors/processors_pybind.cc @@ -22,6 +22,12 @@ void BindProcessor(pybind11::module& m); void BindResizeByShort(pybind11::module& m); void BindCenterCrop(pybind11::module& m); void BindPad(pybind11::module& m); +void BindCast(pybind11::module& m); +void BindHWC2CHW(pybind11::module& m); +void BindNormalize(pybind11::module& m); +void BindPadToSize(pybind11::module& m); +void BindResize(pybind11::module& m); +void BindStridePad(pybind11::module& m); void BindProcessors(pybind11::module& m) { auto processors_m = @@ -32,5 +38,11 @@ void BindProcessors(pybind11::module& m) { BindResizeByShort(processors_m); BindCenterCrop(processors_m); BindPad(processors_m); + BindCast(processors_m); + BindHWC2CHW(processors_m); + BindNormalize(processors_m); + BindPadToSize(processors_m); + BindResize(processors_m); + BindStridePad(processors_m); } } // namespace fastdeploy diff --git a/fastdeploy/vision/common/processors/resize_pybind.cc b/fastdeploy/vision/common/processors/resize_pybind.cc new file mode 100644 index 000000000..0d9f4e35a --- /dev/null +++ b/fastdeploy/vision/common/processors/resize_pybind.cc @@ -0,0 +1,23 @@ +// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "fastdeploy/pybind/main.h" + +namespace fastdeploy { +void BindResize(pybind11::module& m) { + pybind11::class_(m, "Resize") + .def(pybind11::init(), + "Default constructor"); +} + +} // namespace fastdeploy \ No newline at end of file diff --git a/fastdeploy/vision/common/processors/stride_pad_pybind.cc b/fastdeploy/vision/common/processors/stride_pad_pybind.cc new file mode 100644 index 000000000..e0afee280 --- /dev/null +++ b/fastdeploy/vision/common/processors/stride_pad_pybind.cc @@ -0,0 +1,22 @@ +// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "fastdeploy/pybind/main.h" + +namespace fastdeploy { +void BindStridePad(pybind11::module& m) { + pybind11::class_(m, "StridePad") + .def(pybind11::init>(), "Default constructor"); +} + +} // namespace fastdeploy \ No newline at end of file diff --git a/python/fastdeploy/vision/common/processors.py b/python/fastdeploy/vision/common/processors.py index d663a72fb..492301523 100644 --- a/python/fastdeploy/vision/common/processors.py +++ b/python/fastdeploy/vision/common/processors.py @@ -4,16 +4,18 @@ from ... import c_lib_wrap as C class Processor(): def __init__(self): - self.processor + self.processor = None def __call__(self, mat): + """call for processing input. + + :param mat: the input data FDMat or FDMatBatch. + """ self.processor(mat) class ResizeByShort(Processor): def __init__(self, target_size: int, interp=1, use_scale=True, max_hw=[]): - self.processor = C.vision.processors.ResizeByShort(target_size, interp, - use_scale, max_hw) """Create a ResizeByShort operation with the given parameters. :param target_size: the target short size to resize the image @@ -21,22 +23,22 @@ class ResizeByShort(Processor): :param use_scale: optionally, whether to scale image :param max_hw: max spatial size which is used by ResizeByShort """ + self.processor = C.vision.processors.ResizeByShort(target_size, interp, + use_scale, max_hw) class CenterCrop(Processor): def __init__(self, width, height): - self.processor = C.vision.processors.CenterCrop(width, height) """Create a CenterCrop operation with the given parameters. :param width: desired width of the cropped image :param height: desired height of the cropped image """ + self.processor = C.vision.processors.CenterCrop(width, height) class Pad(Processor): def __init__(self, top: int, bottom: int, left: int, right: int, value=[]): - self.processor = C.vision.processors.Pad(top, bottom, left, right, - value) """Create a Pad operation with the given parameters. :param top: the top padding @@ -45,6 +47,8 @@ class Pad(Processor): :param right: the right padding :param value: the value that is used to pad on the input image """ + self.processor = C.vision.processors.Pad(top, bottom, left, right, + value) class NormalizeAndPermute(Processor): @@ -55,8 +59,6 @@ class NormalizeAndPermute(Processor): min=[], max=[], swap_rb=False): - self.processor = C.vision.processors.NormalizeAndPermute( - mean, std, is_scale, min, max, swap_rb) """Creae a Normalize and a Permute operation with the given parameters. :param mean A list containing the mean of each channel @@ -65,3 +67,85 @@ class NormalizeAndPermute(Processor): :param min A list containing the minimum value of each channel :param max A list containing the maximum value of each channel """ + self.processor = C.vision.processors.NormalizeAndPermute( + mean, std, is_scale, min, max, swap_rb) + + +class Cast(Processor): + def __init__(self, dtype="float"): + """Creat a new cast opereaton with given dtype + + :param dtype dtype of the output + """ + self.processor = C.vision.processors.Cast(dtype) + + +class HWC2CHW(Processor): + def __init__(self): + """Creat a new hwc2chw processor with default dtype. + + :return An instance of processor `HWC2CHW` + """ + self.processor = C.vision.processors.HWC2CHW() + + +class Normalize(Processor): + def __init__(self, + mean=[], + std=[], + is_scale=True, + min=[], + max=[], + swap_rb=False): + """Creat a new normalize opereator with given paremeters. + + :param mean A list containing the mean of each channel + :param std A list containing the standard deviation of each channel + :param is_scale Specifies if the image are being scaled or not + :param min A list containing the minimum value of each channel + :param max A list containing the maximum value of each channel + """ + self.processor = C.vision.processors.Normalize(mean, std, is_scale, + min, max, swap_rb) + + +class PadToSize(Processor): + def __init__(self, width, height, value=[]): + """Create a new PadToSize opereator with given parameters. + + :param width Desired width of the output image + :param height Desired height of the output image + :param value values to pad with + """ + self.processor = C.vision.processors.PadToSize(width, height, value) + + +class Resize(Processor): + def __init__(self, + width, + height, + scale_w=-1.0, + scale_h=-1.0, + interp=1, + use_scale=False): + """Create a Resize operation with the given parameters. + + :param width Desired width of the output image + :param height Desired height of the output image + :param scale_w Scales the width in x-direction + :param scale_h Scales the height in y-direction + :param interp: optionally, the interpolation mode for resizing image + :param use_scale: optionally, whether to scale image + """ + self.processor = C.vision.processors.Resize(width, height, scale_w, + scale_h, interp, use_scale) + + +class StridePad(Processor): + def __init__(self, stride, value=[]): + """Create a StridePad processor with given parameters. + + :param stride Stride of the processor + :param value values to pad with + """ + self.processor = C.vision.processors.StridePad(stride, value) diff --git a/tutorials/vision_processor/python/preprocess.py b/tutorials/vision_processor/python/preprocess.py index a8a656258..aa643b429 100644 --- a/tutorials/vision_processor/python/preprocess.py +++ b/tutorials/vision_processor/python/preprocess.py @@ -21,7 +21,7 @@ class CustomProcessor(PyProcessorManager): def __init__(self) -> None: super().__init__() # create op - self.resize_op = ResizeByShort( + self.resize_short_op = ResizeByShort( target_size=100, interp=1, use_scale=True, max_hw=[500, 500]) self.normalize_permute_op = NormalizeAndPermute( mean=[0.485, 0.456, 0.406], @@ -31,14 +31,37 @@ class CustomProcessor(PyProcessorManager): max=[], swap_rb=False) self.centercrop_op = CenterCrop(width=50, height=50) - self.pad_op = Pad( - top=5, bottom=5, left=5, right=5, value=[225, 225, 225]) + self.pad_op = Pad(top=5, + bottom=5, + left=5, + right=5, + value=[225, 225, 225]) + self.cast_op = Cast(dtype="float") + self.hwc2chw_op = HWC2CHW() + self.normalize_op = Normalize( + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225], + is_scale=True, + min=[], + max=[], + swap_rb=False) + self.pad_to_size_op = PadToSize( + height=160, width=160, value=[225, 225, 225]) + self.resize_op = Resize( + width=50, + height=50, + scale_w=-1.0, + scale_h=-1.0, + interp=1, + use_scale=False) + self.stride_pad_op = StridePad(stride=3, value=[225, 225, 225]) def apply(self, image_batch): outputs = [] - self.resize_op(image_batch) + self.resize_short_op(image_batch) self.centercrop_op(image_batch) self.pad_op(image_batch) + self.pad_to_size_op(image_batch) self.normalize_permute_op(image_batch) for i in range(len(image_batch.mats)):