mirror of
				https://github.com/PaddlePaddle/FastDeploy.git
				synced 2025-11-01 04:12:58 +08:00 
			
		
		
		
	 18669b539a
			
		
	
	18669b539a
	
	
	
		
			
			* 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>
		
			
				
	
	
		
			687 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			687 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // 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
 |