mirror of
https://github.com/PaddlePaddle/FastDeploy.git
synced 2025-10-05 16:48:03 +08:00
[Model] Add PIPNet and FaceLandmark1000 Support (#548)
* first commit for yolov7 * pybind for yolov7 * CPP README.md * CPP README.md * modified yolov7.cc * README.md * python file modify * delete license in fastdeploy/ * repush the conflict part * README.md modified * README.md modified * file path modified * file path modified * file path modified * file path modified * file path modified * README modified * README modified * move some helpers to private * add examples for yolov7 * api.md modified * api.md modified * api.md modified * YOLOv7 * yolov7 release link * yolov7 release link * yolov7 release link * copyright * change some helpers to private * change variables to const and fix documents. * gitignore * Transfer some funtions to private member of class * Transfer some funtions to private member of class * 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 <root@bjyz-sys-gpu-kongming3.bjyz.baidu.com> * 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 <jiangjiajun@baidu.com> Co-authored-by: root <root@bjyz-sys-gpu-kongming3.bjyz.baidu.com> Co-authored-by: DefTruth <31974251+DefTruth@users.noreply.github.com> Co-authored-by: huangjianhui <852142024@qq.com> * first commit for yolor * for merge * Develop (#11) * Fix compile problem in different python version (#26) * fix some usage problem in linux * Fix compile problem Co-authored-by: root <root@bjyz-sys-gpu-kongming3.bjyz.baidu.com> * 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 <jiangjiajun@baidu.com> Co-authored-by: root <root@bjyz-sys-gpu-kongming3.bjyz.baidu.com> Co-authored-by: DefTruth <31974251+DefTruth@users.noreply.github.com> Co-authored-by: huangjianhui <852142024@qq.com> * 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 <root@bjyz-sys-gpu-kongming3.bjyz.baidu.com> * 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 <jiangjiajun@baidu.com> Co-authored-by: root <root@bjyz-sys-gpu-kongming3.bjyz.baidu.com> Co-authored-by: DefTruth <31974251+DefTruth@users.noreply.github.com> Co-authored-by: huangjianhui <852142024@qq.com> Co-authored-by: Jason <jiangjiajun@baidu.com> Co-authored-by: root <root@bjyz-sys-gpu-kongming3.bjyz.baidu.com> 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 <root@bjyz-sys-gpu-kongming3.bjyz.baidu.com> * 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 <jiangjiajun@baidu.com> Co-authored-by: root <root@bjyz-sys-gpu-kongming3.bjyz.baidu.com> 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 <root@bjyz-sys-gpu-kongming3.bjyz.baidu.com> * 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 <root@bjyz-sys-gpu-kongming3.bjyz.baidu.com> Co-authored-by: DefTruth <31974251+DefTruth@users.noreply.github.com> Co-authored-by: huangjianhui <852142024@qq.com> Co-authored-by: Jason <jiangjiajun@baidu.com> Co-authored-by: root <root@bjyz-sys-gpu-kongming3.bjyz.baidu.com> Co-authored-by: DefTruth <31974251+DefTruth@users.noreply.github.com> Co-authored-by: huangjianhui <852142024@qq.com> Co-authored-by: Jason <928090362@qq.com> * add is_dynamic for YOLO series (#22) * modify ppmatting backend and docs * modify ppmatting docs * fix the PPMatting size problem * fix LimitShort's log * retrigger ci * modify PPMatting docs * modify the way for dealing with LimitShort * add python comments for external models * modify resnet c++ comments * modify C++ comments for external models * modify python comments and add result class comments * fix comments compile error * modify result.h comments * c++ version for FaceLandmark1000 * add pipnet land1000 sigle test and python code * fix facelandmark1000 sigle test * fix python examples for PIPNet and FaceLandmark1000 * fix examples links for PIPNet and FaceLandmark1000 * modify test_vision_colorspace_convert.cc * modify facealign readme * retrigger ci * modify README * test ci * fix download_prebuilt_libraries.md * fix download_prebuilt_libraries.md * modify for comments * modify supported_num_landmarks * retrigger ci * check code style * check code style Co-authored-by: Jason <jiangjiajun@baidu.com> Co-authored-by: root <root@bjyz-sys-gpu-kongming3.bjyz.baidu.com> Co-authored-by: DefTruth <31974251+DefTruth@users.noreply.github.com> Co-authored-by: huangjianhui <852142024@qq.com> Co-authored-by: Jason <928090362@qq.com>
This commit is contained in:
@@ -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
|
||||
|
||||
|
@@ -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](./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) |
|
||||
|
25
examples/vision/facealign/face_landmark_1000/README.md
Normal file
25
examples/vision/facealign/face_landmark_1000/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# FaceLandmark 模型部署
|
||||
|
||||
## 模型版本说明
|
||||
|
||||
- [FaceLandmark1000](https://github.com/Single430/FaceLandmark1000/tree/1a951b6)
|
||||
|
||||
## 支持模型列表
|
||||
|
||||
目前FastDeploy支持如下模型的部署
|
||||
|
||||
- [FaceLandmark1000 模型](https://github.com/Single430/FaceLandmark1000)
|
||||
|
||||
## 下载预训练模型
|
||||
|
||||
为了方便开发者的测试,下面提供了FaceLandmark导出的各系列模型,开发者可直接下载使用。
|
||||
|
||||
| 模型 | 参数大小 | 精度 | 备注 |
|
||||
|:---------------------------------------------------------------- |:----- |:----- | :------ |
|
||||
| [FaceLandmark1000](https://bj.bcebos.com/paddlehub/fastdeploy/FaceLandmark1000.onnx) | 2.1M | - |
|
||||
|
||||
|
||||
## 详细部署文档
|
||||
|
||||
- [Python部署](python)
|
||||
- [C++部署](cpp)
|
@@ -0,0 +1,18 @@
|
||||
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库依赖
|
||||
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()
|
84
examples/vision/facealign/face_landmark_1000/cpp/README.md
Normal file
84
examples/vision/facealign/face_landmark_1000/cpp/README.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# FaceLandmark1000 C++部署示例
|
||||
|
||||
本目录下提供`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.7.0以上(x.x.x >= 0.7.0)支持FaceLandmark1000模型
|
||||
|
||||
```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
|
||||
|
||||
#下载官方转换好的 FaceLandmark1000 模型文件和测试图片
|
||||
wget https://bj.bcebos.com/paddlehub/fastdeploy/FaceLandmark1000.onnx
|
||||
wget https://bj.bcebos.com/paddlehub/fastdeploy/facealign_input.png
|
||||
|
||||
# CPU推理
|
||||
./infer_demo --model FaceLandmark1000.onnx --image facealign_input.png --device cpu
|
||||
# GPU推理
|
||||
./infer_demo --model FaceLandmark1000.onnx --image facealign_input.png --device gpu
|
||||
# GPU上TensorRT推理
|
||||
./infer_demo --model FaceLandmark1000.onnx --image facealign_input.png --device gpu --backend trt
|
||||
```
|
||||
|
||||
运行完成可视化结果如下图所示
|
||||
|
||||
<div width="500">
|
||||
<img width="470" height="384" float="left" src="https://user-images.githubusercontent.com/67993288/200761309-90c096e2-c2f3-4140-8012-32ed84e5f389.jpg">
|
||||
</div>
|
||||
|
||||
以上命令只适用于Linux或MacOS, Windows下SDK的使用方式请参考:
|
||||
- [如何在Windows中使用FastDeploy C++ SDK](../../../../../docs/cn/faq/use_sdk_on_windows.md)
|
||||
|
||||
## FaceLandmark1000 C++接口
|
||||
|
||||
### FaceLandmark1000 类
|
||||
|
||||
```c++
|
||||
fastdeploy::vision::facealign::FaceLandmark1000(
|
||||
const string& model_file,
|
||||
const string& params_file = "",
|
||||
const RuntimeOption& runtime_option = RuntimeOption(),
|
||||
const ModelFormat& model_format = ModelFormat::ONNX)
|
||||
```
|
||||
|
||||
FaceLandmark1000模型加载和初始化,其中model_file为导出的ONNX模型格式。
|
||||
|
||||
**参数**
|
||||
|
||||
> * **model_file**(str): 模型文件路径
|
||||
> * **params_file**(str): 参数文件路径,当模型格式为ONNX时,此参数传入空字符串即可
|
||||
> * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置
|
||||
> * **model_format**(ModelFormat): 模型格式,默认为ONNX格式
|
||||
|
||||
#### Predict函数
|
||||
|
||||
> ```c++
|
||||
> FaceLandmark1000::Predict(cv::Mat* im, FaceAlignmentResult* result)
|
||||
> ```
|
||||
>
|
||||
> 模型预测接口,输入图像直接输出landmarks结果。
|
||||
>
|
||||
> **参数**
|
||||
>
|
||||
> > * **im**: 输入图像,注意需为HWC,BGR格式
|
||||
> > * **result**: landmarks结果, FaceAlignmentResult说明参考[视觉模型预测结果](../../../../../docs/api/vision_results/)
|
||||
|
||||
### 类成员变量
|
||||
|
||||
用户可按照自己的实际需求,修改下列预处理参数,从而影响最终的推理和部署效果
|
||||
|
||||
> > * **size**(vector<int>): 通过此参数修改预处理过程中resize的大小,包含两个整型元素,表示[width, height], 默认值为[128, 128]
|
||||
|
||||
- [模型介绍](../../)
|
||||
- [Python部署](../python)
|
||||
- [视觉模型预测结果](../../../../../docs/api/vision_results/)
|
||||
- [如何切换模型推理后端引擎](../../../../../docs/cn/faq/how_to_change_backend.md)
|
110
examples/vision/facealign/face_landmark_1000/cpp/infer.cc
Normal file
110
examples/vision/facealign/face_landmark_1000/cpp/infer.cc
Normal file
@@ -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;
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
# 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`快速完成FaceLandmark1000在CPU/GPU,以及GPU上通过TensorRT加速部署的示例,保证 FastDeploy 版本 >= 0.7.0 支持FaceLandmark1000模型。执行如下脚本即可完成
|
||||
|
||||
```bash
|
||||
#下载部署示例代码
|
||||
git clone https://github.com/PaddlePaddle/FastDeploy.git
|
||||
cd FastDeploy/examples/vision/facealign/facelandmark1000/python
|
||||
|
||||
# 下载FaceLandmark1000模型文件和测试图片
|
||||
## 原版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 FaceLandmark1000.onnx --image facealign_input.png --device cpu
|
||||
# GPU推理
|
||||
python infer.py --model FaceLandmark1000.onnx --image facealign_input.png --device gpu
|
||||
# TRT推理
|
||||
python infer.py --model FaceLandmark1000.onnx --image facealign_input.png --device gpu --backend trt
|
||||
```
|
||||
|
||||
运行完成可视化结果如下图所示
|
||||
|
||||
<div width="500">
|
||||
<img width="470" height="384" float="left" src="https://user-images.githubusercontent.com/67993288/200761309-90c096e2-c2f3-4140-8012-32ed84e5f389.jpg">
|
||||
</div>
|
||||
|
||||
## FaceLandmark1000 Python接口
|
||||
|
||||
```python
|
||||
fd.vision.facealign.FaceLandmark1000(model_file, params_file=None, runtime_option=None, model_format=ModelFormat.ONNX)
|
||||
```
|
||||
|
||||
FaceLandmark1000模型加载和初始化,其中model_file为导出的ONNX模型格式
|
||||
|
||||
**参数**
|
||||
|
||||
> * **model_file**(str): 模型文件路径
|
||||
> * **params_file**(str): 参数文件路径,当模型格式为ONNX格式时,此参数无需设定
|
||||
> * **runtime_option**(RuntimeOption): 后端推理配置,默认为None,即采用默认配置
|
||||
> * **model_format**(ModelFormat): 模型格式,默认为ONNX
|
||||
|
||||
### predict函数
|
||||
|
||||
> ```python
|
||||
> FaceLandmark1000.predict(input_image)
|
||||
> ```
|
||||
>
|
||||
> 模型预测结口,输入图像直接输出landmarks坐标结果。
|
||||
>
|
||||
> **参数**
|
||||
>
|
||||
> > * **input_image**(np.ndarray): 输入数据,注意需为HWC,BGR格式
|
||||
|
||||
> **返回**
|
||||
>
|
||||
> > 返回`fastdeploy.vision.FaceAlignmentResult`结构体,结构体说明参考文档[视觉模型预测结果](../../../../../docs/api/vision_results/)
|
||||
|
||||
|
||||
## 其它文档
|
||||
|
||||
- [FaceLandmark1000 模型介绍](..)
|
||||
- [FaceLandmark1000 C++部署](../cpp)
|
||||
- [模型预测结果说明](../../../../../docs/api/vision_results/)
|
||||
- [如何切换模型推理后端引擎](../../../../../docs/cn/faq/how_to_change_backend.md)
|
90
examples/vision/facealign/face_landmark_1000/python/infer.py
Normal file
90
examples/vision/facealign/face_landmark_1000/python/infer.py
Normal file
@@ -0,0 +1,90 @@
|
||||
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 FaceLandmark1000 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=ast.literal_eval,
|
||||
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.FaceLandmark1000(
|
||||
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")
|
33
examples/vision/facealign/pipnet/README.md
Normal file
33
examples/vision/facealign/pipnet/README.md
Normal file
@@ -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)
|
18
examples/vision/facealign/pipnet/cpp/CMakeLists.txt
Normal file
18
examples/vision/facealign/pipnet/cpp/CMakeLists.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
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库依赖
|
||||
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()
|
84
examples/vision/facealign/pipnet/cpp/README.md
Normal file
84
examples/vision/facealign/pipnet/cpp/README.md
Normal file
@@ -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.7.0以上(x.x.x >= 0.7.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
|
||||
```
|
||||
|
||||
运行完成可视化结果如下图所示
|
||||
|
||||
<div width="500">
|
||||
<img width="470" height="384" float="left" src="https://user-images.githubusercontent.com/67993288/200761400-08491112-56c3-470f-87ac-87be805d5658.jpg">
|
||||
</div>
|
||||
|
||||
以上命令只适用于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)
|
111
examples/vision/facealign/pipnet/cpp/infer.cc
Normal file
111
examples/vision/facealign/pipnet/cpp/infer.cc
Normal file
@@ -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;
|
||||
}
|
71
examples/vision/facealign/pipnet/python/README.md
Normal file
71
examples/vision/facealign/pipnet/python/README.md
Normal file
@@ -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.7.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
|
||||
```
|
||||
|
||||
运行完成可视化结果如下图所示
|
||||
|
||||
<div width="500">
|
||||
<img width="470" height="384" float="left" src="https://user-images.githubusercontent.com/67993288/200761400-08491112-56c3-470f-87ac-87be805d5658.jpg">
|
||||
</div>
|
||||
|
||||
## 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)
|
93
examples/vision/facealign/pipnet/python/infer.py
Normal file
93
examples/vision/facealign/pipnet/python/infer.py
Normal file
@@ -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=ast.literal_eval,
|
||||
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")
|
@@ -34,6 +34,8 @@
|
||||
#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/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"
|
||||
|
@@ -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,15 +62,72 @@ bool RGB2BGR::ImplByFlyCV(Mat* mat) {
|
||||
}
|
||||
#endif
|
||||
|
||||
bool BGR2RGB::Run(Mat* mat, ProcLib lib) {
|
||||
bool BGR2GRAY::ImplByOpenCV(FDMat* 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(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;
|
||||
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(FDMat* 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(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;
|
||||
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(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(FDMat* mat, ProcLib lib) {
|
||||
auto b = BGR2GRAY();
|
||||
return b(mat, lib);
|
||||
}
|
||||
|
||||
bool RGB2GRAY::Run(FDMat* mat, ProcLib lib) {
|
||||
auto r = RGB2GRAY();
|
||||
return r(mat, lib);
|
||||
}
|
||||
|
||||
|
||||
} // namespace vision
|
||||
} // namespace fastdeploy
|
||||
|
@@ -21,24 +21,48 @@ 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(FDMat* mat);
|
||||
#ifdef ENABLE_FLYCV
|
||||
bool ImplByFalconCV(FDMat* mat);
|
||||
#endif
|
||||
virtual std::string Name() { return "BGR2GRAY"; }
|
||||
|
||||
static bool Run(FDMat* mat, ProcLib lib = ProcLib::OPENCV);
|
||||
};
|
||||
|
||||
class FASTDEPLOY_DECL RGB2GRAY : public Processor {
|
||||
public:
|
||||
bool ImplByOpenCV(FDMat* mat);
|
||||
#ifdef ENABLE_FLYCV
|
||||
bool ImplByFalconCV(FDMat* mat);
|
||||
#endif
|
||||
std::string Name() { return "RGB2GRAY"; }
|
||||
|
||||
static bool Run(FDMat* mat, ProcLib lib = ProcLib::OPENCV);
|
||||
};
|
||||
|
||||
|
||||
} // namespace vision
|
||||
} // namespace fastdeploy
|
||||
|
@@ -259,7 +259,10 @@ std::string FaceAlignmentResult::Str() {
|
||||
std::string out;
|
||||
|
||||
out = "FaceAlignmentResult: [x, y]\n";
|
||||
for (size_t i = 0; i < landmarks.size(); ++i) {
|
||||
out = out + "There are " +std::to_string(landmarks.size()) + " landmarks, the top 10 are listed as below:\n";
|
||||
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";
|
||||
}
|
||||
|
134
fastdeploy/vision/facealign/contrib/face_landmark_1000.cc
Normal file
134
fastdeploy/vision/facealign/contrib/face_landmark_1000.cc
Normal file
@@ -0,0 +1,134 @@
|
||||
// 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<std::string, std::array<int, 2>>* 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<std::string, std::array<int, 2>>& 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<float*>(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<float, 2>{x * in_w, y * in_h});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FaceLandmark1000::Predict(cv::Mat* im, FaceAlignmentResult* result) {
|
||||
Mat mat(*im);
|
||||
std::vector<FDTensor> input_tensors(1);
|
||||
|
||||
std::map<std::string, std::array<int, 2>> 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<FDTensor> 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
|
75
fastdeploy/vision/facealign/contrib/face_landmark_1000.h
Normal file
75
fastdeploy/vision/facealign/contrib/face_landmark_1000.h
Normal file
@@ -0,0 +1,75 @@
|
||||
// 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);
|
||||
|
||||
/** \brief Get the input size of image
|
||||
*
|
||||
* \return Vector of int values, default {128,128}
|
||||
*/
|
||||
std::vector<int> 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<int>& size) { size_ = size; }
|
||||
|
||||
private:
|
||||
bool Initialize();
|
||||
|
||||
bool Preprocess(Mat* mat, FDTensor* outputs,
|
||||
std::map<std::string, std::array<int, 2>>* im_info);
|
||||
|
||||
bool Postprocess(FDTensor& infer_result, FaceAlignmentResult* result,
|
||||
const std::map<std::string, std::array<int, 2>>& im_info);
|
||||
// tuple of (width, height), default (128, 128)
|
||||
std::vector<int> size_;
|
||||
};
|
||||
|
||||
} // namespace facealign
|
||||
} // namespace vision
|
||||
} // namespace fastdeploy
|
@@ -0,0 +1,34 @@
|
||||
// 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_<vision::facealign::FaceLandmark1000, FastDeployModel>(
|
||||
m, "FaceLandmark1000")
|
||||
.def(pybind11::init<std::string, std::string, RuntimeOption,
|
||||
ModelFormat>())
|
||||
.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
|
687
fastdeploy/vision/facealign/contrib/pipnet.cc
Normal file
687
fastdeploy/vision/facealign/contrib/pipnet.cc
Normal file
@@ -0,0 +1,687 @@
|
||||
// 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/vision/utils/utils.h"
|
||||
|
||||
namespace fastdeploy {
|
||||
|
||||
namespace vision {
|
||||
|
||||
namespace facealign {
|
||||
|
||||
void PIPNet::GenerateLandmarks(std::vector<FDTensor>& 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<float*>(outputs_cls.Data());
|
||||
const float* outputs_x_ptr = static_cast<float*>(outputs_x.Data());
|
||||
const float* outputs_y_ptr = static_cast<float*>(outputs_y.Data());
|
||||
const float* outputs_nb_x_ptr = static_cast<float*>(outputs_nb_x.Data());
|
||||
const float* outputs_nb_y_ptr = static_cast<float*>(outputs_nb_y.Data());
|
||||
|
||||
// find max_ids
|
||||
std::vector<unsigned int> 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<float> output_x_select(num_landmarks_);
|
||||
std::vector<float> 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::map<unsigned int, std::vector<float>> output_nb_x_select;
|
||||
std::map<unsigned int, std::vector<float>> output_nb_y_select;
|
||||
// initialize offsets map
|
||||
for (unsigned int i = 0; i < num_landmarks_; ++i) {
|
||||
std::vector<float> nb_x_offset(num_nb_);
|
||||
std::vector<float> 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<float> lms_pred_x(num_landmarks_); // 19
|
||||
std::vector<float> lms_pred_y(num_landmarks_); // 19
|
||||
std::map<unsigned int, std::vector<float>> lms_pred_nb_x; // 19,10
|
||||
std::map<unsigned int, std::vector<float>> lms_pred_nb_y; // 19,10
|
||||
|
||||
// initialize pred maps
|
||||
for (unsigned int i = 0; i < num_landmarks_; ++i) {
|
||||
std::vector<float> nb_x_offset(num_nb_);
|
||||
std::vector<float> 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<float>(max_ids.at(i) % grid_w);
|
||||
float cy = static_cast<float>(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::map<unsigned int, std::vector<float>>
|
||||
tmp_nb_x; // 19,max_len_map_[num_landmarks_]
|
||||
std::map<unsigned int, std::vector<float>>
|
||||
tmp_nb_y; // 19,max_len_map_[num_landmarks_]
|
||||
// initialize reverse maps
|
||||
for (unsigned int i = 0; i < num_landmarks_; ++i) {
|
||||
std::vector<float> tmp_x(max_len_map_[num_landmarks_]);
|
||||
std::vector<float> 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<float, 2>{x * img_width, y * img_height});
|
||||
}
|
||||
};
|
||||
|
||||
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}."
|
||||
<< std::endl;
|
||||
}
|
||||
num_landmarks_ = num_landmarks;
|
||||
}
|
||||
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};
|
||||
num_nb_ = 10;
|
||||
net_stride_ = 32;
|
||||
num_landmarks_ = 19;
|
||||
supported_num_landmarks_ = {19, 29, 68, 98};
|
||||
// parameters for num_landmarks_ == 19
|
||||
reverse_index1_map_[19] = {
|
||||
1, 2, 6, 7, 8, 1, 2, 6, 7, 8, 1, 2, 6, 7, 8, 1, 2, 6,
|
||||
0, 2, 3, 4, 6, 7, 8, 0, 2, 3, 4, 6, 7, 8, 0, 2, 3, 4,
|
||||
0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 1, 3, 4, 5, 6,
|
||||
0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 14, 0, 1, 2, 4, 5, 6,
|
||||
1, 2, 3, 5, 9, 10, 11, 1, 2, 3, 5, 9, 10, 11, 1, 2, 3, 5,
|
||||
3, 4, 9, 10, 11, 3, 4, 9, 10, 11, 3, 4, 9, 10, 11, 3, 4, 9,
|
||||
0, 1, 2, 3, 7, 8, 12, 13, 15, 0, 1, 2, 3, 7, 8, 12, 13, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 15, 16, 18, 0, 1,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 14, 16, 17, 18, 0, 1,
|
||||
3, 4, 5, 9, 10, 14, 17, 3, 4, 5, 9, 10, 14, 17, 3, 4, 5, 9,
|
||||
0, 1, 6, 7, 8, 13, 14, 15, 16, 17, 18, 0, 1, 6, 7, 8, 13, 14,
|
||||
0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 0, 2, 5,
|
||||
4, 5, 9, 10, 11, 12, 13, 15, 16, 17, 18, 4, 5, 9, 10, 11, 12, 13,
|
||||
12, 13, 14, 16, 17, 18, 12, 13, 14, 16, 17, 18, 12, 13, 14, 16, 17, 18,
|
||||
12, 13, 14, 15, 17, 18, 12, 13, 14, 15, 17, 18, 12, 13, 14, 15, 17, 18,
|
||||
12, 13, 14, 15, 16, 18, 12, 13, 14, 15, 16, 18, 12, 13, 14, 15, 16, 18,
|
||||
15, 16, 17, 15, 16, 17, 15, 16, 17, 15, 16, 17, 15, 16, 17, 15, 16, 17};
|
||||
reverse_index2_map_[19] = {
|
||||
0, 6, 1, 4, 6, 0, 6, 1, 4, 6, 0, 6, 1, 4, 6, 0, 6, 1, 0, 1, 8, 7, 2, 2, 3,
|
||||
0, 1, 8, 7, 2, 2, 3, 0, 1, 8, 7, 3, 1, 3, 5, 5, 4, 3, 1, 5, 6, 6, 9, 3, 1,
|
||||
3, 5, 5, 4, 5, 5, 3, 1, 3, 7, 5, 5, 1, 3, 4, 9, 5, 5, 3, 1, 3, 7, 7, 8, 1,
|
||||
0, 3, 2, 2, 7, 8, 1, 0, 3, 2, 2, 7, 8, 1, 0, 6, 0, 6, 4, 1, 6, 0, 6, 4, 1,
|
||||
6, 0, 6, 4, 1, 6, 0, 6, 1, 3, 4, 9, 1, 2, 6, 9, 8, 1, 3, 4, 9, 1, 2, 6, 9,
|
||||
8, 2, 2, 2, 7, 8, 9, 0, 0, 9, 9, 9, 5, 7, 7, 8, 8, 2, 2, 4, 4, 0, 5, 6, 6,
|
||||
3, 0, 4, 5, 7, 4, 3, 8, 6, 6, 9, 6, 7, 6, 5, 0, 4, 4, 8, 6, 4, 0, 3, 8, 4,
|
||||
4, 9, 7, 6, 7, 9, 8, 7, 2, 2, 2, 9, 9, 9, 0, 0, 8, 5, 9, 7, 9, 9, 8, 4, 3,
|
||||
1, 2, 1, 6, 8, 4, 3, 1, 2, 1, 6, 8, 4, 3, 1, 2, 6, 9, 5, 7, 8, 0, 2, 1, 3,
|
||||
4, 4, 6, 9, 5, 7, 8, 0, 2, 8, 9, 8, 6, 8, 7, 7, 8, 8, 0, 0, 2, 2, 2, 5, 8,
|
||||
9, 8, 9, 7, 8, 7, 5, 2, 1, 4, 4, 1, 3, 9, 7, 8, 7, 5, 2, 1, 1, 5, 7, 0, 3,
|
||||
1, 1, 5, 7, 0, 3, 1, 1, 5, 7, 0, 3, 1, 3, 2, 3, 0, 0, 0, 3, 2, 3, 0, 0, 0,
|
||||
3, 2, 3, 0, 0, 0, 7, 6, 1, 3, 1, 2, 7, 6, 1, 3, 1, 2, 7, 6, 1, 3, 1, 2, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5};
|
||||
max_len_map_[19] = 18;
|
||||
// parameters for num_landmarks_ == 29
|
||||
reverse_index1_map_[29] = {
|
||||
2, 4, 5, 8, 12, 13, 16, 2, 4, 5, 8, 12, 13, 16, 2, 4, 5, 8,
|
||||
12, 3, 6, 7, 9, 14, 15, 17, 3, 6, 7, 9, 14, 15, 17, 3, 6, 7,
|
||||
9, 14, 0, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 16, 0, 3, 4,
|
||||
5, 6, 7, 0, 1, 2, 4, 5, 6, 7, 9, 10, 11, 12, 14, 15, 17, 0,
|
||||
1, 2, 4, 5, 0, 2, 5, 8, 10, 12, 13, 16, 0, 2, 5, 8, 10, 12,
|
||||
13, 16, 0, 2, 5, 0, 2, 4, 8, 10, 12, 13, 16, 0, 2, 4, 8, 10,
|
||||
12, 13, 16, 0, 2, 4, 1, 3, 7, 9, 11, 14, 15, 17, 1, 3, 7, 9,
|
||||
11, 14, 15, 17, 1, 3, 7, 1, 3, 6, 9, 11, 14, 15, 17, 1, 3, 6,
|
||||
9, 11, 14, 15, 17, 1, 3, 6, 0, 2, 4, 5, 10, 12, 13, 16, 0, 2,
|
||||
4, 5, 10, 12, 13, 16, 0, 2, 4, 1, 3, 6, 7, 11, 14, 15, 17, 1,
|
||||
3, 6, 7, 11, 14, 15, 17, 1, 3, 6, 0, 2, 3, 4, 5, 8, 12, 13,
|
||||
16, 18, 20, 0, 2, 3, 4, 5, 8, 12, 13, 1, 2, 3, 6, 7, 9, 14,
|
||||
15, 17, 19, 20, 21, 1, 2, 3, 6, 7, 9, 14, 0, 2, 4, 5, 8, 10,
|
||||
13, 16, 0, 2, 4, 5, 8, 10, 13, 16, 0, 2, 4, 0, 2, 4, 5, 8,
|
||||
10, 12, 16, 18, 22, 0, 2, 4, 5, 8, 10, 12, 16, 18, 1, 3, 6, 7,
|
||||
9, 11, 15, 17, 1, 3, 6, 7, 9, 11, 15, 17, 1, 3, 6, 1, 3, 6,
|
||||
7, 9, 11, 14, 17, 19, 23, 1, 3, 6, 7, 9, 11, 14, 17, 19, 0, 2,
|
||||
4, 5, 8, 10, 12, 13, 18, 0, 2, 4, 5, 8, 10, 12, 13, 18, 0, 1,
|
||||
3, 6, 7, 9, 11, 14, 15, 19, 1, 3, 6, 7, 9, 11, 14, 15, 19, 1,
|
||||
0, 4, 5, 8, 10, 12, 13, 16, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
|
||||
0, 1, 6, 7, 9, 11, 14, 15, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27,
|
||||
28, 1, 1, 8, 9, 10, 11, 13, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25,
|
||||
26, 27, 28, 18, 19, 20, 22, 23, 24, 25, 26, 27, 28, 18, 19, 20, 22, 23,
|
||||
24, 25, 26, 27, 18, 20, 21, 24, 25, 26, 27, 28, 18, 20, 21, 24, 25, 26,
|
||||
27, 28, 18, 20, 21, 19, 21, 24, 25, 26, 27, 28, 19, 21, 24, 25, 26, 27,
|
||||
28, 19, 21, 24, 25, 26, 18, 19, 20, 21, 22, 23, 25, 26, 27, 28, 18, 19,
|
||||
20, 21, 22, 23, 25, 26, 27, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, 18,
|
||||
19, 20, 21, 22, 23, 24, 26, 27, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28,
|
||||
18, 19, 20, 21, 22, 23, 24, 25, 27, 20, 21, 22, 23, 24, 25, 26, 28, 20,
|
||||
21, 22, 23, 24, 25, 26, 28, 20, 21, 22, 22, 23, 24, 25, 26, 27, 22, 23,
|
||||
24, 25, 26, 27, 22, 23, 24, 25, 26, 27, 22};
|
||||
reverse_index2_map_[29] = {
|
||||
9, 3, 5, 3, 7, 7, 7, 9, 3, 5, 3, 7, 7, 7, 9, 3, 5, 3, 7, 9, 3, 5, 3, 7,
|
||||
7, 7, 9, 3, 5, 3, 7, 7, 7, 9, 3, 5, 3, 7, 7, 6, 6, 6, 8, 9, 7, 0, 9, 6,
|
||||
5, 9, 6, 7, 6, 6, 6, 8, 9, 9, 7, 6, 8, 9, 6, 6, 7, 8, 0, 9, 6, 6, 6, 9,
|
||||
7, 6, 8, 9, 2, 5, 0, 5, 5, 3, 6, 5, 2, 5, 0, 5, 5, 3, 6, 5, 2, 5, 0, 1,
|
||||
3, 0, 4, 4, 2, 4, 2, 1, 3, 0, 4, 4, 2, 4, 2, 1, 3, 0, 2, 4, 0, 5, 5, 3,
|
||||
5, 5, 2, 4, 0, 5, 5, 3, 5, 5, 2, 4, 0, 1, 3, 0, 4, 4, 2, 4, 2, 1, 3, 0,
|
||||
4, 4, 2, 4, 2, 1, 3, 0, 0, 7, 4, 3, 6, 5, 3, 4, 0, 7, 4, 3, 6, 5, 3, 4,
|
||||
0, 7, 4, 0, 7, 4, 3, 6, 5, 2, 4, 0, 7, 4, 3, 6, 5, 2, 4, 0, 7, 4, 6, 0,
|
||||
8, 7, 7, 6, 4, 2, 3, 5, 6, 6, 0, 8, 7, 7, 6, 4, 2, 6, 8, 0, 7, 7, 6, 4,
|
||||
3, 3, 5, 7, 9, 6, 8, 0, 7, 7, 6, 4, 3, 1, 1, 1, 2, 3, 1, 0, 3, 1, 1, 1,
|
||||
2, 3, 1, 0, 3, 1, 1, 5, 4, 5, 4, 0, 2, 1, 1, 6, 9, 5, 4, 5, 4, 0, 2, 1,
|
||||
1, 6, 3, 1, 1, 1, 2, 3, 1, 0, 3, 1, 1, 1, 2, 3, 1, 0, 3, 1, 1, 5, 5, 5,
|
||||
4, 0, 2, 1, 1, 7, 9, 5, 5, 5, 4, 0, 2, 1, 1, 7, 4, 2, 2, 2, 1, 1, 0, 0,
|
||||
9, 4, 2, 2, 2, 1, 1, 0, 0, 9, 4, 4, 2, 2, 2, 1, 1, 0, 0, 9, 4, 2, 2, 2,
|
||||
1, 1, 0, 0, 9, 4, 8, 9, 8, 8, 7, 8, 8, 8, 8, 1, 3, 0, 8, 5, 8, 9, 9, 9,
|
||||
8, 8, 9, 8, 8, 7, 8, 8, 8, 8, 2, 4, 8, 0, 6, 7, 8, 8, 7, 8, 9, 9, 9, 9,
|
||||
8, 9, 9, 9, 9, 0, 0, 0, 6, 6, 4, 4, 6, 7, 8, 1, 1, 0, 5, 5, 2, 3, 3, 4,
|
||||
6, 1, 1, 0, 5, 5, 2, 3, 3, 4, 2, 8, 7, 7, 5, 4, 6, 5, 2, 8, 7, 7, 5, 4,
|
||||
6, 5, 2, 8, 7, 2, 8, 8, 6, 5, 5, 4, 2, 8, 8, 6, 5, 5, 4, 2, 8, 8, 6, 5,
|
||||
3, 3, 3, 1, 2, 3, 0, 2, 2, 3, 3, 3, 3, 1, 2, 3, 0, 2, 2, 4, 4, 4, 2, 1,
|
||||
1, 0, 0, 1, 2, 4, 4, 4, 2, 1, 1, 0, 0, 1, 7, 6, 5, 5, 3, 2, 1, 1, 0, 1,
|
||||
7, 6, 5, 5, 3, 2, 1, 1, 0, 9, 6, 4, 4, 3, 2, 1, 0, 9, 6, 4, 4, 3, 2, 1,
|
||||
0, 9, 6, 4, 7, 7, 9, 9, 7, 3, 7, 7, 9, 9, 7, 3, 7, 7, 9, 9, 7, 3, 7};
|
||||
max_len_map_[29] = 19;
|
||||
// parameters for num_landmarks_ == 68
|
||||
reverse_index1_map_[68] = {
|
||||
1, 2, 17, 18, 36, 1, 2, 17, 18, 36, 1, 2, 17, 18, 36, 1, 2, 17,
|
||||
18, 36, 1, 2, 0, 2, 3, 17, 0, 2, 3, 17, 0, 2, 3, 17, 0, 2,
|
||||
3, 17, 0, 2, 3, 17, 0, 2, 0, 1, 3, 4, 0, 1, 3, 4, 0, 1,
|
||||
3, 4, 0, 1, 3, 4, 0, 1, 3, 4, 0, 1, 1, 2, 4, 5, 1, 2,
|
||||
4, 5, 1, 2, 4, 5, 1, 2, 4, 5, 1, 2, 4, 5, 1, 2, 2, 3,
|
||||
5, 6, 2, 3, 5, 6, 2, 3, 5, 6, 2, 3, 5, 6, 2, 3, 5, 6,
|
||||
2, 3, 3, 4, 6, 7, 3, 4, 6, 7, 3, 4, 6, 7, 3, 4, 6, 7,
|
||||
3, 4, 6, 7, 3, 4, 3, 4, 5, 7, 8, 3, 4, 5, 7, 8, 3, 4,
|
||||
5, 7, 8, 3, 4, 5, 7, 8, 3, 4, 5, 6, 8, 9, 5, 6, 8, 9,
|
||||
5, 6, 8, 9, 5, 6, 8, 9, 5, 6, 8, 9, 5, 6, 6, 7, 9, 10,
|
||||
6, 7, 9, 10, 6, 7, 9, 10, 6, 7, 9, 10, 6, 7, 9, 10, 6, 7,
|
||||
7, 8, 10, 11, 7, 8, 10, 11, 7, 8, 10, 11, 7, 8, 10, 11, 7, 8,
|
||||
10, 11, 7, 8, 8, 9, 11, 12, 13, 8, 9, 11, 12, 13, 8, 9, 11, 12,
|
||||
13, 8, 9, 11, 12, 13, 8, 9, 9, 10, 12, 13, 9, 10, 12, 13, 9, 10,
|
||||
12, 13, 9, 10, 12, 13, 9, 10, 12, 13, 9, 10, 10, 11, 13, 14, 10, 11,
|
||||
13, 14, 10, 11, 13, 14, 10, 11, 13, 14, 10, 11, 13, 14, 10, 11, 11, 12,
|
||||
14, 15, 11, 12, 14, 15, 11, 12, 14, 15, 11, 12, 14, 15, 11, 12, 14, 15,
|
||||
11, 12, 12, 13, 15, 16, 12, 13, 15, 16, 12, 13, 15, 16, 12, 13, 15, 16,
|
||||
12, 13, 15, 16, 12, 13, 13, 14, 16, 26, 13, 14, 16, 26, 13, 14, 16, 26,
|
||||
13, 14, 16, 26, 13, 14, 16, 26, 13, 14, 14, 15, 25, 26, 45, 14, 15, 25,
|
||||
26, 45, 14, 15, 25, 26, 45, 14, 15, 25, 26, 45, 14, 15, 0, 1, 2, 18,
|
||||
19, 36, 37, 41, 0, 1, 2, 18, 19, 36, 37, 41, 0, 1, 2, 18, 19, 36,
|
||||
0, 1, 17, 19, 20, 36, 37, 38, 41, 0, 1, 17, 19, 20, 36, 37, 38, 41,
|
||||
0, 1, 17, 19, 0, 17, 18, 20, 21, 36, 37, 38, 40, 41, 0, 17, 18, 20,
|
||||
21, 36, 37, 38, 40, 41, 0, 17, 17, 18, 19, 21, 36, 37, 38, 39, 40, 41,
|
||||
17, 18, 19, 21, 36, 37, 38, 39, 40, 41, 17, 18, 18, 19, 20, 22, 27, 28,
|
||||
37, 38, 39, 40, 41, 18, 19, 20, 22, 27, 28, 37, 38, 39, 40, 41, 21, 23,
|
||||
24, 25, 27, 28, 42, 43, 44, 46, 47, 21, 23, 24, 25, 27, 28, 42, 43, 44,
|
||||
46, 47, 22, 24, 25, 26, 42, 43, 44, 45, 46, 47, 22, 24, 25, 26, 42, 43,
|
||||
44, 45, 46, 47, 22, 24, 16, 22, 23, 25, 26, 43, 44, 45, 46, 47, 16, 22,
|
||||
23, 25, 26, 43, 44, 45, 46, 47, 16, 22, 15, 16, 23, 24, 26, 43, 44, 45,
|
||||
46, 15, 16, 23, 24, 26, 43, 44, 45, 46, 15, 16, 23, 24, 14, 15, 16, 24,
|
||||
25, 44, 45, 46, 14, 15, 16, 24, 25, 44, 45, 46, 14, 15, 16, 24, 25, 44,
|
||||
20, 21, 22, 23, 28, 29, 38, 39, 40, 42, 43, 47, 20, 21, 22, 23, 28, 29,
|
||||
38, 39, 40, 42, 21, 22, 27, 29, 30, 39, 40, 42, 47, 21, 22, 27, 29, 30,
|
||||
39, 40, 42, 47, 21, 22, 27, 29, 27, 28, 30, 31, 35, 39, 42, 27, 28, 30,
|
||||
31, 35, 39, 42, 27, 28, 30, 31, 35, 39, 42, 27, 28, 29, 31, 32, 33, 34,
|
||||
35, 28, 29, 31, 32, 33, 34, 35, 28, 29, 31, 32, 33, 34, 35, 28, 2, 3,
|
||||
29, 30, 32, 33, 48, 49, 2, 3, 29, 30, 32, 33, 48, 49, 2, 3, 29, 30,
|
||||
32, 33, 29, 30, 31, 33, 34, 35, 49, 50, 29, 30, 31, 33, 34, 35, 49, 50,
|
||||
29, 30, 31, 33, 34, 35, 29, 30, 31, 32, 34, 35, 50, 51, 52, 29, 30, 31,
|
||||
32, 34, 35, 50, 51, 52, 29, 30, 31, 32, 29, 30, 31, 32, 33, 35, 52, 53,
|
||||
29, 30, 31, 32, 33, 35, 52, 53, 29, 30, 31, 32, 33, 35, 13, 14, 29, 30,
|
||||
32, 33, 34, 53, 54, 13, 14, 29, 30, 32, 33, 34, 53, 54, 13, 14, 29, 30,
|
||||
0, 1, 2, 17, 18, 19, 20, 37, 38, 39, 40, 41, 0, 1, 2, 17, 18, 19,
|
||||
20, 37, 38, 39, 0, 1, 17, 18, 19, 20, 21, 36, 38, 39, 40, 41, 0, 1,
|
||||
17, 18, 19, 20, 21, 36, 38, 39, 0, 1, 17, 18, 19, 20, 21, 27, 28, 36,
|
||||
37, 39, 40, 41, 0, 1, 17, 18, 19, 20, 21, 27, 19, 20, 21, 27, 28, 29,
|
||||
36, 37, 38, 40, 41, 19, 20, 21, 27, 28, 29, 36, 37, 38, 40, 41, 0, 1,
|
||||
17, 18, 19, 20, 21, 27, 28, 36, 37, 38, 39, 41, 0, 1, 17, 18, 19, 20,
|
||||
21, 27, 0, 1, 2, 17, 18, 19, 20, 21, 36, 37, 38, 39, 40, 0, 1, 2,
|
||||
17, 18, 19, 20, 21, 36, 22, 23, 24, 27, 28, 29, 43, 44, 45, 46, 47, 22,
|
||||
23, 24, 27, 28, 29, 43, 44, 45, 46, 47, 15, 16, 22, 23, 24, 25, 26, 27,
|
||||
42, 44, 45, 46, 47, 15, 16, 22, 23, 24, 25, 26, 27, 42, 15, 16, 22, 23,
|
||||
24, 25, 26, 42, 43, 45, 46, 47, 15, 16, 22, 23, 24, 25, 26, 42, 43, 45,
|
||||
14, 15, 16, 23, 24, 25, 26, 42, 43, 44, 46, 47, 14, 15, 16, 23, 24, 25,
|
||||
26, 42, 43, 44, 14, 15, 16, 22, 23, 24, 25, 26, 42, 43, 44, 45, 47, 14,
|
||||
15, 16, 22, 23, 24, 25, 26, 42, 15, 16, 22, 23, 24, 25, 26, 27, 28, 42,
|
||||
43, 44, 45, 46, 15, 16, 22, 23, 24, 25, 26, 27, 2, 3, 4, 5, 6, 49,
|
||||
59, 60, 2, 3, 4, 5, 6, 49, 59, 60, 2, 3, 4, 5, 6, 49, 3, 4,
|
||||
5, 31, 32, 48, 50, 51, 59, 60, 61, 67, 3, 4, 5, 31, 32, 48, 50, 51,
|
||||
59, 60, 30, 31, 32, 33, 34, 48, 49, 51, 52, 58, 59, 60, 61, 62, 66, 67,
|
||||
30, 31, 32, 33, 34, 48, 30, 31, 32, 33, 34, 35, 48, 49, 50, 52, 53, 54,
|
||||
56, 58, 60, 61, 62, 63, 64, 65, 66, 67, 30, 32, 33, 34, 35, 50, 51, 53,
|
||||
54, 55, 56, 62, 63, 64, 65, 30, 32, 33, 34, 35, 50, 51, 11, 12, 13, 34,
|
||||
35, 52, 54, 55, 63, 64, 65, 11, 12, 13, 34, 35, 52, 54, 55, 63, 64, 65,
|
||||
10, 11, 12, 13, 14, 53, 55, 64, 10, 11, 12, 13, 14, 53, 55, 64, 10, 11,
|
||||
12, 13, 14, 53, 8, 9, 10, 11, 12, 13, 53, 54, 56, 57, 63, 64, 65, 8,
|
||||
9, 10, 11, 12, 13, 53, 54, 56, 7, 8, 9, 10, 11, 12, 54, 55, 57, 58,
|
||||
63, 64, 65, 66, 7, 8, 9, 10, 11, 12, 54, 55, 6, 7, 8, 9, 10, 55,
|
||||
56, 58, 59, 62, 65, 66, 67, 6, 7, 8, 9, 10, 55, 56, 58, 59, 4, 5,
|
||||
6, 7, 8, 9, 48, 56, 57, 59, 60, 61, 62, 66, 67, 4, 5, 6, 7, 8,
|
||||
9, 48, 3, 4, 5, 6, 7, 8, 48, 49, 57, 58, 60, 61, 67, 3, 4, 5,
|
||||
6, 7, 8, 48, 49, 57, 2, 3, 4, 5, 6, 31, 48, 49, 59, 2, 3, 4,
|
||||
5, 6, 31, 48, 49, 59, 2, 3, 4, 5, 31, 32, 33, 48, 49, 50, 51, 52,
|
||||
57, 58, 59, 60, 62, 63, 66, 67, 31, 32, 33, 48, 49, 50, 33, 34, 48, 49,
|
||||
50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 63, 64, 65, 66, 67, 33,
|
||||
34, 35, 50, 51, 52, 53, 54, 55, 56, 57, 61, 62, 64, 65, 66, 34, 35, 50,
|
||||
51, 52, 53, 54, 10, 11, 12, 13, 14, 35, 53, 54, 55, 10, 11, 12, 13, 14,
|
||||
35, 53, 54, 55, 10, 11, 12, 13, 9, 10, 11, 12, 51, 52, 53, 54, 55, 56,
|
||||
57, 58, 61, 62, 63, 64, 66, 67, 9, 10, 11, 12, 7, 8, 9, 50, 51, 52,
|
||||
55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 67, 7, 8, 9, 50, 4, 5,
|
||||
6, 7, 48, 49, 50, 51, 56, 57, 58, 59, 60, 61, 62, 63, 65, 66, 4, 5,
|
||||
6, 7};
|
||||
reverse_index2_map_[68] = {
|
||||
0, 3, 1, 7, 8, 0, 3, 1, 7, 8, 0, 3, 1, 7, 8, 0, 3, 1, 7, 8, 0, 3, 1, 1, 4,
|
||||
9, 1, 1, 4, 9, 1, 1, 4, 9, 1, 1, 4, 9, 1, 1, 4, 9, 1, 1, 6, 1, 1, 5, 6, 1,
|
||||
1, 5, 6, 1, 1, 5, 6, 1, 1, 5, 6, 1, 1, 5, 6, 1, 5, 0, 0, 6, 5, 0, 0, 6, 5,
|
||||
0, 0, 6, 5, 0, 0, 6, 5, 0, 0, 6, 5, 0, 2, 0, 1, 7, 2, 0, 1, 7, 2, 0, 1, 7,
|
||||
2, 0, 1, 7, 2, 0, 1, 7, 2, 0, 2, 1, 1, 6, 2, 1, 1, 6, 2, 1, 1, 6, 2, 1, 1,
|
||||
6, 2, 1, 1, 6, 2, 1, 9, 4, 0, 1, 4, 9, 4, 0, 1, 4, 9, 4, 0, 1, 4, 9, 4, 0,
|
||||
1, 4, 9, 4, 5, 0, 1, 3, 5, 0, 1, 3, 5, 0, 1, 3, 5, 0, 1, 3, 5, 0, 1, 3, 5,
|
||||
0, 4, 0, 0, 4, 4, 0, 0, 4, 4, 0, 0, 4, 4, 0, 0, 4, 4, 0, 0, 4, 4, 0, 3, 0,
|
||||
0, 5, 3, 0, 0, 5, 3, 0, 0, 5, 3, 0, 0, 5, 3, 0, 0, 5, 3, 0, 3, 1, 0, 4, 9,
|
||||
3, 1, 0, 4, 9, 3, 1, 0, 4, 9, 3, 1, 0, 4, 9, 3, 1, 6, 1, 0, 2, 6, 1, 0, 2,
|
||||
6, 1, 0, 2, 6, 1, 0, 2, 6, 1, 0, 2, 6, 1, 7, 1, 0, 2, 7, 1, 0, 2, 7, 1, 0,
|
||||
2, 7, 1, 0, 2, 7, 1, 0, 2, 7, 1, 6, 1, 1, 4, 6, 1, 1, 4, 6, 1, 1, 4, 6, 1,
|
||||
1, 4, 6, 1, 1, 4, 6, 1, 5, 1, 0, 6, 5, 1, 0, 6, 5, 1, 0, 6, 5, 1, 0, 6, 5,
|
||||
1, 0, 6, 5, 1, 3, 0, 0, 9, 3, 0, 0, 9, 3, 0, 0, 9, 3, 0, 0, 9, 3, 0, 0, 9,
|
||||
3, 0, 3, 1, 7, 2, 8, 3, 1, 7, 2, 8, 3, 1, 7, 2, 8, 3, 1, 7, 2, 8, 3, 1, 0,
|
||||
3, 9, 0, 4, 4, 8, 6, 0, 3, 9, 0, 4, 4, 8, 6, 0, 3, 9, 0, 4, 4, 3, 8, 0, 0,
|
||||
6, 5, 7, 9, 7, 3, 8, 0, 0, 6, 5, 7, 9, 7, 3, 8, 0, 0, 7, 4, 1, 1, 6, 6, 5,
|
||||
7, 9, 5, 7, 4, 1, 1, 6, 6, 5, 7, 9, 5, 7, 4, 8, 4, 1, 0, 9, 6, 4, 7, 6, 8,
|
||||
8, 4, 1, 0, 9, 6, 4, 7, 6, 8, 8, 4, 9, 6, 0, 4, 2, 7, 9, 6, 5, 5, 9, 9, 6,
|
||||
0, 4, 2, 7, 9, 6, 5, 5, 9, 4, 1, 6, 9, 3, 8, 5, 6, 9, 9, 6, 4, 1, 6, 9, 3,
|
||||
8, 5, 6, 9, 9, 6, 0, 1, 4, 8, 7, 5, 7, 9, 8, 5, 0, 1, 4, 8, 7, 5, 7, 9, 8,
|
||||
5, 0, 1, 7, 6, 0, 1, 4, 7, 5, 6, 6, 9, 7, 6, 0, 1, 4, 7, 5, 6, 6, 9, 7, 6,
|
||||
8, 3, 5, 0, 0, 9, 6, 5, 7, 8, 3, 5, 0, 0, 9, 6, 5, 7, 8, 3, 5, 0, 8, 3, 1,
|
||||
4, 0, 8, 4, 5, 8, 3, 1, 4, 0, 8, 4, 5, 8, 3, 1, 4, 0, 8, 9, 1, 1, 9, 1, 2,
|
||||
8, 4, 7, 2, 8, 7, 9, 1, 1, 9, 1, 2, 8, 4, 7, 2, 8, 8, 0, 0, 6, 6, 8, 6, 8,
|
||||
8, 8, 0, 0, 6, 6, 8, 6, 8, 8, 8, 0, 0, 5, 0, 0, 9, 9, 9, 9, 5, 0, 0, 9, 9,
|
||||
9, 9, 5, 0, 0, 9, 9, 9, 9, 5, 4, 1, 2, 2, 2, 2, 2, 4, 1, 2, 2, 2, 2, 2, 4,
|
||||
1, 2, 2, 2, 2, 2, 4, 8, 8, 6, 5, 0, 7, 7, 9, 8, 8, 6, 5, 0, 7, 7, 9, 8, 8,
|
||||
6, 5, 0, 7, 4, 3, 0, 0, 4, 5, 8, 7, 4, 3, 0, 0, 4, 5, 8, 7, 4, 3, 0, 0, 4,
|
||||
5, 7, 2, 1, 1, 1, 1, 5, 8, 5, 7, 2, 1, 1, 1, 1, 5, 8, 5, 7, 2, 1, 1, 3, 1,
|
||||
5, 4, 1, 0, 6, 9, 3, 1, 5, 4, 1, 0, 6, 9, 3, 1, 5, 4, 1, 0, 8, 9, 5, 4, 9,
|
||||
6, 0, 8, 7, 8, 9, 5, 4, 9, 6, 0, 8, 7, 8, 9, 5, 4, 2, 2, 4, 2, 3, 5, 8, 1,
|
||||
5, 8, 4, 1, 2, 2, 4, 2, 3, 5, 8, 1, 5, 8, 5, 6, 3, 2, 2, 3, 7, 1, 1, 3, 3,
|
||||
0, 5, 6, 3, 2, 2, 3, 7, 1, 1, 3, 9, 9, 6, 6, 3, 2, 2, 7, 9, 3, 2, 1, 0, 3,
|
||||
9, 9, 6, 6, 3, 2, 2, 7, 9, 4, 3, 4, 3, 9, 7, 4, 2, 1, 4, 9, 4, 3, 4, 3, 9,
|
||||
7, 4, 2, 1, 4, 8, 7, 7, 8, 8, 5, 5, 8, 5, 2, 3, 0, 0, 2, 8, 7, 7, 8, 8, 5,
|
||||
5, 8, 4, 4, 5, 5, 5, 7, 7, 9, 0, 0, 3, 2, 2, 4, 4, 5, 5, 5, 7, 7, 9, 0, 3,
|
||||
4, 9, 1, 2, 8, 2, 4, 7, 4, 2, 3, 4, 9, 1, 2, 8, 2, 4, 7, 4, 2, 9, 9, 2, 2,
|
||||
3, 6, 6, 6, 1, 2, 3, 3, 0, 9, 9, 2, 2, 3, 6, 6, 6, 1, 6, 5, 7, 3, 2, 2, 3,
|
||||
4, 1, 1, 1, 3, 6, 5, 7, 3, 2, 2, 3, 4, 1, 1, 4, 2, 2, 8, 5, 3, 1, 8, 4, 1,
|
||||
0, 4, 4, 2, 2, 8, 5, 3, 1, 8, 4, 1, 5, 5, 4, 9, 7, 7, 5, 5, 3, 3, 0, 0, 1,
|
||||
5, 5, 4, 9, 7, 7, 5, 5, 3, 7, 8, 5, 6, 8, 8, 7, 9, 6, 0, 0, 3, 2, 2, 7, 8,
|
||||
5, 6, 8, 8, 7, 9, 6, 3, 2, 2, 5, 3, 3, 0, 6, 3, 2, 2, 5, 3, 3, 0, 6, 3, 2,
|
||||
2, 5, 3, 6, 7, 8, 4, 6, 1, 3, 9, 4, 1, 5, 8, 6, 7, 8, 4, 6, 1, 3, 9, 4, 1,
|
||||
7, 3, 3, 4, 8, 5, 1, 1, 7, 9, 8, 5, 1, 6, 9, 5, 7, 3, 3, 4, 8, 5, 9, 6, 5,
|
||||
3, 5, 6, 9, 6, 1, 1, 6, 9, 8, 8, 8, 3, 0, 3, 8, 6, 6, 6, 8, 8, 5, 3, 3, 8,
|
||||
2, 1, 5, 8, 9, 7, 1, 5, 4, 8, 8, 5, 3, 3, 8, 2, 8, 7, 6, 6, 4, 3, 1, 3, 5,
|
||||
1, 8, 8, 7, 6, 6, 4, 3, 1, 3, 5, 1, 8, 5, 2, 2, 4, 6, 2, 4, 0, 5, 2, 2, 4,
|
||||
6, 2, 4, 0, 5, 2, 2, 4, 6, 2, 7, 5, 2, 3, 6, 7, 5, 2, 2, 9, 8, 2, 5, 7, 5,
|
||||
2, 3, 6, 7, 5, 2, 2, 7, 5, 2, 3, 7, 8, 6, 0, 1, 5, 7, 6, 3, 8, 7, 5, 2, 3,
|
||||
7, 8, 6, 0, 8, 4, 2, 4, 8, 7, 0, 0, 7, 8, 7, 4, 7, 8, 4, 2, 4, 8, 7, 0, 0,
|
||||
7, 9, 7, 3, 2, 6, 7, 6, 5, 0, 0, 6, 7, 9, 7, 3, 9, 7, 3, 2, 6, 7, 6, 7, 6,
|
||||
3, 2, 5, 8, 2, 5, 8, 2, 2, 8, 4, 7, 6, 3, 2, 5, 8, 2, 5, 8, 7, 5, 3, 4, 6,
|
||||
8, 0, 0, 1, 7, 5, 3, 4, 6, 8, 0, 0, 1, 7, 5, 3, 4, 7, 7, 9, 3, 2, 0, 3, 9,
|
||||
6, 4, 5, 3, 2, 6, 3, 0, 7, 7, 9, 3, 2, 0, 8, 9, 8, 7, 2, 0, 2, 7, 8, 9, 6,
|
||||
5, 6, 9, 7, 2, 2, 7, 2, 0, 2, 8, 7, 7, 9, 4, 0, 3, 3, 5, 4, 7, 6, 3, 3, 0,
|
||||
5, 7, 7, 9, 4, 0, 3, 3, 6, 4, 3, 5, 7, 8, 0, 0, 1, 6, 4, 3, 5, 7, 8, 0, 0,
|
||||
1, 6, 4, 3, 5, 8, 9, 9, 9, 7, 4, 4, 4, 2, 1, 4, 7, 9, 5, 0, 4, 2, 9, 8, 9,
|
||||
9, 9, 9, 9, 9, 6, 5, 8, 6, 3, 2, 3, 6, 9, 4, 1, 4, 9, 1, 1, 9, 9, 9, 6, 8,
|
||||
9, 9, 8, 4, 4, 4, 6, 7, 3, 1, 2, 4, 0, 4, 9, 9, 1, 8, 9, 9, 8};
|
||||
max_len_map_[68] = 22;
|
||||
// parameters for num_landmarks_ == 98
|
||||
reverse_index1_map_[98] = {
|
||||
1, 2, 3, 4, 5, 33, 1, 2, 3, 4, 5, 33, 1, 2, 3, 4, 5, 0,
|
||||
2, 3, 4, 5, 6, 33, 0, 2, 3, 4, 5, 6, 33, 0, 2, 3, 0, 1,
|
||||
3, 4, 5, 6, 0, 1, 3, 4, 5, 6, 0, 1, 3, 4, 5, 0, 1, 2,
|
||||
4, 5, 6, 7, 0, 1, 2, 4, 5, 6, 7, 0, 1, 2, 0, 1, 2, 3,
|
||||
5, 6, 7, 8, 0, 1, 2, 3, 5, 6, 7, 8, 0, 1, 2, 3, 4, 6,
|
||||
7, 8, 9, 1, 2, 3, 4, 6, 7, 8, 9, 1, 2, 3, 4, 5, 7, 8,
|
||||
9, 10, 2, 3, 4, 5, 7, 8, 9, 10, 2, 3, 4, 5, 6, 8, 9, 10,
|
||||
3, 4, 5, 6, 8, 9, 10, 3, 4, 5, 4, 5, 6, 7, 9, 10, 11, 4,
|
||||
5, 6, 7, 9, 10, 11, 4, 5, 6, 4, 5, 6, 7, 8, 10, 11, 12, 4,
|
||||
5, 6, 7, 8, 10, 11, 12, 4, 5, 6, 7, 8, 9, 11, 12, 13, 76, 5,
|
||||
6, 7, 8, 9, 11, 12, 13, 7, 8, 9, 10, 12, 13, 14, 76, 88, 7, 8,
|
||||
9, 10, 12, 13, 14, 76, 8, 9, 10, 11, 13, 14, 15, 8, 9, 10, 11, 13,
|
||||
14, 15, 8, 9, 10, 10, 11, 12, 14, 15, 16, 10, 11, 12, 14, 15, 16, 10,
|
||||
11, 12, 14, 15, 11, 12, 13, 15, 16, 17, 11, 12, 13, 15, 16, 17, 11, 12,
|
||||
13, 15, 16, 12, 13, 14, 16, 17, 18, 12, 13, 14, 16, 17, 18, 12, 13, 14,
|
||||
16, 17, 13, 14, 15, 17, 18, 19, 13, 14, 15, 17, 18, 19, 13, 14, 15, 17,
|
||||
18, 14, 15, 16, 18, 19, 20, 14, 15, 16, 18, 19, 20, 14, 15, 16, 18, 19,
|
||||
15, 16, 17, 19, 20, 21, 15, 16, 17, 19, 20, 21, 15, 16, 17, 19, 20, 16,
|
||||
17, 18, 20, 21, 22, 16, 17, 18, 20, 21, 22, 16, 17, 18, 20, 21, 17, 18,
|
||||
19, 21, 22, 23, 24, 17, 18, 19, 21, 22, 23, 24, 17, 18, 19, 18, 19, 20,
|
||||
22, 23, 24, 25, 82, 18, 19, 20, 22, 23, 24, 25, 82, 18, 19, 20, 21, 23,
|
||||
24, 25, 26, 27, 19, 20, 21, 23, 24, 25, 26, 27, 19, 20, 21, 22, 24, 25,
|
||||
26, 27, 28, 20, 21, 22, 24, 25, 26, 27, 28, 20, 21, 22, 23, 25, 26, 27,
|
||||
28, 21, 22, 23, 25, 26, 27, 28, 21, 22, 23, 21, 22, 23, 24, 26, 27, 28,
|
||||
29, 21, 22, 23, 24, 26, 27, 28, 29, 21, 22, 23, 24, 25, 27, 28, 29, 30,
|
||||
22, 23, 24, 25, 27, 28, 29, 30, 22, 23, 24, 25, 26, 28, 29, 30, 31, 23,
|
||||
24, 25, 26, 28, 29, 30, 31, 23, 24, 25, 26, 27, 29, 30, 31, 32, 24, 25,
|
||||
26, 27, 29, 30, 31, 32, 24, 25, 26, 27, 28, 30, 31, 32, 25, 26, 27, 28,
|
||||
30, 31, 32, 25, 26, 27, 26, 27, 28, 29, 31, 32, 26, 27, 28, 29, 31, 32,
|
||||
26, 27, 28, 29, 31, 26, 27, 28, 29, 30, 32, 46, 26, 27, 28, 29, 30, 32,
|
||||
46, 26, 27, 28, 27, 28, 29, 30, 31, 46, 27, 28, 29, 30, 31, 46, 27, 28,
|
||||
29, 30, 31, 0, 1, 2, 3, 34, 41, 60, 0, 1, 2, 3, 34, 41, 60, 0,
|
||||
1, 2, 0, 33, 35, 40, 41, 60, 0, 33, 35, 40, 41, 60, 0, 33, 35, 40,
|
||||
41, 33, 34, 36, 37, 39, 40, 41, 60, 61, 62, 33, 34, 36, 37, 39, 40, 41,
|
||||
34, 35, 37, 38, 39, 40, 63, 64, 34, 35, 37, 38, 39, 40, 63, 64, 34, 36,
|
||||
38, 39, 51, 64, 36, 38, 39, 51, 64, 36, 38, 39, 51, 64, 36, 38, 36, 37,
|
||||
39, 51, 52, 63, 64, 65, 36, 37, 39, 51, 52, 63, 64, 65, 36, 35, 36, 37,
|
||||
38, 40, 62, 63, 64, 65, 66, 67, 96, 35, 36, 37, 38, 40, 33, 34, 35, 36,
|
||||
37, 38, 39, 41, 60, 61, 62, 63, 65, 66, 67, 96, 33, 0, 1, 2, 33, 34,
|
||||
35, 40, 60, 61, 67, 0, 1, 2, 33, 34, 35, 40, 43, 49, 50, 51, 68, 43,
|
||||
49, 50, 51, 68, 43, 49, 50, 51, 68, 43, 49, 42, 44, 45, 48, 49, 50, 68,
|
||||
69, 42, 44, 45, 48, 49, 50, 68, 69, 42, 42, 43, 45, 46, 47, 48, 49, 70,
|
||||
42, 43, 45, 46, 47, 48, 49, 70, 42, 32, 44, 46, 47, 48, 71, 72, 73, 32,
|
||||
44, 46, 47, 48, 71, 72, 73, 32, 29, 30, 31, 32, 45, 47, 72, 29, 30, 31,
|
||||
32, 45, 47, 72, 29, 30, 31, 30, 31, 32, 44, 45, 46, 48, 71, 72, 73, 30,
|
||||
31, 32, 44, 45, 46, 48, 42, 43, 44, 45, 46, 47, 49, 50, 69, 70, 71, 72,
|
||||
73, 74, 75, 97, 42, 42, 43, 44, 48, 50, 68, 69, 70, 74, 75, 97, 42, 43,
|
||||
44, 48, 50, 68, 42, 43, 49, 51, 52, 68, 69, 75, 42, 43, 49, 51, 52, 68,
|
||||
69, 75, 42, 37, 38, 42, 50, 52, 53, 64, 68, 37, 38, 42, 50, 52, 53, 64,
|
||||
68, 37, 51, 53, 54, 51, 53, 54, 51, 53, 54, 51, 53, 54, 51, 53, 54, 51,
|
||||
53, 51, 52, 54, 55, 56, 57, 59, 51, 52, 54, 55, 56, 57, 59, 51, 52, 54,
|
||||
52, 53, 55, 56, 57, 58, 59, 52, 53, 55, 56, 57, 58, 59, 52, 53, 55, 53,
|
||||
54, 56, 57, 76, 77, 78, 88, 53, 54, 56, 57, 76, 77, 78, 88, 53, 53, 54,
|
||||
55, 57, 58, 77, 78, 79, 88, 53, 54, 55, 57, 58, 77, 78, 79, 53, 54, 55,
|
||||
56, 58, 59, 78, 79, 80, 90, 53, 54, 55, 56, 58, 59, 78, 53, 54, 56, 57,
|
||||
59, 79, 80, 81, 82, 92, 53, 54, 56, 57, 59, 79, 80, 53, 54, 57, 58, 80,
|
||||
81, 82, 92, 53, 54, 57, 58, 80, 81, 82, 92, 53, 0, 1, 2, 3, 4, 33,
|
||||
34, 41, 61, 62, 66, 67, 96, 0, 1, 2, 3, 0, 1, 33, 34, 35, 40, 41,
|
||||
60, 62, 63, 65, 66, 67, 96, 0, 1, 33, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 60, 61, 63, 64, 65, 66, 67, 96, 35, 36, 37, 38, 39, 40, 51, 52, 61,
|
||||
62, 64, 65, 66, 67, 96, 35, 36, 36, 37, 38, 39, 51, 52, 53, 63, 65, 66,
|
||||
96, 36, 37, 38, 39, 51, 52, 36, 37, 38, 39, 52, 61, 62, 63, 64, 66, 67,
|
||||
96, 36, 37, 38, 39, 52, 41, 60, 61, 62, 63, 64, 65, 67, 96, 41, 60, 61,
|
||||
62, 63, 64, 65, 67, 0, 1, 2, 3, 33, 34, 35, 40, 41, 60, 61, 62, 65,
|
||||
66, 96, 0, 1, 42, 43, 49, 50, 51, 52, 53, 69, 74, 75, 97, 42, 43, 49,
|
||||
50, 51, 52, 42, 43, 44, 48, 49, 50, 51, 68, 70, 71, 73, 74, 75, 97, 42,
|
||||
43, 44, 42, 43, 44, 45, 46, 47, 48, 49, 50, 68, 69, 71, 72, 73, 74, 75,
|
||||
97, 31, 32, 44, 45, 46, 47, 48, 69, 70, 72, 73, 74, 75, 97, 31, 32, 44,
|
||||
28, 29, 30, 31, 32, 45, 46, 47, 70, 71, 73, 74, 97, 28, 29, 30, 31, 29,
|
||||
30, 31, 32, 44, 45, 46, 47, 48, 70, 71, 72, 74, 75, 97, 29, 30, 47, 68,
|
||||
69, 70, 71, 72, 73, 75, 97, 47, 68, 69, 70, 71, 72, 73, 75, 42, 43, 49,
|
||||
50, 52, 68, 69, 70, 71, 72, 73, 74, 97, 42, 43, 49, 50, 6, 7, 8, 9,
|
||||
10, 11, 12, 55, 77, 87, 88, 89, 95, 6, 7, 8, 9, 55, 56, 76, 78, 86,
|
||||
87, 88, 89, 95, 55, 56, 76, 78, 86, 87, 88, 89, 54, 55, 56, 57, 58, 76,
|
||||
77, 79, 80, 85, 86, 87, 88, 89, 90, 94, 95, 54, 55, 56, 57, 58, 59, 77,
|
||||
78, 80, 81, 84, 85, 86, 89, 90, 91, 94, 54, 57, 58, 59, 78, 79, 81, 82,
|
||||
83, 84, 85, 90, 91, 92, 93, 94, 54, 58, 59, 80, 82, 83, 84, 91, 92, 93,
|
||||
58, 59, 80, 82, 83, 84, 91, 92, 20, 21, 22, 23, 24, 25, 26, 59, 81, 83,
|
||||
91, 92, 93, 20, 21, 22, 23, 17, 18, 19, 20, 21, 22, 23, 81, 82, 84, 91,
|
||||
92, 93, 17, 18, 19, 20, 16, 17, 18, 19, 20, 81, 82, 83, 85, 91, 92, 93,
|
||||
94, 16, 17, 18, 19, 14, 15, 16, 17, 18, 83, 84, 86, 87, 90, 93, 94, 95,
|
||||
14, 15, 16, 17, 11, 12, 13, 14, 15, 16, 76, 77, 85, 87, 88, 89, 94, 95,
|
||||
11, 12, 13, 9, 10, 11, 12, 13, 14, 76, 77, 86, 88, 89, 95, 9, 10, 11,
|
||||
12, 13, 7, 8, 9, 10, 11, 12, 13, 55, 76, 77, 86, 87, 89, 95, 7, 8,
|
||||
9, 55, 56, 76, 77, 78, 79, 86, 87, 88, 90, 95, 55, 56, 76, 77, 78, 79,
|
||||
56, 57, 58, 78, 79, 80, 83, 84, 85, 86, 87, 89, 91, 92, 93, 94, 95, 58,
|
||||
59, 79, 80, 81, 82, 83, 84, 85, 90, 92, 93, 94, 58, 59, 79, 80, 19, 20,
|
||||
21, 22, 23, 24, 25, 59, 81, 82, 83, 84, 91, 93, 19, 20, 21, 18, 19, 79,
|
||||
80, 81, 82, 83, 84, 85, 90, 91, 92, 94, 18, 19, 79, 80, 15, 16, 17, 78,
|
||||
79, 80, 83, 84, 85, 86, 87, 89, 90, 91, 93, 95, 15, 13, 14, 15, 76, 77,
|
||||
78, 85, 86, 87, 88, 89, 90, 94, 13, 14, 15, 76, 34, 35, 36, 38, 39, 40,
|
||||
41, 60, 61, 62, 63, 64, 65, 66, 67, 34, 35, 43, 44, 45, 47, 48, 49, 50,
|
||||
68, 69, 70, 71, 72, 73, 74, 75, 43, 44};
|
||||
reverse_index2_map_[98] = {
|
||||
0, 2, 4, 6, 8, 4, 0, 2, 4, 6, 8, 4, 0, 2, 4, 6, 8, 0, 0, 2, 4, 6, 8, 8, 0,
|
||||
0, 2, 4, 6, 8, 8, 0, 0, 2, 1, 1, 0, 2, 4, 6, 1, 1, 0, 2, 4, 6, 1, 1, 0, 2,
|
||||
4, 3, 2, 1, 0, 2, 4, 6, 3, 2, 1, 0, 2, 4, 6, 3, 2, 1, 6, 3, 3, 1, 0, 2, 4,
|
||||
7, 6, 3, 3, 1, 0, 2, 4, 7, 6, 6, 4, 3, 1, 0, 2, 4, 8, 6, 4, 3, 1, 0, 2, 4,
|
||||
8, 6, 7, 5, 3, 1, 0, 2, 4, 9, 7, 5, 3, 1, 0, 2, 4, 9, 7, 6, 5, 3, 1, 0, 2,
|
||||
4, 6, 5, 3, 1, 0, 2, 4, 6, 5, 3, 7, 5, 3, 1, 0, 2, 4, 7, 5, 3, 1, 0, 2, 4,
|
||||
7, 5, 3, 9, 7, 5, 3, 1, 0, 2, 5, 9, 7, 5, 3, 1, 0, 2, 5, 9, 9, 7, 5, 3, 1,
|
||||
0, 2, 5, 8, 9, 7, 5, 3, 1, 0, 2, 5, 7, 5, 3, 1, 0, 2, 5, 9, 9, 7, 5, 3, 1,
|
||||
0, 2, 5, 9, 9, 5, 3, 1, 0, 2, 4, 9, 5, 3, 1, 0, 2, 4, 9, 5, 3, 6, 3, 1, 0,
|
||||
2, 6, 6, 3, 1, 0, 2, 6, 6, 3, 1, 0, 2, 7, 3, 1, 0, 3, 7, 7, 3, 1, 0, 3, 7,
|
||||
7, 3, 1, 0, 3, 6, 3, 1, 1, 3, 6, 6, 3, 1, 1, 3, 6, 6, 3, 1, 1, 3, 7, 3, 1,
|
||||
1, 3, 7, 7, 3, 1, 1, 3, 7, 7, 3, 1, 1, 3, 6, 3, 0, 1, 3, 6, 6, 3, 0, 1, 3,
|
||||
6, 6, 3, 0, 1, 3, 7, 2, 0, 1, 3, 5, 7, 2, 0, 1, 3, 5, 7, 2, 0, 1, 3, 5, 2,
|
||||
0, 1, 3, 5, 5, 2, 0, 1, 3, 5, 5, 2, 0, 1, 3, 4, 2, 0, 1, 3, 5, 8, 4, 2, 0,
|
||||
1, 3, 5, 8, 4, 2, 0, 5, 2, 0, 1, 3, 5, 7, 9, 5, 2, 0, 1, 3, 5, 7, 9, 5, 4,
|
||||
2, 0, 1, 3, 5, 7, 9, 4, 2, 0, 1, 3, 5, 7, 9, 4, 4, 2, 0, 1, 3, 5, 7, 9, 4,
|
||||
2, 0, 1, 3, 5, 7, 9, 4, 4, 2, 0, 1, 3, 5, 7, 4, 2, 0, 1, 3, 5, 7, 4, 2, 0,
|
||||
9, 4, 2, 0, 1, 3, 5, 6, 9, 4, 2, 0, 1, 3, 5, 6, 9, 9, 4, 2, 0, 1, 3, 5, 6,
|
||||
9, 4, 2, 0, 1, 3, 5, 6, 9, 8, 4, 2, 0, 1, 3, 4, 6, 8, 4, 2, 0, 1, 3, 4, 6,
|
||||
8, 6, 4, 2, 0, 1, 3, 3, 5, 6, 4, 2, 0, 1, 3, 3, 5, 6, 6, 4, 2, 0, 1, 2, 3,
|
||||
6, 4, 2, 0, 1, 2, 3, 6, 4, 2, 6, 4, 2, 0, 1, 1, 6, 4, 2, 0, 1, 1, 6, 4, 2,
|
||||
0, 1, 8, 6, 4, 2, 0, 0, 9, 8, 6, 4, 2, 0, 0, 9, 8, 6, 4, 8, 6, 4, 2, 0, 6,
|
||||
8, 6, 4, 2, 0, 6, 8, 6, 4, 2, 0, 2, 4, 5, 8, 3, 1, 6, 2, 4, 5, 8, 3, 1, 6,
|
||||
2, 4, 5, 7, 1, 1, 5, 0, 8, 7, 1, 1, 5, 0, 8, 7, 1, 1, 5, 0, 7, 1, 2, 8, 6,
|
||||
0, 5, 9, 8, 8, 7, 1, 2, 8, 6, 0, 5, 8, 2, 1, 4, 0, 6, 7, 9, 8, 2, 1, 4, 0,
|
||||
6, 7, 9, 8, 1, 0, 5, 5, 7, 1, 0, 5, 5, 7, 1, 0, 5, 5, 7, 1, 0, 4, 0, 2, 2,
|
||||
6, 6, 2, 8, 4, 0, 2, 2, 6, 6, 2, 8, 4, 4, 0, 2, 1, 4, 7, 4, 4, 5, 9, 9, 7,
|
||||
4, 0, 2, 1, 4, 5, 2, 0, 3, 9, 9, 4, 2, 7, 5, 4, 8, 9, 8, 6, 6, 5, 5, 7, 9,
|
||||
0, 0, 3, 3, 2, 6, 7, 5, 7, 9, 0, 0, 3, 3, 2, 5, 0, 6, 7, 2, 5, 0, 6, 7, 2,
|
||||
5, 0, 6, 7, 2, 5, 1, 1, 8, 5, 0, 4, 9, 7, 1, 1, 8, 5, 0, 4, 9, 7, 1, 8, 1,
|
||||
1, 7, 4, 0, 6, 9, 8, 1, 1, 7, 4, 0, 6, 9, 8, 7, 2, 1, 0, 6, 9, 8, 9, 7, 2,
|
||||
1, 0, 6, 9, 8, 9, 7, 8, 5, 4, 2, 2, 1, 6, 8, 5, 4, 2, 2, 1, 6, 8, 5, 4, 9,
|
||||
7, 6, 3, 0, 0, 3, 6, 2, 7, 9, 7, 6, 3, 0, 0, 3, 7, 3, 0, 3, 5, 2, 2, 9, 8,
|
||||
4, 5, 7, 6, 7, 9, 6, 7, 2, 0, 4, 2, 1, 3, 2, 7, 9, 5, 8, 2, 0, 4, 2, 1, 3,
|
||||
0, 4, 3, 1, 5, 2, 6, 8, 0, 4, 3, 1, 5, 2, 6, 8, 0, 5, 6, 5, 5, 1, 5, 8, 8,
|
||||
5, 6, 5, 5, 1, 5, 8, 8, 5, 0, 1, 9, 0, 1, 9, 0, 1, 9, 0, 1, 9, 0, 1, 9, 0,
|
||||
1, 7, 0, 1, 9, 9, 9, 9, 7, 0, 1, 9, 9, 9, 9, 7, 0, 1, 4, 0, 5, 2, 0, 2, 4,
|
||||
4, 0, 5, 2, 0, 2, 4, 4, 0, 5, 6, 5, 0, 8, 6, 6, 9, 6, 6, 5, 0, 8, 6, 6, 9,
|
||||
6, 6, 3, 2, 0, 2, 7, 7, 5, 7, 8, 3, 2, 0, 2, 7, 7, 5, 7, 2, 0, 2, 1, 1, 2,
|
||||
4, 3, 5, 7, 2, 0, 2, 1, 1, 2, 4, 4, 3, 7, 1, 0, 5, 4, 8, 8, 8, 4, 3, 7, 1,
|
||||
0, 5, 4, 7, 4, 7, 0, 9, 6, 6, 6, 7, 4, 7, 0, 9, 6, 6, 6, 7, 4, 5, 6, 7, 8,
|
||||
2, 5, 4, 1, 9, 6, 1, 9, 4, 5, 6, 7, 8, 9, 3, 4, 6, 2, 3, 1, 2, 9, 7, 4, 0,
|
||||
5, 8, 9, 3, 9, 6, 5, 6, 7, 7, 3, 1, 7, 4, 2, 3, 6, 4, 1, 4, 0, 8, 5, 3, 3,
|
||||
1, 8, 8, 9, 7, 3, 1, 0, 5, 8, 3, 8, 5, 8, 4, 2, 8, 4, 3, 9, 1, 1, 7, 8, 8,
|
||||
4, 2, 8, 4, 3, 9, 6, 5, 9, 7, 9, 6, 0, 0, 3, 5, 2, 9, 6, 5, 9, 7, 9, 3, 4,
|
||||
1, 5, 5, 3, 2, 1, 9, 3, 4, 1, 5, 5, 3, 2, 9, 8, 8, 9, 6, 7, 9, 9, 6, 0, 0,
|
||||
5, 6, 2, 4, 9, 8, 4, 8, 8, 2, 3, 2, 8, 1, 8, 1, 9, 4, 8, 8, 2, 3, 2, 3, 5,
|
||||
8, 8, 1, 3, 9, 0, 3, 7, 8, 5, 0, 5, 3, 5, 8, 9, 6, 5, 6, 8, 6, 1, 4, 7, 6,
|
||||
4, 2, 5, 4, 2, 4, 0, 9, 8, 6, 4, 3, 3, 4, 9, 1, 1, 0, 4, 7, 2, 9, 8, 6, 8,
|
||||
7, 7, 5, 4, 5, 2, 5, 8, 1, 1, 6, 7, 8, 7, 7, 5, 9, 8, 8, 9, 9, 7, 4, 7, 9,
|
||||
5, 0, 0, 1, 6, 3, 9, 8, 9, 5, 5, 2, 4, 3, 2, 3, 1, 9, 5, 5, 2, 4, 3, 2, 3,
|
||||
6, 9, 9, 6, 8, 1, 0, 6, 8, 9, 5, 3, 4, 6, 9, 9, 6, 9, 8, 6, 6, 5, 6, 7, 8,
|
||||
4, 2, 0, 8, 7, 9, 8, 6, 6, 1, 5, 2, 7, 5, 3, 2, 0, 3, 1, 5, 2, 7, 5, 3, 2,
|
||||
0, 7, 4, 3, 4, 9, 7, 5, 1, 3, 7, 7, 6, 7, 2, 2, 3, 4, 6, 7, 4, 3, 4, 6, 9,
|
||||
0, 0, 9, 9, 6, 9, 7, 0, 7, 2, 8, 5, 3, 3, 3, 2, 5, 7, 6, 7, 8, 3, 2, 7, 4,
|
||||
4, 8, 5, 1, 6, 2, 3, 5, 0, 2, 3, 5, 1, 6, 2, 3, 5, 0, 2, 7, 6, 6, 6, 7, 8,
|
||||
9, 8, 4, 2, 8, 0, 8, 7, 6, 6, 6, 8, 7, 6, 5, 7, 8, 9, 3, 1, 1, 3, 1, 2, 8,
|
||||
7, 6, 5, 7, 5, 4, 5, 9, 7, 5, 5, 1, 4, 5, 1, 5, 7, 5, 4, 5, 8, 5, 4, 6, 8,
|
||||
8, 2, 2, 8, 4, 9, 0, 9, 8, 5, 4, 6, 9, 8, 4, 4, 6, 8, 5, 8, 2, 5, 5, 4, 6,
|
||||
1, 9, 8, 4, 9, 8, 5, 4, 6, 7, 1, 3, 1, 1, 3, 2, 9, 8, 5, 4, 6, 9, 8, 7, 7,
|
||||
8, 9, 9, 6, 0, 2, 8, 1, 5, 5, 9, 8, 7, 3, 6, 3, 0, 2, 8, 3, 4, 3, 6, 0, 3,
|
||||
6, 3, 0, 2, 8, 8, 6, 8, 1, 0, 1, 9, 6, 3, 6, 9, 6, 6, 9, 7, 1, 8, 6, 5, 6,
|
||||
2, 0, 3, 4, 3, 9, 5, 3, 0, 9, 6, 5, 6, 2, 9, 8, 8, 7, 7, 9, 9, 7, 2, 0, 1,
|
||||
8, 5, 5, 9, 8, 8, 9, 8, 9, 8, 1, 4, 0, 0, 4, 8, 1, 4, 7, 9, 8, 9, 8, 8, 9,
|
||||
9, 6, 4, 7, 7, 4, 0, 4, 7, 9, 1, 9, 6, 6, 8, 8, 9, 9, 4, 1, 8, 5, 0, 0, 4,
|
||||
1, 9, 8, 8, 9, 9, 4, 9, 7, 7, 8, 7, 7, 8, 5, 3, 0, 2, 3, 2, 0, 3, 9, 7, 7,
|
||||
7, 9, 8, 7, 7, 8, 4, 3, 0, 3, 4, 3, 0, 2, 7, 7};
|
||||
max_len_map_[98] = 17;
|
||||
if (!InitRuntime()) {
|
||||
FDERROR << "Failed to initialize fastdeploy backend." << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PIPNet::Preprocess(Mat* mat, FDTensor* output,
|
||||
std::map<std::string, std::array<int, 2>>* 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(
|
||||
std::vector<FDTensor>& infer_result, FaceAlignmentResult* result,
|
||||
const std::map<std::string, std::array<int, 2>>& 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;
|
||||
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];
|
||||
GenerateLandmarks(infer_result, result, in_h, in_w);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PIPNet::Predict(cv::Mat* im, FaceAlignmentResult* result) {
|
||||
Mat mat(*im);
|
||||
std::vector<FDTensor> input_tensors(1);
|
||||
|
||||
std::map<std::string, std::array<int, 2>> 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<FDTensor> output_tensors;
|
||||
if (!Infer(input_tensors, &output_tensors)) {
|
||||
FDERROR << "Failed to inference." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Postprocess(output_tensors, result, im_info)) {
|
||||
FDERROR << "Failed to post process." << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace facealign
|
||||
} // namespace vision
|
||||
} // namespace fastdeploy
|
127
fastdeploy/vision/facealign/contrib/pipnet.h
Normal file
127
fastdeploy/vision/facealign/contrib/pipnet.h
Normal file
@@ -0,0 +1,127 @@
|
||||
// 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);
|
||||
|
||||
/** \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<float> 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<float> GetStdVals() { return std_vals_; }
|
||||
/** \brief Get the input size of image
|
||||
*
|
||||
* \return Vector of int values, default {256, 256}
|
||||
*/
|
||||
std::vector<int> GetSize() { return size_; }
|
||||
/** \brief Set the number of landmarks
|
||||
*
|
||||
* \param[in] num_landmarks Integer value which represents number of 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(const std::vector<float>& 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<float>& 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<int>& size) { size_ = size; }
|
||||
|
||||
private:
|
||||
bool Initialize();
|
||||
|
||||
bool Preprocess(Mat* mat, FDTensor* outputs,
|
||||
std::map<std::string, std::array<int, 2>>* im_info);
|
||||
|
||||
bool Postprocess(std::vector<FDTensor>& infer_result,
|
||||
FaceAlignmentResult* result,
|
||||
const std::map<std::string, std::array<int, 2>>& im_info);
|
||||
void GenerateLandmarks(std::vector<FDTensor>& infer_result,
|
||||
FaceAlignmentResult* result,
|
||||
float img_height, float img_width);
|
||||
std::map<int, int> num_lms_map_;
|
||||
std::map<int, int> max_len_map_;
|
||||
std::map<int, std::vector<int>> reverse_index1_map_;
|
||||
std::map<int, std::vector<int>> reverse_index2_map_;
|
||||
int num_nb_;
|
||||
int net_stride_;
|
||||
// Now PIPNet support num_landmarks in {19, 29, 68, 98}
|
||||
std::vector<int> supported_num_landmarks_;
|
||||
// tuple of (width, height), default (256, 256)
|
||||
std::vector<int> size_;
|
||||
|
||||
// Mean parameters for normalize, size should be the the same as channels,
|
||||
// default mean_vals = {0.485f, 0.456f, 0.406f}
|
||||
std::vector<float> 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<float> std_vals_;
|
||||
// number of landmarks
|
||||
int num_landmarks_;
|
||||
};
|
||||
|
||||
} // namespace facealign
|
||||
} // namespace vision
|
||||
} // namespace fastdeploy
|
39
fastdeploy/vision/facealign/contrib/pipnet_pybind.cc
Normal file
39
fastdeploy/vision/facealign/contrib/pipnet_pybind.cc
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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_<vision::facealign::PIPNet, FastDeployModel>(m, "PIPNet")
|
||||
.def(pybind11::init<std::string, std::string, RuntimeOption,
|
||||
ModelFormat>())
|
||||
.def("predict",
|
||||
[](vision::facealign::PIPNet& self, pybind11::array& data) {
|
||||
auto mat = PyArrayToCvMat(data);
|
||||
vision::FaceAlignmentResult res;
|
||||
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);
|
||||
}
|
||||
} // namespace fastdeploy
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
107
python/fastdeploy/vision/facealign/contrib/pipnet.py
Normal file
107
python/fastdeploy/vision/facealign/contrib/pipnet.py
Normal file
@@ -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
|
43
tests/eval_example/test_facelandmark1000.py
Normal file
43
tests/eval_example/test_facelandmark1000.py
Normal file
@@ -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)
|
43
tests/eval_example/test_pipnet.py
Normal file
43
tests/eval_example/test_pipnet.py
Normal file
@@ -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)
|
@@ -71,6 +71,56 @@ TEST(fastdeploy, flycv_rgb2bgr) {
|
||||
check_data(reinterpret_cast<const uint8_t*>(opencv.Data()), reinterpret_cast<const uint8_t*>(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<const uint8_t*>(opencv.Data()), reinterpret_cast<const uint8_t*>(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<const uint8_t*>(opencv.Data()), reinterpret_cast<const uint8_t*>(flycv.Data()), opencv.Numel());
|
||||
check_type(opencv.dtype, flycv.dtype);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace fastdeploy
|
||||
|
Reference in New Issue
Block a user