text: /* Copyright 2020 iwatake2222
  
  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 ***/
  /* for general */
  #include <cstdint>
  #include <cstdlib>
  #include <cmath>
  #include <cstring>
  #include <string>
  #include <vector>
  #include <array>
  #include <algorithm>
  #include <chrono>
  #include <fstream>
  #include <memory>
  
  /* for OpenCV */
  #include <opencv2/opencv.hpp>
  
  /* for My modules */
  #include "common_helper.h"
  #include "common_helper_cv.h"
  #include "semantic_segmentation_engine.h"
  #include "image_processor.h"
  
  /*** Macro ***/
  #define TAG "ImageProcessor"
  #define PRINT(...)   COMMON_HELPER_PRINT(TAG, __VA_ARGS__)
  #define PRINT_E(...) COMMON_HELPER_PRINT_E(TAG, __VA_ARGS__)
  
  /*** Global variable ***/
  std::unique_ptr<SemanticSegmentationEngine> s_engine;
  
  /*** Function ***/
  static void DrawFps(cv::Mat& mat, double time_inference, cv::Point pos, double font_scale, int32_t thickness, cv::Scalar color_front, cv::Scalar color_back, bool is_text_on_rect = true)
  {
      char text[64];
      static auto time_previous = std::chrono::steady_clock::now();
      auto time_now = std::chrono::steady_clock::now();
      double fps = 1e9 / (time_now - time_previous).count();
      time_previous = time_now;
      snprintf(text, sizeof(text), "FPS: %.1f, Inference: %.1f [ms]", fps, time_inference);
      CommonHelper::DrawText(mat, text, cv::Point(0, 0), 0.5, 2, CommonHelper::CreateCvColor(0, 0, 0), CommonHelper::CreateCvColor(180, 180, 180), true);
  }
  
  int32_t ImageProcessor::Initialize(const ImageProcessor::InputParam& input_param)
  {
      if (s_engine) {
          PRINT_E("Already initialized\n");
          return -1;
      }
  
      s_engine.reset(new SemanticSegmentationEngine());
      if (s_engine->Initialize(input_param.work_dir, input_param.num_threads) != SemanticSegmentationEngine::kRetOk) {
          s_engine->Finalize();
          s_engine.reset();
          return -1;
      }
      return 0;
  }
  
  int32_t ImageProcessor::Finalize(void)
  {
      if (!s_engine) {
          PRINT_E("Not initialized\n");
          return -1;
      }
  
      if (s_engine->Finalize() != SemanticSegmentationEngine::kRetOk) {
          return -1;
      }
  
      return 0;
  }
  
  
  int32_t ImageProcessor::Command(int32_t cmd)
  {
      if (!s_engine) {
          PRINT_E("Not initialized\n");
          return -1;
      }
  
      switch (cmd) {
      case 0:
      default:
          PRINT_E("command(%d) is not supported\n", cmd);
          return -1;
      }
  }
  
  
  int32_t ImageProcessor::Process(cv::Mat& mat, ImageProcessor::Result& result)
  {
      if (!s_engine) {
          PRINT_E("Not initialized\n");
          return -1;
      }
  
      SemanticSegmentationEngine::Result ss_result;
      if (s_engine->Process(mat, ss_result) != SemanticSegmentationEngine::kRetOk) {
          return -1;
      }
  
      /* Draw the result */
      cv::resize(ss_result.image_mask, ss_result.image_mask, mat.size());
      cv::add(mat, ss_result.image_mask, mat);
  
      DrawFps(mat, ss_result.time_inference, cv::Point(0, 0), 0.5, 2, CommonHelper::CreateCvColor(0, 0, 0), CommonHelper::CreateCvColor(180, 180, 180), true);
  
      /* Return the results */
      result.time_pre_process = ss_result.time_pre_process;
      result.time_inference = ss_result.time_inference;
      result.time_post_process = ss_result.time_post_process;
  
      return 0;
  }
  
  