From 1684b05b07b104165c2c6916ee45b6289c29740c Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Wed, 13 Jul 2022 13:55:44 +0000 Subject: [PATCH 01/69] first commit for yolov7 --- fastdeploy/vision.h | 1 + fastdeploy/vision/wongkinyiu/__init__.py | 116 +++++++++ .../vision/wongkinyiu/wongkinyiu_pybind.cc | 41 ++++ fastdeploy/vision/wongkinyiu/yolov7.cc | 230 ++++++++++++++++++ fastdeploy/vision/wongkinyiu/yolov7.h | 87 +++++++ model_zoo/vision/yolov7/cpp/CMakeLists.txt | 18 ++ model_zoo/vision/yolov7/cpp/README.md | 30 +++ model_zoo/vision/yolov7/cpp/yolov7.cc | 40 +++ model_zoo/vision/yolov7/yolov7.py | 23 ++ 9 files changed, 586 insertions(+) create mode 100644 fastdeploy/vision/wongkinyiu/__init__.py create mode 100644 fastdeploy/vision/wongkinyiu/wongkinyiu_pybind.cc create mode 100644 fastdeploy/vision/wongkinyiu/yolov7.cc create mode 100644 fastdeploy/vision/wongkinyiu/yolov7.h create mode 100644 model_zoo/vision/yolov7/cpp/CMakeLists.txt create mode 100644 model_zoo/vision/yolov7/cpp/README.md create mode 100644 model_zoo/vision/yolov7/cpp/yolov7.cc create mode 100644 model_zoo/vision/yolov7/yolov7.py diff --git a/fastdeploy/vision.h b/fastdeploy/vision.h index ca2b9a618af..821f3689e5c 100644 --- a/fastdeploy/vision.h +++ b/fastdeploy/vision.h @@ -17,6 +17,7 @@ #ifdef ENABLE_VISION #include "fastdeploy/vision/ppcls/model.h" #include "fastdeploy/vision/ultralytics/yolov5.h" +#include "fastdeploy/vision/wongkinyiu/yolov7.h" #endif #include "fastdeploy/vision/visualize/visualize.h" diff --git a/fastdeploy/vision/wongkinyiu/__init__.py b/fastdeploy/vision/wongkinyiu/__init__.py new file mode 100644 index 00000000000..e3ed7730e66 --- /dev/null +++ b/fastdeploy/vision/wongkinyiu/__init__.py @@ -0,0 +1,116 @@ +# 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. + +from __future__ import absolute_import +import logging +from ... import FastDeployModel, Frontend +from ... import fastdeploy_main as C + + +class YOLOv7(FastDeployModel): + def __init__(self, + model_file, + params_file="", + runtime_option=None, + model_format=Frontend.ONNX): + # 调用基函数进行backend_option的初始化 + # 初始化后的option保存在self._runtime_option + super(YOLOv7, self).__init__(runtime_option) + + self._model = C.vision.yongkinyiu.YOLOv7( + model_file, params_file, self._runtime_option, model_format) + # 通过self.initialized判断整个模型的初始化是否成功 + assert self.initialized, "YOLOv7 initialize failed." + + def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): + return self._model.predict(input_image, conf_threshold, + nms_iou_threshold) + + # 一些跟YOLOv7模型有关的属性封装 + # 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持) + @property + def size(self): + return self.model.size + + @property + def padding_value(self): + return self.model.padding_value + + @property + def is_no_pad(self): + return self.model.is_no_pad + + @property + def is_mini_pad(self): + return self.model.is_mini_pad + + @property + def is_scale_up(self): + return self.model.is_scale_up + + @property + def stride(self): + return self.model.stride + + @property + def max_wh(self): + return self.model.max_wh + + @size.setter + def size(self, wh): + assert isinstance(wh, [list, tuple]),\ + "The value to set `size` must be type of tuple or list." + assert len(wh) == 2,\ + "The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format( + len(wh)) + self.model.size = wh + + @padding_value.setter + def padding_value(self, value): + assert isinstance( + value, + list), "The value to set `padding_value` must be type of list." + self.model.padding_value = value + + @is_no_pad.setter + def is_no_pad(self, value): + assert isinstance( + value, bool), "The value to set `is_no_pad` must be type of bool." + self.model.is_no_pad = value + + @is_mini_pad.setter + def is_mini_pad(self, value): + assert isinstance( + value, + bool), "The value to set `is_mini_pad` must be type of bool." + self.model.is_mini_pad = value + + @is_scale_up.setter + def is_scale_up(self, value): + assert isinstance( + value, + bool), "The value to set `is_scale_up` must be type of bool." + self.model.is_scale_up = value + + @stride.setter + def stride(self, value): + assert isinstance( + value, int), "The value to set `stride` must be type of int." + self.model.stride = value + + @max_wh.setter + def max_wh(self, value): + assert isinstance( + value, float), "The value to set `max_wh` must be type of float." + self.model.max_wh = value diff --git a/fastdeploy/vision/wongkinyiu/wongkinyiu_pybind.cc b/fastdeploy/vision/wongkinyiu/wongkinyiu_pybind.cc new file mode 100644 index 00000000000..99f0aab6281 --- /dev/null +++ b/fastdeploy/vision/wongkinyiu/wongkinyiu_pybind.cc @@ -0,0 +1,41 @@ +// 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 BindWongkinyiu(pybind11::module& m) { + auto yongkinyiu_module = + m.def_submodule("WongKinYiu", "https://github.com/WongKinYiu/yolov7"); + pybind11::class_( + yongkinyiu_module, "YOLOv7") + .def(pybind11::init()) + .def("predict", + [](vision::yongkinyiu::YOLOv7& self, pybind11::array& data, + float conf_threshold, float nms_iou_threshold) { + auto mat = PyArrayToCvMat(data); + vision::DetectionResult res; + self.Predict(&mat, &res, conf_threshold, nms_iou_threshold); + return res; + }) + .def_readwrite("size", &vision::yongkinyiu::YOLOv7::size) + .def_readwrite("padding_value", + &vision::yongkinyiu::YOLOv7::padding_value) + .def_readwrite("is_mini_pad", &vision::yongkinyiu::YOLOv7::is_mini_pad) + .def_readwrite("is_no_pad", &vision::yongkinyiu::YOLOv7::is_no_pad) + .def_readwrite("is_scale_up", &vision::yongkinyiu::YOLOv7::is_scale_up) + .def_readwrite("stride", &vision::yongkinyiu::YOLOv7::stride) + .def_readwrite("max_wh", &vision::yongkinyiu::YOLOv7::max_wh); +} +} // namespace fastdeploy diff --git a/fastdeploy/vision/wongkinyiu/yolov7.cc b/fastdeploy/vision/wongkinyiu/yolov7.cc new file mode 100644 index 00000000000..09004b5c3ca --- /dev/null +++ b/fastdeploy/vision/wongkinyiu/yolov7.cc @@ -0,0 +1,230 @@ +#include "fastdeploy/vision/WongKinYiu/yolov7.h" +#include "fastdeploy/utils/perf.h" +#include "fastdeploy/vision/utils/utils.h" + +namespace fastdeploy { +namespace vision { +namespace wongkinyiu { + +void LetterBox(Mat* mat, std::vector size, std::vector color, + bool _auto, bool scale_fill = false, bool scale_up = true, + int stride = 32) { + float scale = + std::min(size[1] * 1.0 / mat->Height(), size[0] * 1.0 / mat->Width()); + if (!scale_up) { + scale = std::min(scale, 1.0f); + } + + int resize_h = int(round(mat->Height() * scale)); + int resize_w = int(round(mat->Width() * scale)); + + int pad_w = size[0] - resize_w; + int pad_h = size[1] - resize_h; + if (_auto) { + pad_h = pad_h % stride; + pad_w = pad_w % stride; + } else if (scale_fill) { + pad_h = 0; + pad_w = 0; + resize_h = size[1]; + resize_w = size[0]; + } + Resize::Run(mat, resize_w, resize_h); + if (pad_h > 0 || pad_w > 0) { + float half_h = pad_h * 1.0 / 2; + int top = int(round(half_h - 0.1)); + int bottom = int(round(half_h + 0.1)); + float half_w = pad_w * 1.0 / 2; + int left = int(round(half_w - 0.1)); + int right = int(round(half_w + 0.1)); + Pad::Run(mat, top, bottom, left, right, color); + } +} + +YOLOv7::YOLOv7(const std::string& model_file, const std::string& params_file, + const RuntimeOption& custom_option, + const Frontend& model_format) { + if (model_format == Frontend::ONNX) { + valid_cpu_backends = {Backend::ORT}; // 指定可用的CPU后端 + valid_gpu_backends = {Backend::ORT, Backend::TRT}; // 指定可用的GPU后端 + } else { + valid_cpu_backends = {Backend::PDINFER, Backend::ORT}; + valid_gpu_backends = {Backend::PDINFER, Backend::ORT, Backend::TRT}; + } + runtime_option = custom_option; + runtime_option.model_format = model_format; + runtime_option.model_file = model_file; + runtime_option.params_file = params_file; + initialized = Initialize(); +} + +bool YOLOv7::Initialize() { + // parameters for preprocess + size = {640, 640}; + padding_value = {114.0, 114.0, 114.0}; + is_mini_pad = false; + is_no_pad = false; + is_scale_up = false; + stride = 32; + max_wh = 7680.0; + + if (!InitRuntime()) { + FDERROR << "Failed to initialize fastdeploy backend." << std::endl; + return false; + } + return true; +} + +bool YOLOv7::Preprocess(Mat* mat, FDTensor* output, + std::map>* im_info) { + // process after image load + double ratio = (size[0] * 1.0) / std::max(static_cast(mat->Height()), + static_cast(mat->Width())); + if (ratio != 1.0) { + int interp = cv::INTER_AREA; + if (ratio > 1.0) { + interp = cv::INTER_LINEAR; + } + int resize_h = int(mat->Height() * ratio); + int resize_w = int(mat->Width() * ratio); + Resize::Run(mat, resize_w, resize_h, -1, -1, interp); + } + // yolov7's preprocess steps + // 1. letterbox + // 2. BGR->RGB + // 3. HWC->CHW + LetterBox(mat, size, padding_value, is_mini_pad, is_no_pad, is_scale_up, + stride); + BGR2RGB::Run(mat); + Normalize::Run(mat, std::vector(mat->Channels(), 0.0), + std::vector(mat->Channels(), 1.0)); + + // Record output shape of preprocessed image + (*im_info)["output_shape"] = {static_cast(mat->Height()), + static_cast(mat->Width())}; + + HWC2CHW::Run(mat); + Cast::Run(mat, "float"); + mat->ShareWithTensor(output); + output->shape.insert(output->shape.begin(), 1); // reshape to n, h, w, c + return true; +} + +bool YOLOv7::Postprocess( + FDTensor& infer_result, DetectionResult* result, + const std::map>& im_info, + float conf_threshold, float nms_iou_threshold) { + FDASSERT(infer_result.shape[0] == 1, "Only support batch =1 now."); + result->Clear(); + result->Reserve(infer_result.shape[1]); + if (infer_result.dtype != FDDataType::FP32) { + FDERROR << "Only support post process with float32 data." << std::endl; + return false; + } + float* data = static_cast(infer_result.Data()); + for (size_t i = 0; i < infer_result.shape[1]; ++i) { + int s = i * infer_result.shape[2]; + float confidence = data[s + 4]; + float* max_class_score = + std::max_element(data + s + 5, data + s + infer_result.shape[2]); + confidence *= (*max_class_score); + // filter boxes by conf_threshold + if (confidence <= conf_threshold) { + continue; + } + int32_t label_id = std::distance(data + s + 5, max_class_score); + // convert from [x, y, w, h] to [x1, y1, x2, y2] + result->boxes.emplace_back(std::array{ + data[s] - data[s + 2] / 2.0f + label_id * max_wh, + data[s + 1] - data[s + 3] / 2.0f + label_id * max_wh, + data[s + 0] + data[s + 2] / 2.0f + label_id * max_wh, + data[s + 1] + data[s + 3] / 2.0f + label_id * max_wh}); + result->label_ids.push_back(label_id); + result->scores.push_back(confidence); + } + utils::NMS(result, nms_iou_threshold); + + // scale the boxes to the origin image shape + auto iter_out = im_info.find("output_shape"); + auto iter_ipt = im_info.find("input_shape"); + FDASSERT(iter_out != im_info.end() && iter_ipt != im_info.end(), + "Cannot find input_shape or output_shape from im_info."); + float out_h = iter_out->second[0]; + float out_w = iter_out->second[1]; + float ipt_h = iter_ipt->second[0]; + float ipt_w = iter_ipt->second[1]; + float scale = std::min(out_h / ipt_h, out_w / ipt_w); + for (size_t i = 0; i < result->boxes.size(); ++i) { + float pad_h = (out_h - ipt_h * scale) / 2; + float pad_w = (out_w - ipt_w * scale) / 2; + int32_t label_id = (result->label_ids)[i]; + // clip box + result->boxes[i][0] = result->boxes[i][0] - max_wh * label_id; + result->boxes[i][1] = result->boxes[i][1] - max_wh * label_id; + result->boxes[i][2] = result->boxes[i][2] - max_wh * label_id; + result->boxes[i][3] = result->boxes[i][3] - max_wh * label_id; + result->boxes[i][0] = std::max((result->boxes[i][0] - pad_w) / scale, 0.0f); + result->boxes[i][1] = std::max((result->boxes[i][1] - pad_h) / scale, 0.0f); + result->boxes[i][2] = std::max((result->boxes[i][2] - pad_w) / scale, 0.0f); + result->boxes[i][3] = std::max((result->boxes[i][3] - pad_h) / scale, 0.0f); + result->boxes[i][0] = std::min(result->boxes[i][0], ipt_w); + result->boxes[i][1] = std::min(result->boxes[i][1], ipt_h); + result->boxes[i][2] = std::min(result->boxes[i][2], ipt_w); + result->boxes[i][3] = std::min(result->boxes[i][3], ipt_h); + } + return true; +} + +bool YOLOv7::Predict(cv::Mat* im, DetectionResult* result, float conf_threshold, + float nms_iou_threshold) { +#ifdef FASTDEPLOY_DEBUG + TIMERECORD_START(0) +#endif + + Mat mat(*im); + std::vector input_tensors(1); + + std::map> im_info; + + // Record the shape of image and the shape of preprocessed image + im_info["input_shape"] = {static_cast(mat.Height()), + static_cast(mat.Width())}; + im_info["output_shape"] = {static_cast(mat.Height()), + static_cast(mat.Width())}; + + if (!Preprocess(&mat, &input_tensors[0], &im_info)) { + FDERROR << "Failed to preprocess input image." << std::endl; + return false; + } + +#ifdef FASTDEPLOY_DEBUG + TIMERECORD_END(0, "Preprocess") + TIMERECORD_START(1) +#endif + + input_tensors[0].name = InputInfoOfRuntime(0).name; + std::vector output_tensors; + if (!Infer(input_tensors, &output_tensors)) { + FDERROR << "Failed to inference." << std::endl; + return false; + } +#ifdef FASTDEPLOY_DEBUG + TIMERECORD_END(1, "Inference") + TIMERECORD_START(2) +#endif + + if (!Postprocess(output_tensors[0], result, im_info, conf_threshold, + nms_iou_threshold)) { + FDERROR << "Failed to post process." << std::endl; + return false; + } + +#ifdef FASTDEPLOY_DEBUG + TIMERECORD_END(2, "Postprocess") +#endif + return true; +} + +} // namespace wongkinyiu +} // namespace vision +} // namespace fastdeploy diff --git a/fastdeploy/vision/wongkinyiu/yolov7.h b/fastdeploy/vision/wongkinyiu/yolov7.h new file mode 100644 index 00000000000..b21c04936a3 --- /dev/null +++ b/fastdeploy/vision/wongkinyiu/yolov7.h @@ -0,0 +1,87 @@ +// 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. + +#pragma once +#include "fastdeploy/fastdeploy_model.h" +#include "fastdeploy/vision/common/processors/transform.h" +#include "fastdeploy/vision/common/result.h" + +namespace fastdeploy { +namespace vision { +namespace wongkinyiu { + +class FASTDEPLOY_DECL YOLOv7 : public FastDeployModel { + public: + // 当model_format为ONNX时,无需指定params_file + // 当model_format为Paddle时,则需同时指定model_file & params_file + YOLOv7(const std::string& model_file, const std::string& params_file = "", + const RuntimeOption& custom_option = RuntimeOption(), + const Frontend& model_format = Frontend::ONNX); + + // 定义模型的名称 + virtual std::string ModelName() const { return "WongKinYiu/yolov7"; } + + // 初始化函数,包括初始化后端,以及其它模型推理需要涉及的操作 + virtual bool Initialize(); + + // 输入图像预处理操作 + // Mat为FastDeploy定义的数据结构 + // FDTensor为预处理后的Tensor数据,传给后端进行推理 + // im_info为预处理过程保存的数据,在后处理中需要用到 + virtual bool Preprocess(Mat* mat, FDTensor* outputs, + std::map>* im_info); + + // 后端推理结果后处理,输出给用户 + // infer_result 为后端推理后的输出Tensor + // result 为模型预测的结果 + // im_info 为预处理记录的信息,后处理用于还原box + // conf_threshold 后处理时过滤box的置信度阈值 + // nms_iou_threshold 后处理时NMS设定的iou阈值 + virtual bool Postprocess( + FDTensor& infer_result, DetectionResult* result, + const std::map>& im_info, + float conf_threshold, float nms_iou_threshold); + + // 模型预测接口,即用户调用的接口 + // im 为用户的输入数据,目前对于CV均定义为cv::Mat + // result 为模型预测的输出结构体 + // conf_threshold 为后处理的参数 + // nms_iou_threshold 为后处理的参数 + virtual bool Predict(cv::Mat* im, DetectionResult* result, + float conf_threshold = 0.25, + float nms_iou_threshold = 0.5); + + // 以下为模型在预测时的一些参数,基本是前后处理所需 + // 用户在创建模型后,可根据模型的要求,以及自己的需求 + // 对参数进行修改 + // tuple of (width, height) + std::vector size; + // padding value, size should be same with Channels + std::vector padding_value; + // only pad to the minimum rectange which height and width is times of stride + bool is_mini_pad; + // while is_mini_pad = false and is_no_pad = true, will resize the image to + // the set size + bool is_no_pad; + // if is_scale_up is false, the input image only can be zoom out, the maximum + // resize scale cannot exceed 1.0 + bool is_scale_up; + // padding stride, for is_mini_pad + int stride; + // for offseting the boxes by classes when using NMS + float max_wh; +}; +} // namespace wongkinyiu +} // namespace vision +} // namespace fastdeploy diff --git a/model_zoo/vision/yolov7/cpp/CMakeLists.txt b/model_zoo/vision/yolov7/cpp/CMakeLists.txt new file mode 100644 index 00000000000..b3b790698c1 --- /dev/null +++ b/model_zoo/vision/yolov7/cpp/CMakeLists.txt @@ -0,0 +1,18 @@ +PROJECT(yolov7_demo C CXX) +CMAKE_MINIMUM_REQUIRED (VERSION 3.16) + +# 在低版本ABI环境中,通过如下代码进行兼容性编译 +# add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) + +# 指定下载解压后的fastdeploy库路径 +set(FASTDEPLOY_INSTALL_DIR /home/fastdeploy/FastDeploy/build/fastdeploy-0.0.3/) + +include(${FASTDEPLOY_INSTALL_DIR}/FastDeploy.cmake) + +# 添加FastDeploy依赖头文件 +include_directories(${FASTDEPLOY_INCS}) + +add_executable(yolov7_demo ${PROJECT_SOURCE_DIR}/yolov7.cc) +# 添加FastDeploy库依赖 +target_link_libraries(yolov7_demo ${FASTDEPLOY_LIBS}) + diff --git a/model_zoo/vision/yolov7/cpp/README.md b/model_zoo/vision/yolov7/cpp/README.md new file mode 100644 index 00000000000..dd740ff58aa --- /dev/null +++ b/model_zoo/vision/yolov7/cpp/README.md @@ -0,0 +1,30 @@ +# 编译YOLOv5示例 + + +``` +# 下载和解压预测库 +wget https://bj.bcebos.com/paddle2onnx/fastdeploy/fastdeploy-linux-x64-0.0.3.tgz +tar xvf fastdeploy-linux-x64-0.0.3.tgz + +# 编译示例代码 +mkdir build & cd build +cmake .. +make -j + +# 下载模型和图片 +wget https://github.com/ultralytics/yolov5/releases/download/v6.0/yolov5s.onnx +wget https://raw.githubusercontent.com/ultralytics/yolov5/master/data/images/bus.jpg + +# 执行 +./yolov5_demo +``` + +执行完后可视化的结果保存在本地`vis_result.jpg`,同时会将检测框输出在终端,如下所示 +``` +DetectionResult: [xmin, ymin, xmax, ymax, score, label_id] +223.395142,403.948669, 345.337189, 867.339050, 0.856906, 0 +668.301758,400.781342, 808.441772, 882.534973, 0.829716, 0 +50.210720,398.571411, 243.123367, 905.016602, 0.805375, 0 +23.768242,214.979370, 802.627686, 778.840881, 0.756311, 5 +0.737200,552.281006, 78.617218, 890.945007, 0.363471, 0 +``` diff --git a/model_zoo/vision/yolov7/cpp/yolov7.cc b/model_zoo/vision/yolov7/cpp/yolov7.cc new file mode 100644 index 00000000000..4b899728597 --- /dev/null +++ b/model_zoo/vision/yolov7/cpp/yolov7.cc @@ -0,0 +1,40 @@ +// 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/vision.h" + +int main() { + namespace vis = fastdeploy::vision; + auto model = vis::wongkinyiu::YOLOv7("/home/fastdeploy/yolov7/onnxfiles/yolov7.onnx"); + if (!model.Initialized()) { + std::cerr << "Init Failed." << std::endl; + return -1; + } + cv::Mat im = cv::imread("bus.jpg"); + cv::Mat vis_im = im.clone(); + + vis::DetectionResult res; + if (!model.Predict(&im, &res)) { + std::cerr << "Prediction Failed." << std::endl; + return -1; + } + + // 输出预测框结果 + std::cout << res.Str() << std::endl; + + // 可视化预测结果 + vis::Visualize::VisDetection(&vis_im, res); + cv::imwrite("vis_result.jpg", vis_im); + return 0; +} diff --git a/model_zoo/vision/yolov7/yolov7.py b/model_zoo/vision/yolov7/yolov7.py new file mode 100644 index 00000000000..c502c663661 --- /dev/null +++ b/model_zoo/vision/yolov7/yolov7.py @@ -0,0 +1,23 @@ +import fastdeploy as fd +import cv2 + +# 下载模型和测试图片 +model_url = "https://github.com/ultralytics/yolov5/releases/download/v6.0/yolov5s.onnx" +test_jpg_url = "https://raw.githubusercontent.com/ultralytics/yolov5/master/data/images/bus.jpg" +fd.download(model_url, ".", show_progress=True) +fd.download(test_jpg_url, ".", show_progress=True) + +# 加载模型 +model = fd.vision.ultralytics.YOLOv5("yolov5s.onnx") + +# 预测图片 +im = cv2.imread("bus.jpg") +result = model.predict(im, conf_threshold=0.25, nms_iou_threshold=0.5) + +# 可视化结果 +fd.vision.visualize.vis_detection(im, result) +cv2.imwrite("vis_result.jpg", im) + +# 输出预测结果 +print(result) +print(model.runtime_option) From 71c00d94e12c6a52afc1342de893bec2f7850ae2 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Thu, 14 Jul 2022 07:02:55 +0000 Subject: [PATCH 02/69] pybind for yolov7 --- fastdeploy/vision/__init__.py | 1 + fastdeploy/vision/vision_pybind.cc | 2 ++ fastdeploy/vision/wongkinyiu/__init__.py | 2 +- .../vision/wongkinyiu/wongkinyiu_pybind.cc | 24 +++++++++---------- model_zoo/vision/yolov7/yolov7.py | 8 +++---- 5 files changed, 20 insertions(+), 17 deletions(-) diff --git a/fastdeploy/vision/__init__.py b/fastdeploy/vision/__init__.py index 810b23cd3db..1ea30c35ae0 100644 --- a/fastdeploy/vision/__init__.py +++ b/fastdeploy/vision/__init__.py @@ -17,3 +17,4 @@ from . import ppcls from . import ultralytics from . import visualize +from . import wongkinyiu diff --git a/fastdeploy/vision/vision_pybind.cc b/fastdeploy/vision/vision_pybind.cc index f3c3f0052da..5d79ffb2a6d 100644 --- a/fastdeploy/vision/vision_pybind.cc +++ b/fastdeploy/vision/vision_pybind.cc @@ -17,6 +17,7 @@ namespace fastdeploy { void BindPpClsModel(pybind11::module& m); +void BindWongkinyiu(pybind11::module& m); void BindUltralytics(pybind11::module& m); #ifdef ENABLE_VISION_VISUALIZE void BindVisualize(pybind11::module& m); @@ -40,6 +41,7 @@ void BindVision(pybind11::module& m) { BindPpClsModel(m); BindUltralytics(m); + BindWongkinyiu(m); BindVisualize(m); } } // namespace fastdeploy diff --git a/fastdeploy/vision/wongkinyiu/__init__.py b/fastdeploy/vision/wongkinyiu/__init__.py index e3ed7730e66..0ce06209fc6 100644 --- a/fastdeploy/vision/wongkinyiu/__init__.py +++ b/fastdeploy/vision/wongkinyiu/__init__.py @@ -28,7 +28,7 @@ def __init__(self, # 初始化后的option保存在self._runtime_option super(YOLOv7, self).__init__(runtime_option) - self._model = C.vision.yongkinyiu.YOLOv7( + self._model = C.vision.wongkinyiu.YOLOv7( model_file, params_file, self._runtime_option, model_format) # 通过self.initialized判断整个模型的初始化是否成功 assert self.initialized, "YOLOv7 initialize failed." diff --git a/fastdeploy/vision/wongkinyiu/wongkinyiu_pybind.cc b/fastdeploy/vision/wongkinyiu/wongkinyiu_pybind.cc index 99f0aab6281..4a10f47a763 100644 --- a/fastdeploy/vision/wongkinyiu/wongkinyiu_pybind.cc +++ b/fastdeploy/vision/wongkinyiu/wongkinyiu_pybind.cc @@ -16,26 +16,26 @@ namespace fastdeploy { void BindWongkinyiu(pybind11::module& m) { - auto yongkinyiu_module = - m.def_submodule("WongKinYiu", "https://github.com/WongKinYiu/yolov7"); - pybind11::class_( - yongkinyiu_module, "YOLOv7") + auto wongkinyiu_module = + m.def_submodule("wongkinyiu", "https://github.com/WongKinYiu/yolov7"); + pybind11::class_( + wongkinyiu_module, "YOLOv7") .def(pybind11::init()) .def("predict", - [](vision::yongkinyiu::YOLOv7& self, pybind11::array& data, + [](vision::wongkinyiu::YOLOv7& self, pybind11::array& data, float conf_threshold, float nms_iou_threshold) { auto mat = PyArrayToCvMat(data); vision::DetectionResult res; self.Predict(&mat, &res, conf_threshold, nms_iou_threshold); return res; }) - .def_readwrite("size", &vision::yongkinyiu::YOLOv7::size) + .def_readwrite("size", &vision::wongkinyiu::YOLOv7::size) .def_readwrite("padding_value", - &vision::yongkinyiu::YOLOv7::padding_value) - .def_readwrite("is_mini_pad", &vision::yongkinyiu::YOLOv7::is_mini_pad) - .def_readwrite("is_no_pad", &vision::yongkinyiu::YOLOv7::is_no_pad) - .def_readwrite("is_scale_up", &vision::yongkinyiu::YOLOv7::is_scale_up) - .def_readwrite("stride", &vision::yongkinyiu::YOLOv7::stride) - .def_readwrite("max_wh", &vision::yongkinyiu::YOLOv7::max_wh); + &vision::wongkinyiu::YOLOv7::padding_value) + .def_readwrite("is_mini_pad", &vision::wongkinyiu::YOLOv7::is_mini_pad) + .def_readwrite("is_no_pad", &vision::wongkinyiu::YOLOv7::is_no_pad) + .def_readwrite("is_scale_up", &vision::wongkinyiu::YOLOv7::is_scale_up) + .def_readwrite("stride", &vision::wongkinyiu::YOLOv7::stride) + .def_readwrite("max_wh", &vision::wongkinyiu::YOLOv7::max_wh); } } // namespace fastdeploy diff --git a/model_zoo/vision/yolov7/yolov7.py b/model_zoo/vision/yolov7/yolov7.py index c502c663661..81c529b15b1 100644 --- a/model_zoo/vision/yolov7/yolov7.py +++ b/model_zoo/vision/yolov7/yolov7.py @@ -2,16 +2,16 @@ import cv2 # 下载模型和测试图片 -model_url = "https://github.com/ultralytics/yolov5/releases/download/v6.0/yolov5s.onnx" -test_jpg_url = "https://raw.githubusercontent.com/ultralytics/yolov5/master/data/images/bus.jpg" +model_url = "TODO " +test_jpg_url = "https://github.com/WongKinYiu/yolov7/blob/main/inference/images/horses.jpg" fd.download(model_url, ".", show_progress=True) fd.download(test_jpg_url, ".", show_progress=True) # 加载模型 -model = fd.vision.ultralytics.YOLOv5("yolov5s.onnx") +model = fd.vision.wongkinyiu.YOLOv7("yolov7.onnx") # 预测图片 -im = cv2.imread("bus.jpg") +im = cv2.imread("horses.jpg") result = model.predict(im, conf_threshold=0.25, nms_iou_threshold=0.5) # 可视化结果 From 21ab2f939c8e1469f320826808c5d430234e25fd Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Thu, 14 Jul 2022 07:14:03 +0000 Subject: [PATCH 03/69] CPP README.md --- model_zoo/vision/yolov7/cpp/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/model_zoo/vision/yolov7/cpp/README.md b/model_zoo/vision/yolov7/cpp/README.md index dd740ff58aa..f19c0625d10 100644 --- a/model_zoo/vision/yolov7/cpp/README.md +++ b/model_zoo/vision/yolov7/cpp/README.md @@ -12,11 +12,11 @@ cmake .. make -j # 下载模型和图片 -wget https://github.com/ultralytics/yolov5/releases/download/v6.0/yolov5s.onnx -wget https://raw.githubusercontent.com/ultralytics/yolov5/master/data/images/bus.jpg +wget "TODO" +wget https://github.com/WongKinYiu/yolov7/blob/main/inference/images/horses.jpg # 执行 -./yolov5_demo +./yolov7_demo ``` 执行完后可视化的结果保存在本地`vis_result.jpg`,同时会将检测框输出在终端,如下所示 From d63e862f919d0ce9025f78271a03e9a122d2ccdd Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Thu, 14 Jul 2022 07:14:30 +0000 Subject: [PATCH 04/69] CPP README.md --- model_zoo/vision/yolov7/cpp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model_zoo/vision/yolov7/cpp/README.md b/model_zoo/vision/yolov7/cpp/README.md index f19c0625d10..b43d4381e57 100644 --- a/model_zoo/vision/yolov7/cpp/README.md +++ b/model_zoo/vision/yolov7/cpp/README.md @@ -1,4 +1,4 @@ -# 编译YOLOv5示例 +# 编译YOLOv7示例 ``` From 7b3b0e271072987f11fb8ffabdc8d276cf878fa0 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Thu, 14 Jul 2022 09:54:30 +0000 Subject: [PATCH 05/69] modified yolov7.cc --- fastdeploy/vision/wongkinyiu/yolov7.cc | 2 +- model_zoo/vision/yolov7/cpp/CMakeLists.txt | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/fastdeploy/vision/wongkinyiu/yolov7.cc b/fastdeploy/vision/wongkinyiu/yolov7.cc index 09004b5c3ca..6baf4c336b4 100644 --- a/fastdeploy/vision/wongkinyiu/yolov7.cc +++ b/fastdeploy/vision/wongkinyiu/yolov7.cc @@ -1,4 +1,4 @@ -#include "fastdeploy/vision/WongKinYiu/yolov7.h" +#include "fastdeploy/vision/wongkinyiu/yolov7.h" #include "fastdeploy/utils/perf.h" #include "fastdeploy/vision/utils/utils.h" diff --git a/model_zoo/vision/yolov7/cpp/CMakeLists.txt b/model_zoo/vision/yolov7/cpp/CMakeLists.txt index b3b790698c1..09f07b1748a 100644 --- a/model_zoo/vision/yolov7/cpp/CMakeLists.txt +++ b/model_zoo/vision/yolov7/cpp/CMakeLists.txt @@ -5,7 +5,7 @@ CMAKE_MINIMUM_REQUIRED (VERSION 3.16) # add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) # 指定下载解压后的fastdeploy库路径 -set(FASTDEPLOY_INSTALL_DIR /home/fastdeploy/FastDeploy/build/fastdeploy-0.0.3/) +set(FASTDEPLOY_INSTALL_DIR /home/fastdeploy/FastDeploy/build/fastdeploy-0.0.3) include(${FASTDEPLOY_INSTALL_DIR}/FastDeploy.cmake) @@ -14,5 +14,4 @@ include_directories(${FASTDEPLOY_INCS}) add_executable(yolov7_demo ${PROJECT_SOURCE_DIR}/yolov7.cc) # 添加FastDeploy库依赖 -target_link_libraries(yolov7_demo ${FASTDEPLOY_LIBS}) - +target_link_libraries(yolov7_demo ${FASTDEPLOY_LIBS}) \ No newline at end of file From d039e800190e484c583509c3b0e97eb2222f32e9 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Fri, 15 Jul 2022 05:11:01 +0000 Subject: [PATCH 06/69] README.md --- model_zoo/vision/yolov7/README.md | 80 +++++++++++++++++++++++++++++++ model_zoo/vision/yolov7/api.md | 71 +++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 model_zoo/vision/yolov7/README.md create mode 100644 model_zoo/vision/yolov7/api.md diff --git a/model_zoo/vision/yolov7/README.md b/model_zoo/vision/yolov7/README.md new file mode 100644 index 00000000000..80f9aa0facb --- /dev/null +++ b/model_zoo/vision/yolov7/README.md @@ -0,0 +1,80 @@ +# 编译YOLOv7示例 + +本文档说明如何进行[YOLOv7](https://github.com/WongKinYiu/yolov7)的快速部署推理。本目录结构如下 + +``` +. +├── cpp +│   ├── CMakeLists.txt +│   ├── README.md +│   └── yolov7.cc +├── README.md +└── yolov7.py +``` + +## 生成ONNX文件 + +- 手动获取 + + 访问[YOLOv7](https://github.com/WongKinYiu/yolov7)官方github库,按照指引下载安装,下载`yolov7.pt` 模型,利用 `models/export.py` 得到`onnx`格式文件。 + + + + ``` + #下载yolov7模型文件 + wget https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7.pt + + # 导出onnx格式文件 + python models/export.py --grid --dynamic --weights PATH/TO/yolo7.pt + ``` + + + +- 从PaddlePaddle获取 + +## Python部署 + +### 安装FastDeploy + +使用如下命令安装FastDeploy,注意到此处安装的是`vision-cpu`,也可根据需求安装`vision-gpu` + +``` +# 安装fastdeploy-python工具 +pip install fastdeploy-python + +# 安装vision-cpu模块 +fastdeploy install vision-cpu +``` + +### 运行demo + +``` +python yolov7.py +``` + + + +## C++部署 + +### 编译demo文件 + +``` +# 切换到./cpp/ 目录下 +cd cpp/ + +# 下载和解压预测库 +wget https://bj.bcebos.com/paddle2onnx/fastdeploy/fastdeploy-linux-x64-0.0.3.tgz +tar xvf fastdeploy-linux-x64-0.0.3.tgz + +# 编译示例代码 +mkdir build & cd build +cmake .. +make -j +``` + + + + + + + diff --git a/model_zoo/vision/yolov7/api.md b/model_zoo/vision/yolov7/api.md new file mode 100644 index 00000000000..898a3f585f5 --- /dev/null +++ b/model_zoo/vision/yolov7/api.md @@ -0,0 +1,71 @@ +# YOLOv7 API说明 + +## Python API + +### YOLOv7类 +``` +fastdeploy.vision.ultralytics.YOLOv7(model_file, params_file=None, runtime_option=None, model_format=fd.Frontend.ONNX) +``` +YOLOv7模型加载和初始化,当model_format为`fd.Frontend.ONNX`时,只需提供model_file,如`yolov7s.onnx`;当model_format为`fd.Frontend.PADDLE`时,则需同时提供model_file和params_file。 + +**参数** + +> * **model_file**(str): 模型文件路径 +> * **params_file**(str): 参数文件路径 +> * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置 +> * **model_format**(Frontend): 模型格式 + +#### predict函数 +> ``` +> YOLOv7.predict(image_data, conf_threshold=0.25, nms_iou_threshold=0.5) +> ``` +> 模型预测结口,输入图像直接输出检测结果。 +> +> **参数** +> +> > * **image_data**(np.ndarray): 输入数据,注意需为HWC,RGB格式 +> > * **conf_threshold**(float): 检测框置信度过滤阈值 +> > * **nms_iou_threshold**(float): NMS处理过程中iou阈值 + +示例代码参考[yolov7.py](./yolov7.py) + + +## C++ API + +### YOLOv7类 +``` +fastdeploy::vision::ultralytics::YOLOv7( + const string& model_file, + const string& params_file = "", + const RuntimeOption& runtime_option = RuntimeOption(), + const Frontend& model_format = Frontend::ONNX) +``` +YOLOv7模型加载和初始化,当model_format为`Frontend::ONNX`时,只需提供model_file,如`yolov7s.onnx`;当model_format为`Frontend::PADDLE`时,则需同时提供model_file和params_file。 + +**参数** + +> * **model_file**(str): 模型文件路径 +> * **params_file**(str): 参数文件路径 +> * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置 +> * **model_format**(Frontend): 模型格式 + +#### predict函数 +> ``` +> YOLOv7::predict(cv::Mat* im, DetectionResult* result, +> float conf_threshold = 0.25, +> float nms_iou_threshold = 0.5) +> ``` +> 模型预测接口,输入图像直接输出检测结果。 +> +> **参数** +> +> > * **im**: 输入图像,注意需为HWC,RGB格式 +> > * **result**: 检测结果,包括检测框,各个框的置信度 +> > * **conf_threshold**: 检测框置信度过滤阈值 +> > * **nms_iou_threshold**: NMS处理过程中iou阈值 + +示例代码参考[cpp/yolov7.cc](cpp/yolov7.cc) + +## 其它API使用 + +- [模型部署RuntimeOption配置](../../../docs/api/runtime_option.md) From a34a815de844834bfcacc8154ab206587b9a7b0b Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 03:14:38 +0000 Subject: [PATCH 07/69] python file modify --- fastdeploy/LICENSE | 201 +++++++ fastdeploy/ThirdPartyNotices.txt | 734 +++++++++++++++++++++++ fastdeploy/vision/wongkinyiu/__init__.py | 28 +- model_zoo/vision/yolov7/yolov7.py | 8 +- 4 files changed, 953 insertions(+), 18 deletions(-) create mode 100644 fastdeploy/LICENSE create mode 100644 fastdeploy/ThirdPartyNotices.txt diff --git a/fastdeploy/LICENSE b/fastdeploy/LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/fastdeploy/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/fastdeploy/ThirdPartyNotices.txt b/fastdeploy/ThirdPartyNotices.txt new file mode 100644 index 00000000000..5842b9a7179 --- /dev/null +++ b/fastdeploy/ThirdPartyNotices.txt @@ -0,0 +1,734 @@ +This project depends on some open source projects, list as below + +-------- +1. https://github.com/protocolbuffers/protobuf + +Copyright 2008 Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Code generated by the Protocol Buffer compiler is owned by the owner +of the input file used when generating it. This code is not +standalone and requires a support library to be linked with it. This +support library is itself covered by the above license. + +-------- +2. https://github.com/onnx/onnx + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + +-------- +3. https://github.com/microsoft/onnxruntime + +MIT License + +Copyright (c) Microsoft Corporation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +-------- +4. https://github.com/pybind/pybind11 + +Copyright (c) 2016 Wenzel Jakob , All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Please also refer to the file .github/CONTRIBUTING.md, which clarifies licensing of +external contributions to this project including patches, pull requests, etc. + +-------- +4. https://github.com/onnx/onnx-tensorrt + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2021 NVIDIA Corporation + + 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. + +-------- +5. https://github.com/opencv/opencv + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + +-------- +6. https://github.com/jbeder/yaml-cpp + +Copyright (c) 2008-2015 Jesse Beder. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/fastdeploy/vision/wongkinyiu/__init__.py b/fastdeploy/vision/wongkinyiu/__init__.py index 0ce06209fc6..542389e208b 100644 --- a/fastdeploy/vision/wongkinyiu/__init__.py +++ b/fastdeploy/vision/wongkinyiu/__init__.py @@ -41,31 +41,31 @@ def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): # 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持) @property def size(self): - return self.model.size + return self._model.size @property def padding_value(self): - return self.model.padding_value + return self._model.padding_value @property def is_no_pad(self): - return self.model.is_no_pad + return self._model.is_no_pad @property def is_mini_pad(self): - return self.model.is_mini_pad + return self._model.is_mini_pad @property def is_scale_up(self): - return self.model.is_scale_up + return self._model.is_scale_up @property def stride(self): - return self.model.stride + return self._model.stride @property def max_wh(self): - return self.model.max_wh + return self._model.max_wh @size.setter def size(self, wh): @@ -74,43 +74,43 @@ def size(self, wh): assert len(wh) == 2,\ "The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format( len(wh)) - self.model.size = wh + self._model.size = wh @padding_value.setter def padding_value(self, value): assert isinstance( value, list), "The value to set `padding_value` must be type of list." - self.model.padding_value = value + self._model.padding_value = value @is_no_pad.setter def is_no_pad(self, value): assert isinstance( value, bool), "The value to set `is_no_pad` must be type of bool." - self.model.is_no_pad = value + self._model.is_no_pad = value @is_mini_pad.setter def is_mini_pad(self, value): assert isinstance( value, bool), "The value to set `is_mini_pad` must be type of bool." - self.model.is_mini_pad = value + self._model.is_mini_pad = value @is_scale_up.setter def is_scale_up(self, value): assert isinstance( value, bool), "The value to set `is_scale_up` must be type of bool." - self.model.is_scale_up = value + self._model.is_scale_up = value @stride.setter def stride(self, value): assert isinstance( value, int), "The value to set `stride` must be type of int." - self.model.stride = value + self._model.stride = value @max_wh.setter def max_wh(self, value): assert isinstance( value, float), "The value to set `max_wh` must be type of float." - self.model.max_wh = value + self._model.max_wh = value diff --git a/model_zoo/vision/yolov7/yolov7.py b/model_zoo/vision/yolov7/yolov7.py index 81c529b15b1..ca8aeeaf886 100644 --- a/model_zoo/vision/yolov7/yolov7.py +++ b/model_zoo/vision/yolov7/yolov7.py @@ -2,13 +2,13 @@ import cv2 # 下载模型和测试图片 -model_url = "TODO " -test_jpg_url = "https://github.com/WongKinYiu/yolov7/blob/main/inference/images/horses.jpg" -fd.download(model_url, ".", show_progress=True) +# model_url = "TODO " +test_jpg_url = "https://raw.githubusercontent.com/WongKinYiu/yolov7/main/inference/images/horses.jpg" +# fd.download(model_url, ".", show_progress=True) fd.download(test_jpg_url, ".", show_progress=True) # 加载模型 -model = fd.vision.wongkinyiu.YOLOv7("yolov7.onnx") +model = fd.vision.wongkinyiu.YOLOv7("/home/fastdeploy/yolov7/onnxfiles/yolov7.onnx") # 预测图片 im = cv2.imread("horses.jpg") From 39f64f2f5c0c0c479fa7219b1b436f61d625a61f Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 06:03:08 +0000 Subject: [PATCH 08/69] delete license in fastdeploy/ --- fastdeploy/LICENSE | 201 --------- fastdeploy/ThirdPartyNotices.txt | 734 ------------------------------- 2 files changed, 935 deletions(-) delete mode 100644 fastdeploy/LICENSE delete mode 100644 fastdeploy/ThirdPartyNotices.txt diff --git a/fastdeploy/LICENSE b/fastdeploy/LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/fastdeploy/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/fastdeploy/ThirdPartyNotices.txt b/fastdeploy/ThirdPartyNotices.txt deleted file mode 100644 index 5842b9a7179..00000000000 --- a/fastdeploy/ThirdPartyNotices.txt +++ /dev/null @@ -1,734 +0,0 @@ -This project depends on some open source projects, list as below - --------- -1. https://github.com/protocolbuffers/protobuf - -Copyright 2008 Google Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Code generated by the Protocol Buffer compiler is owned by the owner -of the input file used when generating it. This code is not -standalone and requires a support library to be linked with it. This -support library is itself covered by the above license. - --------- -2. https://github.com/onnx/onnx - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. - --------- -3. https://github.com/microsoft/onnxruntime - -MIT License - -Copyright (c) Microsoft Corporation - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - --------- -4. https://github.com/pybind/pybind11 - -Copyright (c) 2016 Wenzel Jakob , All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Please also refer to the file .github/CONTRIBUTING.md, which clarifies licensing of -external contributions to this project including patches, pull requests, etc. - --------- -4. https://github.com/onnx/onnx-tensorrt - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 NVIDIA Corporation - - 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. - --------- -5. https://github.com/opencv/opencv - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. - --------- -6. https://github.com/jbeder/yaml-cpp - -Copyright (c) 2008-2015 Jesse Beder. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. From d071b3702c39386dc3cc9a19af7e0ee56b36cdca Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 06:15:17 +0000 Subject: [PATCH 09/69] repush the conflict part --- fastdeploy/vision.h | 3 --- fastdeploy/vision/vision_pybind.cc | 3 --- 2 files changed, 6 deletions(-) diff --git a/fastdeploy/vision.h b/fastdeploy/vision.h index 4e83d2681cc..5f948092d73 100644 --- a/fastdeploy/vision.h +++ b/fastdeploy/vision.h @@ -17,11 +17,8 @@ #ifdef ENABLE_VISION #include "fastdeploy/vision/ppcls/model.h" #include "fastdeploy/vision/ultralytics/yolov5.h" -<<<<<<< HEAD #include "fastdeploy/vision/wongkinyiu/yolov7.h" -======= #include "fastdeploy/vision/meituan/yolov6.h" ->>>>>>> PaddlePaddle-develop #endif #include "fastdeploy/vision/visualize/visualize.h" diff --git a/fastdeploy/vision/vision_pybind.cc b/fastdeploy/vision/vision_pybind.cc index 256fb1e114f..bc54e0d674d 100644 --- a/fastdeploy/vision/vision_pybind.cc +++ b/fastdeploy/vision/vision_pybind.cc @@ -42,12 +42,9 @@ void BindVision(pybind11::module& m) { BindPpClsModel(m); BindUltralytics(m); -<<<<<<< HEAD BindWongkinyiu(m); -======= BindMeituan(m); #ifdef ENABLE_VISION_VISUALIZE ->>>>>>> PaddlePaddle-develop BindVisualize(m); #endif } From d5026ca1e47612b7ab85fb27a2730ea350dfc211 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 06:44:54 +0000 Subject: [PATCH 10/69] README.md modified --- model_zoo/vision/yolov7/README.md | 36 +++++++++------------- model_zoo/vision/yolov7/api.md | 8 ++--- model_zoo/vision/yolov7/cpp/CMakeLists.txt | 2 +- model_zoo/vision/yolov7/cpp/README.md | 3 +- model_zoo/vision/yolov7/cpp/yolov7.cc | 2 +- model_zoo/vision/yolov7/yolov7.py | 4 +-- 6 files changed, 24 insertions(+), 31 deletions(-) diff --git a/model_zoo/vision/yolov7/README.md b/model_zoo/vision/yolov7/README.md index 80f9aa0facb..93a6f811886 100644 --- a/model_zoo/vision/yolov7/README.md +++ b/model_zoo/vision/yolov7/README.md @@ -32,9 +32,9 @@ - 从PaddlePaddle获取 -## Python部署 -### 安装FastDeploy + +## 安装FastDeploy 使用如下命令安装FastDeploy,注意到此处安装的是`vision-cpu`,也可根据需求安装`vision-gpu` @@ -45,33 +45,27 @@ pip install fastdeploy-python # 安装vision-cpu模块 fastdeploy install vision-cpu ``` +## Python部署 -### 运行demo - +执行如下代码即会自动下载测试图片 ``` python yolov7.py ``` - - -## C++部署 - -### 编译demo文件 - +执行完成后会将可视化结果保存在本地`vis_result.jpg`,同时输出检测结果如下 ``` -# 切换到./cpp/ 目录下 -cd cpp/ - -# 下载和解压预测库 -wget https://bj.bcebos.com/paddle2onnx/fastdeploy/fastdeploy-linux-x64-0.0.3.tgz -tar xvf fastdeploy-linux-x64-0.0.3.tgz - -# 编译示例代码 -mkdir build & cd build -cmake .. -make -j +DetectionResult: [xmin, ymin, xmax, ymax, score, label_id] +223.395142,403.948669, 345.337189, 867.339050, 0.856906, 0 +668.301758,400.781342, 808.441772, 882.534973, 0.829716, 0 +50.210720,398.571411, 243.123367, 905.016602, 0.805375, 0 +23.768242,214.979370, 802.627686, 778.840881, 0.756311, 5 +0.737200,552.281006, 78.617218, 890.945007, 0.363471, 0 ``` +## 其它文档 + +- [C++部署](./cpp/README.md) +- [YOLOv7 API文档](./api.md) diff --git a/model_zoo/vision/yolov7/api.md b/model_zoo/vision/yolov7/api.md index 898a3f585f5..7c5fc301634 100644 --- a/model_zoo/vision/yolov7/api.md +++ b/model_zoo/vision/yolov7/api.md @@ -4,9 +4,9 @@ ### YOLOv7类 ``` -fastdeploy.vision.ultralytics.YOLOv7(model_file, params_file=None, runtime_option=None, model_format=fd.Frontend.ONNX) +fastdeploy.vision.wongkinyiu.YOLOv7(model_file, params_file=None, runtime_option=None, model_format=fd.Frontend.ONNX) ``` -YOLOv7模型加载和初始化,当model_format为`fd.Frontend.ONNX`时,只需提供model_file,如`yolov7s.onnx`;当model_format为`fd.Frontend.PADDLE`时,则需同时提供model_file和params_file。 +YOLOv7模型加载和初始化,当model_format为`fd.Frontend.ONNX`时,只需提供model_file,如`yolov7.onnx`;当model_format为`fd.Frontend.PADDLE`时,则需同时提供model_file和params_file。 **参数** @@ -34,13 +34,13 @@ YOLOv7模型加载和初始化,当model_format为`fd.Frontend.ONNX`时,只 ### YOLOv7类 ``` -fastdeploy::vision::ultralytics::YOLOv7( +fastdeploy::vision::wongkinyiu::YOLOv7( const string& model_file, const string& params_file = "", const RuntimeOption& runtime_option = RuntimeOption(), const Frontend& model_format = Frontend::ONNX) ``` -YOLOv7模型加载和初始化,当model_format为`Frontend::ONNX`时,只需提供model_file,如`yolov7s.onnx`;当model_format为`Frontend::PADDLE`时,则需同时提供model_file和params_file。 +YOLOv7模型加载和初始化,当model_format为`Frontend::ONNX`时,只需提供model_file,如`yolov7.onnx`;当model_format为`Frontend::PADDLE`时,则需同时提供model_file和params_file。 **参数** diff --git a/model_zoo/vision/yolov7/cpp/CMakeLists.txt b/model_zoo/vision/yolov7/cpp/CMakeLists.txt index 09f07b1748a..ec7c86d026a 100644 --- a/model_zoo/vision/yolov7/cpp/CMakeLists.txt +++ b/model_zoo/vision/yolov7/cpp/CMakeLists.txt @@ -5,7 +5,7 @@ CMAKE_MINIMUM_REQUIRED (VERSION 3.16) # add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) # 指定下载解压后的fastdeploy库路径 -set(FASTDEPLOY_INSTALL_DIR /home/fastdeploy/FastDeploy/build/fastdeploy-0.0.3) +set(FASTDEPLOY_INSTALL_DIR ${PROJECT_SOURCE_DIR}/fastdeploy-linux-x64-0.3.0/) include(${FASTDEPLOY_INSTALL_DIR}/FastDeploy.cmake) diff --git a/model_zoo/vision/yolov7/cpp/README.md b/model_zoo/vision/yolov7/cpp/README.md index b43d4381e57..fd46e210f80 100644 --- a/model_zoo/vision/yolov7/cpp/README.md +++ b/model_zoo/vision/yolov7/cpp/README.md @@ -26,5 +26,6 @@ DetectionResult: [xmin, ymin, xmax, ymax, score, label_id] 668.301758,400.781342, 808.441772, 882.534973, 0.829716, 0 50.210720,398.571411, 243.123367, 905.016602, 0.805375, 0 23.768242,214.979370, 802.627686, 778.840881, 0.756311, 5 -0.737200,552.281006, 78.617218, 890.945007, 0.363471, 0 +0.737200,552.281006, 78.617218, 890.945007, 0.36341 ``` + diff --git a/model_zoo/vision/yolov7/cpp/yolov7.cc b/model_zoo/vision/yolov7/cpp/yolov7.cc index 4b899728597..1607b2be093 100644 --- a/model_zoo/vision/yolov7/cpp/yolov7.cc +++ b/model_zoo/vision/yolov7/cpp/yolov7.cc @@ -16,7 +16,7 @@ int main() { namespace vis = fastdeploy::vision; - auto model = vis::wongkinyiu::YOLOv7("/home/fastdeploy/yolov7/onnxfiles/yolov7.onnx"); + auto model = vis::wongkinyiu::YOLOv7("yolov7.onnx"); if (!model.Initialized()) { std::cerr << "Init Failed." << std::endl; return -1; diff --git a/model_zoo/vision/yolov7/yolov7.py b/model_zoo/vision/yolov7/yolov7.py index ca8aeeaf886..cef467622d8 100644 --- a/model_zoo/vision/yolov7/yolov7.py +++ b/model_zoo/vision/yolov7/yolov7.py @@ -2,13 +2,11 @@ import cv2 # 下载模型和测试图片 -# model_url = "TODO " test_jpg_url = "https://raw.githubusercontent.com/WongKinYiu/yolov7/main/inference/images/horses.jpg" -# fd.download(model_url, ".", show_progress=True) fd.download(test_jpg_url, ".", show_progress=True) # 加载模型 -model = fd.vision.wongkinyiu.YOLOv7("/home/fastdeploy/yolov7/onnxfiles/yolov7.onnx") +model = fd.vision.wongkinyiu.YOLOv7("yolov7.onnx") # 预测图片 im = cv2.imread("horses.jpg") From fb376adf9616b9b3aa3d515c739655567161722b Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 06:46:19 +0000 Subject: [PATCH 11/69] README.md modified --- model_zoo/vision/yolov7/README.md | 10 +++++----- model_zoo/vision/yolov7/cpp/README.md | 10 +++++----- model_zoo/vision/yolov7/cpp/yolov7.cc | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/model_zoo/vision/yolov7/README.md b/model_zoo/vision/yolov7/README.md index 93a6f811886..77e7a654d14 100644 --- a/model_zoo/vision/yolov7/README.md +++ b/model_zoo/vision/yolov7/README.md @@ -55,11 +55,11 @@ python yolov7.py 执行完成后会将可视化结果保存在本地`vis_result.jpg`,同时输出检测结果如下 ``` DetectionResult: [xmin, ymin, xmax, ymax, score, label_id] -223.395142,403.948669, 345.337189, 867.339050, 0.856906, 0 -668.301758,400.781342, 808.441772, 882.534973, 0.829716, 0 -50.210720,398.571411, 243.123367, 905.016602, 0.805375, 0 -23.768242,214.979370, 802.627686, 778.840881, 0.756311, 5 -0.737200,552.281006, 78.617218, 890.945007, 0.363471, 0 +0.056616,191.221619, 314.871063, 409.948914, 0.955449, 17 +432.547852,211.914841, 594.904297, 346.708618, 0.942706, 17 +0.000000,185.456207, 153.967789, 286.157562, 0.860487, 17 +224.049210,195.147003, 419.658234, 364.004852, 0.798262, 17 +369.316986,209.055725, 456.373840, 321.627625, 0.687066, 17 ``` ## 其它文档 diff --git a/model_zoo/vision/yolov7/cpp/README.md b/model_zoo/vision/yolov7/cpp/README.md index fd46e210f80..012d4c765b8 100644 --- a/model_zoo/vision/yolov7/cpp/README.md +++ b/model_zoo/vision/yolov7/cpp/README.md @@ -22,10 +22,10 @@ wget https://github.com/WongKinYiu/yolov7/blob/main/inference/images/horses.jpg 执行完后可视化的结果保存在本地`vis_result.jpg`,同时会将检测框输出在终端,如下所示 ``` DetectionResult: [xmin, ymin, xmax, ymax, score, label_id] -223.395142,403.948669, 345.337189, 867.339050, 0.856906, 0 -668.301758,400.781342, 808.441772, 882.534973, 0.829716, 0 -50.210720,398.571411, 243.123367, 905.016602, 0.805375, 0 -23.768242,214.979370, 802.627686, 778.840881, 0.756311, 5 -0.737200,552.281006, 78.617218, 890.945007, 0.36341 +0.056616,191.221619, 314.871063, 409.948914, 0.955449, 17 +432.547852,211.914841, 594.904297, 346.708618, 0.942706, 17 +0.000000,185.456207, 153.967789, 286.157562, 0.860487, 17 +224.049210,195.147003, 419.658234, 364.004852, 0.798262, 17 +369.316986,209.055725, 456.373840, 321.627625, 0.687066, 17 ``` diff --git a/model_zoo/vision/yolov7/cpp/yolov7.cc b/model_zoo/vision/yolov7/cpp/yolov7.cc index 1607b2be093..8b41c0288b6 100644 --- a/model_zoo/vision/yolov7/cpp/yolov7.cc +++ b/model_zoo/vision/yolov7/cpp/yolov7.cc @@ -21,7 +21,7 @@ int main() { std::cerr << "Init Failed." << std::endl; return -1; } - cv::Mat im = cv::imread("bus.jpg"); + cv::Mat im = cv::imread("horses.jpg"); cv::Mat vis_im = im.clone(); vis::DetectionResult res; From 4b8737c9c0577c1a6ba0132ad76b6e72aa9e8e20 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 06:54:11 +0000 Subject: [PATCH 12/69] file path modified --- model_zoo/vision/yolov7/README.md | 3 +++ model_zoo/vision/yolov7/cpp/yolov7.cc | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/model_zoo/vision/yolov7/README.md b/model_zoo/vision/yolov7/README.md index 77e7a654d14..70841fa61e7 100644 --- a/model_zoo/vision/yolov7/README.md +++ b/model_zoo/vision/yolov7/README.md @@ -26,6 +26,9 @@ # 导出onnx格式文件 python models/export.py --grid --dynamic --weights PATH/TO/yolo7.pt + + # 移动onnx文件到demo目录 + cp PATH/TO/yolo7.onnx PATH/TO/model_zoo/vision/yolov7/ ``` diff --git a/model_zoo/vision/yolov7/cpp/yolov7.cc b/model_zoo/vision/yolov7/cpp/yolov7.cc index 8b41c0288b6..6d2a80a85c9 100644 --- a/model_zoo/vision/yolov7/cpp/yolov7.cc +++ b/model_zoo/vision/yolov7/cpp/yolov7.cc @@ -16,12 +16,12 @@ int main() { namespace vis = fastdeploy::vision; - auto model = vis::wongkinyiu::YOLOv7("yolov7.onnx"); + auto model = vis::wongkinyiu::YOLOv7("../yolov7.onnx"); if (!model.Initialized()) { std::cerr << "Init Failed." << std::endl; return -1; } - cv::Mat im = cv::imread("horses.jpg"); + cv::Mat im = cv::imread("../horses.jpg"); cv::Mat vis_im = im.clone(); vis::DetectionResult res; From ce922a0326c8dc14964476be7501a896d9e39302 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 06:57:49 +0000 Subject: [PATCH 13/69] file path modified --- model_zoo/vision/yolov7/cpp/README.md | 27 +++++++++++++++++++++++++-- model_zoo/vision/yolov7/cpp/yolov7.cc | 4 ++-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/model_zoo/vision/yolov7/cpp/README.md b/model_zoo/vision/yolov7/cpp/README.md index 012d4c765b8..bef869f8815 100644 --- a/model_zoo/vision/yolov7/cpp/README.md +++ b/model_zoo/vision/yolov7/cpp/README.md @@ -1,5 +1,29 @@ # 编译YOLOv7示例 +## 生成ONNX文件 + +- 手动获取 + + 访问[YOLOv7](https://github.com/WongKinYiu/yolov7)官方github库,按照指引下载安装,下载`yolov7.pt` 模型,利用 `models/export.py` 得到`onnx`格式文件。 + + + + ``` + #下载yolov7模型文件 + wget https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7.pt + + # 导出onnx格式文件 + python models/export.py --grid --dynamic --weights PATH/TO/yolo7.pt + + # 移动onnx文件到demo目录 + cp PATH/TO/yolo7.onnx PATH/TO/model_zoo/vision/yolov7/ + ``` + + + +- 从PaddlePaddle获取 + + ``` # 下载和解压预测库 @@ -11,8 +35,7 @@ mkdir build & cd build cmake .. make -j -# 下载模型和图片 -wget "TODO" +# 下载图片 wget https://github.com/WongKinYiu/yolov7/blob/main/inference/images/horses.jpg # 执行 diff --git a/model_zoo/vision/yolov7/cpp/yolov7.cc b/model_zoo/vision/yolov7/cpp/yolov7.cc index 6d2a80a85c9..8b41c0288b6 100644 --- a/model_zoo/vision/yolov7/cpp/yolov7.cc +++ b/model_zoo/vision/yolov7/cpp/yolov7.cc @@ -16,12 +16,12 @@ int main() { namespace vis = fastdeploy::vision; - auto model = vis::wongkinyiu::YOLOv7("../yolov7.onnx"); + auto model = vis::wongkinyiu::YOLOv7("yolov7.onnx"); if (!model.Initialized()) { std::cerr << "Init Failed." << std::endl; return -1; } - cv::Mat im = cv::imread("../horses.jpg"); + cv::Mat im = cv::imread("horses.jpg"); cv::Mat vis_im = im.clone(); vis::DetectionResult res; From 6e00b82b40e3e8d19944408379ed11fb77a90073 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 06:59:58 +0000 Subject: [PATCH 14/69] file path modified --- model_zoo/vision/yolov7/cpp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model_zoo/vision/yolov7/cpp/README.md b/model_zoo/vision/yolov7/cpp/README.md index bef869f8815..1b577a7a3a1 100644 --- a/model_zoo/vision/yolov7/cpp/README.md +++ b/model_zoo/vision/yolov7/cpp/README.md @@ -23,7 +23,7 @@ - 从PaddlePaddle获取 - +## 运行demo ``` # 下载和解压预测库 From 8c359fb9defa42ccd404890d26bc55b8f063c176 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 07:02:31 +0000 Subject: [PATCH 15/69] file path modified --- model_zoo/vision/yolov7/cpp/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/model_zoo/vision/yolov7/cpp/README.md b/model_zoo/vision/yolov7/cpp/README.md index 1b577a7a3a1..918625eea79 100644 --- a/model_zoo/vision/yolov7/cpp/README.md +++ b/model_zoo/vision/yolov7/cpp/README.md @@ -15,8 +15,6 @@ # 导出onnx格式文件 python models/export.py --grid --dynamic --weights PATH/TO/yolo7.pt - # 移动onnx文件到demo目录 - cp PATH/TO/yolo7.onnx PATH/TO/model_zoo/vision/yolov7/ ``` @@ -35,6 +33,9 @@ mkdir build & cd build cmake .. make -j +# 移动onnx文件到demo目录 +cp PATH/TO/yolo7.onnx PATH/TO/model_zoo/vision/yolov7/cpp/build/ + # 下载图片 wget https://github.com/WongKinYiu/yolov7/blob/main/inference/images/horses.jpg From 906c730255d7e4e1198784f45918984dcfe9820f Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 07:03:37 +0000 Subject: [PATCH 16/69] file path modified --- model_zoo/vision/yolov7/README.md | 2 +- model_zoo/vision/yolov7/cpp/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/model_zoo/vision/yolov7/README.md b/model_zoo/vision/yolov7/README.md index 70841fa61e7..7246a4a7b75 100644 --- a/model_zoo/vision/yolov7/README.md +++ b/model_zoo/vision/yolov7/README.md @@ -12,7 +12,7 @@ └── yolov7.py ``` -## 生成ONNX文件 +## 获取ONNX文件 - 手动获取 diff --git a/model_zoo/vision/yolov7/cpp/README.md b/model_zoo/vision/yolov7/cpp/README.md index 918625eea79..ce6337962d5 100644 --- a/model_zoo/vision/yolov7/cpp/README.md +++ b/model_zoo/vision/yolov7/cpp/README.md @@ -1,6 +1,6 @@ # 编译YOLOv7示例 -## 生成ONNX文件 +## 获取ONNX文件 - 手动获取 From 80c12230f5447966d363f34f57a15abeda1951ae Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 07:36:14 +0000 Subject: [PATCH 17/69] README modified --- model_zoo/vision/yolov7/cpp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model_zoo/vision/yolov7/cpp/README.md b/model_zoo/vision/yolov7/cpp/README.md index ce6337962d5..0fcaf8ae11d 100644 --- a/model_zoo/vision/yolov7/cpp/README.md +++ b/model_zoo/vision/yolov7/cpp/README.md @@ -37,7 +37,7 @@ make -j cp PATH/TO/yolo7.onnx PATH/TO/model_zoo/vision/yolov7/cpp/build/ # 下载图片 -wget https://github.com/WongKinYiu/yolov7/blob/main/inference/images/horses.jpg +wget hhttps://raw.githubusercontent.com/WongKinYiu/yolov7/main/inference/images/horses.jpg # 执行 ./yolov7_demo From 6072757fe8af3a7f2a666b638a379865d26e9e59 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 07:36:46 +0000 Subject: [PATCH 18/69] README modified --- model_zoo/vision/yolov7/cpp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model_zoo/vision/yolov7/cpp/README.md b/model_zoo/vision/yolov7/cpp/README.md index 0fcaf8ae11d..a1d146053ab 100644 --- a/model_zoo/vision/yolov7/cpp/README.md +++ b/model_zoo/vision/yolov7/cpp/README.md @@ -37,7 +37,7 @@ make -j cp PATH/TO/yolo7.onnx PATH/TO/model_zoo/vision/yolov7/cpp/build/ # 下载图片 -wget hhttps://raw.githubusercontent.com/WongKinYiu/yolov7/main/inference/images/horses.jpg +wget https://raw.githubusercontent.com/WongKinYiu/yolov7/main/inference/images/horses.jpg # 执行 ./yolov7_demo From 2c6e6a4836b6c20c4a3ebc562d9cf3722c414423 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 08:25:58 +0000 Subject: [PATCH 19/69] move some helpers to private --- fastdeploy/vision/wongkinyiu/yolov7.h | 43 ++++++++++++++------------- model_zoo/vision/yolov7/api.md | 2 +- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/fastdeploy/vision/wongkinyiu/yolov7.h b/fastdeploy/vision/wongkinyiu/yolov7.h index b21c04936a3..29dffaf2f43 100644 --- a/fastdeploy/vision/wongkinyiu/yolov7.h +++ b/fastdeploy/vision/wongkinyiu/yolov7.h @@ -32,27 +32,6 @@ class FASTDEPLOY_DECL YOLOv7 : public FastDeployModel { // 定义模型的名称 virtual std::string ModelName() const { return "WongKinYiu/yolov7"; } - // 初始化函数,包括初始化后端,以及其它模型推理需要涉及的操作 - virtual bool Initialize(); - - // 输入图像预处理操作 - // Mat为FastDeploy定义的数据结构 - // FDTensor为预处理后的Tensor数据,传给后端进行推理 - // im_info为预处理过程保存的数据,在后处理中需要用到 - virtual bool Preprocess(Mat* mat, FDTensor* outputs, - std::map>* im_info); - - // 后端推理结果后处理,输出给用户 - // infer_result 为后端推理后的输出Tensor - // result 为模型预测的结果 - // im_info 为预处理记录的信息,后处理用于还原box - // conf_threshold 后处理时过滤box的置信度阈值 - // nms_iou_threshold 后处理时NMS设定的iou阈值 - virtual bool Postprocess( - FDTensor& infer_result, DetectionResult* result, - const std::map>& im_info, - float conf_threshold, float nms_iou_threshold); - // 模型预测接口,即用户调用的接口 // im 为用户的输入数据,目前对于CV均定义为cv::Mat // result 为模型预测的输出结构体 @@ -81,6 +60,28 @@ class FASTDEPLOY_DECL YOLOv7 : public FastDeployModel { int stride; // for offseting the boxes by classes when using NMS float max_wh; + + private: + // 初始化函数,包括初始化后端,以及其它模型推理需要涉及的操作 + virtual bool Initialize(); + + // 输入图像预处理操作 + // Mat为FastDeploy定义的数据结构 + // FDTensor为预处理后的Tensor数据,传给后端进行推理 + // im_info为预处理过程保存的数据,在后处理中需要用到 + virtual bool Preprocess(Mat* mat, FDTensor* outputs, + std::map>* im_info); + + // 后端推理结果后处理,输出给用户 + // infer_result 为后端推理后的输出Tensor + // result 为模型预测的结果 + // im_info 为预处理记录的信息,后处理用于还原box + // conf_threshold 后处理时过滤box的置信度阈值 + // nms_iou_threshold 后处理时NMS设定的iou阈值 + virtual bool Postprocess( + FDTensor& infer_result, DetectionResult* result, + const std::map>& im_info, + float conf_threshold, float nms_iou_threshold); }; } // namespace wongkinyiu } // namespace vision diff --git a/model_zoo/vision/yolov7/api.md b/model_zoo/vision/yolov7/api.md index 7c5fc301634..1f40ba645a0 100644 --- a/model_zoo/vision/yolov7/api.md +++ b/model_zoo/vision/yolov7/api.md @@ -23,7 +23,7 @@ YOLOv7模型加载和初始化,当model_format为`fd.Frontend.ONNX`时,只 > > **参数** > -> > * **image_data**(np.ndarray): 输入数据,注意需为HWC,RGB格式 +> > * **image_data**(np.ndarray): 输入数据,注意需为HWC,BGR格式 > > * **conf_threshold**(float): 检测框置信度过滤阈值 > > * **nms_iou_threshold**(float): NMS处理过程中iou阈值 From 48136f0d152af4a1a658af71ddaacfe4498b9f2e Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 08:46:49 +0000 Subject: [PATCH 20/69] add examples for yolov7 --- examples/CMakeLists.txt | 1 + examples/vision/wongkinyiu_yolov7.cc | 52 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 examples/vision/wongkinyiu_yolov7.cc diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 4228a3e01f7..31cd1723b1f 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -17,6 +17,7 @@ endfunction() if (WTIH_VISION_EXAMPLES) add_fastdeploy_executable(vision ultralytics yolov5) add_fastdeploy_executable(vision meituan yolov6) + add_fastdeploy_executable(vision wongkinyiu yolov7) endif() # other examples ... \ No newline at end of file diff --git a/examples/vision/wongkinyiu_yolov7.cc b/examples/vision/wongkinyiu_yolov7.cc new file mode 100644 index 00000000000..7de033cae8f --- /dev/null +++ b/examples/vision/wongkinyiu_yolov7.cc @@ -0,0 +1,52 @@ +// 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/vision.h" + +int main() { + namespace vis = fastdeploy::vision; + + std::string model_file = "../resources/models/yolov7.onnx"; + std::string img_path = "../resources/images/horses.jpg"; + std::string vis_path = "../resources/outputs/wongkinyiu_yolov7_vis_result.jpg"; + + auto model = vis::wongkinyiu::YOLOv7(model_file); + if (!model.Initialized()) { + std::cerr << "Init Failed! Model: " << model_file << std::endl; + return -1; + } else { + std::cout << "Init Done! Model:" << model_file << std::endl; + } + model.EnableDebug(); + + cv::Mat im = cv::imread(img_path); + cv::Mat vis_im = im.clone(); + + vis::DetectionResult res; + if (!model.Predict(&im, &res)) { + std::cerr << "Prediction Failed." << std::endl; + return -1; + } else { + std::cout << "Prediction Done!" << std::endl; + } + + // 输出预测框结果 + std::cout << res.Str() << std::endl; + + // 可视化预测结果 + vis::Visualize::VisDetection(&vis_im, res); + cv::imwrite(vis_path, vis_im); + std::cout << "Detect Done! Saved: " << vis_path << std::endl; + return 0; +} From 6feca9233a0503c3e2644b9fa2d1dd76ce5bdbb5 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 09:07:47 +0000 Subject: [PATCH 21/69] api.md modified --- model_zoo/vision/yolov7/api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/model_zoo/vision/yolov7/api.md b/model_zoo/vision/yolov7/api.md index 1f40ba645a0..92b16c47557 100644 --- a/model_zoo/vision/yolov7/api.md +++ b/model_zoo/vision/yolov7/api.md @@ -51,7 +51,7 @@ YOLOv7模型加载和初始化,当model_format为`Frontend::ONNX`时,只需 #### predict函数 > ``` -> YOLOv7::predict(cv::Mat* im, DetectionResult* result, +> YOLOv7::Predict(cv::Mat* im, DetectionResult* result, > float conf_threshold = 0.25, > float nms_iou_threshold = 0.5) > ``` @@ -59,7 +59,7 @@ YOLOv7模型加载和初始化,当model_format为`Frontend::ONNX`时,只需 > > **参数** > -> > * **im**: 输入图像,注意需为HWC,RGB格式 +> > * **im**: 输入图像,注意需为HWC,BGR格式 > > * **result**: 检测结果,包括检测框,各个框的置信度 > > * **conf_threshold**: 检测框置信度过滤阈值 > > * **nms_iou_threshold**: NMS处理过程中iou阈值 From ae70d4f50ec9981e97dd7b79f3e3265c2105ed0c Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 09:11:01 +0000 Subject: [PATCH 22/69] api.md modified --- model_zoo/vision/yolov7/api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model_zoo/vision/yolov7/api.md b/model_zoo/vision/yolov7/api.md index 92b16c47557..abd2abdcec0 100644 --- a/model_zoo/vision/yolov7/api.md +++ b/model_zoo/vision/yolov7/api.md @@ -49,7 +49,7 @@ YOLOv7模型加载和初始化,当model_format为`Frontend::ONNX`时,只需 > * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置 > * **model_format**(Frontend): 模型格式 -#### predict函数 +#### Predict函数 > ``` > YOLOv7::Predict(cv::Mat* im, DetectionResult* result, > float conf_threshold = 0.25, From f591b8567b08afbd1e3894100becaa2ce511424b Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 09:31:25 +0000 Subject: [PATCH 23/69] api.md modified --- model_zoo/vision/yolov7/api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model_zoo/vision/yolov7/api.md b/model_zoo/vision/yolov7/api.md index abd2abdcec0..02cf78121c6 100644 --- a/model_zoo/vision/yolov7/api.md +++ b/model_zoo/vision/yolov7/api.md @@ -49,7 +49,7 @@ YOLOv7模型加载和初始化,当model_format为`Frontend::ONNX`时,只需 > * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置 > * **model_format**(Frontend): 模型格式 -#### Predict函数 +#### redict函数 > ``` > YOLOv7::Predict(cv::Mat* im, DetectionResult* result, > float conf_threshold = 0.25, From f0def41c8b5e5e2b1d627ada84b2c4b17c84aeac Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 09:41:47 +0000 Subject: [PATCH 24/69] YOLOv7 --- model_zoo/vision/yolov7/api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model_zoo/vision/yolov7/api.md b/model_zoo/vision/yolov7/api.md index 02cf78121c6..abd2abdcec0 100644 --- a/model_zoo/vision/yolov7/api.md +++ b/model_zoo/vision/yolov7/api.md @@ -49,7 +49,7 @@ YOLOv7模型加载和初始化,当model_format为`Frontend::ONNX`时,只需 > * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置 > * **model_format**(Frontend): 模型格式 -#### redict函数 +#### Predict函数 > ``` > YOLOv7::Predict(cv::Mat* im, DetectionResult* result, > float conf_threshold = 0.25, From 15b91609aae1f81e3d5789d40c18f0aa16e37e86 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 10:50:08 +0000 Subject: [PATCH 25/69] yolov7 release link --- model_zoo/vision/yolov7/README.md | 2 +- model_zoo/vision/yolov7/cpp/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/model_zoo/vision/yolov7/README.md b/model_zoo/vision/yolov7/README.md index 7246a4a7b75..c81c75d8d29 100644 --- a/model_zoo/vision/yolov7/README.md +++ b/model_zoo/vision/yolov7/README.md @@ -16,7 +16,7 @@ - 手动获取 - 访问[YOLOv7](https://github.com/WongKinYiu/yolov7)官方github库,按照指引下载安装,下载`yolov7.pt` 模型,利用 `models/export.py` 得到`onnx`格式文件。 + 访问[YOLOv7](https://github.com/WongKinYiu/yolov7/releases/tag/v0.1)官方github库,按照指引下载安装,下载`yolov7.pt` 模型,利用 `models/export.py` 得到`onnx`格式文件。 diff --git a/model_zoo/vision/yolov7/cpp/README.md b/model_zoo/vision/yolov7/cpp/README.md index a1d146053ab..c3d4e8bcb21 100644 --- a/model_zoo/vision/yolov7/cpp/README.md +++ b/model_zoo/vision/yolov7/cpp/README.md @@ -4,7 +4,7 @@ - 手动获取 - 访问[YOLOv7](https://github.com/WongKinYiu/yolov7)官方github库,按照指引下载安装,下载`yolov7.pt` 模型,利用 `models/export.py` 得到`onnx`格式文件。 + 访问[YOLOv7](https://github.com/WongKinYiu/yolov7/releases/tag/v0.1)官方github库,按照指引下载安装,下载`yolov7.pt` 模型,利用 `models/export.py` 得到`onnx`格式文件。 From 4706e8ca754735d318650c3f7a90b3e00f6ef16a Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 11:01:53 +0000 Subject: [PATCH 26/69] yolov7 release link --- model_zoo/vision/yolov7/README.md | 2 ++ model_zoo/vision/yolov7/cpp/README.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/model_zoo/vision/yolov7/README.md b/model_zoo/vision/yolov7/README.md index c81c75d8d29..e330a3055b8 100644 --- a/model_zoo/vision/yolov7/README.md +++ b/model_zoo/vision/yolov7/README.md @@ -1,5 +1,7 @@ # 编译YOLOv7示例 +当前支持模型版本为:[YOLOv7](https://github.com/WongKinYiu/yolov7/releases/tag/v0.1) + 本文档说明如何进行[YOLOv7](https://github.com/WongKinYiu/yolov7)的快速部署推理。本目录结构如下 ``` diff --git a/model_zoo/vision/yolov7/cpp/README.md b/model_zoo/vision/yolov7/cpp/README.md index c3d4e8bcb21..2e9570f2243 100644 --- a/model_zoo/vision/yolov7/cpp/README.md +++ b/model_zoo/vision/yolov7/cpp/README.md @@ -1,5 +1,7 @@ # 编译YOLOv7示例 +当前支持模型版本为:[YOLOv7](https://github.com/WongKinYiu/yolov7/releases/tag/v0.1) + ## 获取ONNX文件 - 手动获取 From dc8358461f384cc7ee0fcc592a68e5a917925bf6 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 11:05:01 +0000 Subject: [PATCH 27/69] yolov7 release link --- model_zoo/vision/yolov7/README.md | 2 +- model_zoo/vision/yolov7/cpp/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/model_zoo/vision/yolov7/README.md b/model_zoo/vision/yolov7/README.md index e330a3055b8..7eed2c0c436 100644 --- a/model_zoo/vision/yolov7/README.md +++ b/model_zoo/vision/yolov7/README.md @@ -1,6 +1,6 @@ # 编译YOLOv7示例 -当前支持模型版本为:[YOLOv7](https://github.com/WongKinYiu/yolov7/releases/tag/v0.1) +当前支持模型版本为:[YOLOv7 v0.1](https://github.com/WongKinYiu/yolov7/releases/tag/v0.1) 本文档说明如何进行[YOLOv7](https://github.com/WongKinYiu/yolov7)的快速部署推理。本目录结构如下 diff --git a/model_zoo/vision/yolov7/cpp/README.md b/model_zoo/vision/yolov7/cpp/README.md index 2e9570f2243..13a5e8343e3 100644 --- a/model_zoo/vision/yolov7/cpp/README.md +++ b/model_zoo/vision/yolov7/cpp/README.md @@ -1,6 +1,6 @@ # 编译YOLOv7示例 -当前支持模型版本为:[YOLOv7](https://github.com/WongKinYiu/yolov7/releases/tag/v0.1) +当前支持模型版本为:[YOLOv7 v0.1](https://github.com/WongKinYiu/yolov7/releases/tag/v0.1) ## 获取ONNX文件 From 086debd8d3e040d37b0b8cbc006277d91e246baa Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 11:10:43 +0000 Subject: [PATCH 28/69] copyright --- fastdeploy/vision/wongkinyiu/yolov7.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/fastdeploy/vision/wongkinyiu/yolov7.cc b/fastdeploy/vision/wongkinyiu/yolov7.cc index 6baf4c336b4..db470d327e7 100644 --- a/fastdeploy/vision/wongkinyiu/yolov7.cc +++ b/fastdeploy/vision/wongkinyiu/yolov7.cc @@ -1,3 +1,17 @@ +// 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/vision/wongkinyiu/yolov7.h" #include "fastdeploy/utils/perf.h" #include "fastdeploy/vision/utils/utils.h" From 4f980b9ce8e2573d76385ca4f0b98febf66f57a4 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 18 Jul 2022 12:09:04 +0000 Subject: [PATCH 29/69] change some helpers to private --- fastdeploy/vision/wongkinyiu/yolov7.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fastdeploy/vision/wongkinyiu/yolov7.h b/fastdeploy/vision/wongkinyiu/yolov7.h index 29dffaf2f43..75cab34dedd 100644 --- a/fastdeploy/vision/wongkinyiu/yolov7.h +++ b/fastdeploy/vision/wongkinyiu/yolov7.h @@ -63,13 +63,13 @@ class FASTDEPLOY_DECL YOLOv7 : public FastDeployModel { private: // 初始化函数,包括初始化后端,以及其它模型推理需要涉及的操作 - virtual bool Initialize(); + bool Initialize(); // 输入图像预处理操作 // Mat为FastDeploy定义的数据结构 // FDTensor为预处理后的Tensor数据,传给后端进行推理 // im_info为预处理过程保存的数据,在后处理中需要用到 - virtual bool Preprocess(Mat* mat, FDTensor* outputs, + bool Preprocess(Mat* mat, FDTensor* outputs, std::map>* im_info); // 后端推理结果后处理,输出给用户 @@ -78,7 +78,7 @@ class FASTDEPLOY_DECL YOLOv7 : public FastDeployModel { // im_info 为预处理记录的信息,后处理用于还原box // conf_threshold 后处理时过滤box的置信度阈值 // nms_iou_threshold 后处理时NMS设定的iou阈值 - virtual bool Postprocess( + bool Postprocess( FDTensor& infer_result, DetectionResult* result, const std::map>& im_info, float conf_threshold, float nms_iou_threshold); From 80beadfa3ce7ebb7cc2d345d4154cd42f6dec785 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Tue, 19 Jul 2022 02:57:08 +0000 Subject: [PATCH 30/69] change variables to const and fix documents. --- fastdeploy/vision/wongkinyiu/yolov7.cc | 6 +++--- model_zoo/vision/yolov7/README.md | 16 ++-------------- model_zoo/vision/yolov7/cpp/README.md | 8 +------- 3 files changed, 6 insertions(+), 24 deletions(-) diff --git a/fastdeploy/vision/wongkinyiu/yolov7.cc b/fastdeploy/vision/wongkinyiu/yolov7.cc index db470d327e7..248718a69ac 100644 --- a/fastdeploy/vision/wongkinyiu/yolov7.cc +++ b/fastdeploy/vision/wongkinyiu/yolov7.cc @@ -20,9 +20,9 @@ namespace fastdeploy { namespace vision { namespace wongkinyiu { -void LetterBox(Mat* mat, std::vector size, std::vector color, - bool _auto, bool scale_fill = false, bool scale_up = true, - int stride = 32) { +void LetterBox(Mat* mat, const std::vector& size, + const std::vector& color, bool _auto, + bool scale_fill = false, bool scale_up = true, int stride = 32) { float scale = std::min(size[1] * 1.0 / mat->Height(), size[0] * 1.0 / mat->Width()); if (!scale_up) { diff --git a/model_zoo/vision/yolov7/README.md b/model_zoo/vision/yolov7/README.md index 7eed2c0c436..2bb13ce4594 100644 --- a/model_zoo/vision/yolov7/README.md +++ b/model_zoo/vision/yolov7/README.md @@ -20,12 +20,12 @@ 访问[YOLOv7](https://github.com/WongKinYiu/yolov7/releases/tag/v0.1)官方github库,按照指引下载安装,下载`yolov7.pt` 模型,利用 `models/export.py` 得到`onnx`格式文件。 - + ``` #下载yolov7模型文件 wget https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7.pt - + # 导出onnx格式文件 python models/export.py --grid --dynamic --weights PATH/TO/yolo7.pt @@ -33,12 +33,6 @@ cp PATH/TO/yolo7.onnx PATH/TO/model_zoo/vision/yolov7/ ``` - - -- 从PaddlePaddle获取 - - - ## 安装FastDeploy 使用如下命令安装FastDeploy,注意到此处安装的是`vision-cpu`,也可根据需求安装`vision-gpu` @@ -71,9 +65,3 @@ DetectionResult: [xmin, ymin, xmax, ymax, score, label_id] - [C++部署](./cpp/README.md) - [YOLOv7 API文档](./api.md) - - - - - - diff --git a/model_zoo/vision/yolov7/cpp/README.md b/model_zoo/vision/yolov7/cpp/README.md index 13a5e8343e3..f216c1aecff 100644 --- a/model_zoo/vision/yolov7/cpp/README.md +++ b/model_zoo/vision/yolov7/cpp/README.md @@ -8,20 +8,15 @@ 访问[YOLOv7](https://github.com/WongKinYiu/yolov7/releases/tag/v0.1)官方github库,按照指引下载安装,下载`yolov7.pt` 模型,利用 `models/export.py` 得到`onnx`格式文件。 - - ``` #下载yolov7模型文件 wget https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7.pt - + # 导出onnx格式文件 python models/export.py --grid --dynamic --weights PATH/TO/yolo7.pt ``` - - -- 从PaddlePaddle获取 ## 运行demo @@ -54,4 +49,3 @@ DetectionResult: [xmin, ymin, xmax, ymax, score, label_id] 224.049210,195.147003, 419.658234, 364.004852, 0.798262, 17 369.316986,209.055725, 456.373840, 321.627625, 0.687066, 17 ``` - From f5f7a863e09490213c5ea51fd83c584ff10752df Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Tue, 19 Jul 2022 05:16:07 +0000 Subject: [PATCH 31/69] gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 39783b88395..51f2f2ed805 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,4 @@ fastdeploy.egg-info .setuptools-cmake-build fastdeploy/version.py fastdeploy/LICENSE* -fastdeploy/ThirdPartyNotices* \ No newline at end of file +fastdeploy/ThirdPartyNotices* From e6cec25cace95e029adc08412aa359486446ec6d Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Tue, 19 Jul 2022 08:05:01 +0000 Subject: [PATCH 32/69] Transfer some funtions to private member of class --- fastdeploy/vision/wongkinyiu/yolov7.cc | 10 +++++----- fastdeploy/vision/wongkinyiu/yolov7.h | 17 ++++++++++++----- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/fastdeploy/vision/wongkinyiu/yolov7.cc b/fastdeploy/vision/wongkinyiu/yolov7.cc index 248718a69ac..532f552947d 100644 --- a/fastdeploy/vision/wongkinyiu/yolov7.cc +++ b/fastdeploy/vision/wongkinyiu/yolov7.cc @@ -20,9 +20,9 @@ namespace fastdeploy { namespace vision { namespace wongkinyiu { -void LetterBox(Mat* mat, const std::vector& size, - const std::vector& color, bool _auto, - bool scale_fill = false, bool scale_up = true, int stride = 32) { +void YOLOv7::LetterBox(Mat* mat, const std::vector& size, + const std::vector& color, bool _auto, + bool scale_fill, bool scale_up, int stride) { float scale = std::min(size[1] * 1.0 / mat->Height(), size[0] * 1.0 / mat->Width()); if (!scale_up) { @@ -107,8 +107,8 @@ bool YOLOv7::Preprocess(Mat* mat, FDTensor* output, // 1. letterbox // 2. BGR->RGB // 3. HWC->CHW - LetterBox(mat, size, padding_value, is_mini_pad, is_no_pad, is_scale_up, - stride); + YOLOv7::LetterBox(mat, size, padding_value, is_mini_pad, is_no_pad, + is_scale_up, stride); BGR2RGB::Run(mat); Normalize::Run(mat, std::vector(mat->Channels(), 0.0), std::vector(mat->Channels(), 1.0)); diff --git a/fastdeploy/vision/wongkinyiu/yolov7.h b/fastdeploy/vision/wongkinyiu/yolov7.h index 75cab34dedd..90be9ea463a 100644 --- a/fastdeploy/vision/wongkinyiu/yolov7.h +++ b/fastdeploy/vision/wongkinyiu/yolov7.h @@ -70,7 +70,7 @@ class FASTDEPLOY_DECL YOLOv7 : public FastDeployModel { // FDTensor为预处理后的Tensor数据,传给后端进行推理 // im_info为预处理过程保存的数据,在后处理中需要用到 bool Preprocess(Mat* mat, FDTensor* outputs, - std::map>* im_info); + std::map>* im_info); // 后端推理结果后处理,输出给用户 // infer_result 为后端推理后的输出Tensor @@ -78,10 +78,17 @@ class FASTDEPLOY_DECL YOLOv7 : public FastDeployModel { // im_info 为预处理记录的信息,后处理用于还原box // conf_threshold 后处理时过滤box的置信度阈值 // nms_iou_threshold 后处理时NMS设定的iou阈值 - bool Postprocess( - FDTensor& infer_result, DetectionResult* result, - const std::map>& im_info, - float conf_threshold, float nms_iou_threshold); + bool Postprocess(FDTensor& infer_result, DetectionResult* result, + const std::map>& im_info, + float conf_threshold, float nms_iou_threshold); + + // 对图片进行LetterBox处理 + // mat 为输入图片 + // size 为输入图片的size + void LetterBox(Mat* mat, const std::vector& size, + const std::vector& color, bool _auto, + bool scale_fill = false, bool scale_up = true, + int stride = 32); }; } // namespace wongkinyiu } // namespace vision From e25e4f2a5c18ffe45bd3b8574dbe7c612a528e72 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Tue, 19 Jul 2022 08:07:49 +0000 Subject: [PATCH 33/69] Transfer some funtions to private member of class --- fastdeploy/vision/wongkinyiu/yolov7.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fastdeploy/vision/wongkinyiu/yolov7.h b/fastdeploy/vision/wongkinyiu/yolov7.h index 90be9ea463a..c494754f0e1 100644 --- a/fastdeploy/vision/wongkinyiu/yolov7.h +++ b/fastdeploy/vision/wongkinyiu/yolov7.h @@ -83,8 +83,8 @@ class FASTDEPLOY_DECL YOLOv7 : public FastDeployModel { float conf_threshold, float nms_iou_threshold); // 对图片进行LetterBox处理 - // mat 为输入图片 - // size 为输入图片的size + // mat 为读取到的原图 + // size 为输入模型的图像尺寸 void LetterBox(Mat* mat, const std::vector& size, const std::vector& color, bool _auto, bool scale_fill = false, bool scale_up = true, From e8a8439dd97e0a6d52f299bff2958290637687c8 Mon Sep 17 00:00:00 2001 From: ziqi-jin <67993288+ziqi-jin@users.noreply.github.com> Date: Wed, 20 Jul 2022 15:25:57 +0800 Subject: [PATCH 34/69] Merge from develop (#9) * Fix compile problem in different python version (#26) * fix some usage problem in linux * Fix compile problem Co-authored-by: root * Add PaddleDetetion/PPYOLOE model support (#22) * add ppdet/ppyoloe * Add demo code and documents * add convert processor to vision (#27) * update .gitignore * Added checking for cmake include dir * fixed missing trt_backend option bug when init from trt * remove un-need data layout and add pre-check for dtype * changed RGB2BRG to BGR2RGB in ppcls model * add model_zoo yolov6 c++/python demo * fixed CMakeLists.txt typos * update yolov6 cpp/README.md * add yolox c++/pybind and model_zoo demo * move some helpers to private * fixed CMakeLists.txt typos * add normalize with alpha and beta * add version notes for yolov5/yolov6/yolox * add copyright to yolov5.cc * revert normalize * fixed some bugs in yolox * fixed examples/CMakeLists.txt to avoid conflicts * add convert processor to vision * format examples/CMakeLists summary * Fix bug while the inference result is empty with YOLOv5 (#29) * Add multi-label function for yolov5 * Update README.md Update doc * Update fastdeploy_runtime.cc fix variable option.trt_max_shape wrong name * Update runtime_option.md Update resnet model dynamic shape setting name from images to x * Fix bug when inference result boxes are empty * Delete detection.py Co-authored-by: Jason Co-authored-by: root Co-authored-by: DefTruth <31974251+DefTruth@users.noreply.github.com> Co-authored-by: huangjianhui <852142024@qq.com> --- examples/CMakeLists.txt | 26 +-- examples/vision/ppdet_ppyoloe.cc | 51 ++++++ fastdeploy/__init__.py | 2 +- fastdeploy/download.py | 2 +- fastdeploy/utils/utils.h | 4 + fastdeploy/vision.h | 1 + fastdeploy/vision/__init__.py | 1 + .../vision/common/processors/convert.cc | 62 +++++++ fastdeploy/vision/common/processors/convert.h | 42 +++++ .../vision/common/processors/transform.h | 1 + fastdeploy/vision/meituan/yolov6.cc | 28 +-- fastdeploy/vision/ppcls/model.cc | 19 +- fastdeploy/vision/ppcls/model.h | 16 +- fastdeploy/vision/ppcls/ppcls_pybind.cc | 2 +- fastdeploy/vision/ppdet/__init__.py | 39 ++++ fastdeploy/vision/ppdet/ppdet_pybind.cc | 32 ++++ fastdeploy/vision/ppdet/ppyoloe.cc | 170 ++++++++++++++++++ fastdeploy/vision/ppdet/ppyoloe.h | 44 +++++ fastdeploy/vision/ultralytics/yolov5.cc | 19 +- fastdeploy/vision/utils/sort_det_res.cc | 6 +- fastdeploy/vision/vision_pybind.cc | 10 +- fastdeploy/vision/visualize/detection.cc | 4 +- model_zoo/vision/ppyoloe/README.md | 52 ++++++ model_zoo/vision/ppyoloe/api.md | 74 ++++++++ model_zoo/vision/ppyoloe/cpp/CMakeLists.txt | 17 ++ model_zoo/vision/ppyoloe/cpp/README.md | 39 ++++ model_zoo/vision/ppyoloe/cpp/ppyoloe.cc | 51 ++++++ model_zoo/vision/ppyoloe/ppyoloe.py | 24 +++ setup.py | 30 +++- 29 files changed, 818 insertions(+), 50 deletions(-) create mode 100644 examples/vision/ppdet_ppyoloe.cc create mode 100644 fastdeploy/vision/common/processors/convert.cc create mode 100644 fastdeploy/vision/common/processors/convert.h create mode 100644 fastdeploy/vision/ppdet/__init__.py create mode 100644 fastdeploy/vision/ppdet/ppdet_pybind.cc create mode 100644 fastdeploy/vision/ppdet/ppyoloe.cc create mode 100644 fastdeploy/vision/ppdet/ppyoloe.h create mode 100644 model_zoo/vision/ppyoloe/README.md create mode 100644 model_zoo/vision/ppyoloe/api.md create mode 100644 model_zoo/vision/ppyoloe/cpp/CMakeLists.txt create mode 100644 model_zoo/vision/ppyoloe/cpp/README.md create mode 100644 model_zoo/vision/ppyoloe/cpp/ppyoloe.cc create mode 100644 model_zoo/vision/ppyoloe/ppyoloe.py diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 1e2dc43bd40..112193c86a2 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,24 +1,26 @@ -function(add_fastdeploy_executable field url model) +function(add_fastdeploy_executable FIELD CC_FILE) # temp target name/file var in function scope - set(TEMP_TARGET_FILE ${PROJECT_SOURCE_DIR}/examples/${field}/${url}_${model}.cc) - set(TEMP_TARGET_NAME ${field}_${url}_${model}) + set(TEMP_TARGET_FILE ${CC_FILE}) + string(REGEX MATCHALL "[0-9A-Za-z_]*.cc" FILE_NAME ${CC_FILE}) + string(REGEX REPLACE ".cc" "" FILE_PREFIX ${FILE_NAME}) + set(TEMP_TARGET_NAME ${FIELD}_${FILE_PREFIX}) if (EXISTS ${TEMP_TARGET_FILE} AND TARGET fastdeploy) add_executable(${TEMP_TARGET_NAME} ${TEMP_TARGET_FILE}) target_link_libraries(${TEMP_TARGET_NAME} PUBLIC fastdeploy) - message(STATUS "Found source file: [${field}/${url}_${model}.cc], ADD!!! fastdeploy executable: [${TEMP_TARGET_NAME}] !") - else () - message(WARNING "Can not found source file: [${field}/${url}_${model}.cc], SKIP!!! fastdeploy executable: [${TEMP_TARGET_NAME}] !") + message(STATUS " Added FastDeploy Executable : ${TEMP_TARGET_NAME}") endif() unset(TEMP_TARGET_FILE) unset(TEMP_TARGET_NAME) endfunction() # vision examples -if (WITH_VISION_EXAMPLES) - add_fastdeploy_executable(vision ultralytics yolov5) - add_fastdeploy_executable(vision meituan yolov6) - add_fastdeploy_executable(vision wongkinyiu yolov7) - add_fastdeploy_executable(vision megvii yolox) +if(WITH_VISION_EXAMPLES AND EXISTS ${PROJECT_SOURCE_DIR}/examples/vision) + message(STATUS "") + message(STATUS "*************FastDeploy Examples Summary**********") + file(GLOB ALL_VISION_EXAMPLE_SRCS ${PROJECT_SOURCE_DIR}/examples/vision/*.cc) + foreach(_CC_FILE ${ALL_VISION_EXAMPLE_SRCS}) + add_fastdeploy_executable(vision ${_CC_FILE}) + endforeach() endif() -# other examples ... \ No newline at end of file +# other examples ... diff --git a/examples/vision/ppdet_ppyoloe.cc b/examples/vision/ppdet_ppyoloe.cc new file mode 100644 index 00000000000..b234021c92e --- /dev/null +++ b/examples/vision/ppdet_ppyoloe.cc @@ -0,0 +1,51 @@ +// 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/vision.h" + +int main() { + namespace vis = fastdeploy::vision; + + std::string model_file = "ppyoloe_crn_l_300e_coco/model.pdmodel"; + std::string params_file = "ppyoloe_crn_l_300e_coco/model.pdiparams"; + std::string config_file = "ppyoloe_crn_l_300e_coco/infer_cfg.yml"; + std::string img_path = "test.jpeg"; + std::string vis_path = "vis.jpeg"; + + auto model = vis::ppdet::PPYOLOE(model_file, params_file, config_file); + if (!model.Initialized()) { + std::cerr << "Init Failed." << std::endl; + return -1; + } + + cv::Mat im = cv::imread(img_path); + cv::Mat vis_im = im.clone(); + + vis::DetectionResult res; + if (!model.Predict(&im, &res)) { + std::cerr << "Prediction Failed." << std::endl; + return -1; + } else { + std::cout << "Prediction Done!" << std::endl; + } + + // 输出预测框结果 + std::cout << res.Str() << std::endl; + + // 可视化预测结果 + vis::Visualize::VisDetection(&vis_im, res); + cv::imwrite(vis_path, vis_im); + std::cout << "Detect Done! Saved: " << vis_path << std::endl; + return 0; +} diff --git a/fastdeploy/__init__.py b/fastdeploy/__init__.py index 500e7cc42ae..68006c1bed5 100644 --- a/fastdeploy/__init__.py +++ b/fastdeploy/__init__.py @@ -17,7 +17,7 @@ from .fastdeploy_runtime import * from . import fastdeploy_main as C from . import vision -from .download import download +from .download import download, download_and_decompress def TensorInfoStr(tensor_info): diff --git a/fastdeploy/download.py b/fastdeploy/download.py index e00af098dfd..67f21d8e76d 100644 --- a/fastdeploy/download.py +++ b/fastdeploy/download.py @@ -156,7 +156,7 @@ def decompress(fname): def url2dir(url, path, rename=None): full_name = download(url, path, rename, show_progress=True) - print("SDK is donwloaded, now extracting...") + print("File is donwloaded, now extracting...") if url.count(".tgz") > 0 or url.count(".tar") > 0 or url.count("zip") > 0: return decompress(full_name) diff --git a/fastdeploy/utils/utils.h b/fastdeploy/utils/utils.h index 1b9f625b5e5..93120842659 100644 --- a/fastdeploy/utils/utils.h +++ b/fastdeploy/utils/utils.h @@ -64,6 +64,10 @@ class FASTDEPLOY_DECL FDLogger { bool verbose_ = true; }; +#ifndef __REL_FILE__ +#define __REL_FILE__ __FILE__ +#endif + #define FDERROR \ FDLogger(true, "[ERROR]") \ << __REL_FILE__ << "(" << __LINE__ << ")::" << __FUNCTION__ << "\t" diff --git a/fastdeploy/vision.h b/fastdeploy/vision.h index ac3f006c0ad..cafe310c706 100644 --- a/fastdeploy/vision.h +++ b/fastdeploy/vision.h @@ -16,6 +16,7 @@ #include "fastdeploy/core/config.h" #ifdef ENABLE_VISION #include "fastdeploy/vision/ppcls/model.h" +#include "fastdeploy/vision/ppdet/ppyoloe.h" #include "fastdeploy/vision/ultralytics/yolov5.h" #include "fastdeploy/vision/wongkinyiu/yolov7.h" #include "fastdeploy/vision/meituan/yolov6.h" diff --git a/fastdeploy/vision/__init__.py b/fastdeploy/vision/__init__.py index 7122bede0be..6acbf0c3763 100644 --- a/fastdeploy/vision/__init__.py +++ b/fastdeploy/vision/__init__.py @@ -15,6 +15,7 @@ from . import evaluation from . import ppcls +from . import ppdet from . import ultralytics from . import meituan from . import megvii diff --git a/fastdeploy/vision/common/processors/convert.cc b/fastdeploy/vision/common/processors/convert.cc new file mode 100644 index 00000000000..a7ca6de07a9 --- /dev/null +++ b/fastdeploy/vision/common/processors/convert.cc @@ -0,0 +1,62 @@ +// 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/vision/common/processors/convert.h" + +namespace fastdeploy { + +namespace vision { + +Convert::Convert(const std::vector& alpha, + const std::vector& beta) { + FDASSERT(alpha.size() == beta.size(), + "Convert: requires the size of alpha equal to the size of beta."); + FDASSERT(alpha.size() != 0, + "Convert: requires the size of alpha and beta > 0."); + alpha_.assign(alpha.begin(), alpha.end()); + beta_.assign(beta.begin(), beta.end()); +} + +bool Convert::CpuRun(Mat* mat) { + cv::Mat* im = mat->GetCpuMat(); + std::vector split_im; + cv::split(*im, split_im); + for (int c = 0; c < im->channels(); c++) { + split_im[c].convertTo(split_im[c], CV_32FC1, alpha_[c], beta_[c]); + } + cv::merge(split_im, *im); + return true; +} + +#ifdef ENABLE_OPENCV_CUDA +bool Convert::GpuRun(Mat* mat) { + cv::cuda::GpuMat* im = mat->GetGpuMat(); + std::vector split_im; + cv::cuda::split(*im, split_im); + for (int c = 0; c < im->channels(); c++) { + split_im[c].convertTo(split_im[c], CV_32FC1, alpha_[c], beta_[c]); + } + cv::cuda::merge(split_im, *im); + return true; +} +#endif + +bool Convert::Run(Mat* mat, const std::vector& alpha, + const std::vector& beta, ProcLib lib) { + auto c = Convert(alpha, beta); + return c(mat, lib); +} + +} // namespace vision +} // namespace fastdeploy \ No newline at end of file diff --git a/fastdeploy/vision/common/processors/convert.h b/fastdeploy/vision/common/processors/convert.h new file mode 100644 index 00000000000..5d5a5276f5d --- /dev/null +++ b/fastdeploy/vision/common/processors/convert.h @@ -0,0 +1,42 @@ +// 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. + +#pragma once + +#include "fastdeploy/vision/common/processors/base.h" + +namespace fastdeploy { +namespace vision { +class Convert : public Processor { + public: + Convert(const std::vector& alpha, const std::vector& beta); + + bool CpuRun(Mat* mat); +#ifdef ENABLE_OPENCV_CUDA + bool GpuRun(Mat* mat); +#endif + std::string Name() { return "Convert"; } + + // Compute `result = mat * alpha + beta` directly by channel. + // The default behavior is the same as OpenCV's convertTo method. + static bool Run(Mat* mat, const std::vector& alpha, + const std::vector& beta, + ProcLib lib = ProcLib::OPENCV_CPU); + + private: + std::vector alpha_; + std::vector beta_; +}; +} // namespace vision +} // namespace fastdeploy diff --git a/fastdeploy/vision/common/processors/transform.h b/fastdeploy/vision/common/processors/transform.h index 12eec8d72df..08073b4e423 100644 --- a/fastdeploy/vision/common/processors/transform.h +++ b/fastdeploy/vision/common/processors/transform.h @@ -17,6 +17,7 @@ #include "fastdeploy/vision/common/processors/cast.h" #include "fastdeploy/vision/common/processors/center_crop.h" #include "fastdeploy/vision/common/processors/color_space_convert.h" +#include "fastdeploy/vision/common/processors/convert.h" #include "fastdeploy/vision/common/processors/hwc2chw.h" #include "fastdeploy/vision/common/processors/normalize.h" #include "fastdeploy/vision/common/processors/pad.h" diff --git a/fastdeploy/vision/meituan/yolov6.cc b/fastdeploy/vision/meituan/yolov6.cc index 8f37bf89c6f..8ac73771940 100644 --- a/fastdeploy/vision/meituan/yolov6.cc +++ b/fastdeploy/vision/meituan/yolov6.cc @@ -25,14 +25,14 @@ namespace meituan { void LetterBox(Mat* mat, std::vector size, std::vector color, bool _auto, bool scale_fill = false, bool scale_up = true, int stride = 32) { - float scale = std::min(size[1] * 1.0f / static_cast(mat->Height()), - size[0] * 1.0f / static_cast(mat->Width())); + float scale = std::min(size[1] * 1.0f / static_cast(mat->Height()), + size[0] * 1.0f / static_cast(mat->Width())); if (!scale_up) { scale = std::min(scale, 1.0f); } int resize_h = int(round(static_cast(mat->Height()) * scale)); - int resize_w = int(round(static_cast(mat->Width()) * scale)); + int resize_w = int(round(static_cast(mat->Width()) * scale)); int pad_w = size[0] - resize_w; int pad_h = size[1] - resize_h; @@ -85,13 +85,13 @@ bool YOLOv6::Initialize() { is_scale_up = false; stride = 32; max_wh = 4096.0f; - + if (!InitRuntime()) { FDERROR << "Failed to initialize fastdeploy backend." << std::endl; return false; } - // Check if the input shape is dynamic after Runtime already initialized, - // Note that, We need to force is_mini_pad 'false' to keep static + // Check if the input shape is dynamic after Runtime already initialized, + // Note that, We need to force is_mini_pad 'false' to keep static // shape after padding (LetterBox) when the is_dynamic_shape is 'false'. is_dynamic_input_ = false; auto shape = InputInfoOfRuntime(0).shape; @@ -102,7 +102,7 @@ bool YOLOv6::Initialize() { break; } } - if (!is_dynamic_input_) { + if (!is_dynamic_input_) { is_mini_pad = false; } return true; @@ -111,15 +111,15 @@ bool YOLOv6::Initialize() { bool YOLOv6::Preprocess(Mat* mat, FDTensor* output, std::map>* im_info) { // process after image load - float ratio = std::min(size[1] * 1.0f / static_cast(mat->Height()), - size[0] * 1.0f / static_cast(mat->Width())); + float ratio = std::min(size[1] * 1.0f / static_cast(mat->Height()), + size[0] * 1.0f / static_cast(mat->Width())); if (ratio != 1.0) { int interp = cv::INTER_AREA; if (ratio > 1.0) { interp = cv::INTER_LINEAR; } int resize_h = int(round(static_cast(mat->Height()) * ratio)); - int resize_w = int(round(static_cast(mat->Width()) * ratio)); + int resize_w = int(round(static_cast(mat->Width()) * ratio)); Resize::Run(mat, resize_w, resize_h, -1, -1, interp); } // yolov6's preprocess steps @@ -129,8 +129,12 @@ bool YOLOv6::Preprocess(Mat* mat, FDTensor* output, LetterBox(mat, size, padding_value, is_mini_pad, is_no_pad, is_scale_up, stride); BGR2RGB::Run(mat); - Normalize::Run(mat, std::vector(mat->Channels(), 0.0), - std::vector(mat->Channels(), 1.0)); + // Normalize::Run(mat, std::vector(mat->Channels(), 0.0), + // std::vector(mat->Channels(), 1.0)); + // Compute `result = mat * alpha + beta` directly by channel + std::vector alpha = {1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f}; + std::vector beta = {0.0f, 0.0f, 0.0f}; + Convert::Run(mat, alpha, beta); // Record output shape of preprocessed image (*im_info)["output_shape"] = {static_cast(mat->Height()), diff --git a/fastdeploy/vision/ppcls/model.cc b/fastdeploy/vision/ppcls/model.cc index 915cb975129..c4e5b767c71 100644 --- a/fastdeploy/vision/ppcls/model.cc +++ b/fastdeploy/vision/ppcls/model.cc @@ -1,3 +1,16 @@ +// 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/vision/ppcls/model.h" #include "fastdeploy/vision/utils/utils.h" @@ -135,6 +148,6 @@ bool Model::Predict(cv::Mat* im, ClassifyResult* result, int topk) { return true; } -} // namespace ppcls -} // namespace vision -} // namespace fastdeploy +} // namespace ppcls +} // namespace vision +} // namespace fastdeploy diff --git a/fastdeploy/vision/ppcls/model.h b/fastdeploy/vision/ppcls/model.h index 36841d74c68..265f92d32ba 100644 --- a/fastdeploy/vision/ppcls/model.h +++ b/fastdeploy/vision/ppcls/model.h @@ -1,7 +1,21 @@ +// 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. + #pragma once #include "fastdeploy/fastdeploy_model.h" -#include "fastdeploy/vision/common/result.h" #include "fastdeploy/vision/common/processors/transform.h" +#include "fastdeploy/vision/common/result.h" namespace fastdeploy { namespace vision { diff --git a/fastdeploy/vision/ppcls/ppcls_pybind.cc b/fastdeploy/vision/ppcls/ppcls_pybind.cc index ef3fffee8ec..1abc0b2b7c5 100644 --- a/fastdeploy/vision/ppcls/ppcls_pybind.cc +++ b/fastdeploy/vision/ppcls/ppcls_pybind.cc @@ -14,7 +14,7 @@ #include "fastdeploy/pybind/main.h" namespace fastdeploy { -void BindPpClsModel(pybind11::module& m) { +void BindPPCls(pybind11::module& m) { auto ppcls_module = m.def_submodule("ppcls", "Module to deploy PaddleClas."); pybind11::class_(ppcls_module, "Model") .def(pybind11::init(ppdet_module, + "PPYOLOE") + .def(pybind11::init()) + .def("predict", [](vision::ppdet::PPYOLOE& self, pybind11::array& data, + float conf_threshold, float nms_iou_threshold) { + auto mat = PyArrayToCvMat(data); + vision::DetectionResult res; + self.Predict(&mat, &res, conf_threshold, nms_iou_threshold); + return res; + }); +} +} // namespace fastdeploy diff --git a/fastdeploy/vision/ppdet/ppyoloe.cc b/fastdeploy/vision/ppdet/ppyoloe.cc new file mode 100644 index 00000000000..c215ecb0cab --- /dev/null +++ b/fastdeploy/vision/ppdet/ppyoloe.cc @@ -0,0 +1,170 @@ +#include "fastdeploy/vision/ppdet/ppyoloe.h" +#include "fastdeploy/vision/utils/utils.h" +#include "yaml-cpp/yaml.h" + +namespace fastdeploy { +namespace vision { +namespace ppdet { + +PPYOLOE::PPYOLOE(const std::string& model_file, const std::string& params_file, + const std::string& config_file, + const RuntimeOption& custom_option, + const Frontend& model_format) { + config_file_ = config_file; + valid_cpu_backends = {Backend::ORT, Backend::PDINFER}; + valid_gpu_backends = {Backend::ORT, Backend::PDINFER}; + runtime_option = custom_option; + runtime_option.model_format = model_format; + runtime_option.model_file = model_file; + runtime_option.params_file = params_file; + initialized = Initialize(); +} + +bool PPYOLOE::Initialize() { + if (!BuildPreprocessPipelineFromConfig()) { + std::cout << "Failed to build preprocess pipeline from configuration file." + << std::endl; + return false; + } + if (!InitRuntime()) { + std::cout << "Failed to initialize fastdeploy backend." << std::endl; + return false; + } + return true; +} + +bool PPYOLOE::BuildPreprocessPipelineFromConfig() { + processors_.clear(); + YAML::Node cfg; + try { + cfg = YAML::LoadFile(config_file_); + } catch (YAML::BadFile& e) { + std::cout << "Failed to load yaml file " << config_file_ + << ", maybe you should check this file." << std::endl; + return false; + } + + if (cfg["arch"].as() != "YOLO") { + std::cout << "Require the arch of model is YOLO, but arch defined in " + "config file is " + << cfg["arch"].as() << "." << std::endl; + return false; + } + processors_.push_back(std::make_shared()); + + for (const auto& op : cfg["Preprocess"]) { + std::string op_name = op["type"].as(); + if (op_name == "NormalizeImage") { + auto mean = op["mean"].as>(); + auto std = op["std"].as>(); + bool is_scale = op["is_scale"].as(); + processors_.push_back(std::make_shared(mean, std, is_scale)); + } else if (op_name == "Resize") { + bool keep_ratio = op["keep_ratio"].as(); + auto target_size = op["target_size"].as>(); + int interp = op["interp"].as(); + FDASSERT(target_size.size(), + "Require size of target_size be 2, but now it's " + + std::to_string(target_size.size()) + "."); + FDASSERT(!keep_ratio, + "Only support keep_ratio is false while deploy " + "PaddleDetection model."); + int width = target_size[1]; + int height = target_size[0]; + processors_.push_back( + std::make_shared(width, height, -1.0, -1.0, interp, false)); + } else if (op_name == "Permute") { + processors_.push_back(std::make_shared()); + } else { + std::cout << "Unexcepted preprocess operator: " << op_name << "." + << std::endl; + return false; + } + } + return true; +} + +bool PPYOLOE::Preprocess(Mat* mat, std::vector* outputs) { + int origin_w = mat->Width(); + int origin_h = mat->Height(); + for (size_t i = 0; i < processors_.size(); ++i) { + if (!(*(processors_[i].get()))(mat)) { + std::cout << "Failed to process image data in " << processors_[i]->Name() + << "." << std::endl; + return false; + } + } + + outputs->resize(2); + (*outputs)[0].name = InputInfoOfRuntime(0).name; + mat->ShareWithTensor(&((*outputs)[0])); + + // reshape to [1, c, h, w] + (*outputs)[0].shape.insert((*outputs)[0].shape.begin(), 1); + + (*outputs)[1].Allocate({1, 2}, FDDataType::FP32, InputInfoOfRuntime(1).name); + float* ptr = static_cast((*outputs)[1].MutableData()); + ptr[0] = mat->Height() * 1.0 / mat->Height(); + ptr[1] = mat->Width() * 1.0 / mat->Width(); + return true; +} + +bool PPYOLOE::Postprocess(std::vector& infer_result, + DetectionResult* result, float conf_threshold, + float nms_threshold) { + FDASSERT(infer_result[1].shape[0] == 1, + "Only support batch = 1 in FastDeploy now."); + int box_num = 0; + if (infer_result[1].dtype == FDDataType::INT32) { + box_num = *(static_cast(infer_result[1].Data())); + } else if (infer_result[1].dtype == FDDataType::INT64) { + box_num = *(static_cast(infer_result[1].Data())); + } else { + FDASSERT( + false, + "The output box_num of PPYOLOE model should be type of int32/int64."); + } + result->Reserve(box_num); + float* box_data = static_cast(infer_result[0].Data()); + for (size_t i = 0; i < box_num; ++i) { + if (box_data[i * 6 + 1] < conf_threshold) { + continue; + } + result->label_ids.push_back(box_data[i * 6]); + result->scores.push_back(box_data[i * 6 + 1]); + result->boxes.emplace_back( + std::array{box_data[i * 6 + 2], box_data[i * 6 + 3], + box_data[i * 6 + 4] - box_data[i * 6 + 2], + box_data[i * 6 + 5] - box_data[i * 6 + 3]}); + } + return true; +} + +bool PPYOLOE::Predict(cv::Mat* im, DetectionResult* result, + float conf_threshold, float iou_threshold) { + Mat mat(*im); + std::vector processed_data; + if (!Preprocess(&mat, &processed_data)) { + FDERROR << "Failed to preprocess input data while using model:" + << ModelName() << "." << std::endl; + return false; + } + + std::vector infer_result; + if (!Infer(processed_data, &infer_result)) { + FDERROR << "Failed to inference while using model:" << ModelName() << "." + << std::endl; + return false; + } + + if (!Postprocess(infer_result, result, conf_threshold, iou_threshold)) { + FDERROR << "Failed to postprocess while using model:" << ModelName() << "." + << std::endl; + return false; + } + return true; +} + +} // namespace ppdet +} // namespace vision +} // namespace fastdeploy diff --git a/fastdeploy/vision/ppdet/ppyoloe.h b/fastdeploy/vision/ppdet/ppyoloe.h new file mode 100644 index 00000000000..a3db268ca47 --- /dev/null +++ b/fastdeploy/vision/ppdet/ppyoloe.h @@ -0,0 +1,44 @@ +#pragma once +#include "fastdeploy/fastdeploy_model.h" +#include "fastdeploy/vision/common/processors/transform.h" +#include "fastdeploy/vision/common/result.h" + +#include "fastdeploy/vision/utils/utils.h" + +namespace fastdeploy { +namespace vision { +namespace ppdet { + +class FASTDEPLOY_DECL PPYOLOE : public FastDeployModel { + public: + PPYOLOE(const std::string& model_file, const std::string& params_file, + const std::string& config_file, + const RuntimeOption& custom_option = RuntimeOption(), + const Frontend& model_format = Frontend::PADDLE); + + std::string ModelName() const { return "PaddleDetection/PPYOLOE"; } + + virtual bool Initialize(); + + virtual bool BuildPreprocessPipelineFromConfig(); + + virtual bool Preprocess(Mat* mat, std::vector* outputs); + + virtual bool Postprocess(std::vector& infer_result, + DetectionResult* result, float conf_threshold, + float nms_threshold); + + virtual bool Predict(cv::Mat* im, DetectionResult* result, + float conf_threshold = 0.5, float nms_threshold = 0.7); + + private: + std::vector> processors_; + std::string config_file_; + // PaddleDetection can export model without nms + // This flag will help us to handle the different + // situation + bool has_nms_; +}; +} // namespace ppdet +} // namespace vision +} // namespace fastdeploy diff --git a/fastdeploy/vision/ultralytics/yolov5.cc b/fastdeploy/vision/ultralytics/yolov5.cc index 193cfe97948..0b7e50e735b 100644 --- a/fastdeploy/vision/ultralytics/yolov5.cc +++ b/fastdeploy/vision/ultralytics/yolov5.cc @@ -87,8 +87,8 @@ bool YOLOv5::Initialize() { FDERROR << "Failed to initialize fastdeploy backend." << std::endl; return false; } - // Check if the input shape is dynamic after Runtime already initialized, - // Note that, We need to force is_mini_pad 'false' to keep static + // Check if the input shape is dynamic after Runtime already initialized, + // Note that, We need to force is_mini_pad 'false' to keep static // shape after padding (LetterBox) when the is_dynamic_shape is 'false'. is_dynamic_input_ = false; auto shape = InputInfoOfRuntime(0).shape; @@ -99,7 +99,7 @@ bool YOLOv5::Initialize() { break; } } - if (!is_dynamic_input_) { + if (!is_dynamic_input_) { is_mini_pad = false; } return true; @@ -126,8 +126,12 @@ bool YOLOv5::Preprocess(Mat* mat, FDTensor* output, LetterBox(mat, size, padding_value, is_mini_pad, is_no_pad, is_scale_up, stride); BGR2RGB::Run(mat); - Normalize::Run(mat, std::vector(mat->Channels(), 0.0), - std::vector(mat->Channels(), 1.0)); + // Normalize::Run(mat, std::vector(mat->Channels(), 0.0), + // std::vector(mat->Channels(), 1.0)); + // Compute `result = mat * alpha + beta` directly by channel + std::vector alpha = {1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f}; + std::vector beta = {0.0f, 0.0f, 0.0f}; + Convert::Run(mat, alpha, beta); // Record output shape of preprocessed image (*im_info)["output_shape"] = {static_cast(mat->Height()), @@ -198,6 +202,11 @@ bool YOLOv5::Postprocess( result->scores.push_back(confidence); } } + + if (result->boxes.size() == 0) { + return true; + } + utils::NMS(result, nms_iou_threshold); // scale the boxes to the origin image shape diff --git a/fastdeploy/vision/utils/sort_det_res.cc b/fastdeploy/vision/utils/sort_det_res.cc index e4a0db97614..93dbb69694b 100644 --- a/fastdeploy/vision/utils/sort_det_res.cc +++ b/fastdeploy/vision/utils/sort_det_res.cc @@ -68,7 +68,11 @@ void MergeSort(DetectionResult* result, size_t low, size_t high) { void SortDetectionResult(DetectionResult* result) { size_t low = 0; - size_t high = result->scores.size() - 1; + size_t high = result->scores.size(); + if (high == 0) { + return; + } + high = high - 1; MergeSort(result, low, high); } diff --git a/fastdeploy/vision/vision_pybind.cc b/fastdeploy/vision/vision_pybind.cc index 41ada5541a2..0334303ce6e 100644 --- a/fastdeploy/vision/vision_pybind.cc +++ b/fastdeploy/vision/vision_pybind.cc @@ -16,7 +16,8 @@ namespace fastdeploy { -void BindPpClsModel(pybind11::module& m); +void BindPPCls(pybind11::module& m); +void BindPPDet(pybind11::module& m); void BindWongkinyiu(pybind11::module& m); void BindUltralytics(pybind11::module& m); void BindMeituan(pybind11::module& m); @@ -41,13 +42,14 @@ void BindVision(pybind11::module& m) { .def("__repr__", &vision::DetectionResult::Str) .def("__str__", &vision::DetectionResult::Str); - BindPpClsModel(m); + BindPPCls(m); + BindPPDet(m); BindUltralytics(m); BindWongkinyiu(m); BindMeituan(m); BindMegvii(m); #ifdef ENABLE_VISION_VISUALIZE BindVisualize(m); -#endif +#endif } -} // namespace fastdeploy +} // namespace fastdeploy diff --git a/fastdeploy/vision/visualize/detection.cc b/fastdeploy/vision/visualize/detection.cc index d0c41161487..5b5538bff7f 100644 --- a/fastdeploy/vision/visualize/detection.cc +++ b/fastdeploy/vision/visualize/detection.cc @@ -43,7 +43,7 @@ void Visualize::VisDetection(cv::Mat* im, const DetectionResult& result, } std::string text = id + "," + score; int font = cv::FONT_HERSHEY_SIMPLEX; - cv::Size text_size = cv::getTextSize(text, font, font_size, 0.5, nullptr); + cv::Size text_size = cv::getTextSize(text, font, font_size, 1, nullptr); cv::Point origin; origin.x = rect.x; origin.y = rect.y; @@ -52,7 +52,7 @@ void Visualize::VisDetection(cv::Mat* im, const DetectionResult& result, text_size.width, text_size.height); cv::rectangle(*im, rect, rect_color, line_size); cv::putText(*im, text, origin, font, font_size, cv::Scalar(255, 255, 255), - 0.5); + 1); } } diff --git a/model_zoo/vision/ppyoloe/README.md b/model_zoo/vision/ppyoloe/README.md new file mode 100644 index 00000000000..42d18104ad8 --- /dev/null +++ b/model_zoo/vision/ppyoloe/README.md @@ -0,0 +1,52 @@ +# PaddleDetection/PPYOLOE部署示例 + +- 当前支持PaddleDetection版本为[release/2.4](https://github.com/PaddlePaddle/PaddleDetection/tree/release/2.4) + +本文档说明如何进行[PPYOLOE](https://github.com/PaddlePaddle/PaddleDetection/tree/release/2.4/configs/ppyoloe)的快速部署推理。本目录结构如下 +``` +. +├── cpp # C++ 代码目录 +│   ├── CMakeLists.txt # C++ 代码编译CMakeLists文件 +│   ├── README.md # C++ 代码编译部署文档 +│   └── ppyoloe.cc # C++ 示例代码 +├── README.md # PPYOLOE 部署文档 +└── ppyoloe.py # Python示例代码 +``` + +## 安装FastDeploy + +使用如下命令安装FastDeploy,注意到此处安装的是`vision-cpu`,也可根据需求安装`vision-gpu` +``` +# 安装fastdeploy-python工具 +pip install fastdeploy-python +``` + +## Python部署 + +执行如下代码即会自动下载PPYOLOE模型和测试图片 +``` +python ppyoloe.py +``` + +执行完成后会将可视化结果保存在本地`vis_result.jpg`,同时输出检测结果如下 +``` +DetectionResult: [xmin, ymin, xmax, ymax, score, label_id] +162.380249,132.057449, 463.178345, 413.167114, 0.962918, 33 +414.914642,141.148666, 91.275269, 308.688293, 0.951003, 0 +163.449234,129.669067, 35.253891, 135.111786, 0.900734, 0 +267.232239,142.290436, 31.578918, 126.329773, 0.848709, 0 +581.790833,179.027115, 30.893127, 135.484940, 0.837986, 0 +104.407021,72.602615, 22.900627, 75.469055, 0.796468, 0 +348.795380,70.122147, 18.806061, 85.829330, 0.785557, 0 +364.118683,92.457428, 17.437622, 89.212891, 0.774282, 0 +75.180283,192.470490, 41.898407, 55.552414, 0.712569, 56 +328.133759,61.894299, 19.100616, 65.633575, 0.710519, 0 +504.797760,181.732574, 107.740814, 248.115082, 0.708902, 0 +379.063080,64.762360, 15.956146, 68.312546, 0.680725, 0 +25.858747,186.564178, 34.958130, 56.007080, 0.580415, 0 +``` + +## 其它文档 + +- [C++部署](./cpp/README.md) +- [PPYOLOE API文档](./api.md) diff --git a/model_zoo/vision/ppyoloe/api.md b/model_zoo/vision/ppyoloe/api.md new file mode 100644 index 00000000000..1c5cbcaadbd --- /dev/null +++ b/model_zoo/vision/ppyoloe/api.md @@ -0,0 +1,74 @@ +# PPYOLOE API说明 + +## Python API + +### PPYOLOE类 +``` +fastdeploy.vision.ultralytics.PPYOLOE(model_file, params_file, config_file, runtime_option=None, model_format=fd.Frontend.PADDLE) +``` +PPYOLOE模型加载和初始化,需同时提供model_file和params_file, 当前仅支持model_format为Paddle格式 + +**参数** + +> * **model_file**(str): 模型文件路径 +> * **params_file**(str): 参数文件路径 +> * **config_file**(str): 模型推理配置文件 +> * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置 +> * **model_format**(Frontend): 模型格式 + +#### predict函数 +> ``` +> PPYOLOE.predict(image_data, conf_threshold=0.25, nms_iou_threshold=0.5) +> ``` +> 模型预测结口,输入图像直接输出检测结果。 +> +> **参数** +> +> > * **image_data**(np.ndarray): 输入数据,注意需为HWC,BGR格式 +> > * **conf_threshold**(float): 检测框置信度过滤阈值 +> > * **nms_iou_threshold**(float): NMS处理过程中iou阈值(当模型中包含nms处理时,此参数自动无效) + +示例代码参考[ppyoloe.py](./ppyoloe.py) + + +## C++ API + +### PPYOLOE类 +``` +fastdeploy::vision::ultralytics::PPYOLOE( + const string& model_file, + const string& params_file, + const string& config_file, + const RuntimeOption& runtime_option = RuntimeOption(), + const Frontend& model_format = Frontend::ONNX) +``` +PPYOLOE模型加载和初始化,需同时提供model_file和params_file, 当前仅支持model_format为Paddle格式 + +**参数** + +> * **model_file**(str): 模型文件路径 +> * **params_file**(str): 参数文件路径 +> * **config_file**(str): 模型推理配置文件 +> * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置 +> * **model_format**(Frontend): 模型格式 + +#### Predict函数 +> ``` +> YOLOv5::Predict(cv::Mat* im, DetectionResult* result, +> float conf_threshold = 0.25, +> float nms_iou_threshold = 0.5) +> ``` +> 模型预测接口,输入图像直接输出检测结果。 +> +> **参数** +> +> > * **im**: 输入图像,注意需为HWC,BGR格式 +> > * **result**: 检测结果,包括检测框,各个框的置信度 +> > * **conf_threshold**: 检测框置信度过滤阈值 +> > * **nms_iou_threshold**: NMS处理过程中iou阈值(当模型中包含nms处理时,此参数自动无效) + +示例代码参考[cpp/yolov5.cc](cpp/yolov5.cc) + +## 其它API使用 + +- [模型部署RuntimeOption配置](../../../docs/api/runtime_option.md) diff --git a/model_zoo/vision/ppyoloe/cpp/CMakeLists.txt b/model_zoo/vision/ppyoloe/cpp/CMakeLists.txt new file mode 100644 index 00000000000..e6815665171 --- /dev/null +++ b/model_zoo/vision/ppyoloe/cpp/CMakeLists.txt @@ -0,0 +1,17 @@ +PROJECT(ppyoloe_demo C CXX) +CMAKE_MINIMUM_REQUIRED (VERSION 3.16) + +# 在低版本ABI环境中,通过如下代码进行兼容性编译 +# add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) + +# 指定下载解压后的fastdeploy库路径 +set(FASTDEPLOY_INSTALL_DIR ${PROJECT_SOURCE_DIR}/fastdeploy-linux-x64-0.3.0/) + +include(${FASTDEPLOY_INSTALL_DIR}/FastDeploy.cmake) + +# 添加FastDeploy依赖头文件 +include_directories(${FASTDEPLOY_INCS}) + +add_executable(ppyoloe_demo ${PROJECT_SOURCE_DIR}/ppyoloe.cc) +# 添加FastDeploy库依赖 +target_link_libraries(ppyoloe_demo ${FASTDEPLOY_LIBS}) diff --git a/model_zoo/vision/ppyoloe/cpp/README.md b/model_zoo/vision/ppyoloe/cpp/README.md new file mode 100644 index 00000000000..1027c2eeb24 --- /dev/null +++ b/model_zoo/vision/ppyoloe/cpp/README.md @@ -0,0 +1,39 @@ +# 编译PPYOLOE示例 + + +``` +# 下载和解压预测库 +wget https://bj.bcebos.com/paddle2onnx/fastdeploy/fastdeploy-linux-x64-0.0.3.tgz +tar xvf fastdeploy-linux-x64-0.0.3.tgz + +# 编译示例代码 +mkdir build & cd build +cmake .. +make -j + +# 下载模型和图片 +wget https://bj.bcebos.com/paddle2onnx/fastdeploy/models/ppdet/ppyoloe_crn_l_300e_coco.tgz +tar xvf ppyoloe_crn_l_300e_coco.tgz +wget https://raw.githubusercontent.com/PaddlePaddle/PaddleDetection/release/2.4/demo/000000014439_640x640.jpg + +# 执行 +./ppyoloe_demo +``` + +执行完后可视化的结果保存在本地`vis_result.jpg`,同时会将检测框输出在终端,如下所示 +``` +DetectionResult: [xmin, ymin, xmax, ymax, score, label_id] +162.380249,132.057449, 463.178345, 413.167114, 0.962918, 33 +414.914642,141.148666, 91.275269, 308.688293, 0.951003, 0 +163.449234,129.669067, 35.253891, 135.111786, 0.900734, 0 +267.232239,142.290436, 31.578918, 126.329773, 0.848709, 0 +581.790833,179.027115, 30.893127, 135.484940, 0.837986, 0 +104.407021,72.602615, 22.900627, 75.469055, 0.796468, 0 +348.795380,70.122147, 18.806061, 85.829330, 0.785557, 0 +364.118683,92.457428, 17.437622, 89.212891, 0.774282, 0 +75.180283,192.470490, 41.898407, 55.552414, 0.712569, 56 +328.133759,61.894299, 19.100616, 65.633575, 0.710519, 0 +504.797760,181.732574, 107.740814, 248.115082, 0.708902, 0 +379.063080,64.762360, 15.956146, 68.312546, 0.680725, 0 +25.858747,186.564178, 34.958130, 56.007080, 0.580415, 0 +``` diff --git a/model_zoo/vision/ppyoloe/cpp/ppyoloe.cc b/model_zoo/vision/ppyoloe/cpp/ppyoloe.cc new file mode 100644 index 00000000000..e63f29e62a5 --- /dev/null +++ b/model_zoo/vision/ppyoloe/cpp/ppyoloe.cc @@ -0,0 +1,51 @@ +// 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/vision.h" + +int main() { + namespace vis = fastdeploy::vision; + + std::string model_file = "ppyoloe_crn_l_300e_coco/model.pdmodel"; + std::string params_file = "ppyoloe_crn_l_300e_coco/model.pdiparams"; + std::string config_file = "ppyoloe_crn_l_300e_coco/infer_cfg.yml"; + std::string img_path = "000000014439_640x640.jpg"; + std::string vis_path = "vis.jpeg"; + + auto model = vis::ppdet::PPYOLOE(model_file, params_file, config_file); + if (!model.Initialized()) { + std::cerr << "Init Failed." << std::endl; + return -1; + } + + cv::Mat im = cv::imread(img_path); + cv::Mat vis_im = im.clone(); + + vis::DetectionResult res; + if (!model.Predict(&im, &res)) { + std::cerr << "Prediction Failed." << std::endl; + return -1; + } else { + std::cout << "Prediction Done!" << std::endl; + } + + // 输出预测框结果 + std::cout << res.Str() << std::endl; + + // 可视化预测结果 + vis::Visualize::VisDetection(&vis_im, res); + cv::imwrite(vis_path, vis_im); + std::cout << "Detect Done! Saved: " << vis_path << std::endl; + return 0; +} diff --git a/model_zoo/vision/ppyoloe/ppyoloe.py b/model_zoo/vision/ppyoloe/ppyoloe.py new file mode 100644 index 00000000000..7d79dfd8cf7 --- /dev/null +++ b/model_zoo/vision/ppyoloe/ppyoloe.py @@ -0,0 +1,24 @@ +import fastdeploy as fd +import cv2 + +# 下载模型和测试图片 +model_url = "https://bj.bcebos.com/paddle2onnx/fastdeploy/models/ppdet/ppyoloe_crn_l_300e_coco.tgz" +test_jpg_url = "https://raw.githubusercontent.com/PaddlePaddle/PaddleDetection/release/2.4/demo/000000014439_640x640.jpg" +fd.download_and_decompress(model_url, ".") +fd.download(test_jpg_url, ".", show_progress=True) + +# 加载模型 +model = fd.vision.ppdet.PPYOLOE("ppyoloe_crn_l_300e_coco/model.pdmodel", + "ppyoloe_crn_l_300e_coco/model.pdiparams", + "ppyoloe_crn_l_300e_coco/infer_cfg.yml") + +# 预测图片 +im = cv2.imread("000000014439_640x640.jpg") +result = model.predict(im, conf_threshold=0.5) + +# 可视化结果 +fd.vision.visualize.vis_detection(im, result) +cv2.imwrite("vis_result.jpg", im) + +# 输出预测结果 +print(result) diff --git a/setup.py b/setup.py index f0ff3f16dee..e76f057b1c0 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,8 @@ setup_configs["ENABLE_TRT_BACKEND"] = os.getenv("ENABLE_TRT_BACKEND", "OFF") setup_configs["WITH_GPU"] = os.getenv("WITH_GPU", "OFF") setup_configs["TRT_DIRECTORY"] = os.getenv("TRT_DIRECTORY", "UNDEFINED") -setup_configs["CUDA_DIRECTORY"] = os.getenv("CUDA_DIRECTORY", "/usr/local/cuda") +setup_configs["CUDA_DIRECTORY"] = os.getenv("CUDA_DIRECTORY", + "/usr/local/cuda") TOP_DIR = os.path.realpath(os.path.dirname(__file__)) SRC_DIR = os.path.join(TOP_DIR, "fastdeploy") @@ -325,17 +326,32 @@ def run(self): shutil.copy("LICENSE", "fastdeploy") depend_libs = list() - # modify the search path of libraries - command = "patchelf --set-rpath '$ORIGIN/libs/' .setuptools-cmake-build/fastdeploy_main.cpython-36m-x86_64-linux-gnu.so" - # The sw_64 not suppot patchelf, so we just disable that. - if platform.machine() != 'sw_64' and platform.machine() != 'mips64': - assert os.system(command) == 0, "patch fastdeploy_main.cpython-36m-x86_64-linux-gnu.so failed, the command: {}".format(command) + if platform.system().lower() == "linux": + for f in os.listdir(".setuptools-cmake-build"): + full_name = os.path.join(".setuptools-cmake-build", f) + if not os.path.isfile(full_name): + continue + if not full_name.count("fastdeploy_main.cpython-"): + continue + if not full_name.endswith(".so"): + continue + # modify the search path of libraries + command = "patchelf --set-rpath '$ORIGIN/libs/' {}".format( + full_name) + # The sw_64 not suppot patchelf, so we just disable that. + if platform.machine() != 'sw_64' and platform.machine( + ) != 'mips64': + assert os.system( + command + ) == 0, "patch fastdeploy_main.cpython-36m-x86_64-linux-gnu.so failed, the command: {}".format( + command) for f in os.listdir(".setuptools-cmake-build"): if not os.path.isfile(os.path.join(".setuptools-cmake-build", f)): continue if f.count("libfastdeploy") > 0: - shutil.copy(os.path.join(".setuptools-cmake-build", f), "fastdeploy/libs") + shutil.copy( + os.path.join(".setuptools-cmake-build", f), "fastdeploy/libs") for dirname in os.listdir(".setuptools-cmake-build/third_libs/install"): for lib in os.listdir( os.path.join(".setuptools-cmake-build/third_libs/install", From a182893d9232c3ff0ecda5d07ec6517ddca8f449 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Wed, 20 Jul 2022 07:38:15 +0000 Subject: [PATCH 35/69] first commit for yolor --- examples/CMakeLists.txt | 25 +- .../{ppdet_ppyoloe.cc => wongkinyiu_yolor.cc} | 15 +- fastdeploy/__init__.py | 2 +- fastdeploy/download.py | 2 +- fastdeploy/utils/utils.h | 27 +- fastdeploy/vision.h | 6 +- fastdeploy/vision/__init__.py | 1 - .../vision/common/processors/convert.cc | 62 ----- fastdeploy/vision/common/processors/convert.h | 42 --- .../vision/common/processors/transform.h | 1 - fastdeploy/vision/meituan/yolov6.cc | 8 +- fastdeploy/vision/ppcls/model.cc | 19 +- fastdeploy/vision/ppcls/model.h | 20 +- fastdeploy/vision/ppcls/ppcls_pybind.cc | 4 +- fastdeploy/vision/ppdet/__init__.py | 39 --- fastdeploy/vision/ppdet/ppdet_pybind.cc | 32 --- fastdeploy/vision/ppdet/ppyoloe.cc | 170 ------------ fastdeploy/vision/ppdet/ppyoloe.h | 44 ---- fastdeploy/vision/ultralytics/yolov5.cc | 13 +- fastdeploy/vision/utils/sort_det_res.cc | 6 +- fastdeploy/vision/vision_pybind.cc | 6 +- fastdeploy/vision/visualize/detection.cc | 8 +- fastdeploy/vision/wongkinyiu/__init__.py | 98 +++++++ .../vision/wongkinyiu/wongkinyiu_pybind.cc | 21 +- fastdeploy/vision/wongkinyiu/yolor.cc | 243 ++++++++++++++++++ fastdeploy/vision/wongkinyiu/yolor.h | 95 +++++++ model_zoo/vision/ppyoloe/README.md | 52 ---- model_zoo/vision/ppyoloe/cpp/README.md | 39 --- model_zoo/vision/ppyoloe/ppyoloe.py | 24 -- model_zoo/vision/yolor/README.md | 67 +++++ model_zoo/vision/{ppyoloe => yolor}/api.md | 31 +-- .../{ppyoloe => yolor}/cpp/CMakeLists.txt | 6 +- model_zoo/vision/yolor/cpp/README.md | 51 ++++ .../cpp/ppyoloe.cc => yolor/cpp/yolor.cc} | 17 +- model_zoo/vision/yolor/yolor.py | 21 ++ setup.py | 27 +- 36 files changed, 679 insertions(+), 665 deletions(-) rename examples/vision/{ppdet_ppyoloe.cc => wongkinyiu_yolor.cc} (75%) delete mode 100644 fastdeploy/vision/common/processors/convert.cc delete mode 100644 fastdeploy/vision/common/processors/convert.h delete mode 100644 fastdeploy/vision/ppdet/__init__.py delete mode 100644 fastdeploy/vision/ppdet/ppdet_pybind.cc delete mode 100644 fastdeploy/vision/ppdet/ppyoloe.cc delete mode 100644 fastdeploy/vision/ppdet/ppyoloe.h create mode 100644 fastdeploy/vision/wongkinyiu/yolor.cc create mode 100644 fastdeploy/vision/wongkinyiu/yolor.h delete mode 100644 model_zoo/vision/ppyoloe/README.md delete mode 100644 model_zoo/vision/ppyoloe/cpp/README.md delete mode 100644 model_zoo/vision/ppyoloe/ppyoloe.py create mode 100644 model_zoo/vision/yolor/README.md rename model_zoo/vision/{ppyoloe => yolor}/api.md (56%) rename model_zoo/vision/{ppyoloe => yolor}/cpp/CMakeLists.txt (75%) create mode 100644 model_zoo/vision/yolor/cpp/README.md rename model_zoo/vision/{ppyoloe/cpp/ppyoloe.cc => yolor/cpp/yolor.cc} (66%) create mode 100644 model_zoo/vision/yolor/yolor.py diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 112193c86a2..67361223c6b 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,26 +1,25 @@ -function(add_fastdeploy_executable FIELD CC_FILE) +function(add_fastdeploy_executable field url model) # temp target name/file var in function scope - set(TEMP_TARGET_FILE ${CC_FILE}) - string(REGEX MATCHALL "[0-9A-Za-z_]*.cc" FILE_NAME ${CC_FILE}) - string(REGEX REPLACE ".cc" "" FILE_PREFIX ${FILE_NAME}) - set(TEMP_TARGET_NAME ${FIELD}_${FILE_PREFIX}) + set(TEMP_TARGET_FILE ${PROJECT_SOURCE_DIR}/examples/${field}/${url}_${model}.cc) + set(TEMP_TARGET_NAME ${field}_${url}_${model}) if (EXISTS ${TEMP_TARGET_FILE} AND TARGET fastdeploy) add_executable(${TEMP_TARGET_NAME} ${TEMP_TARGET_FILE}) target_link_libraries(${TEMP_TARGET_NAME} PUBLIC fastdeploy) - message(STATUS " Added FastDeploy Executable : ${TEMP_TARGET_NAME}") + message(STATUS "Found source file: [${field}/${url}_${model}.cc], ADD!!! fastdeploy executable: [${TEMP_TARGET_NAME}] !") + else () + message(WARNING "Can not found source file: [${field}/${url}_${model}.cc], SKIP!!! fastdeploy executable: [${TEMP_TARGET_NAME}] !") endif() unset(TEMP_TARGET_FILE) unset(TEMP_TARGET_NAME) endfunction() # vision examples -if(WITH_VISION_EXAMPLES AND EXISTS ${PROJECT_SOURCE_DIR}/examples/vision) - message(STATUS "") - message(STATUS "*************FastDeploy Examples Summary**********") - file(GLOB ALL_VISION_EXAMPLE_SRCS ${PROJECT_SOURCE_DIR}/examples/vision/*.cc) - foreach(_CC_FILE ${ALL_VISION_EXAMPLE_SRCS}) - add_fastdeploy_executable(vision ${_CC_FILE}) - endforeach() +if (WITH_VISION_EXAMPLES) + add_fastdeploy_executable(vision ultralytics yolov5) + add_fastdeploy_executable(vision meituan yolov6) + add_fastdeploy_executable(vision wongkinyiu yolov7) + add_fastdeploy_executable(vision megvii yolox) + add_fastdeploy_executable(vision wongkinyiu yolor) endif() # other examples ... diff --git a/examples/vision/ppdet_ppyoloe.cc b/examples/vision/wongkinyiu_yolor.cc similarity index 75% rename from examples/vision/ppdet_ppyoloe.cc rename to examples/vision/wongkinyiu_yolor.cc index b234021c92e..abdca2b7fff 100644 --- a/examples/vision/ppdet_ppyoloe.cc +++ b/examples/vision/wongkinyiu_yolor.cc @@ -17,17 +17,18 @@ int main() { namespace vis = fastdeploy::vision; - std::string model_file = "ppyoloe_crn_l_300e_coco/model.pdmodel"; - std::string params_file = "ppyoloe_crn_l_300e_coco/model.pdiparams"; - std::string config_file = "ppyoloe_crn_l_300e_coco/infer_cfg.yml"; - std::string img_path = "test.jpeg"; - std::string vis_path = "vis.jpeg"; + std::string model_file = "../resources/models/yolor.onnx"; + std::string img_path = "../resources/images/horses.jpg"; + std::string vis_path = "../resources/outputs/wongkinyiu_yolor_vis_result.jpg"; - auto model = vis::ppdet::PPYOLOE(model_file, params_file, config_file); + auto model = vis::wongkinyiu::YOLOR(model_file); if (!model.Initialized()) { - std::cerr << "Init Failed." << std::endl; + std::cerr << "Init Failed! Model: " << model_file << std::endl; return -1; + } else { + std::cout << "Init Done! Model:" << model_file << std::endl; } + model.EnableDebug(); cv::Mat im = cv::imread(img_path); cv::Mat vis_im = im.clone(); diff --git a/fastdeploy/__init__.py b/fastdeploy/__init__.py index 68006c1bed5..500e7cc42ae 100644 --- a/fastdeploy/__init__.py +++ b/fastdeploy/__init__.py @@ -17,7 +17,7 @@ from .fastdeploy_runtime import * from . import fastdeploy_main as C from . import vision -from .download import download, download_and_decompress +from .download import download def TensorInfoStr(tensor_info): diff --git a/fastdeploy/download.py b/fastdeploy/download.py index 67f21d8e76d..e00af098dfd 100644 --- a/fastdeploy/download.py +++ b/fastdeploy/download.py @@ -156,7 +156,7 @@ def decompress(fname): def url2dir(url, path, rename=None): full_name = download(url, path, rename, show_progress=True) - print("File is donwloaded, now extracting...") + print("SDK is donwloaded, now extracting...") if url.count(".tgz") > 0 or url.count(".tar") > 0 or url.count("zip") > 0: return decompress(full_name) diff --git a/fastdeploy/utils/utils.h b/fastdeploy/utils/utils.h index 93120842659..23ca6ee51aa 100644 --- a/fastdeploy/utils/utils.h +++ b/fastdeploy/utils/utils.h @@ -26,10 +26,10 @@ #define FASTDEPLOY_DECL __declspec(dllexport) #else #define FASTDEPLOY_DECL __declspec(dllimport) -#endif // FASTDEPLOY_LIB +#endif // FASTDEPLOY_LIB #else #define FASTDEPLOY_DECL __attribute__((visibility("default"))) -#endif // _WIN32 +#endif // _WIN32 namespace fastdeploy { @@ -42,7 +42,8 @@ class FASTDEPLOY_DECL FDLogger { } explicit FDLogger(bool verbose, const std::string& prefix = "[FastDeploy]"); - template FDLogger& operator<<(const T& val) { + template + FDLogger& operator<<(const T& val) { if (!verbose_) { return *this; } @@ -64,18 +65,14 @@ class FASTDEPLOY_DECL FDLogger { bool verbose_ = true; }; -#ifndef __REL_FILE__ -#define __REL_FILE__ __FILE__ -#endif +#define FDERROR \ + FDLogger(true, "[ERROR]") << __REL_FILE__ << "(" << __LINE__ \ + << ")::" << __FUNCTION__ << "\t" -#define FDERROR \ - FDLogger(true, "[ERROR]") \ - << __REL_FILE__ << "(" << __LINE__ << ")::" << __FUNCTION__ << "\t" - -#define FDASSERT(condition, message) \ - if (!(condition)) { \ - FDERROR << message << std::endl; \ - std::abort(); \ +#define FDASSERT(condition, message) \ + if (!(condition)) { \ + FDERROR << message << std::endl; \ + std::abort(); \ } -} // namespace fastdeploy +} // namespace fastdeploy diff --git a/fastdeploy/vision.h b/fastdeploy/vision.h index cafe310c706..43984632511 100644 --- a/fastdeploy/vision.h +++ b/fastdeploy/vision.h @@ -15,12 +15,12 @@ #include "fastdeploy/core/config.h" #ifdef ENABLE_VISION +#include "fastdeploy/vision/megvii/yolox.h" +#include "fastdeploy/vision/meituan/yolov6.h" #include "fastdeploy/vision/ppcls/model.h" -#include "fastdeploy/vision/ppdet/ppyoloe.h" #include "fastdeploy/vision/ultralytics/yolov5.h" +#include "fastdeploy/vision/wongkinyiu/yolor.h" #include "fastdeploy/vision/wongkinyiu/yolov7.h" -#include "fastdeploy/vision/meituan/yolov6.h" -#include "fastdeploy/vision/megvii/yolox.h" #endif #include "fastdeploy/vision/visualize/visualize.h" diff --git a/fastdeploy/vision/__init__.py b/fastdeploy/vision/__init__.py index 6acbf0c3763..7122bede0be 100644 --- a/fastdeploy/vision/__init__.py +++ b/fastdeploy/vision/__init__.py @@ -15,7 +15,6 @@ from . import evaluation from . import ppcls -from . import ppdet from . import ultralytics from . import meituan from . import megvii diff --git a/fastdeploy/vision/common/processors/convert.cc b/fastdeploy/vision/common/processors/convert.cc deleted file mode 100644 index a7ca6de07a9..00000000000 --- a/fastdeploy/vision/common/processors/convert.cc +++ /dev/null @@ -1,62 +0,0 @@ -// 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/vision/common/processors/convert.h" - -namespace fastdeploy { - -namespace vision { - -Convert::Convert(const std::vector& alpha, - const std::vector& beta) { - FDASSERT(alpha.size() == beta.size(), - "Convert: requires the size of alpha equal to the size of beta."); - FDASSERT(alpha.size() != 0, - "Convert: requires the size of alpha and beta > 0."); - alpha_.assign(alpha.begin(), alpha.end()); - beta_.assign(beta.begin(), beta.end()); -} - -bool Convert::CpuRun(Mat* mat) { - cv::Mat* im = mat->GetCpuMat(); - std::vector split_im; - cv::split(*im, split_im); - for (int c = 0; c < im->channels(); c++) { - split_im[c].convertTo(split_im[c], CV_32FC1, alpha_[c], beta_[c]); - } - cv::merge(split_im, *im); - return true; -} - -#ifdef ENABLE_OPENCV_CUDA -bool Convert::GpuRun(Mat* mat) { - cv::cuda::GpuMat* im = mat->GetGpuMat(); - std::vector split_im; - cv::cuda::split(*im, split_im); - for (int c = 0; c < im->channels(); c++) { - split_im[c].convertTo(split_im[c], CV_32FC1, alpha_[c], beta_[c]); - } - cv::cuda::merge(split_im, *im); - return true; -} -#endif - -bool Convert::Run(Mat* mat, const std::vector& alpha, - const std::vector& beta, ProcLib lib) { - auto c = Convert(alpha, beta); - return c(mat, lib); -} - -} // namespace vision -} // namespace fastdeploy \ No newline at end of file diff --git a/fastdeploy/vision/common/processors/convert.h b/fastdeploy/vision/common/processors/convert.h deleted file mode 100644 index 5d5a5276f5d..00000000000 --- a/fastdeploy/vision/common/processors/convert.h +++ /dev/null @@ -1,42 +0,0 @@ -// 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. - -#pragma once - -#include "fastdeploy/vision/common/processors/base.h" - -namespace fastdeploy { -namespace vision { -class Convert : public Processor { - public: - Convert(const std::vector& alpha, const std::vector& beta); - - bool CpuRun(Mat* mat); -#ifdef ENABLE_OPENCV_CUDA - bool GpuRun(Mat* mat); -#endif - std::string Name() { return "Convert"; } - - // Compute `result = mat * alpha + beta` directly by channel. - // The default behavior is the same as OpenCV's convertTo method. - static bool Run(Mat* mat, const std::vector& alpha, - const std::vector& beta, - ProcLib lib = ProcLib::OPENCV_CPU); - - private: - std::vector alpha_; - std::vector beta_; -}; -} // namespace vision -} // namespace fastdeploy diff --git a/fastdeploy/vision/common/processors/transform.h b/fastdeploy/vision/common/processors/transform.h index 08073b4e423..12eec8d72df 100644 --- a/fastdeploy/vision/common/processors/transform.h +++ b/fastdeploy/vision/common/processors/transform.h @@ -17,7 +17,6 @@ #include "fastdeploy/vision/common/processors/cast.h" #include "fastdeploy/vision/common/processors/center_crop.h" #include "fastdeploy/vision/common/processors/color_space_convert.h" -#include "fastdeploy/vision/common/processors/convert.h" #include "fastdeploy/vision/common/processors/hwc2chw.h" #include "fastdeploy/vision/common/processors/normalize.h" #include "fastdeploy/vision/common/processors/pad.h" diff --git a/fastdeploy/vision/meituan/yolov6.cc b/fastdeploy/vision/meituan/yolov6.cc index 8ac73771940..b75f2016ee7 100644 --- a/fastdeploy/vision/meituan/yolov6.cc +++ b/fastdeploy/vision/meituan/yolov6.cc @@ -129,12 +129,8 @@ bool YOLOv6::Preprocess(Mat* mat, FDTensor* output, LetterBox(mat, size, padding_value, is_mini_pad, is_no_pad, is_scale_up, stride); BGR2RGB::Run(mat); - // Normalize::Run(mat, std::vector(mat->Channels(), 0.0), - // std::vector(mat->Channels(), 1.0)); - // Compute `result = mat * alpha + beta` directly by channel - std::vector alpha = {1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f}; - std::vector beta = {0.0f, 0.0f, 0.0f}; - Convert::Run(mat, alpha, beta); + Normalize::Run(mat, std::vector(mat->Channels(), 0.0), + std::vector(mat->Channels(), 1.0)); // Record output shape of preprocessed image (*im_info)["output_shape"] = {static_cast(mat->Height()), diff --git a/fastdeploy/vision/ppcls/model.cc b/fastdeploy/vision/ppcls/model.cc index c4e5b767c71..915cb975129 100644 --- a/fastdeploy/vision/ppcls/model.cc +++ b/fastdeploy/vision/ppcls/model.cc @@ -1,16 +1,3 @@ -// 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/vision/ppcls/model.h" #include "fastdeploy/vision/utils/utils.h" @@ -148,6 +135,6 @@ bool Model::Predict(cv::Mat* im, ClassifyResult* result, int topk) { return true; } -} // namespace ppcls -} // namespace vision -} // namespace fastdeploy +} // namespace ppcls +} // namespace vision +} // namespace fastdeploy diff --git a/fastdeploy/vision/ppcls/model.h b/fastdeploy/vision/ppcls/model.h index 265f92d32ba..fae99d4f3c8 100644 --- a/fastdeploy/vision/ppcls/model.h +++ b/fastdeploy/vision/ppcls/model.h @@ -1,17 +1,3 @@ -// 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. - #pragma once #include "fastdeploy/fastdeploy_model.h" #include "fastdeploy/vision/common/processors/transform.h" @@ -46,6 +32,6 @@ class FASTDEPLOY_DECL Model : public FastDeployModel { std::vector> processors_; std::string config_file_; }; -} // namespace ppcls -} // namespace vision -} // namespace fastdeploy +} // namespace ppcls +} // namespace vision +} // namespace fastdeploy diff --git a/fastdeploy/vision/ppcls/ppcls_pybind.cc b/fastdeploy/vision/ppcls/ppcls_pybind.cc index 1abc0b2b7c5..828bef3c7aa 100644 --- a/fastdeploy/vision/ppcls/ppcls_pybind.cc +++ b/fastdeploy/vision/ppcls/ppcls_pybind.cc @@ -14,7 +14,7 @@ #include "fastdeploy/pybind/main.h" namespace fastdeploy { -void BindPPCls(pybind11::module& m) { +void BindPpClsModel(pybind11::module& m) { auto ppcls_module = m.def_submodule("ppcls", "Module to deploy PaddleClas."); pybind11::class_(ppcls_module, "Model") .def(pybind11::init(ppdet_module, - "PPYOLOE") - .def(pybind11::init()) - .def("predict", [](vision::ppdet::PPYOLOE& self, pybind11::array& data, - float conf_threshold, float nms_iou_threshold) { - auto mat = PyArrayToCvMat(data); - vision::DetectionResult res; - self.Predict(&mat, &res, conf_threshold, nms_iou_threshold); - return res; - }); -} -} // namespace fastdeploy diff --git a/fastdeploy/vision/ppdet/ppyoloe.cc b/fastdeploy/vision/ppdet/ppyoloe.cc deleted file mode 100644 index c215ecb0cab..00000000000 --- a/fastdeploy/vision/ppdet/ppyoloe.cc +++ /dev/null @@ -1,170 +0,0 @@ -#include "fastdeploy/vision/ppdet/ppyoloe.h" -#include "fastdeploy/vision/utils/utils.h" -#include "yaml-cpp/yaml.h" - -namespace fastdeploy { -namespace vision { -namespace ppdet { - -PPYOLOE::PPYOLOE(const std::string& model_file, const std::string& params_file, - const std::string& config_file, - const RuntimeOption& custom_option, - const Frontend& model_format) { - config_file_ = config_file; - valid_cpu_backends = {Backend::ORT, Backend::PDINFER}; - valid_gpu_backends = {Backend::ORT, Backend::PDINFER}; - runtime_option = custom_option; - runtime_option.model_format = model_format; - runtime_option.model_file = model_file; - runtime_option.params_file = params_file; - initialized = Initialize(); -} - -bool PPYOLOE::Initialize() { - if (!BuildPreprocessPipelineFromConfig()) { - std::cout << "Failed to build preprocess pipeline from configuration file." - << std::endl; - return false; - } - if (!InitRuntime()) { - std::cout << "Failed to initialize fastdeploy backend." << std::endl; - return false; - } - return true; -} - -bool PPYOLOE::BuildPreprocessPipelineFromConfig() { - processors_.clear(); - YAML::Node cfg; - try { - cfg = YAML::LoadFile(config_file_); - } catch (YAML::BadFile& e) { - std::cout << "Failed to load yaml file " << config_file_ - << ", maybe you should check this file." << std::endl; - return false; - } - - if (cfg["arch"].as() != "YOLO") { - std::cout << "Require the arch of model is YOLO, but arch defined in " - "config file is " - << cfg["arch"].as() << "." << std::endl; - return false; - } - processors_.push_back(std::make_shared()); - - for (const auto& op : cfg["Preprocess"]) { - std::string op_name = op["type"].as(); - if (op_name == "NormalizeImage") { - auto mean = op["mean"].as>(); - auto std = op["std"].as>(); - bool is_scale = op["is_scale"].as(); - processors_.push_back(std::make_shared(mean, std, is_scale)); - } else if (op_name == "Resize") { - bool keep_ratio = op["keep_ratio"].as(); - auto target_size = op["target_size"].as>(); - int interp = op["interp"].as(); - FDASSERT(target_size.size(), - "Require size of target_size be 2, but now it's " + - std::to_string(target_size.size()) + "."); - FDASSERT(!keep_ratio, - "Only support keep_ratio is false while deploy " - "PaddleDetection model."); - int width = target_size[1]; - int height = target_size[0]; - processors_.push_back( - std::make_shared(width, height, -1.0, -1.0, interp, false)); - } else if (op_name == "Permute") { - processors_.push_back(std::make_shared()); - } else { - std::cout << "Unexcepted preprocess operator: " << op_name << "." - << std::endl; - return false; - } - } - return true; -} - -bool PPYOLOE::Preprocess(Mat* mat, std::vector* outputs) { - int origin_w = mat->Width(); - int origin_h = mat->Height(); - for (size_t i = 0; i < processors_.size(); ++i) { - if (!(*(processors_[i].get()))(mat)) { - std::cout << "Failed to process image data in " << processors_[i]->Name() - << "." << std::endl; - return false; - } - } - - outputs->resize(2); - (*outputs)[0].name = InputInfoOfRuntime(0).name; - mat->ShareWithTensor(&((*outputs)[0])); - - // reshape to [1, c, h, w] - (*outputs)[0].shape.insert((*outputs)[0].shape.begin(), 1); - - (*outputs)[1].Allocate({1, 2}, FDDataType::FP32, InputInfoOfRuntime(1).name); - float* ptr = static_cast((*outputs)[1].MutableData()); - ptr[0] = mat->Height() * 1.0 / mat->Height(); - ptr[1] = mat->Width() * 1.0 / mat->Width(); - return true; -} - -bool PPYOLOE::Postprocess(std::vector& infer_result, - DetectionResult* result, float conf_threshold, - float nms_threshold) { - FDASSERT(infer_result[1].shape[0] == 1, - "Only support batch = 1 in FastDeploy now."); - int box_num = 0; - if (infer_result[1].dtype == FDDataType::INT32) { - box_num = *(static_cast(infer_result[1].Data())); - } else if (infer_result[1].dtype == FDDataType::INT64) { - box_num = *(static_cast(infer_result[1].Data())); - } else { - FDASSERT( - false, - "The output box_num of PPYOLOE model should be type of int32/int64."); - } - result->Reserve(box_num); - float* box_data = static_cast(infer_result[0].Data()); - for (size_t i = 0; i < box_num; ++i) { - if (box_data[i * 6 + 1] < conf_threshold) { - continue; - } - result->label_ids.push_back(box_data[i * 6]); - result->scores.push_back(box_data[i * 6 + 1]); - result->boxes.emplace_back( - std::array{box_data[i * 6 + 2], box_data[i * 6 + 3], - box_data[i * 6 + 4] - box_data[i * 6 + 2], - box_data[i * 6 + 5] - box_data[i * 6 + 3]}); - } - return true; -} - -bool PPYOLOE::Predict(cv::Mat* im, DetectionResult* result, - float conf_threshold, float iou_threshold) { - Mat mat(*im); - std::vector processed_data; - if (!Preprocess(&mat, &processed_data)) { - FDERROR << "Failed to preprocess input data while using model:" - << ModelName() << "." << std::endl; - return false; - } - - std::vector infer_result; - if (!Infer(processed_data, &infer_result)) { - FDERROR << "Failed to inference while using model:" << ModelName() << "." - << std::endl; - return false; - } - - if (!Postprocess(infer_result, result, conf_threshold, iou_threshold)) { - FDERROR << "Failed to postprocess while using model:" << ModelName() << "." - << std::endl; - return false; - } - return true; -} - -} // namespace ppdet -} // namespace vision -} // namespace fastdeploy diff --git a/fastdeploy/vision/ppdet/ppyoloe.h b/fastdeploy/vision/ppdet/ppyoloe.h deleted file mode 100644 index a3db268ca47..00000000000 --- a/fastdeploy/vision/ppdet/ppyoloe.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once -#include "fastdeploy/fastdeploy_model.h" -#include "fastdeploy/vision/common/processors/transform.h" -#include "fastdeploy/vision/common/result.h" - -#include "fastdeploy/vision/utils/utils.h" - -namespace fastdeploy { -namespace vision { -namespace ppdet { - -class FASTDEPLOY_DECL PPYOLOE : public FastDeployModel { - public: - PPYOLOE(const std::string& model_file, const std::string& params_file, - const std::string& config_file, - const RuntimeOption& custom_option = RuntimeOption(), - const Frontend& model_format = Frontend::PADDLE); - - std::string ModelName() const { return "PaddleDetection/PPYOLOE"; } - - virtual bool Initialize(); - - virtual bool BuildPreprocessPipelineFromConfig(); - - virtual bool Preprocess(Mat* mat, std::vector* outputs); - - virtual bool Postprocess(std::vector& infer_result, - DetectionResult* result, float conf_threshold, - float nms_threshold); - - virtual bool Predict(cv::Mat* im, DetectionResult* result, - float conf_threshold = 0.5, float nms_threshold = 0.7); - - private: - std::vector> processors_; - std::string config_file_; - // PaddleDetection can export model without nms - // This flag will help us to handle the different - // situation - bool has_nms_; -}; -} // namespace ppdet -} // namespace vision -} // namespace fastdeploy diff --git a/fastdeploy/vision/ultralytics/yolov5.cc b/fastdeploy/vision/ultralytics/yolov5.cc index 0b7e50e735b..c8c6e06a94c 100644 --- a/fastdeploy/vision/ultralytics/yolov5.cc +++ b/fastdeploy/vision/ultralytics/yolov5.cc @@ -126,12 +126,8 @@ bool YOLOv5::Preprocess(Mat* mat, FDTensor* output, LetterBox(mat, size, padding_value, is_mini_pad, is_no_pad, is_scale_up, stride); BGR2RGB::Run(mat); - // Normalize::Run(mat, std::vector(mat->Channels(), 0.0), - // std::vector(mat->Channels(), 1.0)); - // Compute `result = mat * alpha + beta` directly by channel - std::vector alpha = {1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f}; - std::vector beta = {0.0f, 0.0f, 0.0f}; - Convert::Run(mat, alpha, beta); + Normalize::Run(mat, std::vector(mat->Channels(), 0.0), + std::vector(mat->Channels(), 1.0)); // Record output shape of preprocessed image (*im_info)["output_shape"] = {static_cast(mat->Height()), @@ -202,11 +198,6 @@ bool YOLOv5::Postprocess( result->scores.push_back(confidence); } } - - if (result->boxes.size() == 0) { - return true; - } - utils::NMS(result, nms_iou_threshold); // scale the boxes to the origin image shape diff --git a/fastdeploy/vision/utils/sort_det_res.cc b/fastdeploy/vision/utils/sort_det_res.cc index 93dbb69694b..e4a0db97614 100644 --- a/fastdeploy/vision/utils/sort_det_res.cc +++ b/fastdeploy/vision/utils/sort_det_res.cc @@ -68,11 +68,7 @@ void MergeSort(DetectionResult* result, size_t low, size_t high) { void SortDetectionResult(DetectionResult* result) { size_t low = 0; - size_t high = result->scores.size(); - if (high == 0) { - return; - } - high = high - 1; + size_t high = result->scores.size() - 1; MergeSort(result, low, high); } diff --git a/fastdeploy/vision/vision_pybind.cc b/fastdeploy/vision/vision_pybind.cc index 0334303ce6e..e4ba05b8938 100644 --- a/fastdeploy/vision/vision_pybind.cc +++ b/fastdeploy/vision/vision_pybind.cc @@ -16,8 +16,7 @@ namespace fastdeploy { -void BindPPCls(pybind11::module& m); -void BindPPDet(pybind11::module& m); +void BindPpClsModel(pybind11::module& m); void BindWongkinyiu(pybind11::module& m); void BindUltralytics(pybind11::module& m); void BindMeituan(pybind11::module& m); @@ -42,8 +41,7 @@ void BindVision(pybind11::module& m) { .def("__repr__", &vision::DetectionResult::Str) .def("__str__", &vision::DetectionResult::Str); - BindPPCls(m); - BindPPDet(m); + BindPpClsModel(m); BindUltralytics(m); BindWongkinyiu(m); BindMeituan(m); diff --git a/fastdeploy/vision/visualize/detection.cc b/fastdeploy/vision/visualize/detection.cc index 5b5538bff7f..e5f01bdd35f 100644 --- a/fastdeploy/vision/visualize/detection.cc +++ b/fastdeploy/vision/visualize/detection.cc @@ -43,7 +43,7 @@ void Visualize::VisDetection(cv::Mat* im, const DetectionResult& result, } std::string text = id + "," + score; int font = cv::FONT_HERSHEY_SIMPLEX; - cv::Size text_size = cv::getTextSize(text, font, font_size, 1, nullptr); + cv::Size text_size = cv::getTextSize(text, font, font_size, 0.5, nullptr); cv::Point origin; origin.x = rect.x; origin.y = rect.y; @@ -52,10 +52,10 @@ void Visualize::VisDetection(cv::Mat* im, const DetectionResult& result, text_size.width, text_size.height); cv::rectangle(*im, rect, rect_color, line_size); cv::putText(*im, text, origin, font, font_size, cv::Scalar(255, 255, 255), - 1); + 0.5); } } -} // namespace vision -} // namespace fastdeploy +} // namespace vision +} // namespace fastdeploy #endif diff --git a/fastdeploy/vision/wongkinyiu/__init__.py b/fastdeploy/vision/wongkinyiu/__init__.py index 542389e208b..026d10062fb 100644 --- a/fastdeploy/vision/wongkinyiu/__init__.py +++ b/fastdeploy/vision/wongkinyiu/__init__.py @@ -114,3 +114,101 @@ def max_wh(self, value): assert isinstance( value, float), "The value to set `max_wh` must be type of float." self._model.max_wh = value + + +class YOLOR(FastDeployModel): + def __init__(self, + model_file, + params_file="", + runtime_option=None, + model_format=Frontend.ONNX): + # 调用基函数进行backend_option的初始化 + # 初始化后的option保存在self._runtime_option + super(YOLOR, self).__init__(runtime_option) + + self._model = C.vision.wongkinyiu.YOLOR( + model_file, params_file, self._runtime_option, model_format) + # 通过self.initialized判断整个模型的初始化是否成功 + assert self.initialized, "YOLOR initialize failed." + + def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): + return self._model.predict(input_image, conf_threshold, + nms_iou_threshold) + + # 一些跟YOLOv7模型有关的属性封装 + # 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持) + @property + def size(self): + return self._model.size + + @property + def padding_value(self): + return self._model.padding_value + + @property + def is_no_pad(self): + return self._model.is_no_pad + + @property + def is_mini_pad(self): + return self._model.is_mini_pad + + @property + def is_scale_up(self): + return self._model.is_scale_up + + @property + def stride(self): + return self._model.stride + + @property + def max_wh(self): + return self._model.max_wh + + @size.setter + def size(self, wh): + assert isinstance(wh, [list, tuple]),\ + "The value to set `size` must be type of tuple or list." + assert len(wh) == 2,\ + "The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format( + len(wh)) + self._model.size = wh + + @padding_value.setter + def padding_value(self, value): + assert isinstance( + value, + list), "The value to set `padding_value` must be type of list." + self._model.padding_value = value + + @is_no_pad.setter + def is_no_pad(self, value): + assert isinstance( + value, bool), "The value to set `is_no_pad` must be type of bool." + self._model.is_no_pad = value + + @is_mini_pad.setter + def is_mini_pad(self, value): + assert isinstance( + value, + bool), "The value to set `is_mini_pad` must be type of bool." + self._model.is_mini_pad = value + + @is_scale_up.setter + def is_scale_up(self, value): + assert isinstance( + value, + bool), "The value to set `is_scale_up` must be type of bool." + self._model.is_scale_up = value + + @stride.setter + def stride(self, value): + assert isinstance( + value, int), "The value to set `stride` must be type of int." + self._model.stride = value + + @max_wh.setter + def max_wh(self, value): + assert isinstance( + value, float), "The value to set `max_wh` must be type of float." + self._model.max_wh = value diff --git a/fastdeploy/vision/wongkinyiu/wongkinyiu_pybind.cc b/fastdeploy/vision/wongkinyiu/wongkinyiu_pybind.cc index 4a10f47a763..6bde2a1841b 100644 --- a/fastdeploy/vision/wongkinyiu/wongkinyiu_pybind.cc +++ b/fastdeploy/vision/wongkinyiu/wongkinyiu_pybind.cc @@ -17,7 +17,7 @@ namespace fastdeploy { void BindWongkinyiu(pybind11::module& m) { auto wongkinyiu_module = - m.def_submodule("wongkinyiu", "https://github.com/WongKinYiu/yolov7"); + m.def_submodule("wongkinyiu", "https://github.com/WongKinYiu"); pybind11::class_( wongkinyiu_module, "YOLOv7") .def(pybind11::init()) @@ -37,5 +37,24 @@ void BindWongkinyiu(pybind11::module& m) { .def_readwrite("is_scale_up", &vision::wongkinyiu::YOLOv7::is_scale_up) .def_readwrite("stride", &vision::wongkinyiu::YOLOv7::stride) .def_readwrite("max_wh", &vision::wongkinyiu::YOLOv7::max_wh); + + pybind11::class_( + wongkinyiu_module, "YOLOR") + .def(pybind11::init()) + .def("predict", + [](vision::wongkinyiu::YOLOR& self, pybind11::array& data, + float conf_threshold, float nms_iou_threshold) { + auto mat = PyArrayToCvMat(data); + vision::DetectionResult res; + self.Predict(&mat, &res, conf_threshold, nms_iou_threshold); + return res; + }) + .def_readwrite("size", &vision::wongkinyiu::YOLOR::size) + .def_readwrite("padding_value", &vision::wongkinyiu::YOLOR::padding_value) + .def_readwrite("is_mini_pad", &vision::wongkinyiu::YOLOR::is_mini_pad) + .def_readwrite("is_no_pad", &vision::wongkinyiu::YOLOR::is_no_pad) + .def_readwrite("is_scale_up", &vision::wongkinyiu::YOLOR::is_scale_up) + .def_readwrite("stride", &vision::wongkinyiu::YOLOR::stride) + .def_readwrite("max_wh", &vision::wongkinyiu::YOLOR::max_wh); } } // namespace fastdeploy diff --git a/fastdeploy/vision/wongkinyiu/yolor.cc b/fastdeploy/vision/wongkinyiu/yolor.cc new file mode 100644 index 00000000000..5cf9d6cb833 --- /dev/null +++ b/fastdeploy/vision/wongkinyiu/yolor.cc @@ -0,0 +1,243 @@ +// 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/vision/wongkinyiu/yolor.h" +#include "fastdeploy/utils/perf.h" +#include "fastdeploy/vision/utils/utils.h" + +namespace fastdeploy { +namespace vision { +namespace wongkinyiu { + +void YOLOR::LetterBox(Mat* mat, const std::vector& size, + const std::vector& color, bool _auto, + bool scale_fill, bool scale_up, int stride) { + float scale = + std::min(size[1] * 1.0 / mat->Height(), size[0] * 1.0 / mat->Width()); + if (!scale_up) { + scale = std::min(scale, 1.0f); + } + + int resize_h = int(round(mat->Height() * scale)); + int resize_w = int(round(mat->Width() * scale)); + + int pad_w = size[0] - resize_w; + int pad_h = size[1] - resize_h; + if (_auto) { + pad_h = pad_h % stride; + pad_w = pad_w % stride; + } else if (scale_fill) { + pad_h = 0; + pad_w = 0; + resize_h = size[1]; + resize_w = size[0]; + } + Resize::Run(mat, resize_w, resize_h); + if (pad_h > 0 || pad_w > 0) { + float half_h = pad_h * 1.0 / 2; + int top = int(round(half_h - 0.1)); + int bottom = int(round(half_h + 0.1)); + float half_w = pad_w * 1.0 / 2; + int left = int(round(half_w - 0.1)); + int right = int(round(half_w + 0.1)); + Pad::Run(mat, top, bottom, left, right, color); + } +} + +YOLOR::YOLOR(const std::string& model_file, const std::string& params_file, + const RuntimeOption& custom_option, const Frontend& model_format) { + if (model_format == Frontend::ONNX) { + valid_cpu_backends = {Backend::ORT}; // 指定可用的CPU后端 + valid_gpu_backends = {Backend::ORT, Backend::TRT}; // 指定可用的GPU后端 + } else { + valid_cpu_backends = {Backend::PDINFER, Backend::ORT}; + valid_gpu_backends = {Backend::PDINFER, Backend::ORT, Backend::TRT}; + } + runtime_option = custom_option; + runtime_option.model_format = model_format; + runtime_option.model_file = model_file; + runtime_option.params_file = params_file; + initialized = Initialize(); +} + +bool YOLOR::Initialize() { + // parameters for preprocess + size = {640, 640}; + padding_value = {114.0, 114.0, 114.0}; + is_mini_pad = false; + is_no_pad = false; + is_scale_up = false; + stride = 32; + max_wh = 7680.0; + + if (!InitRuntime()) { + FDERROR << "Failed to initialize fastdeploy backend." << std::endl; + return false; + } + return true; +} + +bool YOLOR::Preprocess(Mat* mat, FDTensor* output, + std::map>* im_info) { + // process after image load + double ratio = (size[0] * 1.0) / std::max(static_cast(mat->Height()), + static_cast(mat->Width())); + if (ratio != 1.0) { + int interp = cv::INTER_AREA; + if (ratio > 1.0) { + interp = cv::INTER_LINEAR; + } + int resize_h = int(mat->Height() * ratio); + int resize_w = int(mat->Width() * ratio); + Resize::Run(mat, resize_w, resize_h, -1, -1, interp); + } + // yolor's preprocess steps + // 1. letterbox + // 2. BGR->RGB + // 3. HWC->CHW + YOLOR::LetterBox(mat, size, padding_value, is_mini_pad, is_no_pad, + is_scale_up, stride); + BGR2RGB::Run(mat); + Normalize::Run(mat, std::vector(mat->Channels(), 0.0), + std::vector(mat->Channels(), 1.0)); + + // Record output shape of preprocessed image + (*im_info)["output_shape"] = {static_cast(mat->Height()), + static_cast(mat->Width())}; + + HWC2CHW::Run(mat); + Cast::Run(mat, "float"); + mat->ShareWithTensor(output); + output->shape.insert(output->shape.begin(), 1); // reshape to n, h, w, c + return true; +} + +bool YOLOR::Postprocess( + FDTensor& infer_result, DetectionResult* result, + const std::map>& im_info, + float conf_threshold, float nms_iou_threshold) { + FDASSERT(infer_result.shape[0] == 1, "Only support batch =1 now."); + result->Clear(); + result->Reserve(infer_result.shape[1]); + if (infer_result.dtype != FDDataType::FP32) { + FDERROR << "Only support post process with float32 data." << std::endl; + return false; + } + float* data = static_cast(infer_result.Data()); + for (size_t i = 0; i < infer_result.shape[1]; ++i) { + int s = i * infer_result.shape[2]; + float confidence = data[s + 4]; + float* max_class_score = + std::max_element(data + s + 5, data + s + infer_result.shape[2]); + confidence *= (*max_class_score); + // filter boxes by conf_threshold + if (confidence <= conf_threshold) { + continue; + } + int32_t label_id = std::distance(data + s + 5, max_class_score); + // convert from [x, y, w, h] to [x1, y1, x2, y2] + result->boxes.emplace_back(std::array{ + data[s] - data[s + 2] / 2.0f + label_id * max_wh, + data[s + 1] - data[s + 3] / 2.0f + label_id * max_wh, + data[s + 0] + data[s + 2] / 2.0f + label_id * max_wh, + data[s + 1] + data[s + 3] / 2.0f + label_id * max_wh}); + result->label_ids.push_back(label_id); + result->scores.push_back(confidence); + } + utils::NMS(result, nms_iou_threshold); + + // scale the boxes to the origin image shape + auto iter_out = im_info.find("output_shape"); + auto iter_ipt = im_info.find("input_shape"); + FDASSERT(iter_out != im_info.end() && iter_ipt != im_info.end(), + "Cannot find input_shape or output_shape from im_info."); + float out_h = iter_out->second[0]; + float out_w = iter_out->second[1]; + float ipt_h = iter_ipt->second[0]; + float ipt_w = iter_ipt->second[1]; + float scale = std::min(out_h / ipt_h, out_w / ipt_w); + for (size_t i = 0; i < result->boxes.size(); ++i) { + float pad_h = (out_h - ipt_h * scale) / 2; + float pad_w = (out_w - ipt_w * scale) / 2; + int32_t label_id = (result->label_ids)[i]; + // clip box + result->boxes[i][0] = result->boxes[i][0] - max_wh * label_id; + result->boxes[i][1] = result->boxes[i][1] - max_wh * label_id; + result->boxes[i][2] = result->boxes[i][2] - max_wh * label_id; + result->boxes[i][3] = result->boxes[i][3] - max_wh * label_id; + result->boxes[i][0] = std::max((result->boxes[i][0] - pad_w) / scale, 0.0f); + result->boxes[i][1] = std::max((result->boxes[i][1] - pad_h) / scale, 0.0f); + result->boxes[i][2] = std::max((result->boxes[i][2] - pad_w) / scale, 0.0f); + result->boxes[i][3] = std::max((result->boxes[i][3] - pad_h) / scale, 0.0f); + result->boxes[i][0] = std::min(result->boxes[i][0], ipt_w); + result->boxes[i][1] = std::min(result->boxes[i][1], ipt_h); + result->boxes[i][2] = std::min(result->boxes[i][2], ipt_w); + result->boxes[i][3] = std::min(result->boxes[i][3], ipt_h); + } + return true; +} + +bool YOLOR::Predict(cv::Mat* im, DetectionResult* result, float conf_threshold, + float nms_iou_threshold) { +#ifdef FASTDEPLOY_DEBUG + TIMERECORD_START(0) +#endif + + Mat mat(*im); + std::vector input_tensors(1); + + std::map> im_info; + + // Record the shape of image and the shape of preprocessed image + im_info["input_shape"] = {static_cast(mat.Height()), + static_cast(mat.Width())}; + im_info["output_shape"] = {static_cast(mat.Height()), + static_cast(mat.Width())}; + + if (!Preprocess(&mat, &input_tensors[0], &im_info)) { + FDERROR << "Failed to preprocess input image." << std::endl; + return false; + } + +#ifdef FASTDEPLOY_DEBUG + TIMERECORD_END(0, "Preprocess") + TIMERECORD_START(1) +#endif + + input_tensors[0].name = InputInfoOfRuntime(0).name; + std::vector output_tensors; + if (!Infer(input_tensors, &output_tensors)) { + FDERROR << "Failed to inference." << std::endl; + return false; + } +#ifdef FASTDEPLOY_DEBUG + TIMERECORD_END(1, "Inference") + TIMERECORD_START(2) +#endif + + if (!Postprocess(output_tensors[0], result, im_info, conf_threshold, + nms_iou_threshold)) { + FDERROR << "Failed to post process." << std::endl; + return false; + } + +#ifdef FASTDEPLOY_DEBUG + TIMERECORD_END(2, "Postprocess") +#endif + return true; +} + +} // namespace wongkinyiu +} // namespace vision +} // namespace fastdeploy diff --git a/fastdeploy/vision/wongkinyiu/yolor.h b/fastdeploy/vision/wongkinyiu/yolor.h new file mode 100644 index 00000000000..69f5ea87606 --- /dev/null +++ b/fastdeploy/vision/wongkinyiu/yolor.h @@ -0,0 +1,95 @@ +// 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. + +#pragma once +#include "fastdeploy/fastdeploy_model.h" +#include "fastdeploy/vision/common/processors/transform.h" +#include "fastdeploy/vision/common/result.h" + +namespace fastdeploy { +namespace vision { +namespace wongkinyiu { + +class FASTDEPLOY_DECL YOLOR : public FastDeployModel { + public: + // 当model_format为ONNX时,无需指定params_file + // 当model_format为Paddle时,则需同时指定model_file & params_file + YOLOR(const std::string& model_file, const std::string& params_file = "", + const RuntimeOption& custom_option = RuntimeOption(), + const Frontend& model_format = Frontend::ONNX); + + // 定义模型的名称 + virtual std::string ModelName() const { return "WongKinYiu/yolor"; } + + // 模型预测接口,即用户调用的接口 + // im 为用户的输入数据,目前对于CV均定义为cv::Mat + // result 为模型预测的输出结构体 + // conf_threshold 为后处理的参数 + // nms_iou_threshold 为后处理的参数 + virtual bool Predict(cv::Mat* im, DetectionResult* result, + float conf_threshold = 0.25, + float nms_iou_threshold = 0.5); + + // 以下为模型在预测时的一些参数,基本是前后处理所需 + // 用户在创建模型后,可根据模型的要求,以及自己的需求 + // 对参数进行修改 + // tuple of (width, height) + std::vector size; + // padding value, size should be same with Channels + std::vector padding_value; + // only pad to the minimum rectange which height and width is times of stride + bool is_mini_pad; + // while is_mini_pad = false and is_no_pad = true, will resize the image to + // the set size + bool is_no_pad; + // if is_scale_up is false, the input image only can be zoom out, the maximum + // resize scale cannot exceed 1.0 + bool is_scale_up; + // padding stride, for is_mini_pad + int stride; + // for offseting the boxes by classes when using NMS + float max_wh; + + private: + // 初始化函数,包括初始化后端,以及其它模型推理需要涉及的操作 + bool Initialize(); + + // 输入图像预处理操作 + // Mat为FastDeploy定义的数据结构 + // FDTensor为预处理后的Tensor数据,传给后端进行推理 + // im_info为预处理过程保存的数据,在后处理中需要用到 + bool Preprocess(Mat* mat, FDTensor* outputs, + std::map>* im_info); + + // 后端推理结果后处理,输出给用户 + // infer_result 为后端推理后的输出Tensor + // result 为模型预测的结果 + // im_info 为预处理记录的信息,后处理用于还原box + // conf_threshold 后处理时过滤box的置信度阈值 + // nms_iou_threshold 后处理时NMS设定的iou阈值 + bool Postprocess(FDTensor& infer_result, DetectionResult* result, + const std::map>& im_info, + float conf_threshold, float nms_iou_threshold); + + // 对图片进行LetterBox处理 + // mat 为读取到的原图 + // size 为输入模型的图像尺寸 + void LetterBox(Mat* mat, const std::vector& size, + const std::vector& color, bool _auto, + bool scale_fill = false, bool scale_up = true, + int stride = 32); +}; +} // namespace wongkinyiu +} // namespace vision +} // namespace fastdeploy diff --git a/model_zoo/vision/ppyoloe/README.md b/model_zoo/vision/ppyoloe/README.md deleted file mode 100644 index 42d18104ad8..00000000000 --- a/model_zoo/vision/ppyoloe/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# PaddleDetection/PPYOLOE部署示例 - -- 当前支持PaddleDetection版本为[release/2.4](https://github.com/PaddlePaddle/PaddleDetection/tree/release/2.4) - -本文档说明如何进行[PPYOLOE](https://github.com/PaddlePaddle/PaddleDetection/tree/release/2.4/configs/ppyoloe)的快速部署推理。本目录结构如下 -``` -. -├── cpp # C++ 代码目录 -│   ├── CMakeLists.txt # C++ 代码编译CMakeLists文件 -│   ├── README.md # C++ 代码编译部署文档 -│   └── ppyoloe.cc # C++ 示例代码 -├── README.md # PPYOLOE 部署文档 -└── ppyoloe.py # Python示例代码 -``` - -## 安装FastDeploy - -使用如下命令安装FastDeploy,注意到此处安装的是`vision-cpu`,也可根据需求安装`vision-gpu` -``` -# 安装fastdeploy-python工具 -pip install fastdeploy-python -``` - -## Python部署 - -执行如下代码即会自动下载PPYOLOE模型和测试图片 -``` -python ppyoloe.py -``` - -执行完成后会将可视化结果保存在本地`vis_result.jpg`,同时输出检测结果如下 -``` -DetectionResult: [xmin, ymin, xmax, ymax, score, label_id] -162.380249,132.057449, 463.178345, 413.167114, 0.962918, 33 -414.914642,141.148666, 91.275269, 308.688293, 0.951003, 0 -163.449234,129.669067, 35.253891, 135.111786, 0.900734, 0 -267.232239,142.290436, 31.578918, 126.329773, 0.848709, 0 -581.790833,179.027115, 30.893127, 135.484940, 0.837986, 0 -104.407021,72.602615, 22.900627, 75.469055, 0.796468, 0 -348.795380,70.122147, 18.806061, 85.829330, 0.785557, 0 -364.118683,92.457428, 17.437622, 89.212891, 0.774282, 0 -75.180283,192.470490, 41.898407, 55.552414, 0.712569, 56 -328.133759,61.894299, 19.100616, 65.633575, 0.710519, 0 -504.797760,181.732574, 107.740814, 248.115082, 0.708902, 0 -379.063080,64.762360, 15.956146, 68.312546, 0.680725, 0 -25.858747,186.564178, 34.958130, 56.007080, 0.580415, 0 -``` - -## 其它文档 - -- [C++部署](./cpp/README.md) -- [PPYOLOE API文档](./api.md) diff --git a/model_zoo/vision/ppyoloe/cpp/README.md b/model_zoo/vision/ppyoloe/cpp/README.md deleted file mode 100644 index 1027c2eeb24..00000000000 --- a/model_zoo/vision/ppyoloe/cpp/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# 编译PPYOLOE示例 - - -``` -# 下载和解压预测库 -wget https://bj.bcebos.com/paddle2onnx/fastdeploy/fastdeploy-linux-x64-0.0.3.tgz -tar xvf fastdeploy-linux-x64-0.0.3.tgz - -# 编译示例代码 -mkdir build & cd build -cmake .. -make -j - -# 下载模型和图片 -wget https://bj.bcebos.com/paddle2onnx/fastdeploy/models/ppdet/ppyoloe_crn_l_300e_coco.tgz -tar xvf ppyoloe_crn_l_300e_coco.tgz -wget https://raw.githubusercontent.com/PaddlePaddle/PaddleDetection/release/2.4/demo/000000014439_640x640.jpg - -# 执行 -./ppyoloe_demo -``` - -执行完后可视化的结果保存在本地`vis_result.jpg`,同时会将检测框输出在终端,如下所示 -``` -DetectionResult: [xmin, ymin, xmax, ymax, score, label_id] -162.380249,132.057449, 463.178345, 413.167114, 0.962918, 33 -414.914642,141.148666, 91.275269, 308.688293, 0.951003, 0 -163.449234,129.669067, 35.253891, 135.111786, 0.900734, 0 -267.232239,142.290436, 31.578918, 126.329773, 0.848709, 0 -581.790833,179.027115, 30.893127, 135.484940, 0.837986, 0 -104.407021,72.602615, 22.900627, 75.469055, 0.796468, 0 -348.795380,70.122147, 18.806061, 85.829330, 0.785557, 0 -364.118683,92.457428, 17.437622, 89.212891, 0.774282, 0 -75.180283,192.470490, 41.898407, 55.552414, 0.712569, 56 -328.133759,61.894299, 19.100616, 65.633575, 0.710519, 0 -504.797760,181.732574, 107.740814, 248.115082, 0.708902, 0 -379.063080,64.762360, 15.956146, 68.312546, 0.680725, 0 -25.858747,186.564178, 34.958130, 56.007080, 0.580415, 0 -``` diff --git a/model_zoo/vision/ppyoloe/ppyoloe.py b/model_zoo/vision/ppyoloe/ppyoloe.py deleted file mode 100644 index 7d79dfd8cf7..00000000000 --- a/model_zoo/vision/ppyoloe/ppyoloe.py +++ /dev/null @@ -1,24 +0,0 @@ -import fastdeploy as fd -import cv2 - -# 下载模型和测试图片 -model_url = "https://bj.bcebos.com/paddle2onnx/fastdeploy/models/ppdet/ppyoloe_crn_l_300e_coco.tgz" -test_jpg_url = "https://raw.githubusercontent.com/PaddlePaddle/PaddleDetection/release/2.4/demo/000000014439_640x640.jpg" -fd.download_and_decompress(model_url, ".") -fd.download(test_jpg_url, ".", show_progress=True) - -# 加载模型 -model = fd.vision.ppdet.PPYOLOE("ppyoloe_crn_l_300e_coco/model.pdmodel", - "ppyoloe_crn_l_300e_coco/model.pdiparams", - "ppyoloe_crn_l_300e_coco/infer_cfg.yml") - -# 预测图片 -im = cv2.imread("000000014439_640x640.jpg") -result = model.predict(im, conf_threshold=0.5) - -# 可视化结果 -fd.vision.visualize.vis_detection(im, result) -cv2.imwrite("vis_result.jpg", im) - -# 输出预测结果 -print(result) diff --git a/model_zoo/vision/yolor/README.md b/model_zoo/vision/yolor/README.md new file mode 100644 index 00000000000..467023f1690 --- /dev/null +++ b/model_zoo/vision/yolor/README.md @@ -0,0 +1,67 @@ +# 编译YOLOR示例 + +当前支持模型版本为:[YOLOR v0.1](https://github.com/WongKinYiu/yolor/releases/tag/weights) + +本文档说明如何进行[YOLOR](https://github.com/WongKinYiu/yolor)的快速部署推理。本目录结构如下 + +``` +. +├── cpp +│   ├── CMakeLists.txt +│   ├── README.md +│   └── yolor.cc +├── README.md +└── yolor.py +``` + +## 获取ONNX文件 + +- 手动获取 + + 访问[YOLOR](https://github.com/WongKinYiu/yolor)官方github库,按照指引下载安装,下载`yolor.pt` 模型,利用 `models/export.py` 得到`onnx`格式文件。 + + + + ``` + #下载yolor模型文件 + wget https://github.com/WongKinYiu/yolor/releases/download/v0.1/yolor.pt + + # 导出onnx格式文件 + python models/export.py --grid --dynamic --weights PATH/TO/yolo7.pt + + # 移动onnx文件到demo目录 + cp PATH/TO/yolo7.onnx PATH/TO/model_zoo/vision/yolor/ + ``` + +## 安装FastDeploy + +使用如下命令安装FastDeploy,注意到此处安装的是`vision-cpu`,也可根据需求安装`vision-gpu` + +``` +# 安装fastdeploy-python工具 +pip install fastdeploy-python + +# 安装vision-cpu模块 +fastdeploy install vision-cpu +``` +## Python部署 + +执行如下代码即会自动下载测试图片 +``` +python yolor.py +``` + +执行完成后会将可视化结果保存在本地`vis_result.jpg`,同时输出检测结果如下 +``` +DetectionResult: [xmin, ymin, xmax, ymax, score, label_id] +0.000000,185.201431, 315.673126, 410.071594, 0.959289, 17 +433.802826,211.603455, 595.489319, 346.425537, 0.952615, 17 +230.446854,195.618805, 418.365479, 362.712128, 0.884253, 17 +336.545624,208.555618, 457.704315, 323.543152, 0.788450, 17 +0.896423,183.936996, 154.788727, 304.916412, 0.672804, 17 +``` + +## 其它文档 + +- [C++部署](./cpp/README.md) +- [YOLOR API文档](./api.md) diff --git a/model_zoo/vision/ppyoloe/api.md b/model_zoo/vision/yolor/api.md similarity index 56% rename from model_zoo/vision/ppyoloe/api.md rename to model_zoo/vision/yolor/api.md index 1c5cbcaadbd..b1e5be889be 100644 --- a/model_zoo/vision/ppyoloe/api.md +++ b/model_zoo/vision/yolor/api.md @@ -1,24 +1,23 @@ -# PPYOLOE API说明 +# YOLOR API说明 ## Python API -### PPYOLOE类 +### YOLOR类 ``` -fastdeploy.vision.ultralytics.PPYOLOE(model_file, params_file, config_file, runtime_option=None, model_format=fd.Frontend.PADDLE) +fastdeploy.vision.wongkinyiu.YOLOR(model_file, params_file=None, runtime_option=None, model_format=fd.Frontend.ONNX) ``` -PPYOLOE模型加载和初始化,需同时提供model_file和params_file, 当前仅支持model_format为Paddle格式 +YOLOR模型加载和初始化,当model_format为`fd.Frontend.ONNX`时,只需提供model_file,如`yolor.onnx`;当model_format为`fd.Frontend.PADDLE`时,则需同时提供model_file和params_file。 **参数** > * **model_file**(str): 模型文件路径 > * **params_file**(str): 参数文件路径 -> * **config_file**(str): 模型推理配置文件 > * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置 > * **model_format**(Frontend): 模型格式 #### predict函数 > ``` -> PPYOLOE.predict(image_data, conf_threshold=0.25, nms_iou_threshold=0.5) +> YOLOR.predict(image_data, conf_threshold=0.25, nms_iou_threshold=0.5) > ``` > 模型预测结口,输入图像直接输出检测结果。 > @@ -26,35 +25,33 @@ PPYOLOE模型加载和初始化,需同时提供model_file和params_file, 当 > > > * **image_data**(np.ndarray): 输入数据,注意需为HWC,BGR格式 > > * **conf_threshold**(float): 检测框置信度过滤阈值 -> > * **nms_iou_threshold**(float): NMS处理过程中iou阈值(当模型中包含nms处理时,此参数自动无效) +> > * **nms_iou_threshold**(float): NMS处理过程中iou阈值 -示例代码参考[ppyoloe.py](./ppyoloe.py) +示例代码参考[yolor.py](./yolor.py) ## C++ API -### PPYOLOE类 +### YOLOR类 ``` -fastdeploy::vision::ultralytics::PPYOLOE( +fastdeploy::vision::wongkinyiu::YOLOR( const string& model_file, - const string& params_file, - const string& config_file, + const string& params_file = "", const RuntimeOption& runtime_option = RuntimeOption(), const Frontend& model_format = Frontend::ONNX) ``` -PPYOLOE模型加载和初始化,需同时提供model_file和params_file, 当前仅支持model_format为Paddle格式 +YOLOR模型加载和初始化,当model_format为`Frontend::ONNX`时,只需提供model_file,如`yolor.onnx`;当model_format为`Frontend::PADDLE`时,则需同时提供model_file和params_file。 **参数** > * **model_file**(str): 模型文件路径 > * **params_file**(str): 参数文件路径 -> * **config_file**(str): 模型推理配置文件 > * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置 > * **model_format**(Frontend): 模型格式 #### Predict函数 > ``` -> YOLOv5::Predict(cv::Mat* im, DetectionResult* result, +> YOLOR::Predict(cv::Mat* im, DetectionResult* result, > float conf_threshold = 0.25, > float nms_iou_threshold = 0.5) > ``` @@ -65,9 +62,9 @@ PPYOLOE模型加载和初始化,需同时提供model_file和params_file, 当 > > * **im**: 输入图像,注意需为HWC,BGR格式 > > * **result**: 检测结果,包括检测框,各个框的置信度 > > * **conf_threshold**: 检测框置信度过滤阈值 -> > * **nms_iou_threshold**: NMS处理过程中iou阈值(当模型中包含nms处理时,此参数自动无效) +> > * **nms_iou_threshold**: NMS处理过程中iou阈值 -示例代码参考[cpp/yolov5.cc](cpp/yolov5.cc) +示例代码参考[cpp/yolor.cc](cpp/yolor.cc) ## 其它API使用 diff --git a/model_zoo/vision/ppyoloe/cpp/CMakeLists.txt b/model_zoo/vision/yolor/cpp/CMakeLists.txt similarity index 75% rename from model_zoo/vision/ppyoloe/cpp/CMakeLists.txt rename to model_zoo/vision/yolor/cpp/CMakeLists.txt index e6815665171..18248b84522 100644 --- a/model_zoo/vision/ppyoloe/cpp/CMakeLists.txt +++ b/model_zoo/vision/yolor/cpp/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT(ppyoloe_demo C CXX) +PROJECT(yolor_demo C CXX) CMAKE_MINIMUM_REQUIRED (VERSION 3.16) # 在低版本ABI环境中,通过如下代码进行兼容性编译 @@ -12,6 +12,6 @@ include(${FASTDEPLOY_INSTALL_DIR}/FastDeploy.cmake) # 添加FastDeploy依赖头文件 include_directories(${FASTDEPLOY_INCS}) -add_executable(ppyoloe_demo ${PROJECT_SOURCE_DIR}/ppyoloe.cc) +add_executable(yolor_demo ${PROJECT_SOURCE_DIR}/yolor.cc) # 添加FastDeploy库依赖 -target_link_libraries(ppyoloe_demo ${FASTDEPLOY_LIBS}) +target_link_libraries(yolor_demo ${FASTDEPLOY_LIBS}) diff --git a/model_zoo/vision/yolor/cpp/README.md b/model_zoo/vision/yolor/cpp/README.md new file mode 100644 index 00000000000..eddf5bc51b3 --- /dev/null +++ b/model_zoo/vision/yolor/cpp/README.md @@ -0,0 +1,51 @@ +# 编译YOLOR示例 + +当前支持模型版本为:[YOLOR v0.1](https://github.com/WongKinYiu/yolor/releases/tag/weights) + +## 获取ONNX文件 + +- 手动获取 + + 访问[YOLOR](https://github.com/WongKinYiu/yolor/releases/tag/weights)官方github库,按照指引下载安装,下载`yolor.pt` 模型,利用 `models/export.py` 得到`onnx`格式文件。 + + ``` + #下载yolor模型文件 + wget https://github.com/WongKinYiu/yolor/releases/download/v0.1/yolor.pt + + # 导出onnx格式文件 + python models/export.py --grid --dynamic --weights PATH/TO/yolo7.pt + + ``` + + +## 运行demo + +``` +# 下载和解压预测库 +wget https://bj.bcebos.com/paddle2onnx/fastdeploy/fastdeploy-linux-x64-0.0.3.tgz +tar xvf fastdeploy-linux-x64-0.0.3.tgz + +# 编译示例代码 +mkdir build & cd build +cmake .. +make -j + +# 移动onnx文件到demo目录 +cp PATH/TO/yolo7.onnx PATH/TO/model_zoo/vision/yolor/cpp/build/ + +# 下载图片 +wget https://raw.githubusercontent.com/WongKinYiu/yolor/paper/inference/images/horses.jpg + +# 执行 +./yolor_demo +``` + +执行完后可视化的结果保存在本地`vis_result.jpg`,同时会将检测框输出在终端,如下所示 +``` +DetectionResult: [xmin, ymin, xmax, ymax, score, label_id] +0.000000,185.201431, 315.673126, 410.071594, 0.959289, 17 +433.802826,211.603455, 595.489319, 346.425537, 0.952615, 17 +230.446854,195.618805, 418.365479, 362.712128, 0.884253, 17 +336.545624,208.555618, 457.704315, 323.543152, 0.788450, 17 +0.896423,183.936996, 154.788727, 304.916412, 0.672804, 17 +``` diff --git a/model_zoo/vision/ppyoloe/cpp/ppyoloe.cc b/model_zoo/vision/yolor/cpp/yolor.cc similarity index 66% rename from model_zoo/vision/ppyoloe/cpp/ppyoloe.cc rename to model_zoo/vision/yolor/cpp/yolor.cc index e63f29e62a5..db194583fce 100644 --- a/model_zoo/vision/ppyoloe/cpp/ppyoloe.cc +++ b/model_zoo/vision/yolor/cpp/yolor.cc @@ -16,28 +16,18 @@ int main() { namespace vis = fastdeploy::vision; - - std::string model_file = "ppyoloe_crn_l_300e_coco/model.pdmodel"; - std::string params_file = "ppyoloe_crn_l_300e_coco/model.pdiparams"; - std::string config_file = "ppyoloe_crn_l_300e_coco/infer_cfg.yml"; - std::string img_path = "000000014439_640x640.jpg"; - std::string vis_path = "vis.jpeg"; - - auto model = vis::ppdet::PPYOLOE(model_file, params_file, config_file); + auto model = vis::wongkinyiu::YOLOR("yolor.onnx"); if (!model.Initialized()) { std::cerr << "Init Failed." << std::endl; return -1; } - - cv::Mat im = cv::imread(img_path); + cv::Mat im = cv::imread("horses.jpg"); cv::Mat vis_im = im.clone(); vis::DetectionResult res; if (!model.Predict(&im, &res)) { std::cerr << "Prediction Failed." << std::endl; return -1; - } else { - std::cout << "Prediction Done!" << std::endl; } // 输出预测框结果 @@ -45,7 +35,6 @@ int main() { // 可视化预测结果 vis::Visualize::VisDetection(&vis_im, res); - cv::imwrite(vis_path, vis_im); - std::cout << "Detect Done! Saved: " << vis_path << std::endl; + cv::imwrite("vis_result.jpg", vis_im); return 0; } diff --git a/model_zoo/vision/yolor/yolor.py b/model_zoo/vision/yolor/yolor.py new file mode 100644 index 00000000000..56d3f9689e7 --- /dev/null +++ b/model_zoo/vision/yolor/yolor.py @@ -0,0 +1,21 @@ +import fastdeploy as fd +import cv2 + +# 下载模型和测试图片 +test_jpg_url = "https://raw.githubusercontent.com/WongKinYiu/yolor/paper/inference/images/horses.jpg" +fd.download(test_jpg_url, ".", show_progress=True) + +# 加载模型 +model = fd.vision.wongkinyiu.YOLOR("yolor.onnx") + +# 预测图片 +im = cv2.imread("horses.jpg") +result = model.predict(im, conf_threshold=0.25, nms_iou_threshold=0.5) + +# 可视化结果 +fd.vision.visualize.vis_detection(im, result) +cv2.imwrite("vis_result.jpg", im) + +# 输出预测结果 +print(result) +print(model.runtime_option) diff --git a/setup.py b/setup.py index e76f057b1c0..5147025b4ec 100644 --- a/setup.py +++ b/setup.py @@ -326,25 +326,14 @@ def run(self): shutil.copy("LICENSE", "fastdeploy") depend_libs = list() - if platform.system().lower() == "linux": - for f in os.listdir(".setuptools-cmake-build"): - full_name = os.path.join(".setuptools-cmake-build", f) - if not os.path.isfile(full_name): - continue - if not full_name.count("fastdeploy_main.cpython-"): - continue - if not full_name.endswith(".so"): - continue - # modify the search path of libraries - command = "patchelf --set-rpath '$ORIGIN/libs/' {}".format( - full_name) - # The sw_64 not suppot patchelf, so we just disable that. - if platform.machine() != 'sw_64' and platform.machine( - ) != 'mips64': - assert os.system( - command - ) == 0, "patch fastdeploy_main.cpython-36m-x86_64-linux-gnu.so failed, the command: {}".format( - command) + # modify the search path of libraries + command = "patchelf --set-rpath '$ORIGIN/libs/' .setuptools-cmake-build/fastdeploy_main.cpython-37m-x86_64-linux-gnu.so" + # The sw_64 not suppot patchelf, so we just disable that. + if platform.machine() != 'sw_64' and platform.machine() != 'mips64': + assert os.system( + command + ) == 0, "patch fastdeploy_main.cpython-37m-x86_64-linux-gnu.so failed, the command: {}".format( + command) for f in os.listdir(".setuptools-cmake-build"): if not os.path.isfile(os.path.join(".setuptools-cmake-build", f)): From 3aa015fd722877e7c449a25a9ad0eedbc6fc099a Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Wed, 20 Jul 2022 07:58:07 +0000 Subject: [PATCH 36/69] for merge --- examples/CMakeLists.txt | 25 +-- examples/vision/ppdet_ppyoloe.cc | 51 ++++++ fastdeploy/__init__.py | 2 +- fastdeploy/download.py | 2 +- fastdeploy/utils/utils.h | 4 + fastdeploy/vision.h | 1 + fastdeploy/vision/__init__.py | 1 + .../vision/common/processors/convert.cc | 62 +++++++ fastdeploy/vision/common/processors/convert.h | 42 +++++ .../vision/common/processors/transform.h | 1 + fastdeploy/vision/meituan/yolov6.cc | 8 +- fastdeploy/vision/ppcls/model.cc | 13 ++ fastdeploy/vision/ppcls/model.h | 14 ++ fastdeploy/vision/ppcls/ppcls_pybind.cc | 2 +- fastdeploy/vision/ppdet/__init__.py | 39 ++++ fastdeploy/vision/ppdet/ppdet_pybind.cc | 32 ++++ fastdeploy/vision/ppdet/ppyoloe.cc | 170 ++++++++++++++++++ fastdeploy/vision/ppdet/ppyoloe.h | 44 +++++ fastdeploy/vision/ultralytics/yolov5.cc | 13 +- fastdeploy/vision/utils/sort_det_res.cc | 6 +- fastdeploy/vision/vision_pybind.cc | 6 +- fastdeploy/vision/visualize/detection.cc | 4 +- model_zoo/vision/ppyoloe/README.md | 52 ++++++ model_zoo/vision/ppyoloe/api.md | 74 ++++++++ model_zoo/vision/ppyoloe/cpp/CMakeLists.txt | 17 ++ model_zoo/vision/ppyoloe/cpp/README.md | 39 ++++ model_zoo/vision/ppyoloe/cpp/ppyoloe.cc | 51 ++++++ model_zoo/vision/ppyoloe/ppyoloe.py | 24 +++ setup.py | 27 ++- 29 files changed, 794 insertions(+), 32 deletions(-) create mode 100644 examples/vision/ppdet_ppyoloe.cc create mode 100644 fastdeploy/vision/common/processors/convert.cc create mode 100644 fastdeploy/vision/common/processors/convert.h create mode 100644 fastdeploy/vision/ppdet/__init__.py create mode 100644 fastdeploy/vision/ppdet/ppdet_pybind.cc create mode 100644 fastdeploy/vision/ppdet/ppyoloe.cc create mode 100644 fastdeploy/vision/ppdet/ppyoloe.h create mode 100644 model_zoo/vision/ppyoloe/README.md create mode 100644 model_zoo/vision/ppyoloe/api.md create mode 100644 model_zoo/vision/ppyoloe/cpp/CMakeLists.txt create mode 100644 model_zoo/vision/ppyoloe/cpp/README.md create mode 100644 model_zoo/vision/ppyoloe/cpp/ppyoloe.cc create mode 100644 model_zoo/vision/ppyoloe/ppyoloe.py diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 67361223c6b..112193c86a2 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,25 +1,26 @@ -function(add_fastdeploy_executable field url model) +function(add_fastdeploy_executable FIELD CC_FILE) # temp target name/file var in function scope - set(TEMP_TARGET_FILE ${PROJECT_SOURCE_DIR}/examples/${field}/${url}_${model}.cc) - set(TEMP_TARGET_NAME ${field}_${url}_${model}) + set(TEMP_TARGET_FILE ${CC_FILE}) + string(REGEX MATCHALL "[0-9A-Za-z_]*.cc" FILE_NAME ${CC_FILE}) + string(REGEX REPLACE ".cc" "" FILE_PREFIX ${FILE_NAME}) + set(TEMP_TARGET_NAME ${FIELD}_${FILE_PREFIX}) if (EXISTS ${TEMP_TARGET_FILE} AND TARGET fastdeploy) add_executable(${TEMP_TARGET_NAME} ${TEMP_TARGET_FILE}) target_link_libraries(${TEMP_TARGET_NAME} PUBLIC fastdeploy) - message(STATUS "Found source file: [${field}/${url}_${model}.cc], ADD!!! fastdeploy executable: [${TEMP_TARGET_NAME}] !") - else () - message(WARNING "Can not found source file: [${field}/${url}_${model}.cc], SKIP!!! fastdeploy executable: [${TEMP_TARGET_NAME}] !") + message(STATUS " Added FastDeploy Executable : ${TEMP_TARGET_NAME}") endif() unset(TEMP_TARGET_FILE) unset(TEMP_TARGET_NAME) endfunction() # vision examples -if (WITH_VISION_EXAMPLES) - add_fastdeploy_executable(vision ultralytics yolov5) - add_fastdeploy_executable(vision meituan yolov6) - add_fastdeploy_executable(vision wongkinyiu yolov7) - add_fastdeploy_executable(vision megvii yolox) - add_fastdeploy_executable(vision wongkinyiu yolor) +if(WITH_VISION_EXAMPLES AND EXISTS ${PROJECT_SOURCE_DIR}/examples/vision) + message(STATUS "") + message(STATUS "*************FastDeploy Examples Summary**********") + file(GLOB ALL_VISION_EXAMPLE_SRCS ${PROJECT_SOURCE_DIR}/examples/vision/*.cc) + foreach(_CC_FILE ${ALL_VISION_EXAMPLE_SRCS}) + add_fastdeploy_executable(vision ${_CC_FILE}) + endforeach() endif() # other examples ... diff --git a/examples/vision/ppdet_ppyoloe.cc b/examples/vision/ppdet_ppyoloe.cc new file mode 100644 index 00000000000..b234021c92e --- /dev/null +++ b/examples/vision/ppdet_ppyoloe.cc @@ -0,0 +1,51 @@ +// 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/vision.h" + +int main() { + namespace vis = fastdeploy::vision; + + std::string model_file = "ppyoloe_crn_l_300e_coco/model.pdmodel"; + std::string params_file = "ppyoloe_crn_l_300e_coco/model.pdiparams"; + std::string config_file = "ppyoloe_crn_l_300e_coco/infer_cfg.yml"; + std::string img_path = "test.jpeg"; + std::string vis_path = "vis.jpeg"; + + auto model = vis::ppdet::PPYOLOE(model_file, params_file, config_file); + if (!model.Initialized()) { + std::cerr << "Init Failed." << std::endl; + return -1; + } + + cv::Mat im = cv::imread(img_path); + cv::Mat vis_im = im.clone(); + + vis::DetectionResult res; + if (!model.Predict(&im, &res)) { + std::cerr << "Prediction Failed." << std::endl; + return -1; + } else { + std::cout << "Prediction Done!" << std::endl; + } + + // 输出预测框结果 + std::cout << res.Str() << std::endl; + + // 可视化预测结果 + vis::Visualize::VisDetection(&vis_im, res); + cv::imwrite(vis_path, vis_im); + std::cout << "Detect Done! Saved: " << vis_path << std::endl; + return 0; +} diff --git a/fastdeploy/__init__.py b/fastdeploy/__init__.py index 500e7cc42ae..68006c1bed5 100644 --- a/fastdeploy/__init__.py +++ b/fastdeploy/__init__.py @@ -17,7 +17,7 @@ from .fastdeploy_runtime import * from . import fastdeploy_main as C from . import vision -from .download import download +from .download import download, download_and_decompress def TensorInfoStr(tensor_info): diff --git a/fastdeploy/download.py b/fastdeploy/download.py index e00af098dfd..67f21d8e76d 100644 --- a/fastdeploy/download.py +++ b/fastdeploy/download.py @@ -156,7 +156,7 @@ def decompress(fname): def url2dir(url, path, rename=None): full_name = download(url, path, rename, show_progress=True) - print("SDK is donwloaded, now extracting...") + print("File is donwloaded, now extracting...") if url.count(".tgz") > 0 or url.count(".tar") > 0 or url.count("zip") > 0: return decompress(full_name) diff --git a/fastdeploy/utils/utils.h b/fastdeploy/utils/utils.h index 23ca6ee51aa..e605ee5a750 100644 --- a/fastdeploy/utils/utils.h +++ b/fastdeploy/utils/utils.h @@ -65,6 +65,10 @@ class FASTDEPLOY_DECL FDLogger { bool verbose_ = true; }; +#ifndef __REL_FILE__ +#define __REL_FILE__ __FILE__ +#endif + #define FDERROR \ FDLogger(true, "[ERROR]") << __REL_FILE__ << "(" << __LINE__ \ << ")::" << __FUNCTION__ << "\t" diff --git a/fastdeploy/vision.h b/fastdeploy/vision.h index 43984632511..68c0881cac7 100644 --- a/fastdeploy/vision.h +++ b/fastdeploy/vision.h @@ -18,6 +18,7 @@ #include "fastdeploy/vision/megvii/yolox.h" #include "fastdeploy/vision/meituan/yolov6.h" #include "fastdeploy/vision/ppcls/model.h" +#include "fastdeploy/vision/ppdet/ppyoloe.h" #include "fastdeploy/vision/ultralytics/yolov5.h" #include "fastdeploy/vision/wongkinyiu/yolor.h" #include "fastdeploy/vision/wongkinyiu/yolov7.h" diff --git a/fastdeploy/vision/__init__.py b/fastdeploy/vision/__init__.py index 7122bede0be..6acbf0c3763 100644 --- a/fastdeploy/vision/__init__.py +++ b/fastdeploy/vision/__init__.py @@ -15,6 +15,7 @@ from . import evaluation from . import ppcls +from . import ppdet from . import ultralytics from . import meituan from . import megvii diff --git a/fastdeploy/vision/common/processors/convert.cc b/fastdeploy/vision/common/processors/convert.cc new file mode 100644 index 00000000000..a7ca6de07a9 --- /dev/null +++ b/fastdeploy/vision/common/processors/convert.cc @@ -0,0 +1,62 @@ +// 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/vision/common/processors/convert.h" + +namespace fastdeploy { + +namespace vision { + +Convert::Convert(const std::vector& alpha, + const std::vector& beta) { + FDASSERT(alpha.size() == beta.size(), + "Convert: requires the size of alpha equal to the size of beta."); + FDASSERT(alpha.size() != 0, + "Convert: requires the size of alpha and beta > 0."); + alpha_.assign(alpha.begin(), alpha.end()); + beta_.assign(beta.begin(), beta.end()); +} + +bool Convert::CpuRun(Mat* mat) { + cv::Mat* im = mat->GetCpuMat(); + std::vector split_im; + cv::split(*im, split_im); + for (int c = 0; c < im->channels(); c++) { + split_im[c].convertTo(split_im[c], CV_32FC1, alpha_[c], beta_[c]); + } + cv::merge(split_im, *im); + return true; +} + +#ifdef ENABLE_OPENCV_CUDA +bool Convert::GpuRun(Mat* mat) { + cv::cuda::GpuMat* im = mat->GetGpuMat(); + std::vector split_im; + cv::cuda::split(*im, split_im); + for (int c = 0; c < im->channels(); c++) { + split_im[c].convertTo(split_im[c], CV_32FC1, alpha_[c], beta_[c]); + } + cv::cuda::merge(split_im, *im); + return true; +} +#endif + +bool Convert::Run(Mat* mat, const std::vector& alpha, + const std::vector& beta, ProcLib lib) { + auto c = Convert(alpha, beta); + return c(mat, lib); +} + +} // namespace vision +} // namespace fastdeploy \ No newline at end of file diff --git a/fastdeploy/vision/common/processors/convert.h b/fastdeploy/vision/common/processors/convert.h new file mode 100644 index 00000000000..5d5a5276f5d --- /dev/null +++ b/fastdeploy/vision/common/processors/convert.h @@ -0,0 +1,42 @@ +// 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. + +#pragma once + +#include "fastdeploy/vision/common/processors/base.h" + +namespace fastdeploy { +namespace vision { +class Convert : public Processor { + public: + Convert(const std::vector& alpha, const std::vector& beta); + + bool CpuRun(Mat* mat); +#ifdef ENABLE_OPENCV_CUDA + bool GpuRun(Mat* mat); +#endif + std::string Name() { return "Convert"; } + + // Compute `result = mat * alpha + beta` directly by channel. + // The default behavior is the same as OpenCV's convertTo method. + static bool Run(Mat* mat, const std::vector& alpha, + const std::vector& beta, + ProcLib lib = ProcLib::OPENCV_CPU); + + private: + std::vector alpha_; + std::vector beta_; +}; +} // namespace vision +} // namespace fastdeploy diff --git a/fastdeploy/vision/common/processors/transform.h b/fastdeploy/vision/common/processors/transform.h index 12eec8d72df..08073b4e423 100644 --- a/fastdeploy/vision/common/processors/transform.h +++ b/fastdeploy/vision/common/processors/transform.h @@ -17,6 +17,7 @@ #include "fastdeploy/vision/common/processors/cast.h" #include "fastdeploy/vision/common/processors/center_crop.h" #include "fastdeploy/vision/common/processors/color_space_convert.h" +#include "fastdeploy/vision/common/processors/convert.h" #include "fastdeploy/vision/common/processors/hwc2chw.h" #include "fastdeploy/vision/common/processors/normalize.h" #include "fastdeploy/vision/common/processors/pad.h" diff --git a/fastdeploy/vision/meituan/yolov6.cc b/fastdeploy/vision/meituan/yolov6.cc index b75f2016ee7..8ac73771940 100644 --- a/fastdeploy/vision/meituan/yolov6.cc +++ b/fastdeploy/vision/meituan/yolov6.cc @@ -129,8 +129,12 @@ bool YOLOv6::Preprocess(Mat* mat, FDTensor* output, LetterBox(mat, size, padding_value, is_mini_pad, is_no_pad, is_scale_up, stride); BGR2RGB::Run(mat); - Normalize::Run(mat, std::vector(mat->Channels(), 0.0), - std::vector(mat->Channels(), 1.0)); + // Normalize::Run(mat, std::vector(mat->Channels(), 0.0), + // std::vector(mat->Channels(), 1.0)); + // Compute `result = mat * alpha + beta` directly by channel + std::vector alpha = {1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f}; + std::vector beta = {0.0f, 0.0f, 0.0f}; + Convert::Run(mat, alpha, beta); // Record output shape of preprocessed image (*im_info)["output_shape"] = {static_cast(mat->Height()), diff --git a/fastdeploy/vision/ppcls/model.cc b/fastdeploy/vision/ppcls/model.cc index 915cb975129..a89a1e4731b 100644 --- a/fastdeploy/vision/ppcls/model.cc +++ b/fastdeploy/vision/ppcls/model.cc @@ -1,3 +1,16 @@ +// 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/vision/ppcls/model.h" #include "fastdeploy/vision/utils/utils.h" diff --git a/fastdeploy/vision/ppcls/model.h b/fastdeploy/vision/ppcls/model.h index fae99d4f3c8..71800a7d768 100644 --- a/fastdeploy/vision/ppcls/model.h +++ b/fastdeploy/vision/ppcls/model.h @@ -1,3 +1,17 @@ +// 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. + #pragma once #include "fastdeploy/fastdeploy_model.h" #include "fastdeploy/vision/common/processors/transform.h" diff --git a/fastdeploy/vision/ppcls/ppcls_pybind.cc b/fastdeploy/vision/ppcls/ppcls_pybind.cc index 828bef3c7aa..10ff5ee109b 100644 --- a/fastdeploy/vision/ppcls/ppcls_pybind.cc +++ b/fastdeploy/vision/ppcls/ppcls_pybind.cc @@ -14,7 +14,7 @@ #include "fastdeploy/pybind/main.h" namespace fastdeploy { -void BindPpClsModel(pybind11::module& m) { +void BindPPCls(pybind11::module& m) { auto ppcls_module = m.def_submodule("ppcls", "Module to deploy PaddleClas."); pybind11::class_(ppcls_module, "Model") .def(pybind11::init(ppdet_module, + "PPYOLOE") + .def(pybind11::init()) + .def("predict", [](vision::ppdet::PPYOLOE& self, pybind11::array& data, + float conf_threshold, float nms_iou_threshold) { + auto mat = PyArrayToCvMat(data); + vision::DetectionResult res; + self.Predict(&mat, &res, conf_threshold, nms_iou_threshold); + return res; + }); +} +} // namespace fastdeploy diff --git a/fastdeploy/vision/ppdet/ppyoloe.cc b/fastdeploy/vision/ppdet/ppyoloe.cc new file mode 100644 index 00000000000..c215ecb0cab --- /dev/null +++ b/fastdeploy/vision/ppdet/ppyoloe.cc @@ -0,0 +1,170 @@ +#include "fastdeploy/vision/ppdet/ppyoloe.h" +#include "fastdeploy/vision/utils/utils.h" +#include "yaml-cpp/yaml.h" + +namespace fastdeploy { +namespace vision { +namespace ppdet { + +PPYOLOE::PPYOLOE(const std::string& model_file, const std::string& params_file, + const std::string& config_file, + const RuntimeOption& custom_option, + const Frontend& model_format) { + config_file_ = config_file; + valid_cpu_backends = {Backend::ORT, Backend::PDINFER}; + valid_gpu_backends = {Backend::ORT, Backend::PDINFER}; + runtime_option = custom_option; + runtime_option.model_format = model_format; + runtime_option.model_file = model_file; + runtime_option.params_file = params_file; + initialized = Initialize(); +} + +bool PPYOLOE::Initialize() { + if (!BuildPreprocessPipelineFromConfig()) { + std::cout << "Failed to build preprocess pipeline from configuration file." + << std::endl; + return false; + } + if (!InitRuntime()) { + std::cout << "Failed to initialize fastdeploy backend." << std::endl; + return false; + } + return true; +} + +bool PPYOLOE::BuildPreprocessPipelineFromConfig() { + processors_.clear(); + YAML::Node cfg; + try { + cfg = YAML::LoadFile(config_file_); + } catch (YAML::BadFile& e) { + std::cout << "Failed to load yaml file " << config_file_ + << ", maybe you should check this file." << std::endl; + return false; + } + + if (cfg["arch"].as() != "YOLO") { + std::cout << "Require the arch of model is YOLO, but arch defined in " + "config file is " + << cfg["arch"].as() << "." << std::endl; + return false; + } + processors_.push_back(std::make_shared()); + + for (const auto& op : cfg["Preprocess"]) { + std::string op_name = op["type"].as(); + if (op_name == "NormalizeImage") { + auto mean = op["mean"].as>(); + auto std = op["std"].as>(); + bool is_scale = op["is_scale"].as(); + processors_.push_back(std::make_shared(mean, std, is_scale)); + } else if (op_name == "Resize") { + bool keep_ratio = op["keep_ratio"].as(); + auto target_size = op["target_size"].as>(); + int interp = op["interp"].as(); + FDASSERT(target_size.size(), + "Require size of target_size be 2, but now it's " + + std::to_string(target_size.size()) + "."); + FDASSERT(!keep_ratio, + "Only support keep_ratio is false while deploy " + "PaddleDetection model."); + int width = target_size[1]; + int height = target_size[0]; + processors_.push_back( + std::make_shared(width, height, -1.0, -1.0, interp, false)); + } else if (op_name == "Permute") { + processors_.push_back(std::make_shared()); + } else { + std::cout << "Unexcepted preprocess operator: " << op_name << "." + << std::endl; + return false; + } + } + return true; +} + +bool PPYOLOE::Preprocess(Mat* mat, std::vector* outputs) { + int origin_w = mat->Width(); + int origin_h = mat->Height(); + for (size_t i = 0; i < processors_.size(); ++i) { + if (!(*(processors_[i].get()))(mat)) { + std::cout << "Failed to process image data in " << processors_[i]->Name() + << "." << std::endl; + return false; + } + } + + outputs->resize(2); + (*outputs)[0].name = InputInfoOfRuntime(0).name; + mat->ShareWithTensor(&((*outputs)[0])); + + // reshape to [1, c, h, w] + (*outputs)[0].shape.insert((*outputs)[0].shape.begin(), 1); + + (*outputs)[1].Allocate({1, 2}, FDDataType::FP32, InputInfoOfRuntime(1).name); + float* ptr = static_cast((*outputs)[1].MutableData()); + ptr[0] = mat->Height() * 1.0 / mat->Height(); + ptr[1] = mat->Width() * 1.0 / mat->Width(); + return true; +} + +bool PPYOLOE::Postprocess(std::vector& infer_result, + DetectionResult* result, float conf_threshold, + float nms_threshold) { + FDASSERT(infer_result[1].shape[0] == 1, + "Only support batch = 1 in FastDeploy now."); + int box_num = 0; + if (infer_result[1].dtype == FDDataType::INT32) { + box_num = *(static_cast(infer_result[1].Data())); + } else if (infer_result[1].dtype == FDDataType::INT64) { + box_num = *(static_cast(infer_result[1].Data())); + } else { + FDASSERT( + false, + "The output box_num of PPYOLOE model should be type of int32/int64."); + } + result->Reserve(box_num); + float* box_data = static_cast(infer_result[0].Data()); + for (size_t i = 0; i < box_num; ++i) { + if (box_data[i * 6 + 1] < conf_threshold) { + continue; + } + result->label_ids.push_back(box_data[i * 6]); + result->scores.push_back(box_data[i * 6 + 1]); + result->boxes.emplace_back( + std::array{box_data[i * 6 + 2], box_data[i * 6 + 3], + box_data[i * 6 + 4] - box_data[i * 6 + 2], + box_data[i * 6 + 5] - box_data[i * 6 + 3]}); + } + return true; +} + +bool PPYOLOE::Predict(cv::Mat* im, DetectionResult* result, + float conf_threshold, float iou_threshold) { + Mat mat(*im); + std::vector processed_data; + if (!Preprocess(&mat, &processed_data)) { + FDERROR << "Failed to preprocess input data while using model:" + << ModelName() << "." << std::endl; + return false; + } + + std::vector infer_result; + if (!Infer(processed_data, &infer_result)) { + FDERROR << "Failed to inference while using model:" << ModelName() << "." + << std::endl; + return false; + } + + if (!Postprocess(infer_result, result, conf_threshold, iou_threshold)) { + FDERROR << "Failed to postprocess while using model:" << ModelName() << "." + << std::endl; + return false; + } + return true; +} + +} // namespace ppdet +} // namespace vision +} // namespace fastdeploy diff --git a/fastdeploy/vision/ppdet/ppyoloe.h b/fastdeploy/vision/ppdet/ppyoloe.h new file mode 100644 index 00000000000..a3db268ca47 --- /dev/null +++ b/fastdeploy/vision/ppdet/ppyoloe.h @@ -0,0 +1,44 @@ +#pragma once +#include "fastdeploy/fastdeploy_model.h" +#include "fastdeploy/vision/common/processors/transform.h" +#include "fastdeploy/vision/common/result.h" + +#include "fastdeploy/vision/utils/utils.h" + +namespace fastdeploy { +namespace vision { +namespace ppdet { + +class FASTDEPLOY_DECL PPYOLOE : public FastDeployModel { + public: + PPYOLOE(const std::string& model_file, const std::string& params_file, + const std::string& config_file, + const RuntimeOption& custom_option = RuntimeOption(), + const Frontend& model_format = Frontend::PADDLE); + + std::string ModelName() const { return "PaddleDetection/PPYOLOE"; } + + virtual bool Initialize(); + + virtual bool BuildPreprocessPipelineFromConfig(); + + virtual bool Preprocess(Mat* mat, std::vector* outputs); + + virtual bool Postprocess(std::vector& infer_result, + DetectionResult* result, float conf_threshold, + float nms_threshold); + + virtual bool Predict(cv::Mat* im, DetectionResult* result, + float conf_threshold = 0.5, float nms_threshold = 0.7); + + private: + std::vector> processors_; + std::string config_file_; + // PaddleDetection can export model without nms + // This flag will help us to handle the different + // situation + bool has_nms_; +}; +} // namespace ppdet +} // namespace vision +} // namespace fastdeploy diff --git a/fastdeploy/vision/ultralytics/yolov5.cc b/fastdeploy/vision/ultralytics/yolov5.cc index c8c6e06a94c..b2e6009b1cb 100644 --- a/fastdeploy/vision/ultralytics/yolov5.cc +++ b/fastdeploy/vision/ultralytics/yolov5.cc @@ -126,8 +126,12 @@ bool YOLOv5::Preprocess(Mat* mat, FDTensor* output, LetterBox(mat, size, padding_value, is_mini_pad, is_no_pad, is_scale_up, stride); BGR2RGB::Run(mat); - Normalize::Run(mat, std::vector(mat->Channels(), 0.0), - std::vector(mat->Channels(), 1.0)); + // Normalize::Run(mat, std::vector(mat->Channels(), 0.0), + // std::vector(mat->Channels(), 1.0)); + // Compute `result = mat * alpha + beta` directly by channel + std::vector alpha = {1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f}; + std::vector beta = {0.0f, 0.0f, 0.0f}; + Convert::Run(mat, alpha, beta); // Record output shape of preprocessed image (*im_info)["output_shape"] = {static_cast(mat->Height()), @@ -198,6 +202,11 @@ bool YOLOv5::Postprocess( result->scores.push_back(confidence); } } + + if (result->boxes.size() == 0) { + return true; + } + utils::NMS(result, nms_iou_threshold); // scale the boxes to the origin image shape diff --git a/fastdeploy/vision/utils/sort_det_res.cc b/fastdeploy/vision/utils/sort_det_res.cc index e4a0db97614..790126a6acf 100644 --- a/fastdeploy/vision/utils/sort_det_res.cc +++ b/fastdeploy/vision/utils/sort_det_res.cc @@ -68,7 +68,11 @@ void MergeSort(DetectionResult* result, size_t low, size_t high) { void SortDetectionResult(DetectionResult* result) { size_t low = 0; - size_t high = result->scores.size() - 1; + size_t high = result->scores.size(); + if (high == 0) { + return; + } + high = high - 1; MergeSort(result, low, high); } diff --git a/fastdeploy/vision/vision_pybind.cc b/fastdeploy/vision/vision_pybind.cc index e4ba05b8938..0334303ce6e 100644 --- a/fastdeploy/vision/vision_pybind.cc +++ b/fastdeploy/vision/vision_pybind.cc @@ -16,7 +16,8 @@ namespace fastdeploy { -void BindPpClsModel(pybind11::module& m); +void BindPPCls(pybind11::module& m); +void BindPPDet(pybind11::module& m); void BindWongkinyiu(pybind11::module& m); void BindUltralytics(pybind11::module& m); void BindMeituan(pybind11::module& m); @@ -41,7 +42,8 @@ void BindVision(pybind11::module& m) { .def("__repr__", &vision::DetectionResult::Str) .def("__str__", &vision::DetectionResult::Str); - BindPpClsModel(m); + BindPPCls(m); + BindPPDet(m); BindUltralytics(m); BindWongkinyiu(m); BindMeituan(m); diff --git a/fastdeploy/vision/visualize/detection.cc b/fastdeploy/vision/visualize/detection.cc index e5f01bdd35f..6d60072447a 100644 --- a/fastdeploy/vision/visualize/detection.cc +++ b/fastdeploy/vision/visualize/detection.cc @@ -43,7 +43,7 @@ void Visualize::VisDetection(cv::Mat* im, const DetectionResult& result, } std::string text = id + "," + score; int font = cv::FONT_HERSHEY_SIMPLEX; - cv::Size text_size = cv::getTextSize(text, font, font_size, 0.5, nullptr); + cv::Size text_size = cv::getTextSize(text, font, font_size, 1, nullptr); cv::Point origin; origin.x = rect.x; origin.y = rect.y; @@ -52,7 +52,7 @@ void Visualize::VisDetection(cv::Mat* im, const DetectionResult& result, text_size.width, text_size.height); cv::rectangle(*im, rect, rect_color, line_size); cv::putText(*im, text, origin, font, font_size, cv::Scalar(255, 255, 255), - 0.5); + 1); } } diff --git a/model_zoo/vision/ppyoloe/README.md b/model_zoo/vision/ppyoloe/README.md new file mode 100644 index 00000000000..42d18104ad8 --- /dev/null +++ b/model_zoo/vision/ppyoloe/README.md @@ -0,0 +1,52 @@ +# PaddleDetection/PPYOLOE部署示例 + +- 当前支持PaddleDetection版本为[release/2.4](https://github.com/PaddlePaddle/PaddleDetection/tree/release/2.4) + +本文档说明如何进行[PPYOLOE](https://github.com/PaddlePaddle/PaddleDetection/tree/release/2.4/configs/ppyoloe)的快速部署推理。本目录结构如下 +``` +. +├── cpp # C++ 代码目录 +│   ├── CMakeLists.txt # C++ 代码编译CMakeLists文件 +│   ├── README.md # C++ 代码编译部署文档 +│   └── ppyoloe.cc # C++ 示例代码 +├── README.md # PPYOLOE 部署文档 +└── ppyoloe.py # Python示例代码 +``` + +## 安装FastDeploy + +使用如下命令安装FastDeploy,注意到此处安装的是`vision-cpu`,也可根据需求安装`vision-gpu` +``` +# 安装fastdeploy-python工具 +pip install fastdeploy-python +``` + +## Python部署 + +执行如下代码即会自动下载PPYOLOE模型和测试图片 +``` +python ppyoloe.py +``` + +执行完成后会将可视化结果保存在本地`vis_result.jpg`,同时输出检测结果如下 +``` +DetectionResult: [xmin, ymin, xmax, ymax, score, label_id] +162.380249,132.057449, 463.178345, 413.167114, 0.962918, 33 +414.914642,141.148666, 91.275269, 308.688293, 0.951003, 0 +163.449234,129.669067, 35.253891, 135.111786, 0.900734, 0 +267.232239,142.290436, 31.578918, 126.329773, 0.848709, 0 +581.790833,179.027115, 30.893127, 135.484940, 0.837986, 0 +104.407021,72.602615, 22.900627, 75.469055, 0.796468, 0 +348.795380,70.122147, 18.806061, 85.829330, 0.785557, 0 +364.118683,92.457428, 17.437622, 89.212891, 0.774282, 0 +75.180283,192.470490, 41.898407, 55.552414, 0.712569, 56 +328.133759,61.894299, 19.100616, 65.633575, 0.710519, 0 +504.797760,181.732574, 107.740814, 248.115082, 0.708902, 0 +379.063080,64.762360, 15.956146, 68.312546, 0.680725, 0 +25.858747,186.564178, 34.958130, 56.007080, 0.580415, 0 +``` + +## 其它文档 + +- [C++部署](./cpp/README.md) +- [PPYOLOE API文档](./api.md) diff --git a/model_zoo/vision/ppyoloe/api.md b/model_zoo/vision/ppyoloe/api.md new file mode 100644 index 00000000000..1c5cbcaadbd --- /dev/null +++ b/model_zoo/vision/ppyoloe/api.md @@ -0,0 +1,74 @@ +# PPYOLOE API说明 + +## Python API + +### PPYOLOE类 +``` +fastdeploy.vision.ultralytics.PPYOLOE(model_file, params_file, config_file, runtime_option=None, model_format=fd.Frontend.PADDLE) +``` +PPYOLOE模型加载和初始化,需同时提供model_file和params_file, 当前仅支持model_format为Paddle格式 + +**参数** + +> * **model_file**(str): 模型文件路径 +> * **params_file**(str): 参数文件路径 +> * **config_file**(str): 模型推理配置文件 +> * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置 +> * **model_format**(Frontend): 模型格式 + +#### predict函数 +> ``` +> PPYOLOE.predict(image_data, conf_threshold=0.25, nms_iou_threshold=0.5) +> ``` +> 模型预测结口,输入图像直接输出检测结果。 +> +> **参数** +> +> > * **image_data**(np.ndarray): 输入数据,注意需为HWC,BGR格式 +> > * **conf_threshold**(float): 检测框置信度过滤阈值 +> > * **nms_iou_threshold**(float): NMS处理过程中iou阈值(当模型中包含nms处理时,此参数自动无效) + +示例代码参考[ppyoloe.py](./ppyoloe.py) + + +## C++ API + +### PPYOLOE类 +``` +fastdeploy::vision::ultralytics::PPYOLOE( + const string& model_file, + const string& params_file, + const string& config_file, + const RuntimeOption& runtime_option = RuntimeOption(), + const Frontend& model_format = Frontend::ONNX) +``` +PPYOLOE模型加载和初始化,需同时提供model_file和params_file, 当前仅支持model_format为Paddle格式 + +**参数** + +> * **model_file**(str): 模型文件路径 +> * **params_file**(str): 参数文件路径 +> * **config_file**(str): 模型推理配置文件 +> * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置 +> * **model_format**(Frontend): 模型格式 + +#### Predict函数 +> ``` +> YOLOv5::Predict(cv::Mat* im, DetectionResult* result, +> float conf_threshold = 0.25, +> float nms_iou_threshold = 0.5) +> ``` +> 模型预测接口,输入图像直接输出检测结果。 +> +> **参数** +> +> > * **im**: 输入图像,注意需为HWC,BGR格式 +> > * **result**: 检测结果,包括检测框,各个框的置信度 +> > * **conf_threshold**: 检测框置信度过滤阈值 +> > * **nms_iou_threshold**: NMS处理过程中iou阈值(当模型中包含nms处理时,此参数自动无效) + +示例代码参考[cpp/yolov5.cc](cpp/yolov5.cc) + +## 其它API使用 + +- [模型部署RuntimeOption配置](../../../docs/api/runtime_option.md) diff --git a/model_zoo/vision/ppyoloe/cpp/CMakeLists.txt b/model_zoo/vision/ppyoloe/cpp/CMakeLists.txt new file mode 100644 index 00000000000..e6815665171 --- /dev/null +++ b/model_zoo/vision/ppyoloe/cpp/CMakeLists.txt @@ -0,0 +1,17 @@ +PROJECT(ppyoloe_demo C CXX) +CMAKE_MINIMUM_REQUIRED (VERSION 3.16) + +# 在低版本ABI环境中,通过如下代码进行兼容性编译 +# add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) + +# 指定下载解压后的fastdeploy库路径 +set(FASTDEPLOY_INSTALL_DIR ${PROJECT_SOURCE_DIR}/fastdeploy-linux-x64-0.3.0/) + +include(${FASTDEPLOY_INSTALL_DIR}/FastDeploy.cmake) + +# 添加FastDeploy依赖头文件 +include_directories(${FASTDEPLOY_INCS}) + +add_executable(ppyoloe_demo ${PROJECT_SOURCE_DIR}/ppyoloe.cc) +# 添加FastDeploy库依赖 +target_link_libraries(ppyoloe_demo ${FASTDEPLOY_LIBS}) diff --git a/model_zoo/vision/ppyoloe/cpp/README.md b/model_zoo/vision/ppyoloe/cpp/README.md new file mode 100644 index 00000000000..1027c2eeb24 --- /dev/null +++ b/model_zoo/vision/ppyoloe/cpp/README.md @@ -0,0 +1,39 @@ +# 编译PPYOLOE示例 + + +``` +# 下载和解压预测库 +wget https://bj.bcebos.com/paddle2onnx/fastdeploy/fastdeploy-linux-x64-0.0.3.tgz +tar xvf fastdeploy-linux-x64-0.0.3.tgz + +# 编译示例代码 +mkdir build & cd build +cmake .. +make -j + +# 下载模型和图片 +wget https://bj.bcebos.com/paddle2onnx/fastdeploy/models/ppdet/ppyoloe_crn_l_300e_coco.tgz +tar xvf ppyoloe_crn_l_300e_coco.tgz +wget https://raw.githubusercontent.com/PaddlePaddle/PaddleDetection/release/2.4/demo/000000014439_640x640.jpg + +# 执行 +./ppyoloe_demo +``` + +执行完后可视化的结果保存在本地`vis_result.jpg`,同时会将检测框输出在终端,如下所示 +``` +DetectionResult: [xmin, ymin, xmax, ymax, score, label_id] +162.380249,132.057449, 463.178345, 413.167114, 0.962918, 33 +414.914642,141.148666, 91.275269, 308.688293, 0.951003, 0 +163.449234,129.669067, 35.253891, 135.111786, 0.900734, 0 +267.232239,142.290436, 31.578918, 126.329773, 0.848709, 0 +581.790833,179.027115, 30.893127, 135.484940, 0.837986, 0 +104.407021,72.602615, 22.900627, 75.469055, 0.796468, 0 +348.795380,70.122147, 18.806061, 85.829330, 0.785557, 0 +364.118683,92.457428, 17.437622, 89.212891, 0.774282, 0 +75.180283,192.470490, 41.898407, 55.552414, 0.712569, 56 +328.133759,61.894299, 19.100616, 65.633575, 0.710519, 0 +504.797760,181.732574, 107.740814, 248.115082, 0.708902, 0 +379.063080,64.762360, 15.956146, 68.312546, 0.680725, 0 +25.858747,186.564178, 34.958130, 56.007080, 0.580415, 0 +``` diff --git a/model_zoo/vision/ppyoloe/cpp/ppyoloe.cc b/model_zoo/vision/ppyoloe/cpp/ppyoloe.cc new file mode 100644 index 00000000000..e63f29e62a5 --- /dev/null +++ b/model_zoo/vision/ppyoloe/cpp/ppyoloe.cc @@ -0,0 +1,51 @@ +// 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/vision.h" + +int main() { + namespace vis = fastdeploy::vision; + + std::string model_file = "ppyoloe_crn_l_300e_coco/model.pdmodel"; + std::string params_file = "ppyoloe_crn_l_300e_coco/model.pdiparams"; + std::string config_file = "ppyoloe_crn_l_300e_coco/infer_cfg.yml"; + std::string img_path = "000000014439_640x640.jpg"; + std::string vis_path = "vis.jpeg"; + + auto model = vis::ppdet::PPYOLOE(model_file, params_file, config_file); + if (!model.Initialized()) { + std::cerr << "Init Failed." << std::endl; + return -1; + } + + cv::Mat im = cv::imread(img_path); + cv::Mat vis_im = im.clone(); + + vis::DetectionResult res; + if (!model.Predict(&im, &res)) { + std::cerr << "Prediction Failed." << std::endl; + return -1; + } else { + std::cout << "Prediction Done!" << std::endl; + } + + // 输出预测框结果 + std::cout << res.Str() << std::endl; + + // 可视化预测结果 + vis::Visualize::VisDetection(&vis_im, res); + cv::imwrite(vis_path, vis_im); + std::cout << "Detect Done! Saved: " << vis_path << std::endl; + return 0; +} diff --git a/model_zoo/vision/ppyoloe/ppyoloe.py b/model_zoo/vision/ppyoloe/ppyoloe.py new file mode 100644 index 00000000000..7d79dfd8cf7 --- /dev/null +++ b/model_zoo/vision/ppyoloe/ppyoloe.py @@ -0,0 +1,24 @@ +import fastdeploy as fd +import cv2 + +# 下载模型和测试图片 +model_url = "https://bj.bcebos.com/paddle2onnx/fastdeploy/models/ppdet/ppyoloe_crn_l_300e_coco.tgz" +test_jpg_url = "https://raw.githubusercontent.com/PaddlePaddle/PaddleDetection/release/2.4/demo/000000014439_640x640.jpg" +fd.download_and_decompress(model_url, ".") +fd.download(test_jpg_url, ".", show_progress=True) + +# 加载模型 +model = fd.vision.ppdet.PPYOLOE("ppyoloe_crn_l_300e_coco/model.pdmodel", + "ppyoloe_crn_l_300e_coco/model.pdiparams", + "ppyoloe_crn_l_300e_coco/infer_cfg.yml") + +# 预测图片 +im = cv2.imread("000000014439_640x640.jpg") +result = model.predict(im, conf_threshold=0.5) + +# 可视化结果 +fd.vision.visualize.vis_detection(im, result) +cv2.imwrite("vis_result.jpg", im) + +# 输出预测结果 +print(result) diff --git a/setup.py b/setup.py index 5147025b4ec..e76f057b1c0 100644 --- a/setup.py +++ b/setup.py @@ -326,14 +326,25 @@ def run(self): shutil.copy("LICENSE", "fastdeploy") depend_libs = list() - # modify the search path of libraries - command = "patchelf --set-rpath '$ORIGIN/libs/' .setuptools-cmake-build/fastdeploy_main.cpython-37m-x86_64-linux-gnu.so" - # The sw_64 not suppot patchelf, so we just disable that. - if platform.machine() != 'sw_64' and platform.machine() != 'mips64': - assert os.system( - command - ) == 0, "patch fastdeploy_main.cpython-37m-x86_64-linux-gnu.so failed, the command: {}".format( - command) + if platform.system().lower() == "linux": + for f in os.listdir(".setuptools-cmake-build"): + full_name = os.path.join(".setuptools-cmake-build", f) + if not os.path.isfile(full_name): + continue + if not full_name.count("fastdeploy_main.cpython-"): + continue + if not full_name.endswith(".so"): + continue + # modify the search path of libraries + command = "patchelf --set-rpath '$ORIGIN/libs/' {}".format( + full_name) + # The sw_64 not suppot patchelf, so we just disable that. + if platform.machine() != 'sw_64' and platform.machine( + ) != 'mips64': + assert os.system( + command + ) == 0, "patch fastdeploy_main.cpython-36m-x86_64-linux-gnu.so failed, the command: {}".format( + command) for f in os.listdir(".setuptools-cmake-build"): if not os.path.isfile(os.path.join(".setuptools-cmake-build", f)): From d6b98aa507ac785796541dfe18822204879376bf Mon Sep 17 00:00:00 2001 From: ziqi-jin <67993288+ziqi-jin@users.noreply.github.com> Date: Wed, 20 Jul 2022 15:59:53 +0800 Subject: [PATCH 37/69] Develop (#11) * Fix compile problem in different python version (#26) * fix some usage problem in linux * Fix compile problem Co-authored-by: root * Add PaddleDetetion/PPYOLOE model support (#22) * add ppdet/ppyoloe * Add demo code and documents * add convert processor to vision (#27) * update .gitignore * Added checking for cmake include dir * fixed missing trt_backend option bug when init from trt * remove un-need data layout and add pre-check for dtype * changed RGB2BRG to BGR2RGB in ppcls model * add model_zoo yolov6 c++/python demo * fixed CMakeLists.txt typos * update yolov6 cpp/README.md * add yolox c++/pybind and model_zoo demo * move some helpers to private * fixed CMakeLists.txt typos * add normalize with alpha and beta * add version notes for yolov5/yolov6/yolox * add copyright to yolov5.cc * revert normalize * fixed some bugs in yolox * fixed examples/CMakeLists.txt to avoid conflicts * add convert processor to vision * format examples/CMakeLists summary * Fix bug while the inference result is empty with YOLOv5 (#29) * Add multi-label function for yolov5 * Update README.md Update doc * Update fastdeploy_runtime.cc fix variable option.trt_max_shape wrong name * Update runtime_option.md Update resnet model dynamic shape setting name from images to x * Fix bug when inference result boxes are empty * Delete detection.py Co-authored-by: Jason Co-authored-by: root Co-authored-by: DefTruth <31974251+DefTruth@users.noreply.github.com> Co-authored-by: huangjianhui <852142024@qq.com> --- examples/CMakeLists.txt | 26 +-- examples/vision/ppdet_ppyoloe.cc | 51 ++++++ fastdeploy/__init__.py | 2 +- fastdeploy/download.py | 2 +- fastdeploy/utils/utils.h | 4 + fastdeploy/vision.h | 1 + fastdeploy/vision/__init__.py | 1 + .../vision/common/processors/convert.cc | 62 +++++++ fastdeploy/vision/common/processors/convert.h | 42 +++++ .../vision/common/processors/transform.h | 1 + fastdeploy/vision/meituan/yolov6.cc | 28 +-- fastdeploy/vision/ppcls/model.cc | 19 +- fastdeploy/vision/ppcls/model.h | 16 +- fastdeploy/vision/ppcls/ppcls_pybind.cc | 2 +- fastdeploy/vision/ppdet/__init__.py | 39 ++++ fastdeploy/vision/ppdet/ppdet_pybind.cc | 32 ++++ fastdeploy/vision/ppdet/ppyoloe.cc | 170 ++++++++++++++++++ fastdeploy/vision/ppdet/ppyoloe.h | 44 +++++ fastdeploy/vision/ultralytics/yolov5.cc | 19 +- fastdeploy/vision/utils/sort_det_res.cc | 6 +- fastdeploy/vision/vision_pybind.cc | 10 +- fastdeploy/vision/visualize/detection.cc | 4 +- model_zoo/vision/ppyoloe/README.md | 52 ++++++ model_zoo/vision/ppyoloe/api.md | 74 ++++++++ model_zoo/vision/ppyoloe/cpp/CMakeLists.txt | 17 ++ model_zoo/vision/ppyoloe/cpp/README.md | 39 ++++ model_zoo/vision/ppyoloe/cpp/ppyoloe.cc | 51 ++++++ model_zoo/vision/ppyoloe/ppyoloe.py | 24 +++ setup.py | 30 +++- 29 files changed, 818 insertions(+), 50 deletions(-) create mode 100644 examples/vision/ppdet_ppyoloe.cc create mode 100644 fastdeploy/vision/common/processors/convert.cc create mode 100644 fastdeploy/vision/common/processors/convert.h create mode 100644 fastdeploy/vision/ppdet/__init__.py create mode 100644 fastdeploy/vision/ppdet/ppdet_pybind.cc create mode 100644 fastdeploy/vision/ppdet/ppyoloe.cc create mode 100644 fastdeploy/vision/ppdet/ppyoloe.h create mode 100644 model_zoo/vision/ppyoloe/README.md create mode 100644 model_zoo/vision/ppyoloe/api.md create mode 100644 model_zoo/vision/ppyoloe/cpp/CMakeLists.txt create mode 100644 model_zoo/vision/ppyoloe/cpp/README.md create mode 100644 model_zoo/vision/ppyoloe/cpp/ppyoloe.cc create mode 100644 model_zoo/vision/ppyoloe/ppyoloe.py diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 1e2dc43bd40..112193c86a2 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,24 +1,26 @@ -function(add_fastdeploy_executable field url model) +function(add_fastdeploy_executable FIELD CC_FILE) # temp target name/file var in function scope - set(TEMP_TARGET_FILE ${PROJECT_SOURCE_DIR}/examples/${field}/${url}_${model}.cc) - set(TEMP_TARGET_NAME ${field}_${url}_${model}) + set(TEMP_TARGET_FILE ${CC_FILE}) + string(REGEX MATCHALL "[0-9A-Za-z_]*.cc" FILE_NAME ${CC_FILE}) + string(REGEX REPLACE ".cc" "" FILE_PREFIX ${FILE_NAME}) + set(TEMP_TARGET_NAME ${FIELD}_${FILE_PREFIX}) if (EXISTS ${TEMP_TARGET_FILE} AND TARGET fastdeploy) add_executable(${TEMP_TARGET_NAME} ${TEMP_TARGET_FILE}) target_link_libraries(${TEMP_TARGET_NAME} PUBLIC fastdeploy) - message(STATUS "Found source file: [${field}/${url}_${model}.cc], ADD!!! fastdeploy executable: [${TEMP_TARGET_NAME}] !") - else () - message(WARNING "Can not found source file: [${field}/${url}_${model}.cc], SKIP!!! fastdeploy executable: [${TEMP_TARGET_NAME}] !") + message(STATUS " Added FastDeploy Executable : ${TEMP_TARGET_NAME}") endif() unset(TEMP_TARGET_FILE) unset(TEMP_TARGET_NAME) endfunction() # vision examples -if (WITH_VISION_EXAMPLES) - add_fastdeploy_executable(vision ultralytics yolov5) - add_fastdeploy_executable(vision meituan yolov6) - add_fastdeploy_executable(vision wongkinyiu yolov7) - add_fastdeploy_executable(vision megvii yolox) +if(WITH_VISION_EXAMPLES AND EXISTS ${PROJECT_SOURCE_DIR}/examples/vision) + message(STATUS "") + message(STATUS "*************FastDeploy Examples Summary**********") + file(GLOB ALL_VISION_EXAMPLE_SRCS ${PROJECT_SOURCE_DIR}/examples/vision/*.cc) + foreach(_CC_FILE ${ALL_VISION_EXAMPLE_SRCS}) + add_fastdeploy_executable(vision ${_CC_FILE}) + endforeach() endif() -# other examples ... \ No newline at end of file +# other examples ... diff --git a/examples/vision/ppdet_ppyoloe.cc b/examples/vision/ppdet_ppyoloe.cc new file mode 100644 index 00000000000..b234021c92e --- /dev/null +++ b/examples/vision/ppdet_ppyoloe.cc @@ -0,0 +1,51 @@ +// 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/vision.h" + +int main() { + namespace vis = fastdeploy::vision; + + std::string model_file = "ppyoloe_crn_l_300e_coco/model.pdmodel"; + std::string params_file = "ppyoloe_crn_l_300e_coco/model.pdiparams"; + std::string config_file = "ppyoloe_crn_l_300e_coco/infer_cfg.yml"; + std::string img_path = "test.jpeg"; + std::string vis_path = "vis.jpeg"; + + auto model = vis::ppdet::PPYOLOE(model_file, params_file, config_file); + if (!model.Initialized()) { + std::cerr << "Init Failed." << std::endl; + return -1; + } + + cv::Mat im = cv::imread(img_path); + cv::Mat vis_im = im.clone(); + + vis::DetectionResult res; + if (!model.Predict(&im, &res)) { + std::cerr << "Prediction Failed." << std::endl; + return -1; + } else { + std::cout << "Prediction Done!" << std::endl; + } + + // 输出预测框结果 + std::cout << res.Str() << std::endl; + + // 可视化预测结果 + vis::Visualize::VisDetection(&vis_im, res); + cv::imwrite(vis_path, vis_im); + std::cout << "Detect Done! Saved: " << vis_path << std::endl; + return 0; +} diff --git a/fastdeploy/__init__.py b/fastdeploy/__init__.py index 500e7cc42ae..68006c1bed5 100644 --- a/fastdeploy/__init__.py +++ b/fastdeploy/__init__.py @@ -17,7 +17,7 @@ from .fastdeploy_runtime import * from . import fastdeploy_main as C from . import vision -from .download import download +from .download import download, download_and_decompress def TensorInfoStr(tensor_info): diff --git a/fastdeploy/download.py b/fastdeploy/download.py index e00af098dfd..67f21d8e76d 100644 --- a/fastdeploy/download.py +++ b/fastdeploy/download.py @@ -156,7 +156,7 @@ def decompress(fname): def url2dir(url, path, rename=None): full_name = download(url, path, rename, show_progress=True) - print("SDK is donwloaded, now extracting...") + print("File is donwloaded, now extracting...") if url.count(".tgz") > 0 or url.count(".tar") > 0 or url.count("zip") > 0: return decompress(full_name) diff --git a/fastdeploy/utils/utils.h b/fastdeploy/utils/utils.h index 1b9f625b5e5..93120842659 100644 --- a/fastdeploy/utils/utils.h +++ b/fastdeploy/utils/utils.h @@ -64,6 +64,10 @@ class FASTDEPLOY_DECL FDLogger { bool verbose_ = true; }; +#ifndef __REL_FILE__ +#define __REL_FILE__ __FILE__ +#endif + #define FDERROR \ FDLogger(true, "[ERROR]") \ << __REL_FILE__ << "(" << __LINE__ << ")::" << __FUNCTION__ << "\t" diff --git a/fastdeploy/vision.h b/fastdeploy/vision.h index ac3f006c0ad..cafe310c706 100644 --- a/fastdeploy/vision.h +++ b/fastdeploy/vision.h @@ -16,6 +16,7 @@ #include "fastdeploy/core/config.h" #ifdef ENABLE_VISION #include "fastdeploy/vision/ppcls/model.h" +#include "fastdeploy/vision/ppdet/ppyoloe.h" #include "fastdeploy/vision/ultralytics/yolov5.h" #include "fastdeploy/vision/wongkinyiu/yolov7.h" #include "fastdeploy/vision/meituan/yolov6.h" diff --git a/fastdeploy/vision/__init__.py b/fastdeploy/vision/__init__.py index 7122bede0be..6acbf0c3763 100644 --- a/fastdeploy/vision/__init__.py +++ b/fastdeploy/vision/__init__.py @@ -15,6 +15,7 @@ from . import evaluation from . import ppcls +from . import ppdet from . import ultralytics from . import meituan from . import megvii diff --git a/fastdeploy/vision/common/processors/convert.cc b/fastdeploy/vision/common/processors/convert.cc new file mode 100644 index 00000000000..a7ca6de07a9 --- /dev/null +++ b/fastdeploy/vision/common/processors/convert.cc @@ -0,0 +1,62 @@ +// 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/vision/common/processors/convert.h" + +namespace fastdeploy { + +namespace vision { + +Convert::Convert(const std::vector& alpha, + const std::vector& beta) { + FDASSERT(alpha.size() == beta.size(), + "Convert: requires the size of alpha equal to the size of beta."); + FDASSERT(alpha.size() != 0, + "Convert: requires the size of alpha and beta > 0."); + alpha_.assign(alpha.begin(), alpha.end()); + beta_.assign(beta.begin(), beta.end()); +} + +bool Convert::CpuRun(Mat* mat) { + cv::Mat* im = mat->GetCpuMat(); + std::vector split_im; + cv::split(*im, split_im); + for (int c = 0; c < im->channels(); c++) { + split_im[c].convertTo(split_im[c], CV_32FC1, alpha_[c], beta_[c]); + } + cv::merge(split_im, *im); + return true; +} + +#ifdef ENABLE_OPENCV_CUDA +bool Convert::GpuRun(Mat* mat) { + cv::cuda::GpuMat* im = mat->GetGpuMat(); + std::vector split_im; + cv::cuda::split(*im, split_im); + for (int c = 0; c < im->channels(); c++) { + split_im[c].convertTo(split_im[c], CV_32FC1, alpha_[c], beta_[c]); + } + cv::cuda::merge(split_im, *im); + return true; +} +#endif + +bool Convert::Run(Mat* mat, const std::vector& alpha, + const std::vector& beta, ProcLib lib) { + auto c = Convert(alpha, beta); + return c(mat, lib); +} + +} // namespace vision +} // namespace fastdeploy \ No newline at end of file diff --git a/fastdeploy/vision/common/processors/convert.h b/fastdeploy/vision/common/processors/convert.h new file mode 100644 index 00000000000..5d5a5276f5d --- /dev/null +++ b/fastdeploy/vision/common/processors/convert.h @@ -0,0 +1,42 @@ +// 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. + +#pragma once + +#include "fastdeploy/vision/common/processors/base.h" + +namespace fastdeploy { +namespace vision { +class Convert : public Processor { + public: + Convert(const std::vector& alpha, const std::vector& beta); + + bool CpuRun(Mat* mat); +#ifdef ENABLE_OPENCV_CUDA + bool GpuRun(Mat* mat); +#endif + std::string Name() { return "Convert"; } + + // Compute `result = mat * alpha + beta` directly by channel. + // The default behavior is the same as OpenCV's convertTo method. + static bool Run(Mat* mat, const std::vector& alpha, + const std::vector& beta, + ProcLib lib = ProcLib::OPENCV_CPU); + + private: + std::vector alpha_; + std::vector beta_; +}; +} // namespace vision +} // namespace fastdeploy diff --git a/fastdeploy/vision/common/processors/transform.h b/fastdeploy/vision/common/processors/transform.h index 12eec8d72df..08073b4e423 100644 --- a/fastdeploy/vision/common/processors/transform.h +++ b/fastdeploy/vision/common/processors/transform.h @@ -17,6 +17,7 @@ #include "fastdeploy/vision/common/processors/cast.h" #include "fastdeploy/vision/common/processors/center_crop.h" #include "fastdeploy/vision/common/processors/color_space_convert.h" +#include "fastdeploy/vision/common/processors/convert.h" #include "fastdeploy/vision/common/processors/hwc2chw.h" #include "fastdeploy/vision/common/processors/normalize.h" #include "fastdeploy/vision/common/processors/pad.h" diff --git a/fastdeploy/vision/meituan/yolov6.cc b/fastdeploy/vision/meituan/yolov6.cc index 8f37bf89c6f..8ac73771940 100644 --- a/fastdeploy/vision/meituan/yolov6.cc +++ b/fastdeploy/vision/meituan/yolov6.cc @@ -25,14 +25,14 @@ namespace meituan { void LetterBox(Mat* mat, std::vector size, std::vector color, bool _auto, bool scale_fill = false, bool scale_up = true, int stride = 32) { - float scale = std::min(size[1] * 1.0f / static_cast(mat->Height()), - size[0] * 1.0f / static_cast(mat->Width())); + float scale = std::min(size[1] * 1.0f / static_cast(mat->Height()), + size[0] * 1.0f / static_cast(mat->Width())); if (!scale_up) { scale = std::min(scale, 1.0f); } int resize_h = int(round(static_cast(mat->Height()) * scale)); - int resize_w = int(round(static_cast(mat->Width()) * scale)); + int resize_w = int(round(static_cast(mat->Width()) * scale)); int pad_w = size[0] - resize_w; int pad_h = size[1] - resize_h; @@ -85,13 +85,13 @@ bool YOLOv6::Initialize() { is_scale_up = false; stride = 32; max_wh = 4096.0f; - + if (!InitRuntime()) { FDERROR << "Failed to initialize fastdeploy backend." << std::endl; return false; } - // Check if the input shape is dynamic after Runtime already initialized, - // Note that, We need to force is_mini_pad 'false' to keep static + // Check if the input shape is dynamic after Runtime already initialized, + // Note that, We need to force is_mini_pad 'false' to keep static // shape after padding (LetterBox) when the is_dynamic_shape is 'false'. is_dynamic_input_ = false; auto shape = InputInfoOfRuntime(0).shape; @@ -102,7 +102,7 @@ bool YOLOv6::Initialize() { break; } } - if (!is_dynamic_input_) { + if (!is_dynamic_input_) { is_mini_pad = false; } return true; @@ -111,15 +111,15 @@ bool YOLOv6::Initialize() { bool YOLOv6::Preprocess(Mat* mat, FDTensor* output, std::map>* im_info) { // process after image load - float ratio = std::min(size[1] * 1.0f / static_cast(mat->Height()), - size[0] * 1.0f / static_cast(mat->Width())); + float ratio = std::min(size[1] * 1.0f / static_cast(mat->Height()), + size[0] * 1.0f / static_cast(mat->Width())); if (ratio != 1.0) { int interp = cv::INTER_AREA; if (ratio > 1.0) { interp = cv::INTER_LINEAR; } int resize_h = int(round(static_cast(mat->Height()) * ratio)); - int resize_w = int(round(static_cast(mat->Width()) * ratio)); + int resize_w = int(round(static_cast(mat->Width()) * ratio)); Resize::Run(mat, resize_w, resize_h, -1, -1, interp); } // yolov6's preprocess steps @@ -129,8 +129,12 @@ bool YOLOv6::Preprocess(Mat* mat, FDTensor* output, LetterBox(mat, size, padding_value, is_mini_pad, is_no_pad, is_scale_up, stride); BGR2RGB::Run(mat); - Normalize::Run(mat, std::vector(mat->Channels(), 0.0), - std::vector(mat->Channels(), 1.0)); + // Normalize::Run(mat, std::vector(mat->Channels(), 0.0), + // std::vector(mat->Channels(), 1.0)); + // Compute `result = mat * alpha + beta` directly by channel + std::vector alpha = {1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f}; + std::vector beta = {0.0f, 0.0f, 0.0f}; + Convert::Run(mat, alpha, beta); // Record output shape of preprocessed image (*im_info)["output_shape"] = {static_cast(mat->Height()), diff --git a/fastdeploy/vision/ppcls/model.cc b/fastdeploy/vision/ppcls/model.cc index 915cb975129..c4e5b767c71 100644 --- a/fastdeploy/vision/ppcls/model.cc +++ b/fastdeploy/vision/ppcls/model.cc @@ -1,3 +1,16 @@ +// 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/vision/ppcls/model.h" #include "fastdeploy/vision/utils/utils.h" @@ -135,6 +148,6 @@ bool Model::Predict(cv::Mat* im, ClassifyResult* result, int topk) { return true; } -} // namespace ppcls -} // namespace vision -} // namespace fastdeploy +} // namespace ppcls +} // namespace vision +} // namespace fastdeploy diff --git a/fastdeploy/vision/ppcls/model.h b/fastdeploy/vision/ppcls/model.h index 36841d74c68..265f92d32ba 100644 --- a/fastdeploy/vision/ppcls/model.h +++ b/fastdeploy/vision/ppcls/model.h @@ -1,7 +1,21 @@ +// 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. + #pragma once #include "fastdeploy/fastdeploy_model.h" -#include "fastdeploy/vision/common/result.h" #include "fastdeploy/vision/common/processors/transform.h" +#include "fastdeploy/vision/common/result.h" namespace fastdeploy { namespace vision { diff --git a/fastdeploy/vision/ppcls/ppcls_pybind.cc b/fastdeploy/vision/ppcls/ppcls_pybind.cc index ef3fffee8ec..1abc0b2b7c5 100644 --- a/fastdeploy/vision/ppcls/ppcls_pybind.cc +++ b/fastdeploy/vision/ppcls/ppcls_pybind.cc @@ -14,7 +14,7 @@ #include "fastdeploy/pybind/main.h" namespace fastdeploy { -void BindPpClsModel(pybind11::module& m) { +void BindPPCls(pybind11::module& m) { auto ppcls_module = m.def_submodule("ppcls", "Module to deploy PaddleClas."); pybind11::class_(ppcls_module, "Model") .def(pybind11::init(ppdet_module, + "PPYOLOE") + .def(pybind11::init()) + .def("predict", [](vision::ppdet::PPYOLOE& self, pybind11::array& data, + float conf_threshold, float nms_iou_threshold) { + auto mat = PyArrayToCvMat(data); + vision::DetectionResult res; + self.Predict(&mat, &res, conf_threshold, nms_iou_threshold); + return res; + }); +} +} // namespace fastdeploy diff --git a/fastdeploy/vision/ppdet/ppyoloe.cc b/fastdeploy/vision/ppdet/ppyoloe.cc new file mode 100644 index 00000000000..c215ecb0cab --- /dev/null +++ b/fastdeploy/vision/ppdet/ppyoloe.cc @@ -0,0 +1,170 @@ +#include "fastdeploy/vision/ppdet/ppyoloe.h" +#include "fastdeploy/vision/utils/utils.h" +#include "yaml-cpp/yaml.h" + +namespace fastdeploy { +namespace vision { +namespace ppdet { + +PPYOLOE::PPYOLOE(const std::string& model_file, const std::string& params_file, + const std::string& config_file, + const RuntimeOption& custom_option, + const Frontend& model_format) { + config_file_ = config_file; + valid_cpu_backends = {Backend::ORT, Backend::PDINFER}; + valid_gpu_backends = {Backend::ORT, Backend::PDINFER}; + runtime_option = custom_option; + runtime_option.model_format = model_format; + runtime_option.model_file = model_file; + runtime_option.params_file = params_file; + initialized = Initialize(); +} + +bool PPYOLOE::Initialize() { + if (!BuildPreprocessPipelineFromConfig()) { + std::cout << "Failed to build preprocess pipeline from configuration file." + << std::endl; + return false; + } + if (!InitRuntime()) { + std::cout << "Failed to initialize fastdeploy backend." << std::endl; + return false; + } + return true; +} + +bool PPYOLOE::BuildPreprocessPipelineFromConfig() { + processors_.clear(); + YAML::Node cfg; + try { + cfg = YAML::LoadFile(config_file_); + } catch (YAML::BadFile& e) { + std::cout << "Failed to load yaml file " << config_file_ + << ", maybe you should check this file." << std::endl; + return false; + } + + if (cfg["arch"].as() != "YOLO") { + std::cout << "Require the arch of model is YOLO, but arch defined in " + "config file is " + << cfg["arch"].as() << "." << std::endl; + return false; + } + processors_.push_back(std::make_shared()); + + for (const auto& op : cfg["Preprocess"]) { + std::string op_name = op["type"].as(); + if (op_name == "NormalizeImage") { + auto mean = op["mean"].as>(); + auto std = op["std"].as>(); + bool is_scale = op["is_scale"].as(); + processors_.push_back(std::make_shared(mean, std, is_scale)); + } else if (op_name == "Resize") { + bool keep_ratio = op["keep_ratio"].as(); + auto target_size = op["target_size"].as>(); + int interp = op["interp"].as(); + FDASSERT(target_size.size(), + "Require size of target_size be 2, but now it's " + + std::to_string(target_size.size()) + "."); + FDASSERT(!keep_ratio, + "Only support keep_ratio is false while deploy " + "PaddleDetection model."); + int width = target_size[1]; + int height = target_size[0]; + processors_.push_back( + std::make_shared(width, height, -1.0, -1.0, interp, false)); + } else if (op_name == "Permute") { + processors_.push_back(std::make_shared()); + } else { + std::cout << "Unexcepted preprocess operator: " << op_name << "." + << std::endl; + return false; + } + } + return true; +} + +bool PPYOLOE::Preprocess(Mat* mat, std::vector* outputs) { + int origin_w = mat->Width(); + int origin_h = mat->Height(); + for (size_t i = 0; i < processors_.size(); ++i) { + if (!(*(processors_[i].get()))(mat)) { + std::cout << "Failed to process image data in " << processors_[i]->Name() + << "." << std::endl; + return false; + } + } + + outputs->resize(2); + (*outputs)[0].name = InputInfoOfRuntime(0).name; + mat->ShareWithTensor(&((*outputs)[0])); + + // reshape to [1, c, h, w] + (*outputs)[0].shape.insert((*outputs)[0].shape.begin(), 1); + + (*outputs)[1].Allocate({1, 2}, FDDataType::FP32, InputInfoOfRuntime(1).name); + float* ptr = static_cast((*outputs)[1].MutableData()); + ptr[0] = mat->Height() * 1.0 / mat->Height(); + ptr[1] = mat->Width() * 1.0 / mat->Width(); + return true; +} + +bool PPYOLOE::Postprocess(std::vector& infer_result, + DetectionResult* result, float conf_threshold, + float nms_threshold) { + FDASSERT(infer_result[1].shape[0] == 1, + "Only support batch = 1 in FastDeploy now."); + int box_num = 0; + if (infer_result[1].dtype == FDDataType::INT32) { + box_num = *(static_cast(infer_result[1].Data())); + } else if (infer_result[1].dtype == FDDataType::INT64) { + box_num = *(static_cast(infer_result[1].Data())); + } else { + FDASSERT( + false, + "The output box_num of PPYOLOE model should be type of int32/int64."); + } + result->Reserve(box_num); + float* box_data = static_cast(infer_result[0].Data()); + for (size_t i = 0; i < box_num; ++i) { + if (box_data[i * 6 + 1] < conf_threshold) { + continue; + } + result->label_ids.push_back(box_data[i * 6]); + result->scores.push_back(box_data[i * 6 + 1]); + result->boxes.emplace_back( + std::array{box_data[i * 6 + 2], box_data[i * 6 + 3], + box_data[i * 6 + 4] - box_data[i * 6 + 2], + box_data[i * 6 + 5] - box_data[i * 6 + 3]}); + } + return true; +} + +bool PPYOLOE::Predict(cv::Mat* im, DetectionResult* result, + float conf_threshold, float iou_threshold) { + Mat mat(*im); + std::vector processed_data; + if (!Preprocess(&mat, &processed_data)) { + FDERROR << "Failed to preprocess input data while using model:" + << ModelName() << "." << std::endl; + return false; + } + + std::vector infer_result; + if (!Infer(processed_data, &infer_result)) { + FDERROR << "Failed to inference while using model:" << ModelName() << "." + << std::endl; + return false; + } + + if (!Postprocess(infer_result, result, conf_threshold, iou_threshold)) { + FDERROR << "Failed to postprocess while using model:" << ModelName() << "." + << std::endl; + return false; + } + return true; +} + +} // namespace ppdet +} // namespace vision +} // namespace fastdeploy diff --git a/fastdeploy/vision/ppdet/ppyoloe.h b/fastdeploy/vision/ppdet/ppyoloe.h new file mode 100644 index 00000000000..a3db268ca47 --- /dev/null +++ b/fastdeploy/vision/ppdet/ppyoloe.h @@ -0,0 +1,44 @@ +#pragma once +#include "fastdeploy/fastdeploy_model.h" +#include "fastdeploy/vision/common/processors/transform.h" +#include "fastdeploy/vision/common/result.h" + +#include "fastdeploy/vision/utils/utils.h" + +namespace fastdeploy { +namespace vision { +namespace ppdet { + +class FASTDEPLOY_DECL PPYOLOE : public FastDeployModel { + public: + PPYOLOE(const std::string& model_file, const std::string& params_file, + const std::string& config_file, + const RuntimeOption& custom_option = RuntimeOption(), + const Frontend& model_format = Frontend::PADDLE); + + std::string ModelName() const { return "PaddleDetection/PPYOLOE"; } + + virtual bool Initialize(); + + virtual bool BuildPreprocessPipelineFromConfig(); + + virtual bool Preprocess(Mat* mat, std::vector* outputs); + + virtual bool Postprocess(std::vector& infer_result, + DetectionResult* result, float conf_threshold, + float nms_threshold); + + virtual bool Predict(cv::Mat* im, DetectionResult* result, + float conf_threshold = 0.5, float nms_threshold = 0.7); + + private: + std::vector> processors_; + std::string config_file_; + // PaddleDetection can export model without nms + // This flag will help us to handle the different + // situation + bool has_nms_; +}; +} // namespace ppdet +} // namespace vision +} // namespace fastdeploy diff --git a/fastdeploy/vision/ultralytics/yolov5.cc b/fastdeploy/vision/ultralytics/yolov5.cc index 193cfe97948..0b7e50e735b 100644 --- a/fastdeploy/vision/ultralytics/yolov5.cc +++ b/fastdeploy/vision/ultralytics/yolov5.cc @@ -87,8 +87,8 @@ bool YOLOv5::Initialize() { FDERROR << "Failed to initialize fastdeploy backend." << std::endl; return false; } - // Check if the input shape is dynamic after Runtime already initialized, - // Note that, We need to force is_mini_pad 'false' to keep static + // Check if the input shape is dynamic after Runtime already initialized, + // Note that, We need to force is_mini_pad 'false' to keep static // shape after padding (LetterBox) when the is_dynamic_shape is 'false'. is_dynamic_input_ = false; auto shape = InputInfoOfRuntime(0).shape; @@ -99,7 +99,7 @@ bool YOLOv5::Initialize() { break; } } - if (!is_dynamic_input_) { + if (!is_dynamic_input_) { is_mini_pad = false; } return true; @@ -126,8 +126,12 @@ bool YOLOv5::Preprocess(Mat* mat, FDTensor* output, LetterBox(mat, size, padding_value, is_mini_pad, is_no_pad, is_scale_up, stride); BGR2RGB::Run(mat); - Normalize::Run(mat, std::vector(mat->Channels(), 0.0), - std::vector(mat->Channels(), 1.0)); + // Normalize::Run(mat, std::vector(mat->Channels(), 0.0), + // std::vector(mat->Channels(), 1.0)); + // Compute `result = mat * alpha + beta` directly by channel + std::vector alpha = {1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f}; + std::vector beta = {0.0f, 0.0f, 0.0f}; + Convert::Run(mat, alpha, beta); // Record output shape of preprocessed image (*im_info)["output_shape"] = {static_cast(mat->Height()), @@ -198,6 +202,11 @@ bool YOLOv5::Postprocess( result->scores.push_back(confidence); } } + + if (result->boxes.size() == 0) { + return true; + } + utils::NMS(result, nms_iou_threshold); // scale the boxes to the origin image shape diff --git a/fastdeploy/vision/utils/sort_det_res.cc b/fastdeploy/vision/utils/sort_det_res.cc index e4a0db97614..93dbb69694b 100644 --- a/fastdeploy/vision/utils/sort_det_res.cc +++ b/fastdeploy/vision/utils/sort_det_res.cc @@ -68,7 +68,11 @@ void MergeSort(DetectionResult* result, size_t low, size_t high) { void SortDetectionResult(DetectionResult* result) { size_t low = 0; - size_t high = result->scores.size() - 1; + size_t high = result->scores.size(); + if (high == 0) { + return; + } + high = high - 1; MergeSort(result, low, high); } diff --git a/fastdeploy/vision/vision_pybind.cc b/fastdeploy/vision/vision_pybind.cc index 41ada5541a2..0334303ce6e 100644 --- a/fastdeploy/vision/vision_pybind.cc +++ b/fastdeploy/vision/vision_pybind.cc @@ -16,7 +16,8 @@ namespace fastdeploy { -void BindPpClsModel(pybind11::module& m); +void BindPPCls(pybind11::module& m); +void BindPPDet(pybind11::module& m); void BindWongkinyiu(pybind11::module& m); void BindUltralytics(pybind11::module& m); void BindMeituan(pybind11::module& m); @@ -41,13 +42,14 @@ void BindVision(pybind11::module& m) { .def("__repr__", &vision::DetectionResult::Str) .def("__str__", &vision::DetectionResult::Str); - BindPpClsModel(m); + BindPPCls(m); + BindPPDet(m); BindUltralytics(m); BindWongkinyiu(m); BindMeituan(m); BindMegvii(m); #ifdef ENABLE_VISION_VISUALIZE BindVisualize(m); -#endif +#endif } -} // namespace fastdeploy +} // namespace fastdeploy diff --git a/fastdeploy/vision/visualize/detection.cc b/fastdeploy/vision/visualize/detection.cc index d0c41161487..5b5538bff7f 100644 --- a/fastdeploy/vision/visualize/detection.cc +++ b/fastdeploy/vision/visualize/detection.cc @@ -43,7 +43,7 @@ void Visualize::VisDetection(cv::Mat* im, const DetectionResult& result, } std::string text = id + "," + score; int font = cv::FONT_HERSHEY_SIMPLEX; - cv::Size text_size = cv::getTextSize(text, font, font_size, 0.5, nullptr); + cv::Size text_size = cv::getTextSize(text, font, font_size, 1, nullptr); cv::Point origin; origin.x = rect.x; origin.y = rect.y; @@ -52,7 +52,7 @@ void Visualize::VisDetection(cv::Mat* im, const DetectionResult& result, text_size.width, text_size.height); cv::rectangle(*im, rect, rect_color, line_size); cv::putText(*im, text, origin, font, font_size, cv::Scalar(255, 255, 255), - 0.5); + 1); } } diff --git a/model_zoo/vision/ppyoloe/README.md b/model_zoo/vision/ppyoloe/README.md new file mode 100644 index 00000000000..42d18104ad8 --- /dev/null +++ b/model_zoo/vision/ppyoloe/README.md @@ -0,0 +1,52 @@ +# PaddleDetection/PPYOLOE部署示例 + +- 当前支持PaddleDetection版本为[release/2.4](https://github.com/PaddlePaddle/PaddleDetection/tree/release/2.4) + +本文档说明如何进行[PPYOLOE](https://github.com/PaddlePaddle/PaddleDetection/tree/release/2.4/configs/ppyoloe)的快速部署推理。本目录结构如下 +``` +. +├── cpp # C++ 代码目录 +│   ├── CMakeLists.txt # C++ 代码编译CMakeLists文件 +│   ├── README.md # C++ 代码编译部署文档 +│   └── ppyoloe.cc # C++ 示例代码 +├── README.md # PPYOLOE 部署文档 +└── ppyoloe.py # Python示例代码 +``` + +## 安装FastDeploy + +使用如下命令安装FastDeploy,注意到此处安装的是`vision-cpu`,也可根据需求安装`vision-gpu` +``` +# 安装fastdeploy-python工具 +pip install fastdeploy-python +``` + +## Python部署 + +执行如下代码即会自动下载PPYOLOE模型和测试图片 +``` +python ppyoloe.py +``` + +执行完成后会将可视化结果保存在本地`vis_result.jpg`,同时输出检测结果如下 +``` +DetectionResult: [xmin, ymin, xmax, ymax, score, label_id] +162.380249,132.057449, 463.178345, 413.167114, 0.962918, 33 +414.914642,141.148666, 91.275269, 308.688293, 0.951003, 0 +163.449234,129.669067, 35.253891, 135.111786, 0.900734, 0 +267.232239,142.290436, 31.578918, 126.329773, 0.848709, 0 +581.790833,179.027115, 30.893127, 135.484940, 0.837986, 0 +104.407021,72.602615, 22.900627, 75.469055, 0.796468, 0 +348.795380,70.122147, 18.806061, 85.829330, 0.785557, 0 +364.118683,92.457428, 17.437622, 89.212891, 0.774282, 0 +75.180283,192.470490, 41.898407, 55.552414, 0.712569, 56 +328.133759,61.894299, 19.100616, 65.633575, 0.710519, 0 +504.797760,181.732574, 107.740814, 248.115082, 0.708902, 0 +379.063080,64.762360, 15.956146, 68.312546, 0.680725, 0 +25.858747,186.564178, 34.958130, 56.007080, 0.580415, 0 +``` + +## 其它文档 + +- [C++部署](./cpp/README.md) +- [PPYOLOE API文档](./api.md) diff --git a/model_zoo/vision/ppyoloe/api.md b/model_zoo/vision/ppyoloe/api.md new file mode 100644 index 00000000000..1c5cbcaadbd --- /dev/null +++ b/model_zoo/vision/ppyoloe/api.md @@ -0,0 +1,74 @@ +# PPYOLOE API说明 + +## Python API + +### PPYOLOE类 +``` +fastdeploy.vision.ultralytics.PPYOLOE(model_file, params_file, config_file, runtime_option=None, model_format=fd.Frontend.PADDLE) +``` +PPYOLOE模型加载和初始化,需同时提供model_file和params_file, 当前仅支持model_format为Paddle格式 + +**参数** + +> * **model_file**(str): 模型文件路径 +> * **params_file**(str): 参数文件路径 +> * **config_file**(str): 模型推理配置文件 +> * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置 +> * **model_format**(Frontend): 模型格式 + +#### predict函数 +> ``` +> PPYOLOE.predict(image_data, conf_threshold=0.25, nms_iou_threshold=0.5) +> ``` +> 模型预测结口,输入图像直接输出检测结果。 +> +> **参数** +> +> > * **image_data**(np.ndarray): 输入数据,注意需为HWC,BGR格式 +> > * **conf_threshold**(float): 检测框置信度过滤阈值 +> > * **nms_iou_threshold**(float): NMS处理过程中iou阈值(当模型中包含nms处理时,此参数自动无效) + +示例代码参考[ppyoloe.py](./ppyoloe.py) + + +## C++ API + +### PPYOLOE类 +``` +fastdeploy::vision::ultralytics::PPYOLOE( + const string& model_file, + const string& params_file, + const string& config_file, + const RuntimeOption& runtime_option = RuntimeOption(), + const Frontend& model_format = Frontend::ONNX) +``` +PPYOLOE模型加载和初始化,需同时提供model_file和params_file, 当前仅支持model_format为Paddle格式 + +**参数** + +> * **model_file**(str): 模型文件路径 +> * **params_file**(str): 参数文件路径 +> * **config_file**(str): 模型推理配置文件 +> * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置 +> * **model_format**(Frontend): 模型格式 + +#### Predict函数 +> ``` +> YOLOv5::Predict(cv::Mat* im, DetectionResult* result, +> float conf_threshold = 0.25, +> float nms_iou_threshold = 0.5) +> ``` +> 模型预测接口,输入图像直接输出检测结果。 +> +> **参数** +> +> > * **im**: 输入图像,注意需为HWC,BGR格式 +> > * **result**: 检测结果,包括检测框,各个框的置信度 +> > * **conf_threshold**: 检测框置信度过滤阈值 +> > * **nms_iou_threshold**: NMS处理过程中iou阈值(当模型中包含nms处理时,此参数自动无效) + +示例代码参考[cpp/yolov5.cc](cpp/yolov5.cc) + +## 其它API使用 + +- [模型部署RuntimeOption配置](../../../docs/api/runtime_option.md) diff --git a/model_zoo/vision/ppyoloe/cpp/CMakeLists.txt b/model_zoo/vision/ppyoloe/cpp/CMakeLists.txt new file mode 100644 index 00000000000..e6815665171 --- /dev/null +++ b/model_zoo/vision/ppyoloe/cpp/CMakeLists.txt @@ -0,0 +1,17 @@ +PROJECT(ppyoloe_demo C CXX) +CMAKE_MINIMUM_REQUIRED (VERSION 3.16) + +# 在低版本ABI环境中,通过如下代码进行兼容性编译 +# add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) + +# 指定下载解压后的fastdeploy库路径 +set(FASTDEPLOY_INSTALL_DIR ${PROJECT_SOURCE_DIR}/fastdeploy-linux-x64-0.3.0/) + +include(${FASTDEPLOY_INSTALL_DIR}/FastDeploy.cmake) + +# 添加FastDeploy依赖头文件 +include_directories(${FASTDEPLOY_INCS}) + +add_executable(ppyoloe_demo ${PROJECT_SOURCE_DIR}/ppyoloe.cc) +# 添加FastDeploy库依赖 +target_link_libraries(ppyoloe_demo ${FASTDEPLOY_LIBS}) diff --git a/model_zoo/vision/ppyoloe/cpp/README.md b/model_zoo/vision/ppyoloe/cpp/README.md new file mode 100644 index 00000000000..1027c2eeb24 --- /dev/null +++ b/model_zoo/vision/ppyoloe/cpp/README.md @@ -0,0 +1,39 @@ +# 编译PPYOLOE示例 + + +``` +# 下载和解压预测库 +wget https://bj.bcebos.com/paddle2onnx/fastdeploy/fastdeploy-linux-x64-0.0.3.tgz +tar xvf fastdeploy-linux-x64-0.0.3.tgz + +# 编译示例代码 +mkdir build & cd build +cmake .. +make -j + +# 下载模型和图片 +wget https://bj.bcebos.com/paddle2onnx/fastdeploy/models/ppdet/ppyoloe_crn_l_300e_coco.tgz +tar xvf ppyoloe_crn_l_300e_coco.tgz +wget https://raw.githubusercontent.com/PaddlePaddle/PaddleDetection/release/2.4/demo/000000014439_640x640.jpg + +# 执行 +./ppyoloe_demo +``` + +执行完后可视化的结果保存在本地`vis_result.jpg`,同时会将检测框输出在终端,如下所示 +``` +DetectionResult: [xmin, ymin, xmax, ymax, score, label_id] +162.380249,132.057449, 463.178345, 413.167114, 0.962918, 33 +414.914642,141.148666, 91.275269, 308.688293, 0.951003, 0 +163.449234,129.669067, 35.253891, 135.111786, 0.900734, 0 +267.232239,142.290436, 31.578918, 126.329773, 0.848709, 0 +581.790833,179.027115, 30.893127, 135.484940, 0.837986, 0 +104.407021,72.602615, 22.900627, 75.469055, 0.796468, 0 +348.795380,70.122147, 18.806061, 85.829330, 0.785557, 0 +364.118683,92.457428, 17.437622, 89.212891, 0.774282, 0 +75.180283,192.470490, 41.898407, 55.552414, 0.712569, 56 +328.133759,61.894299, 19.100616, 65.633575, 0.710519, 0 +504.797760,181.732574, 107.740814, 248.115082, 0.708902, 0 +379.063080,64.762360, 15.956146, 68.312546, 0.680725, 0 +25.858747,186.564178, 34.958130, 56.007080, 0.580415, 0 +``` diff --git a/model_zoo/vision/ppyoloe/cpp/ppyoloe.cc b/model_zoo/vision/ppyoloe/cpp/ppyoloe.cc new file mode 100644 index 00000000000..e63f29e62a5 --- /dev/null +++ b/model_zoo/vision/ppyoloe/cpp/ppyoloe.cc @@ -0,0 +1,51 @@ +// 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/vision.h" + +int main() { + namespace vis = fastdeploy::vision; + + std::string model_file = "ppyoloe_crn_l_300e_coco/model.pdmodel"; + std::string params_file = "ppyoloe_crn_l_300e_coco/model.pdiparams"; + std::string config_file = "ppyoloe_crn_l_300e_coco/infer_cfg.yml"; + std::string img_path = "000000014439_640x640.jpg"; + std::string vis_path = "vis.jpeg"; + + auto model = vis::ppdet::PPYOLOE(model_file, params_file, config_file); + if (!model.Initialized()) { + std::cerr << "Init Failed." << std::endl; + return -1; + } + + cv::Mat im = cv::imread(img_path); + cv::Mat vis_im = im.clone(); + + vis::DetectionResult res; + if (!model.Predict(&im, &res)) { + std::cerr << "Prediction Failed." << std::endl; + return -1; + } else { + std::cout << "Prediction Done!" << std::endl; + } + + // 输出预测框结果 + std::cout << res.Str() << std::endl; + + // 可视化预测结果 + vis::Visualize::VisDetection(&vis_im, res); + cv::imwrite(vis_path, vis_im); + std::cout << "Detect Done! Saved: " << vis_path << std::endl; + return 0; +} diff --git a/model_zoo/vision/ppyoloe/ppyoloe.py b/model_zoo/vision/ppyoloe/ppyoloe.py new file mode 100644 index 00000000000..7d79dfd8cf7 --- /dev/null +++ b/model_zoo/vision/ppyoloe/ppyoloe.py @@ -0,0 +1,24 @@ +import fastdeploy as fd +import cv2 + +# 下载模型和测试图片 +model_url = "https://bj.bcebos.com/paddle2onnx/fastdeploy/models/ppdet/ppyoloe_crn_l_300e_coco.tgz" +test_jpg_url = "https://raw.githubusercontent.com/PaddlePaddle/PaddleDetection/release/2.4/demo/000000014439_640x640.jpg" +fd.download_and_decompress(model_url, ".") +fd.download(test_jpg_url, ".", show_progress=True) + +# 加载模型 +model = fd.vision.ppdet.PPYOLOE("ppyoloe_crn_l_300e_coco/model.pdmodel", + "ppyoloe_crn_l_300e_coco/model.pdiparams", + "ppyoloe_crn_l_300e_coco/infer_cfg.yml") + +# 预测图片 +im = cv2.imread("000000014439_640x640.jpg") +result = model.predict(im, conf_threshold=0.5) + +# 可视化结果 +fd.vision.visualize.vis_detection(im, result) +cv2.imwrite("vis_result.jpg", im) + +# 输出预测结果 +print(result) diff --git a/setup.py b/setup.py index f0ff3f16dee..e76f057b1c0 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,8 @@ setup_configs["ENABLE_TRT_BACKEND"] = os.getenv("ENABLE_TRT_BACKEND", "OFF") setup_configs["WITH_GPU"] = os.getenv("WITH_GPU", "OFF") setup_configs["TRT_DIRECTORY"] = os.getenv("TRT_DIRECTORY", "UNDEFINED") -setup_configs["CUDA_DIRECTORY"] = os.getenv("CUDA_DIRECTORY", "/usr/local/cuda") +setup_configs["CUDA_DIRECTORY"] = os.getenv("CUDA_DIRECTORY", + "/usr/local/cuda") TOP_DIR = os.path.realpath(os.path.dirname(__file__)) SRC_DIR = os.path.join(TOP_DIR, "fastdeploy") @@ -325,17 +326,32 @@ def run(self): shutil.copy("LICENSE", "fastdeploy") depend_libs = list() - # modify the search path of libraries - command = "patchelf --set-rpath '$ORIGIN/libs/' .setuptools-cmake-build/fastdeploy_main.cpython-36m-x86_64-linux-gnu.so" - # The sw_64 not suppot patchelf, so we just disable that. - if platform.machine() != 'sw_64' and platform.machine() != 'mips64': - assert os.system(command) == 0, "patch fastdeploy_main.cpython-36m-x86_64-linux-gnu.so failed, the command: {}".format(command) + if platform.system().lower() == "linux": + for f in os.listdir(".setuptools-cmake-build"): + full_name = os.path.join(".setuptools-cmake-build", f) + if not os.path.isfile(full_name): + continue + if not full_name.count("fastdeploy_main.cpython-"): + continue + if not full_name.endswith(".so"): + continue + # modify the search path of libraries + command = "patchelf --set-rpath '$ORIGIN/libs/' {}".format( + full_name) + # The sw_64 not suppot patchelf, so we just disable that. + if platform.machine() != 'sw_64' and platform.machine( + ) != 'mips64': + assert os.system( + command + ) == 0, "patch fastdeploy_main.cpython-36m-x86_64-linux-gnu.so failed, the command: {}".format( + command) for f in os.listdir(".setuptools-cmake-build"): if not os.path.isfile(os.path.join(".setuptools-cmake-build", f)): continue if f.count("libfastdeploy") > 0: - shutil.copy(os.path.join(".setuptools-cmake-build", f), "fastdeploy/libs") + shutil.copy( + os.path.join(".setuptools-cmake-build", f), "fastdeploy/libs") for dirname in os.listdir(".setuptools-cmake-build/third_libs/install"): for lib in os.listdir( os.path.join(".setuptools-cmake-build/third_libs/install", From 013921ac21f7a77aa9a7f6ca98bb25990b4d9c19 Mon Sep 17 00:00:00 2001 From: ziqi-jin <67993288+ziqi-jin@users.noreply.github.com> Date: Thu, 21 Jul 2022 10:40:44 +0800 Subject: [PATCH 38/69] Yolor (#16) * Develop (#11) (#12) * Fix compile problem in different python version (#26) * fix some usage problem in linux * Fix compile problem Co-authored-by: root * Add PaddleDetetion/PPYOLOE model support (#22) * add ppdet/ppyoloe * Add demo code and documents * add convert processor to vision (#27) * update .gitignore * Added checking for cmake include dir * fixed missing trt_backend option bug when init from trt * remove un-need data layout and add pre-check for dtype * changed RGB2BRG to BGR2RGB in ppcls model * add model_zoo yolov6 c++/python demo * fixed CMakeLists.txt typos * update yolov6 cpp/README.md * add yolox c++/pybind and model_zoo demo * move some helpers to private * fixed CMakeLists.txt typos * add normalize with alpha and beta * add version notes for yolov5/yolov6/yolox * add copyright to yolov5.cc * revert normalize * fixed some bugs in yolox * fixed examples/CMakeLists.txt to avoid conflicts * add convert processor to vision * format examples/CMakeLists summary * Fix bug while the inference result is empty with YOLOv5 (#29) * Add multi-label function for yolov5 * Update README.md Update doc * Update fastdeploy_runtime.cc fix variable option.trt_max_shape wrong name * Update runtime_option.md Update resnet model dynamic shape setting name from images to x * Fix bug when inference result boxes are empty * Delete detection.py Co-authored-by: Jason Co-authored-by: root Co-authored-by: DefTruth <31974251+DefTruth@users.noreply.github.com> Co-authored-by: huangjianhui <852142024@qq.com> Co-authored-by: Jason Co-authored-by: root Co-authored-by: DefTruth <31974251+DefTruth@users.noreply.github.com> Co-authored-by: huangjianhui <852142024@qq.com> * Develop (#13) * Fix compile problem in different python version (#26) * fix some usage problem in linux * Fix compile problem Co-authored-by: root * Add PaddleDetetion/PPYOLOE model support (#22) * add ppdet/ppyoloe * Add demo code and documents * add convert processor to vision (#27) * update .gitignore * Added checking for cmake include dir * fixed missing trt_backend option bug when init from trt * remove un-need data layout and add pre-check for dtype * changed RGB2BRG to BGR2RGB in ppcls model * add model_zoo yolov6 c++/python demo * fixed CMakeLists.txt typos * update yolov6 cpp/README.md * add yolox c++/pybind and model_zoo demo * move some helpers to private * fixed CMakeLists.txt typos * add normalize with alpha and beta * add version notes for yolov5/yolov6/yolox * add copyright to yolov5.cc * revert normalize * fixed some bugs in yolox * fixed examples/CMakeLists.txt to avoid conflicts * add convert processor to vision * format examples/CMakeLists summary * Fix bug while the inference result is empty with YOLOv5 (#29) * Add multi-label function for yolov5 * Update README.md Update doc * Update fastdeploy_runtime.cc fix variable option.trt_max_shape wrong name * Update runtime_option.md Update resnet model dynamic shape setting name from images to x * Fix bug when inference result boxes are empty * Delete detection.py Co-authored-by: Jason Co-authored-by: root Co-authored-by: DefTruth <31974251+DefTruth@users.noreply.github.com> Co-authored-by: huangjianhui <852142024@qq.com> * documents * documents * documents * documents * documents * documents * documents * documents * documents * documents * documents * documents * Develop (#14) * Fix compile problem in different python version (#26) * fix some usage problem in linux * Fix compile problem Co-authored-by: root * Add PaddleDetetion/PPYOLOE model support (#22) * add ppdet/ppyoloe * Add demo code and documents * add convert processor to vision (#27) * update .gitignore * Added checking for cmake include dir * fixed missing trt_backend option bug when init from trt * remove un-need data layout and add pre-check for dtype * changed RGB2BRG to BGR2RGB in ppcls model * add model_zoo yolov6 c++/python demo * fixed CMakeLists.txt typos * update yolov6 cpp/README.md * add yolox c++/pybind and model_zoo demo * move some helpers to private * fixed CMakeLists.txt typos * add normalize with alpha and beta * add version notes for yolov5/yolov6/yolox * add copyright to yolov5.cc * revert normalize * fixed some bugs in yolox * fixed examples/CMakeLists.txt to avoid conflicts * add convert processor to vision * format examples/CMakeLists summary * Fix bug while the inference result is empty with YOLOv5 (#29) * Add multi-label function for yolov5 * Update README.md Update doc * Update fastdeploy_runtime.cc fix variable option.trt_max_shape wrong name * Update runtime_option.md Update resnet model dynamic shape setting name from images to x * Fix bug when inference result boxes are empty * Delete detection.py Co-authored-by: root Co-authored-by: DefTruth <31974251+DefTruth@users.noreply.github.com> Co-authored-by: huangjianhui <852142024@qq.com> Co-authored-by: Jason Co-authored-by: root Co-authored-by: DefTruth <31974251+DefTruth@users.noreply.github.com> Co-authored-by: huangjianhui <852142024@qq.com> Co-authored-by: Jason <928090362@qq.com> --- fastdeploy/vision/wongkinyiu/__init__.py | 2 +- model_zoo/vision/yolor/README.md | 13 ++++++------- model_zoo/vision/yolor/cpp/README.md | 14 ++++++++------ model_zoo/vision/yolov7/README.md | 4 ++-- model_zoo/vision/yolov7/cpp/README.md | 4 ++-- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/fastdeploy/vision/wongkinyiu/__init__.py b/fastdeploy/vision/wongkinyiu/__init__.py index 026d10062fb..3c77e858965 100644 --- a/fastdeploy/vision/wongkinyiu/__init__.py +++ b/fastdeploy/vision/wongkinyiu/__init__.py @@ -135,7 +135,7 @@ def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): return self._model.predict(input_image, conf_threshold, nms_iou_threshold) - # 一些跟YOLOv7模型有关的属性封装 + # 一些跟YOLOR模型有关的属性封装 # 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持) @property def size(self): diff --git a/model_zoo/vision/yolor/README.md b/model_zoo/vision/yolor/README.md index 467023f1690..358e62bbe1a 100644 --- a/model_zoo/vision/yolor/README.md +++ b/model_zoo/vision/yolor/README.md @@ -1,6 +1,7 @@ # 编译YOLOR示例 -当前支持模型版本为:[YOLOR v0.1](https://github.com/WongKinYiu/yolor/releases/tag/weights) +当前支持模型版本为:[YOLOR weights](https://github.com/WongKinYiu/yolor/releases/tag/weights) +(tips: 如果使用 `git clone` 的方式下载仓库代码,请将分支切换(checkout)到 `paper` 分支). 本文档说明如何进行[YOLOR](https://github.com/WongKinYiu/yolor)的快速部署推理。本目录结构如下 @@ -18,19 +19,17 @@ - 手动获取 - 访问[YOLOR](https://github.com/WongKinYiu/yolor)官方github库,按照指引下载安装,下载`yolor.pt` 模型,利用 `models/export.py` 得到`onnx`格式文件。 - - + 访问[YOLOR](https://github.com/WongKinYiu/yolor)官方github库,按照指引下载安装,下载`yolor.pt` 模型,利用 `models/export.py` 得到`onnx`格式文件。如果您导出的`onnx`模型出现精度不达标或者是数据维度的问题,可以参考[yolor#32](https://github.com/WongKinYiu/yolor/issues/32)的解决办法 ``` #下载yolor模型文件 - wget https://github.com/WongKinYiu/yolor/releases/download/v0.1/yolor.pt + wget https://github.com/WongKinYiu/yolor/releases/download/weights/yolor-d6-paper-570.pt # 导出onnx格式文件 - python models/export.py --grid --dynamic --weights PATH/TO/yolo7.pt + python models/export.py --weights PATH/TO/yolor-xx-xx-xx.pt --img-size 640 # 移动onnx文件到demo目录 - cp PATH/TO/yolo7.onnx PATH/TO/model_zoo/vision/yolor/ + cp PATH/TO/yolor.onnx PATH/TO/model_zoo/vision/yolor/ ``` ## 安装FastDeploy diff --git a/model_zoo/vision/yolor/cpp/README.md b/model_zoo/vision/yolor/cpp/README.md index eddf5bc51b3..d06bbe30055 100644 --- a/model_zoo/vision/yolor/cpp/README.md +++ b/model_zoo/vision/yolor/cpp/README.md @@ -1,20 +1,22 @@ # 编译YOLOR示例 -当前支持模型版本为:[YOLOR v0.1](https://github.com/WongKinYiu/yolor/releases/tag/weights) - +当前支持模型版本为:[YOLOR weights](https://github.com/WongKinYiu/yolor/releases/tag/weights) +(tips: 如果使用 `git clone` 的方式下载仓库代码,请将分支切换(checkout)到 `paper` 分支). ## 获取ONNX文件 - 手动获取 - 访问[YOLOR](https://github.com/WongKinYiu/yolor/releases/tag/weights)官方github库,按照指引下载安装,下载`yolor.pt` 模型,利用 `models/export.py` 得到`onnx`格式文件。 + 访问[YOLOR](https://github.com/WongKinYiu/yolor)官方github库,按照指引下载安装,下载`yolor.pt` 模型,利用 `models/export.py` 得到`onnx`格式文件。如果您导出的`onnx`模型出现精度不达标或者是数据维度的问题,可以参考[yolor#32](https://github.com/WongKinYiu/yolor/issues/32)的解决办法 ``` #下载yolor模型文件 - wget https://github.com/WongKinYiu/yolor/releases/download/v0.1/yolor.pt + wget https://github.com/WongKinYiu/yolor/releases/download/weights/yolor-d6-paper-570.pt # 导出onnx格式文件 - python models/export.py --grid --dynamic --weights PATH/TO/yolo7.pt + python models/export.py --weights PATH/TO/yolor-xx-xx-xx.pt --img-size 640 + # 移动onnx文件到demo目录 + cp PATH/TO/yolor.onnx PATH/TO/model_zoo/vision/yolor/ ``` @@ -31,7 +33,7 @@ cmake .. make -j # 移动onnx文件到demo目录 -cp PATH/TO/yolo7.onnx PATH/TO/model_zoo/vision/yolor/cpp/build/ +cp PATH/TO/yolor.onnx PATH/TO/model_zoo/vision/yolor/cpp/build/ # 下载图片 wget https://raw.githubusercontent.com/WongKinYiu/yolor/paper/inference/images/horses.jpg diff --git a/model_zoo/vision/yolov7/README.md b/model_zoo/vision/yolov7/README.md index 2bb13ce4594..8b2f06d7611 100644 --- a/model_zoo/vision/yolov7/README.md +++ b/model_zoo/vision/yolov7/README.md @@ -27,10 +27,10 @@ wget https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7.pt # 导出onnx格式文件 - python models/export.py --grid --dynamic --weights PATH/TO/yolo7.pt + python models/export.py --grid --dynamic --weights PATH/TO/yolov7.pt # 移动onnx文件到demo目录 - cp PATH/TO/yolo7.onnx PATH/TO/model_zoo/vision/yolov7/ + cp PATH/TO/yolov7.onnx PATH/TO/model_zoo/vision/yolov7/ ``` ## 安装FastDeploy diff --git a/model_zoo/vision/yolov7/cpp/README.md b/model_zoo/vision/yolov7/cpp/README.md index f216c1aecff..655e98678cd 100644 --- a/model_zoo/vision/yolov7/cpp/README.md +++ b/model_zoo/vision/yolov7/cpp/README.md @@ -13,7 +13,7 @@ wget https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7.pt # 导出onnx格式文件 - python models/export.py --grid --dynamic --weights PATH/TO/yolo7.pt + python models/export.py --grid --dynamic --weights PATH/TO/yolov7.pt ``` @@ -31,7 +31,7 @@ cmake .. make -j # 移动onnx文件到demo目录 -cp PATH/TO/yolo7.onnx PATH/TO/model_zoo/vision/yolov7/cpp/build/ +cp PATH/TO/yolov7.onnx PATH/TO/model_zoo/vision/yolov7/cpp/build/ # 下载图片 wget https://raw.githubusercontent.com/WongKinYiu/yolov7/main/inference/images/horses.jpg From 90ca4cb0cd2c29a657dbe544d570b4498e4e35d7 Mon Sep 17 00:00:00 2001 From: ziqi-jin <67993288+ziqi-jin@users.noreply.github.com> Date: Fri, 29 Jul 2022 14:49:38 +0800 Subject: [PATCH 39/69] add is_dynamic for YOLO series (#22) --- csrcs/fastdeploy/vision/ppogg/yolov5lite.cc | 15 +++++++++++++++ csrcs/fastdeploy/vision/ppogg/yolov5lite.h | 10 ++++++++++ .../vision/wongkinyiu/scaledyolov4.cc | 15 +++++++++++++++ .../fastdeploy/vision/wongkinyiu/scaledyolov4.h | 10 ++++++++++ csrcs/fastdeploy/vision/wongkinyiu/yolor.cc | 17 ++++++++++++++++- csrcs/fastdeploy/vision/wongkinyiu/yolor.h | 10 ++++++++++ csrcs/fastdeploy/vision/wongkinyiu/yolov7.cc | 17 ++++++++++++++++- csrcs/fastdeploy/vision/wongkinyiu/yolov7.h | 10 ++++++++++ 8 files changed, 102 insertions(+), 2 deletions(-) diff --git a/csrcs/fastdeploy/vision/ppogg/yolov5lite.cc b/csrcs/fastdeploy/vision/ppogg/yolov5lite.cc index 320867f581a..a84ead937aa 100644 --- a/csrcs/fastdeploy/vision/ppogg/yolov5lite.cc +++ b/csrcs/fastdeploy/vision/ppogg/yolov5lite.cc @@ -118,6 +118,21 @@ bool YOLOv5Lite::Initialize() { FDERROR << "Failed to initialize fastdeploy backend." << std::endl; return false; } + // Check if the input shape is dynamic after Runtime already initialized, + // Note that, We need to force is_mini_pad 'false' to keep static + // shape after padding (LetterBox) when the is_dynamic_shape is 'false'. + is_dynamic_input_ = false; + auto shape = InputInfoOfRuntime(0).shape; + for (int i = 0; i < shape.size(); ++i) { + // if height or width is dynamic + if (i >= 2 && shape[i] <= 0) { + is_dynamic_input_ = true; + break; + } + } + if (!is_dynamic_input_) { + is_mini_pad = false; + } return true; } diff --git a/csrcs/fastdeploy/vision/ppogg/yolov5lite.h b/csrcs/fastdeploy/vision/ppogg/yolov5lite.h index 3eb556cfa35..669240e2117 100644 --- a/csrcs/fastdeploy/vision/ppogg/yolov5lite.h +++ b/csrcs/fastdeploy/vision/ppogg/yolov5lite.h @@ -126,6 +126,16 @@ class FASTDEPLOY_DECL YOLOv5Lite : public FastDeployModel { void GenerateAnchors(const std::vector& size, const std::vector& downsample_strides, std::vector* anchors, const int num_anchors = 3); + + // 查看输入是否为动态维度的 不建议直接使用 不同模型的逻辑可能不一致 + bool IsDynamicInput() const { return is_dynamic_input_; } + + // whether to inference with dynamic shape (e.g ONNX export with dynamic shape + // or not.) + // while is_dynamic_shape if 'false', is_mini_pad will force 'false'. This + // value will + // auto check by fastdeploy after the internal Runtime already initialized. + bool is_dynamic_input_; }; } // namespace ppogg } // namespace vision diff --git a/csrcs/fastdeploy/vision/wongkinyiu/scaledyolov4.cc b/csrcs/fastdeploy/vision/wongkinyiu/scaledyolov4.cc index 7321fc01bbd..a562c9b2755 100644 --- a/csrcs/fastdeploy/vision/wongkinyiu/scaledyolov4.cc +++ b/csrcs/fastdeploy/vision/wongkinyiu/scaledyolov4.cc @@ -89,6 +89,21 @@ bool ScaledYOLOv4::Initialize() { FDERROR << "Failed to initialize fastdeploy backend." << std::endl; return false; } + // Check if the input shape is dynamic after Runtime already initialized, + // Note that, We need to force is_mini_pad 'false' to keep static + // shape after padding (LetterBox) when the is_dynamic_shape is 'false'. + is_dynamic_input_ = false; + auto shape = InputInfoOfRuntime(0).shape; + for (int i = 0; i < shape.size(); ++i) { + // if height or width is dynamic + if (i >= 2 && shape[i] <= 0) { + is_dynamic_input_ = true; + break; + } + } + if (!is_dynamic_input_) { + is_mini_pad = false; + } return true; } diff --git a/csrcs/fastdeploy/vision/wongkinyiu/scaledyolov4.h b/csrcs/fastdeploy/vision/wongkinyiu/scaledyolov4.h index 39066a29ec0..247d5221e19 100644 --- a/csrcs/fastdeploy/vision/wongkinyiu/scaledyolov4.h +++ b/csrcs/fastdeploy/vision/wongkinyiu/scaledyolov4.h @@ -90,6 +90,16 @@ class FASTDEPLOY_DECL ScaledYOLOv4 : public FastDeployModel { const std::vector& color, bool _auto, bool scale_fill = false, bool scale_up = true, int stride = 32); + + // 查看输入是否为动态维度的 不建议直接使用 不同模型的逻辑可能不一致 + bool IsDynamicInput() const { return is_dynamic_input_; } + + // whether to inference with dynamic shape (e.g ONNX export with dynamic shape + // or not.) + // while is_dynamic_shape if 'false', is_mini_pad will force 'false'. This + // value will + // auto check by fastdeploy after the internal Runtime already initialized. + bool is_dynamic_input_; }; } // namespace wongkinyiu } // namespace vision diff --git a/csrcs/fastdeploy/vision/wongkinyiu/yolor.cc b/csrcs/fastdeploy/vision/wongkinyiu/yolor.cc index 070ea72e608..7de994f2a47 100644 --- a/csrcs/fastdeploy/vision/wongkinyiu/yolor.cc +++ b/csrcs/fastdeploy/vision/wongkinyiu/yolor.cc @@ -87,6 +87,21 @@ bool YOLOR::Initialize() { FDERROR << "Failed to initialize fastdeploy backend." << std::endl; return false; } + // Check if the input shape is dynamic after Runtime already initialized, + // Note that, We need to force is_mini_pad 'false' to keep static + // shape after padding (LetterBox) when the is_dynamic_shape is 'false'. + is_dynamic_input_ = false; + auto shape = InputInfoOfRuntime(0).shape; + for (int i = 0; i < shape.size(); ++i) { + // if height or width is dynamic + if (i >= 2 && shape[i] <= 0) { + is_dynamic_input_ = true; + break; + } + } + if (!is_dynamic_input_) { + is_mini_pad = false; + } return true; } @@ -176,7 +191,7 @@ bool YOLOR::Postprocess( float pad_h = (out_h - ipt_h * scale) / 2.0f; float pad_w = (out_w - ipt_w * scale) / 2.0f; if (is_mini_pad) { - // 和 LetterBox中_auto=true的处理逻辑对应 + // 和 LetterBox中_auto=true的处理逻辑对应 pad_h = static_cast(static_cast(pad_h) % stride); pad_w = static_cast(static_cast(pad_w) % stride); } diff --git a/csrcs/fastdeploy/vision/wongkinyiu/yolor.h b/csrcs/fastdeploy/vision/wongkinyiu/yolor.h index 7597f42d320..b3a00663c1f 100644 --- a/csrcs/fastdeploy/vision/wongkinyiu/yolor.h +++ b/csrcs/fastdeploy/vision/wongkinyiu/yolor.h @@ -89,6 +89,16 @@ class FASTDEPLOY_DECL YOLOR : public FastDeployModel { const std::vector& color, bool _auto, bool scale_fill = false, bool scale_up = true, int stride = 32); + + // 查看输入是否为动态维度的 不建议直接使用 不同模型的逻辑可能不一致 + bool IsDynamicInput() const { return is_dynamic_input_; } + + // whether to inference with dynamic shape (e.g ONNX export with dynamic shape + // or not.) + // while is_dynamic_shape if 'false', is_mini_pad will force 'false'. This + // value will + // auto check by fastdeploy after the internal Runtime already initialized. + bool is_dynamic_input_; }; } // namespace wongkinyiu } // namespace vision diff --git a/csrcs/fastdeploy/vision/wongkinyiu/yolov7.cc b/csrcs/fastdeploy/vision/wongkinyiu/yolov7.cc index 457f8800cf7..6f603c87fc5 100644 --- a/csrcs/fastdeploy/vision/wongkinyiu/yolov7.cc +++ b/csrcs/fastdeploy/vision/wongkinyiu/yolov7.cc @@ -88,6 +88,21 @@ bool YOLOv7::Initialize() { FDERROR << "Failed to initialize fastdeploy backend." << std::endl; return false; } + // Check if the input shape is dynamic after Runtime already initialized, + // Note that, We need to force is_mini_pad 'false' to keep static + // shape after padding (LetterBox) when the is_dynamic_shape is 'false'. + is_dynamic_input_ = false; + auto shape = InputInfoOfRuntime(0).shape; + for (int i = 0; i < shape.size(); ++i) { + // if height or width is dynamic + if (i >= 2 && shape[i] <= 0) { + is_dynamic_input_ = true; + break; + } + } + if (!is_dynamic_input_) { + is_mini_pad = false; + } return true; } @@ -177,7 +192,7 @@ bool YOLOv7::Postprocess( float pad_h = (out_h - ipt_h * scale) / 2.0f; float pad_w = (out_w - ipt_w * scale) / 2.0f; if (is_mini_pad) { - // 和 LetterBox中_auto=true的处理逻辑对应 + // 和 LetterBox中_auto=true的处理逻辑对应 pad_h = static_cast(static_cast(pad_h) % stride); pad_w = static_cast(static_cast(pad_w) % stride); } diff --git a/csrcs/fastdeploy/vision/wongkinyiu/yolov7.h b/csrcs/fastdeploy/vision/wongkinyiu/yolov7.h index 64e18ad47b0..5dbdfb8f4a4 100644 --- a/csrcs/fastdeploy/vision/wongkinyiu/yolov7.h +++ b/csrcs/fastdeploy/vision/wongkinyiu/yolov7.h @@ -89,6 +89,16 @@ class FASTDEPLOY_DECL YOLOv7 : public FastDeployModel { const std::vector& color, bool _auto, bool scale_fill = false, bool scale_up = true, int stride = 32); + + // 查看输入是否为动态维度的 不建议直接使用 不同模型的逻辑可能不一致 + bool IsDynamicInput() const { return is_dynamic_input_; } + + // whether to inference with dynamic shape (e.g ONNX export with dynamic shape + // or not.) + // while is_dynamic_shape if 'false', is_mini_pad will force 'false'. This + // value will + // auto check by fastdeploy after the internal Runtime already initialized. + bool is_dynamic_input_; }; } // namespace wongkinyiu } // namespace vision From 19db925e6323d330e6eeed11b29eeb8612e832c2 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Thu, 1 Sep 2022 06:39:35 +0000 Subject: [PATCH 40/69] modify ppmatting backend and docs --- .../vision/matting/ppmatting/ppmatting.cc | 2 +- .../vision/matting/ppmatting/ppmatting.h | 2 +- .../vision/matting/ppmatting/cpp/README.md | 2 -- .../vision/matting/ppmatting/cpp/infer.cc | 35 ------------------- .../vision/matting/ppmatting/python/README.md | 2 -- 5 files changed, 2 insertions(+), 41 deletions(-) diff --git a/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.cc b/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.cc index 63a9eff584b..31a40c94ca4 100644 --- a/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.cc +++ b/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.cc @@ -27,7 +27,7 @@ PPMatting::PPMatting(const std::string& model_file, const Frontend& model_format) { config_file_ = config_file; valid_cpu_backends = {Backend::PDINFER, Backend::ORT}; - valid_gpu_backends = {Backend::PDINFER, Backend::ORT, Backend::TRT}; + valid_gpu_backends = {Backend::PDINFER, Backend::TRT}; runtime_option = custom_option; runtime_option.model_format = model_format; runtime_option.model_file = model_file; diff --git a/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.h b/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.h index 148fe10e814..763d4307706 100644 --- a/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.h +++ b/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.h @@ -27,7 +27,7 @@ class FASTDEPLOY_DECL PPMatting : public FastDeployModel { const RuntimeOption& custom_option = RuntimeOption(), const Frontend& model_format = Frontend::PADDLE); - std::string ModelName() const { return "PaddleMat"; } + std::string ModelName() const { return "PaddleMatting"; } virtual bool Predict(cv::Mat* im, MattingResult* result); diff --git a/examples/vision/matting/ppmatting/cpp/README.md b/examples/vision/matting/ppmatting/cpp/README.md index 20ef29f7b39..64b243c4a88 100644 --- a/examples/vision/matting/ppmatting/cpp/README.md +++ b/examples/vision/matting/ppmatting/cpp/README.md @@ -27,8 +27,6 @@ wget https://bj.bcebos.com/paddlehub/fastdeploy/matting_bgr.jpg # CPU推理 ./infer_demo PP-Matting-512 matting_input.jpg matting_bgr.jpg 0 -# GPU推理 (TODO: ORT-GPU 推理会报错) -./infer_demo PP-Matting-512 matting_input.jpg matting_bgr.jpg 1 # GPU上TensorRT推理 ./infer_demo PP-Matting-512 matting_input.jpg matting_bgr.jpg 2 ``` diff --git a/examples/vision/matting/ppmatting/cpp/infer.cc b/examples/vision/matting/ppmatting/cpp/infer.cc index bb8c6eac288..f2dfeedee9b 100644 --- a/examples/vision/matting/ppmatting/cpp/infer.cc +++ b/examples/vision/matting/ppmatting/cpp/infer.cc @@ -50,39 +50,6 @@ void CpuInfer(const std::string& model_dir, const std::string& image_file, << std::endl; } -void GpuInfer(const std::string& model_dir, const std::string& image_file, - const std::string& background_file) { - auto model_file = model_dir + sep + "model.pdmodel"; - auto params_file = model_dir + sep + "model.pdiparams"; - auto config_file = model_dir + sep + "deploy.yaml"; - - auto option = fastdeploy::RuntimeOption(); - option.UseGpu(); - auto model = fastdeploy::vision::matting::PPMatting(model_file, params_file, - config_file, option); - if (!model.Initialized()) { - std::cerr << "Failed to initialize." << std::endl; - return; - } - - auto im = cv::imread(image_file); - auto im_bak = im.clone(); - cv::Mat bg = cv::imread(background_file); - fastdeploy::vision::MattingResult res; - if (!model.Predict(&im, &res)) { - std::cerr << "Failed to predict." << std::endl; - return; - } - auto vis_im = fastdeploy::vision::Visualize::VisMattingAlpha(im_bak, res); - auto vis_im_with_bg = - fastdeploy::vision::Visualize::SwapBackgroundMatting(im_bak, bg, res); - cv::imwrite("visualized_result.jpg", vis_im_with_bg); - cv::imwrite("visualized_result_fg.jpg", vis_im); - std::cout << "Visualized result save in ./visualized_result_replaced_bg.jpg " - "and ./visualized_result_fg.jpgg" - << std::endl; -} - void TrtInfer(const std::string& model_dir, const std::string& image_file, const std::string& background_file) { auto model_file = model_dir + sep + "model.pdmodel"; @@ -131,8 +98,6 @@ int main(int argc, char* argv[]) { } if (std::atoi(argv[4]) == 0) { CpuInfer(argv[1], argv[2], argv[3]); - } else if (std::atoi(argv[4]) == 1) { - GpuInfer(argv[1], argv[2], argv[3]); } else if (std::atoi(argv[4]) == 2) { TrtInfer(argv[1], argv[2], argv[3]); } diff --git a/examples/vision/matting/ppmatting/python/README.md b/examples/vision/matting/ppmatting/python/README.md index cd4ed7d2df7..370bdff574e 100644 --- a/examples/vision/matting/ppmatting/python/README.md +++ b/examples/vision/matting/ppmatting/python/README.md @@ -19,8 +19,6 @@ wget https://bj.bcebos.com/paddlehub/fastdeploy/matting_input.jpg wget https://bj.bcebos.com/paddlehub/fastdeploy/matting_bgr.jpg # CPU推理 python infer.py --model PP-Matting-512 --image matting_input.jpg --bg matting_bgr.jpg --device cpu -# GPU推理 (TODO: ORT-GPU 推理会报错) -python infer.py --model PP-Matting-512 --image matting_input.jpg --bg matting_bgr.jpg --device gpu # GPU上使用TensorRT推理 (注意:TensorRT推理第一次运行,有序列化模型的操作,有一定耗时,需要耐心等待) python infer.py --model PP-Matting-512 --image matting_input.jpg --bg matting_bgr.jpg --device gpu --use_trt True ``` From 15be4a62a0af562cbebdcb1e2792cb9a7906e771 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Thu, 1 Sep 2022 13:16:47 +0000 Subject: [PATCH 41/69] modify ppmatting docs --- .../vision/matting/ppmatting/cpp/README.md | 2 + .../vision/matting/ppmatting/cpp/infer.cc | 40 ++++++++++++++++++- .../vision/matting/ppmatting/python/README.md | 2 + .../vision/matting/ppmatting/python/infer.py | 3 +- 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/examples/vision/matting/ppmatting/cpp/README.md b/examples/vision/matting/ppmatting/cpp/README.md index 64b243c4a88..56b4a13f307 100644 --- a/examples/vision/matting/ppmatting/cpp/README.md +++ b/examples/vision/matting/ppmatting/cpp/README.md @@ -27,6 +27,8 @@ wget https://bj.bcebos.com/paddlehub/fastdeploy/matting_bgr.jpg # CPU推理 ./infer_demo PP-Matting-512 matting_input.jpg matting_bgr.jpg 0 +# GPU推理 +./infer_demo PP-Matting-512 matting_input.jpg matting_bgr.jpg 1 # GPU上TensorRT推理 ./infer_demo PP-Matting-512 matting_input.jpg matting_bgr.jpg 2 ``` diff --git a/examples/vision/matting/ppmatting/cpp/infer.cc b/examples/vision/matting/ppmatting/cpp/infer.cc index f2dfeedee9b..2e764725cf2 100644 --- a/examples/vision/matting/ppmatting/cpp/infer.cc +++ b/examples/vision/matting/ppmatting/cpp/infer.cc @@ -25,8 +25,10 @@ void CpuInfer(const std::string& model_dir, const std::string& image_file, auto model_file = model_dir + sep + "model.pdmodel"; auto params_file = model_dir + sep + "model.pdiparams"; auto config_file = model_dir + sep + "deploy.yaml"; + auto option = fastdeploy::RuntimeOption(); + option.UseOrtBackend(); auto model = fastdeploy::vision::matting::PPMatting(model_file, params_file, - config_file); + config_file, option); if (!model.Initialized()) { std::cerr << "Failed to initialize." << std::endl; return; @@ -50,6 +52,40 @@ void CpuInfer(const std::string& model_dir, const std::string& image_file, << std::endl; } +void GpuInfer(const std::string& model_dir, const std::string& image_file, + const std::string& background_file) { + auto model_file = model_dir + sep + "model.pdmodel"; + auto params_file = model_dir + sep + "model.pdiparams"; + auto config_file = model_dir + sep + "deploy.yaml"; + + auto option = fastdeploy::RuntimeOption(); + option.UseGpu(); + option.UsePaddleBackend(); + auto model = fastdeploy::vision::matting::PPMatting(model_file, params_file, + config_file, option); + if (!model.Initialized()) { + std::cerr << "Failed to initialize." << std::endl; + return; + } + + auto im = cv::imread(image_file); + auto im_bak = im.clone(); + cv::Mat bg = cv::imread(background_file); + fastdeploy::vision::MattingResult res; + if (!model.Predict(&im, &res)) { + std::cerr << "Failed to predict." << std::endl; + return; + } + auto vis_im = fastdeploy::vision::Visualize::VisMattingAlpha(im_bak, res); + auto vis_im_with_bg = + fastdeploy::vision::Visualize::SwapBackgroundMatting(im_bak, bg, res); + cv::imwrite("visualized_result.jpg", vis_im_with_bg); + cv::imwrite("visualized_result_fg.jpg", vis_im); + std::cout << "Visualized result save in ./visualized_result_replaced_bg.jpg " + "and ./visualized_result_fg.jpgg" + << std::endl; +} + void TrtInfer(const std::string& model_dir, const std::string& image_file, const std::string& background_file) { auto model_file = model_dir + sep + "model.pdmodel"; @@ -98,6 +134,8 @@ int main(int argc, char* argv[]) { } if (std::atoi(argv[4]) == 0) { CpuInfer(argv[1], argv[2], argv[3]); + } else if (std::atoi(argv[4]) == 1) { + GpuInfer(argv[1], argv[2], argv[3]); } else if (std::atoi(argv[4]) == 2) { TrtInfer(argv[1], argv[2], argv[3]); } diff --git a/examples/vision/matting/ppmatting/python/README.md b/examples/vision/matting/ppmatting/python/README.md index 370bdff574e..ea6e6804e68 100644 --- a/examples/vision/matting/ppmatting/python/README.md +++ b/examples/vision/matting/ppmatting/python/README.md @@ -19,6 +19,8 @@ wget https://bj.bcebos.com/paddlehub/fastdeploy/matting_input.jpg wget https://bj.bcebos.com/paddlehub/fastdeploy/matting_bgr.jpg # CPU推理 python infer.py --model PP-Matting-512 --image matting_input.jpg --bg matting_bgr.jpg --device cpu +# GPU推理 +python infer.py --model PP-Matting-512 --image matting_input.jpg --bg matting_bgr.jpg --device gpu # GPU上使用TensorRT推理 (注意:TensorRT推理第一次运行,有序列化模型的操作,有一定耗时,需要耐心等待) python infer.py --model PP-Matting-512 --image matting_input.jpg --bg matting_bgr.jpg --device gpu --use_trt True ``` diff --git a/examples/vision/matting/ppmatting/python/infer.py b/examples/vision/matting/ppmatting/python/infer.py index 4f5e7ffc4e6..e0ceae751ef 100644 --- a/examples/vision/matting/ppmatting/python/infer.py +++ b/examples/vision/matting/ppmatting/python/infer.py @@ -32,9 +32,10 @@ def parse_arguments(): def build_option(args): option = fd.RuntimeOption() - + option.use_ort_backend() if args.device.lower() == "gpu": option.use_gpu() + option.use_paddle_backend() if args.use_trt: option.use_trt_backend() From 3a5b93a5196b396adf7fe99775362e920b1a3728 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Sat, 3 Sep 2022 07:47:56 +0000 Subject: [PATCH 42/69] fix the PPMatting size problem --- .../common/processors/resize_by_long.cc | 78 +++++++++++++++++++ .../vision/common/processors/resize_by_long.h | 49 ++++++++++++ .../vision/common/processors/transform.h | 1 + .../vision/matting/ppmatting/ppmatting.cc | 44 ++++++++++- .../vision/matting/modnet/python/README.md | 1 + 5 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 csrc/fastdeploy/vision/common/processors/resize_by_long.cc create mode 100644 csrc/fastdeploy/vision/common/processors/resize_by_long.h diff --git a/csrc/fastdeploy/vision/common/processors/resize_by_long.cc b/csrc/fastdeploy/vision/common/processors/resize_by_long.cc new file mode 100644 index 00000000000..7c2c90152fd --- /dev/null +++ b/csrc/fastdeploy/vision/common/processors/resize_by_long.cc @@ -0,0 +1,78 @@ +// 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/vision/common/processors/resize_by_long.h" + +namespace fastdeploy { +namespace vision { + +bool ResizeByLong::CpuRun(Mat* mat) { + cv::Mat* im = mat->GetCpuMat(); + int origin_w = im->cols; + int origin_h = im->rows; + double scale = GenerateScale(origin_w, origin_h); + if (use_scale_) { + cv::resize(*im, *im, cv::Size(), scale, scale, interp_); + } else { + int width = static_cast(round(scale * im->cols)); + int height = static_cast(round(scale * im->rows)); + cv::resize(*im, *im, cv::Size(width, height), 0, 0, interp_); + } + mat->SetWidth(im->cols); + mat->SetHeight(im->rows); + return true; +} + +#ifdef ENABLE_OPENCV_CUDA +bool ResizeByLong::GpuRun(Mat* mat) { + cv::cuda::GpuMat* im = mat->GetGpuMat(); + int origin_w = im->cols; + int origin_h = im->rows; + double scale = GenerateScale(origin_w, origin_h); + im->convertTo(*im, CV_32FC(im->channels())); + if (use_scale_) { + cv::cuda::resize(*im, *im, cv::Size(), scale, scale, interp_); + } else { + int width = static_cast(round(scale * im->cols)); + int height = static_cast(round(scale * im->rows)); + cv::cuda::resize(*im, *im, cv::Size(width, height), 0, 0, interp_); + } + mat->SetWidth(im->cols); + mat->SetHeight(im->rows); + return true; +} +#endif + +double ResizeByLong::GenerateScale(const int origin_w, const int origin_h) { + int im_size_max = std::max(origin_w, origin_h); + int im_size_min = std::min(origin_w, origin_h); + double scale = 1.0f; + if (target_size_ == -1) { + if (im_size_max > max_size_) { + scale = static_cast(max_size_) / static_cast(im_size_max); + } + } else { + scale = + static_cast(target_size_) / static_cast(im_size_max); + } + return scale; +} + +bool ResizeByLong::Run(Mat* mat, int target_size, int interp, bool use_scale, + int max_size, ProcLib lib) { + auto r = ResizeByLong(target_size, interp, use_scale, max_size); + return r(mat, lib); +} +} // namespace vision +} // namespace fastdeploy diff --git a/csrc/fastdeploy/vision/common/processors/resize_by_long.h b/csrc/fastdeploy/vision/common/processors/resize_by_long.h new file mode 100644 index 00000000000..5984bfca149 --- /dev/null +++ b/csrc/fastdeploy/vision/common/processors/resize_by_long.h @@ -0,0 +1,49 @@ +// 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. + +#pragma once + +#include "fastdeploy/vision/common/processors/base.h" + +namespace fastdeploy { +namespace vision { + +class ResizeByLong : public Processor { + public: + ResizeByLong(int target_size, int interp = 1, bool use_scale = true, + int max_size = -1) { + target_size_ = target_size; + max_size_ = max_size; + interp_ = interp; + use_scale_ = use_scale; + } + bool CpuRun(Mat* mat); +#ifdef ENABLE_OPENCV_CUDA + bool GpuRun(Mat* mat); +#endif + std::string Name() { return "ResizeByLong"; } + + static bool Run(Mat* mat, int target_size, int interp = 1, + bool use_scale = true, int max_size = -1, + ProcLib lib = ProcLib::OPENCV_CPU); + + private: + double GenerateScale(const int origin_w, const int origin_h); + int target_size_; + int max_size_; + int interp_; + bool use_scale_; +}; +} // namespace vision +} // namespace fastdeploy diff --git a/csrc/fastdeploy/vision/common/processors/transform.h b/csrc/fastdeploy/vision/common/processors/transform.h index 065006fbfb0..cf720ceb7bf 100644 --- a/csrc/fastdeploy/vision/common/processors/transform.h +++ b/csrc/fastdeploy/vision/common/processors/transform.h @@ -24,6 +24,7 @@ #include "fastdeploy/vision/common/processors/pad.h" #include "fastdeploy/vision/common/processors/pad_to_size.h" #include "fastdeploy/vision/common/processors/resize.h" +#include "fastdeploy/vision/common/processors/resize_by_long.h" #include "fastdeploy/vision/common/processors/resize_by_short.h" #include "fastdeploy/vision/common/processors/resize_to_int_mult.h" #include "fastdeploy/vision/common/processors/stride_pad.h" diff --git a/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.cc b/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.cc index 31a40c94ca4..5009e05078f 100644 --- a/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.cc +++ b/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.cc @@ -74,6 +74,10 @@ bool PPMatting::BuildPreprocessPipelineFromConfig() { if (op["min_short"]) { min_short = op["min_short"].as(); } + std::cout << "If LimintShort in yaml file, you may transfer PPMatting " + "model by yourself, please make sure your input image's " + "width==hight and not smaller than " + << max_short << std::endl; processors_.push_back( std::make_shared(max_short, min_short)); } else if (op["type"].as() == "ResizeToIntMult") { @@ -92,6 +96,22 @@ bool PPMatting::BuildPreprocessPipelineFromConfig() { std = op["std"].as>(); } processors_.push_back(std::make_shared(mean, std)); + } else if (op["type"].as() == "ResizeByLong") { + int target_size = 512; + if (op["target_size"]) { + target_size = op["target_size"].as(); + } + processors_.push_back(std::make_shared(target_size)); + } else if (op["type"].as() == "Pad") { + // size: (w, h) + auto size = op["size"].as>(); + std::vector value = {114, 114, 114}; + if (op["fill_value"]) { + auto value = op["fill_value"].as>(); + } + processors_.push_back(std::make_shared("float")); + processors_.push_back( + std::make_shared(size[1], size[0], value)); } } processors_.push_back(std::make_shared()); @@ -107,6 +127,14 @@ bool PPMatting::Preprocess(Mat* mat, FDTensor* output, << "." << std::endl; return false; } + if (processors_[i]->Name().compare("PadToSize") == 0) { + (*im_info)["pad_to_size"] = {static_cast(mat->Height()), + static_cast(mat->Width())}; + } + if (processors_[i]->Name().compare("ResizeByLong") == 0) { + (*im_info)["resize_by_long"] = {static_cast(mat->Height()), + static_cast(mat->Width())}; + } } // Record output shape of preprocessed image @@ -135,6 +163,8 @@ bool PPMatting::Postprocess( // 先获取alpha并resize (使用opencv) auto iter_ipt = im_info.find("input_shape"); auto iter_out = im_info.find("output_shape"); + auto pad_to_size = im_info.find("output_shape"); + auto resize_by_long = im_info.find("resize_by_long"); FDASSERT(iter_out != im_info.end() && iter_ipt != im_info.end(), "Cannot find input_shape or output_shape from im_info."); int out_h = iter_out->second[0]; @@ -145,7 +175,19 @@ bool PPMatting::Postprocess( // TODO: 需要修改成FDTensor或Mat的运算 现在依赖cv::Mat float* alpha_ptr = static_cast(alpha_tensor.Data()); cv::Mat alpha_zero_copy_ref(out_h, out_w, CV_32FC1, alpha_ptr); - Mat alpha_resized(alpha_zero_copy_ref); // ref-only, zero copy. + cv::Mat cropped_alpha; + if (pad_to_size != im_info.end() && resize_by_long != im_info.end()) { + int resize_h = resize_by_long->second[0]; + int resize_w = resize_by_long->second[1]; + int pad_h = pad_to_size->second[0]; + int pad_w = pad_to_size->second[1]; + alpha_zero_copy_ref(cv::Rect(0, 0, resize_w, resize_h)) + .copyTo(cropped_alpha); + } else { + cropped_alpha = alpha_zero_copy_ref; + } + Mat alpha_resized(cropped_alpha); // ref-only, zero copy. + if ((out_h != ipt_h) || (out_w != ipt_w)) { // already allocated a new continuous memory after resize. // cv::resize(alpha_resized, alpha_resized, cv::Size(ipt_w, ipt_h)); diff --git a/examples/vision/matting/modnet/python/README.md b/examples/vision/matting/modnet/python/README.md index 99abdc68287..dfa37b94f0e 100644 --- a/examples/vision/matting/modnet/python/README.md +++ b/examples/vision/matting/modnet/python/README.md @@ -33,6 +33,7 @@ python infer.py --model modnet_photographic_portrait_matting.onnx --image mattin + ## MODNet Python接口 ```python From c2332b0d3f3920114aea3bb0bb013c64e38c9f2d Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Sat, 3 Sep 2022 10:57:02 +0000 Subject: [PATCH 43/69] fix LimitShort's log --- .../vision/common/processors/limit_short.h | 1 + .../vision/matting/ppmatting/ppmatting.cc | 31 +++++++++++++------ .../vision/matting/ppmatting/cpp/infer.cc | 1 - .../vision/matting/ppmatting/python/infer.py | 10 +++--- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/csrc/fastdeploy/vision/common/processors/limit_short.h b/csrc/fastdeploy/vision/common/processors/limit_short.h index 51a26a1ba6f..25eff6d717c 100644 --- a/csrc/fastdeploy/vision/common/processors/limit_short.h +++ b/csrc/fastdeploy/vision/common/processors/limit_short.h @@ -34,6 +34,7 @@ class LimitShort : public Processor { static bool Run(Mat* mat, int max_short = -1, int min_short = -1, ProcLib lib = ProcLib::OPENCV_CPU); + int GetMaxShort() { return max_short_; } private: int max_short_; diff --git a/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.cc b/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.cc index 5009e05078f..f93a46b7154 100644 --- a/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.cc +++ b/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.cc @@ -26,7 +26,7 @@ PPMatting::PPMatting(const std::string& model_file, const RuntimeOption& custom_option, const Frontend& model_format) { config_file_ = config_file; - valid_cpu_backends = {Backend::PDINFER, Backend::ORT}; + valid_cpu_backends = {Backend::ORT, Backend::PDINFER}; valid_gpu_backends = {Backend::PDINFER, Backend::TRT}; runtime_option = custom_option; runtime_option.model_format = model_format; @@ -74,10 +74,11 @@ bool PPMatting::BuildPreprocessPipelineFromConfig() { if (op["min_short"]) { min_short = op["min_short"].as(); } - std::cout << "If LimintShort in yaml file, you may transfer PPMatting " - "model by yourself, please make sure your input image's " - "width==hight and not smaller than " - << max_short << std::endl; + FDINFO << "Detected LimitShort processing step in yaml file, if the " + "model is exported from PaddleSeg, please make sure the " + "input of your model is fixed with a square shape, and " + "greater than or equal to " + << max_short << "." << std::endl; processors_.push_back( std::make_shared(max_short, min_short)); } else if (op["type"].as() == "ResizeToIntMult") { @@ -97,15 +98,12 @@ bool PPMatting::BuildPreprocessPipelineFromConfig() { } processors_.push_back(std::make_shared(mean, std)); } else if (op["type"].as() == "ResizeByLong") { - int target_size = 512; - if (op["target_size"]) { - target_size = op["target_size"].as(); - } + int target_size = op["target_size"].as(); processors_.push_back(std::make_shared(target_size)); } else if (op["type"].as() == "Pad") { // size: (w, h) auto size = op["size"].as>(); - std::vector value = {114, 114, 114}; + std::vector value = {127.5, 127.5, 127.5}; if (op["fill_value"]) { auto value = op["fill_value"].as>(); } @@ -122,6 +120,19 @@ bool PPMatting::BuildPreprocessPipelineFromConfig() { bool PPMatting::Preprocess(Mat* mat, FDTensor* output, std::map>* im_info) { for (size_t i = 0; i < processors_.size(); ++i) { + if (processors_[i]->Name().compare("LimitShort") == 0) { + int input_h = static_cast(mat->Height()); + int input_w = static_cast(mat->Width()); + FDASSERT(input_h == input_w, + "Detected LimitShort processing step in yaml file, please make " + "sure the input of your model is fixed with a square shape"); + auto processor = dynamic_cast(processors_[i].get()); + int max_short = processor->GetMaxShort(); + FDASSERT(input_h >= max_short && input_w >= max_short, + "Detected LimitShort processing step in yaml file, please make " + "sure the input of your model is greater than or equal to %d.", + max_short); + } if (!(*(processors_[i].get()))(mat)) { FDERROR << "Failed to process image data in " << processors_[i]->Name() << "." << std::endl; diff --git a/examples/vision/matting/ppmatting/cpp/infer.cc b/examples/vision/matting/ppmatting/cpp/infer.cc index 2e764725cf2..f47b484e5ed 100644 --- a/examples/vision/matting/ppmatting/cpp/infer.cc +++ b/examples/vision/matting/ppmatting/cpp/infer.cc @@ -26,7 +26,6 @@ void CpuInfer(const std::string& model_dir, const std::string& image_file, auto params_file = model_dir + sep + "model.pdiparams"; auto config_file = model_dir + sep + "deploy.yaml"; auto option = fastdeploy::RuntimeOption(); - option.UseOrtBackend(); auto model = fastdeploy::vision::matting::PPMatting(model_file, params_file, config_file, option); if (!model.Initialized()) { diff --git a/examples/vision/matting/ppmatting/python/infer.py b/examples/vision/matting/ppmatting/python/infer.py index e0ceae751ef..04423802468 100644 --- a/examples/vision/matting/ppmatting/python/infer.py +++ b/examples/vision/matting/ppmatting/python/infer.py @@ -32,14 +32,14 @@ def parse_arguments(): def build_option(args): option = fd.RuntimeOption() - option.use_ort_backend() if args.device.lower() == "gpu": option.use_gpu() - option.use_paddle_backend() + if args.use_trt: + option.use_trt_backend() + option.set_trt_input_shape("img", [1, 3, 512, 512]) + else: + option.use_paddle_backend() - if args.use_trt: - option.use_trt_backend() - option.set_trt_input_shape("img", [1, 3, 512, 512]) return option From 950f94826f70cb018d76f4cb9dfee860c85bd460 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Sun, 4 Sep 2022 09:28:19 +0000 Subject: [PATCH 44/69] retrigger ci From 64a13c9299757fc79fcd5c9d6997d9b48187d13f Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Sun, 4 Sep 2022 11:14:08 +0000 Subject: [PATCH 45/69] modify PPMatting docs --- examples/vision/matting/ppmatting/README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/vision/matting/ppmatting/README.md b/examples/vision/matting/ppmatting/README.md index 0e12051150d..d714322847a 100644 --- a/examples/vision/matting/ppmatting/README.md +++ b/examples/vision/matting/ppmatting/README.md @@ -15,19 +15,18 @@ 在部署前,需要先将PPMatting导出成部署模型,导出步骤参考文档[导出模型](https://github.com/PaddlePaddle/PaddleSeg/tree/release/2.6/Matting) -注意:在导出模型时不要进行NMS的去除操作,正常导出即可。 ## 下载预训练模型 为了方便开发者的测试,下面提供了PPMatting导出的各系列模型,开发者可直接下载使用。 -其中精度指标来源于PPMatting中对各模型的介绍,详情各参考PPMatting中的说明。 +其中精度指标来源于PPMatting中对各模型的介绍(未提供精度数据),详情各参考PPMatting中的说明。 | 模型 | 参数大小 | 精度 | 备注 | |:---------------------------------------------------------------- |:----- |:----- | :------ | -| [PPMatting](https://bj.bcebos.com/paddlehub/fastdeploy/PP-Matting-512.tgz) | 87MB | - | -| [PPMatting](https://bj.bcebos.com/paddlehub/fastdeploy/PP-Matting-1024.tgz) | 87MB | - | +| [PPMatting-512](https://bj.bcebos.com/paddlehub/fastdeploy/PP-Matting-512.tgz) | 87MB | - | +| [PPMatting-1024](https://bj.bcebos.com/paddlehub/fastdeploy/PP-Matting-1024.tgz) | 87MB | - | From 09c073d9d3b4683d6e3efb1b70bc3a8d16709655 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Tue, 6 Sep 2022 06:20:28 +0000 Subject: [PATCH 46/69] modify the way for dealing with LimitShort --- .../vision/matting/ppmatting/ppmatting.cc | 25 ++++++++----------- .../vision/matting/ppmatting/python/infer.py | 10 ++++---- external/paddle_inference.cmake | 2 +- 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.cc b/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.cc index f93a46b7154..8c60b7ee00d 100644 --- a/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.cc +++ b/csrc/fastdeploy/vision/matting/ppmatting/ppmatting.cc @@ -123,25 +123,23 @@ bool PPMatting::Preprocess(Mat* mat, FDTensor* output, if (processors_[i]->Name().compare("LimitShort") == 0) { int input_h = static_cast(mat->Height()); int input_w = static_cast(mat->Width()); - FDASSERT(input_h == input_w, - "Detected LimitShort processing step in yaml file, please make " - "sure the input of your model is fixed with a square shape"); auto processor = dynamic_cast(processors_[i].get()); int max_short = processor->GetMaxShort(); - FDASSERT(input_h >= max_short && input_w >= max_short, - "Detected LimitShort processing step in yaml file, please make " - "sure the input of your model is greater than or equal to %d.", - max_short); + if (runtime_option.backend != Backend::PDINFER) { + if (input_w != input_h || input_h < max_short || input_w < max_short) { + FDWARNING << "Detected LimitShort processing step in yaml file and " + "the size of input image is Unqualified, Fastdeploy " + "will resize the input image into (" + << max_short << "," << max_short << ")." << std::endl; + Resize::Run(mat, max_short, max_short); + } + } } if (!(*(processors_[i].get()))(mat)) { FDERROR << "Failed to process image data in " << processors_[i]->Name() << "." << std::endl; return false; } - if (processors_[i]->Name().compare("PadToSize") == 0) { - (*im_info)["pad_to_size"] = {static_cast(mat->Height()), - static_cast(mat->Width())}; - } if (processors_[i]->Name().compare("ResizeByLong") == 0) { (*im_info)["resize_by_long"] = {static_cast(mat->Height()), static_cast(mat->Width())}; @@ -174,7 +172,6 @@ bool PPMatting::Postprocess( // 先获取alpha并resize (使用opencv) auto iter_ipt = im_info.find("input_shape"); auto iter_out = im_info.find("output_shape"); - auto pad_to_size = im_info.find("output_shape"); auto resize_by_long = im_info.find("resize_by_long"); FDASSERT(iter_out != im_info.end() && iter_ipt != im_info.end(), "Cannot find input_shape or output_shape from im_info."); @@ -187,11 +184,9 @@ bool PPMatting::Postprocess( float* alpha_ptr = static_cast(alpha_tensor.Data()); cv::Mat alpha_zero_copy_ref(out_h, out_w, CV_32FC1, alpha_ptr); cv::Mat cropped_alpha; - if (pad_to_size != im_info.end() && resize_by_long != im_info.end()) { + if (resize_by_long != im_info.end()) { int resize_h = resize_by_long->second[0]; int resize_w = resize_by_long->second[1]; - int pad_h = pad_to_size->second[0]; - int pad_w = pad_to_size->second[1]; alpha_zero_copy_ref(cv::Rect(0, 0, resize_w, resize_h)) .copyTo(cropped_alpha); } else { diff --git a/examples/vision/matting/ppmatting/python/infer.py b/examples/vision/matting/ppmatting/python/infer.py index 04423802468..b60fcbc8200 100644 --- a/examples/vision/matting/ppmatting/python/infer.py +++ b/examples/vision/matting/ppmatting/python/infer.py @@ -34,11 +34,11 @@ def build_option(args): option = fd.RuntimeOption() if args.device.lower() == "gpu": option.use_gpu() - if args.use_trt: - option.use_trt_backend() - option.set_trt_input_shape("img", [1, 3, 512, 512]) - else: - option.use_paddle_backend() + option.use_paddle_backend() + + if args.use_trt: + option.use_trt_backend() + option.set_trt_input_shape("img", [1, 3, 512, 512]) return option diff --git a/external/paddle_inference.cmake b/external/paddle_inference.cmake index f4665180523..8d56e851633 100644 --- a/external/paddle_inference.cmake +++ b/external/paddle_inference.cmake @@ -47,7 +47,7 @@ else() endif(WIN32) set(PADDLEINFERENCE_URL_BASE "https://bj.bcebos.com/paddle2onnx/libs/") -set(PADDLEINFERENCE_VERSION "2.3.2") +set(PADDLEINFERENCE_VERSION "2.3.1") if(WIN32) if (WITH_GPU) set(PADDLEINFERENCE_FILE "paddle_inference-win-x64-gpu-${PADDLEINFERENCE_VERSION}.zip") From a75c0c4988aaa462df286d1b8ac5fc908f255c1d Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Fri, 21 Oct 2022 02:46:13 +0000 Subject: [PATCH 47/69] add python comments for external models --- docs/api_docs/python/face_detection.md | 34 +++++++ docs/api_docs/python/face_recognition.md | 41 +++++++++ docs/api_docs/python/index.rst | 3 + docs/api_docs/python/matting.md | 16 +++- docs/api_docs/python/object_detection.md | 90 +++++++++++++++++++ .../detection/contrib/yolov5lite_pybind.cc | 4 +- .../vision/detection/contrib/nanodet_plus.py | 32 +++++++ .../vision/detection/contrib/scaled_yolov4.py | 45 +++++++++- .../vision/detection/contrib/yolor.py | 45 +++++++++- .../vision/detection/contrib/yolov5.py | 51 +++++++++-- .../vision/detection/contrib/yolov5lite.py | 68 ++++++++++++-- .../vision/detection/contrib/yolov6.py | 48 ++++++++-- .../vision/detection/contrib/yolov7.py | 48 ++++++++-- .../detection/contrib/yolov7end2end_ort.py | 41 ++++++++- .../detection/contrib/yolov7end2end_trt.py | 44 +++++++-- .../vision/detection/contrib/yolox.py | 31 +++++++ .../vision/facedet/contrib/retinaface.py | 29 ++++++ .../vision/facedet/contrib/scrfd.py | 46 ++++++++-- .../vision/facedet/contrib/ultraface.py | 17 ++++ .../vision/facedet/contrib/yolov5face.py | 45 +++++++++- .../vision/faceid/contrib/adaface.py | 27 ++++++ .../vision/faceid/contrib/arcface.py | 27 ++++++ .../vision/faceid/contrib/cosface.py | 27 ++++++ .../vision/faceid/contrib/insightface_rec.py | 27 ++++++ .../vision/faceid/contrib/partial_fc.py | 27 ++++++ .../fastdeploy/vision/faceid/contrib/vpl.py | 27 ++++++ .../vision/matting/contrib/modnet.py | 24 +++++ .../vision/matting/ppmatting/__init__.py | 13 +++ 28 files changed, 917 insertions(+), 60 deletions(-) create mode 100644 docs/api_docs/python/face_detection.md create mode 100644 docs/api_docs/python/face_recognition.md diff --git a/docs/api_docs/python/face_detection.md b/docs/api_docs/python/face_detection.md new file mode 100644 index 00000000000..3e8d5762ca8 --- /dev/null +++ b/docs/api_docs/python/face_detection.md @@ -0,0 +1,34 @@ +# Face Detection API + +## fastdeploy.vision.facedet.RetinaFace + +```{eval-rst} +.. autoclass:: fastdeploy.vision.facedet.RetinaFace + :members: + :inherited-members: +``` + + +## fastdeploy.vision.facedet.SCRFD + +```{eval-rst} +.. autoclass:: fastdeploy.vision.facedet.SCRFD + :members: + :inherited-members: +``` + +## fastdeploy.vision.facedet.UltraFace + +```{eval-rst} +.. autoclass:: fastdeploy.vision.facedet.UltraFace + :members: + :inherited-members: +``` + +## fastdeploy.vision.facedet.YOLOv5Face + +```{eval-rst} +.. autoclass:: fastdeploy.vision.facedet.YOLOv5Face + :members: + :inherited-members: +``` diff --git a/docs/api_docs/python/face_recognition.md b/docs/api_docs/python/face_recognition.md new file mode 100644 index 00000000000..344aab79687 --- /dev/null +++ b/docs/api_docs/python/face_recognition.md @@ -0,0 +1,41 @@ +# Face Recognition API + +## fastdeploy.vision.faceid.AdaFace + +```{eval-rst} +.. autoclass:: fastdeploy.vision.faceid.AdaFace + :members: + :inherited-members: +``` + +## fastdeploy.vision.faceid.CosFace + +```{eval-rst} +.. autoclass:: fastdeploy.vision.faceid.CosFace + :members: + :inherited-members: +``` + +## fastdeploy.vision.faceid.ArcFace + +```{eval-rst} +.. autoclass:: fastdeploy.vision.faceid.ArcFace + :members: + :inherited-members: +``` + +## fastdeploy.vision.faceid.PartialFC + +```{eval-rst} +.. autoclass:: fastdeploy.vision.faceid.PartialFC + :members: + :inherited-members: +``` + +## fastdeploy.vision.faceid.VPL + +```{eval-rst} +.. autoclass:: fastdeploy.vision.faceid.VPL + :members: + :inherited-members: +``` diff --git a/docs/api_docs/python/index.rst b/docs/api_docs/python/index.rst index 5761cd3a511..7fa5e501e1a 100644 --- a/docs/api_docs/python/index.rst +++ b/docs/api_docs/python/index.rst @@ -18,3 +18,6 @@ FastDeploy image_classification.md keypoint_detection.md matting.md + face_recognition.md + face_detection.md + diff --git a/docs/api_docs/python/matting.md b/docs/api_docs/python/matting.md index 174f00cc6fc..7c121110acb 100644 --- a/docs/api_docs/python/matting.md +++ b/docs/api_docs/python/matting.md @@ -1,3 +1,17 @@ # Matting API -comming soon... +## fastdeploy.vision.matting.MODNet + +```{eval-rst} +.. autoclass:: fastdeploy.vision.matting.MODNet + :members: + :inherited-members: +``` + +## fastdeploy.vision.matting.PPMatting + +```{eval-rst} +.. autoclass:: fastdeploy.vision.matting.PPMatting + :members: + :inherited-members: +``` diff --git a/docs/api_docs/python/object_detection.md b/docs/api_docs/python/object_detection.md index e3d50fcb3eb..6bab167cf06 100644 --- a/docs/api_docs/python/object_detection.md +++ b/docs/api_docs/python/object_detection.md @@ -63,3 +63,93 @@ :members: :inherited-members: ``` + +## fastdeploy.vision.detection.NanoDetPlus + +```{eval-rst} +.. autoclass:: fastdeploy.vision.detection.NanoDetPlus + :members: + :inherited-members: +``` + +## fastdeploy.vision.detection.ScaledYOLOv4 + +```{eval-rst} +.. autoclass:: fastdeploy.vision.detection.ScaledYOLOv4 + :members: + :inherited-members: +``` + +## fastdeploy.vision.detection.YOLOR + +```{eval-rst} +.. autoclass:: fastdeploy.vision.detection.YOLOR + :members: + :inherited-members: +``` + +## fastdeploy.vision.detection.YOLOv5 + +```{eval-rst} +.. autoclass:: fastdeploy.vision.detection.YOLOv5 + :members: + :inherited-members: +``` + +## fastdeploy.vision.detection.YOLOv5Lite + +```{eval-rst} +.. autoclass:: fastdeploy.vision.detection.YOLOv5Lite + :members: + :inherited-members: +``` + +## fastdeploy.vision.detection.YOLOv6 + +```{eval-rst} +.. autoclass:: fastdeploy.vision.detection.YOLOv6 + :members: + :inherited-members: +``` + +## fastdeploy.vision.detection.YOLOv7 + +```{eval-rst} +.. autoclass:: fastdeploy.vision.detection.YOLOv7 + :members: + :inherited-members: +``` + + +## fastdeploy.vision.detection.YOLOR + +```{eval-rst} +.. autoclass:: fastdeploy.vision.detection.YOLOR + :members: + :inherited-members: +``` + + +## fastdeploy.vision.detection.YOLOv7End2EndORT + +```{eval-rst} +.. autoclass:: fastdeploy.vision.detection.YOLOv7End2EndORT + :members: + :inherited-members: +``` + +## fastdeploy.vision.detection.YOLOv7End2EndTRT + +```{eval-rst} +.. autoclass:: fastdeploy.vision.detection.YOLOv7End2EndTRT + :members: + :inherited-members: +``` + +## fastdeploy.vision.detection.YOLOX + +```{eval-rst} +.. autoclass:: fastdeploy.vision.detection.YOLOX + :members: + :inherited-members: +``` diff --git a/fastdeploy/vision/detection/contrib/yolov5lite_pybind.cc b/fastdeploy/vision/detection/contrib/yolov5lite_pybind.cc index cdd20f16989..b4f765e235a 100644 --- a/fastdeploy/vision/detection/contrib/yolov5lite_pybind.cc +++ b/fastdeploy/vision/detection/contrib/yolov5lite_pybind.cc @@ -31,10 +31,12 @@ void BindYOLOv5Lite(pybind11::module& m) { .def("use_cuda_preprocessing", [](vision::detection::YOLOv5Lite& self, int max_image_size) { self.UseCudaPreprocessing(max_image_size); - }) + }) .def_readwrite("size", &vision::detection::YOLOv5Lite::size) .def_readwrite("padding_value", &vision::detection::YOLOv5Lite::padding_value) + .def_readwrite("downsample_strides", + &vision::detection::YOLOv5Lite::downsample_strides) .def_readwrite("is_mini_pad", &vision::detection::YOLOv5Lite::is_mini_pad) .def_readwrite("is_no_pad", &vision::detection::YOLOv5Lite::is_no_pad) .def_readwrite("is_scale_up", &vision::detection::YOLOv5Lite::is_scale_up) diff --git a/python/fastdeploy/vision/detection/contrib/nanodet_plus.py b/python/fastdeploy/vision/detection/contrib/nanodet_plus.py index a46dd7a9e66..00693335fb3 100644 --- a/python/fastdeploy/vision/detection/contrib/nanodet_plus.py +++ b/python/fastdeploy/vision/detection/contrib/nanodet_plus.py @@ -24,6 +24,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a NanoDetPlus model exported by NanoDet. + + :param model_file: (str)Path of model file, e.g ./nanodet.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(NanoDetPlus, self).__init__(runtime_option) @@ -34,6 +41,13 @@ def __init__(self, assert self.initialized, "NanoDetPlus initialize failed." def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): + """Detect an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :param conf_threshold: confidence threashold for postprocessing, default is 0.25 + :param nms_iou_threshold: iou threashold for NMS, default is 0.5 + :return: DetectionResult + """ return self._model.predict(input_image, conf_threshold, nms_iou_threshold) @@ -41,26 +55,44 @@ def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): # 多数是预处理相关,可通过修改如model.size = [416, 416]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def padding_value(self): + """ + padding value, size should be the same as channels + """ return self._model.padding_value @property def keep_ratio(self): + """ + keep aspect ratio or not when perform resize operation. This option is set as false by default in NanoDet-Plus + """ return self._model.keep_ratio @property def downsample_strides(self): + """ + downsample strides for NanoDet-Plus to generate anchors, will take (8, 16, 32, 64) as default values + """ return self._model.downsample_strides @property def max_wh(self): + """ + for offseting the boxes by classes when using NMS, default 4096 + """ return self._model.max_wh @property def reg_max(self): + """ + reg_max for GFL regression, default 7 + """ return self._model.reg_max @size.setter diff --git a/python/fastdeploy/vision/detection/contrib/scaled_yolov4.py b/python/fastdeploy/vision/detection/contrib/scaled_yolov4.py index aebb60fb006..921ee0375e2 100644 --- a/python/fastdeploy/vision/detection/contrib/scaled_yolov4.py +++ b/python/fastdeploy/vision/detection/contrib/scaled_yolov4.py @@ -24,6 +24,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a ScaledYOLOv4 model exported by ScaledYOLOv4. + + :param model_file: (str)Path of model file, e.g ./scaled_yolov4.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(ScaledYOLOv4, self).__init__(runtime_option) @@ -34,6 +41,13 @@ def __init__(self, assert self.initialized, "ScaledYOLOv4 initialize failed." def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): + """Detect an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :param conf_threshold: confidence threashold for postprocessing, default is 0.25 + :param nms_iou_threshold: iou threashold for NMS, default is 0.5 + :return: DetectionResult + """ return self._model.predict(input_image, conf_threshold, nms_iou_threshold) @@ -41,30 +55,51 @@ def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): # 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def padding_value(self): + """ + padding value, size should be the same as channels + """ return self._model.padding_value @property def is_no_pad(self): + """ + while is_mini_pad = false and is_no_pad = true, will resize the image to the set size + """ return self._model.is_no_pad @property def is_mini_pad(self): + """ + only pad to the minimum rectange which height and width is times of stride + """ return self._model.is_mini_pad @property def is_scale_up(self): + """ + if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 + """ return self._model.is_scale_up @property def stride(self): + """ + padding stride, for is_mini_pad + """ return self._model.stride @property def max_wh(self): + """ + for offseting the boxes by classes when using NMS + """ return self._model.max_wh @size.setter @@ -92,19 +127,21 @@ def is_no_pad(self, value): @is_mini_pad.setter def is_mini_pad(self, value): assert isinstance( - value, bool), "The value to set `is_mini_pad` must be type of bool." + value, + bool), "The value to set `is_mini_pad` must be type of bool." self._model.is_mini_pad = value @is_scale_up.setter def is_scale_up(self, value): assert isinstance( - value, bool), "The value to set `is_scale_up` must be type of bool." + value, + bool), "The value to set `is_scale_up` must be type of bool." self._model.is_scale_up = value @stride.setter def stride(self, value): - assert isinstance(value, - int), "The value to set `stride` must be type of int." + assert isinstance( + value, int), "The value to set `stride` must be type of int." self._model.stride = value @max_wh.setter diff --git a/python/fastdeploy/vision/detection/contrib/yolor.py b/python/fastdeploy/vision/detection/contrib/yolor.py index 0545076128e..70e69aa9dd0 100644 --- a/python/fastdeploy/vision/detection/contrib/yolor.py +++ b/python/fastdeploy/vision/detection/contrib/yolor.py @@ -24,6 +24,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a YOLOR model exported by YOLOR + + :param model_file: (str)Path of model file, e.g ./yolor.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(YOLOR, self).__init__(runtime_option) @@ -34,6 +41,13 @@ def __init__(self, assert self.initialized, "YOLOR initialize failed." def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): + """Detect an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :param conf_threshold: confidence threashold for postprocessing, default is 0.25 + :param nms_iou_threshold: iou threashold for NMS, default is 0.5 + :return: DetectionResult + """ return self._model.predict(input_image, conf_threshold, nms_iou_threshold) @@ -41,30 +55,51 @@ def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): # 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def padding_value(self): + """ + padding value, size should be the same as channels + """ return self._model.padding_value @property def is_no_pad(self): + """ + while is_mini_pad = false and is_no_pad = true, will resize the image to the set size + """ return self._model.is_no_pad @property def is_mini_pad(self): + """ + only pad to the minimum rectange which height and width is times of stride + """ return self._model.is_mini_pad @property def is_scale_up(self): + """ + if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 + """ return self._model.is_scale_up @property def stride(self): + """ + padding stride, for is_mini_pad + """ return self._model.stride @property def max_wh(self): + """ + for offseting the boxes by classes when using NMS + """ return self._model.max_wh @size.setter @@ -92,19 +127,21 @@ def is_no_pad(self, value): @is_mini_pad.setter def is_mini_pad(self, value): assert isinstance( - value, bool), "The value to set `is_mini_pad` must be type of bool." + value, + bool), "The value to set `is_mini_pad` must be type of bool." self._model.is_mini_pad = value @is_scale_up.setter def is_scale_up(self, value): assert isinstance( - value, bool), "The value to set `is_scale_up` must be type of bool." + value, + bool), "The value to set `is_scale_up` must be type of bool." self._model.is_scale_up = value @stride.setter def stride(self, value): - assert isinstance(value, - int), "The value to set `stride` must be type of int." + assert isinstance( + value, int), "The value to set `stride` must be type of int." self._model.stride = value @max_wh.setter diff --git a/python/fastdeploy/vision/detection/contrib/yolov5.py b/python/fastdeploy/vision/detection/contrib/yolov5.py index 9fdd2b77ec8..d59690b8be9 100644 --- a/python/fastdeploy/vision/detection/contrib/yolov5.py +++ b/python/fastdeploy/vision/detection/contrib/yolov5.py @@ -24,6 +24,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a YOLOv5 model exported by YOLOv5. + + :param model_file: (str)Path of model file, e.g ./yolov5.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(YOLOv5, self).__init__(runtime_option) @@ -34,12 +41,16 @@ def __init__(self, assert self.initialized, "YOLOv5 initialize failed." def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): + """Detect an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :param conf_threshold: confidence threashold for postprocessing, default is 0.25 + :param nms_iou_threshold: iou threashold for NMS, default is 0.5 + :return: DetectionResult + """ return self._model.predict(input_image, conf_threshold, nms_iou_threshold) - def use_cuda_preprocessing(self, max_image_size=3840 * 2160): - return self._model.use_cuda_preprocessing(max_image_size) - @staticmethod def preprocess(input_image, size=[640, 640], @@ -69,30 +80,51 @@ def postprocess(infer_result, # 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def padding_value(self): + """ + padding value, size should be the same as channels + """ return self._model.padding_value @property def is_no_pad(self): + """ + while is_mini_pad = false and is_no_pad = true, will resize the image to the set size + """ return self._model.is_no_pad @property def is_mini_pad(self): + """ + only pad to the minimum rectange which height and width is times of stride + """ return self._model.is_mini_pad @property def is_scale_up(self): + """ + if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 + """ return self._model.is_scale_up @property def stride(self): + """ + padding stride, for is_mini_pad + """ return self._model.stride @property def max_wh(self): + """ + for offseting the boxes by classes when using NMS + """ return self._model.max_wh @property @@ -124,19 +156,21 @@ def is_no_pad(self, value): @is_mini_pad.setter def is_mini_pad(self, value): assert isinstance( - value, bool), "The value to set `is_mini_pad` must be type of bool." + value, + bool), "The value to set `is_mini_pad` must be type of bool." self._model.is_mini_pad = value @is_scale_up.setter def is_scale_up(self, value): assert isinstance( - value, bool), "The value to set `is_scale_up` must be type of bool." + value, + bool), "The value to set `is_scale_up` must be type of bool." self._model.is_scale_up = value @stride.setter def stride(self, value): - assert isinstance(value, - int), "The value to set `stride` must be type of int." + assert isinstance( + value, int), "The value to set `stride` must be type of int." self._model.stride = value @max_wh.setter @@ -148,5 +182,6 @@ def max_wh(self, value): @multi_label.setter def multi_label(self, value): assert isinstance( - value, bool), "The value to set `multi_label` must be type of bool." + value, + bool), "The value to set `multi_label` must be type of bool." self._model.multi_label = value diff --git a/python/fastdeploy/vision/detection/contrib/yolov5lite.py b/python/fastdeploy/vision/detection/contrib/yolov5lite.py index f5027774047..8b26548e582 100644 --- a/python/fastdeploy/vision/detection/contrib/yolov5lite.py +++ b/python/fastdeploy/vision/detection/contrib/yolov5lite.py @@ -24,6 +24,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a YOLOv5Lite model exported by YOLOv5Lite. + + :param model_file: (str)Path of model file, e.g ./yolov5lite.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(YOLOv5Lite, self).__init__(runtime_option) @@ -34,50 +41,88 @@ def __init__(self, assert self.initialized, "YOLOv5Lite initialize failed." def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): + """Detect an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :param conf_threshold: confidence threashold for postprocessing, default is 0.25 + :param nms_iou_threshold: iou threashold for NMS, default is 0.5 + :return: DetectionResult + """ return self._model.predict(input_image, conf_threshold, nms_iou_threshold) - def use_cuda_preprocessing(self, max_image_size=3840 * 2160): - return self._model.use_cuda_preprocessing(max_image_size) - # 一些跟YOLOv5Lite模型有关的属性封装 # 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def padding_value(self): + """ + padding value, size should be the same as channels + """ return self._model.padding_value @property def is_no_pad(self): + """ + while is_mini_pad = false and is_no_pad = true, will resize the image to the set size + """ return self._model.is_no_pad @property def is_mini_pad(self): + """ + only pad to the minimum rectange which height and width is times of stride + """ return self._model.is_mini_pad @property def is_scale_up(self): + """ + if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 + """ return self._model.is_scale_up @property def stride(self): + """ + padding stride, for is_mini_pad + """ return self._model.stride @property def max_wh(self): + """ + for offseting the boxes by classes when using NMS + """ return self._model.max_wh @property def is_decode_exported(self): + """ + whether the model_file was exported with decode module. + The official YOLOv5Lite/export.py script will export ONNX file without decode module. + Please set it 'true' manually if the model file was exported with decode module. + false : ONNX files without decode module. true : ONNX file with decode module. + """ return self._model.is_decode_exported @property def anchor_config(self): return self._model.anchor_config + @property + def downsample_strides(self): + """ + downsample strides for YOLOv5Lite to generate anchors, will take (8,16,32) as default values, might have stride=64. + """ + return self._model.downsample_strides + @size.setter def size(self, wh): assert isinstance(wh, (list, tuple)),\ @@ -103,19 +148,21 @@ def is_no_pad(self, value): @is_mini_pad.setter def is_mini_pad(self, value): assert isinstance( - value, bool), "The value to set `is_mini_pad` must be type of bool." + value, + bool), "The value to set `is_mini_pad` must be type of bool." self._model.is_mini_pad = value @is_scale_up.setter def is_scale_up(self, value): assert isinstance( - value, bool), "The value to set `is_scale_up` must be type of bool." + value, + bool), "The value to set `is_scale_up` must be type of bool." self._model.is_scale_up = value @stride.setter def stride(self, value): - assert isinstance(value, - int), "The value to set `stride` must be type of int." + assert isinstance( + value, int), "The value to set `stride` must be type of int." self._model.stride = value @max_wh.setter @@ -138,3 +185,10 @@ def anchor_config(self, anchor_config_val): assert isinstance(anchor_config_val[0], list),\ "The value to set `anchor_config` must be 2-dimensions tuple or list" self._model.anchor_config = anchor_config_val + + @downsample_strides.setter + def downsample_strides(self, value): + assert isinstance( + value, + list), "The value to set `downsample_strides` must be type of list." + self._model.downsample_strides = value diff --git a/python/fastdeploy/vision/detection/contrib/yolov6.py b/python/fastdeploy/vision/detection/contrib/yolov6.py index 5e09de4d6ac..2c7f1df1574 100644 --- a/python/fastdeploy/vision/detection/contrib/yolov6.py +++ b/python/fastdeploy/vision/detection/contrib/yolov6.py @@ -24,6 +24,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a YOLOv6 model exported by YOLOv6. + + :param model_file: (str)Path of model file, e.g ./yolov6.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(YOLOv6, self).__init__(runtime_option) @@ -34,40 +41,65 @@ def __init__(self, assert self.initialized, "YOLOv6 initialize failed." def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): + """Detect an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :param conf_threshold: confidence threashold for postprocessing, default is 0.25 + :param nms_iou_threshold: iou threashold for NMS, default is 0.5 + :return: DetectionResult + """ return self._model.predict(input_image, conf_threshold, nms_iou_threshold) - def use_cuda_preprocessing(self, max_image_size=3840 * 2160): - return self._model.use_cuda_preprocessing(max_image_size) - # 一些跟YOLOv6模型有关的属性封装 # 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def padding_value(self): + """ + padding value, size should be the same as channels + """ return self._model.padding_value @property def is_no_pad(self): + """ + while is_mini_pad = false and is_no_pad = true, will resize the image to the set size + """ return self._model.is_no_pad @property def is_mini_pad(self): + """ + only pad to the minimum rectange which height and width is times of stride + """ return self._model.is_mini_pad @property def is_scale_up(self): + """ + if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 + """ return self._model.is_scale_up @property def stride(self): + """ + padding stride, for is_mini_pad + """ return self._model.stride @property def max_wh(self): + """ + for offseting the boxes by classes when using NMS + """ return self._model.max_wh @size.setter @@ -95,19 +127,21 @@ def is_no_pad(self, value): @is_mini_pad.setter def is_mini_pad(self, value): assert isinstance( - value, bool), "The value to set `is_mini_pad` must be type of bool." + value, + bool), "The value to set `is_mini_pad` must be type of bool." self._model.is_mini_pad = value @is_scale_up.setter def is_scale_up(self, value): assert isinstance( - value, bool), "The value to set `is_scale_up` must be type of bool." + value, + bool), "The value to set `is_scale_up` must be type of bool." self._model.is_scale_up = value @stride.setter def stride(self, value): - assert isinstance(value, - int), "The value to set `stride` must be type of int." + assert isinstance( + value, int), "The value to set `stride` must be type of int." self._model.stride = value @max_wh.setter diff --git a/python/fastdeploy/vision/detection/contrib/yolov7.py b/python/fastdeploy/vision/detection/contrib/yolov7.py index a102fd83ae5..e22a1841cfa 100644 --- a/python/fastdeploy/vision/detection/contrib/yolov7.py +++ b/python/fastdeploy/vision/detection/contrib/yolov7.py @@ -24,6 +24,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a YOLOv7 model exported by YOLOv7. + + :param model_file: (str)Path of model file, e.g ./yolov7.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(YOLOv7, self).__init__(runtime_option) @@ -34,40 +41,65 @@ def __init__(self, assert self.initialized, "YOLOv7 initialize failed." def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): + """Detect an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :param conf_threshold: confidence threashold for postprocessing, default is 0.25 + :param nms_iou_threshold: iou threashold for NMS, default is 0.5 + :return: DetectionResult + """ return self._model.predict(input_image, conf_threshold, nms_iou_threshold) - def use_cuda_preprocessing(self, max_image_size=3840 * 2160): - return self._model.use_cuda_preprocessing(max_image_size) - # 一些跟YOLOv7模型有关的属性封装 # 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def padding_value(self): + """ + padding value, size should be the same as channels + """ return self._model.padding_value @property def is_no_pad(self): + """ + while is_mini_pad = false and is_no_pad = true, will resize the image to the set size + """ return self._model.is_no_pad @property def is_mini_pad(self): + """ + only pad to the minimum rectange which height and width is times of stride + """ return self._model.is_mini_pad @property def is_scale_up(self): + """ + if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 + """ return self._model.is_scale_up @property def stride(self): + """ + padding stride, for is_mini_pad + """ return self._model.stride @property def max_wh(self): + """ + for offseting the boxes by classes when using NMS + """ return self._model.max_wh @size.setter @@ -95,19 +127,21 @@ def is_no_pad(self, value): @is_mini_pad.setter def is_mini_pad(self, value): assert isinstance( - value, bool), "The value to set `is_mini_pad` must be type of bool." + value, + bool), "The value to set `is_mini_pad` must be type of bool." self._model.is_mini_pad = value @is_scale_up.setter def is_scale_up(self, value): assert isinstance( - value, bool), "The value to set `is_scale_up` must be type of bool." + value, + bool), "The value to set `is_scale_up` must be type of bool." self._model.is_scale_up = value @stride.setter def stride(self, value): - assert isinstance(value, - int), "The value to set `stride` must be type of int." + assert isinstance( + value, int), "The value to set `stride` must be type of int." self._model.stride = value @max_wh.setter diff --git a/python/fastdeploy/vision/detection/contrib/yolov7end2end_ort.py b/python/fastdeploy/vision/detection/contrib/yolov7end2end_ort.py index 41b79f78624..de776199757 100644 --- a/python/fastdeploy/vision/detection/contrib/yolov7end2end_ort.py +++ b/python/fastdeploy/vision/detection/contrib/yolov7end2end_ort.py @@ -24,6 +24,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a YOLOv7End2EndORT model exported by YOLOv7. + + :param model_file: (str)Path of model file, e.g ./yolov7end2end_ort.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(YOLOv7End2EndORT, self).__init__(runtime_option) @@ -34,32 +41,56 @@ def __init__(self, assert self.initialized, "YOLOv7End2End initialize failed." def predict(self, input_image, conf_threshold=0.25): + """Detect an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :param conf_threshold: confidence threashold for postprocessing, default is 0.25 + :return: DetectionResult + """ return self._model.predict(input_image, conf_threshold) # 一些跟模型有关的属性封装 # 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def padding_value(self): + """ + padding value, size should be the same as channels + """ return self._model.padding_value @property def is_no_pad(self): + """ + while is_mini_pad = false and is_no_pad = true, will resize the image to the set size + """ return self._model.is_no_pad @property def is_mini_pad(self): + """ + only pad to the minimum rectange which height and width is times of stride + """ return self._model.is_mini_pad @property def is_scale_up(self): + """ + if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 + """ return self._model.is_scale_up @property def stride(self): + """ + padding stride, for is_mini_pad + """ return self._model.stride @size.setter @@ -87,17 +118,19 @@ def is_no_pad(self, value): @is_mini_pad.setter def is_mini_pad(self, value): assert isinstance( - value, bool), "The value to set `is_mini_pad` must be type of bool." + value, + bool), "The value to set `is_mini_pad` must be type of bool." self._model.is_mini_pad = value @is_scale_up.setter def is_scale_up(self, value): assert isinstance( - value, bool), "The value to set `is_scale_up` must be type of bool." + value, + bool), "The value to set `is_scale_up` must be type of bool." self._model.is_scale_up = value @stride.setter def stride(self, value): - assert isinstance(value, - int), "The value to set `stride` must be type of int." + assert isinstance( + value, int), "The value to set `stride` must be type of int." self._model.stride = value diff --git a/python/fastdeploy/vision/detection/contrib/yolov7end2end_trt.py b/python/fastdeploy/vision/detection/contrib/yolov7end2end_trt.py index d0c2e90ac1a..3ee084273f6 100644 --- a/python/fastdeploy/vision/detection/contrib/yolov7end2end_trt.py +++ b/python/fastdeploy/vision/detection/contrib/yolov7end2end_trt.py @@ -24,6 +24,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a YOLOv7End2EndTRT model exported by YOLOv7. + + :param model_file: (str)Path of model file, e.g ./yolov7end2end_trt.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(YOLOv7End2EndTRT, self).__init__(runtime_option) @@ -34,35 +41,56 @@ def __init__(self, assert self.initialized, "YOLOv7End2EndTRT initialize failed." def predict(self, input_image, conf_threshold=0.25): - return self._model.predict(input_image, conf_threshold) + """Detect an input image - def use_cuda_preprocessing(self, max_image_size=3840 * 2160): - return self._model.use_cuda_preprocessing(max_image_size) + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :param conf_threshold: confidence threashold for postprocessing, default is 0.25 + :return: DetectionResult + """ + return self._model.predict(input_image, conf_threshold) # 一些跟模型有关的属性封装 # 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def padding_value(self): + """ + padding value, size should be the same as channels + """ return self._model.padding_value @property def is_no_pad(self): + """ + while is_mini_pad = false and is_no_pad = true, will resize the image to the set size + """ return self._model.is_no_pad @property def is_mini_pad(self): + """ + only pad to the minimum rectange which height and width is times of stride + """ return self._model.is_mini_pad @property def is_scale_up(self): + """ + if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 + """ return self._model.is_scale_up @property def stride(self): + """ + padding stride, for is_mini_pad + """ return self._model.stride @size.setter @@ -90,17 +118,19 @@ def is_no_pad(self, value): @is_mini_pad.setter def is_mini_pad(self, value): assert isinstance( - value, bool), "The value to set `is_mini_pad` must be type of bool." + value, + bool), "The value to set `is_mini_pad` must be type of bool." self._model.is_mini_pad = value @is_scale_up.setter def is_scale_up(self, value): assert isinstance( - value, bool), "The value to set `is_scale_up` must be type of bool." + value, + bool), "The value to set `is_scale_up` must be type of bool." self._model.is_scale_up = value @stride.setter def stride(self, value): - assert isinstance(value, - int), "The value to set `stride` must be type of int." + assert isinstance( + value, int), "The value to set `stride` must be type of int." self._model.stride = value diff --git a/python/fastdeploy/vision/detection/contrib/yolox.py b/python/fastdeploy/vision/detection/contrib/yolox.py index e7f0da1aad8..0d643a4b377 100644 --- a/python/fastdeploy/vision/detection/contrib/yolox.py +++ b/python/fastdeploy/vision/detection/contrib/yolox.py @@ -24,6 +24,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a YOLOX model exported by YOLOX. + + :param model_file: (str)Path of model file, e.g ./yolox.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(YOLOX, self).__init__(runtime_option) @@ -34,6 +41,13 @@ def __init__(self, assert self.initialized, "YOLOX initialize failed." def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): + """Detect an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :param conf_threshold: confidence threashold for postprocessing, default is 0.25 + :param nms_iou_threshold: iou threashold for NMS, default is 0.5 + :return: DetectionResult + """ return self._model.predict(input_image, conf_threshold, nms_iou_threshold) @@ -41,22 +55,39 @@ def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): # 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def padding_value(self): + """ + padding value, size should be the same as channels + """ return self._model.padding_value @property def is_decode_exported(self): + """ + whether the model_file was exported with decode module. + The official YOLOX/tools/export_onnx.py script will export ONNX file without decode module. + Please set it 'true' manually if the model file was exported with decode module. + """ return self._model.is_decode_exported @property def downsample_strides(self): + """ + downsample strides for YOLOX to generate anchors, will take (8,16,32) as default values, might have stride=64. + """ return self._model.downsample_strides @property def max_wh(self): + """ + for offseting the boxes by classes when using NMS + """ return self._model.max_wh @size.setter diff --git a/python/fastdeploy/vision/facedet/contrib/retinaface.py b/python/fastdeploy/vision/facedet/contrib/retinaface.py index 88eb3ccb368..e959f5af381 100644 --- a/python/fastdeploy/vision/facedet/contrib/retinaface.py +++ b/python/fastdeploy/vision/facedet/contrib/retinaface.py @@ -24,6 +24,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a RetinaFace model exported by RetinaFace. + + :param model_file: (str)Path of model file, e.g ./retinaface.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(RetinaFace, self).__init__(runtime_option) @@ -34,6 +41,13 @@ def __init__(self, assert self.initialized, "RetinaFace initialize failed." def predict(self, input_image, conf_threshold=0.7, nms_iou_threshold=0.3): + """Detect the location and key points of human faces from an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :param conf_threshold: confidence threashold for postprocessing, default is 0.7 + :param nms_iou_threshold: iou threashold for NMS, default is 0.3 + :return: FaceDetectionResult + """ return self._model.predict(input_image, conf_threshold, nms_iou_threshold) @@ -41,22 +55,37 @@ def predict(self, input_image, conf_threshold=0.7, nms_iou_threshold=0.3): # 多数是预处理相关,可通过修改如model.size = [640, 480]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def variance(self): + """ + variance in RetinaFace's prior-box(anchor) generate process, default (0.1, 0.2) + """ return self._model.variance @property def downsample_strides(self): + """ + downsample strides (namely, steps) for RetinaFace to generate anchors, will take (8,16,32) as default values + """ return self._model.downsample_strides @property def min_sizes(self): + """ + min sizes, width and height for each anchor + """ return self._model.min_sizes @property def landmarks_per_face(self): + """ + landmarks_per_face, default 5 in RetinaFace + """ return self._model.landmarks_per_face @size.setter diff --git a/python/fastdeploy/vision/facedet/contrib/scrfd.py b/python/fastdeploy/vision/facedet/contrib/scrfd.py index bdf4ea08eb6..85afd9e81d1 100644 --- a/python/fastdeploy/vision/facedet/contrib/scrfd.py +++ b/python/fastdeploy/vision/facedet/contrib/scrfd.py @@ -24,16 +24,30 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a SCRFD model exported by SCRFD. + + :param model_file: (str)Path of model file, e.g ./scrfd.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(SCRFD, self).__init__(runtime_option) - self._model = C.vision.facedet.SCRFD(model_file, params_file, - self._runtime_option, model_format) + self._model = C.vision.facedet.SCRFD( + model_file, params_file, self._runtime_option, model_format) # 通过self.initialized判断整个模型的初始化是否成功 assert self.initialized, "SCRFD initialize failed." def predict(self, input_image, conf_threshold=0.7, nms_iou_threshold=0.3): + """Detect the location and key points of human faces from an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :param conf_threshold: confidence threashold for postprocessing, default is 0.7 + :param nms_iou_threshold: iou threashold for NMS, default is 0.3 + :return: FaceDetectionResult + """ return self._model.predict(input_image, conf_threshold, nms_iou_threshold) @@ -41,26 +55,44 @@ def predict(self, input_image, conf_threshold=0.7, nms_iou_threshold=0.3): # 多数是预处理相关,可通过修改如model.size = [640, 640]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def padding_value(self): + """ + padding value, size should be the same as channels + """ return self._model.padding_value @property def is_no_pad(self): + """ + while is_mini_pad = false and is_no_pad = true, will resize the image to the set size + """ return self._model.is_no_pad @property def is_mini_pad(self): + """ + only pad to the minimum rectange which height and width is times of stride + """ return self._model.is_mini_pad @property def is_scale_up(self): + """ + if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 + """ return self._model.is_scale_up @property def stride(self): + """ + padding stride, for is_mini_pad + """ return self._model.stride @property @@ -108,19 +140,21 @@ def is_no_pad(self, value): @is_mini_pad.setter def is_mini_pad(self, value): assert isinstance( - value, bool), "The value to set `is_mini_pad` must be type of bool." + value, + bool), "The value to set `is_mini_pad` must be type of bool." self._model.is_mini_pad = value @is_scale_up.setter def is_scale_up(self, value): assert isinstance( - value, bool), "The value to set `is_scale_up` must be type of bool." + value, + bool), "The value to set `is_scale_up` must be type of bool." self._model.is_scale_up = value @stride.setter def stride(self, value): - assert isinstance(value, - int), "The value to set `stride` must be type of int." + assert isinstance( + value, int), "The value to set `stride` must be type of int." self._model.stride = value @downsample_strides.setter diff --git a/python/fastdeploy/vision/facedet/contrib/ultraface.py b/python/fastdeploy/vision/facedet/contrib/ultraface.py index 3228833db12..5b592d34d0a 100644 --- a/python/fastdeploy/vision/facedet/contrib/ultraface.py +++ b/python/fastdeploy/vision/facedet/contrib/ultraface.py @@ -24,6 +24,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a UltraFace model exported by UltraFace. + + :param model_file: (str)Path of model file, e.g ./ultraface.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(UltraFace, self).__init__(runtime_option) @@ -34,6 +41,13 @@ def __init__(self, assert self.initialized, "UltraFace initialize failed." def predict(self, input_image, conf_threshold=0.7, nms_iou_threshold=0.3): + """Detect the location and key points of human faces from an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :param conf_threshold: confidence threashold for postprocessing, default is 0.7 + :param nms_iou_threshold: iou threashold for NMS, default is 0.3 + :return: FaceDetectionResult + """ return self._model.predict(input_image, conf_threshold, nms_iou_threshold) @@ -41,6 +55,9 @@ def predict(self, input_image, conf_threshold=0.7, nms_iou_threshold=0.3): # 多数是预处理相关,可通过修改如model.size = [640, 480]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @size.setter diff --git a/python/fastdeploy/vision/facedet/contrib/yolov5face.py b/python/fastdeploy/vision/facedet/contrib/yolov5face.py index 7fd294b3a8f..13d5ea9e154 100644 --- a/python/fastdeploy/vision/facedet/contrib/yolov5face.py +++ b/python/fastdeploy/vision/facedet/contrib/yolov5face.py @@ -24,6 +24,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a YOLOv5Face model exported by YOLOv5Face. + + :param model_file: (str)Path of model file, e.g ./yolov5face.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(YOLOv5Face, self).__init__(runtime_option) @@ -34,6 +41,13 @@ def __init__(self, assert self.initialized, "YOLOv5Face initialize failed." def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): + """Detect the location and key points of human faces from an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :param conf_threshold: confidence threashold for postprocessing, default is 0.25 + :param nms_iou_threshold: iou threashold for NMS, default is 0.5 + :return: FaceDetectionResult + """ return self._model.predict(input_image, conf_threshold, nms_iou_threshold) @@ -41,30 +55,51 @@ def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): # 多数是预处理相关,可通过修改如model.size = [1280, 1280]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def padding_value(self): + """ + padding value, size should be the same as channels + """ return self._model.padding_value @property def is_no_pad(self): + """ + while is_mini_pad = false and is_no_pad = true, will resize the image to the set size + """ return self._model.is_no_pad @property def is_mini_pad(self): + """ + only pad to the minimum rectange which height and width is times of stride + """ return self._model.is_mini_pad @property def is_scale_up(self): + """ + if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 + """ return self._model.is_scale_up @property def stride(self): + """ + padding stride, for is_mini_pad + """ return self._model.stride @property def landmarks_per_face(self): + """ + landmarks_per_face, default 5 in YOLOv5Face + """ return self._model.landmarks_per_face @size.setter @@ -92,19 +127,21 @@ def is_no_pad(self, value): @is_mini_pad.setter def is_mini_pad(self, value): assert isinstance( - value, bool), "The value to set `is_mini_pad` must be type of bool." + value, + bool), "The value to set `is_mini_pad` must be type of bool." self._model.is_mini_pad = value @is_scale_up.setter def is_scale_up(self, value): assert isinstance( - value, bool), "The value to set `is_scale_up` must be type of bool." + value, + bool), "The value to set `is_scale_up` must be type of bool." self._model.is_scale_up = value @stride.setter def stride(self, value): - assert isinstance(value, - int), "The value to set `stride` must be type of int." + assert isinstance( + value, int), "The value to set `stride` must be type of int." self._model.stride = value @landmarks_per_face.setter diff --git a/python/fastdeploy/vision/faceid/contrib/adaface.py b/python/fastdeploy/vision/faceid/contrib/adaface.py index ceeb4faedc1..1cbee19cd9b 100644 --- a/python/fastdeploy/vision/faceid/contrib/adaface.py +++ b/python/fastdeploy/vision/faceid/contrib/adaface.py @@ -23,6 +23,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.PADDLE): + """Load a AdaFace model exported by InsigtFace. + + :param model_file: (str)Path of model file, e.g ./adaface.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(AdaFace, self).__init__(runtime_option) @@ -33,28 +40,48 @@ def __init__(self, assert self.initialized, "AdaFace initialize failed." def predict(self, input_image): + """ Predict the face recognition result for an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :return: FaceRecognitionResult + """ return self._model.predict(input_image) # 一些跟模型有关的属性封装 # 多数是预处理相关,可通过修改如model.size = [112, 112]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def alpha(self): + """ + alpha value for normalization + """ return self._model.alpha @property def beta(self): + """ + beta value for normalization + """ return self._model.beta @property def swap_rb(self): + """ + whether to swap the B and R channel, such as BGR->RGB, default true. + """ return self._model.swap_rb @property def l2_normalize(self): + """ + whether to apply l2 normalize to embedding values, default; + """ return self._model.l2_normalize @size.setter diff --git a/python/fastdeploy/vision/faceid/contrib/arcface.py b/python/fastdeploy/vision/faceid/contrib/arcface.py index 2e4785fa927..e1e176784fe 100644 --- a/python/fastdeploy/vision/faceid/contrib/arcface.py +++ b/python/fastdeploy/vision/faceid/contrib/arcface.py @@ -25,6 +25,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a ArcFace model exported by InsigtFace. + + :param model_file: (str)Path of model file, e.g ./arcface.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(ArcFace, self).__init__(runtime_option) @@ -35,28 +42,48 @@ def __init__(self, assert self.initialized, "ArcFace initialize failed." def predict(self, input_image): + """ Predict the face recognition result for an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :return: FaceRecognitionResult + """ return self._model.predict(input_image) # 一些跟模型有关的属性封装 # 多数是预处理相关,可通过修改如model.size = [112, 112]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def alpha(self): + """ + alpha value for normalization + """ return self._model.alpha @property def beta(self): + """ + beta value for normalization + """ return self._model.beta @property def swap_rb(self): + """ + whether to swap the B and R channel, such as BGR->RGB, default true. + """ return self._model.swap_rb @property def l2_normalize(self): + """ + whether to apply l2 normalize to embedding values, default; + """ return self._model.l2_normalize @size.setter diff --git a/python/fastdeploy/vision/faceid/contrib/cosface.py b/python/fastdeploy/vision/faceid/contrib/cosface.py index f7b620227b4..220301b271f 100644 --- a/python/fastdeploy/vision/faceid/contrib/cosface.py +++ b/python/fastdeploy/vision/faceid/contrib/cosface.py @@ -24,6 +24,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a CosFace model exported by InsigtFace. + + :param model_file: (str)Path of model file, e.g ./cosface.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(CosFace, self).__init__(runtime_option) @@ -34,28 +41,48 @@ def __init__(self, assert self.initialized, "CosFace initialize failed." def predict(self, input_image): + """ Predict the face recognition result for an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :return: FaceRecognitionResult + """ return self._model.predict(input_image) # 一些跟模型有关的属性封装 # 多数是预处理相关,可通过修改如model.size = [112, 112]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def alpha(self): + """ + alpha value for normalization + """ return self._model.alpha @property def beta(self): + """ + beta value for normalization + """ return self._model.beta @property def swap_rb(self): + """ + whether to swap the B and R channel, such as BGR->RGB, default true. + """ return self._model.swap_rb @property def l2_normalize(self): + """ + whether to apply l2 normalize to embedding values, default; + """ return self._model.l2_normalize @size.setter diff --git a/python/fastdeploy/vision/faceid/contrib/insightface_rec.py b/python/fastdeploy/vision/faceid/contrib/insightface_rec.py index df23fd6cd88..7cc96d8920c 100644 --- a/python/fastdeploy/vision/faceid/contrib/insightface_rec.py +++ b/python/fastdeploy/vision/faceid/contrib/insightface_rec.py @@ -24,6 +24,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a InsightFace model exported by InsigtFace. + + :param model_file: (str)Path of model file, e.g ./arcface.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(InsightFaceRecognitionModel, self).__init__(runtime_option) @@ -34,28 +41,48 @@ def __init__(self, assert self.initialized, "InsightFaceRecognitionModel initialize failed." def predict(self, input_image): + """ Predict the face recognition result for an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :return: FaceRecognitionResult + """ return self._model.predict(input_image) # 一些跟InsightFaceRecognitionModel模型有关的属性封装 # 多数是预处理相关,可通过修改如model.size = [112, 112]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def alpha(self): + """ + alpha value for normalization + """ return self._model.alpha @property def beta(self): + """ + beta value for normalization + """ return self._model.beta @property def swap_rb(self): + """ + whether to swap the B and R channel, such as BGR->RGB, default true. + """ return self._model.swap_rb @property def l2_normalize(self): + """ + whether to apply l2 normalize to embedding values, default; + """ return self._model.l2_normalize @size.setter diff --git a/python/fastdeploy/vision/faceid/contrib/partial_fc.py b/python/fastdeploy/vision/faceid/contrib/partial_fc.py index dcc57d2e899..5da57d4290a 100644 --- a/python/fastdeploy/vision/faceid/contrib/partial_fc.py +++ b/python/fastdeploy/vision/faceid/contrib/partial_fc.py @@ -24,6 +24,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a PartialFC model exported by InsigtFace. + + :param model_file: (str)Path of model file, e.g ./partial_fc.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(PartialFC, self).__init__(runtime_option) @@ -34,28 +41,48 @@ def __init__(self, assert self.initialized, "PartialFC initialize failed." def predict(self, input_image): + """ Predict the face recognition result for an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :return: FaceRecognitionResult + """ return self._model.predict(input_image) # 一些跟模型有关的属性封装 # 多数是预处理相关,可通过修改如model.size = [112, 112]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def alpha(self): + """ + alpha value for normalization + """ return self._model.alpha @property def beta(self): + """ + beta value for normalization + """ return self._model.beta @property def swap_rb(self): + """ + whether to swap the B and R channel, such as BGR->RGB, default true. + """ return self._model.swap_rb @property def l2_normalize(self): + """ + whether to apply l2 normalize to embedding values, default; + """ return self._model.l2_normalize @size.setter diff --git a/python/fastdeploy/vision/faceid/contrib/vpl.py b/python/fastdeploy/vision/faceid/contrib/vpl.py index 3d77abbce03..651914f05b8 100644 --- a/python/fastdeploy/vision/faceid/contrib/vpl.py +++ b/python/fastdeploy/vision/faceid/contrib/vpl.py @@ -24,6 +24,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a VPL model exported by InsigtFace. + + :param model_file: (str)Path of model file, e.g ./vpl.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(VPL, self).__init__(runtime_option) @@ -34,28 +41,48 @@ def __init__(self, assert self.initialized, "VPL initialize failed." def predict(self, input_image): + """ Predict the face recognition result for an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :return: FaceRecognitionResult + """ return self._model.predict(input_image) # 一些跟模型有关的属性封装 # 多数是预处理相关,可通过修改如model.size = [112, 112]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def alpha(self): + """ + alpha value for normalization + """ return self._model.alpha @property def beta(self): + """ + beta value for normalization + """ return self._model.beta @property def swap_rb(self): + """ + whether to swap the B and R channel, such as BGR->RGB, default true. + """ return self._model.swap_rb @property def l2_normalize(self): + """ + whether to apply l2 normalize to embedding values, default; + """ return self._model.l2_normalize @size.setter diff --git a/python/fastdeploy/vision/matting/contrib/modnet.py b/python/fastdeploy/vision/matting/contrib/modnet.py index 17bfb76f8e2..de4cc0b9657 100644 --- a/python/fastdeploy/vision/matting/contrib/modnet.py +++ b/python/fastdeploy/vision/matting/contrib/modnet.py @@ -24,6 +24,13 @@ def __init__(self, params_file="", runtime_option=None, model_format=ModelFormat.ONNX): + """Load a MODNet model exported by MODNet. + + :param model_file: (str)Path of model file, e.g ./modnet.onnx + :param params_file: (str)Path of parameters file, e.g yolox/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ # 调用基函数进行backend_option的初始化 # 初始化后的option保存在self._runtime_option super(MODNet, self).__init__(runtime_option) @@ -34,24 +41,41 @@ def __init__(self, assert self.initialized, "MODNet initialize failed." def predict(self, input_image): + """ Predict the matting result for an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :return: MattingResult + """ return self._model.predict(input_image) # 一些跟模型有关的属性封装 # 多数是预处理相关,可通过修改如model.size = [256, 256]改变预处理时resize的大小(前提是模型支持) @property def size(self): + """ + The preprocess image size, tuple of (width, height) + """ return self._model.size @property def alpha(self): + """ + alpha value for normalization + """ return self._model.alpha @property def beta(self): + """ + beta value for normalization + """ return self._model.beta @property def swap_rb(self): + """ + whether to swap the B and R channel, such as BGR->RGB, default true. + """ return self._model.swap_rb @size.setter diff --git a/python/fastdeploy/vision/matting/ppmatting/__init__.py b/python/fastdeploy/vision/matting/ppmatting/__init__.py index 450ac4aa75b..5d1f46387ae 100644 --- a/python/fastdeploy/vision/matting/ppmatting/__init__.py +++ b/python/fastdeploy/vision/matting/ppmatting/__init__.py @@ -25,6 +25,14 @@ def __init__(self, config_file, runtime_option=None, model_format=ModelFormat.PADDLE): + """Load a PPMatting model exported by PaddleSeg. + + :param model_file: (str)Path of model file, e.g PPMatting-512/model.pdmodel + :param params_file: (str)Path of parameters file, e.g PPMatting-512/model.pdiparams, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param config_file: (str)Path of configuration file for deployment, e.g PPMatting-512/deploy.yml + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model + """ super(PPMatting, self).__init__(runtime_option) assert model_format == ModelFormat.PADDLE, "PPMatting model only support model format of ModelFormat.Paddle now." @@ -34,5 +42,10 @@ def __init__(self, assert self.initialized, "PPMatting model initialize failed." def predict(self, input_image): + """ Predict the matting result for an input image + + :param input_image: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :return: MattingResult + """ assert input_image is not None, "The input image data is None." return self._model.predict(input_image) From 985d2732279fa3ec5dc423aeac1226359c166874 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Fri, 21 Oct 2022 03:00:34 +0000 Subject: [PATCH 48/69] modify resnet c++ comments --- fastdeploy/vision/classification/contrib/resnet.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fastdeploy/vision/classification/contrib/resnet.h b/fastdeploy/vision/classification/contrib/resnet.h index f766f1bf505..11fce18650e 100644 --- a/fastdeploy/vision/classification/contrib/resnet.h +++ b/fastdeploy/vision/classification/contrib/resnet.h @@ -25,7 +25,7 @@ namespace vision { * */ namespace classification { -/*! @brief ResNet series model +/*! @brief Torchvision ResNet series model */ class FASTDEPLOY_DECL ResNet : public FastDeployModel { public: @@ -44,7 +44,7 @@ class FASTDEPLOY_DECL ResNet : public FastDeployModel { virtual std::string ModelName() const { return "ResNet"; } /** \brief Predict for the input "im", the result will be saved in "result". * - * \param[in] im Input image for inference. + * \param[in] im The input image data, comes from cv::imread(), is a 3-D array with layout HWC, BGR format * \param[in] result Saving the inference result. * \param[in] topk The length of return values, e.g., if topk==2, the result will include the 2 most possible class label for input image. */ From e32a25ca129f52fbcfc81ce560162413111515b9 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Fri, 21 Oct 2022 05:39:27 +0000 Subject: [PATCH 49/69] modify C++ comments for external models --- .../vision/classification/contrib/resnet.h | 9 +++-- .../vision/detection/contrib/nanodet_plus.h | 22 ++++++----- .../vision/detection/contrib/scaledyolov4.h | 22 +++++------ fastdeploy/vision/detection/contrib/yolor.h | 28 +++++++------- fastdeploy/vision/detection/contrib/yolov5.h | 23 ++++++------ .../vision/detection/contrib/yolov5lite.h | 33 ++++++++--------- fastdeploy/vision/detection/contrib/yolov6.h | 26 ++++++------- fastdeploy/vision/detection/contrib/yolov7.h | 23 ++++++------ .../detection/contrib/yolov7end2end_ort.h | 21 ++++++----- .../detection/contrib/yolov7end2end_trt.h | 21 ++++++----- fastdeploy/vision/detection/contrib/yolox.h | 13 ++++--- .../vision/facedet/contrib/retinaface.h | 16 +++++--- fastdeploy/vision/facedet/contrib/scrfd.h | 37 +++++++++++-------- fastdeploy/vision/facedet/contrib/ultraface.h | 4 +- .../vision/facedet/contrib/yolov5face.h | 23 ++++++------ .../vision/faceid/contrib/insightface_rec.h | 12 +++--- fastdeploy/vision/matting/contrib/modnet.h | 10 +++-- 17 files changed, 186 insertions(+), 157 deletions(-) diff --git a/fastdeploy/vision/classification/contrib/resnet.h b/fastdeploy/vision/classification/contrib/resnet.h index 11fce18650e..f5db8b1bed6 100644 --- a/fastdeploy/vision/classification/contrib/resnet.h +++ b/fastdeploy/vision/classification/contrib/resnet.h @@ -49,12 +49,13 @@ class FASTDEPLOY_DECL ResNet : public FastDeployModel { * \param[in] topk The length of return values, e.g., if topk==2, the result will include the 2 most possible class label for input image. */ virtual bool Predict(cv::Mat* im, ClassifyResult* result, int topk = 1); - - /// Tuple of (width, height) + /*! @brief + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize + */ std::vector size; - /// Mean parameters for normalize + /// Mean parameters for normalize, size should be the the same as channels std::vector mean_vals; - /// Std parameters for normalize + /// Std parameters for normalize, size should be the the same as channels std::vector std_vals; diff --git a/fastdeploy/vision/detection/contrib/nanodet_plus.h b/fastdeploy/vision/detection/contrib/nanodet_plus.h index 34e353a730f..9923e4d37dd 100644 --- a/fastdeploy/vision/detection/contrib/nanodet_plus.h +++ b/fastdeploy/vision/detection/contrib/nanodet_plus.h @@ -53,21 +53,23 @@ class FASTDEPLOY_DECL NanoDetPlus : public FastDeployModel { float conf_threshold = 0.35f, float nms_iou_threshold = 0.5f); - /// tuple of input size (width, height), e.g (320, 320) - std::vector size; - /// padding value, size should be the same as channels - std::vector padding_value; /*! @brief - keep aspect ratio or not when perform resize operation. This option is set as `false` by default in NanoDet-Plus + Argument for image preprocessing step, tuple of input size (width, height), e.g (320, 320) */ + std::vector size; + // padding value, size should be the same as channels + std::vector padding_value; + // keep aspect ratio or not when perform resize operation. + // This option is set as `false` by default in NanoDet-Plus bool keep_ratio; - /*! @brief - downsample strides for NanoDet-Plus to generate anchors, will take (8, 16, 32, 64) as default values - */ + // downsample strides for NanoDet-Plus to generate anchors, + // will take (8, 16, 32, 64) as default values std::vector downsample_strides; - /// for offseting the boxes by classes when using NMS, default 4096 + // for offseting the boxes by classes when using NMS, default 4096 float max_wh; - /// reg_max for GFL regression, default 7 + /*! @brief + Argument for image postprocessing step, reg_max for GFL regression, default 7 + */ int reg_max; private: diff --git a/fastdeploy/vision/detection/contrib/scaledyolov4.h b/fastdeploy/vision/detection/contrib/scaledyolov4.h index 963c892ec96..a0108cfa57b 100644 --- a/fastdeploy/vision/detection/contrib/scaledyolov4.h +++ b/fastdeploy/vision/detection/contrib/scaledyolov4.h @@ -50,23 +50,23 @@ class FASTDEPLOY_DECL ScaledYOLOv4 : public FastDeployModel { float conf_threshold = 0.25, float nms_iou_threshold = 0.5); - /// tuple of (width, height) + /*! @brief + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize + */ std::vector size; - /// padding value, size should be the same as channels + // padding value, size should be the same as channels std::vector padding_value; - /// only pad to the minimum rectange which height and width is times of stride + // only pad to the minimum rectange which height and width is times of stride bool is_mini_pad; - /*! @brief - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - */ + // while is_mini_pad = false and is_no_pad = true, + // will resize the image to the set size bool is_no_pad; - /*! @brief - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - */ + // if is_scale_up is false, the input image only can be zoom out, + // the maximum resize scale cannot exceed 1.0 bool is_scale_up; - /// padding stride, for is_mini_pad + // padding stride, for is_mini_pad int stride; - /// for offseting the boxes by classes when using NMS + // for offseting the boxes by classes when using NMS float max_wh; private: diff --git a/fastdeploy/vision/detection/contrib/yolor.h b/fastdeploy/vision/detection/contrib/yolor.h index af6ebf46f86..7a09faa7342 100644 --- a/fastdeploy/vision/detection/contrib/yolor.h +++ b/fastdeploy/vision/detection/contrib/yolor.h @@ -1,4 +1,5 @@ -// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. //NOLINT + + // 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. @@ -38,7 +39,7 @@ class FASTDEPLOY_DECL YOLOR : public FastDeployModel { virtual std::string ModelName() const { return "YOLOR"; } /** \brief Predict the detection result for an input image * - * \param[in] im The input image data, comes from cv::imread(), is a 3-D array with layout HWC, BGR format + * \param[in] im The input image data, comes from cv::imread() * \param[in] result The output detection result will be writen to this structure * \param[in] conf_threshold confidence threashold for postprocessing, default is 0.25 * \param[in] nms_iou_threshold iou threashold for NMS, default is 0.5 @@ -48,23 +49,24 @@ class FASTDEPLOY_DECL YOLOR : public FastDeployModel { float conf_threshold = 0.25, float nms_iou_threshold = 0.5); - /// tuple of (width, height) + /*! @brief + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize + */ std::vector size; - /// padding value, size should be the same as channels + // padding value, size should be the same as channels + std::vector padding_value; - /// only pad to the minimum rectange which height and width is times of stride + // only pad to the minimum rectange which height and width is times of stride bool is_mini_pad; - /*! @brief - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - */ + // while is_mini_pad = false and is_no_pad = true, + // will resize the image to the set size bool is_no_pad; - /*! @brief - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - */ + // if is_scale_up is false, the input image only can be zoom out, + // the maximum resize scale cannot exceed 1.0 bool is_scale_up; - /// padding stride, for is_mini_pad + // padding stride, for is_mini_pad int stride; - /// for offseting the boxes by classes when using NMS + // for offseting the boxes by classes when using NMS float max_wh; private: diff --git a/fastdeploy/vision/detection/contrib/yolov5.h b/fastdeploy/vision/detection/contrib/yolov5.h index e899ad4c547..15d98e6f239 100644 --- a/fastdeploy/vision/detection/contrib/yolov5.h +++ b/fastdeploy/vision/detection/contrib/yolov5.h @@ -77,23 +77,24 @@ class FASTDEPLOY_DECL YOLOv5 : public FastDeployModel { float conf_threshold, float nms_iou_threshold, bool multi_label, float max_wh = 7680.0); - /// tuple of (width, height) + /*! @brief + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize + */ std::vector size_; - /// padding value, size should be the same as channels + // padding value, size should be the same as channels + std::vector padding_value_; - /// only pad to the minimum rectange which height and width is times of stride + // only pad to the minimum rectange which height and width is times of stride bool is_mini_pad_; - /*! @brief - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - */ + // while is_mini_pad = false and is_no_pad = true, + // will resize the image to the set size bool is_no_pad_; - /*! @brief - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - */ + // if is_scale_up is false, the input image only can be zoom out, + // the maximum resize scale cannot exceed 1.0 bool is_scale_up_; - /// padding stride, for is_mini_pad + // padding stride, for is_mini_pad int stride_; - /// for offseting the boxes by classes when using NMS + // for offseting the boxes by classes when using NMS float max_wh_; /// for different strategies to get boxes when postprocessing bool multi_label_; diff --git a/fastdeploy/vision/detection/contrib/yolov5lite.h b/fastdeploy/vision/detection/contrib/yolov5lite.h index 63717b01ce8..8bbcf331ae2 100644 --- a/fastdeploy/vision/detection/contrib/yolov5lite.h +++ b/fastdeploy/vision/detection/contrib/yolov5lite.h @@ -53,31 +53,30 @@ class FASTDEPLOY_DECL YOLOv5Lite : public FastDeployModel { void UseCudaPreprocessing(int max_img_size = 3840 * 2160); - /// tuple of (width, height) + /*! @brief + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize + */ std::vector size; - /// padding value, size should be the same as channels + // padding value, size should be the same as channels + std::vector padding_value; - /// only pad to the minimum rectange which height and width is times of stride + // only pad to the minimum rectange which height and width is times of stride bool is_mini_pad; - /*! @brief - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - */ + // while is_mini_pad = false and is_no_pad = true, + // will resize the image to the set size bool is_no_pad; - /*! @brief - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - */ + // if is_scale_up is false, the input image only can be zoom out, + // the maximum resize scale cannot exceed 1.0 bool is_scale_up; - /// padding stride, for is_mini_pad + // padding stride, for is_mini_pad int stride; - /// for offseting the boxes by classes when using NMS + // for offseting the boxes by classes when using NMS float max_wh; - /*! @brief - downsample strides for YOLOv5Lite to generate anchors, will take (8,16,32) as default values, might have stride=64. - */ + // downsample strides for YOLOv5Lite to generate anchors, + // will take (8,16,32) as default values, might have stride=64. std::vector downsample_strides; - /*! @brief - anchors parameters, downsample_strides will take (8,16,32), each stride has three anchors with width and hight - */ + // anchors parameters, downsample_strides will take (8,16,32), + // each stride has three anchors with width and hight std::vector> anchor_config; /*! @brief whether the model_file was exported with decode module. The official diff --git a/fastdeploy/vision/detection/contrib/yolov6.h b/fastdeploy/vision/detection/contrib/yolov6.h index b90197a2e1a..1e0af6fd33a 100644 --- a/fastdeploy/vision/detection/contrib/yolov6.h +++ b/fastdeploy/vision/detection/contrib/yolov6.h @@ -56,25 +56,25 @@ class FASTDEPLOY_DECL YOLOv6 : public FastDeployModel { void UseCudaPreprocessing(int max_img_size = 3840 * 2160); - /// tuple of (width, height) + /*! @brief + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize + */ std::vector size; - /// padding value, size should be the same as channels + // padding value, size should be the same as channels + std::vector padding_value; - /// only pad to the minimum rectange which height and width is times of stride + // only pad to the minimum rectange which height and width is times of stride bool is_mini_pad; - /*! @brief - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - */ + // while is_mini_pad = false and is_no_pad = true, + // will resize the image to the set size bool is_no_pad; - /*! @brief - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - */ + // if is_scale_up is false, the input image only can be zoom out, + // the maximum resize scale cannot exceed 1.0 bool is_scale_up; - /// padding stride, for is_mini_pad + // padding stride, for is_mini_pad int stride; - /*! @brief - for offseting the boxes by classes when using NMS, default 4096 in meituan/YOLOv6 - */ + // for offseting the boxes by classes when using NMS, + // default 4096 in meituan/YOLOv6 float max_wh; private: diff --git a/fastdeploy/vision/detection/contrib/yolov7.h b/fastdeploy/vision/detection/contrib/yolov7.h index e7921061d86..2eb038f719d 100644 --- a/fastdeploy/vision/detection/contrib/yolov7.h +++ b/fastdeploy/vision/detection/contrib/yolov7.h @@ -53,23 +53,24 @@ class FASTDEPLOY_DECL YOLOv7 : public FastDeployModel { void UseCudaPreprocessing(int max_img_size = 3840 * 2160); - /// tuple of (width, height) + /*! @brief + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize + */ std::vector size; - /// padding value, size should be the same as channels + // padding value, size should be the same as channels + std::vector padding_value; - /// only pad to the minimum rectange which height and width is times of stride + // only pad to the minimum rectange which height and width is times of stride bool is_mini_pad; - /*! @brief - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - */ + // while is_mini_pad = false and is_no_pad = true, + // will resize the image to the set size bool is_no_pad; - /*! @brief - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - */ + // if is_scale_up is false, the input image only can be zoom out, + // the maximum resize scale cannot exceed 1.0 bool is_scale_up; - /// padding stride, for is_mini_pad + // padding stride, for is_mini_pad int stride; - /// for offseting the boxes by classes when using NMS + // for offseting the boxes by classes when using NMS float max_wh; private: diff --git a/fastdeploy/vision/detection/contrib/yolov7end2end_ort.h b/fastdeploy/vision/detection/contrib/yolov7end2end_ort.h index 6e0c0d578b4..9434d69edb9 100644 --- a/fastdeploy/vision/detection/contrib/yolov7end2end_ort.h +++ b/fastdeploy/vision/detection/contrib/yolov7end2end_ort.h @@ -47,21 +47,22 @@ class FASTDEPLOY_DECL YOLOv7End2EndORT : public FastDeployModel { virtual bool Predict(cv::Mat* im, DetectionResult* result, float conf_threshold = 0.25); - /// tuple of (width, height) + /*! @brief + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize + */ std::vector size; - /// padding value, size should be the same as channels + // padding value, size should be the same as channels + std::vector padding_value; - /// only pad to the minimum rectange which height and width is times of stride + // only pad to the minimum rectange which height and width is times of stride bool is_mini_pad; - /*! @brief - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - */ + // while is_mini_pad = false and is_no_pad = true, + // will resize the image to the set size bool is_no_pad; - /*! @brief - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - */ + // if is_scale_up is false, the input image only can be zoom out, + // the maximum resize scale cannot exceed 1.0 bool is_scale_up; - /// padding stride, for is_mini_pad + // padding stride, for is_mini_pad int stride; private: diff --git a/fastdeploy/vision/detection/contrib/yolov7end2end_trt.h b/fastdeploy/vision/detection/contrib/yolov7end2end_trt.h index 3a2494d4934..f6ce6e943f2 100644 --- a/fastdeploy/vision/detection/contrib/yolov7end2end_trt.h +++ b/fastdeploy/vision/detection/contrib/yolov7end2end_trt.h @@ -52,21 +52,22 @@ class FASTDEPLOY_DECL YOLOv7End2EndTRT : public FastDeployModel { void UseCudaPreprocessing(int max_img_size = 3840 * 2160); - /// tuple of (width, height) + /*! @brief + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize + */ std::vector size; - /// padding value, size should be the same as channels + // padding value, size should be the same as channels + std::vector padding_value; - /// only pad to the minimum rectange which height and width is times of stride + // only pad to the minimum rectange which height and width is times of stride bool is_mini_pad; - /*! @brief - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - */ + // while is_mini_pad = false and is_no_pad = true, + // will resize the image to the set size bool is_no_pad; - /*! @brief - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - */ + // if is_scale_up is false, the input image only can be zoom out, + // the maximum resize scale cannot exceed 1.0 bool is_scale_up; - /// padding stride, for is_mini_pad + // padding stride, for is_mini_pad int stride; private: diff --git a/fastdeploy/vision/detection/contrib/yolox.h b/fastdeploy/vision/detection/contrib/yolox.h index 07522832cc0..c040c28a8ec 100644 --- a/fastdeploy/vision/detection/contrib/yolox.h +++ b/fastdeploy/vision/detection/contrib/yolox.h @@ -51,9 +51,11 @@ class FASTDEPLOY_DECL YOLOX : public FastDeployModel { float conf_threshold = 0.25, float nms_iou_threshold = 0.5); - /// tuple of (width, height) + /*! @brief + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize + */ std::vector size; - /// padding value, size should be the same as channels + // padding value, size should be the same as channels std::vector padding_value; /*! @brief whether the model_file was exported with decode module. The official @@ -62,11 +64,10 @@ class FASTDEPLOY_DECL YOLOX : public FastDeployModel { was exported with decode module. */ bool is_decode_exported; - /*! @brief - downsample strides for YOLOX to generate anchors, will take (8,16,32) as default values, might have stride=64 - */ + // downsample strides for YOLOX to generate anchors, + // will take (8,16,32) as default values, might have stride=64 std::vector downsample_strides; - /// for offseting the boxes by classes when using NMS, default 4096 + // for offseting the boxes by classes when using NMS, default 4096 float max_wh; private: diff --git a/fastdeploy/vision/facedet/contrib/retinaface.h b/fastdeploy/vision/facedet/contrib/retinaface.h index 33708586a94..e669b8a4b76 100644 --- a/fastdeploy/vision/facedet/contrib/retinaface.h +++ b/fastdeploy/vision/facedet/contrib/retinaface.h @@ -52,19 +52,25 @@ class FASTDEPLOY_DECL RetinaFace : public FastDeployModel { float conf_threshold = 0.25f, float nms_iou_threshold = 0.4f); - /// tuple of (width, height), default (640, 640) + /*! @brief + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize + */, default (640, 640) std::vector size; /*! @brief - variance in RetinaFace's prior-box(anchor) generate process, default (0.1, 0.2) + Argument for image postprocessing step, variance in RetinaFace's prior-box(anchor) generate process, default (0.1, 0.2) */ std::vector variance; /*! @brief - downsample strides (namely, steps) for RetinaFace to generate anchors, will take (8,16,32) as default values + Argument for image postprocessing step, downsample strides (namely, steps) for RetinaFace to generate anchors, will take (8,16,32) as default values */ std::vector downsample_strides; - /// min sizes, width and height for each anchor + /*! @brief + Argument for image postprocessing step, min sizes, width and height for each anchor + */ std::vector> min_sizes; - /// landmarks_per_face, default 5 in RetinaFace + /*! @brief + Argument for image postprocessing step, landmarks_per_face, default 5 in RetinaFace + */ int landmarks_per_face; private: diff --git a/fastdeploy/vision/facedet/contrib/scrfd.h b/fastdeploy/vision/facedet/contrib/scrfd.h index 964e9ac494d..ef82300d1bf 100644 --- a/fastdeploy/vision/facedet/contrib/scrfd.h +++ b/fastdeploy/vision/facedet/contrib/scrfd.h @@ -51,33 +51,40 @@ class FASTDEPLOY_DECL SCRFD : public FastDeployModel { float conf_threshold = 0.25f, float nms_iou_threshold = 0.4f); - /// tuple of (width, height), default (640, 640) + /*! @brief + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize + */, default (640, 640) std::vector size; - /// padding value, size should be the same as channels + // padding value, size should be the same as channels + std::vector padding_value; - /// only pad to the minimum rectange which height and width is times of stride + // only pad to the minimum rectange which height and width is times of stride bool is_mini_pad; - /*! @brief - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - */ + // while is_mini_pad = false and is_no_pad = true, + // will resize the image to the set size bool is_no_pad; - /*! @brief - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - */ + // if is_scale_up is false, the input image only can be zoom out, + // the maximum resize scale cannot exceed 1.0 bool is_scale_up; - /// padding stride, for is_mini_pad + // padding stride, for is_mini_pad int stride; /*! @brief - downsample strides (namely, steps) for SCRFD to generate anchors, will take (8,16,32) as default values + Argument for image postprocessing step, downsample strides (namely, steps) for SCRFD to generate anchors, will take (8,16,32) as default values */ std::vector downsample_strides; - /// landmarks_per_face, default 5 in SCRFD + /*! @brief + Argument for image postprocessing step, landmarks_per_face, default 5 in SCRFD + */ int landmarks_per_face; - /// the outputs of onnx file with key points features or not + /*! @brief + Argument for image postprocessing step, the outputs of onnx file with key points features or not + */ bool use_kps; - /// the upperbond number of boxes processed by nms + /*! @brief + Argument for image postprocessing step, the upperbond number of boxes processed by nms + */ int max_nms; - /// number anchors of each stride + /// Argument for image postprocessing step, anchor number of each stride unsigned int num_anchors; private: diff --git a/fastdeploy/vision/facedet/contrib/ultraface.h b/fastdeploy/vision/facedet/contrib/ultraface.h index ebe1da986b5..960bc0f5e1a 100644 --- a/fastdeploy/vision/facedet/contrib/ultraface.h +++ b/fastdeploy/vision/facedet/contrib/ultraface.h @@ -52,7 +52,9 @@ class FASTDEPLOY_DECL UltraFace : public FastDeployModel { float conf_threshold = 0.7f, float nms_iou_threshold = 0.3f); - /// tuple of (width, height), default (320, 240) + /*! @brief + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize, default (320, 240) + */ std::vector size; private: diff --git a/fastdeploy/vision/facedet/contrib/yolov5face.h b/fastdeploy/vision/facedet/contrib/yolov5face.h index 921d68cce7b..10479052de9 100644 --- a/fastdeploy/vision/facedet/contrib/yolov5face.h +++ b/fastdeploy/vision/facedet/contrib/yolov5face.h @@ -50,26 +50,27 @@ class FASTDEPLOY_DECL YOLOv5Face : public FastDeployModel { float conf_threshold = 0.25, float nms_iou_threshold = 0.5); - /// tuple of (width, height) + /*! @brief + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize + */ std::vector size; - /// padding value, size should be the same as channels + // padding value, size should be the same as channels + std::vector padding_value; - /// only pad to the minimum rectange which height and width is times of stride + // only pad to the minimum rectange which height and width is times of stride bool is_mini_pad; - /*! @brief - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - */ + // while is_mini_pad = false and is_no_pad = true, + // will resize the image to the set size bool is_no_pad; - /*! @brief - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - */ + // if is_scale_up is false, the input image only can be zoom out, + // the maximum resize scale cannot exceed 1.0 bool is_scale_up; - /// padding stride, for is_mini_pad + // padding stride, for is_mini_pad int stride; /*! @brief - setup the number of landmarks for per face (if have), default 5 in + Argument for image postprocessing step, setup the number of landmarks for per face (if have), default 5 in official yolov5face note that, the outupt tensor's shape must be: (1,n,4+1+2*landmarks_per_face+1=box+obj+landmarks+cls) */ diff --git a/fastdeploy/vision/faceid/contrib/insightface_rec.h b/fastdeploy/vision/faceid/contrib/insightface_rec.h index e12765a20c3..60b4dc1e9b3 100644 --- a/fastdeploy/vision/faceid/contrib/insightface_rec.h +++ b/fastdeploy/vision/faceid/contrib/insightface_rec.h @@ -40,15 +40,17 @@ class FASTDEPLOY_DECL InsightFaceRecognitionModel : public FastDeployModel { virtual std::string ModelName() const { return "deepinsight/insightface"; } - /// tuple of (width, height), default (112, 112) + /*! @brief + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize + */, default (112, 112) std::vector size; - /// alpha values for normalization + /// Argument for image preprocessing step, alpha values for normalization std::vector alpha; - /// beta values for normalization + /// Argument for image preprocessing step, beta values for normalization std::vector beta; - /// whether to swap the B and R channel, such as BGR->RGB, default true. + /// Argument for image preprocessing step, whether to swap the B and R channel, such as BGR->RGB, default true. bool swap_rb; - /// whether to apply l2 normalize to embedding values, default; + /// Argument for image postprocessing step, whether to apply l2 normalize to embedding values, default; bool l2_normalize; /** \brief Predict the face recognition result for an input image * diff --git a/fastdeploy/vision/matting/contrib/modnet.h b/fastdeploy/vision/matting/contrib/modnet.h index 3e53e1ba6f9..e6c1b2a57f2 100644 --- a/fastdeploy/vision/matting/contrib/modnet.h +++ b/fastdeploy/vision/matting/contrib/modnet.h @@ -39,13 +39,15 @@ class FASTDEPLOY_DECL MODNet : public FastDeployModel { std::string ModelName() const { return "matting/MODNet"; } - /// tuple of (width, height), default (256, 256) + /*! @brief + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize + */, default (256, 256) std::vector size; - /// parameters for normalization + /// Argument for image preprocessing step, parameters for normalization, size should be the the same as channels std::vector alpha; - /// parameters for normalization + /// Argument for image preprocessing step, parameters for normalization, size should be the the same as channels std::vector beta; - /// whether to swap the B and R channel, such as BGR->RGB, default true. + /// Argument for image preprocessing step, whether to swap the B and R channel, such as BGR->RGB, default true. bool swap_rb; /** \brief Predict the matting result for an input image * From 8a73af624779bf90011a15c27d3e1593d18ee52f Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Fri, 21 Oct 2022 09:35:23 +0000 Subject: [PATCH 50/69] modify python comments and add result class comments --- fastdeploy/vision/common/result.h | 67 +++++++++++++------ .../vision/faceid/contrib/insightface_rec.h | 2 +- .../vision/detection/contrib/nanodet_plus.py | 18 ++--- .../vision/detection/contrib/scaled_yolov4.py | 26 ++----- .../vision/detection/contrib/yolor.py | 26 ++----- .../vision/detection/contrib/yolov5.py | 26 ++----- .../vision/detection/contrib/yolov5lite.py | 26 ++----- .../vision/detection/contrib/yolov6.py | 26 ++----- .../vision/detection/contrib/yolov7.py | 26 ++----- .../detection/contrib/yolov7end2end_ort.py | 22 ++---- .../detection/contrib/yolov7end2end_trt.py | 22 ++---- .../vision/detection/contrib/yolox.py | 10 +-- .../vision/facedet/contrib/retinaface.py | 10 +-- .../vision/facedet/contrib/scrfd.py | 22 ++---- .../vision/facedet/contrib/ultraface.py | 2 +- .../vision/facedet/contrib/yolov5face.py | 24 ++----- .../vision/faceid/contrib/adaface.py | 10 +-- .../vision/faceid/contrib/arcface.py | 10 +-- .../vision/faceid/contrib/cosface.py | 10 +-- .../vision/faceid/contrib/insightface_rec.py | 10 +-- .../vision/faceid/contrib/partial_fc.py | 10 +-- .../fastdeploy/vision/faceid/contrib/vpl.py | 10 +-- .../vision/matting/contrib/modnet.py | 8 +-- 23 files changed, 164 insertions(+), 259 deletions(-) diff --git a/fastdeploy/vision/common/result.h b/fastdeploy/vision/common/result.h index e37538280ec..6bdd08dc53b 100644 --- a/fastdeploy/vision/common/result.h +++ b/fastdeploy/vision/common/result.h @@ -154,88 +154,117 @@ struct FASTDEPLOY_DECL OCRResult : public BaseResult { std::string Str(); }; +/*! @brief Face detection result structure for all the face detection models + */ struct FASTDEPLOY_DECL FaceDetectionResult : public BaseResult { - // box: xmin, ymin, xmax, ymax + /** \brief All the detected object boxes for an input image, the size of `boxes` is the number of detected objects, and the element of `boxes` is a array of 4 float values, means [xmin, ymin, xmax, ymax] + */ std::vector> boxes; - // landmark: x, y, landmarks may empty if the - // model don't detect face with landmarks. - // Note, one face might have multiple landmarks, - // such as 5/19/21/68/98/..., etc. + /** \brief + * If the model detect face with landmarks, every detected object box correspoing to a landmark, which is a array of 2 float values, means location [x,y] + */ std::vector> landmarks; + /** \brief + * Indicates the confidence of all targets detected from a single image, and the number of elements is consistent with boxes.size() + */ std::vector scores; ResultType type = ResultType::FACE_DETECTION; - // set landmarks_per_face manually in your post processes. + /** \brief + * User can set landmarks_per_face manually in the post processes. + */ int landmarks_per_face; FaceDetectionResult() { landmarks_per_face = 0; } FaceDetectionResult(const FaceDetectionResult& res); - + /// Clear detection result void Clear(); void Reserve(int size); void Resize(int size); - + /// Debug function, convert the result to string to print std::string Str(); }; +/*! @brief Segmentation result structure for all the segmentation models + */ struct FASTDEPLOY_DECL SegmentationResult : public BaseResult { - // mask + /** \brief + * label_map stores the pixel-level category labels for input image. the number of pixels is equal to label_map.size() + */ std::vector label_map; + /** \brief + * score_map stores the probability of the predicted label for each pixel of input image. + */ std::vector score_map; + /// The output shape, means [H, W] std::vector shape; bool contain_score_map = false; ResultType type = ResultType::SEGMENTATION; - + /// Clear detection result void Clear(); void Reserve(int size); void Resize(int size); - + /// Debug function, convert the result to string to print std::string Str(); }; +/*! @brief Face recognition result structure for all the Face recognition models + */ struct FASTDEPLOY_DECL FaceRecognitionResult : public BaseResult { - // face embedding vector with 128/256/512 ... dim + /** \brief The feature embedding that represents the final extraction of the face recognition model can be used to calculate the feature similarity between faces. + */ std::vector embedding; ResultType type = ResultType::FACE_RECOGNITION; FaceRecognitionResult() {} FaceRecognitionResult(const FaceRecognitionResult& res); - + /// Clear detection result void Clear(); void Reserve(int size); void Resize(int size); - + /// Debug function, convert the result to string to print std::string Str(); }; +/*! @brief Matting result structure for all the Matting models + */ struct FASTDEPLOY_DECL MattingResult : public BaseResult { // alpha matte and fgr (predicted foreground: HWC/BGR float32) + /** \brief + alpha is a one-dimensional vector, which is the predicted alpha transparency value. The range of values is [0., 1.], and the length is hxw. h, w are the height and width of the input image + */ std::vector alpha; // h x w + /** \brief + If the model can predict foreground, foreground save the predicted foreground image, the shape is [hight,width,channel] generally. + */ std::vector foreground; // h x w x c (c=3 default) - // height, width, channel for foreground and alpha - // must be (h,w,c) and setup before Reserve and Resize - // c is only for foreground if contain_foreground is true. + /** \brief + * The shape of output result, when contain_foreground == false, shape only contains (h, w), when contain_foreground == true, shape contains (h, w, c), and c is generally 3 + */ std::vector shape; + /** \brief + If the model can predict alpha matte and foreground, contain_foreground = true, default false + */ bool contain_foreground = false; ResultType type = ResultType::MATTING; MattingResult() {} MattingResult(const MattingResult& res); - + /// Clear detection result void Clear(); void Reserve(int size); void Resize(int size); - + /// Debug function, convert the result to string to print std::string Str(); }; diff --git a/fastdeploy/vision/faceid/contrib/insightface_rec.h b/fastdeploy/vision/faceid/contrib/insightface_rec.h index 60b4dc1e9b3..84d5c2471a6 100644 --- a/fastdeploy/vision/faceid/contrib/insightface_rec.h +++ b/fastdeploy/vision/faceid/contrib/insightface_rec.h @@ -50,7 +50,7 @@ class FASTDEPLOY_DECL InsightFaceRecognitionModel : public FastDeployModel { std::vector beta; /// Argument for image preprocessing step, whether to swap the B and R channel, such as BGR->RGB, default true. bool swap_rb; - /// Argument for image postprocessing step, whether to apply l2 normalize to embedding values, default; + /// Argument for image postprocessing step, whether to apply l2 normalize to embedding values, default false; bool l2_normalize; /** \brief Predict the face recognition result for an input image * diff --git a/python/fastdeploy/vision/detection/contrib/nanodet_plus.py b/python/fastdeploy/vision/detection/contrib/nanodet_plus.py index 00693335fb3..b5a83fe2b25 100644 --- a/python/fastdeploy/vision/detection/contrib/nanodet_plus.py +++ b/python/fastdeploy/vision/detection/contrib/nanodet_plus.py @@ -56,36 +56,28 @@ def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def padding_value(self): - """ - padding value, size should be the same as channels - """ + # padding value, size should be the same as channels return self._model.padding_value @property def keep_ratio(self): - """ - keep aspect ratio or not when perform resize operation. This option is set as false by default in NanoDet-Plus - """ + # keep aspect ratio or not when perform resize operation. This option is set as false by default in NanoDet-Plus return self._model.keep_ratio @property def downsample_strides(self): - """ - downsample strides for NanoDet-Plus to generate anchors, will take (8, 16, 32, 64) as default values - """ + # downsample strides for NanoDet-Plus to generate anchors, will take (8, 16, 32, 64) as default values return self._model.downsample_strides @property def max_wh(self): - """ - for offseting the boxes by classes when using NMS, default 4096 - """ + # for offseting the boxes by classes when using NMS, default 4096 return self._model.max_wh @property diff --git a/python/fastdeploy/vision/detection/contrib/scaled_yolov4.py b/python/fastdeploy/vision/detection/contrib/scaled_yolov4.py index 921ee0375e2..1e46ba1a147 100644 --- a/python/fastdeploy/vision/detection/contrib/scaled_yolov4.py +++ b/python/fastdeploy/vision/detection/contrib/scaled_yolov4.py @@ -56,50 +56,38 @@ def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def padding_value(self): - """ - padding value, size should be the same as channels - """ + # padding value, size should be the same as channels return self._model.padding_value @property def is_no_pad(self): - """ - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - """ + # while is_mini_pad = false and is_no_pad = true, will resize the image to the set size return self._model.is_no_pad @property def is_mini_pad(self): - """ - only pad to the minimum rectange which height and width is times of stride - """ + # only pad to the minimum rectange which height and width is times of stride return self._model.is_mini_pad @property def is_scale_up(self): - """ - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - """ + # if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 return self._model.is_scale_up @property def stride(self): - """ - padding stride, for is_mini_pad - """ + # padding stride, for is_mini_pad return self._model.stride @property def max_wh(self): - """ - for offseting the boxes by classes when using NMS - """ + # for offseting the boxes by classes when using NMS return self._model.max_wh @size.setter diff --git a/python/fastdeploy/vision/detection/contrib/yolor.py b/python/fastdeploy/vision/detection/contrib/yolor.py index 70e69aa9dd0..6326630e1ad 100644 --- a/python/fastdeploy/vision/detection/contrib/yolor.py +++ b/python/fastdeploy/vision/detection/contrib/yolor.py @@ -56,50 +56,38 @@ def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def padding_value(self): - """ - padding value, size should be the same as channels - """ + # padding value, size should be the same as channels return self._model.padding_value @property def is_no_pad(self): - """ - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - """ + # while is_mini_pad = false and is_no_pad = true, will resize the image to the set size return self._model.is_no_pad @property def is_mini_pad(self): - """ - only pad to the minimum rectange which height and width is times of stride - """ + # only pad to the minimum rectange which height and width is times of stride return self._model.is_mini_pad @property def is_scale_up(self): - """ - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - """ + # if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 return self._model.is_scale_up @property def stride(self): - """ - padding stride, for is_mini_pad - """ + # padding stride, for is_mini_pad return self._model.stride @property def max_wh(self): - """ - for offseting the boxes by classes when using NMS - """ + # for offseting the boxes by classes when using NMS return self._model.max_wh @size.setter diff --git a/python/fastdeploy/vision/detection/contrib/yolov5.py b/python/fastdeploy/vision/detection/contrib/yolov5.py index d59690b8be9..a5068df5e7b 100644 --- a/python/fastdeploy/vision/detection/contrib/yolov5.py +++ b/python/fastdeploy/vision/detection/contrib/yolov5.py @@ -81,50 +81,38 @@ def postprocess(infer_result, @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def padding_value(self): - """ - padding value, size should be the same as channels - """ + # padding value, size should be the same as channels return self._model.padding_value @property def is_no_pad(self): - """ - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - """ + # while is_mini_pad = false and is_no_pad = true, will resize the image to the set size return self._model.is_no_pad @property def is_mini_pad(self): - """ - only pad to the minimum rectange which height and width is times of stride - """ + # only pad to the minimum rectange which height and width is times of stride return self._model.is_mini_pad @property def is_scale_up(self): - """ - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - """ + # if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 return self._model.is_scale_up @property def stride(self): - """ - padding stride, for is_mini_pad - """ + # padding stride, for is_mini_pad return self._model.stride @property def max_wh(self): - """ - for offseting the boxes by classes when using NMS - """ + # for offseting the boxes by classes when using NMS return self._model.max_wh @property diff --git a/python/fastdeploy/vision/detection/contrib/yolov5lite.py b/python/fastdeploy/vision/detection/contrib/yolov5lite.py index 8b26548e582..606dc98c43a 100644 --- a/python/fastdeploy/vision/detection/contrib/yolov5lite.py +++ b/python/fastdeploy/vision/detection/contrib/yolov5lite.py @@ -56,50 +56,38 @@ def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def padding_value(self): - """ - padding value, size should be the same as channels - """ + # padding value, size should be the same as channels return self._model.padding_value @property def is_no_pad(self): - """ - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - """ + # while is_mini_pad = false and is_no_pad = true, will resize the image to the set size return self._model.is_no_pad @property def is_mini_pad(self): - """ - only pad to the minimum rectange which height and width is times of stride - """ + # only pad to the minimum rectange which height and width is times of stride return self._model.is_mini_pad @property def is_scale_up(self): - """ - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - """ + # if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 return self._model.is_scale_up @property def stride(self): - """ - padding stride, for is_mini_pad - """ + # padding stride, for is_mini_pad return self._model.stride @property def max_wh(self): - """ - for offseting the boxes by classes when using NMS - """ + # for offseting the boxes by classes when using NMS return self._model.max_wh @property diff --git a/python/fastdeploy/vision/detection/contrib/yolov6.py b/python/fastdeploy/vision/detection/contrib/yolov6.py index 2c7f1df1574..9f953311440 100644 --- a/python/fastdeploy/vision/detection/contrib/yolov6.py +++ b/python/fastdeploy/vision/detection/contrib/yolov6.py @@ -56,50 +56,38 @@ def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def padding_value(self): - """ - padding value, size should be the same as channels - """ + # padding value, size should be the same as channels return self._model.padding_value @property def is_no_pad(self): - """ - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - """ + # while is_mini_pad = false and is_no_pad = true, will resize the image to the set size return self._model.is_no_pad @property def is_mini_pad(self): - """ - only pad to the minimum rectange which height and width is times of stride - """ + # only pad to the minimum rectange which height and width is times of stride return self._model.is_mini_pad @property def is_scale_up(self): - """ - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - """ + # if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 return self._model.is_scale_up @property def stride(self): - """ - padding stride, for is_mini_pad - """ + # padding stride, for is_mini_pad return self._model.stride @property def max_wh(self): - """ - for offseting the boxes by classes when using NMS - """ + # for offseting the boxes by classes when using NMS return self._model.max_wh @size.setter diff --git a/python/fastdeploy/vision/detection/contrib/yolov7.py b/python/fastdeploy/vision/detection/contrib/yolov7.py index e22a1841cfa..53ef24a1019 100644 --- a/python/fastdeploy/vision/detection/contrib/yolov7.py +++ b/python/fastdeploy/vision/detection/contrib/yolov7.py @@ -56,50 +56,38 @@ def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def padding_value(self): - """ - padding value, size should be the same as channels - """ + # padding value, size should be the same as channels return self._model.padding_value @property def is_no_pad(self): - """ - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - """ + # while is_mini_pad = false and is_no_pad = true, will resize the image to the set size return self._model.is_no_pad @property def is_mini_pad(self): - """ - only pad to the minimum rectange which height and width is times of stride - """ + # only pad to the minimum rectange which height and width is times of stride return self._model.is_mini_pad @property def is_scale_up(self): - """ - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - """ + # if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 return self._model.is_scale_up @property def stride(self): - """ - padding stride, for is_mini_pad - """ + # padding stride, for is_mini_pad return self._model.stride @property def max_wh(self): - """ - for offseting the boxes by classes when using NMS - """ + # for offseting the boxes by classes when using NMS return self._model.max_wh @size.setter diff --git a/python/fastdeploy/vision/detection/contrib/yolov7end2end_ort.py b/python/fastdeploy/vision/detection/contrib/yolov7end2end_ort.py index de776199757..e16ec6a901c 100644 --- a/python/fastdeploy/vision/detection/contrib/yolov7end2end_ort.py +++ b/python/fastdeploy/vision/detection/contrib/yolov7end2end_ort.py @@ -54,43 +54,33 @@ def predict(self, input_image, conf_threshold=0.25): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def padding_value(self): - """ - padding value, size should be the same as channels - """ + # padding value, size should be the same as channels return self._model.padding_value @property def is_no_pad(self): - """ - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - """ + # while is_mini_pad = false and is_no_pad = true, will resize the image to the set size return self._model.is_no_pad @property def is_mini_pad(self): - """ - only pad to the minimum rectange which height and width is times of stride - """ + # only pad to the minimum rectange which height and width is times of stride return self._model.is_mini_pad @property def is_scale_up(self): - """ - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - """ + # if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 return self._model.is_scale_up @property def stride(self): - """ - padding stride, for is_mini_pad - """ + # padding stride, for is_mini_pad return self._model.stride @size.setter diff --git a/python/fastdeploy/vision/detection/contrib/yolov7end2end_trt.py b/python/fastdeploy/vision/detection/contrib/yolov7end2end_trt.py index 3ee084273f6..4a2621b44cd 100644 --- a/python/fastdeploy/vision/detection/contrib/yolov7end2end_trt.py +++ b/python/fastdeploy/vision/detection/contrib/yolov7end2end_trt.py @@ -54,43 +54,33 @@ def predict(self, input_image, conf_threshold=0.25): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def padding_value(self): - """ - padding value, size should be the same as channels - """ + # padding value, size should be the same as channels return self._model.padding_value @property def is_no_pad(self): - """ - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - """ + # while is_mini_pad = false and is_no_pad = true, will resize the image to the set size return self._model.is_no_pad @property def is_mini_pad(self): - """ - only pad to the minimum rectange which height and width is times of stride - """ + # only pad to the minimum rectange which height and width is times of stride return self._model.is_mini_pad @property def is_scale_up(self): - """ - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - """ + # if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 return self._model.is_scale_up @property def stride(self): - """ - padding stride, for is_mini_pad - """ + # padding stride, for is_mini_pad return self._model.stride @size.setter diff --git a/python/fastdeploy/vision/detection/contrib/yolox.py b/python/fastdeploy/vision/detection/contrib/yolox.py index 0d643a4b377..c121cd80260 100644 --- a/python/fastdeploy/vision/detection/contrib/yolox.py +++ b/python/fastdeploy/vision/detection/contrib/yolox.py @@ -56,15 +56,13 @@ def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def padding_value(self): - """ - padding value, size should be the same as channels - """ + # padding value, size should be the same as channels return self._model.padding_value @property @@ -85,9 +83,7 @@ def downsample_strides(self): @property def max_wh(self): - """ - for offseting the boxes by classes when using NMS - """ + # for offseting the boxes by classes when using NMS return self._model.max_wh @size.setter diff --git a/python/fastdeploy/vision/facedet/contrib/retinaface.py b/python/fastdeploy/vision/facedet/contrib/retinaface.py index e959f5af381..9afa5055c64 100644 --- a/python/fastdeploy/vision/facedet/contrib/retinaface.py +++ b/python/fastdeploy/vision/facedet/contrib/retinaface.py @@ -56,35 +56,35 @@ def predict(self, input_image, conf_threshold=0.7, nms_iou_threshold=0.3): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def variance(self): """ - variance in RetinaFace's prior-box(anchor) generate process, default (0.1, 0.2) + Argument for image postprocessing step, variance in RetinaFace's prior-box(anchor) generate process, default (0.1, 0.2) """ return self._model.variance @property def downsample_strides(self): """ - downsample strides (namely, steps) for RetinaFace to generate anchors, will take (8,16,32) as default values + Argument for image postprocessing step, downsample strides (namely, steps) for RetinaFace to generate anchors, will take (8,16,32) as default values """ return self._model.downsample_strides @property def min_sizes(self): """ - min sizes, width and height for each anchor + Argument for image postprocessing step, min sizes, width and height for each anchor """ return self._model.min_sizes @property def landmarks_per_face(self): """ - landmarks_per_face, default 5 in RetinaFace + Argument for image postprocessing step, landmarks_per_face, default 5 in RetinaFace """ return self._model.landmarks_per_face diff --git a/python/fastdeploy/vision/facedet/contrib/scrfd.py b/python/fastdeploy/vision/facedet/contrib/scrfd.py index 85afd9e81d1..fa8e1cfd7d4 100644 --- a/python/fastdeploy/vision/facedet/contrib/scrfd.py +++ b/python/fastdeploy/vision/facedet/contrib/scrfd.py @@ -56,43 +56,33 @@ def predict(self, input_image, conf_threshold=0.7, nms_iou_threshold=0.3): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def padding_value(self): - """ - padding value, size should be the same as channels - """ + # padding value, size should be the same as channels return self._model.padding_value @property def is_no_pad(self): - """ - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - """ + # while is_mini_pad = false and is_no_pad = true, will resize the image to the set size return self._model.is_no_pad @property def is_mini_pad(self): - """ - only pad to the minimum rectange which height and width is times of stride - """ + # only pad to the minimum rectange which height and width is times of stride return self._model.is_mini_pad @property def is_scale_up(self): - """ - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - """ + # if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 return self._model.is_scale_up @property def stride(self): - """ - padding stride, for is_mini_pad - """ + # padding stride, for is_mini_pad return self._model.stride @property diff --git a/python/fastdeploy/vision/facedet/contrib/ultraface.py b/python/fastdeploy/vision/facedet/contrib/ultraface.py index 5b592d34d0a..8d84a6d86f7 100644 --- a/python/fastdeploy/vision/facedet/contrib/ultraface.py +++ b/python/fastdeploy/vision/facedet/contrib/ultraface.py @@ -56,7 +56,7 @@ def predict(self, input_image, conf_threshold=0.7, nms_iou_threshold=0.3): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size diff --git a/python/fastdeploy/vision/facedet/contrib/yolov5face.py b/python/fastdeploy/vision/facedet/contrib/yolov5face.py index 13d5ea9e154..be09e840a8a 100644 --- a/python/fastdeploy/vision/facedet/contrib/yolov5face.py +++ b/python/fastdeploy/vision/facedet/contrib/yolov5face.py @@ -56,49 +56,39 @@ def predict(self, input_image, conf_threshold=0.25, nms_iou_threshold=0.5): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def padding_value(self): - """ - padding value, size should be the same as channels - """ + # padding value, size should be the same as channels return self._model.padding_value @property def is_no_pad(self): - """ - while is_mini_pad = false and is_no_pad = true, will resize the image to the set size - """ + # while is_mini_pad = false and is_no_pad = true, will resize the image to the set size return self._model.is_no_pad @property def is_mini_pad(self): - """ - only pad to the minimum rectange which height and width is times of stride - """ + # only pad to the minimum rectange which height and width is times of stride return self._model.is_mini_pad @property def is_scale_up(self): - """ - if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 - """ + # if is_scale_up is false, the input image only can be zoom out, the maximum resize scale cannot exceed 1.0 return self._model.is_scale_up @property def stride(self): - """ - padding stride, for is_mini_pad - """ + # padding stride, for is_mini_pad return self._model.stride @property def landmarks_per_face(self): """ - landmarks_per_face, default 5 in YOLOv5Face + Argument for image postprocessing step, landmarks_per_face, default 5 in YOLOv5Face """ return self._model.landmarks_per_face diff --git a/python/fastdeploy/vision/faceid/contrib/adaface.py b/python/fastdeploy/vision/faceid/contrib/adaface.py index 1cbee19cd9b..c0b6d9b1dd5 100644 --- a/python/fastdeploy/vision/faceid/contrib/adaface.py +++ b/python/fastdeploy/vision/faceid/contrib/adaface.py @@ -52,35 +52,35 @@ def predict(self, input_image): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def alpha(self): """ - alpha value for normalization + Argument for image preprocessing step, alpha value for normalization """ return self._model.alpha @property def beta(self): """ - beta value for normalization + Argument for image preprocessing step, beta value for normalization """ return self._model.beta @property def swap_rb(self): """ - whether to swap the B and R channel, such as BGR->RGB, default true. + Argument for image preprocessing step, whether to swap the B and R channel, such as BGR->RGB, default true. """ return self._model.swap_rb @property def l2_normalize(self): """ - whether to apply l2 normalize to embedding values, default; + Argument for image preprocessing step, whether to apply l2 normalize to embedding values, default; """ return self._model.l2_normalize diff --git a/python/fastdeploy/vision/faceid/contrib/arcface.py b/python/fastdeploy/vision/faceid/contrib/arcface.py index e1e176784fe..be0a09d954c 100644 --- a/python/fastdeploy/vision/faceid/contrib/arcface.py +++ b/python/fastdeploy/vision/faceid/contrib/arcface.py @@ -54,35 +54,35 @@ def predict(self, input_image): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def alpha(self): """ - alpha value for normalization + Argument for image preprocessing step, alpha value for normalization """ return self._model.alpha @property def beta(self): """ - beta value for normalization + Argument for image preprocessing step, beta value for normalization """ return self._model.beta @property def swap_rb(self): """ - whether to swap the B and R channel, such as BGR->RGB, default true. + Argument for image preprocessing step, whether to swap the B and R channel, such as BGR->RGB, default true. """ return self._model.swap_rb @property def l2_normalize(self): """ - whether to apply l2 normalize to embedding values, default; + Argument for image preprocessing step, whether to apply l2 normalize to embedding values, default; """ return self._model.l2_normalize diff --git a/python/fastdeploy/vision/faceid/contrib/cosface.py b/python/fastdeploy/vision/faceid/contrib/cosface.py index 220301b271f..982f3c48106 100644 --- a/python/fastdeploy/vision/faceid/contrib/cosface.py +++ b/python/fastdeploy/vision/faceid/contrib/cosface.py @@ -53,35 +53,35 @@ def predict(self, input_image): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def alpha(self): """ - alpha value for normalization + Argument for image preprocessing step, alpha value for normalization """ return self._model.alpha @property def beta(self): """ - beta value for normalization + Argument for image preprocessing step, beta value for normalization """ return self._model.beta @property def swap_rb(self): """ - whether to swap the B and R channel, such as BGR->RGB, default true. + Argument for image preprocessing step, whether to swap the B and R channel, such as BGR->RGB, default true. """ return self._model.swap_rb @property def l2_normalize(self): """ - whether to apply l2 normalize to embedding values, default; + Argument for image preprocessing step, whether to apply l2 normalize to embedding values, default False; """ return self._model.l2_normalize diff --git a/python/fastdeploy/vision/faceid/contrib/insightface_rec.py b/python/fastdeploy/vision/faceid/contrib/insightface_rec.py index 7cc96d8920c..2793b88f4ea 100644 --- a/python/fastdeploy/vision/faceid/contrib/insightface_rec.py +++ b/python/fastdeploy/vision/faceid/contrib/insightface_rec.py @@ -53,35 +53,35 @@ def predict(self, input_image): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def alpha(self): """ - alpha value for normalization + Argument for image preprocessing step, alpha value for normalization """ return self._model.alpha @property def beta(self): """ - beta value for normalization + Argument for image preprocessing step, beta value for normalization """ return self._model.beta @property def swap_rb(self): """ - whether to swap the B and R channel, such as BGR->RGB, default true. + Argument for image preprocessing step, whether to swap the B and R channel, such as BGR->RGB, default true. """ return self._model.swap_rb @property def l2_normalize(self): """ - whether to apply l2 normalize to embedding values, default; + Argument for image preprocessing step, whether to apply l2 normalize to embedding values, default False; """ return self._model.l2_normalize diff --git a/python/fastdeploy/vision/faceid/contrib/partial_fc.py b/python/fastdeploy/vision/faceid/contrib/partial_fc.py index 5da57d4290a..de31b0a2730 100644 --- a/python/fastdeploy/vision/faceid/contrib/partial_fc.py +++ b/python/fastdeploy/vision/faceid/contrib/partial_fc.py @@ -53,35 +53,35 @@ def predict(self, input_image): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def alpha(self): """ - alpha value for normalization + Argument for image preprocessing step, alpha value for normalization """ return self._model.alpha @property def beta(self): """ - beta value for normalization + Argument for image preprocessing step, beta value for normalization """ return self._model.beta @property def swap_rb(self): """ - whether to swap the B and R channel, such as BGR->RGB, default true. + Argument for image preprocessing step, whether to swap the B and R channel, such as BGR->RGB, default true. """ return self._model.swap_rb @property def l2_normalize(self): """ - whether to apply l2 normalize to embedding values, default; + Argument for image preprocessing step, whether to apply l2 normalize to embedding values, default False; """ return self._model.l2_normalize diff --git a/python/fastdeploy/vision/faceid/contrib/vpl.py b/python/fastdeploy/vision/faceid/contrib/vpl.py index 651914f05b8..3a8df5f169f 100644 --- a/python/fastdeploy/vision/faceid/contrib/vpl.py +++ b/python/fastdeploy/vision/faceid/contrib/vpl.py @@ -53,35 +53,35 @@ def predict(self, input_image): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def alpha(self): """ - alpha value for normalization + Argument for image preprocessing step, alpha value for normalization """ return self._model.alpha @property def beta(self): """ - beta value for normalization + Argument for image preprocessing step, beta value for normalization """ return self._model.beta @property def swap_rb(self): """ - whether to swap the B and R channel, such as BGR->RGB, default true. + Argument for image preprocessing step, whether to swap the B and R channel, such as BGR->RGB, default true. """ return self._model.swap_rb @property def l2_normalize(self): """ - whether to apply l2 normalize to embedding values, default; + Argument for image preprocessing step, whether to apply l2 normalize to embedding values, default False; """ return self._model.l2_normalize diff --git a/python/fastdeploy/vision/matting/contrib/modnet.py b/python/fastdeploy/vision/matting/contrib/modnet.py index de4cc0b9657..33fb5a025d2 100644 --- a/python/fastdeploy/vision/matting/contrib/modnet.py +++ b/python/fastdeploy/vision/matting/contrib/modnet.py @@ -53,28 +53,28 @@ def predict(self, input_image): @property def size(self): """ - The preprocess image size, tuple of (width, height) + Argument for image preprocessing step, the preprocess image size, tuple of (width, height) """ return self._model.size @property def alpha(self): """ - alpha value for normalization + Argument for image preprocessing step, alpha value for normalization """ return self._model.alpha @property def beta(self): """ - beta value for normalization + Argument for image preprocessing step, beta value for normalization """ return self._model.beta @property def swap_rb(self): """ - whether to swap the B and R channel, such as BGR->RGB, default true. + Argument for image preprocessing step, whether to swap the B and R channel, such as BGR->RGB, default true. """ return self._model.swap_rb From 337e8c099bbdcb585abee64e11861e1ffee03562 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 24 Oct 2022 02:33:50 +0000 Subject: [PATCH 51/69] fix comments compile error --- fastdeploy/vision/facedet/contrib/retinaface.h | 4 ++-- fastdeploy/vision/facedet/contrib/scrfd.h | 4 ++-- .../vision/faceid/contrib/insightface_rec.h | 12 ++++++++---- fastdeploy/vision/matting/contrib/modnet.h | 16 +++++++++++----- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/fastdeploy/vision/facedet/contrib/retinaface.h b/fastdeploy/vision/facedet/contrib/retinaface.h index e669b8a4b76..e7011df89d0 100644 --- a/fastdeploy/vision/facedet/contrib/retinaface.h +++ b/fastdeploy/vision/facedet/contrib/retinaface.h @@ -53,8 +53,8 @@ class FASTDEPLOY_DECL RetinaFace : public FastDeployModel { float nms_iou_threshold = 0.4f); /*! @brief - Argument for image preprocessing step, tuple of (width, height), decide the target size after resize - */, default (640, 640) + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize, default (640, 640) + */ std::vector size; /*! @brief Argument for image postprocessing step, variance in RetinaFace's prior-box(anchor) generate process, default (0.1, 0.2) diff --git a/fastdeploy/vision/facedet/contrib/scrfd.h b/fastdeploy/vision/facedet/contrib/scrfd.h index ef82300d1bf..58dd8807b9e 100644 --- a/fastdeploy/vision/facedet/contrib/scrfd.h +++ b/fastdeploy/vision/facedet/contrib/scrfd.h @@ -52,8 +52,8 @@ class FASTDEPLOY_DECL SCRFD : public FastDeployModel { float nms_iou_threshold = 0.4f); /*! @brief - Argument for image preprocessing step, tuple of (width, height), decide the target size after resize - */, default (640, 640) + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize, default (640, 640) + */ std::vector size; // padding value, size should be the same as channels diff --git a/fastdeploy/vision/faceid/contrib/insightface_rec.h b/fastdeploy/vision/faceid/contrib/insightface_rec.h index 84d5c2471a6..12f882d7aa2 100644 --- a/fastdeploy/vision/faceid/contrib/insightface_rec.h +++ b/fastdeploy/vision/faceid/contrib/insightface_rec.h @@ -41,16 +41,20 @@ class FASTDEPLOY_DECL InsightFaceRecognitionModel : public FastDeployModel { virtual std::string ModelName() const { return "deepinsight/insightface"; } /*! @brief - Argument for image preprocessing step, tuple of (width, height), decide the target size after resize - */, default (112, 112) + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize, default (112, 112) + */ std::vector size; /// Argument for image preprocessing step, alpha values for normalization std::vector alpha; /// Argument for image preprocessing step, beta values for normalization std::vector beta; - /// Argument for image preprocessing step, whether to swap the B and R channel, such as BGR->RGB, default true. + /*! @brief + Argument for image preprocessing step, whether to swap the B and R channel, such as BGR->RGB, default true. + */ bool swap_rb; - /// Argument for image postprocessing step, whether to apply l2 normalize to embedding values, default false; + /*! @brief + Argument for image postprocessing step, whether to apply l2 normalize to embedding values, default false; + */ bool l2_normalize; /** \brief Predict the face recognition result for an input image * diff --git a/fastdeploy/vision/matting/contrib/modnet.h b/fastdeploy/vision/matting/contrib/modnet.h index e6c1b2a57f2..75148b60a12 100644 --- a/fastdeploy/vision/matting/contrib/modnet.h +++ b/fastdeploy/vision/matting/contrib/modnet.h @@ -40,14 +40,20 @@ class FASTDEPLOY_DECL MODNet : public FastDeployModel { std::string ModelName() const { return "matting/MODNet"; } /*! @brief - Argument for image preprocessing step, tuple of (width, height), decide the target size after resize - */, default (256, 256) + Argument for image preprocessing step, tuple of (width, height), decide the target size after resize, default (256, 256) + */ std::vector size; - /// Argument for image preprocessing step, parameters for normalization, size should be the the same as channels + /*! @brief + Argument for image preprocessing step, parameters for normalization, size should be the the same as channels + */ std::vector alpha; - /// Argument for image preprocessing step, parameters for normalization, size should be the the same as channels + /*! @brief + Argument for image preprocessing step, parameters for normalization, size should be the the same as channels + */ std::vector beta; - /// Argument for image preprocessing step, whether to swap the B and R channel, such as BGR->RGB, default true. + /*! @brief + Argument for image preprocessing step, whether to swap the B and R channel, such as BGR->RGB, default true. + */ bool swap_rb; /** \brief Predict the matting result for an input image * From d1d6890639a9325537ea38d9f22a24b35dfe9940 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 24 Oct 2022 06:26:59 +0000 Subject: [PATCH 52/69] modify result.h comments --- fastdeploy/vision/common/result.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fastdeploy/vision/common/result.h b/fastdeploy/vision/common/result.h index 6bdd08dc53b..2cc4942403a 100644 --- a/fastdeploy/vision/common/result.h +++ b/fastdeploy/vision/common/result.h @@ -170,7 +170,8 @@ struct FASTDEPLOY_DECL FaceDetectionResult : public BaseResult { std::vector scores; ResultType type = ResultType::FACE_DETECTION; /** \brief - * User can set landmarks_per_face manually in the post processes. + * `landmarks_per_face` indicates the number of face landmarks for each detected face + * if the model's output contains face landmarks (such as YOLOv5Face, SCRFD, ...) */ int landmarks_per_face; @@ -190,11 +191,11 @@ struct FASTDEPLOY_DECL FaceDetectionResult : public BaseResult { */ struct FASTDEPLOY_DECL SegmentationResult : public BaseResult { /** \brief - * label_map stores the pixel-level category labels for input image. the number of pixels is equal to label_map.size() + * `label_map` stores the pixel-level category labels for input image. the number of pixels is equal to label_map.size() */ std::vector label_map; /** \brief - * score_map stores the probability of the predicted label for each pixel of input image. + * `score_map` stores the probability of the predicted label for each pixel of input image. */ std::vector score_map; /// The output shape, means [H, W] @@ -236,13 +237,12 @@ struct FASTDEPLOY_DECL FaceRecognitionResult : public BaseResult { /*! @brief Matting result structure for all the Matting models */ struct FASTDEPLOY_DECL MattingResult : public BaseResult { - // alpha matte and fgr (predicted foreground: HWC/BGR float32) /** \brief - alpha is a one-dimensional vector, which is the predicted alpha transparency value. The range of values is [0., 1.], and the length is hxw. h, w are the height and width of the input image + `alpha` is a one-dimensional vector, which is the predicted alpha transparency value. The range of values is [0., 1.], and the length is hxw. h, w are the height and width of the input image */ std::vector alpha; // h x w /** \brief - If the model can predict foreground, foreground save the predicted foreground image, the shape is [hight,width,channel] generally. + If the model can predict foreground, `foreground` save the predicted foreground image, the shape is [hight,width,channel] generally. */ std::vector foreground; // h x w x c (c=3 default) /** \brief From 0c60494833132a6ce8874cd24b0cc1b9467541de Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Thu, 3 Nov 2022 10:00:58 +0000 Subject: [PATCH 53/69] c++ version for FaceLandmark1000 --- .../facealign/face_landmark_1000/README.md | 25 ++++ .../face_landmark_1000/cpp/CMakeLists.txt | 14 ++ .../face_landmark_1000/cpp/README.md | 84 +++++++++++ .../facealign/face_landmark_1000/cpp/infer.cc | 110 ++++++++++++++ .../face_landmark_1000/python/README.md | 71 +++++++++ .../face_landmark_1000/python/infer.py | 88 +++++++++++ fastdeploy/vision.h | 1 + .../common/processors/color_space_convert.cc | 57 +++++++ .../common/processors/color_space_convert.h | 24 +++ fastdeploy/vision/common/result.cc | 5 +- .../facealign/contrib/face_landmark_1000.cc | 133 +++++++++++++++++ .../facealign/contrib/face_landmark_1000.h | 65 ++++++++ .../contrib/face_landmark_1000_pybind.cc | 31 ++++ fastdeploy/vision/facealign/contrib/pipnet.cc | 140 ++++++++++++++++++ fastdeploy/vision/facealign/contrib/pipnet.h | 73 +++++++++ .../vision/facealign/contrib/pipnet_pybind.cc | 31 ++++ 16 files changed, 951 insertions(+), 1 deletion(-) create mode 100644 examples/vision/facealign/face_landmark_1000/README.md create mode 100644 examples/vision/facealign/face_landmark_1000/cpp/CMakeLists.txt create mode 100644 examples/vision/facealign/face_landmark_1000/cpp/README.md create mode 100644 examples/vision/facealign/face_landmark_1000/cpp/infer.cc create mode 100644 examples/vision/facealign/face_landmark_1000/python/README.md create mode 100644 examples/vision/facealign/face_landmark_1000/python/infer.py create mode 100644 fastdeploy/vision/facealign/contrib/face_landmark_1000.cc create mode 100644 fastdeploy/vision/facealign/contrib/face_landmark_1000.h create mode 100644 fastdeploy/vision/facealign/contrib/face_landmark_1000_pybind.cc create mode 100644 fastdeploy/vision/facealign/contrib/pipnet.cc create mode 100644 fastdeploy/vision/facealign/contrib/pipnet.h create mode 100644 fastdeploy/vision/facealign/contrib/pipnet_pybind.cc diff --git a/examples/vision/facealign/face_landmark_1000/README.md b/examples/vision/facealign/face_landmark_1000/README.md new file mode 100644 index 00000000000..5609ff045c7 --- /dev/null +++ b/examples/vision/facealign/face_landmark_1000/README.md @@ -0,0 +1,25 @@ +# PFLD 模型部署 + +## 模型版本说明 + +- [FaceLandmark1000](https://github.com/Single430/FaceLandmark1000/commit/1a951b6) + +## 支持模型列表 + +目前FastDeploy支持如下模型的部署 + +- [FaceLandmark1000 模型](https://github.com/Single430/FaceLandmark1000) + +## 下载预训练模型 + +为了方便开发者的测试,下面提供了PFLD导出的各系列模型,开发者可直接下载使用。 + +| 模型 | 参数大小 | 精度 | 备注 | +|:---------------------------------------------------------------- |:----- |:----- | :------ | +| [FaceLandmark1000.onnx](https://bj.bcebos.com/paddlehub/fastdeploy/TODO) | 2.1M | - | + + +## 详细部署文档 + +- [Python部署](python) +- [C++部署](cpp) diff --git a/examples/vision/facealign/face_landmark_1000/cpp/CMakeLists.txt b/examples/vision/facealign/face_landmark_1000/cpp/CMakeLists.txt new file mode 100644 index 00000000000..c6c754a4b50 --- /dev/null +++ b/examples/vision/facealign/face_landmark_1000/cpp/CMakeLists.txt @@ -0,0 +1,14 @@ +PROJECT(infer_demo C CXX) +CMAKE_MINIMUM_REQUIRED (VERSION 3.10) + +# 指定下载解压后的fastdeploy库路径 +option(FASTDEPLOY_INSTALL_DIR "Path of downloaded fastdeploy sdk.") +include(${FASTDEPLOY_INSTALL_DIR}/utils/gflags.cmake) +include(${FASTDEPLOY_INSTALL_DIR}/FastDeploy.cmake) + +# 添加FastDeploy依赖头文件 +include_directories(${FASTDEPLOY_INCS}) + +add_executable(infer_demo ${PROJECT_SOURCE_DIR}/infer.cc) +# 添加FastDeploy库依赖 +target_link_libraries(infer_demo ${FASTDEPLOY_LIBS} gflags pthread) diff --git a/examples/vision/facealign/face_landmark_1000/cpp/README.md b/examples/vision/facealign/face_landmark_1000/cpp/README.md new file mode 100644 index 00000000000..4138646d262 --- /dev/null +++ b/examples/vision/facealign/face_landmark_1000/cpp/README.md @@ -0,0 +1,84 @@ +# PFLD C++部署示例 + +本目录下提供`infer.cc`快速完成PFLD在CPU/GPU,以及GPU上通过TensorRT加速部署的示例。 + +在部署前,需确认以下两个步骤 + +- 1. 软硬件环境满足要求,参考[FastDeploy环境要求](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) +- 2. 根据开发环境,下载预编译部署库和samples代码,参考[FastDeploy预编译库](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) + +以Linux上CPU推理为例,在本目录执行如下命令即可完成编译测试,保证 FastDeploy 版本0.6.0以上(x.x.x >= 0.6.0)支持PFLD模型 + +```bash +mkdir build +cd build +wget https://bj.bcebos.com/fastdeploy/release/cpp/fastdeploy-linux-x64-x.x.x.tgz +tar xvf fastdeploy-linux-x64-x.x.x.tgz +cmake .. -DFASTDEPLOY_INSTALL_DIR=${PWD}/fastdeploy-linux-x64-x.x.x +make -j + +#下载官方转换好的 PFLD 模型文件和测试图片 +wget https://bj.bcebos.com/paddlehub/fastdeploy/pfld-106-lite.onnx +wget https://bj.bcebos.com/paddlehub/fastdeploy/facealign_input.png + +# CPU推理 +./infer_demo --model pfld-106-lite.onnx --image facealign_input.png --device cpu +# GPU推理 +./infer_demo --model pfld-106-lite.onnx --image facealign_input.png --device gpu +# GPU上TensorRT推理 +./infer_demo --model pfld-106-lite.onnx --image facealign_input.png --device gpu --backend trt +``` + +运行完成可视化结果如下图所示 + +
+ +
+ +以上命令只适用于Linux或MacOS, Windows下SDK的使用方式请参考: +- [如何在Windows中使用FastDeploy C++ SDK](../../../../../docs/cn/faq/use_sdk_on_windows.md) + +## PFLD C++接口 + +### PFLD 类 + +```c++ +fastdeploy::vision::facealign::PFLD( + const string& model_file, + const string& params_file = "", + const RuntimeOption& runtime_option = RuntimeOption(), + const ModelFormat& model_format = ModelFormat::ONNX) +``` + +PFLD模型加载和初始化,其中model_file为导出的ONNX模型格式。 + +**参数** + +> * **model_file**(str): 模型文件路径 +> * **params_file**(str): 参数文件路径,当模型格式为ONNX时,此参数传入空字符串即可 +> * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置 +> * **model_format**(ModelFormat): 模型格式,默认为ONNX格式 + +#### Predict函数 + +> ```c++ +> PFLD::Predict(cv::Mat* im, FaceAlignmentResult* result) +> ``` +> +> 模型预测接口,输入图像直接输出landmarks结果。 +> +> **参数** +> +> > * **im**: 输入图像,注意需为HWC,BGR格式 +> > * **result**: landmarks结果, FaceAlignmentResult说明参考[视觉模型预测结果](../../../../../docs/api/vision_results/) + +### 类成员变量 + +用户可按照自己的实际需求,修改下列预处理参数,从而影响最终的推理和部署效果 + +> > * **size**(vector<int>): 通过此参数修改预处理过程中resize的大小,包含两个整型元素,表示[width, height], 默认值为[112, 112] + +- [模型介绍](../../) +- [Python部署](../python) +- [视觉模型预测结果](../../../../../docs/api/vision_results/) +- [如何切换模型推理后端引擎](../../../../../docs/cn/faq/how_to_change_backend.md) diff --git a/examples/vision/facealign/face_landmark_1000/cpp/infer.cc b/examples/vision/facealign/face_landmark_1000/cpp/infer.cc new file mode 100644 index 00000000000..702d9609a80 --- /dev/null +++ b/examples/vision/facealign/face_landmark_1000/cpp/infer.cc @@ -0,0 +1,110 @@ +// 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/vision.h" +#include "gflags/gflags.h" + +DEFINE_string(model, "", "Directory of the inference model."); +DEFINE_string(image, "", "Path of the image file."); +DEFINE_string(device, "cpu", + "Type of inference device, support 'cpu' or 'gpu'."); +DEFINE_string(backend, "default", + "The inference runtime backend, support: ['default', 'ort', " + "'paddle', 'ov', 'trt', 'paddle_trt']"); +DEFINE_bool(use_fp16, false, "Whether to use FP16 mode, only support 'trt' and 'paddle_trt' backend"); + +void PrintUsage() { + std::cout << "Usage: infer_demo --model model_path --image img_path --device [cpu|gpu] --backend " + "[default|ort|paddle|ov|trt|paddle_trt] " + "--use_fp16 false" + << std::endl; + std::cout << "Default value of device: cpu" << std::endl; + std::cout << "Default value of backend: default" << std::endl; + std::cout << "Default value of use_fp16: false" << std::endl; +} + +bool CreateRuntimeOption(fastdeploy::RuntimeOption* option) { + if (FLAGS_device == "gpu") { + option->UseGpu(); + if (FLAGS_backend == "ort") { + option->UseOrtBackend(); + } else if (FLAGS_backend == "paddle") { + option->UsePaddleBackend(); + } else if (FLAGS_backend == "trt" || + FLAGS_backend == "paddle_trt") { + option->UseTrtBackend(); + option->SetTrtInputShape("input", {1, 3, 128, 128}); + if (FLAGS_backend == "paddle_trt") { + option->EnablePaddleToTrt(); + } + if (FLAGS_use_fp16) { + option->EnableTrtFP16(); + } + } else if (FLAGS_backend == "default") { + return true; + } else { + std::cout << "While inference with GPU, only support default/ort/paddle/trt/paddle_trt now, " << FLAGS_backend << " is not supported." << std::endl; + return false; + } + } else if (FLAGS_device == "cpu") { + if (FLAGS_backend == "ort") { + option->UseOrtBackend(); + } else if (FLAGS_backend == "ov") { + option->UseOpenVINOBackend(); + } else if (FLAGS_backend == "paddle") { + option->UsePaddleBackend(); + } else if (FLAGS_backend == "default") { + return true; + } else { + std::cout << "While inference with CPU, only support default/ort/ov/paddle now, " << FLAGS_backend << " is not supported." << std::endl; + return false; + } + } else { + std::cerr << "Only support device CPU/GPU now, " << FLAGS_device << " is not supported." << std::endl; + return false; + } + + return true; +} + +int main(int argc, char* argv[]) { + google::ParseCommandLineFlags(&argc, &argv, true); + auto option = fastdeploy::RuntimeOption(); + if (!CreateRuntimeOption(&option)) { + PrintUsage(); + return -1; + } + + auto model = fastdeploy::vision::facealign::FaceLandmark1000(FLAGS_model, "", option); + if (!model.Initialized()) { + std::cerr << "Failed to initialize." << std::endl; + return -1; + } + + auto im = cv::imread(FLAGS_image); + auto im_bak = im.clone(); + + fastdeploy::vision::FaceAlignmentResult res; + if (!model.Predict(&im, &res)) { + std::cerr << "Failed to predict." << std::endl; + return -1; + } + std::cout << res.Str() << std::endl; + + auto vis_im = fastdeploy::vision::VisFaceAlignment(im_bak, res); + cv::imwrite("vis_result.jpg", vis_im); + std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl; + + return 0; +} diff --git a/examples/vision/facealign/face_landmark_1000/python/README.md b/examples/vision/facealign/face_landmark_1000/python/README.md new file mode 100644 index 00000000000..e9fdf545e42 --- /dev/null +++ b/examples/vision/facealign/face_landmark_1000/python/README.md @@ -0,0 +1,71 @@ +# PFLD Python部署示例 + +在部署前,需确认以下两个步骤 + +- 1. 软硬件环境满足要求,参考[FastDeploy环境要求](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) +- 2. FastDeploy Python whl包安装,参考[FastDeploy Python安装](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) + +本目录下提供`infer.py`快速完成PFLD在CPU/GPU,以及GPU上通过TensorRT加速部署的示例,保证 FastDeploy 版本 >= 0.6.0 支持PFLD模型。执行如下脚本即可完成 + +```bash +#下载部署示例代码 +git clone https://github.com/PaddlePaddle/FastDeploy.git +cd FastDeploy/examples/vision/facealign/pfld/python + +# 下载PFLD模型文件和测试图片以及视频 +## 原版ONNX模型 +wget https://bj.bcebos.com/paddlehub/fastdeploy/pfld-106-lite.onnx +wget https://bj.bcebos.com/paddlehub/fastdeploy/facealign_input.png + +# CPU推理 +python infer.py --model pfld-106-lite.onnx --image facealign_input.png --device cpu +# GPU推理 +python infer.py --model pfld-106-lite.onnx --image facealign_input.png --device gpu +# TRT推理 +python infer.py --model pfld-106-lite.onnx --image facealign_input.png --device gpu --backend trt +``` + +运行完成可视化结果如下图所示 + +
+ +
+ +## PFLD Python接口 + +```python +fd.vision.facealign.PFLD(model_file, params_file=None, runtime_option=None, model_format=ModelFormat.ONNX) +``` + +PFLD模型加载和初始化,其中model_file为导出的ONNX模型格式 + +**参数** + +> * **model_file**(str): 模型文件路径 +> * **params_file**(str): 参数文件路径,当模型格式为ONNX格式时,此参数无需设定 +> * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置 +> * **model_format**(ModelFormat): 模型格式,默认为ONNX + +### predict函数 + +> ```python +> PFLD.predict(input_image) +> ``` +> +> 模型预测结口,输入图像直接输出landmarks坐标结果。 +> +> **参数** +> +> > * **input_image**(np.ndarray): 输入数据,注意需为HWC,BGR格式 + +> **返回** +> +> > 返回`fastdeploy.vision.FaceAlignmentResult`结构体,结构体说明参考文档[视觉模型预测结果](../../../../../docs/api/vision_results/) + + +## 其它文档 + +- [PFLD 模型介绍](..) +- [PFLD C++部署](../cpp) +- [模型预测结果说明](../../../../../docs/api/vision_results/) +- [如何切换模型推理后端引擎](../../../../../docs/cn/faq/how_to_change_backend.md) diff --git a/examples/vision/facealign/face_landmark_1000/python/infer.py b/examples/vision/facealign/face_landmark_1000/python/infer.py new file mode 100644 index 00000000000..d185cb5321a --- /dev/null +++ b/examples/vision/facealign/face_landmark_1000/python/infer.py @@ -0,0 +1,88 @@ +import fastdeploy as fd +import cv2 +import os + + +def parse_arguments(): + import argparse + import ast + parser = argparse.ArgumentParser() + parser.add_argument("--model", required=True, help="Path of PFLD model.") + parser.add_argument("--image", type=str, help="Path of test image file.") + parser.add_argument( + "--device", + type=str, + default='cpu', + help="Type of inference device, support 'cpu' or 'gpu'.") + parser.add_argument( + "--backend", + type=str, + default="ort", + help="inference backend, ort, ov, trt, paddle, paddle_trt.") + parser.add_argument( + "--enable_trt_fp16", + type=bool, + default=False, + help="whether enable fp16 in trt/paddle_trt backend") + return parser.parse_args() + + +def build_option(args): + option = fd.RuntimeOption() + device = args.device + backend = args.backend + enable_trt_fp16 = args.enable_trt_fp16 + if device == "gpu": + option.use_gpu() + if backend == "ort": + option.use_ort_backend() + elif backend == "paddle": + option.use_paddle_backend() + elif backend in ["trt", "paddle_trt"]: + option.use_trt_backend() + option.set_trt_input_shape("input", [1, 3, 112, 112]) + if backend == "paddle_trt": + option.enable_paddle_to_trt() + if enable_trt_fp16: + option.enable_trt_fp16() + elif backend == "default": + return option + else: + raise Exception( + "While inference with GPU, only support default/ort/paddle/trt/paddle_trt now, {} is not supported.". + format(backend)) + elif device == "cpu": + if backend == "ort": + option.use_ort_backend() + elif backend == "ov": + option.use_openvino_backend() + elif backend == "paddle": + option.use_paddle_backend() + elif backend == "default": + return option + else: + raise Exception( + "While inference with CPU, only support default/ort/ov/paddle now, {} is not supported.". + format(backend)) + else: + raise Exception( + "Only support device CPU/GPU now, {} is not supported.".format( + device)) + + return option + + +args = parse_arguments() + +# 配置runtime,加载模型 +runtime_option = build_option(args) +model = fd.vision.facealign.PFLD(args.model, runtime_option=runtime_option) + +# for image +im = cv2.imread(args.image) +result = model.predict(im.copy()) +print(result) +# 可视化结果 +vis_im = fd.vision.vis_face_alignment(im, result) +cv2.imwrite("visualized_result.jpg", vis_im) +print("Visualized result save in ./visualized_result.jpg") diff --git a/fastdeploy/vision.h b/fastdeploy/vision.h index c3f99a6ca65..a9b4e488c67 100755 --- a/fastdeploy/vision.h +++ b/fastdeploy/vision.h @@ -34,6 +34,7 @@ #include "fastdeploy/vision/facedet/contrib/ultraface.h" #include "fastdeploy/vision/facedet/contrib/yolov5face.h" #include "fastdeploy/vision/facealign/contrib/pfld.h" +#include "fastdeploy/vision/facealign/contrib/face_landmark_1000.h" #include "fastdeploy/vision/faceid/contrib/adaface.h" #include "fastdeploy/vision/faceid/contrib/arcface.h" #include "fastdeploy/vision/faceid/contrib/cosface.h" diff --git a/fastdeploy/vision/common/processors/color_space_convert.cc b/fastdeploy/vision/common/processors/color_space_convert.cc index 15e8aa42650..9c71d708a88 100644 --- a/fastdeploy/vision/common/processors/color_space_convert.cc +++ b/fastdeploy/vision/common/processors/color_space_convert.cc @@ -60,6 +60,52 @@ bool RGB2BGR::ImplByFalconCV(Mat* mat) { } #endif +bool BGR2GRAY::ImplByOpenCV(Mat* mat) { + cv::Mat* im = mat->GetOpenCVMat(); + cv::Mat new_im; + cv::cvtColor(*im, new_im, cv::COLOR_BGR2GRAY); + mat->SetMat(new_im); + mat->SetChannels(1); + return true; +} + +#ifdef ENABLE_FLYCV +bool BGR2GRAY::ImplByFalconCV(Mat* mat) { + fcv::Mat* im = mat->GetFalconCVMat(); + if (im->channels() != 3) { + FDERROR << "[BGR2GRAY] The channel of input image must be 3, but not it's " << im->channels() << "." << std::endl; + return false; + } + fcv::Mat new_im; + fcv::cvt_color(*im, new_im, fcv::ColorConvertType::CVT_PA_BGR2GRAY); + mat->SetMat(new_im); + return true; +} +#endif + +bool RGB2GRAY::ImplByOpenCV(Mat* mat) { + cv::Mat* im = mat->GetOpenCVMat(); + cv::Mat new_im; + cv::cvtColor(*im, new_im, cv::COLOR_RGB2GRAY); + mat->SetMat(new_im); + return true; +} + +#ifdef ENABLE_FLYCV +bool RGB2GRAY::ImplByFalconCV(Mat* mat) { + fcv::Mat* im = mat->GetFalconCVMat(); + if (im->channels() != 3) { + FDERROR << "[RGB2GRAY] The channel of input image must be 3, but not it's " << im->channels() << "." << std::endl; + return false; + } + fcv::Mat new_im; + fcv::cvt_color(*im, new_im, fcv::ColorConvertType::CVT_PA_RGB2GRAY); + mat->SetMat(new_im); + return true; +} +#endif + + bool BGR2RGB::Run(Mat* mat, ProcLib lib) { auto b = BGR2RGB(); return b(mat, lib); @@ -70,5 +116,16 @@ bool RGB2BGR::Run(Mat* mat, ProcLib lib) { return r(mat, lib); } +bool BGR2GRAY::Run(Mat* mat, ProcLib lib) { + auto b = BGR2GRAY(); + return b(mat, lib); +} + +bool RGB2GRAY::Run(Mat* mat, ProcLib lib) { + auto r = RGB2GRAY(); + return r(mat, lib); +} + + } // namespace vision } // namespace fastdeploy diff --git a/fastdeploy/vision/common/processors/color_space_convert.h b/fastdeploy/vision/common/processors/color_space_convert.h index ad66acd4f30..fe44c12fc77 100644 --- a/fastdeploy/vision/common/processors/color_space_convert.h +++ b/fastdeploy/vision/common/processors/color_space_convert.h @@ -40,5 +40,29 @@ class FASTDEPLOY_DECL RGB2BGR : public Processor { static bool Run(Mat* mat, ProcLib lib = ProcLib::OPENCV); }; + +class FASTDEPLOY_DECL BGR2GRAY : public Processor { + public: + bool ImplByOpenCV(Mat* mat); +#ifdef ENABLE_FLYCV + bool ImplByFalconCV(Mat* mat); +#endif + virtual std::string Name() { return "BGR2GRAY"; } + + static bool Run(Mat* mat, ProcLib lib = ProcLib::OPENCV); +}; + +class FASTDEPLOY_DECL RGB2GRAY : public Processor { + public: + bool ImplByOpenCV(Mat* mat); +#ifdef ENABLE_FLYCV + bool ImplByFalconCV(Mat* mat); +#endif + std::string Name() { return "RGB2GRAY"; } + + static bool Run(Mat* mat, ProcLib lib = ProcLib::OPENCV); +}; + + } // namespace vision } // namespace fastdeploy diff --git a/fastdeploy/vision/common/result.cc b/fastdeploy/vision/common/result.cc index ea5cdd14960..48e6bed7052 100644 --- a/fastdeploy/vision/common/result.cc +++ b/fastdeploy/vision/common/result.cc @@ -251,7 +251,10 @@ std::string FaceAlignmentResult::Str() { std::string out; out = "FaceAlignmentResult: [x, y]\n"; - for (size_t i = 0; i < landmarks.size(); ++i) { + FDASSERT((landmarks.size() >= 10), + "Predict error: the size of landmarks are less than 10."); + out = out + "There are " +std::to_string(landmarks.size()) + " landmarks, the top 10 are listed as below:\n"; + for (size_t i = 0; i < 10; ++i) { out = out + std::to_string(landmarks[i][0]) + "," + std::to_string(landmarks[i][1]) + "\n"; } diff --git a/fastdeploy/vision/facealign/contrib/face_landmark_1000.cc b/fastdeploy/vision/facealign/contrib/face_landmark_1000.cc new file mode 100644 index 00000000000..996d252e36c --- /dev/null +++ b/fastdeploy/vision/facealign/contrib/face_landmark_1000.cc @@ -0,0 +1,133 @@ +// 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/vision/facealign/contrib/face_landmark_1000.h" +#include "fastdeploy/utils/perf.h" +#include "fastdeploy/vision/utils/utils.h" + +namespace fastdeploy { + +namespace vision { + +namespace facealign { + +FaceLandmark1000::FaceLandmark1000(const std::string& model_file, + const std::string& params_file, + const RuntimeOption& custom_option, + const ModelFormat& model_format) { + if (model_format == ModelFormat::ONNX) { + valid_cpu_backends = {Backend::OPENVINO, Backend::ORT}; + valid_gpu_backends = {Backend::ORT, Backend::TRT}; + } else { + valid_cpu_backends = {Backend::PDINFER, Backend::ORT}; + valid_gpu_backends = {Backend::PDINFER, Backend::ORT, Backend::TRT}; + } + runtime_option = custom_option; + runtime_option.model_format = model_format; + runtime_option.model_file = model_file; + runtime_option.params_file = params_file; + initialized = Initialize(); +} + +bool FaceLandmark1000::Initialize() { + // parameters for preprocess + size = {128, 128}; + + if (!InitRuntime()) { + FDERROR << "Failed to initialize fastdeploy backend." << std::endl; + return false; + } + return true; +} + +bool FaceLandmark1000::Preprocess(Mat* mat, FDTensor* output, + std::map>* im_info) { + // Resize + int resize_w = size[0]; + int resize_h = size[1]; + if (resize_h != mat->Height() || resize_w != mat->Width()) { + Resize::Run(mat, resize_w, resize_h); + } + + // BRG2GRAY + BGR2GRAY::Run(mat); + + // Record output shape of preprocessed image + (*im_info)["output_shape"] = {mat->Height(), mat->Width()}; + HWC2CHW::Run(mat); + Cast::Run(mat, "float"); + mat->ShareWithTensor(output); + output->shape.insert(output->shape.begin(), 1); // reshape to n, h, w, c + return true; +} + +bool FaceLandmark1000::Postprocess(FDTensor& infer_result, FaceAlignmentResult* result, + const std::map>& im_info) { + FDASSERT(infer_result.shape[0] == 1, "Only support batch = 1 now."); + if (infer_result.dtype != FDDataType::FP32) { + FDERROR << "Only support post process with float32 data." << std::endl; + return false; + } + + auto iter_in = im_info.find("input_shape"); + FDASSERT(iter_in != im_info.end(), + "Cannot find input_shape from im_info."); + int in_h = iter_in->second[0]; + int in_w = iter_in->second[1]; + + result->Clear(); + float* data = static_cast(infer_result.Data()); + for (size_t i = 0; i < infer_result.shape[1]; i += 2) { + float x = data[i]; + float y = data[i + 1]; + x = std::min(std::max(0.f, x), 1.0f); + y = std::min(std::max(0.f, y), 1.0f); + // decode landmarks (default 106 landmarks) + result->landmarks.emplace_back( + std::array{x * in_w, y * in_h}); + } + + return true; +} + +bool FaceLandmark1000::Predict(cv::Mat* im, FaceAlignmentResult* result) { + Mat mat(*im); + std::vector input_tensors(1); + + std::map> im_info; + + // Record the shape of image and the shape of preprocessed image + im_info["input_shape"] = {mat.Height(), mat.Width()}; + im_info["output_shape"] = {mat.Height(), mat.Width()}; + + if (!Preprocess(&mat, &input_tensors[0], &im_info)) { + FDERROR << "Failed to preprocess input image." << std::endl; + return false; + } + input_tensors[0].name = InputInfoOfRuntime(0).name; + std::vector output_tensors; + if (!Infer(input_tensors, &output_tensors)) { + FDERROR << "Failed to inference." << std::endl; + return false; + } + if (!Postprocess(output_tensors[0], result, im_info)) { + FDERROR << "Failed to post process." << std::endl; + return false; + } + return true; +} + +} // namespace facealign +} // namespace vision +} // namespace fastdeploy \ No newline at end of file diff --git a/fastdeploy/vision/facealign/contrib/face_landmark_1000.h b/fastdeploy/vision/facealign/contrib/face_landmark_1000.h new file mode 100644 index 00000000000..b3a230c7752 --- /dev/null +++ b/fastdeploy/vision/facealign/contrib/face_landmark_1000.h @@ -0,0 +1,65 @@ +// 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. + +#pragma once +#include "fastdeploy/fastdeploy_model.h" +#include "fastdeploy/vision/common/processors/transform.h" +#include "fastdeploy/vision/common/result.h" + +namespace fastdeploy { + +namespace vision { + +namespace facealign { +/*! @brief FaceLandmark1000 model object used when to load a FaceLandmark1000 model exported by FaceLandmark1000. + */ +class FASTDEPLOY_DECL FaceLandmark1000 : public FastDeployModel { + public: + /** \brief Set path of model file and the configuration of runtime. + * + * \param[in] model_file Path of model file, e.g ./face_landmarks_1000.onnx + * \param[in] params_file Path of parameter file, e.g ppyoloe/model.pdiparams, if the model format is ONNX, this parameter will be ignored + * \param[in] custom_option RuntimeOption for inference, the default will use cpu, and choose the backend defined in "valid_cpu_backends" + * \param[in] model_format Model format of the loaded model, default is ONNX format + */ + FaceLandmark1000(const std::string& model_file, + const std::string& params_file = "", + const RuntimeOption& custom_option = RuntimeOption(), + const ModelFormat& model_format = ModelFormat::ONNX); + + std::string ModelName() const { return "FaceLandmark1000"; } + /** \brief Predict the face detection result for an input image + * + * \param[in] im The input image data, comes from cv::imread(), is a 3-D array with layout HWC, BGR format + * \param[in] result The output face detection result will be writen to this structure + * \return true if the prediction successed, otherwise false + */ + virtual bool Predict(cv::Mat* im, FaceAlignmentResult* result); + + /// tuple of (width, height), default (128, 128) + std::vector size; + + private: + bool Initialize(); + + bool Preprocess(Mat* mat, FDTensor* outputs, + std::map>* im_info); + + bool Postprocess(FDTensor& infer_result, FaceAlignmentResult* result, + const std::map>& im_info); +}; + +} // namespace facealign +} // namespace vision +} // namespace fastdeploy diff --git a/fastdeploy/vision/facealign/contrib/face_landmark_1000_pybind.cc b/fastdeploy/vision/facealign/contrib/face_landmark_1000_pybind.cc new file mode 100644 index 00000000000..ff3151b4cd1 --- /dev/null +++ b/fastdeploy/vision/facealign/contrib/face_landmark_1000_pybind.cc @@ -0,0 +1,31 @@ +// 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 BindFaceLandmark1000(pybind11::module& m) { + pybind11::class_(m, "FaceLandmark1000") + .def(pybind11::init()) + .def("predict", + [](vision::facealign::FaceLandmark1000& self, pybind11::array& data) { + auto mat = PyArrayToCvMat(data); + vision::FaceAlignmentResult res; + self.Predict(&mat, &res); + return res; + }) + .def_readwrite("size", &vision::facealign::FaceLandmark1000::size); +} +} // namespace fastdeploy \ No newline at end of file diff --git a/fastdeploy/vision/facealign/contrib/pipnet.cc b/fastdeploy/vision/facealign/contrib/pipnet.cc new file mode 100644 index 00000000000..3461003fba5 --- /dev/null +++ b/fastdeploy/vision/facealign/contrib/pipnet.cc @@ -0,0 +1,140 @@ +// 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/vision/facealign/contrib/pipnet.h" +#include "fastdeploy/utils/perf.h" +#include "fastdeploy/vision/utils/utils.h" + +namespace fastdeploy { + +namespace vision { + +namespace facealign { + + + +PIPNet::PIPNet(const std::string& model_file, + const std::string& params_file, + const RuntimeOption& custom_option, + const ModelFormat& model_format) { + if (model_format == ModelFormat::ONNX) { + valid_cpu_backends = {Backend::OPENVINO, Backend::ORT}; + valid_gpu_backends = {Backend::ORT, Backend::TRT}; + } else { + valid_cpu_backends = {Backend::PDINFER, Backend::ORT}; + valid_gpu_backends = {Backend::PDINFER, Backend::ORT, Backend::TRT}; + } + runtime_option = custom_option; + runtime_option.model_format = model_format; + runtime_option.model_file = model_file; + runtime_option.params_file = params_file; + initialized = Initialize(); +} + +bool PIPNet::Initialize() { + // parameters for preprocess + size = {256, 256}; + mean_vals = {0.485f, 0.456f, 0.406f}; + std_vals = {0.229f, 0.224f, 0.225f}; + if (!InitRuntime()) { + FDERROR << "Failed to initialize fastdeploy backend." << std::endl; + return false; + } + return true; +} + +bool PIPNet::Preprocess(Mat* mat, FDTensor* output, + std::map>* im_info) { + // Resize + int resize_w = size[0]; + int resize_h = size[1]; + if (resize_h != mat->Height() || resize_w != mat->Width()) { + Resize::Run(mat, resize_w, resize_h); + } + // RGR2RGB + BGR2RGB::Run(mat); + + // Normalize + Normalize::Run(mat, mean_vals, std_vals); + + // Record output shape of preprocessed image + (*im_info)["output_shape"] = {mat->Height(), mat->Width()}; + + HWC2CHW::Run(mat); + Cast::Run(mat, "float"); + mat->ShareWithTensor(output); + output->shape.insert(output->shape.begin(), 1); // reshape to n, h, w, c + return true; +} + +bool PIPNet::Postprocess(FDTensor& infer_result, FaceAlignmentResult* result, + const std::map>& im_info) { + FDASSERT(infer_result.shape[0] == 1, "Only support batch = 1 now."); + if (infer_result.dtype != FDDataType::FP32) { + FDERROR << "Only support post process with float32 data." << std::endl; + return false; + } + + auto iter_in = im_info.find("input_shape"); + FDASSERT(iter_in != im_info.end(), + "Cannot find input_shape from im_info."); + int in_h = iter_in->second[0]; + int in_w = iter_in->second[1]; + + result->Clear(); + float* data = static_cast(infer_result.Data()); + for (size_t i = 0; i < infer_result.shape[1]; i += 2) { + float x = data[i]; + float y = data[i + 1]; + x = std::min(std::max(0.f, x), 1.0f); + y = std::min(std::max(0.f, y), 1.0f); + // decode landmarks (default 106 landmarks) + result->landmarks.emplace_back( + std::array{x * in_w, y * in_h}); + } + + return true; +} + +bool PIPNet::Predict(cv::Mat* im, FaceAlignmentResult* result) { + Mat mat(*im); + std::vector input_tensors(1); + + std::map> im_info; + + // Record the shape of image and the shape of preprocessed image + im_info["input_shape"] = {mat.Height(), mat.Width()}; + im_info["output_shape"] = {mat.Height(), mat.Width()}; + + if (!Preprocess(&mat, &input_tensors[0], &im_info)) { + FDERROR << "Failed to preprocess input image." << std::endl; + return false; + } + input_tensors[0].name = InputInfoOfRuntime(0).name; + std::vector output_tensors; + if (!Infer(input_tensors, &output_tensors)) { + FDERROR << "Failed to inference." << std::endl; + return false; + } + + if (!Postprocess(output_tensors[1], result, im_info)) { + FDERROR << "Failed to post process." << std::endl; + return false; + } + return true; +} + +} // namespace facealign +} // namespace vision +} // namespace fastdeploy \ No newline at end of file diff --git a/fastdeploy/vision/facealign/contrib/pipnet.h b/fastdeploy/vision/facealign/contrib/pipnet.h new file mode 100644 index 00000000000..97e29295fbe --- /dev/null +++ b/fastdeploy/vision/facealign/contrib/pipnet.h @@ -0,0 +1,73 @@ +// 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. + +#pragma once +#include "fastdeploy/fastdeploy_model.h" +#include "fastdeploy/vision/common/processors/transform.h" +#include "fastdeploy/vision/common/result.h" + +namespace fastdeploy { + +namespace vision { + +namespace facealign { +/*! @brief PIPNet model object used when to load a PIPNet model exported by PIPNet. + */ +class FASTDEPLOY_DECL PIPNet : public FastDeployModel { + public: + /** \brief Set path of model file and the configuration of runtime. + * + * \param[in] model_file Path of model file, e.g ./pipnet.onnx + * \param[in] params_file Path of parameter file, e.g ppyoloe/model.pdiparams, if the model format is ONNX, this parameter will be ignored + * \param[in] custom_option RuntimeOption for inference, the default will use cpu, and choose the backend defined in "valid_cpu_backends" + * \param[in] model_format Model format of the loaded model, default is ONNX format + */ + PIPNet(const std::string& model_file, const std::string& params_file = "", + const RuntimeOption& custom_option = RuntimeOption(), + const ModelFormat& model_format = ModelFormat::ONNX); + + std::string ModelName() const { return "PIPNet"; } + /** \brief Predict the face detection result for an input image + * + * \param[in] im The input image data, comes from cv::imread(), is a 3-D array with layout HWC, BGR format + * \param[in] result The output face detection result will be writen to this structure + * \return true if the prediction successed, otherwise false + */ + virtual bool Predict(cv::Mat* im, FaceAlignmentResult* result); + + /// tuple of (width, height), default (256, 256) + std::vector size; + + /*! @brief + Mean parameters for normalize, size should be the the same as channels, default mean_vals = {0.485f, 0.456f, 0.406f} + */ + std::vector mean_vals; + /*! @brief + Std parameters for normalize, size should be the the same as channels, default std_vals = {0.229f, 0.224f, 0.225f} + */ + std::vector std_vals; + + private: + bool Initialize(); + + bool Preprocess(Mat* mat, FDTensor* outputs, + std::map>* im_info); + + bool Postprocess(FDTensor& infer_result, FaceAlignmentResult* result, + const std::map>& im_info); +}; + +} // namespace facealign +} // namespace vision +} // namespace fastdeploy diff --git a/fastdeploy/vision/facealign/contrib/pipnet_pybind.cc b/fastdeploy/vision/facealign/contrib/pipnet_pybind.cc new file mode 100644 index 00000000000..0ba19c9aa70 --- /dev/null +++ b/fastdeploy/vision/facealign/contrib/pipnet_pybind.cc @@ -0,0 +1,31 @@ +// 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 BindPIPNet(pybind11::module& m) { + pybind11::class_(m, "PIPNet") + .def(pybind11::init()) + .def("predict", + [](vision::facealign::PIPNet& self, pybind11::array& data) { + auto mat = PyArrayToCvMat(data); + vision::FaceAlignmentResult res; + self.Predict(&mat, &res); + return res; + }) + .def_readwrite("size", &vision::facealign::PIPNet::size); +} +} // namespace fastdeploy \ No newline at end of file From b2c068ed050953facd63a8fc70536af5555bdeea Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Wed, 9 Nov 2022 03:23:07 +0000 Subject: [PATCH 54/69] add pipnet land1000 sigle test and python code --- .../facealign/face_landmark_1000/README.md | 8 +- .../face_landmark_1000/cpp/README.md | 28 +- .../face_landmark_1000/python/README.md | 28 +- .../face_landmark_1000/python/infer.py | 6 +- examples/vision/facealign/pipnet/README.md | 33 ++ .../facealign/pipnet/cpp/CMakeLists.txt | 14 + .../vision/facealign/pipnet/cpp/README.md | 84 ++++ examples/vision/facealign/pipnet/cpp/infer.cc | 111 +++++ .../vision/facealign/pipnet/python/README.md | 71 +++ .../vision/facealign/pipnet/python/infer.py | 93 ++++ fastdeploy/vision.h | 1 + .../facealign/contrib/face_landmark_1000.cc | 6 +- .../facealign/contrib/face_landmark_1000.h | 14 +- .../contrib/face_landmark_1000_pybind.cc | 2 +- fastdeploy/vision/facealign/contrib/pipnet.cc | 417 +++++++++++++++++- fastdeploy/vision/facealign/contrib/pipnet.h | 75 +++- .../vision/facealign/contrib/pipnet_pybind.cc | 5 +- .../vision/facealign/facealign_pybind.cc | 5 + .../fastdeploy/vision/facealign/__init__.py | 2 + .../facealign/contrib/face_landmark_1000.py | 68 +++ .../vision/facealign/contrib/pipnet.py | 107 +++++ tests/eval_example/test_facelandmark1000.py | 43 ++ tests/eval_example/test_pipnet.py | 43 ++ .../test_vision_colorspace_convert.cc | 25 ++ 24 files changed, 1215 insertions(+), 74 deletions(-) create mode 100644 examples/vision/facealign/pipnet/README.md create mode 100644 examples/vision/facealign/pipnet/cpp/CMakeLists.txt create mode 100644 examples/vision/facealign/pipnet/cpp/README.md create mode 100644 examples/vision/facealign/pipnet/cpp/infer.cc create mode 100644 examples/vision/facealign/pipnet/python/README.md create mode 100644 examples/vision/facealign/pipnet/python/infer.py create mode 100644 python/fastdeploy/vision/facealign/contrib/face_landmark_1000.py create mode 100644 python/fastdeploy/vision/facealign/contrib/pipnet.py create mode 100644 tests/eval_example/test_facelandmark1000.py create mode 100644 tests/eval_example/test_pipnet.py diff --git a/examples/vision/facealign/face_landmark_1000/README.md b/examples/vision/facealign/face_landmark_1000/README.md index 5609ff045c7..ce45cc285b5 100644 --- a/examples/vision/facealign/face_landmark_1000/README.md +++ b/examples/vision/facealign/face_landmark_1000/README.md @@ -1,8 +1,8 @@ -# PFLD 模型部署 +# FaceLandmark 模型部署 ## 模型版本说明 -- [FaceLandmark1000](https://github.com/Single430/FaceLandmark1000/commit/1a951b6) +- [FaceLandmark1000](https://github.com/Single430/FaceLandmark1000/tree/1a951b6) ## 支持模型列表 @@ -12,11 +12,11 @@ ## 下载预训练模型 -为了方便开发者的测试,下面提供了PFLD导出的各系列模型,开发者可直接下载使用。 +为了方便开发者的测试,下面提供了FaceLandmark导出的各系列模型,开发者可直接下载使用。 | 模型 | 参数大小 | 精度 | 备注 | |:---------------------------------------------------------------- |:----- |:----- | :------ | -| [FaceLandmark1000.onnx](https://bj.bcebos.com/paddlehub/fastdeploy/TODO) | 2.1M | - | +| [FaceLandmark1000](https://bj.bcebos.com/paddlehub/fastdeploy/FaceLandmark1000.onnx) | 2.1M | - | ## 详细部署文档 diff --git a/examples/vision/facealign/face_landmark_1000/cpp/README.md b/examples/vision/facealign/face_landmark_1000/cpp/README.md index 4138646d262..3f34befec49 100644 --- a/examples/vision/facealign/face_landmark_1000/cpp/README.md +++ b/examples/vision/facealign/face_landmark_1000/cpp/README.md @@ -1,13 +1,13 @@ -# PFLD C++部署示例 +# FaceLandmark1000 C++部署示例 -本目录下提供`infer.cc`快速完成PFLD在CPU/GPU,以及GPU上通过TensorRT加速部署的示例。 +本目录下提供`infer.cc`快速完成FaceLandmark1000在CPU/GPU,以及GPU上通过TensorRT加速部署的示例。 在部署前,需确认以下两个步骤 - 1. 软硬件环境满足要求,参考[FastDeploy环境要求](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) - 2. 根据开发环境,下载预编译部署库和samples代码,参考[FastDeploy预编译库](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) -以Linux上CPU推理为例,在本目录执行如下命令即可完成编译测试,保证 FastDeploy 版本0.6.0以上(x.x.x >= 0.6.0)支持PFLD模型 +以Linux上CPU推理为例,在本目录执行如下命令即可完成编译测试,保证 FastDeploy 版本0.6.0以上(x.x.x >= 0.6.0)支持FaceLandmark1000模型 ```bash mkdir build @@ -17,16 +17,16 @@ tar xvf fastdeploy-linux-x64-x.x.x.tgz cmake .. -DFASTDEPLOY_INSTALL_DIR=${PWD}/fastdeploy-linux-x64-x.x.x make -j -#下载官方转换好的 PFLD 模型文件和测试图片 -wget https://bj.bcebos.com/paddlehub/fastdeploy/pfld-106-lite.onnx +#下载官方转换好的 FaceLandmark1000 模型文件和测试图片 +wget https://bj.bcebos.com/paddlehub/fastdeploy/FaceLandmark1000.onnx wget https://bj.bcebos.com/paddlehub/fastdeploy/facealign_input.png # CPU推理 -./infer_demo --model pfld-106-lite.onnx --image facealign_input.png --device cpu +./infer_demo --model FaceLandmark1000.onnx --image facealign_input.png --device cpu # GPU推理 -./infer_demo --model pfld-106-lite.onnx --image facealign_input.png --device gpu +./infer_demo --model FaceLandmark1000.onnx --image facealign_input.png --device gpu # GPU上TensorRT推理 -./infer_demo --model pfld-106-lite.onnx --image facealign_input.png --device gpu --backend trt +./infer_demo --model FaceLandmark1000.onnx --image facealign_input.png --device gpu --backend trt ``` 运行完成可视化结果如下图所示 @@ -38,19 +38,19 @@ wget https://bj.bcebos.com/paddlehub/fastdeploy/facealign_input.png 以上命令只适用于Linux或MacOS, Windows下SDK的使用方式请参考: - [如何在Windows中使用FastDeploy C++ SDK](../../../../../docs/cn/faq/use_sdk_on_windows.md) -## PFLD C++接口 +## FaceLandmark1000 C++接口 -### PFLD 类 +### FaceLandmark1000 类 ```c++ -fastdeploy::vision::facealign::PFLD( +fastdeploy::vision::facealign::FaceLandmark1000( const string& model_file, const string& params_file = "", const RuntimeOption& runtime_option = RuntimeOption(), const ModelFormat& model_format = ModelFormat::ONNX) ``` -PFLD模型加载和初始化,其中model_file为导出的ONNX模型格式。 +FaceLandmark1000模型加载和初始化,其中model_file为导出的ONNX模型格式。 **参数** @@ -62,7 +62,7 @@ PFLD模型加载和初始化,其中model_file为导出的ONNX模型格式。 #### Predict函数 > ```c++ -> PFLD::Predict(cv::Mat* im, FaceAlignmentResult* result) +> FaceLandmark1000::Predict(cv::Mat* im, FaceAlignmentResult* result) > ``` > > 模型预测接口,输入图像直接输出landmarks结果。 @@ -76,7 +76,7 @@ PFLD模型加载和初始化,其中model_file为导出的ONNX模型格式。 用户可按照自己的实际需求,修改下列预处理参数,从而影响最终的推理和部署效果 -> > * **size**(vector<int>): 通过此参数修改预处理过程中resize的大小,包含两个整型元素,表示[width, height], 默认值为[112, 112] +> > * **size**(vector<int>): 通过此参数修改预处理过程中resize的大小,包含两个整型元素,表示[width, height], 默认值为[128, 128] - [模型介绍](../../) - [Python部署](../python) diff --git a/examples/vision/facealign/face_landmark_1000/python/README.md b/examples/vision/facealign/face_landmark_1000/python/README.md index e9fdf545e42..0047f54ac36 100644 --- a/examples/vision/facealign/face_landmark_1000/python/README.md +++ b/examples/vision/facealign/face_landmark_1000/python/README.md @@ -1,28 +1,28 @@ -# PFLD Python部署示例 +# FaceLandmark1000 Python部署示例 在部署前,需确认以下两个步骤 - 1. 软硬件环境满足要求,参考[FastDeploy环境要求](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) - 2. FastDeploy Python whl包安装,参考[FastDeploy Python安装](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) -本目录下提供`infer.py`快速完成PFLD在CPU/GPU,以及GPU上通过TensorRT加速部署的示例,保证 FastDeploy 版本 >= 0.6.0 支持PFLD模型。执行如下脚本即可完成 +本目录下提供`infer.py`快速完成FaceLandmark1000在CPU/GPU,以及GPU上通过TensorRT加速部署的示例,保证 FastDeploy 版本 >= 0.6.0 支持FaceLandmark1000模型。执行如下脚本即可完成 ```bash #下载部署示例代码 git clone https://github.com/PaddlePaddle/FastDeploy.git -cd FastDeploy/examples/vision/facealign/pfld/python +cd FastDeploy/examples/vision/facealign/facelandmark1000/python -# 下载PFLD模型文件和测试图片以及视频 +# 下载FaceLandmark1000模型文件和测试图片 ## 原版ONNX模型 -wget https://bj.bcebos.com/paddlehub/fastdeploy/pfld-106-lite.onnx +wget https://bj.bcebos.com/paddlehub/fastdeploy/FaceLandmark1000.onnx wget https://bj.bcebos.com/paddlehub/fastdeploy/facealign_input.png # CPU推理 -python infer.py --model pfld-106-lite.onnx --image facealign_input.png --device cpu +python infer.py --model FaceLandmark1000.onnx --image facealign_input.png --device cpu # GPU推理 -python infer.py --model pfld-106-lite.onnx --image facealign_input.png --device gpu +python infer.py --model FaceLandmark1000.onnx --image facealign_input.png --device gpu # TRT推理 -python infer.py --model pfld-106-lite.onnx --image facealign_input.png --device gpu --backend trt +python infer.py --model FaceLandmark1000.onnx --image facealign_input.png --device gpu --backend trt ``` 运行完成可视化结果如下图所示 @@ -31,13 +31,13 @@ python infer.py --model pfld-106-lite.onnx --image facealign_input.png --device -## PFLD Python接口 +## FaceLandmark1000 Python接口 ```python -fd.vision.facealign.PFLD(model_file, params_file=None, runtime_option=None, model_format=ModelFormat.ONNX) +fd.vision.facealign.FaceLandmark1000(model_file, params_file=None, runtime_option=None, model_format=ModelFormat.ONNX) ``` -PFLD模型加载和初始化,其中model_file为导出的ONNX模型格式 +FaceLandmark1000模型加载和初始化,其中model_file为导出的ONNX模型格式 **参数** @@ -49,7 +49,7 @@ PFLD模型加载和初始化,其中model_file为导出的ONNX模型格式 ### predict函数 > ```python -> PFLD.predict(input_image) +> FaceLandmark1000.predict(input_image) > ``` > > 模型预测结口,输入图像直接输出landmarks坐标结果。 @@ -65,7 +65,7 @@ PFLD模型加载和初始化,其中model_file为导出的ONNX模型格式 ## 其它文档 -- [PFLD 模型介绍](..) -- [PFLD C++部署](../cpp) +- [FaceLandmark1000 模型介绍](..) +- [FaceLandmark1000 C++部署](../cpp) - [模型预测结果说明](../../../../../docs/api/vision_results/) - [如何切换模型推理后端引擎](../../../../../docs/cn/faq/how_to_change_backend.md) diff --git a/examples/vision/facealign/face_landmark_1000/python/infer.py b/examples/vision/facealign/face_landmark_1000/python/infer.py index d185cb5321a..96f8356339d 100644 --- a/examples/vision/facealign/face_landmark_1000/python/infer.py +++ b/examples/vision/facealign/face_landmark_1000/python/infer.py @@ -7,7 +7,8 @@ def parse_arguments(): import argparse import ast parser = argparse.ArgumentParser() - parser.add_argument("--model", required=True, help="Path of PFLD model.") + parser.add_argument( + "--model", required=True, help="Path of FaceLandmark1000 model.") parser.add_argument("--image", type=str, help="Path of test image file.") parser.add_argument( "--device", @@ -76,7 +77,8 @@ def build_option(args): # 配置runtime,加载模型 runtime_option = build_option(args) -model = fd.vision.facealign.PFLD(args.model, runtime_option=runtime_option) +model = fd.vision.facealign.FaceLandmark1000( + args.model, runtime_option=runtime_option) # for image im = cv2.imread(args.image) diff --git a/examples/vision/facealign/pipnet/README.md b/examples/vision/facealign/pipnet/README.md new file mode 100644 index 00000000000..504aac2241c --- /dev/null +++ b/examples/vision/facealign/pipnet/README.md @@ -0,0 +1,33 @@ +# PIPNet 模型部署 + +## 模型版本说明 + +- [PIPNet](https://github.com/jhb86253817/PIPNet/tree/b9eab58) + +## 支持模型列表 + +目前FastDeploy支持如下模型的部署 + +- [PIPNet 模型](https://github.com/jhb86253817/PIPNet) + +## 下载预训练模型 + +为了方便开发者的测试,下面提供了PIPNet导出的各系列模型,开发者可直接下载使用。 + +| 模型 | 参数大小 | 精度 | 备注 | +|:---------------------------------------------------------------- |:----- |:----- | :------ | +| [PIPNet19_ResNet18_AFLW](https://bj.bcebos.com/paddlehub/fastdeploy/pipnet_resnet18_10x19x32x256_aflw.onnx) | 45.6M | - | +| [PIPNet29_ResNet18_COFW](https://bj.bcebos.com/paddlehub/fastdeploy/pipnet_resnet18_10x29x32x256_cofw.onnx) | 46.1M | - | +| [PIPNet68_ResNet18_300W](https://bj.bcebos.com/paddlehub/fastdeploy/pipnet_resnet18_10x68x32x256_300w.onnx) | 47.9M | - | +| [PIPNet98_ResNet18_WFLW](https://bj.bcebos.com/paddlehub/fastdeploy/pipnet_resnet18_10x98x32x256_wflw.onnx) | 49.3M | - | +| [PIPNet19_ResNet101_AFLW](https://bj.bcebos.com/paddlehub/fastdeploy/pipnet_resnet101_10x19x32x256_aflw.onnx) | 173.4M | - | +| [PIPNet29_ResNet101_COFW](https://bj.bcebos.com/paddlehub/fastdeploy/pipnet_resnet101_10x29x32x256_cofw.onnx) | 175.3M | - | +| [PIPNet68_ResNet101_300W](https://bj.bcebos.com/paddlehub/fastdeploy/pipnet_resnet101_10x68x32x256_300w.onnx) | 182.6M | - | +| [PIPNet98_ResNet101_WFLW](https://bj.bcebos.com/paddlehub/fastdeploy/pipnet_resnet101_10x98x32x256_wflw.onnx) | 188.3M | - | + + + +## 详细部署文档 + +- [Python部署](python) +- [C++部署](cpp) diff --git a/examples/vision/facealign/pipnet/cpp/CMakeLists.txt b/examples/vision/facealign/pipnet/cpp/CMakeLists.txt new file mode 100644 index 00000000000..c6c754a4b50 --- /dev/null +++ b/examples/vision/facealign/pipnet/cpp/CMakeLists.txt @@ -0,0 +1,14 @@ +PROJECT(infer_demo C CXX) +CMAKE_MINIMUM_REQUIRED (VERSION 3.10) + +# 指定下载解压后的fastdeploy库路径 +option(FASTDEPLOY_INSTALL_DIR "Path of downloaded fastdeploy sdk.") +include(${FASTDEPLOY_INSTALL_DIR}/utils/gflags.cmake) +include(${FASTDEPLOY_INSTALL_DIR}/FastDeploy.cmake) + +# 添加FastDeploy依赖头文件 +include_directories(${FASTDEPLOY_INCS}) + +add_executable(infer_demo ${PROJECT_SOURCE_DIR}/infer.cc) +# 添加FastDeploy库依赖 +target_link_libraries(infer_demo ${FASTDEPLOY_LIBS} gflags pthread) diff --git a/examples/vision/facealign/pipnet/cpp/README.md b/examples/vision/facealign/pipnet/cpp/README.md new file mode 100644 index 00000000000..e5156caea32 --- /dev/null +++ b/examples/vision/facealign/pipnet/cpp/README.md @@ -0,0 +1,84 @@ +# PIPNet C++部署示例 + +本目录下提供`infer.cc`快速完成PIPNet在CPU/GPU,以及GPU上通过TensorRT加速部署的示例。 + +在部署前,需确认以下两个步骤 + +- 1. 软硬件环境满足要求,参考[FastDeploy环境要求](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) +- 2. 根据开发环境,下载预编译部署库和samples代码,参考[FastDeploy预编译库](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) + +以Linux上CPU推理为例,在本目录执行如下命令即可完成编译测试,保证 FastDeploy 版本0.6.0以上(x.x.x >= 0.6.0)支持PIPNet模型 + +```bash +mkdir build +cd build +wget https://bj.bcebos.com/fastdeploy/release/cpp/fastdeploy-linux-x64-x.x.x.tgz +tar xvf fastdeploy-linux-x64-x.x.x.tgz +cmake .. -DFASTDEPLOY_INSTALL_DIR=${PWD}/fastdeploy-linux-x64-x.x.x +make -j + +#下载官方转换好的 PIPNet 模型文件和测试图片 +wget https://bj.bcebos.com/paddlehub/fastdeploy/pipnet_resnet18_10x19x32x256_aflw.onnx +wget https://bj.bcebos.com/paddlehub/fastdeploy/facealign_input.png + +# CPU推理 +./infer_demo --model pipnet_resnet18_10x19x32x256_aflw.onnx --image facealign_input.png --device cpu +# GPU推理 +./infer_demo --model pipnet_resnet18_10x19x32x256_aflw.onnx --image facealign_input.png --device gpu +# GPU上TensorRT推理 +./infer_demo --model pipnet_resnet18_10x19x32x256_aflw.onnx --image facealign_input.png --device gpu --backend trt +``` + +运行完成可视化结果如下图所示 + +
+ +
+ +以上命令只适用于Linux或MacOS, Windows下SDK的使用方式请参考: +- [如何在Windows中使用FastDeploy C++ SDK](../../../../../docs/cn/faq/use_sdk_on_windows.md) + +## PIPNet C++接口 + +### PIPNet 类 + +```c++ +fastdeploy::vision::facealign::PIPNet( + const string& model_file, + const string& params_file = "", + const RuntimeOption& runtime_option = RuntimeOption(), + const ModelFormat& model_format = ModelFormat::ONNX) +``` + +PIPNet模型加载和初始化,其中model_file为导出的ONNX模型格式。 + +**参数** + +> * **model_file**(str): 模型文件路径 +> * **params_file**(str): 参数文件路径,当模型格式为ONNX时,此参数传入空字符串即可 +> * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置 +> * **model_format**(ModelFormat): 模型格式,默认为ONNX格式 + +#### Predict函数 + +> ```c++ +> PIPNet::Predict(cv::Mat* im, FaceAlignmentResult* result) +> ``` +> +> 模型预测接口,输入图像直接输出landmarks结果。 +> +> **参数** +> +> > * **im**: 输入图像,注意需为HWC,BGR格式 +> > * **result**: landmarks结果, FaceAlignmentResult说明参考[视觉模型预测结果](../../../../../docs/api/vision_results/) + +### 类成员变量 + +用户可按照自己的实际需求,修改下列预处理参数,从而影响最终的推理和部署效果 + +> > * **size**(vector<int>): 通过此参数修改预处理过程中resize的大小,包含两个整型元素,表示[width, height], 默认值为[256, 256] + +- [模型介绍](../../) +- [Python部署](../python) +- [视觉模型预测结果](../../../../../docs/api/vision_results/) +- [如何切换模型推理后端引擎](../../../../../docs/cn/faq/how_to_change_backend.md) diff --git a/examples/vision/facealign/pipnet/cpp/infer.cc b/examples/vision/facealign/pipnet/cpp/infer.cc new file mode 100644 index 00000000000..cba9667d92e --- /dev/null +++ b/examples/vision/facealign/pipnet/cpp/infer.cc @@ -0,0 +1,111 @@ +// 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/vision.h" +#include "gflags/gflags.h" + +DEFINE_string(model, "", "Directory of the inference model."); +DEFINE_string(image, "", "Path of the image file."); +DEFINE_string(device, "cpu", + "Type of inference device, support 'cpu' or 'gpu'."); +DEFINE_string(backend, "default", + "The inference runtime backend, support: ['default', 'ort', " + "'paddle', 'ov', 'trt', 'paddle_trt']"); +DEFINE_bool(use_fp16, false, "Whether to use FP16 mode, only support 'trt' and 'paddle_trt' backend"); +DEFINE_int32(num_landmarks, 19, "number of landmarks for PIPNet, the num_lms should be a number in {19, 29, 68, 98}"); + +void PrintUsage() { + std::cout << "Usage: infer_demo --model model_path --image img_path --device [cpu|gpu] --backend " + "[default|ort|paddle|ov|trt|paddle_trt] " + "--use_fp16 false" + << std::endl; + std::cout << "Default value of device: cpu" << std::endl; + std::cout << "Default value of backend: default" << std::endl; + std::cout << "Default value of use_fp16: false" << std::endl; +} + +bool CreateRuntimeOption(fastdeploy::RuntimeOption* option) { + if (FLAGS_device == "gpu") { + option->UseGpu(); + if (FLAGS_backend == "ort") { + option->UseOrtBackend(); + } else if (FLAGS_backend == "paddle") { + option->UsePaddleBackend(); + } else if (FLAGS_backend == "trt" || + FLAGS_backend == "paddle_trt") { + option->UseTrtBackend(); + option->SetTrtInputShape("input", {1, 3, 128, 128}); + if (FLAGS_backend == "paddle_trt") { + option->EnablePaddleToTrt(); + } + if (FLAGS_use_fp16) { + option->EnableTrtFP16(); + } + } else if (FLAGS_backend == "default") { + return true; + } else { + std::cout << "While inference with GPU, only support default/ort/paddle/trt/paddle_trt now, " << FLAGS_backend << " is not supported." << std::endl; + return false; + } + } else if (FLAGS_device == "cpu") { + if (FLAGS_backend == "ort") { + option->UseOrtBackend(); + } else if (FLAGS_backend == "ov") { + option->UseOpenVINOBackend(); + } else if (FLAGS_backend == "paddle") { + option->UsePaddleBackend(); + } else if (FLAGS_backend == "default") { + return true; + } else { + std::cout << "While inference with CPU, only support default/ort/ov/paddle now, " << FLAGS_backend << " is not supported." << std::endl; + return false; + } + } else { + std::cerr << "Only support device CPU/GPU now, " << FLAGS_device << " is not supported." << std::endl; + return false; + } + + return true; +} + +int main(int argc, char* argv[]) { + google::ParseCommandLineFlags(&argc, &argv, true); + auto option = fastdeploy::RuntimeOption(); + if (!CreateRuntimeOption(&option)) { + PrintUsage(); + return -1; + } + + auto model = fastdeploy::vision::facealign::PIPNet(FLAGS_model, "", option); + if (!model.Initialized()) { + std::cerr << "Failed to initialize." << std::endl; + return -1; + } + model.SetNumLandmarks(FLAGS_num_landmarks); + auto im = cv::imread(FLAGS_image); + auto im_bak = im.clone(); + + fastdeploy::vision::FaceAlignmentResult res; + if (!model.Predict(&im, &res)) { + std::cerr << "Failed to predict." << std::endl; + return -1; + } + std::cout << res.Str() << std::endl; + + auto vis_im = fastdeploy::vision::VisFaceAlignment(im_bak, res); + cv::imwrite("vis_result.jpg", vis_im); + std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl; + + return 0; +} diff --git a/examples/vision/facealign/pipnet/python/README.md b/examples/vision/facealign/pipnet/python/README.md new file mode 100644 index 00000000000..316a98f3d34 --- /dev/null +++ b/examples/vision/facealign/pipnet/python/README.md @@ -0,0 +1,71 @@ +# PIPNet Python部署示例 + +在部署前,需确认以下两个步骤 + +- 1. 软硬件环境满足要求,参考[FastDeploy环境要求](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) +- 2. FastDeploy Python whl包安装,参考[FastDeploy Python安装](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) + +本目录下提供`infer.py`快速完成PIPNet在CPU/GPU,以及GPU上通过TensorRT加速部署的示例,保证 FastDeploy 版本 >= 0.6.0 支持PIPNet模型。执行如下脚本即可完成 + +```bash +#下载部署示例代码 +git clone https://github.com/PaddlePaddle/FastDeploy.git +cd FastDeploy/examples/vision/facealign/pipnet/python + +# 下载PIPNet模型文件和测试图片以及视频 +## 原版ONNX模型 +wget https://bj.bcebos.com/paddlehub/fastdeploy/pipnet_resnet18_10x19x32x256_aflw.onnx +wget https://bj.bcebos.com/paddlehub/fastdeploy/facealign_input.png + +# CPU推理 +python infer.py --model pipnet_resnet18_10x19x32x256_aflw.onnx --image facealign_input.png --device cpu +# GPU推理 +python infer.py --model pipnet_resnet18_10x19x32x256_aflw.onnx --image facealign_input.png --device gpu +# TRT推理 +python infer.py --model pipnet_resnet18_10x19x32x256_aflw.onnx --image facealign_input.png --device gpu --backend trt +``` + +运行完成可视化结果如下图所示 + +
+ +
+ +## PIPNet Python接口 + +```python +fd.vision.facealign.PIPNet(model_file, params_file=None, runtime_option=None, model_format=ModelFormat.ONNX) +``` + +PIPNet模型加载和初始化,其中model_file为导出的ONNX模型格式 + +**参数** + +> * **model_file**(str): 模型文件路径 +> * **params_file**(str): 参数文件路径,当模型格式为ONNX格式时,此参数无需设定 +> * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置 +> * **model_format**(ModelFormat): 模型格式,默认为ONNX + +### predict函数 + +> ```python +> PIPNet.predict(input_image) +> ``` +> +> 模型预测结口,输入图像直接输出landmarks坐标结果。 +> +> **参数** +> +> > * **input_image**(np.ndarray): 输入数据,注意需为HWC,BGR格式 + +> **返回** +> +> > 返回`fastdeploy.vision.FaceAlignmentResult`结构体,结构体说明参考文档[视觉模型预测结果](../../../../../docs/api/vision_results/) + + +## 其它文档 + +- [PIPNet 模型介绍](..) +- [PIPNet C++部署](../cpp) +- [模型预测结果说明](../../../../../docs/api/vision_results/) +- [如何切换模型推理后端引擎](../../../../../docs/cn/faq/how_to_change_backend.md) diff --git a/examples/vision/facealign/pipnet/python/infer.py b/examples/vision/facealign/pipnet/python/infer.py new file mode 100644 index 00000000000..c724efada5d --- /dev/null +++ b/examples/vision/facealign/pipnet/python/infer.py @@ -0,0 +1,93 @@ +import fastdeploy as fd +import cv2 +import os + + +def parse_arguments(): + import argparse + import ast + parser = argparse.ArgumentParser() + parser.add_argument("--model", required=True, help="Path of PIPNet model.") + parser.add_argument("--image", type=str, help="Path of test image file.") + parser.add_argument( + "--device", + type=str, + default='cpu', + help="Type of inference device, support 'cpu' or 'gpu'.") + parser.add_argument( + "--backend", + type=str, + default="ort", + help="inference backend, ort, ov, trt, paddle, paddle_trt.") + parser.add_argument( + "--enable_trt_fp16", + type=bool, + default=False, + help="whether enable fp16 in trt/paddle_trt backend") + parser.add_argument( + "--num_landmarks", + type=int, + default=19, + help="whether enable fp16 in trt/paddle_trt backend") + return parser.parse_args() + + +def build_option(args): + option = fd.RuntimeOption() + device = args.device + backend = args.backend + enable_trt_fp16 = args.enable_trt_fp16 + if device == "gpu": + option.use_gpu() + if backend == "ort": + option.use_ort_backend() + elif backend == "paddle": + option.use_paddle_backend() + elif backend in ["trt", "paddle_trt"]: + option.use_trt_backend() + option.set_trt_input_shape("input", [1, 3, 112, 112]) + if backend == "paddle_trt": + option.enable_paddle_to_trt() + if enable_trt_fp16: + option.enable_trt_fp16() + elif backend == "default": + return option + else: + raise Exception( + "While inference with GPU, only support default/ort/paddle/trt/paddle_trt now, {} is not supported.". + format(backend)) + elif device == "cpu": + if backend == "ort": + option.use_ort_backend() + elif backend == "ov": + option.use_openvino_backend() + elif backend == "paddle": + option.use_paddle_backend() + elif backend == "default": + return option + else: + raise Exception( + "While inference with CPU, only support default/ort/ov/paddle now, {} is not supported.". + format(backend)) + else: + raise Exception( + "Only support device CPU/GPU now, {} is not supported.".format( + device)) + + return option + + +args = parse_arguments() + +# 配置runtime,加载模型 +runtime_option = build_option(args) +model = fd.vision.facealign.PIPNet(args.model, runtime_option=runtime_option) +model.num_landmarks = args.num_landmarks +# for image +im = cv2.imread(args.image) +result = model.predict(im.copy()) +print(result) +# 可视化结果 +vis_im = fd.vision.vis_face_alignment(im, result) +cv2.imwrite("visualized_result.jpg", vis_im) +print("Visualized result save in ./visualized_result.jpg") diff --git a/fastdeploy/vision.h b/fastdeploy/vision.h index a9b4e488c67..3c7e45b9e6a 100755 --- a/fastdeploy/vision.h +++ b/fastdeploy/vision.h @@ -35,6 +35,7 @@ #include "fastdeploy/vision/facedet/contrib/yolov5face.h" #include "fastdeploy/vision/facealign/contrib/pfld.h" #include "fastdeploy/vision/facealign/contrib/face_landmark_1000.h" +#include "fastdeploy/vision/facealign/contrib/pipnet.h" #include "fastdeploy/vision/faceid/contrib/adaface.h" #include "fastdeploy/vision/faceid/contrib/arcface.h" #include "fastdeploy/vision/faceid/contrib/cosface.h" diff --git a/fastdeploy/vision/facealign/contrib/face_landmark_1000.cc b/fastdeploy/vision/facealign/contrib/face_landmark_1000.cc index 996d252e36c..25b0eee964d 100644 --- a/fastdeploy/vision/facealign/contrib/face_landmark_1000.cc +++ b/fastdeploy/vision/facealign/contrib/face_landmark_1000.cc @@ -42,7 +42,7 @@ FaceLandmark1000::FaceLandmark1000(const std::string& model_file, bool FaceLandmark1000::Initialize() { // parameters for preprocess - size = {128, 128}; + size_ = {128, 128}; if (!InitRuntime()) { FDERROR << "Failed to initialize fastdeploy backend." << std::endl; @@ -54,8 +54,8 @@ bool FaceLandmark1000::Initialize() { bool FaceLandmark1000::Preprocess(Mat* mat, FDTensor* output, std::map>* im_info) { // Resize - int resize_w = size[0]; - int resize_h = size[1]; + int resize_w = size_[0]; + int resize_h = size_[1]; if (resize_h != mat->Height() || resize_w != mat->Width()) { Resize::Run(mat, resize_w, resize_h); } diff --git a/fastdeploy/vision/facealign/contrib/face_landmark_1000.h b/fastdeploy/vision/facealign/contrib/face_landmark_1000.h index b3a230c7752..5f15546f77f 100644 --- a/fastdeploy/vision/facealign/contrib/face_landmark_1000.h +++ b/fastdeploy/vision/facealign/contrib/face_landmark_1000.h @@ -47,8 +47,18 @@ class FASTDEPLOY_DECL FaceLandmark1000 : public FastDeployModel { */ virtual bool Predict(cv::Mat* im, FaceAlignmentResult* result); - /// tuple of (width, height), default (128, 128) - std::vector size; + // tuple of (width, height), default (128, 128) + std::vector size_; + /** \brief Get the input size of image + * + * \return Vector of int values, default {128,128} + */ + std::vector GetSize() {return size_;} + /** \brief Set the input size of image + * + * \param[in] size Vector of int values which represents {width, height} of image + */ + void SetSize(std::vector size) {size_ = size;} private: bool Initialize(); diff --git a/fastdeploy/vision/facealign/contrib/face_landmark_1000_pybind.cc b/fastdeploy/vision/facealign/contrib/face_landmark_1000_pybind.cc index ff3151b4cd1..0067bdef77a 100644 --- a/fastdeploy/vision/facealign/contrib/face_landmark_1000_pybind.cc +++ b/fastdeploy/vision/facealign/contrib/face_landmark_1000_pybind.cc @@ -26,6 +26,6 @@ void BindFaceLandmark1000(pybind11::module& m) { self.Predict(&mat, &res); return res; }) - .def_readwrite("size", &vision::facealign::FaceLandmark1000::size); + .def_readwrite("size", &vision::facealign::FaceLandmark1000::size_); } } // namespace fastdeploy \ No newline at end of file diff --git a/fastdeploy/vision/facealign/contrib/pipnet.cc b/fastdeploy/vision/facealign/contrib/pipnet.cc index 3461003fba5..27d78e8bcbc 100644 --- a/fastdeploy/vision/facealign/contrib/pipnet.cc +++ b/fastdeploy/vision/facealign/contrib/pipnet.cc @@ -22,8 +22,154 @@ namespace vision { namespace facealign { +void PIPNet::GenerateLandmarks(std::vector& infer_result, + FaceAlignmentResult* result, + float img_height, float img_width){ + FDTensor outputs_cls = infer_result.at(0); + FDTensor outputs_x = infer_result.at(1); + FDTensor outputs_y = infer_result.at(2); + FDTensor outputs_nb_x = infer_result.at(3); + FDTensor outputs_nb_y = infer_result.at(4); + int grid_h = outputs_cls.shape[2]; // 8 + int grid_w = outputs_cls.shape[3]; // 8 + int grid_length = grid_h * grid_w; // 8 * 8 = 64 + int input_h = size_[1]; + int input_w = size_[0]; + // fetch data from pointers + const float *outputs_cls_ptr = static_cast(outputs_cls.Data()); + const float *outputs_x_ptr = static_cast(outputs_x.Data()); + const float *outputs_y_ptr = static_cast(outputs_y.Data()); + const float *outputs_nb_x_ptr = static_cast(outputs_nb_x.Data()); + const float *outputs_nb_y_ptr = static_cast(outputs_nb_y.Data()); + // find max_ids + std::vector max_ids(num_landmarks_); + for (unsigned int i = 0; i < num_landmarks_; ++i) + { + const float *score_ptr = outputs_cls_ptr + i * grid_length; + unsigned int max_id = 0; + float max_score = score_ptr[0]; + for (unsigned int j = 0; j < grid_length; ++j) + { + if (score_ptr[j] > max_score) + { + max_score = score_ptr[j]; + max_id = j; + } + } + max_ids[i] = max_id; // range 0~64 + } + // find x & y offsets + std::vector output_x_select(num_landmarks_); + std::vector output_y_select(num_landmarks_); + for (unsigned int i = 0; i < num_landmarks_; ++i) + { + const float *offset_x_ptr = outputs_x_ptr + i * grid_length; + const float *offset_y_ptr = outputs_y_ptr + i * grid_length; + const unsigned int max_id = max_ids.at(i); + output_x_select[i] = offset_x_ptr[max_id]; + output_y_select[i] = offset_y_ptr[max_id]; + } + + // find nb_x & nb_y offsets + std::unordered_map> output_nb_x_select; + std::unordered_map> output_nb_y_select; + // initialize offsets map + for (unsigned int i = 0; i < num_landmarks_; ++i) + { + std::vector nb_x_offset(num_nb_); + std::vector nb_y_offset(num_nb_); + output_nb_x_select[i] = nb_x_offset; + output_nb_y_select[i] = nb_y_offset; + } + for (unsigned int i = 0; i < num_landmarks_; ++i) + { + for (unsigned int j = 0; j < num_nb_; ++j) + { + const unsigned int max_id = max_ids.at(i); + const float *offset_nb_x_ptr = outputs_nb_x_ptr + (i * num_nb_ + j) * grid_length; + const float *offset_nb_y_ptr = outputs_nb_y_ptr + (i * num_nb_ + j) * grid_length; + output_nb_x_select[i][j] = offset_nb_x_ptr[max_id]; + output_nb_y_select[i][j] = offset_nb_y_ptr[max_id]; + } + } + + // calculate coords + std::vector lms_pred_x(num_landmarks_); // 19 + std::vector lms_pred_y(num_landmarks_); // 19 + std::unordered_map> lms_pred_nb_x; // 19,10 + std::unordered_map> lms_pred_nb_y; // 19,10 + + // initialize pred maps + for (unsigned int i = 0; i < num_landmarks_; ++i) + { + std::vector nb_x_offset(num_nb_); + std::vector nb_y_offset(num_nb_); + lms_pred_nb_x[i] = nb_x_offset; + lms_pred_nb_y[i] = nb_y_offset; + } + for (unsigned int i = 0; i < num_landmarks_; ++i) + { + float cx = static_cast(max_ids.at(i) % grid_w); + float cy = static_cast(max_ids.at(i) / grid_w); + // calculate coords & normalize + lms_pred_x[i] = ((cx + output_x_select[i]) * (float) net_stride_) / (float) input_w; + lms_pred_y[i] = ((cy + output_y_select[i]) * (float) net_stride_) / (float) input_h; + for (unsigned int j = 0; j < num_nb_; ++j) + { + lms_pred_nb_x[i][j] = ((cx + output_nb_x_select[i][j]) * (float) net_stride_) / (float) input_w; + lms_pred_nb_y[i][j] = ((cy + output_nb_y_select[i][j]) * (float) net_stride_) / (float) input_h; + } + } + + // reverse indexes + std::unordered_map> tmp_nb_x; // 19,max_len_map_[num_landmarks_] + std::unordered_map> tmp_nb_y; // 19,max_len_map_[num_landmarks_] + // initialize reverse maps + for (unsigned int i = 0; i < num_landmarks_; ++i) + { + std::vector tmp_x(max_len_map_[num_landmarks_]); + std::vector tmp_y(max_len_map_[num_landmarks_]); + tmp_nb_x[i] = tmp_x; + tmp_nb_y[i] = tmp_y; + } + for (unsigned int i = 0; i < num_landmarks_; ++i) + { + for (unsigned int j = 0; j < max_len_map_[num_landmarks_]; ++j) + { + unsigned int ri = reverse_index1_map_[num_landmarks_][i * max_len_map_[num_landmarks_] + j]; + unsigned int rj = reverse_index2_map_[num_landmarks_][i * max_len_map_[num_landmarks_] + j]; + tmp_nb_x[i][j] = lms_pred_nb_x[ri][rj]; + tmp_nb_y[i][j] = lms_pred_nb_y[ri][rj]; + } + } + + // merge predictions + result->Clear(); + for (unsigned int i = 0; i < num_landmarks_; ++i) + { + float total_x = lms_pred_x[i]; + float total_y = lms_pred_y[i]; + for (unsigned int j = 0; j < max_len_map_[num_landmarks_]; ++j) + { + total_x += tmp_nb_x[i][j]; + total_y += tmp_nb_y[i][j]; + } + float x = total_x / ((float) max_len_map_[num_landmarks_] + 1.f); + float y = total_y / ((float) max_len_map_[num_landmarks_] + 1.f); + x = std::min(std::max(0.f, x), 1.0f); + y = std::min(std::max(0.f, y), 1.0f); + result->landmarks.emplace_back( + std::array{x * img_width, y * img_height}); + } +}; +void PIPNet::SetNumLandmarks(int num_landmarks){ + if(supported_num_landmarks_.find(num_landmarks_)==supported_num_landmarks_.end()){ + FDWARNING<<"The number of landmarks should be in {19, 29, 68, 98}."<>* im_info) { // Resize - int resize_w = size[0]; - int resize_h = size[1]; + int resize_w = size_[0]; + int resize_h = size_[1]; if (resize_h != mat->Height() || resize_w != mat->Width()) { Resize::Run(mat, resize_w, resize_h); } @@ -66,7 +450,7 @@ bool PIPNet::Preprocess(Mat* mat, FDTensor* output, BGR2RGB::Run(mat); // Normalize - Normalize::Run(mat, mean_vals, std_vals); + Normalize::Run(mat, mean_vals_, std_vals_); // Record output shape of preprocessed image (*im_info)["output_shape"] = {mat->Height(), mat->Width()}; @@ -78,10 +462,10 @@ bool PIPNet::Preprocess(Mat* mat, FDTensor* output, return true; } -bool PIPNet::Postprocess(FDTensor& infer_result, FaceAlignmentResult* result, +bool PIPNet::Postprocess(std::vector& infer_result, FaceAlignmentResult* result, const std::map>& im_info) { - FDASSERT(infer_result.shape[0] == 1, "Only support batch = 1 now."); - if (infer_result.dtype != FDDataType::FP32) { + FDASSERT(infer_result.at(0).shape[0] == 1, "Only support batch = 1 now."); + if (infer_result.at(0).dtype != FDDataType::FP32) { FDERROR << "Only support post process with float32 data." << std::endl; return false; } @@ -91,18 +475,7 @@ bool PIPNet::Postprocess(FDTensor& infer_result, FaceAlignmentResult* result, "Cannot find input_shape from im_info."); int in_h = iter_in->second[0]; int in_w = iter_in->second[1]; - - result->Clear(); - float* data = static_cast(infer_result.Data()); - for (size_t i = 0; i < infer_result.shape[1]; i += 2) { - float x = data[i]; - float y = data[i + 1]; - x = std::min(std::max(0.f, x), 1.0f); - y = std::min(std::max(0.f, y), 1.0f); - // decode landmarks (default 106 landmarks) - result->landmarks.emplace_back( - std::array{x * in_w, y * in_h}); - } + GenerateLandmarks(infer_result, result, in_h, in_w); return true; } @@ -128,7 +501,7 @@ bool PIPNet::Predict(cv::Mat* im, FaceAlignmentResult* result) { return false; } - if (!Postprocess(output_tensors[1], result, im_info)) { + if (!Postprocess(output_tensors, result, im_info)) { FDERROR << "Failed to post process." << std::endl; return false; } diff --git a/fastdeploy/vision/facealign/contrib/pipnet.h b/fastdeploy/vision/facealign/contrib/pipnet.h index 97e29295fbe..6aab5848293 100644 --- a/fastdeploy/vision/facealign/contrib/pipnet.h +++ b/fastdeploy/vision/facealign/contrib/pipnet.h @@ -16,6 +16,7 @@ #include "fastdeploy/fastdeploy_model.h" #include "fastdeploy/vision/common/processors/transform.h" #include "fastdeploy/vision/common/result.h" +#include namespace fastdeploy { @@ -46,17 +47,57 @@ class FASTDEPLOY_DECL PIPNet : public FastDeployModel { */ virtual bool Predict(cv::Mat* im, FaceAlignmentResult* result); - /// tuple of (width, height), default (256, 256) - std::vector size; + // tuple of (width, height), default (256, 256) + std::vector size_; - /*! @brief - Mean parameters for normalize, size should be the the same as channels, default mean_vals = {0.485f, 0.456f, 0.406f} - */ - std::vector mean_vals; - /*! @brief - Std parameters for normalize, size should be the the same as channels, default std_vals = {0.229f, 0.224f, 0.225f} - */ - std::vector std_vals; + // Mean parameters for normalize, size should be the the same as channels, + // default mean_vals = {0.485f, 0.456f, 0.406f} + std::vector mean_vals_; + // Std parameters for normalize, size should be the the same as channels, + // default std_vals = {0.229f, 0.224f, 0.225f} + std::vector std_vals_; + // number of landmarks + int num_landmarks_; + /** \brief Get the number of landmakrs + * + * \return Integer type, default num_landmarks = 19 + */ + int GetNumLandmarks() {return num_landmarks_;} + /** \brief Get the mean values for normalization + * + * \return Vector of float values, default mean_vals = {0.485f, 0.456f, 0.406f} + */ + std::vector GetMeanVals() { return mean_vals_;} + /** \brief Get the std values for normalization + * + * \return Vector of float values, default std_vals = {0.229f, 0.224f, 0.225f} + */ + std::vector GetStdVals() { return std_vals_;} + /** \brief Get the input size of image + * + * \return Vector of int values, default {256, 256} + */ + std::vector GetSize() { return size_;} + /** \brief Set the number of landmarks + * + * \param[in] num_landmarks Integer value which represents number of landmarks + */ + void SetNumLandmarks(int num_landmarks); + /** \brief Set the mean values for normalization + * + * \param[in] mean_vals Vector of float values whose length is equal to 3 + */ + void SetMeanVals(std::vector mean_vals) { mean_vals_ = mean_vals;} + /** \brief Set the std values for normalization + * + * \param[in] std_vals Vector of float values whose length is equal to 3 + */ + void SetStdVals(std::vector std_vals) {std_vals_ = std_vals;} + /** \brief Set the input size of image + * + * \param[in] size Vector of int values which represents {width, height} of image + */ + void SetSize(std::vector size) {size_ = size;} private: bool Initialize(); @@ -64,8 +105,20 @@ class FASTDEPLOY_DECL PIPNet : public FastDeployModel { bool Preprocess(Mat* mat, FDTensor* outputs, std::map>* im_info); - bool Postprocess(FDTensor& infer_result, FaceAlignmentResult* result, + bool Postprocess(std::vector& infer_result, + FaceAlignmentResult* result, const std::map>& im_info); + void GenerateLandmarks(std::vector& infer_result, + FaceAlignmentResult* result, + float img_height, float img_width); + std::map num_lms_map_; + std::map max_len_map_; + std::map> reverse_index1_map_; + std::map> reverse_index2_map_; + int num_nb_; + int net_stride_; + // Now PIPNet support num_landmarks in {19, 29, 68, 98} + std::set supported_num_landmarks_; }; } // namespace facealign diff --git a/fastdeploy/vision/facealign/contrib/pipnet_pybind.cc b/fastdeploy/vision/facealign/contrib/pipnet_pybind.cc index 0ba19c9aa70..f1b409604ad 100644 --- a/fastdeploy/vision/facealign/contrib/pipnet_pybind.cc +++ b/fastdeploy/vision/facealign/contrib/pipnet_pybind.cc @@ -26,6 +26,9 @@ void BindPIPNet(pybind11::module& m) { self.Predict(&mat, &res); return res; }) - .def_readwrite("size", &vision::facealign::PIPNet::size); + .def_readwrite("size", &vision::facealign::PIPNet::size_) + .def_readwrite("mean_vals", &vision::facealign::PIPNet::mean_vals_) + .def_readwrite("std_vals", &vision::facealign::PIPNet::std_vals_) + .def_readwrite("num_landmarks", &vision::facealign::PIPNet::num_landmarks_); } } // namespace fastdeploy \ No newline at end of file diff --git a/fastdeploy/vision/facealign/facealign_pybind.cc b/fastdeploy/vision/facealign/facealign_pybind.cc index 60ccdf605a9..19067d56699 100644 --- a/fastdeploy/vision/facealign/facealign_pybind.cc +++ b/fastdeploy/vision/facealign/facealign_pybind.cc @@ -17,9 +17,14 @@ namespace fastdeploy { void BindPFLD(pybind11::module& m); +void BindFaceLandmark1000(pybind11::module& m); +void BindPIPNet(pybind11::module& m); void BindFaceAlign(pybind11::module& m) { auto facedet_module = m.def_submodule("facealign", "Face alignment models."); BindPFLD(facedet_module); + BindFaceLandmark1000(facedet_module); + BindPIPNet(facedet_module); + } } // namespace fastdeploy diff --git a/python/fastdeploy/vision/facealign/__init__.py b/python/fastdeploy/vision/facealign/__init__.py index be5b8c76cb0..c55585ff9ad 100644 --- a/python/fastdeploy/vision/facealign/__init__.py +++ b/python/fastdeploy/vision/facealign/__init__.py @@ -14,3 +14,5 @@ from __future__ import absolute_import from .contrib.pfld import PFLD +from .contrib.pipnet import PIPNet +from .contrib.face_landmark_1000 import FaceLandmark1000 diff --git a/python/fastdeploy/vision/facealign/contrib/face_landmark_1000.py b/python/fastdeploy/vision/facealign/contrib/face_landmark_1000.py new file mode 100644 index 00000000000..67f980f4099 --- /dev/null +++ b/python/fastdeploy/vision/facealign/contrib/face_landmark_1000.py @@ -0,0 +1,68 @@ +# 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. + +from __future__ import absolute_import +import logging +from .... import FastDeployModel, ModelFormat +from .... import c_lib_wrap as C + + +class FaceLandmark1000(FastDeployModel): + def __init__(self, + model_file, + params_file="", + runtime_option=None, + model_format=ModelFormat.ONNX): + """Load a face alignment model exported by FaceLandmark1000. + + :param model_file: (str)Path of model file, e.g ./FaceLandmark1000.onnx + :param params_file: (str)Path of parameters file, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model, default is ONNX + """ + + super(FaceLandmark1000, self).__init__(runtime_option) + + assert model_format == ModelFormat.ONNX, "FaceLandmark1000 only support model format of ModelFormat.ONNX now." + self._model = C.vision.facealign.FaceLandmark1000( + model_file, params_file, self._runtime_option, model_format) + assert self.initialized, "FaceLandmark1000 initialize failed." + + def predict(self, input_image): + """Detect an input image landmarks + + :param im: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :return: FaceAlignmentResult + """ + + return self._model.predict(input_image) + + @property + def size(self): + """ + Returns the preprocess image size, default (128, 128) + """ + return self._model.size + + @size.setter + def size(self, wh): + """ + Set the preprocess image size, default (128, 128) + """ + assert isinstance(wh, (list, tuple)),\ + "The value to set `size` must be type of tuple or list." + assert len(wh) == 2,\ + "The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format( + len(wh)) + self._model.size = wh diff --git a/python/fastdeploy/vision/facealign/contrib/pipnet.py b/python/fastdeploy/vision/facealign/contrib/pipnet.py new file mode 100644 index 00000000000..6ba3fc71149 --- /dev/null +++ b/python/fastdeploy/vision/facealign/contrib/pipnet.py @@ -0,0 +1,107 @@ +# 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. + +from __future__ import absolute_import +import logging +from .... import FastDeployModel, ModelFormat +from .... import c_lib_wrap as C + + +class PIPNet(FastDeployModel): + def __init__(self, + model_file, + params_file="", + runtime_option=None, + model_format=ModelFormat.ONNX): + """Load a face alignment model exported by PIPNet. + + :param model_file: (str)Path of model file, e.g ./PIPNet.onnx + :param params_file: (str)Path of parameters file, if the model_fomat is ModelFormat.ONNX, this param will be ignored, can be set as empty string + :param runtime_option: (fastdeploy.RuntimeOption)RuntimeOption for inference this model, if it's None, will use the default backend on CPU + :param model_format: (fastdeploy.ModelForamt)Model format of the loaded model, default is ONNX + """ + + super(PIPNet, self).__init__(runtime_option) + + assert model_format == ModelFormat.ONNX, "PIPNet only support model format of ModelFormat.ONNX now." + self._model = C.vision.facealign.PIPNet( + model_file, params_file, self._runtime_option, model_format) + assert self.initialized, "PIPNet initialize failed." + + def predict(self, input_image): + """Detect an input image landmarks + + :param im: (numpy.ndarray)The input image data, 3-D array with layout HWC, BGR format + :return: FaceAlignmentResult + """ + + return self._model.predict(input_image) + + @property + def size(self): + """ + Returns the preprocess image size, default (256, 256) + """ + return self._model.size + + @property + def mean_vals(self): + """ + Returns the mean value of normlization, default mean_vals = [0.485f, 0.456f, 0.406f]; + """ + return self._model.mean_vals + + @property + def std_vals(self): + """ + Returns the std value of normlization, default std_vals = [0.229f, 0.224f, 0.225f]; + """ + return self._model.std_vals + + @property + def num_landmarks(self): + """ + Returns the number of landmarks + """ + return self._model.num_landmarks + + @size.setter + def size(self, wh): + """ + Set the preprocess image size, default (256, 256) + """ + assert isinstance(wh, (list, tuple)),\ + "The value to set `size` must be type of tuple or list." + assert len(wh) == 2,\ + "The value to set `size` must contatins 2 elements means [width, height], but now it contains {} elements.".format( + len(wh)) + self._model.size = wh + + @mean_vals.setter + def mean_vals(self, value): + assert isinstance( + value, list), "The value to set `mean_vals` must be type of list." + self._model.mean_vals = value + + @std_vals.setter + def std_vals(self, value): + assert isinstance( + value, list), "The value to set `std_vals` must be type of list." + self._model.std_vals = value + + @num_landmarks.setter + def num_landmarks(self, value): + assert isinstance( + value, int), "The value to set `std_vals` must be type of int." + self._model.num_landmarks = value diff --git a/tests/eval_example/test_facelandmark1000.py b/tests/eval_example/test_facelandmark1000.py new file mode 100644 index 00000000000..59af91e9241 --- /dev/null +++ b/tests/eval_example/test_facelandmark1000.py @@ -0,0 +1,43 @@ +# 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. + +import fastdeploy as fd +import cv2 +import os +import numpy as np + + +def test_facealignment_pipnet(): + model_url = "https://bj.bcebos.com/paddlehub/fastdeploy/Facelandmark1000.onnx" + input_url = "https://bj.bcebos.com/paddlehub/fastdeploy/facealign_input.png" + output_url = "https://bj.bcebos.com/paddlehub/fastdeploy/tests/facelandmark1000_result_landmarks.npy" + fd.download(model_url, ".") + fd.download(input_url, ".") + fd.download(output_url, ".") + model_path = "Facelandmark1000.onnx" + # use ORT + runtime_option = fd.RuntimeOption() + runtime_option.use_ort_backend() + model = fd.vision.facealign.Facelandmark1000( + model_path, runtime_option=runtime_option) + + # compare diff + im = cv2.imread("./facealign_input.png") + result = model.predict(im.copy()) + expect = np.load("./facelandmark1000_result_landmarks.npy") + + diff = np.fabs(np.array(result.landmarks) - expect) + thres = 1e-04 + assert diff.max() < thres, "The diff is %f, which is bigger than %f" % ( + diff.max(), thres) diff --git a/tests/eval_example/test_pipnet.py b/tests/eval_example/test_pipnet.py new file mode 100644 index 00000000000..012ae675861 --- /dev/null +++ b/tests/eval_example/test_pipnet.py @@ -0,0 +1,43 @@ +# 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. + +import fastdeploy as fd +import cv2 +import os +import numpy as np + + +def test_facealignment_pipnet(): + model_url = "https://bj.bcebos.com/paddlehub/fastdeploy/pipnet_resnet18_10x19x32x256_aflw.onnx" + input_url = "https://bj.bcebos.com/paddlehub/fastdeploy/facealign_input.png" + output_url = "https://bj.bcebos.com/paddlehub/fastdeploy/tests/pipnet_result_landmarks.npy" + fd.download(model_url, ".") + fd.download(input_url, ".") + fd.download(output_url, ".") + model_path = "pipnet_resnet18_10x19x32x256_aflw.onnx" + # use ORT + runtime_option = fd.RuntimeOption() + runtime_option.use_ort_backend() + model = fd.vision.facealign.PIPNet( + model_path, runtime_option=runtime_option) + + # compare diff + im = cv2.imread("./facealign_input.png") + result = model.predict(im.copy()) + expect = np.load("./pipnet_result_landmarks.npy") + + diff = np.fabs(np.array(result.landmarks) - expect) + thres = 1e-04 + assert diff.max() < thres, "The diff is %f, which is bigger than %f" % ( + diff.max(), thres) diff --git a/tests/vision_preprocess/test_vision_colorspace_convert.cc b/tests/vision_preprocess/test_vision_colorspace_convert.cc index f1253d959ca..210b47bb8ab 100644 --- a/tests/vision_preprocess/test_vision_colorspace_convert.cc +++ b/tests/vision_preprocess/test_vision_colorspace_convert.cc @@ -71,6 +71,31 @@ TEST(fastdeploy, flycv_rgb2bgr) { check_data(reinterpret_cast(opencv.Data()), reinterpret_cast(flycv.Data()), opencv.Numel()); check_type(opencv.dtype, flycv.dtype); } + +TEST(fastdeploy, flycv_rgb2gray) { + CheckShape check_shape; + CheckData check_data; + CheckType check_type; + + cv::Mat mat(64, 64, CV_8UC3); + cv::randu(mat, cv::Scalar::all(0), cv::Scalar::all(255)); + cv::Mat mat1 = mat.clone(); + + vision::Mat mat_opencv(mat); + vision::Mat mat_flycv(mat1); + vision::RGB2GRAY::Run(&mat_opencv, vision::ProcLib::OPENCV); + vision::RGB2GRAY::Run(&mat_flycv, vision::ProcLib::FLYCV); + + FDTensor opencv; + FDTensor flycv; + + mat_opencv.ShareWithTensor(&opencv); + mat_flycv.ShareWithTensor(&flycv); + + check_shape(opencv.shape, flycv.shape); + check_data(reinterpret_cast(opencv.Data()), reinterpret_cast(flycv.Data()), opencv.Numel()); + check_type(opencv.dtype, flycv.dtype); +} #endif } // namespace fastdeploy From 84083c153df98f58b84fcae56f81ad8d9f90acdd Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Wed, 9 Nov 2022 03:55:19 +0000 Subject: [PATCH 55/69] fix facelandmark1000 sigle test --- tests/eval_example/test_facelandmark1000.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/eval_example/test_facelandmark1000.py b/tests/eval_example/test_facelandmark1000.py index 59af91e9241..5fc2f87302c 100644 --- a/tests/eval_example/test_facelandmark1000.py +++ b/tests/eval_example/test_facelandmark1000.py @@ -19,17 +19,17 @@ def test_facealignment_pipnet(): - model_url = "https://bj.bcebos.com/paddlehub/fastdeploy/Facelandmark1000.onnx" + model_url = "https://bj.bcebos.com/paddlehub/fastdeploy/FaceLandmark1000.onnx" input_url = "https://bj.bcebos.com/paddlehub/fastdeploy/facealign_input.png" output_url = "https://bj.bcebos.com/paddlehub/fastdeploy/tests/facelandmark1000_result_landmarks.npy" fd.download(model_url, ".") fd.download(input_url, ".") fd.download(output_url, ".") - model_path = "Facelandmark1000.onnx" + model_path = "FaceLandmark1000.onnx" # use ORT runtime_option = fd.RuntimeOption() runtime_option.use_ort_backend() - model = fd.vision.facealign.Facelandmark1000( + model = fd.vision.facealign.FaceLandmark1000( model_path, runtime_option=runtime_option) # compare diff From 83c726ff3e5ca7d7a6f550ac5ba628b91a79678b Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Wed, 9 Nov 2022 06:54:34 +0000 Subject: [PATCH 56/69] fix python examples for PIPNet and FaceLandmark1000 --- examples/vision/facealign/face_landmark_1000/python/infer.py | 2 +- examples/vision/facealign/pipnet/python/infer.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/vision/facealign/face_landmark_1000/python/infer.py b/examples/vision/facealign/face_landmark_1000/python/infer.py index 96f8356339d..d6f52760c20 100644 --- a/examples/vision/facealign/face_landmark_1000/python/infer.py +++ b/examples/vision/facealign/face_landmark_1000/python/infer.py @@ -22,7 +22,7 @@ def parse_arguments(): help="inference backend, ort, ov, trt, paddle, paddle_trt.") parser.add_argument( "--enable_trt_fp16", - type=bool, + type=ast.literal_eval, default=False, help="whether enable fp16 in trt/paddle_trt backend") return parser.parse_args() diff --git a/examples/vision/facealign/pipnet/python/infer.py b/examples/vision/facealign/pipnet/python/infer.py index c724efada5d..fa34d38444f 100644 --- a/examples/vision/facealign/pipnet/python/infer.py +++ b/examples/vision/facealign/pipnet/python/infer.py @@ -21,7 +21,7 @@ def parse_arguments(): help="inference backend, ort, ov, trt, paddle, paddle_trt.") parser.add_argument( "--enable_trt_fp16", - type=bool, + type=ast.literal_eval, default=False, help="whether enable fp16 in trt/paddle_trt backend") parser.add_argument( From 96e1783262457ac0523816cbfe45745a304e3906 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Wed, 9 Nov 2022 07:04:59 +0000 Subject: [PATCH 57/69] fix examples links for PIPNet and FaceLandmark1000 --- examples/vision/facealign/face_landmark_1000/cpp/README.md | 2 +- examples/vision/facealign/face_landmark_1000/python/README.md | 2 +- examples/vision/facealign/pipnet/cpp/README.md | 2 +- examples/vision/facealign/pipnet/python/README.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/vision/facealign/face_landmark_1000/cpp/README.md b/examples/vision/facealign/face_landmark_1000/cpp/README.md index 3f34befec49..da8733bd88d 100644 --- a/examples/vision/facealign/face_landmark_1000/cpp/README.md +++ b/examples/vision/facealign/face_landmark_1000/cpp/README.md @@ -32,7 +32,7 @@ wget https://bj.bcebos.com/paddlehub/fastdeploy/facealign_input.png 运行完成可视化结果如下图所示
- +
以上命令只适用于Linux或MacOS, Windows下SDK的使用方式请参考: diff --git a/examples/vision/facealign/face_landmark_1000/python/README.md b/examples/vision/facealign/face_landmark_1000/python/README.md index 0047f54ac36..ae60fab6da9 100644 --- a/examples/vision/facealign/face_landmark_1000/python/README.md +++ b/examples/vision/facealign/face_landmark_1000/python/README.md @@ -28,7 +28,7 @@ python infer.py --model FaceLandmark1000.onnx --image facealign_input.png --devi 运行完成可视化结果如下图所示
- +
## FaceLandmark1000 Python接口 diff --git a/examples/vision/facealign/pipnet/cpp/README.md b/examples/vision/facealign/pipnet/cpp/README.md index e5156caea32..196d083ca60 100644 --- a/examples/vision/facealign/pipnet/cpp/README.md +++ b/examples/vision/facealign/pipnet/cpp/README.md @@ -32,7 +32,7 @@ wget https://bj.bcebos.com/paddlehub/fastdeploy/facealign_input.png 运行完成可视化结果如下图所示
- +
以上命令只适用于Linux或MacOS, Windows下SDK的使用方式请参考: diff --git a/examples/vision/facealign/pipnet/python/README.md b/examples/vision/facealign/pipnet/python/README.md index 316a98f3d34..4253072e2a4 100644 --- a/examples/vision/facealign/pipnet/python/README.md +++ b/examples/vision/facealign/pipnet/python/README.md @@ -28,7 +28,7 @@ python infer.py --model pipnet_resnet18_10x19x32x256_aflw.onnx --image facealign 运行完成可视化结果如下图所示
- +
## PIPNet Python接口 From 2d71fcf3636f16499e0a2c69083641cfd8aabb56 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Wed, 9 Nov 2022 07:10:58 +0000 Subject: [PATCH 58/69] modify test_vision_colorspace_convert.cc --- .../test_vision_colorspace_convert.cc | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/vision_preprocess/test_vision_colorspace_convert.cc b/tests/vision_preprocess/test_vision_colorspace_convert.cc index 210b47bb8ab..d9cdc823150 100644 --- a/tests/vision_preprocess/test_vision_colorspace_convert.cc +++ b/tests/vision_preprocess/test_vision_colorspace_convert.cc @@ -96,6 +96,31 @@ TEST(fastdeploy, flycv_rgb2gray) { check_data(reinterpret_cast(opencv.Data()), reinterpret_cast(flycv.Data()), opencv.Numel()); check_type(opencv.dtype, flycv.dtype); } + +TEST(fastdeploy, flycv_bgr2gray) { + CheckShape check_shape; + CheckData check_data; + CheckType check_type; + + cv::Mat mat(64, 64, CV_8UC3); + cv::randu(mat, cv::Scalar::all(0), cv::Scalar::all(255)); + cv::Mat mat1 = mat.clone(); + + vision::Mat mat_opencv(mat); + vision::Mat mat_flycv(mat1); + vision::BGR2GRAY::Run(&mat_opencv, vision::ProcLib::OPENCV); + vision::BGR2GRAY::Run(&mat_flycv, vision::ProcLib::FLYCV); + + FDTensor opencv; + FDTensor flycv; + + mat_opencv.ShareWithTensor(&opencv); + mat_flycv.ShareWithTensor(&flycv); + + check_shape(opencv.shape, flycv.shape); + check_data(reinterpret_cast(opencv.Data()), reinterpret_cast(flycv.Data()), opencv.Numel()); + check_type(opencv.dtype, flycv.dtype); +} #endif } // namespace fastdeploy From a2c30bd2507fc4fd738d67c4f3456450e59de580 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Wed, 9 Nov 2022 08:40:16 +0000 Subject: [PATCH 59/69] modify facealign readme --- examples/vision/facealign/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/vision/facealign/README.md b/examples/vision/facealign/README.md index d145c7c8f9c..9a5dd9d38f6 100644 --- a/examples/vision/facealign/README.md +++ b/examples/vision/facealign/README.md @@ -5,3 +5,5 @@ FastDeploy目前支持如下人脸对齐(关键点检测)模型部署 | 模型 | 说明 | 模型格式 | 版本 | | :--- | :--- | :------- | :--- | | [Hsintao/pfld_106_face_landmarks](./pfld) | PFLD 系列模型 | ONNX | [CommitID:e150195](https://github.com/Hsintao/pfld_106_face_landmarks/commit/e150195) | +| [Single430/FaceLandmark1000](./facelandmark) | FaceLandmark1000 系列模型 | ONNX | [CommitID:1a951b6](https://github.com/Single430/FaceLandmark1000/tree/1a951b6) | +| [jhb86253817/PIPNet](./pipnet) | PIPNet 系列模型 | ONNX | [CommitID:b9eab58](https://github.com/jhb86253817/PIPNet/tree/b9eab58) | From dce700087705d494db5569229e4aa255e1bd9f16 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Thu, 10 Nov 2022 06:27:29 +0000 Subject: [PATCH 60/69] retrigger ci From f6a0f8ed1e0b4ac5dbaeb90e6aa84be8f11f7e3a Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Fri, 11 Nov 2022 05:38:32 +0000 Subject: [PATCH 61/69] modify README --- examples/vision/facealign/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/vision/facealign/README.md b/examples/vision/facealign/README.md index 9a5dd9d38f6..df0b441112a 100644 --- a/examples/vision/facealign/README.md +++ b/examples/vision/facealign/README.md @@ -5,5 +5,5 @@ FastDeploy目前支持如下人脸对齐(关键点检测)模型部署 | 模型 | 说明 | 模型格式 | 版本 | | :--- | :--- | :------- | :--- | | [Hsintao/pfld_106_face_landmarks](./pfld) | PFLD 系列模型 | ONNX | [CommitID:e150195](https://github.com/Hsintao/pfld_106_face_landmarks/commit/e150195) | -| [Single430/FaceLandmark1000](./facelandmark) | FaceLandmark1000 系列模型 | ONNX | [CommitID:1a951b6](https://github.com/Single430/FaceLandmark1000/tree/1a951b6) | +| [Single430/FaceLandmark1000](./face_landmark_1000) | FaceLandmark1000 系列模型 | ONNX | [CommitID:1a951b6](https://github.com/Single430/FaceLandmark1000/tree/1a951b6) | | [jhb86253817/PIPNet](./pipnet) | PIPNet 系列模型 | ONNX | [CommitID:b9eab58](https://github.com/jhb86253817/PIPNet/tree/b9eab58) | From c7ee59cf4b6b1921c3c844fbc29a102855d9c837 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Fri, 11 Nov 2022 07:25:26 +0000 Subject: [PATCH 62/69] test ci --- fastdeploy/vision/facealign/contrib/pipnet.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fastdeploy/vision/facealign/contrib/pipnet.cc b/fastdeploy/vision/facealign/contrib/pipnet.cc index 27d78e8bcbc..92b955e24b8 100644 --- a/fastdeploy/vision/facealign/contrib/pipnet.cc +++ b/fastdeploy/vision/facealign/contrib/pipnet.cc @@ -72,8 +72,8 @@ void PIPNet::GenerateLandmarks(std::vector& infer_result, } // find nb_x & nb_y offsets - std::unordered_map> output_nb_x_select; - std::unordered_map> output_nb_y_select; + std::map> output_nb_x_select; + std::map> output_nb_y_select; // initialize offsets map for (unsigned int i = 0; i < num_landmarks_; ++i) { @@ -97,8 +97,8 @@ void PIPNet::GenerateLandmarks(std::vector& infer_result, // calculate coords std::vector lms_pred_x(num_landmarks_); // 19 std::vector lms_pred_y(num_landmarks_); // 19 - std::unordered_map> lms_pred_nb_x; // 19,10 - std::unordered_map> lms_pred_nb_y; // 19,10 + std::map> lms_pred_nb_x; // 19,10 + std::map> lms_pred_nb_y; // 19,10 // initialize pred maps for (unsigned int i = 0; i < num_landmarks_; ++i) @@ -123,8 +123,8 @@ void PIPNet::GenerateLandmarks(std::vector& infer_result, } // reverse indexes - std::unordered_map> tmp_nb_x; // 19,max_len_map_[num_landmarks_] - std::unordered_map> tmp_nb_y; // 19,max_len_map_[num_landmarks_] + std::map> tmp_nb_x; // 19,max_len_map_[num_landmarks_] + std::map> tmp_nb_y; // 19,max_len_map_[num_landmarks_] // initialize reverse maps for (unsigned int i = 0; i < num_landmarks_; ++i) { From 87d0c26f1664354b1f409045ec8087447186b46e Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Fri, 11 Nov 2022 09:14:04 +0000 Subject: [PATCH 63/69] fix download_prebuilt_libraries.md --- docs/en/build_and_install/download_prebuilt_libraries.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/build_and_install/download_prebuilt_libraries.md b/docs/en/build_and_install/download_prebuilt_libraries.md index 9bf7122ce2d..c0862a25ef1 100755 --- a/docs/en/build_and_install/download_prebuilt_libraries.md +++ b/docs/en/build_and_install/download_prebuilt_libraries.md @@ -3,8 +3,8 @@ FastDeploy provides pre-built libraries for developers to download and install directly. Meanwhile, FastDeploy also offers easy access to compile so that developers can compile FastDeploy according to their own needs. This article is divided into two parts: -- [1.GPU Deployment Environment](##GPU Deployment Environment) -- [2.CPU Deployment Environment](##CPU Deployment Environment) +- [1.GPU Deployment Environment](#GPU Deployment Environment) +- [2.CPU Deployment Environment](#CPU Deployment Environment) ## GPU Deployment Environment From 52e47d6521476a3d3e4a8589e818297d09919a5a Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Fri, 11 Nov 2022 09:17:08 +0000 Subject: [PATCH 64/69] fix download_prebuilt_libraries.md --- docs/en/build_and_install/download_prebuilt_libraries.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/build_and_install/download_prebuilt_libraries.md b/docs/en/build_and_install/download_prebuilt_libraries.md index c0862a25ef1..58edd1d56eb 100755 --- a/docs/en/build_and_install/download_prebuilt_libraries.md +++ b/docs/en/build_and_install/download_prebuilt_libraries.md @@ -3,8 +3,8 @@ FastDeploy provides pre-built libraries for developers to download and install directly. Meanwhile, FastDeploy also offers easy access to compile so that developers can compile FastDeploy according to their own needs. This article is divided into two parts: -- [1.GPU Deployment Environment](#GPU Deployment Environment) -- [2.CPU Deployment Environment](#CPU Deployment Environment) +- [1.GPU Deployment Environment](#gpu-deployment-environment) +- [2.CPU Deployment Environment](#cpu-deployment-environment) ## GPU Deployment Environment From 03ae82dca2cc2905f02dbe3f9cb1a0182539546a Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Fri, 11 Nov 2022 10:34:25 +0000 Subject: [PATCH 65/69] modify for comments --- .../face_landmark_1000/cpp/CMakeLists.txt | 6 +++- .../face_landmark_1000/cpp/README.md | 2 +- .../face_landmark_1000/python/README.md | 2 +- .../facealign/pipnet/cpp/CMakeLists.txt | 6 +++- .../vision/facealign/pipnet/cpp/README.md | 2 +- .../vision/facealign/pipnet/python/README.md | 2 +- .../common/processors/color_space_convert.cc | 24 ++++++------- .../common/processors/color_space_convert.h | 24 ++++++------- fastdeploy/vision/common/result.cc | 6 ++-- .../facealign/contrib/face_landmark_1000.h | 6 ++-- .../contrib/face_landmark_1000_pybind.cc | 2 +- fastdeploy/vision/facealign/contrib/pipnet.cc | 7 ++-- fastdeploy/vision/facealign/contrib/pipnet.h | 35 ++++++++++--------- .../vision/facealign/contrib/pipnet_pybind.cc | 8 ++--- 14 files changed, 70 insertions(+), 62 deletions(-) diff --git a/examples/vision/facealign/face_landmark_1000/cpp/CMakeLists.txt b/examples/vision/facealign/face_landmark_1000/cpp/CMakeLists.txt index c6c754a4b50..c417fcb3880 100644 --- a/examples/vision/facealign/face_landmark_1000/cpp/CMakeLists.txt +++ b/examples/vision/facealign/face_landmark_1000/cpp/CMakeLists.txt @@ -11,4 +11,8 @@ include_directories(${FASTDEPLOY_INCS}) add_executable(infer_demo ${PROJECT_SOURCE_DIR}/infer.cc) # 添加FastDeploy库依赖 -target_link_libraries(infer_demo ${FASTDEPLOY_LIBS} gflags pthread) +if(UNIX AND (NOT APPLE) AND (NOT ANDROID)) + target_link_libraries(infer_demo ${FASTDEPLOY_LIBS} gflags pthread) +else() + target_link_libraries(infer_demo ${FASTDEPLOY_LIBS} gflags) +endif() diff --git a/examples/vision/facealign/face_landmark_1000/cpp/README.md b/examples/vision/facealign/face_landmark_1000/cpp/README.md index da8733bd88d..033f54164d1 100644 --- a/examples/vision/facealign/face_landmark_1000/cpp/README.md +++ b/examples/vision/facealign/face_landmark_1000/cpp/README.md @@ -7,7 +7,7 @@ - 1. 软硬件环境满足要求,参考[FastDeploy环境要求](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) - 2. 根据开发环境,下载预编译部署库和samples代码,参考[FastDeploy预编译库](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) -以Linux上CPU推理为例,在本目录执行如下命令即可完成编译测试,保证 FastDeploy 版本0.6.0以上(x.x.x >= 0.6.0)支持FaceLandmark1000模型 +以Linux上CPU推理为例,在本目录执行如下命令即可完成编译测试,保证 FastDeploy 版本0.7.0以上(x.x.x >= 0.7.0)支持FaceLandmark1000模型 ```bash mkdir build diff --git a/examples/vision/facealign/face_landmark_1000/python/README.md b/examples/vision/facealign/face_landmark_1000/python/README.md index ae60fab6da9..380d1cb2705 100644 --- a/examples/vision/facealign/face_landmark_1000/python/README.md +++ b/examples/vision/facealign/face_landmark_1000/python/README.md @@ -5,7 +5,7 @@ - 1. 软硬件环境满足要求,参考[FastDeploy环境要求](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) - 2. FastDeploy Python whl包安装,参考[FastDeploy Python安装](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) -本目录下提供`infer.py`快速完成FaceLandmark1000在CPU/GPU,以及GPU上通过TensorRT加速部署的示例,保证 FastDeploy 版本 >= 0.6.0 支持FaceLandmark1000模型。执行如下脚本即可完成 +本目录下提供`infer.py`快速完成FaceLandmark1000在CPU/GPU,以及GPU上通过TensorRT加速部署的示例,保证 FastDeploy 版本 >= 0.7.0 支持FaceLandmark1000模型。执行如下脚本即可完成 ```bash #下载部署示例代码 diff --git a/examples/vision/facealign/pipnet/cpp/CMakeLists.txt b/examples/vision/facealign/pipnet/cpp/CMakeLists.txt index c6c754a4b50..c417fcb3880 100644 --- a/examples/vision/facealign/pipnet/cpp/CMakeLists.txt +++ b/examples/vision/facealign/pipnet/cpp/CMakeLists.txt @@ -11,4 +11,8 @@ include_directories(${FASTDEPLOY_INCS}) add_executable(infer_demo ${PROJECT_SOURCE_DIR}/infer.cc) # 添加FastDeploy库依赖 -target_link_libraries(infer_demo ${FASTDEPLOY_LIBS} gflags pthread) +if(UNIX AND (NOT APPLE) AND (NOT ANDROID)) + target_link_libraries(infer_demo ${FASTDEPLOY_LIBS} gflags pthread) +else() + target_link_libraries(infer_demo ${FASTDEPLOY_LIBS} gflags) +endif() diff --git a/examples/vision/facealign/pipnet/cpp/README.md b/examples/vision/facealign/pipnet/cpp/README.md index 196d083ca60..3f11bf62b4f 100644 --- a/examples/vision/facealign/pipnet/cpp/README.md +++ b/examples/vision/facealign/pipnet/cpp/README.md @@ -7,7 +7,7 @@ - 1. 软硬件环境满足要求,参考[FastDeploy环境要求](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) - 2. 根据开发环境,下载预编译部署库和samples代码,参考[FastDeploy预编译库](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) -以Linux上CPU推理为例,在本目录执行如下命令即可完成编译测试,保证 FastDeploy 版本0.6.0以上(x.x.x >= 0.6.0)支持PIPNet模型 +以Linux上CPU推理为例,在本目录执行如下命令即可完成编译测试,保证 FastDeploy 版本0.7.0以上(x.x.x >= 0.7.0)支持PIPNet模型 ```bash mkdir build diff --git a/examples/vision/facealign/pipnet/python/README.md b/examples/vision/facealign/pipnet/python/README.md index 4253072e2a4..ae46849c38e 100644 --- a/examples/vision/facealign/pipnet/python/README.md +++ b/examples/vision/facealign/pipnet/python/README.md @@ -5,7 +5,7 @@ - 1. 软硬件环境满足要求,参考[FastDeploy环境要求](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) - 2. FastDeploy Python whl包安装,参考[FastDeploy Python安装](../../../../../docs/cn/build_and_install/download_prebuilt_libraries.md) -本目录下提供`infer.py`快速完成PIPNet在CPU/GPU,以及GPU上通过TensorRT加速部署的示例,保证 FastDeploy 版本 >= 0.6.0 支持PIPNet模型。执行如下脚本即可完成 +本目录下提供`infer.py`快速完成PIPNet在CPU/GPU,以及GPU上通过TensorRT加速部署的示例,保证 FastDeploy 版本 >= 0.7.0 支持PIPNet模型。执行如下脚本即可完成 ```bash #下载部署示例代码 diff --git a/fastdeploy/vision/common/processors/color_space_convert.cc b/fastdeploy/vision/common/processors/color_space_convert.cc index bb78f7b1785..c486c537940 100644 --- a/fastdeploy/vision/common/processors/color_space_convert.cc +++ b/fastdeploy/vision/common/processors/color_space_convert.cc @@ -16,7 +16,7 @@ namespace fastdeploy { namespace vision { -bool BGR2RGB::ImplByOpenCV(Mat* mat) { +bool BGR2RGB::ImplByOpenCV(FDMat* mat) { cv::Mat* im = mat->GetOpenCVMat(); cv::Mat new_im; cv::cvtColor(*im, new_im, cv::COLOR_BGR2RGB); @@ -25,7 +25,7 @@ bool BGR2RGB::ImplByOpenCV(Mat* mat) { } #ifdef ENABLE_FLYCV -bool BGR2RGB::ImplByFlyCV(Mat* mat) { +bool BGR2RGB::ImplByFlyCV(FDMat* mat) { fcv::Mat* im = mat->GetFlyCVMat(); if (im->channels() != 3) { FDERROR << "[BGR2RGB] The channel of input image must be 3, but not it's " @@ -39,7 +39,7 @@ bool BGR2RGB::ImplByFlyCV(Mat* mat) { } #endif -bool RGB2BGR::ImplByOpenCV(Mat* mat) { +bool RGB2BGR::ImplByOpenCV(FDMat* mat) { cv::Mat* im = mat->GetOpenCVMat(); cv::Mat new_im; cv::cvtColor(*im, new_im, cv::COLOR_RGB2BGR); @@ -48,7 +48,7 @@ bool RGB2BGR::ImplByOpenCV(Mat* mat) { } #ifdef ENABLE_FLYCV -bool RGB2BGR::ImplByFlyCV(Mat* mat) { +bool RGB2BGR::ImplByFlyCV(FDMat* mat) { fcv::Mat* im = mat->GetFlyCVMat(); if (im->channels() != 3) { FDERROR << "[RGB2BGR] The channel of input image must be 3, but not it's " @@ -62,7 +62,7 @@ bool RGB2BGR::ImplByFlyCV(Mat* mat) { } #endif -bool BGR2GRAY::ImplByOpenCV(Mat* mat) { +bool BGR2GRAY::ImplByOpenCV(FDMat* mat) { cv::Mat* im = mat->GetOpenCVMat(); cv::Mat new_im; cv::cvtColor(*im, new_im, cv::COLOR_BGR2GRAY); @@ -72,7 +72,7 @@ bool BGR2GRAY::ImplByOpenCV(Mat* mat) { } #ifdef ENABLE_FLYCV -bool BGR2GRAY::ImplByFalconCV(Mat* mat) { +bool BGR2GRAY::ImplByFalconCV(FDMat* mat) { fcv::Mat* im = mat->GetFalconCVMat(); if (im->channels() != 3) { FDERROR << "[BGR2GRAY] The channel of input image must be 3, but not it's " << im->channels() << "." << std::endl; @@ -85,7 +85,7 @@ bool BGR2GRAY::ImplByFalconCV(Mat* mat) { } #endif -bool RGB2GRAY::ImplByOpenCV(Mat* mat) { +bool RGB2GRAY::ImplByOpenCV(FDMat* mat) { cv::Mat* im = mat->GetOpenCVMat(); cv::Mat new_im; cv::cvtColor(*im, new_im, cv::COLOR_RGB2GRAY); @@ -94,7 +94,7 @@ bool RGB2GRAY::ImplByOpenCV(Mat* mat) { } #ifdef ENABLE_FLYCV -bool RGB2GRAY::ImplByFalconCV(Mat* mat) { +bool RGB2GRAY::ImplByFalconCV(FDMat* mat) { fcv::Mat* im = mat->GetFalconCVMat(); if (im->channels() != 3) { FDERROR << "[RGB2GRAY] The channel of input image must be 3, but not it's " << im->channels() << "." << std::endl; @@ -108,22 +108,22 @@ bool RGB2GRAY::ImplByFalconCV(Mat* mat) { #endif -bool BGR2RGB::Run(Mat* mat, ProcLib lib) { +bool BGR2RGB::Run(FDMat* mat, ProcLib lib) { auto b = BGR2RGB(); return b(mat, lib); } -bool RGB2BGR::Run(Mat* mat, ProcLib lib) { +bool RGB2BGR::Run(FDMat* mat, ProcLib lib) { auto r = RGB2BGR(); return r(mat, lib); } -bool BGR2GRAY::Run(Mat* mat, ProcLib lib) { +bool BGR2GRAY::Run(FDMat* mat, ProcLib lib) { auto b = BGR2GRAY(); return b(mat, lib); } -bool RGB2GRAY::Run(Mat* mat, ProcLib lib) { +bool RGB2GRAY::Run(FDMat* mat, ProcLib lib) { auto r = RGB2GRAY(); return r(mat, lib); } diff --git a/fastdeploy/vision/common/processors/color_space_convert.h b/fastdeploy/vision/common/processors/color_space_convert.h index 72736048e68..f9cb10a1905 100644 --- a/fastdeploy/vision/common/processors/color_space_convert.h +++ b/fastdeploy/vision/common/processors/color_space_convert.h @@ -21,46 +21,46 @@ namespace vision { class FASTDEPLOY_DECL BGR2RGB : public Processor { public: - bool ImplByOpenCV(Mat* mat); + bool ImplByOpenCV(FDMat* mat); #ifdef ENABLE_FLYCV - bool ImplByFlyCV(Mat* mat); + bool ImplByFlyCV(FDMat* mat); #endif virtual std::string Name() { return "BGR2RGB"; } - static bool Run(Mat* mat, ProcLib lib = ProcLib::DEFAULT); + static bool Run(FDMat* mat, ProcLib lib = ProcLib::DEFAULT); }; class FASTDEPLOY_DECL RGB2BGR : public Processor { public: - bool ImplByOpenCV(Mat* mat); + bool ImplByOpenCV(FDMat* mat); #ifdef ENABLE_FLYCV - bool ImplByFlyCV(Mat* mat); + bool ImplByFlyCV(FDMat* mat); #endif std::string Name() { return "RGB2BGR"; } - static bool Run(Mat* mat, ProcLib lib = ProcLib::DEFAULT); + static bool Run(FDMat* mat, ProcLib lib = ProcLib::DEFAULT); }; class FASTDEPLOY_DECL BGR2GRAY : public Processor { public: - bool ImplByOpenCV(Mat* mat); + bool ImplByOpenCV(FDMat* mat); #ifdef ENABLE_FLYCV - bool ImplByFalconCV(Mat* mat); + bool ImplByFalconCV(FDMat* mat); #endif virtual std::string Name() { return "BGR2GRAY"; } - static bool Run(Mat* mat, ProcLib lib = ProcLib::OPENCV); + static bool Run(FDMat* mat, ProcLib lib = ProcLib::OPENCV); }; class FASTDEPLOY_DECL RGB2GRAY : public Processor { public: - bool ImplByOpenCV(Mat* mat); + bool ImplByOpenCV(FDMat* mat); #ifdef ENABLE_FLYCV - bool ImplByFalconCV(Mat* mat); + bool ImplByFalconCV(FDMat* mat); #endif std::string Name() { return "RGB2GRAY"; } - static bool Run(Mat* mat, ProcLib lib = ProcLib::OPENCV); + static bool Run(FDMat* mat, ProcLib lib = ProcLib::OPENCV); }; diff --git a/fastdeploy/vision/common/result.cc b/fastdeploy/vision/common/result.cc index c082ed8d134..faadc578879 100755 --- a/fastdeploy/vision/common/result.cc +++ b/fastdeploy/vision/common/result.cc @@ -259,10 +259,10 @@ std::string FaceAlignmentResult::Str() { std::string out; out = "FaceAlignmentResult: [x, y]\n"; - FDASSERT((landmarks.size() >= 10), - "Predict error: the size of landmarks are less than 10."); out = out + "There are " +std::to_string(landmarks.size()) + " landmarks, the top 10 are listed as below:\n"; - for (size_t i = 0; i < 10; ++i) { + int landmarks_size = landmarks.size(); + size_t result_length = std::min(10, landmarks_size); + for (size_t i = 0; i < result_length; ++i) { out = out + std::to_string(landmarks[i][0]) + "," + std::to_string(landmarks[i][1]) + "\n"; } diff --git a/fastdeploy/vision/facealign/contrib/face_landmark_1000.h b/fastdeploy/vision/facealign/contrib/face_landmark_1000.h index 5f15546f77f..0c9e8de4293 100644 --- a/fastdeploy/vision/facealign/contrib/face_landmark_1000.h +++ b/fastdeploy/vision/facealign/contrib/face_landmark_1000.h @@ -47,8 +47,6 @@ class FASTDEPLOY_DECL FaceLandmark1000 : public FastDeployModel { */ virtual bool Predict(cv::Mat* im, FaceAlignmentResult* result); - // tuple of (width, height), default (128, 128) - std::vector size_; /** \brief Get the input size of image * * \return Vector of int values, default {128,128} @@ -58,7 +56,7 @@ class FASTDEPLOY_DECL FaceLandmark1000 : public FastDeployModel { * * \param[in] size Vector of int values which represents {width, height} of image */ - void SetSize(std::vector size) {size_ = size;} + void SetSize(const std::vector& size) {size_ = size;} private: bool Initialize(); @@ -68,6 +66,8 @@ class FASTDEPLOY_DECL FaceLandmark1000 : public FastDeployModel { bool Postprocess(FDTensor& infer_result, FaceAlignmentResult* result, const std::map>& im_info); + // tuple of (width, height), default (128, 128) + std::vector size_; }; } // namespace facealign diff --git a/fastdeploy/vision/facealign/contrib/face_landmark_1000_pybind.cc b/fastdeploy/vision/facealign/contrib/face_landmark_1000_pybind.cc index 0067bdef77a..b94242e8ccb 100644 --- a/fastdeploy/vision/facealign/contrib/face_landmark_1000_pybind.cc +++ b/fastdeploy/vision/facealign/contrib/face_landmark_1000_pybind.cc @@ -26,6 +26,6 @@ void BindFaceLandmark1000(pybind11::module& m) { self.Predict(&mat, &res); return res; }) - .def_readwrite("size", &vision::facealign::FaceLandmark1000::size_); + .def_property("size", &vision::facealign::FaceLandmark1000::GetSize, &vision::facealign::FaceLandmark1000::SetSize); } } // namespace fastdeploy \ No newline at end of file diff --git a/fastdeploy/vision/facealign/contrib/pipnet.cc b/fastdeploy/vision/facealign/contrib/pipnet.cc index 92b955e24b8..5285c9f6e98 100644 --- a/fastdeploy/vision/facealign/contrib/pipnet.cc +++ b/fastdeploy/vision/facealign/contrib/pipnet.cc @@ -13,7 +13,6 @@ // limitations under the License. #include "fastdeploy/vision/facealign/contrib/pipnet.h" -#include "fastdeploy/utils/perf.h" #include "fastdeploy/vision/utils/utils.h" namespace fastdeploy { @@ -23,8 +22,8 @@ namespace vision { namespace facealign { void PIPNet::GenerateLandmarks(std::vector& infer_result, - FaceAlignmentResult* result, - float img_height, float img_width){ + FaceAlignmentResult* result, + float img_height, float img_width){ FDTensor outputs_cls = infer_result.at(0); FDTensor outputs_x = infer_result.at(1); FDTensor outputs_y = infer_result.at(2); @@ -164,7 +163,7 @@ void PIPNet::GenerateLandmarks(std::vector& infer_result, } }; -void PIPNet::SetNumLandmarks(int num_landmarks){ +void PIPNet::SetNumLandmarks(const int& num_landmarks){ if(supported_num_landmarks_.find(num_landmarks_)==supported_num_landmarks_.end()){ FDWARNING<<"The number of landmarks should be in {19, 29, 68, 98}."< size_; - - // Mean parameters for normalize, size should be the the same as channels, - // default mean_vals = {0.485f, 0.456f, 0.406f} - std::vector mean_vals_; - // Std parameters for normalize, size should be the the same as channels, - // default std_vals = {0.229f, 0.224f, 0.225f} - std::vector std_vals_; - // number of landmarks - int num_landmarks_; /** \brief Get the number of landmakrs * * \return Integer type, default num_landmarks = 19 @@ -82,22 +71,23 @@ class FASTDEPLOY_DECL PIPNet : public FastDeployModel { * * \param[in] num_landmarks Integer value which represents number of landmarks */ - void SetNumLandmarks(int num_landmarks); + void SetNumLandmarks(const int& num_landmarks); /** \brief Set the mean values for normalization * * \param[in] mean_vals Vector of float values whose length is equal to 3 */ - void SetMeanVals(std::vector mean_vals) { mean_vals_ = mean_vals;} + void SetMeanVals(const std::vector& mean_vals) + { mean_vals_ = mean_vals;} /** \brief Set the std values for normalization * * \param[in] std_vals Vector of float values whose length is equal to 3 */ - void SetStdVals(std::vector std_vals) {std_vals_ = std_vals;} + void SetStdVals(const std::vector& std_vals) {std_vals_ = std_vals;} /** \brief Set the input size of image * * \param[in] size Vector of int values which represents {width, height} of image */ - void SetSize(std::vector size) {size_ = size;} + void SetSize(const std::vector& size) {size_ = size;} private: bool Initialize(); @@ -119,6 +109,17 @@ class FASTDEPLOY_DECL PIPNet : public FastDeployModel { int net_stride_; // Now PIPNet support num_landmarks in {19, 29, 68, 98} std::set supported_num_landmarks_; + // tuple of (width, height), default (256, 256) + std::vector size_; + + // Mean parameters for normalize, size should be the the same as channels, + // default mean_vals = {0.485f, 0.456f, 0.406f} + std::vector mean_vals_; + // Std parameters for normalize, size should be the the same as channels, + // default std_vals = {0.229f, 0.224f, 0.225f} + std::vector std_vals_; + // number of landmarks + int num_landmarks_; }; } // namespace facealign diff --git a/fastdeploy/vision/facealign/contrib/pipnet_pybind.cc b/fastdeploy/vision/facealign/contrib/pipnet_pybind.cc index f1b409604ad..7722afc4745 100644 --- a/fastdeploy/vision/facealign/contrib/pipnet_pybind.cc +++ b/fastdeploy/vision/facealign/contrib/pipnet_pybind.cc @@ -26,9 +26,9 @@ void BindPIPNet(pybind11::module& m) { self.Predict(&mat, &res); return res; }) - .def_readwrite("size", &vision::facealign::PIPNet::size_) - .def_readwrite("mean_vals", &vision::facealign::PIPNet::mean_vals_) - .def_readwrite("std_vals", &vision::facealign::PIPNet::std_vals_) - .def_readwrite("num_landmarks", &vision::facealign::PIPNet::num_landmarks_); + .def_property("size", &vision::facealign::PIPNet::GetSize, &vision::facealign::PIPNet::SetSize) + .def_property("mean_vals", &vision::facealign::PIPNet::GetMeanVals, &vision::facealign::PIPNet::SetMeanVals) + .def_property("std_vals", &vision::facealign::PIPNet::GetStdVals, &vision::facealign::PIPNet::SetStdVals) + .def_property("num_landmarks", &vision::facealign::PIPNet::GetNumLandmarks, &vision::facealign::PIPNet::SetNumLandmarks); } } // namespace fastdeploy \ No newline at end of file From 1960ee726afd26a18d677af9e57bd5275a4e9e0a Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Sun, 13 Nov 2022 04:00:00 +0000 Subject: [PATCH 66/69] modify supported_num_landmarks --- fastdeploy/vision/facealign/contrib/pipnet.cc | 3 ++- fastdeploy/vision/facealign/contrib/pipnet.h | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fastdeploy/vision/facealign/contrib/pipnet.cc b/fastdeploy/vision/facealign/contrib/pipnet.cc index 5285c9f6e98..1329c64666b 100644 --- a/fastdeploy/vision/facealign/contrib/pipnet.cc +++ b/fastdeploy/vision/facealign/contrib/pipnet.cc @@ -164,7 +164,8 @@ void PIPNet::GenerateLandmarks(std::vector& infer_result, }; void PIPNet::SetNumLandmarks(const int& num_landmarks){ - if(supported_num_landmarks_.find(num_landmarks_)==supported_num_landmarks_.end()){ + if(std::find(supported_num_landmarks_.begin(), supported_num_landmarks_.end(), num_landmarks) \ + ==supported_num_landmarks_.end()){ FDWARNING<<"The number of landmarks should be in {19, 29, 68, 98}."< namespace fastdeploy { @@ -108,7 +107,7 @@ class FASTDEPLOY_DECL PIPNet : public FastDeployModel { int num_nb_; int net_stride_; // Now PIPNet support num_landmarks in {19, 29, 68, 98} - std::set supported_num_landmarks_; + std::vector supported_num_landmarks_; // tuple of (width, height), default (256, 256) std::vector size_; From 6fc8b14d60f1e310029d98576fa724195f8dc02e Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Mon, 14 Nov 2022 03:30:37 +0000 Subject: [PATCH 67/69] retrigger ci From 947fe9bf5de3d7a178d618458bbea3ce8ed4b15b Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Wed, 16 Nov 2022 02:50:56 +0000 Subject: [PATCH 68/69] check code style --- .../facealign/contrib/face_landmark_1000.cc | 27 +- .../contrib/face_landmark_1000_pybind.cc | 21 +- fastdeploy/vision/facealign/contrib/pipnet.cc | 770 +++++++++++------- .../vision/facealign/contrib/pipnet_pybind.cc | 13 +- 4 files changed, 507 insertions(+), 324 deletions(-) diff --git a/fastdeploy/vision/facealign/contrib/face_landmark_1000.cc b/fastdeploy/vision/facealign/contrib/face_landmark_1000.cc index 25b0eee964d..f7b689575c0 100644 --- a/fastdeploy/vision/facealign/contrib/face_landmark_1000.cc +++ b/fastdeploy/vision/facealign/contrib/face_landmark_1000.cc @@ -13,6 +13,7 @@ // limitations under the License. #include "fastdeploy/vision/facealign/contrib/face_landmark_1000.h" + #include "fastdeploy/utils/perf.h" #include "fastdeploy/vision/utils/utils.h" @@ -23,12 +24,12 @@ namespace vision { namespace facealign { FaceLandmark1000::FaceLandmark1000(const std::string& model_file, - const std::string& params_file, - const RuntimeOption& custom_option, - const ModelFormat& model_format) { + const std::string& params_file, + const RuntimeOption& custom_option, + const ModelFormat& model_format) { if (model_format == ModelFormat::ONNX) { - valid_cpu_backends = {Backend::OPENVINO, Backend::ORT}; - valid_gpu_backends = {Backend::ORT, Backend::TRT}; + valid_cpu_backends = {Backend::OPENVINO, Backend::ORT}; + valid_gpu_backends = {Backend::ORT, Backend::TRT}; } else { valid_cpu_backends = {Backend::PDINFER, Backend::ORT}; valid_gpu_backends = {Backend::PDINFER, Backend::ORT, Backend::TRT}; @@ -51,8 +52,9 @@ bool FaceLandmark1000::Initialize() { return true; } -bool FaceLandmark1000::Preprocess(Mat* mat, FDTensor* output, - std::map>* im_info) { +bool FaceLandmark1000::Preprocess( + Mat* mat, FDTensor* output, + std::map>* im_info) { // Resize int resize_w = size_[0]; int resize_h = size_[1]; @@ -72,8 +74,9 @@ bool FaceLandmark1000::Preprocess(Mat* mat, FDTensor* output, return true; } -bool FaceLandmark1000::Postprocess(FDTensor& infer_result, FaceAlignmentResult* result, - const std::map>& im_info) { +bool FaceLandmark1000::Postprocess( + FDTensor& infer_result, FaceAlignmentResult* result, + const std::map>& im_info) { FDASSERT(infer_result.shape[0] == 1, "Only support batch = 1 now."); if (infer_result.dtype != FDDataType::FP32) { FDERROR << "Only support post process with float32 data." << std::endl; @@ -81,8 +84,7 @@ bool FaceLandmark1000::Postprocess(FDTensor& infer_result, FaceAlignmentResult* } auto iter_in = im_info.find("input_shape"); - FDASSERT(iter_in != im_info.end(), - "Cannot find input_shape from im_info."); + FDASSERT(iter_in != im_info.end(), "Cannot find input_shape from im_info."); int in_h = iter_in->second[0]; int in_w = iter_in->second[1]; @@ -94,8 +96,7 @@ bool FaceLandmark1000::Postprocess(FDTensor& infer_result, FaceAlignmentResult* x = std::min(std::max(0.f, x), 1.0f); y = std::min(std::max(0.f, y), 1.0f); // decode landmarks (default 106 landmarks) - result->landmarks.emplace_back( - std::array{x * in_w, y * in_h}); + result->landmarks.emplace_back(std::array{x * in_w, y * in_h}); } return true; diff --git a/fastdeploy/vision/facealign/contrib/face_landmark_1000_pybind.cc b/fastdeploy/vision/facealign/contrib/face_landmark_1000_pybind.cc index b94242e8ccb..6cb337e535d 100644 --- a/fastdeploy/vision/facealign/contrib/face_landmark_1000_pybind.cc +++ b/fastdeploy/vision/facealign/contrib/face_landmark_1000_pybind.cc @@ -16,16 +16,19 @@ namespace fastdeploy { void BindFaceLandmark1000(pybind11::module& m) { - pybind11::class_(m, "FaceLandmark1000") + pybind11::class_( + m, "FaceLandmark1000") .def(pybind11::init()) - .def("predict", - [](vision::facealign::FaceLandmark1000& self, pybind11::array& data) { - auto mat = PyArrayToCvMat(data); - vision::FaceAlignmentResult res; - self.Predict(&mat, &res); - return res; - }) - .def_property("size", &vision::facealign::FaceLandmark1000::GetSize, &vision::facealign::FaceLandmark1000::SetSize); + .def( + "predict", + [](vision::facealign::FaceLandmark1000& self, pybind11::array& data) { + auto mat = PyArrayToCvMat(data); + vision::FaceAlignmentResult res; + self.Predict(&mat, &res); + return res; + }) + .def_property("size", &vision::facealign::FaceLandmark1000::GetSize, + &vision::facealign::FaceLandmark1000::SetSize); } } // namespace fastdeploy \ No newline at end of file diff --git a/fastdeploy/vision/facealign/contrib/pipnet.cc b/fastdeploy/vision/facealign/contrib/pipnet.cc index 1329c64666b..27ec35c0dd6 100644 --- a/fastdeploy/vision/facealign/contrib/pipnet.cc +++ b/fastdeploy/vision/facealign/contrib/pipnet.cc @@ -13,6 +13,7 @@ // limitations under the License. #include "fastdeploy/vision/facealign/contrib/pipnet.h" + #include "fastdeploy/vision/utils/utils.h" namespace fastdeploy { @@ -21,50 +22,46 @@ namespace vision { namespace facealign { -void PIPNet::GenerateLandmarks(std::vector& infer_result, - FaceAlignmentResult* result, - float img_height, float img_width){ +void PIPNet::GenerateLandmarks(std::vector& infer_result, + FaceAlignmentResult* result, float img_height, + float img_width) { FDTensor outputs_cls = infer_result.at(0); - FDTensor outputs_x = infer_result.at(1); - FDTensor outputs_y = infer_result.at(2); - FDTensor outputs_nb_x = infer_result.at(3); - FDTensor outputs_nb_y = infer_result.at(4); - int grid_h = outputs_cls.shape[2]; // 8 - int grid_w = outputs_cls.shape[3]; // 8 - int grid_length = grid_h * grid_w; // 8 * 8 = 64 + FDTensor outputs_x = infer_result.at(1); + FDTensor outputs_y = infer_result.at(2); + FDTensor outputs_nb_x = infer_result.at(3); + FDTensor outputs_nb_y = infer_result.at(4); + int grid_h = outputs_cls.shape[2]; // 8 + int grid_w = outputs_cls.shape[3]; // 8 + int grid_length = grid_h * grid_w; // 8 * 8 = 64 int input_h = size_[1]; int input_w = size_[0]; // fetch data from pointers - const float *outputs_cls_ptr = static_cast(outputs_cls.Data()); - const float *outputs_x_ptr = static_cast(outputs_x.Data()); - const float *outputs_y_ptr = static_cast(outputs_y.Data()); - const float *outputs_nb_x_ptr = static_cast(outputs_nb_x.Data()); - const float *outputs_nb_y_ptr = static_cast(outputs_nb_y.Data()); + const float* outputs_cls_ptr = static_cast(outputs_cls.Data()); + const float* outputs_x_ptr = static_cast(outputs_x.Data()); + const float* outputs_y_ptr = static_cast(outputs_y.Data()); + const float* outputs_nb_x_ptr = static_cast(outputs_nb_x.Data()); + const float* outputs_nb_y_ptr = static_cast(outputs_nb_y.Data()); // find max_ids std::vector max_ids(num_landmarks_); - for (unsigned int i = 0; i < num_landmarks_; ++i) - { - const float *score_ptr = outputs_cls_ptr + i * grid_length; + for (unsigned int i = 0; i < num_landmarks_; ++i) { + const float* score_ptr = outputs_cls_ptr + i * grid_length; unsigned int max_id = 0; float max_score = score_ptr[0]; - for (unsigned int j = 0; j < grid_length; ++j) - { - if (score_ptr[j] > max_score) - { + for (unsigned int j = 0; j < grid_length; ++j) { + if (score_ptr[j] > max_score) { max_score = score_ptr[j]; max_id = j; } } - max_ids[i] = max_id; // range 0~64 + max_ids[i] = max_id; // range 0~64 } // find x & y offsets std::vector output_x_select(num_landmarks_); std::vector output_y_select(num_landmarks_); - for (unsigned int i = 0; i < num_landmarks_; ++i) - { - const float *offset_x_ptr = outputs_x_ptr + i * grid_length; - const float *offset_y_ptr = outputs_y_ptr + i * grid_length; + for (unsigned int i = 0; i < num_landmarks_; ++i) { + const float* offset_x_ptr = outputs_x_ptr + i * grid_length; + const float* offset_y_ptr = outputs_y_ptr + i * grid_length; const unsigned int max_id = max_ids.at(i); output_x_select[i] = offset_x_ptr[max_id]; output_y_select[i] = offset_y_ptr[max_id]; @@ -74,70 +71,75 @@ void PIPNet::GenerateLandmarks(std::vector& infer_result, std::map> output_nb_x_select; std::map> output_nb_y_select; // initialize offsets map - for (unsigned int i = 0; i < num_landmarks_; ++i) - { + for (unsigned int i = 0; i < num_landmarks_; ++i) { std::vector nb_x_offset(num_nb_); std::vector nb_y_offset(num_nb_); output_nb_x_select[i] = nb_x_offset; output_nb_y_select[i] = nb_y_offset; } - for (unsigned int i = 0; i < num_landmarks_; ++i) - { - for (unsigned int j = 0; j < num_nb_; ++j) - { + for (unsigned int i = 0; i < num_landmarks_; ++i) { + for (unsigned int j = 0; j < num_nb_; ++j) { const unsigned int max_id = max_ids.at(i); - const float *offset_nb_x_ptr = outputs_nb_x_ptr + (i * num_nb_ + j) * grid_length; - const float *offset_nb_y_ptr = outputs_nb_y_ptr + (i * num_nb_ + j) * grid_length; + const float* offset_nb_x_ptr = + outputs_nb_x_ptr + (i * num_nb_ + j) * grid_length; + const float* offset_nb_y_ptr = + outputs_nb_y_ptr + (i * num_nb_ + j) * grid_length; output_nb_x_select[i][j] = offset_nb_x_ptr[max_id]; output_nb_y_select[i][j] = offset_nb_y_ptr[max_id]; } } // calculate coords - std::vector lms_pred_x(num_landmarks_); // 19 - std::vector lms_pred_y(num_landmarks_); // 19 - std::map> lms_pred_nb_x; // 19,10 - std::map> lms_pred_nb_y; // 19,10 + std::vector lms_pred_x(num_landmarks_); // 19 + std::vector lms_pred_y(num_landmarks_); // 19 + std::map> lms_pred_nb_x; // 19,10 + std::map> lms_pred_nb_y; // 19,10 // initialize pred maps - for (unsigned int i = 0; i < num_landmarks_; ++i) - { + for (unsigned int i = 0; i < num_landmarks_; ++i) { std::vector nb_x_offset(num_nb_); std::vector nb_y_offset(num_nb_); lms_pred_nb_x[i] = nb_x_offset; lms_pred_nb_y[i] = nb_y_offset; } - for (unsigned int i = 0; i < num_landmarks_; ++i) - { + for (unsigned int i = 0; i < num_landmarks_; ++i) { float cx = static_cast(max_ids.at(i) % grid_w); float cy = static_cast(max_ids.at(i) / grid_w); // calculate coords & normalize - lms_pred_x[i] = ((cx + output_x_select[i]) * (float) net_stride_) / (float) input_w; - lms_pred_y[i] = ((cy + output_y_select[i]) * (float) net_stride_) / (float) input_h; - for (unsigned int j = 0; j < num_nb_; ++j) - { - lms_pred_nb_x[i][j] = ((cx + output_nb_x_select[i][j]) * (float) net_stride_) / (float) input_w; - lms_pred_nb_y[i][j] = ((cy + output_nb_y_select[i][j]) * (float) net_stride_) / (float) input_h; + lms_pred_x[i] = + ((cx + output_x_select[i]) * (float)net_stride_) / (float)input_w; + lms_pred_y[i] = + ((cy + output_y_select[i]) * (float)net_stride_) / (float)input_h; + for (unsigned int j = 0; j < num_nb_; ++j) { + lms_pred_nb_x[i][j] = + ((cx + output_nb_x_select[i][j]) * (float)net_stride_) / + (float)input_w; + lms_pred_nb_y[i][j] = + ((cy + output_nb_y_select[i][j]) * (float)net_stride_) / + (float)input_h; } } // reverse indexes - std::map> tmp_nb_x; // 19,max_len_map_[num_landmarks_] - std::map> tmp_nb_y; // 19,max_len_map_[num_landmarks_] + std::map> + tmp_nb_x; // 19,max_len_map_[num_landmarks_] + std::map> + tmp_nb_y; // 19,max_len_map_[num_landmarks_] // initialize reverse maps - for (unsigned int i = 0; i < num_landmarks_; ++i) - { + for (unsigned int i = 0; i < num_landmarks_; ++i) { std::vector tmp_x(max_len_map_[num_landmarks_]); std::vector tmp_y(max_len_map_[num_landmarks_]); tmp_nb_x[i] = tmp_x; tmp_nb_y[i] = tmp_y; } - for (unsigned int i = 0; i < num_landmarks_; ++i) - { - for (unsigned int j = 0; j < max_len_map_[num_landmarks_]; ++j) - { - unsigned int ri = reverse_index1_map_[num_landmarks_][i * max_len_map_[num_landmarks_] + j]; - unsigned int rj = reverse_index2_map_[num_landmarks_][i * max_len_map_[num_landmarks_] + j]; + for (unsigned int i = 0; i < num_landmarks_; ++i) { + for (unsigned int j = 0; j < max_len_map_[num_landmarks_]; ++j) { + unsigned int ri = + reverse_index1_map_[num_landmarks_] + [i * max_len_map_[num_landmarks_] + j]; + unsigned int rj = + reverse_index2_map_[num_landmarks_] + [i * max_len_map_[num_landmarks_] + j]; tmp_nb_x[i][j] = lms_pred_nb_x[ri][rj]; tmp_nb_y[i][j] = lms_pred_nb_y[ri][rj]; } @@ -145,17 +147,15 @@ void PIPNet::GenerateLandmarks(std::vector& infer_result, // merge predictions result->Clear(); - for (unsigned int i = 0; i < num_landmarks_; ++i) - { + for (unsigned int i = 0; i < num_landmarks_; ++i) { float total_x = lms_pred_x[i]; float total_y = lms_pred_y[i]; - for (unsigned int j = 0; j < max_len_map_[num_landmarks_]; ++j) - { + for (unsigned int j = 0; j < max_len_map_[num_landmarks_]; ++j) { total_x += tmp_nb_x[i][j]; total_y += tmp_nb_y[i][j]; } - float x = total_x / ((float) max_len_map_[num_landmarks_] + 1.f); - float y = total_y / ((float) max_len_map_[num_landmarks_] + 1.f); + float x = total_x / ((float)max_len_map_[num_landmarks_] + 1.f); + float y = total_y / ((float)max_len_map_[num_landmarks_] + 1.f); x = std::min(std::max(0.f, x), 1.0f); y = std::min(std::max(0.f, y), 1.0f); result->landmarks.emplace_back( @@ -163,20 +163,21 @@ void PIPNet::GenerateLandmarks(std::vector& infer_result, } }; -void PIPNet::SetNumLandmarks(const int& num_landmarks){ - if(std::find(supported_num_landmarks_.begin(), supported_num_landmarks_.end(), num_landmarks) \ - ==supported_num_landmarks_.end()){ - FDWARNING<<"The number of landmarks should be in {19, 29, 68, 98}."<>* im_info) { + std::map>* im_info) { // Resize int resize_w = size_[0]; int resize_h = size_[1]; @@ -462,8 +636,9 @@ bool PIPNet::Preprocess(Mat* mat, FDTensor* output, return true; } -bool PIPNet::Postprocess(std::vector& infer_result, FaceAlignmentResult* result, - const std::map>& im_info) { +bool PIPNet::Postprocess( + std::vector& infer_result, FaceAlignmentResult* result, + const std::map>& im_info) { FDASSERT(infer_result.at(0).shape[0] == 1, "Only support batch = 1 now."); if (infer_result.at(0).dtype != FDDataType::FP32) { FDERROR << "Only support post process with float32 data." << std::endl; @@ -471,8 +646,7 @@ bool PIPNet::Postprocess(std::vector& infer_result, FaceAlignmentResul } auto iter_in = im_info.find("input_shape"); - FDASSERT(iter_in != im_info.end(), - "Cannot find input_shape from im_info."); + FDASSERT(iter_in != im_info.end(), "Cannot find input_shape from im_info."); int in_h = iter_in->second[0]; int in_w = iter_in->second[1]; GenerateLandmarks(infer_result, result, in_h, in_w); diff --git a/fastdeploy/vision/facealign/contrib/pipnet_pybind.cc b/fastdeploy/vision/facealign/contrib/pipnet_pybind.cc index 7722afc4745..025259ebc74 100644 --- a/fastdeploy/vision/facealign/contrib/pipnet_pybind.cc +++ b/fastdeploy/vision/facealign/contrib/pipnet_pybind.cc @@ -26,9 +26,14 @@ void BindPIPNet(pybind11::module& m) { self.Predict(&mat, &res); return res; }) - .def_property("size", &vision::facealign::PIPNet::GetSize, &vision::facealign::PIPNet::SetSize) - .def_property("mean_vals", &vision::facealign::PIPNet::GetMeanVals, &vision::facealign::PIPNet::SetMeanVals) - .def_property("std_vals", &vision::facealign::PIPNet::GetStdVals, &vision::facealign::PIPNet::SetStdVals) - .def_property("num_landmarks", &vision::facealign::PIPNet::GetNumLandmarks, &vision::facealign::PIPNet::SetNumLandmarks); + .def_property("size", &vision::facealign::PIPNet::GetSize, + &vision::facealign::PIPNet::SetSize) + .def_property("mean_vals", &vision::facealign::PIPNet::GetMeanVals, + &vision::facealign::PIPNet::SetMeanVals) + .def_property("std_vals", &vision::facealign::PIPNet::GetStdVals, + &vision::facealign::PIPNet::SetStdVals) + .def_property("num_landmarks", + &vision::facealign::PIPNet::GetNumLandmarks, + &vision::facealign::PIPNet::SetNumLandmarks); } } // namespace fastdeploy \ No newline at end of file From 20b3fa3dd2d76f7c33ac8aa5930c81a6a6df9679 Mon Sep 17 00:00:00 2001 From: ziqi-jin Date: Wed, 16 Nov 2022 02:57:52 +0000 Subject: [PATCH 69/69] check code style --- .../facealign/contrib/face_landmark_1000.h | 4 ++-- fastdeploy/vision/facealign/contrib/pipnet.h | 17 +++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/fastdeploy/vision/facealign/contrib/face_landmark_1000.h b/fastdeploy/vision/facealign/contrib/face_landmark_1000.h index 0c9e8de4293..909edfe155a 100644 --- a/fastdeploy/vision/facealign/contrib/face_landmark_1000.h +++ b/fastdeploy/vision/facealign/contrib/face_landmark_1000.h @@ -51,12 +51,12 @@ class FASTDEPLOY_DECL FaceLandmark1000 : public FastDeployModel { * * \return Vector of int values, default {128,128} */ - std::vector GetSize() {return size_;} + std::vector GetSize() { return size_; } /** \brief Set the input size of image * * \param[in] size Vector of int values which represents {width, height} of image */ - void SetSize(const std::vector& size) {size_ = size;} + void SetSize(const std::vector& size) { size_ = size; } private: bool Initialize(); diff --git a/fastdeploy/vision/facealign/contrib/pipnet.h b/fastdeploy/vision/facealign/contrib/pipnet.h index 33a32d4bcfa..b0ea801f4df 100644 --- a/fastdeploy/vision/facealign/contrib/pipnet.h +++ b/fastdeploy/vision/facealign/contrib/pipnet.h @@ -50,22 +50,22 @@ class FASTDEPLOY_DECL PIPNet : public FastDeployModel { * * \return Integer type, default num_landmarks = 19 */ - int GetNumLandmarks() {return num_landmarks_;} + int GetNumLandmarks() {return num_landmarks_; } /** \brief Get the mean values for normalization * * \return Vector of float values, default mean_vals = {0.485f, 0.456f, 0.406f} */ - std::vector GetMeanVals() { return mean_vals_;} + std::vector GetMeanVals() { return mean_vals_; } /** \brief Get the std values for normalization * * \return Vector of float values, default std_vals = {0.229f, 0.224f, 0.225f} */ - std::vector GetStdVals() { return std_vals_;} + std::vector GetStdVals() { return std_vals_; } /** \brief Get the input size of image * * \return Vector of int values, default {256, 256} */ - std::vector GetSize() { return size_;} + std::vector GetSize() { return size_; } /** \brief Set the number of landmarks * * \param[in] num_landmarks Integer value which represents number of landmarks @@ -75,18 +75,19 @@ class FASTDEPLOY_DECL PIPNet : public FastDeployModel { * * \param[in] mean_vals Vector of float values whose length is equal to 3 */ - void SetMeanVals(const std::vector& mean_vals) - { mean_vals_ = mean_vals;} + void SetMeanVals(const std::vector& mean_vals) { + mean_vals_ = mean_vals; + } /** \brief Set the std values for normalization * * \param[in] std_vals Vector of float values whose length is equal to 3 */ - void SetStdVals(const std::vector& std_vals) {std_vals_ = std_vals;} + void SetStdVals(const std::vector& std_vals) { std_vals_ = std_vals; } /** \brief Set the input size of image * * \param[in] size Vector of int values which represents {width, height} of image */ - void SetSize(const std::vector& size) {size_ = size;} + void SetSize(const std::vector& size) { size_ = size; } private: bool Initialize();